KUnifiedPush

connector_android.cpp
1/*
2 SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
3 SPDX-License-Identifier: LGPL-2.0-or-later
4*/
5
6#include "connector_p.h"
7#include "logging.h"
8
9#include <QCoreApplication>
10using QAndroidJniObject = QJniObject;
11
12using namespace KUnifiedPush;
13
14static QString fromJniString(JNIEnv *env, jstring s)
15{
16 if (!s) {
17 return {};
18 }
19
20 const char *str = env->GetStringUTFChars(s, nullptr);
21 const auto qs = QString::fromUtf8(str);
22 env->ReleaseStringUTFChars(s, str);
23 return qs;
24}
25
26static void newEndpoint(JNIEnv *env, jobject that, jstring token, jstring endpoint)
27{
28 Q_UNUSED(that);
29 for (auto c : ConnectorPrivate::s_instances) {
30 c->NewEndpoint(fromJniString(env, token), fromJniString(env, endpoint));
31 }
32}
33
34static void registrationFailed(JNIEnv *env, jobject that, jstring token, jstring reason)
35{
36 Q_UNUSED(that);
37 for (auto c :ConnectorPrivate::s_instances) {
38 c->registrationFailed(fromJniString(env, token), fromJniString(env, reason));
39 }
40}
41
42static void unregistered(JNIEnv *env, jobject that, jstring token)
43{
44 Q_UNUSED(that);
45 for (auto c : ConnectorPrivate::s_instances) {
46 c->Unregistered(fromJniString(env, token));
47 }
48}
49
50static void message(JNIEnv *env, jobject that, jstring token, jbyteArray message, jstring messageId)
51{
52 Q_UNUSED(that);
53 const auto messageSize = env->GetArrayLength(message);
54 const auto messageData = env->GetByteArrayElements(message, nullptr);
55 const auto messageQBA = QByteArray::fromRawData(reinterpret_cast<const char*>(messageData), messageSize);
56 for (auto c : ConnectorPrivate::s_instances) {
57 c->handleMessage(fromJniString(env, token), messageQBA, fromJniString(env, messageId));
58 }
59 env->ReleaseByteArrayElements(message, messageData, JNI_ABORT);
60}
61
62static const JNINativeMethod methods[] = {
63 {"newEndpoint", "(Ljava/lang/String;Ljava/lang/String;)V", (void*)newEndpoint},
64 {"registrationFailed", "(Ljava/lang/String;Ljava/lang/String;)V", (void*)registrationFailed},
65 {"unregistered", "(Ljava/lang/String;)V", (void*)unregistered},
66 {"message", "(Ljava/lang/String;[BLjava/lang/String;)V", (void*)message},
67};
68
69Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void*)
70{
71 static bool initialized = false;
72 if (initialized) {
73 return JNI_VERSION_1_4;
74 }
75 initialized = true;
76
77 JNIEnv *env = nullptr;
78 if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
79 qCWarning(Log) << "Failed to get JNI environment.";
80 return -1;
81 }
82 jclass cls = env->FindClass("org/kde/kunifiedpush/MessageReceiver");
83 if (env->RegisterNatives(cls, methods, sizeof(methods) / sizeof(JNINativeMethod)) < 0) {
84 qCWarning(Log) << "Failed to register native functions.";
85 return -1;
86 }
87
88 return JNI_VERSION_1_4;
89}
90
91std::vector<ConnectorPrivate*> ConnectorPrivate::s_instances;
92
93void ConnectorPrivate::init()
94{
95 s_instances.push_back(this);
96}
97
98void ConnectorPrivate::deinit()
99{
100 s_instances.erase(std::remove(s_instances.begin(), s_instances.end(), this), s_instances.end());
101}
102
103void ConnectorPrivate::doSetDistributor(const QString &distServiceName)
104{
106 m_distributor = QAndroidJniObject("org.kde.kunifiedpush.Distributor", "(Ljava/lang/String;Landroid/content/Context;)V", QAndroidJniObject::fromString(distServiceName).object(), context.object());
107}
108
109bool ConnectorPrivate::hasDistributor() const
110{
111 return m_distributor.isValid();
112}
113
114void ConnectorPrivate::doRegister()
115{
116 m_distributor.callMethod<void>("register", m_token, m_description, m_vapidPublicKey);
117}
118
119void ConnectorPrivate::doUnregister()
120{
121 m_distributor.callMethod<void>("unregister", m_token);
122}
123
124void ConnectorPrivate::handleMessage(const QString &token, const QByteArray &message, const QString &messageIdentifier)
125{
126 if (m_token != token) {
127 return;
128 }
129
130 Message(token, message, messageIdentifier);
131
132 if (!messageIdentifier.isEmpty()) {
133 m_distributor.callMethod<void>("acknowledge", token, messageIdentifier);
134 }
135}
A received push notification message.
Definition message.h:15
Client-side integration with UnifiedPush.
Definition connector.h:14
QByteArray fromRawData(const char *data, qsizetype size)
QJniObject fromString(const QString &string)
jobject object() const const
QString fromUtf8(QByteArrayView str)
bool isEmpty() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 25 2025 12:05:39 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.