File indexing completed on 2024-12-01 07:25:49
0001 /* 0002 SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org> 0003 SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 0006 #include "wifimonitor_p.h" 0007 #include "logging.h" 0008 0009 #include <QSharedData> 0010 0011 #include <private/qandroidextras_p.h> 0012 #include <QCoreApplication> 0013 #include <QJniEnvironment> 0014 #include <QJniObject> 0015 0016 using namespace KPublicTransport; 0017 0018 namespace KPublicTransport { 0019 class WifiMonitorBackend : public QSharedData 0020 { 0021 public: 0022 void setSsid(const QString &ssid); 0023 void setStatus(int statusCode); 0024 0025 std::vector<WifiMonitor*> frontends; 0026 WifiMonitor::Status status = WifiMonitor::NotAvailable; 0027 QJniObject wifiMonitor; 0028 }; 0029 } 0030 0031 void WifiMonitorBackend::setSsid(const QString &ssid) 0032 { 0033 for (auto m : frontends) { 0034 m->setSsid(ssid); 0035 } 0036 } 0037 0038 void WifiMonitorBackend::setStatus(int statusCode) 0039 { 0040 if (status == statusCode) { 0041 return; 0042 } 0043 status = static_cast<WifiMonitor::Status>(statusCode); 0044 for (auto m : frontends) { 0045 Q_EMIT m->statusChanged(); 0046 } 0047 } 0048 0049 static WifiMonitorBackend *s_backend = nullptr; 0050 0051 static void setSsid(JNIEnv *env, [[maybe_unused]] jobject that, jstring ssid) 0052 { 0053 if (s_backend) { 0054 const char *str = env->GetStringUTFChars(ssid, nullptr); 0055 s_backend->setSsid(QString::fromUtf8(str)); 0056 env->ReleaseStringUTFChars(ssid, str); 0057 } 0058 } 0059 0060 static void setStatus([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jobject that, jint statusCode) 0061 { 0062 if (s_backend) { 0063 s_backend->setStatus(statusCode); 0064 } 0065 } 0066 0067 static const JNINativeMethod methods[] = { 0068 {"setSsid", "(Ljava/lang/String;)V", (void *)setSsid}, 0069 {"setStatus", "(I)V", (void *)setStatus}, 0070 }; 0071 0072 WifiMonitor::WifiMonitor(QObject *parent) 0073 : QObject(parent) 0074 { 0075 static bool nativesRegistered = false; 0076 if (!nativesRegistered) { 0077 QJniEnvironment env; 0078 jclass cls = env->FindClass("org/kde/publictransport/onboard/WifiMonitor"); 0079 if (env->RegisterNatives(cls, methods, sizeof(methods) / sizeof(JNINativeMethod)) < 0) { 0080 qCWarning(Log) << "Failed to register native functions!"; 0081 } 0082 nativesRegistered = true; 0083 } 0084 0085 if (!s_backend) { 0086 s_backend = new WifiMonitorBackend; 0087 s_backend->wifiMonitor = QJniObject("org/kde/publictransport/onboard/WifiMonitor", "(Landroid/content/Context;)V", QNativeInterface::QAndroidApplication::context()); 0088 } 0089 0090 s_backend->ref.ref(); 0091 s_backend->frontends.push_back(this); 0092 } 0093 0094 WifiMonitor::~WifiMonitor() 0095 { 0096 s_backend->ref.deref(); 0097 if (!s_backend->ref) { 0098 delete s_backend; 0099 s_backend = nullptr; 0100 } else { 0101 auto it = std::find(s_backend->frontends.begin(), s_backend->frontends.end(), this); 0102 if (it != s_backend->frontends.end()) { 0103 s_backend->frontends.erase(it); 0104 } 0105 } 0106 } 0107 0108 WifiMonitor::Status WifiMonitor::status() const 0109 { 0110 return s_backend->status; 0111 } 0112 0113 void WifiMonitor::requestPermissions() 0114 { 0115 // TODO make this properly async 0116 QtAndroidPrivate::requestPermission(QStringLiteral("android.permission.ACCESS_FINE_LOCATION")); 0117 s_backend->wifiMonitor.callMethod<void>("checkStatus", "()V"); 0118 }