From fd11f30f01778ff311fb40c07f333881e4ce0789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 17 Oct 2025 11:47:27 +0200 Subject: [PATCH] Drop androidservice --- androidservice/androidservice.pro | 56 ---- androidservice/controlviews/Main.qml | 66 ---- androidservice/controlviews/controlviews.qrc | 5 - .../controlviews/devicecontrolapplication.cpp | 234 -------------- .../controlviews/devicecontrolapplication.h | 37 --- .../java/io/guh/nymeaapp/Action.java | 9 - .../guh/nymeaapp/NymeaAppControlService.java | 289 ------------------ .../nymeaapp/NymeaAppControlsActivity.java | 55 ---- .../java/io/guh/nymeaapp/NymeaAppService.java | 50 --- .../nymeaapp/NymeaAppServiceConnection.java | 283 ----------------- .../java/io/guh/nymeaapp/NymeaHost.java | 13 - .../java/io/guh/nymeaapp/State.java | 10 - .../java/io/guh/nymeaapp/Thing.java | 56 ---- .../nymeaappservice/androidbinder.cpp | 115 ------- .../nymeaappservice/androidbinder.h | 23 -- .../nymeaappservice/nymeaappservice.cpp | 83 ----- .../nymeaappservice/nymeaappservice.h | 27 -- androidservice/service_main.cpp | 37 --- 18 files changed, 1448 deletions(-) delete mode 100644 androidservice/androidservice.pro delete mode 100644 androidservice/controlviews/Main.qml delete mode 100644 androidservice/controlviews/controlviews.qrc delete mode 100644 androidservice/controlviews/devicecontrolapplication.cpp delete mode 100644 androidservice/controlviews/devicecontrolapplication.h delete mode 100644 androidservice/java/io/guh/nymeaapp/Action.java delete mode 100644 androidservice/java/io/guh/nymeaapp/NymeaAppControlService.java delete mode 100644 androidservice/java/io/guh/nymeaapp/NymeaAppControlsActivity.java delete mode 100644 androidservice/java/io/guh/nymeaapp/NymeaAppService.java delete mode 100644 androidservice/java/io/guh/nymeaapp/NymeaAppServiceConnection.java delete mode 100644 androidservice/java/io/guh/nymeaapp/NymeaHost.java delete mode 100644 androidservice/java/io/guh/nymeaapp/State.java delete mode 100644 androidservice/java/io/guh/nymeaapp/Thing.java delete mode 100644 androidservice/nymeaappservice/androidbinder.cpp delete mode 100644 androidservice/nymeaappservice/androidbinder.h delete mode 100644 androidservice/nymeaappservice/nymeaappservice.cpp delete mode 100644 androidservice/nymeaappservice/nymeaappservice.h delete mode 100644 androidservice/service_main.cpp diff --git a/androidservice/androidservice.pro b/androidservice/androidservice.pro deleted file mode 100644 index 8a7c50a8..00000000 --- a/androidservice/androidservice.pro +++ /dev/null @@ -1,56 +0,0 @@ -TEMPLATE = lib -TARGET = service -CONFIG += dll -QT += core core-private -QT += network qml quick quickcontrols2 svg websockets bluetooth charts nfc - -include(../shared.pri) -include(../3rdParty/android/android_openssl/openssl.pri) - - -INCLUDEPATH += $$top_srcdir/libnymea-app/ - -# https://bugreports.qt.io/browse/QTBUG-83165 -LIBS += -L$${top_builddir}/libnymea-app/$${ANDROID_TARGET_ARCH} - -LIBS += -L$$top_builddir/libnymea-app/ -lnymea-app -PRE_TARGETDEPS += ../libnymea-app - -RESOURCES += controlviews/controlviews.qrc \ - ../nymea-app/resources.qrc \ - ../nymea-app/images.qrc \ - ../nymea-app/styles.qrc - -INCLUDEPATH += ../nymea-app/ - -SOURCES += \ - controlviews/devicecontrolapplication.cpp \ - nymeaappservice/nymeaappservice.cpp \ - nymeaappservice/androidbinder.cpp \ - ../nymea-app/stylecontroller.cpp \ - ../nymea-app/platformhelper.cpp \ - ../nymea-app/nfchelper.cpp \ - ../nymea-app/nfcthingactionwriter.cpp \ - ../nymea-app/platformintegration/android/platformhelperandroid.cpp \ - service_main.cpp - -HEADERS += \ - controlviews/devicecontrolapplication.h \ - nymeaappservice/nymeaappservice.h \ - nymeaappservice/androidbinder.h \ - ../nymea-app/stylecontroller.h \ - ../nymea-app/platformhelper.h \ - ../nymea-app/nfchelper.h \ - ../nymea-app/nfcthingactionwriter.h \ - ../nymea-app/platformintegration/android/platformhelperandroid.h \ - -DISTFILES += \ - java/io/guh/nymeaapp/Action.java \ - java/io/guh/nymeaapp/NymeaAppControlService.java \ - java/io/guh/nymeaapp/NymeaAppService.java \ - java/io/guh/nymeaapp/NymeaAppControlsActivity.java \ - java/io/guh/nymeaapp/NymeaAppServiceConnection.java \ - java/io/guh/nymeaapp/Thing.java \ - java/io/guh/nymeaapp/State.java \ - java/io/guh/nymeaapp/NymeaHost.java \ - controlviews/Main.qml diff --git a/androidservice/controlviews/Main.qml b/androidservice/controlviews/Main.qml deleted file mode 100644 index 96585a22..00000000 --- a/androidservice/controlviews/Main.qml +++ /dev/null @@ -1,66 +0,0 @@ -import QtQuick -import QtQuick.Controls -import QtQuick.Controls.Material -import QtQuick.Layouts -import QtCore -import Nymea -import "qrc:/ui/devicepages/" - -ApplicationWindow { - id: app - visible: true - visibility: ApplicationWindow.FullScreen - color: Material.background - title: Configuration.appName - - Material.theme: NymeaUtils.isDark(Style.backgroundColor) ? Material.Dark : Material.Light - Material.background: Style.backgroundColor - Material.accent: Style.accentColor - Material.foreground: Style.foregroundColor - - font.pixelSize: mediumFont - font.weight: Font.Normal - font.capitalization: Font.MixedCase - font.family: Style.fontFamily - - property int margins: 16 - property int bigMargins: 20 - - property int extraSmallFont: 10 - property int smallFont: 13 - property int mediumFont: 16 - property int largeFont: 20 - - property int smallIconSize: 16 - property int iconSize: 24 - property int bigIconSize: 40 - property int hugeIconSize: 64 - - property int delegateHeight: 60 - - readonly property bool landscape: app.width > app.height - - ThingsProxy { - id: thingProxy - engine: _engine - filterThingId: controlledThingId - } - - property Thing controlledThing: engine.thingManager.fetchingData ? null : engine.thingManager.things.getThing(controlledThingId) - - onControlledThingChanged: (controlledThing) => { - loader.setSource("qrc:/ui/devicepages/" + NymeaUtils.interfaceListToDevicePage(controlledThing.thingClass.interfaces), {thing: controlledThing, header: null}) - PlatformHelper.hideSplashScreen(); - } - - Loader { - id: loader - anchors.fill: parent - anchors.bottomMargin: app.margins // For some reason the bottom edge seems a bit off in the overlay - } - - onClosing: { - print("************* Control View closing") - } - -} diff --git a/androidservice/controlviews/controlviews.qrc b/androidservice/controlviews/controlviews.qrc deleted file mode 100644 index f907b18e..00000000 --- a/androidservice/controlviews/controlviews.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - Main.qml - - diff --git a/androidservice/controlviews/devicecontrolapplication.cpp b/androidservice/controlviews/devicecontrolapplication.cpp deleted file mode 100644 index a96f9026..00000000 --- a/androidservice/controlviews/devicecontrolapplication.cpp +++ /dev/null @@ -1,234 +0,0 @@ -#include "devicecontrolapplication.h" - -#include "engine.h" -#include "connection/discovery/nymeadiscovery.h" -#include "connection/nymeahosts.h" -#include "libnymea-app-core.h" -#include "../nymea-app/stylecontroller.h" -#include "../nymea-app/platformhelper.h" -#include "../nymea-app/nfchelper.h" -#include "../nymea-app/nfcthingactionwriter.h" -#include "../nymea-app/platformintegration/android/platformhelperandroid.h" - -#include -#include -#include -#include -#include -#include -#include - -QObject *platformHelperProvider(QQmlEngine *engine, QJSEngine *scriptEngine) -{ - Q_UNUSED(engine) - Q_UNUSED(scriptEngine) - return new PlatformHelperAndroid(); -} - -DeviceControlApplication::DeviceControlApplication(int argc, char *argv[]) : QApplication(argc, argv) -{ - setApplicationName("nymea-app"); - setOrganizationName("nymea"); - - QSettings settings; - - m_discovery = new NymeaDiscovery(this); - - m_engine = new Engine(this); - - m_qmlEngine = new QQmlApplicationEngine(this); - - Nymea::Core::registerQmlTypes(); - - qmlRegisterSingletonType("Nymea", 1, 0, "PlatformHelper", platformHelperProvider); - qmlRegisterSingletonType(QUrl("qrc:///ui/utils/NymeaUtils.qml"), "Nymea", 1, 0, "NymeaUtils" ); - qmlRegisterType("Nymea", 1, 0, "NfcThingActionWriter"); - qmlRegisterSingletonType("Nymea", 1, 0, "NfcHelper", NfcHelper::nfcHelperProvider); - - StyleController *styleController = new StyleController("light", this); - - QQmlFileSelector *styleSelector = new QQmlFileSelector(m_qmlEngine); - styleSelector->setExtraSelectors({styleController->currentStyle()}); - - foreach (const QFileInfo &fi, QDir(":/ui/fonts/").entryInfoList()) { - QFontDatabase::addApplicationFont(fi.absoluteFilePath()); - } - foreach (const QFileInfo &fi, QDir(":/styles/" + styleController->currentStyle() + "/fonts/").entryInfoList()) { - qDebug() << "Adding style font:" << fi.absoluteFilePath(); - QFontDatabase::addApplicationFont(fi.absoluteFilePath()); - } - - qmlRegisterSingletonType(QUrl("qrc:///styles/" + styleController->currentStyle() + "/Style.qml"), "Nymea", 1, 0, "Style" ); - - m_qmlEngine->rootContext()->setContextProperty("styleController", styleController); - m_qmlEngine->rootContext()->setContextProperty("engine", m_engine); - m_qmlEngine->rootContext()->setContextProperty("_engine", m_engine); - m_qmlEngine->rootContext()->setContextProperty("controlledThingId", ""); // Unknown at this point - - m_qmlEngine->load(QUrl(QLatin1String("qrc:/Main.qml"))); - - jboolean startedByNfc = QtAndroid::androidActivity().callMethod("startedByNfc", "()Z"); - if (startedByNfc) { - qDebug() << "**** Started by NFC"; - qDebug() << "Registering NFC handler and waiting for message."; - - QNearFieldManager *manager = new QNearFieldManager(this); - manager->registerNdefMessageHandler(this, SLOT(handleNdefMessage(QNdefMessage,QNearFieldTarget*))); - - } else { - qDebug() << "*** Started by other intent"; - qDebug() << "Expecing nymeaId and thingId in intent extras."; - QString nymeaId = QtAndroid::androidActivity().callObjectMethod("nymeaId").toString(); - QString thingId = QtAndroid::androidActivity().callObjectMethod("thingId").toString(); - - connectToNymea(nymeaId); - m_qmlEngine->rootContext()->setContextProperty("controlledThingId", thingId); - } -} - -void DeviceControlApplication::handleNdefMessage(QNdefMessage message, QNearFieldTarget *target) -{ - Q_UNUSED(target) - qDebug() << "************* NFC message!" << message.toByteArray(); - if (message.count() < 1) { - qWarning() << "NFC message doesn't contain any records..."; - return; - } - // NOTE: At this point we're only supporting one NDEF record per message - QNdefRecord record = message.first(); - QNdefNfcUriRecord uriRecord(record); - - QUrl url = uriRecord.uri(); - if (url.scheme() != "nymea") { - qWarning() << "NDEF URI record scheme is not \"nymea://\""; - return; - } - - QUuid nymeaId = QUuid(url.host()); - if (nymeaId.isNull()) { - qWarning() << "Invalid nymea UUID in NDEF record."; - return; - } - - QUuid thingId = QUuid(QUrlQuery(url).queryItemValue("t")); - if (thingId.isNull()) { - qWarning() << "Invalid thing in NDEF record"; - return; - } - - m_pendingNfcAction = url; - - connectToNymea(nymeaId); - m_qmlEngine->rootContext()->setContextProperty("controlledThingId", thingId); - - connect(m_engine->thingManager(), &ThingManager::fetchingDataChanged, [this](){ - if (m_engine->jsonRpcClient()->connected() && !m_engine->thingManager()->fetchingData()) { - qDebug() << "Ready to process commands"; - runNfcAction(); - } - }); -} - -void DeviceControlApplication::connectToNymea(const QUuid &nymeaId) -{ - NymeaHost *host = m_discovery->nymeaHosts()->find(nymeaId); - if (!host) { - qWarning() << "No such nymea host:" << nymeaId; - // TODO: We could wait here until the discovery finds it... But it really should be cached already... - exit(1); - } - qDebug() << "Connecting to:" << host->name(); - m_engine->jsonRpcClient()->connectToHost(host); -} - -void DeviceControlApplication::runNfcAction() -{ - if (!m_pendingNfcAction.isEmpty()) { - qDebug() << "NFC action:" << m_pendingNfcAction; - } - QUrl url = m_pendingNfcAction; - m_pendingNfcAction.clear(); - - if (url.scheme() != "nymea") { - qWarning() << "NDEF URI record scheme is not \"nymea://\" in" << url.toString(); - return; - } - - QUuid nymeaId = QUuid(url.host()); - if (nymeaId.isNull()) { - qWarning() << "Invalid nymea UUID" << url.host() << "in NDEF record" << url.toString(); - return; - } - - QUuid thingId = QUuid(QUrlQuery(url).queryItemValue("t")); - Thing *thing = m_engine->thingManager()->things()->getThing(thingId); - if (!thing) { - qDebug() << "Thing" << thingId.toString() << "from" << url.toString() << "doesn't exist on nymea host" << nymeaId.toString(); - return; - } - - QList> queryItems = QUrlQuery(url.query()).queryItems(); - for (int i = 0; i < queryItems.count(); i++) { - QString entryName = queryItems.at(i).first; - if (entryName == "t") { - continue; - } - if (!entryName.startsWith("a")) { - qDebug() << "Only actions are supported. Skipping query item" << entryName; - continue; - } - - QString actionString = queryItems.at(i).second; - QStringList parts = actionString.split("#"); - if (parts.count() == 0) { - qDebug() << "Invalid action definition:" << actionString; - continue; - } - - if (parts.count() > 2) { - // The parameters might contain a #, let's merge them again - parts[1] = parts.mid(1).join('#'); - } - - QString actionTypeName = parts.at(0); - ActionType *actionType = thing->thingClass()->actionTypes()->findByName(actionTypeName); - if (!actionType) { - qWarning() << "Invalid action name" << actionType << "in url:" << url.toString(); - continue; - } - - QHash paramsInUri; - if (parts.count() > 1) { - QString paramsString = parts.at(1); - foreach (const QString ¶mString, paramsString.split("+")) { - QStringList parts = paramString.split(":"); - if (parts.count() != 2) { - qWarning() << "Invalid param format" << paramString << "in url:" << url.toString(); - continue; - } - paramsInUri.insert(parts.at(0), parts.at(1)); - } - } - - qDebug() << "Parameters in NFC uri:" << paramsInUri; - - QVariantList params; - for (int j = 0; j < actionType->paramTypes()->rowCount(); j++) { - ParamType *paramType = actionType->paramTypes()->get(j); - QVariantMap param; - param.insert("paramTypeId", paramType->id()); - if (paramsInUri.contains(paramType->name())) { - param.insert("value", paramsInUri.value(paramType->name())); - } else { - param.insert("value", paramType->defaultValue()); - } - params.append(param); - } - - qDebug() << "Action parameters:" << qUtf8Printable(QJsonDocument::fromVariant(params).toJson()); - - m_engine->thingManager()->executeAction(thingId, actionType->id(), params); - } -} - - diff --git a/androidservice/controlviews/devicecontrolapplication.h b/androidservice/controlviews/devicecontrolapplication.h deleted file mode 100644 index edd6985c..00000000 --- a/androidservice/controlviews/devicecontrolapplication.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef DEVICECONTROLAPPLICATION_H -#define DEVICECONTROLAPPLICATION_H - -#include -#include -#include -#include -#include - -#include "types/ruleactions.h" -#include "connection/discovery/nymeadiscovery.h" -#include "engine.h" - -class DeviceControlApplication : public QApplication -{ - Q_OBJECT -public: - explicit DeviceControlApplication(int argc, char *argv[]); - -private slots: - void handleNdefMessage(QNdefMessage message,QNearFieldTarget* target); - - void connectToNymea(const QUuid &nymeaId); - - void runNfcAction(); - -private: - NymeaDiscovery *m_discovery = nullptr; - Engine *m_engine = nullptr; - QQmlApplicationEngine *m_qmlEngine = nullptr; - - QUrl m_pendingNfcAction; - - -}; - -#endif // DEVICECONTROLAPPLICATION_H diff --git a/androidservice/java/io/guh/nymeaapp/Action.java b/androidservice/java/io/guh/nymeaapp/Action.java deleted file mode 100644 index 04923f02..00000000 --- a/androidservice/java/io/guh/nymeaapp/Action.java +++ /dev/null @@ -1,9 +0,0 @@ -package io.guh.nymeaapp; - -import java.util.UUID; - -public class Action { - public UUID typeId; - public String name; - public String displayName; -} diff --git a/androidservice/java/io/guh/nymeaapp/NymeaAppControlService.java b/androidservice/java/io/guh/nymeaapp/NymeaAppControlService.java deleted file mode 100644 index 8d3a7e0d..00000000 --- a/androidservice/java/io/guh/nymeaapp/NymeaAppControlService.java +++ /dev/null @@ -1,289 +0,0 @@ -package io.guh.nymeaapp; - -import android.util.Log; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.ComponentName; -import android.app.PendingIntent; -import android.net.Uri; -import android.content.Context; -import android.service.controls.ControlsProviderService; -import android.service.controls.actions.*; -import android.service.controls.Control; -import android.service.controls.DeviceTypes; -import android.service.controls.templates.*; -import android.os.Binder; -import android.os.IBinder; -import android.os.Parcel; - -import java.util.concurrent.Flow.Publisher; -import java.util.function.Consumer; -import java.util.List; -import java.util.ArrayList; -import java.util.UUID; -import java.util.HashMap; -import io.reactivex.Flowable; -import io.reactivex.processors.ReplayProcessor; -import org.reactivestreams.FlowAdapters; -import org.json.*; - -// Android device controls service - -// This service is instantiated by the android device controls on demand. It will -// connect to the NymeaAppService and interact with nymea through that. - -public class NymeaAppControlService extends ControlsProviderService { - private String TAG = "nymea-app: NymeaAppControlService"; - private NymeaAppServiceConnection m_serviceConnection; - - // For publishing all available - private ReplayProcessor m_publisherForAll; - private ArrayList m_pendingForAll = new ArrayList(); // pending nymea ids to query - - private ReplayProcessor m_updatePublisher; - private List m_activeControlIds; - - - private void ensureServiceConnection() { - if (m_serviceConnection == null) { - m_serviceConnection = new NymeaAppServiceConnection(getBaseContext()) { - @Override public void onConnectedChanged(boolean connected) { - Log.d(TAG, "Connected to NymeaAppService. Known hosts: " + m_serviceConnection.getHosts().size()); - if (connected && m_publisherForAll != null) { - Log.d(TAG, "Processing all"); - processAll(); - } - } - @Override public void onReadyChanged(UUID nymeaId, boolean ready) { - Log.d(TAG, "Nymea instance " + nymeaId.toString() + " ready state changed: " + Boolean.toString(ready)); - if (ready) { - process(nymeaId); - } - } - @Override public void onUpdate(UUID nymeaId, UUID thingId) { - if (m_updatePublisher != null && m_activeControlIds.contains(thingId.toString())) { -// Log.d(TAG, "Updating publisher for thing: " + thingId); - m_updatePublisher.onNext(thingToControl(nymeaId, thingId)); -// m_updatePublisher.onComplete(); - } - } - }; - } - Intent serviceIntent = new Intent(this, NymeaAppService.class); - bindService(serviceIntent, m_serviceConnection, Context.BIND_AUTO_CREATE); - } - - private void processAll() { - ensureServiceConnection(); - if (m_serviceConnection.connected()) { - // Need to add all the pending before processing - if (m_publisherForAll != null) { - for (UUID nymeaId: m_serviceConnection.getHosts().keySet()) { - m_pendingForAll.add(nymeaId); - } - } - for (UUID nymeaId: m_serviceConnection.getHosts().keySet()) { - if (m_serviceConnection.getHosts().get(nymeaId).isReady) { - process(nymeaId); - } - } - } else { - Log.d(TAG, "Not connected to NymeaAppService yet..."); - } - } - - private void process(UUID nymeaId) { - Log.d(TAG, "Processing..."); - ensureServiceConnection(); - if (!m_serviceConnection.connected()) { - Log.d(TAG, "NymeaAppService not connected to nymea instance " + nymeaId + " yet."); - return; - } - if (!m_serviceConnection.getHosts().keySet().contains(nymeaId)) { - Log.d(TAG, "Service connection is not ready yet..."); - return; - } - - for (Thing thing : m_serviceConnection.getHosts().get(nymeaId).things.values()) { - Log.d(TAG, "Processing thing: " + thing.name); - - if (m_publisherForAll != null) { - Log.d(TAG, "Adding stateless"); - m_publisherForAll.onNext(thingToControl(nymeaId, thing.id)); - } - - if (m_updatePublisher != null) { - if (m_activeControlIds.contains(thing.id.toString())) { - Log.d(TAG, "Adding stateful"); - m_updatePublisher.onNext(thingToControl(nymeaId, thing.id)); - } - } - } - - if (m_pendingForAll.contains(nymeaId)) { - m_pendingForAll.remove(nymeaId); - } - - // The publisher for all needs to be completed when done - if (m_publisherForAll != null && m_pendingForAll.isEmpty()) { - Log.d(TAG, "Completing all publisher"); - m_publisherForAll.onComplete(); - } - - Log.d(TAG, "Done processing"); - // We never close the update publisher as we need that one to send updates - } - - - @Override - public Publisher createPublisherForAllAvailable() { - Log.d(TAG, "Creating publishers for all"); - m_publisherForAll = ReplayProcessor.create(); - processAll(); - return FlowAdapters.toFlowPublisher(m_publisherForAll); - } - - @Override - public Publisher createPublisherFor(List controlIds) { - Log.d(TAG, "Creating publishers for " + Integer.toString(controlIds.size())); - m_updatePublisher = ReplayProcessor.create(); - m_activeControlIds = controlIds; - processAll(); - return FlowAdapters.toFlowPublisher(m_updatePublisher); - } - - @Override - public void performControlAction(String controlId, ControlAction action, Consumer consumer) { - Log.d(TAG, "Performing control action: " + controlId); - - UUID nymeaId = m_serviceConnection.hostForThing(UUID.fromString(controlId)); - if (nymeaId == null) { - Log.d(TAG, "Nymea host not found for thing id: " + controlId); - consumer.accept(ControlAction.RESPONSE_FAIL); - return; - } - Thing thing = m_serviceConnection.getThing(UUID.fromString(controlId)); - if (thing == null) { - Log.d(TAG, "Thing not found for id: " + controlId); - consumer.accept(ControlAction.RESPONSE_FAIL); - return; - } - - UUID actionTypeId; - String param; - if (thing.interfaces.contains("dimmablelight") && action instanceof FloatAction) { - actionTypeId = thing.stateByName("brightness").typeId; - FloatAction fAction = (FloatAction) action; - param = String.valueOf(Math.round(fAction.getNewValue())); - } else if (thing.interfaces.contains("power") && action instanceof BooleanAction) { - actionTypeId = thing.stateByName("power").typeId; - BooleanAction bAction = (BooleanAction) action; - param = bAction.getNewState() == true ? "true" : "false"; - } else if (thing.interfaces.contains("closable") && action instanceof BooleanAction) { - BooleanAction bAction = (BooleanAction) action; - if (bAction.getNewState()) { - Log.d(TAG, "executing open"); - actionTypeId = thing.actionByName("open").typeId; - } else { - Log.d(TAG, "executing close"); - actionTypeId = thing.actionByName("close").typeId; - } - param = ""; - } else if (thing.interfaces.contains("volumecontroller") && thing.stateByName("volume") != null) { - actionTypeId = thing.stateByName("volume").typeId; - FloatAction fAction = (FloatAction) action; - param = String.valueOf(Math.round(fAction.getNewValue())); - } else { - Log.d(TAG, "Unhandled action for: " + thing.name); - consumer.accept(ControlAction.RESPONSE_FAIL); - return; - } - - m_serviceConnection.executeAction(nymeaId, thing.id, actionTypeId, param); - consumer.accept(ControlAction.RESPONSE_OK); - - } - - private HashMap m_intents = new HashMap(); - - private Control thingToControl(UUID nymeaId, UUID thingId) { -// Log.d(TAG, "Creating control for thing: " + thing.name + " id: " + thing.id); - - NymeaHost nymeaHost = m_serviceConnection.getHosts().get(nymeaId); - Thing thing = nymeaHost.things.get(thingId); - - // NOTE: intentId 1 doesn't work for some reason I don't understand yet... - // so let's make sure we never add "1" to it by always added 100 - int intentId = m_intents.size() + 100; - PendingIntent pi; - if (m_intents.containsKey(thing.id)) { - intentId = m_intents.get(thing.id); - } else { - m_intents.put(thing.id, intentId); - } - - Context context = getBaseContext(); - Intent intent = new Intent(context, NymeaAppControlsActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); - intent.putExtra("nymeaId", nymeaId.toString()); - intent.putExtra("thingId", thing.id.toString()); - pi = PendingIntent.getActivity(context, intentId, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); - Log.d(TAG, "Created pendingintent for " + thing.name + " with id " + intentId + " and extra " + thing.id); - - Control.StatefulBuilder builder = new Control.StatefulBuilder(thing.id.toString(), pi) - .setTitle(thing.name) - .setSubtitle(thing.className) - .setStructure(nymeaHost.name); - - if (thing.interfaces.contains("impulsebasedgaragedoor")) { - builder.setDeviceType(DeviceTypes.TYPE_GARAGE); - builder.setControlTemplate(new StatelessTemplate(thing.id.toString())); - } else if (thing.interfaces.contains("statefulgaragedoor")) { - builder.setDeviceType(DeviceTypes.TYPE_GARAGE); - State stateState = thing.stateByName("state"); - ControlButton controlButton = new ControlButton(stateState.value.equals("open"), stateState.displayName); - builder.setControlTemplate(new ToggleTemplate(thing.id.toString(), controlButton)); - -// } else if (thing.interfaces.contains("extendedstatefulgaragedoor")) { -// builder.setDeviceTyoe(DeviceTypes.TYPE_GARAGE); - - } else if (thing.interfaces.contains("light")) { - builder.setDeviceType(DeviceTypes.TYPE_LIGHT); - State powerState = thing.stateByName("power"); - ControlButton controlButton = new ControlButton(powerState.value.equals("true"), powerState.displayName); - - if (thing.interfaces.contains("dimmablelight")) { - State brightnessState = thing.stateByName("brightness"); - RangeTemplate rangeTemplate = new RangeTemplate(thing.id.toString(), 0, 100, Float.parseFloat(brightnessState.value), 1, brightnessState.displayName); - builder.setControlTemplate(new ToggleRangeTemplate(thing.id.toString(), controlButton, rangeTemplate)); - } else { - builder.setControlTemplate(new ToggleTemplate(thing.id.toString(), controlButton)); - } - } else if (thing.interfaces.contains("powersocket")) { - builder.setDeviceType(DeviceTypes.TYPE_OUTLET); - State powerState = thing.stateByName("power"); - ControlButton controlButton = new ControlButton(powerState.value.equals("true"), powerState.displayName); - builder.setControlTemplate(new ToggleTemplate(thing.id.toString(), controlButton)); - } else if (thing.interfaces.contains("mediaplayer")) { - if (thing.stateByName("playerType").value == "video") { - builder.setDeviceType(DeviceTypes.TYPE_TV); - } else { - // FIXME: There doesn't seem to be a speaker DeviceType!?! - builder.setDeviceType(DeviceTypes.TYPE_TV); - } - if (thing.interfaces.contains("volumecontroller")) { - State volumeState = thing.stateByName("volume"); - if (volumeState != null) { - RangeTemplate rangeTemplate = new RangeTemplate(thing.id.toString(), 0, 100, Float.parseFloat(volumeState.value), 1, volumeState.displayName); - builder.setControlTemplate(rangeTemplate); - } - } - } else { - builder.setDeviceType(DeviceTypes.TYPE_GENERIC_ON_OFF); - } - builder.setStatus(Control.STATUS_OK); - -// Log.d(TAG, "Created control for thing: " + thing.name + " id: " + thing.id); - return builder.build(); - } -} diff --git a/androidservice/java/io/guh/nymeaapp/NymeaAppControlsActivity.java b/androidservice/java/io/guh/nymeaapp/NymeaAppControlsActivity.java deleted file mode 100644 index 3b94d25e..00000000 --- a/androidservice/java/io/guh/nymeaapp/NymeaAppControlsActivity.java +++ /dev/null @@ -1,55 +0,0 @@ -package io.guh.nymeaapp; -import android.util.Log; -import android.content.Intent; -import android.content.Context; -import android.os.Bundle; -import android.os.Build; -import android.telephony.TelephonyManager; -import android.provider.Settings.Secure; -import android.os.Vibrator; -import android.os.Process; -import android.nfc.NfcAdapter; -import android.nfc.NdefMessage; -import android.os.Parcelable; - -// An activity spawned by android device controls on demand. - -public class NymeaAppControlsActivity extends org.qtproject.qt5.android.bindings.QtActivity -{ - private static final String TAG = "nymea-app: NymeaAppControlActivity"; - - - @Override public void onPause() { - Log.d(TAG, "Pausing..."); - System.exit(0); - } - - @Override public void onResume() { - super.onResume(); - Log.d(TAG, "Resuming..."); - } - - @Override public void onDestroy() { - Log.d(TAG, "Destroying..."); - } - - public boolean startedByNfc() { - return NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction()); - } - - public String nymeaId() - { - return getIntent().getStringExtra("nymeaId"); - } - - public String thingId() - { - return getIntent().getStringExtra("thingId"); - } - - public void vibrate(int duration) - { - Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); - v.vibrate(duration); - } -} diff --git a/androidservice/java/io/guh/nymeaapp/NymeaAppService.java b/androidservice/java/io/guh/nymeaapp/NymeaAppService.java deleted file mode 100644 index 5bc6acf7..00000000 --- a/androidservice/java/io/guh/nymeaapp/NymeaAppService.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.guh.nymeaapp; - -import android.content.Context; -import android.content.Intent; -import android.util.Log; - -import org.qtproject.qt5.android.bindings.QtService; - -// Background service establishing a connection to nymea and providing data on android specific interfaces -// such as IBinder and BroadcastListener - -// This service loads the service_main Qt entry point and does most of its work in C++/Qt - -public class NymeaAppService extends QtService -{ - public static final String NYMEA_APP_BROADCAST = "io.guh.nymeaapp.NymeaAppService.broadcast"; - - private static final String TAG = "nymea-app: NymeaAppService"; - - @Override - public void onCreate() { - super.onCreate(); - Log.i(TAG, "Creating Service"); - } - - @Override - public void onDestroy() { - super.onDestroy(); - Log.i(TAG, "Destroying Service"); - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - int ret = super.onStartCommand(intent, flags, startId); - - // Do some work - - Log.d(TAG, "*************** Service started"); - - return ret; - } - - public void sendBroadcast(String payload) { - Intent sendToUiIntent = new Intent(); - sendToUiIntent.setAction(NYMEA_APP_BROADCAST); - sendToUiIntent.putExtra("data", payload); -// Log.d(TAG, "Service sending broadcast"); - sendBroadcast(sendToUiIntent); - } -} diff --git a/androidservice/java/io/guh/nymeaapp/NymeaAppServiceConnection.java b/androidservice/java/io/guh/nymeaapp/NymeaAppServiceConnection.java deleted file mode 100644 index fd3c3b1b..00000000 --- a/androidservice/java/io/guh/nymeaapp/NymeaAppServiceConnection.java +++ /dev/null @@ -1,283 +0,0 @@ -package io.guh.nymeaapp; - -import java.util.List; -import java.util.ArrayList; -import java.util.UUID; -import java.util.HashMap; - -import android.util.Log; - -import android.os.IBinder; -import android.os.Parcel; -import android.os.RemoteException; - -import android.content.Intent; -import android.content.IntentFilter; -import android.content.BroadcastReceiver; -import android.content.ServiceConnection; -import android.content.ComponentName; -import android.content.Context; - -import android.service.controls.Control; -import android.service.controls.DeviceTypes; - -import io.reactivex.processors.ReplayProcessor; - -import org.json.*; - -// Helper class to establish a connection to the NymeaAppService and interact -// with that using IBinder and ServiceBroadcastListener - -public class NymeaAppServiceConnection implements ServiceConnection { - private static final String TAG = "nymea-app: NymeaAppServiceConnection"; - private IBinder m_service; - private Context m_context; - - private boolean m_connected = false; - private HashMap m_nymeaHosts = new HashMap(); - - public NymeaAppServiceConnection(Context context) { - super(); - m_context = context; - } - - final public boolean connected() { - return m_connected; - } - public void onConnectedChanged(boolean connected) {}; - - final public boolean isReady(UUID nymeaId) { - return m_nymeaHosts.get(nymeaId).isReady; - } - public void onReadyChanged(UUID nymeaId, boolean ready) {} - - public final HashMap getHosts() { - return m_nymeaHosts; - } - - final public Thing getThing(UUID thingId) { - for (HashMap.Entry entry : m_nymeaHosts.entrySet()) { - Thing thing = entry.getValue().things.get(thingId); - if (thing != null) { - return thing; - } - } - return null; - } - final public UUID hostForThing(UUID thingId) { - for (HashMap.Entry entry : m_nymeaHosts.entrySet()) { - Thing thing = entry.getValue().things.get(thingId); - if (thing != null) { - return entry.getKey(); - } - } - return null; - } - - public void onError() {} - public void onUpdate(UUID nymeaId, UUID thingId) {} - - final public void executeAction(UUID nymeaId, UUID thingId, UUID actionTypeId, String paramValue) { - try { - JSONObject params = new JSONObject(); - params.put("nymeaId", nymeaId.toString()); - params.put("thingId", thingId.toString()); - params.put("actionTypeId", actionTypeId.toString()); - JSONArray actionParams = new JSONArray(); - JSONObject param = new JSONObject(); - param.put("paramTypeId", actionTypeId.toString()); - param.put("value", paramValue); - actionParams.put(param); - params.put("params", actionParams); - Parcel parcel = createRequest("ExecuteAction", params); - Parcel retParcel = Parcel.obtain(); - m_service.transact(1, parcel, retParcel, 0); - } catch (Exception e) { - Log.d(TAG, "Error calling executeAction on NymeaAppService"); - } - } - - @Override public void onServiceConnected(ComponentName className, IBinder service) { - Log.d(TAG, "Connected to NymeaAppService"); - m_service = service; - - registerServiceBroadcastReceiver(); - - try { - Parcel parcel = createRequest("GetInstances"); - Parcel retParcel = Parcel.obtain(); - - m_service.transact(1, parcel, retParcel, 0); - - JSONObject reply = new JSONObject(retParcel.readString()); - Log.d(TAG, "Instaces received: " + reply.toString()); - JSONArray instances = reply.getJSONArray("instances"); - for (int i = 0; i < instances.length(); i++) { - JSONObject instanceMap = instances.getJSONObject(i); - NymeaHost nymeaHost = new NymeaHost(); - nymeaHost.id = UUID.fromString(instanceMap.getString("id")); - nymeaHost.name = instanceMap.getString("name"); - nymeaHost.isReady = instanceMap.getBoolean("isReady"); - m_nymeaHosts.put(nymeaHost.id, nymeaHost); - if (nymeaHost.isReady) { - fetchThings(nymeaHost.id); - } - } - } catch (JSONException e) { - Log.d(TAG, "Error while processing JSON in communication with NymeaAppService: " + e.toString()); - onError(); - return; - } catch (RemoteException e) { - Log.d(TAG, "Error communicating with NymeaAppService: " + e.toString()); - onError(); - return; - } - - m_connected = true; - onConnectedChanged(m_connected); - } - - @Override public void onServiceDisconnected(ComponentName arg0) { - m_service = null; - for (int i = 0; i < m_nymeaHosts.size(); i++) { - m_nymeaHosts.get(i).isReady = false; - } - m_connected = false; - onConnectedChanged(m_connected); - } - - public void registerServiceBroadcastReceiver() { - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(NymeaAppService.NYMEA_APP_BROADCAST); - m_context.registerReceiver(serviceMessageReceiver, intentFilter); - Log.d(TAG, "Registered broadcast receiver"); - } - - private BroadcastReceiver serviceMessageReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (NymeaAppService.NYMEA_APP_BROADCAST.equals(intent.getAction())) { - String payload = intent.getStringExtra("data"); - try { - processBroadcast(payload); - } catch(JSONException e) { - Log.d(TAG, "Error parsing broadcast JSON: " + e.toString()); - } - } - } - }; - - private void processBroadcast(String payload) throws JSONException - { - JSONObject data = new JSONObject(payload); - JSONObject params = data.getJSONObject("params"); -// Log.d(TAG, "Broadcast received from NymeaAppService: " + data.getString("notification")); - Log.d(TAG, params.toString()); - - if (data.getString("notification").equals("ThingStateChanged")) { - UUID nymeaId = UUID.fromString(params.getString("nymeaId")); - UUID thingId = UUID.fromString(params.getString("thingId")); - UUID stateTypeId = UUID.fromString(params.getString("stateTypeId")); - String value = params.getString("value"); -// Log.d(TAG, "Thing state changed: " + thingId + " stateTypeId: " + stateTypeId + " value: " + value); - - Thing thing = getThing(thingId); - if (thing != null) { - thing.stateById(stateTypeId).value = value; - onUpdate(nymeaId, thingId); - } else { - Log.d(TAG, "Got a state change notification for a thing we don't know!"); - } - } - - if (data.getString("notification").equals("ReadyStateChanged")) { - UUID nymeaId = UUID.fromString(params.getString("nymeaId")); - NymeaHost host = m_nymeaHosts.get(nymeaId); - host.isReady = params.getBoolean("isReady"); - if (host.isReady) { - Log.d(TAG, "Host is ready. Fetching things..."); - fetchThings(nymeaId); - } else { - Log.d(TAG, "Host is not ready yet..."); - } - } - } - - private void fetchThings(UUID nymeaId) { - Log.d(TAG, "Fetching things"); - String thingsList; - try { - JSONObject params = new JSONObject(); - params.put("nymeaId", nymeaId.toString()); - Parcel parcel = createRequest("GetThings", params); - Parcel retParcel = Parcel.obtain(); - m_service.transact(1, parcel, retParcel, 0); - thingsList = retParcel.readString(); - } catch (Exception e) { - Log.d(TAG, "Error fetching things from NymeaAppService: " + e.toString()); - onError(); - return; - } - - try { - JSONObject result = new JSONObject(thingsList); - for (int i = 0; i < result.getJSONArray("things").length(); i++) { - JSONObject entry = result.getJSONArray("things").getJSONObject(i); - Thing thing = new Thing(); - thing.id = UUID.fromString(entry.getString("id")); - thing.name = entry.getString("name"); - thing.className = entry.getString("className"); - JSONArray ifaces = entry.getJSONArray("interfaces"); - for (int j = 0; j < ifaces.length(); j++) { - thing.interfaces.add(ifaces.get(j)); - } - JSONArray states = entry.getJSONArray("states"); - for (int j = 0; j < states.length(); j++) { - JSONObject stateMap = states.getJSONObject(j); - State s = new State(); - s.typeId = UUID.fromString(stateMap.getString("stateTypeId")); - s.name = stateMap.getString("name"); - s.displayName = stateMap.getString("displayName"); - s.value = stateMap.getString("value"); - thing.states.add(s); - } - JSONArray actions = entry.getJSONArray("actions"); - for (int j = 0; j < actions.length(); j++) { - JSONObject actionMap = actions.getJSONObject(j); - Action a = new Action(); - a.typeId = UUID.fromString(actionMap.getString("actionTypeId")); - a.name = actionMap.getString("name"); - a.displayName = actionMap.getString("displayName"); - thing.actions.add(a); - } - m_nymeaHosts.get(nymeaId).things.put(thing.id, thing); - } - - } catch (Exception e) { - Log.d(TAG, "Error parsing JSON from NymeaAppService: " + e.toString()); - Log.d(TAG, thingsList); - m_service = null; - onError(); - return; - } - - Log.d(TAG, "Things fetched: " + m_nymeaHosts.get(nymeaId).things.size()); - m_nymeaHosts.get(nymeaId).isReady = true; - onReadyChanged(nymeaId, true); - } - - private Parcel createRequest(String method) throws JSONException { - return createRequest(method, null); - } - private Parcel createRequest(String method, JSONObject params) throws JSONException { - Parcel ret = Parcel.obtain(); - JSONObject payload = new JSONObject(); - payload.put("method", method); - if (params != null) { - payload.put("params", params); - } - Log.d(TAG, "Parcel payload: " + payload.toString()); - ret.writeString(payload.toString()); - return ret; - } -} diff --git a/androidservice/java/io/guh/nymeaapp/NymeaHost.java b/androidservice/java/io/guh/nymeaapp/NymeaHost.java deleted file mode 100644 index a568563c..00000000 --- a/androidservice/java/io/guh/nymeaapp/NymeaHost.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.guh.nymeaapp; - -import java.util.HashMap; -import java.util.ArrayList; -import java.util.UUID; - -public class NymeaHost { - - UUID id; - boolean isReady = false; - String name = ""; - HashMap things = new HashMap(); -} diff --git a/androidservice/java/io/guh/nymeaapp/State.java b/androidservice/java/io/guh/nymeaapp/State.java deleted file mode 100644 index 5b7053ea..00000000 --- a/androidservice/java/io/guh/nymeaapp/State.java +++ /dev/null @@ -1,10 +0,0 @@ -package io.guh.nymeaapp; - -import java.util.UUID; - -public class State { - public UUID typeId; - public String name; - public String displayName; - public String value; -} diff --git a/androidservice/java/io/guh/nymeaapp/Thing.java b/androidservice/java/io/guh/nymeaapp/Thing.java deleted file mode 100644 index e5667831..00000000 --- a/androidservice/java/io/guh/nymeaapp/Thing.java +++ /dev/null @@ -1,56 +0,0 @@ -package io.guh.nymeaapp; - -import android.util.Log; - -import java.util.List; -import java.util.ArrayList; -import java.util.UUID; - - -public class Thing { - static final public String TAG = "nymea-app: Thing"; - public UUID id; - public String name; - public String className; - public List interfaces = new ArrayList(); - - public ArrayList states = new ArrayList(); - public ArrayList actions = new ArrayList(); - - public State stateByName(String name) { - for (int i = 0; i < states.size(); i++) { - if (states.get(i).name.equals(name)) { - return states.get(i); - } - } - return null; - } - - public State stateById(UUID stateTypeId) { - for (int i = 0; i < states.size(); i++) { - if (states.get(i).typeId.equals(stateTypeId)) { - return states.get(i); - } - } - return null; - } - - public Action actionByName(String name) { - for (int i = 0; i < actions.size(); i++) { - Log.d(TAG, "Thing has action: " + actions.get(i).name); - if (actions.get(i).name.equals(name)) { - return actions.get(i); - } - } - return null; - } - - public Action actionById(UUID actionTypeId) { - for (int i = 0; i < actions.size(); i++) { - if (actions.get(i).typeId.equals(actionTypeId)) { - return actions.get(i); - } - } - return null; - } -} diff --git a/androidservice/nymeaappservice/androidbinder.cpp b/androidservice/nymeaappservice/androidbinder.cpp deleted file mode 100644 index 6a82781b..00000000 --- a/androidservice/nymeaappservice/androidbinder.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "androidbinder.h" -#include "engine.h" -#include "types/thing.h" - -#include -#include -#include -#include -#include - -AndroidBinder::AndroidBinder(NymeaAppService *service): - m_service(service) -{ -} - -bool AndroidBinder::onTransact(int code, const QAndroidParcel &data, const QAndroidParcel &reply, QAndroidBinder::CallType flags) -{ - qDebug() << "onTransact: code " << code << ", flags " << int(flags); - -// QString payload = data.readData(); - QString payload = data.handle().callObjectMethod("readString").toString(); - - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(payload.toUtf8(), &error); - if (error.error != QJsonParseError::NoError) { - qWarning() << "Error parsing JSON from parcel:" << error.errorString(); - qWarning() << payload; - return false; - } - QVariantMap request = jsonDoc.toVariant().toMap(); - - if (request.value("method").toString() == "GetInstances") { - QVariantMap params; - QVariantList instances; - foreach (const QUuid &nymeaId, m_service->engines().keys()) { - Engine *engine = m_service->engines().value(nymeaId); - QVariantMap instance; - instance.insert("id", nymeaId); - instance.insert("isReady", engine->jsonRpcClient()->connected() && !engine->thingManager()->fetchingData()); - instance.insert("name", engine->jsonRpcClient()->currentHost()->name()); - instances.append(instance); - } - params.insert("instances", instances); - sendReply(reply, params); - return true; - } - - if (request.value("method").toString() == "GetThings") { - QUuid nymeaId = request.value("params").toMap().value("nymeaId").toUuid(); - Engine *engine = m_service->engines().value(nymeaId); - if (!engine) { - qWarning() << "Android client requested things for an invalid nymea instance:" << nymeaId; - return false; - } - QVariantList thingsList; - for (int i = 0; i < engine->thingManager()->things()->rowCount(); i++) { - Thing *thing = engine->thingManager()->things()->get(i); - QVariantMap thingMap; - thingMap.insert("id", thing->id()); - thingMap.insert("name", thing->name()); - thingMap.insert("className", thing->thingClass()->displayName()); - thingMap.insert("interfaces", thing->thingClass()->interfaces()); - QVariantList states; - for (int j = 0; j < thing->states()->rowCount(); j++) { - State *state = thing->states()->get(j); - QVariantMap stateMap; - stateMap.insert("stateTypeId", state->stateTypeId()); - stateMap.insert("name", thing->thingClass()->stateTypes()->getStateType(state->stateTypeId())->name()); - stateMap.insert("displayName", thing->thingClass()->stateTypes()->getStateType(state->stateTypeId())->displayName()); - stateMap.insert("value", state->value()); - states.append(stateMap); - } - thingMap.insert("states", states); - QVariantList actions; - for (int j = 0; j < thing->thingClass()->actionTypes()->rowCount(); j++) { - ActionType *actionType = thing->thingClass()->actionTypes()->get(j); - QVariantMap actionMap; - actionMap.insert("actionTypeId", actionType->id()); - actionMap.insert("name", actionType->name()); - actionMap.insert("displayName", actionType->displayName()); - actions.append(actionMap); - } - thingMap.insert("actions", actions); - thingsList.append(thingMap); - } - QVariantMap params; - params.insert("things", thingsList); - sendReply(reply, params); - return true; - } - - if (request.value("method").toString() == "ExecuteAction") { - qDebug() << "ExecuteAction"; - QUuid nymeaId = request.value("params").toMap().value("nymeaId").toUuid(); - Engine *engine = m_service->engines().value(nymeaId); - if (!engine) { - qWarning() << "Android client requested executeAction for an invalid nymea instance:" << nymeaId; - return false; - } - QUuid thingId = request.value("params").toMap().value("thingId").toUuid(); - QUuid actionTypeId = request.value("params").toMap().value("actionTypeId").toUuid(); - QVariantList params = request.value("params").toMap().value("params").toList(); - - qDebug() << "**** executeAction:" << thingId << actionTypeId << params; - engine->thingManager()->executeAction(thingId, actionTypeId, params); - } - - return false; -} - -void AndroidBinder::sendReply(const QAndroidParcel &reply, const QVariantMap ¶ms) -{ - QString payload = QJsonDocument::fromVariant(params).toJson(); - reply.handle().callMethod("writeString", "(Ljava/lang/String;)V", QJniObject::fromString(payload).object()); -} diff --git a/androidservice/nymeaappservice/androidbinder.h b/androidservice/nymeaappservice/androidbinder.h deleted file mode 100644 index 36a9b795..00000000 --- a/androidservice/nymeaappservice/androidbinder.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef ANDROIDBINDER_H -#define ANDROIDBINDER_H - -#include - -#include "nymeaappservice.h" -#include "engine.h" - -class AndroidBinder : public QAndroidBinder -{ -public: - explicit AndroidBinder(NymeaAppService *service); - - bool onTransact(int code, const QAndroidParcel &data, const QAndroidParcel &reply, QAndroidBinder::CallType flags) override; - -private: - void sendReply(const QAndroidParcel &reply, const QVariantMap ¶ms); - -private: - NymeaAppService *m_service = nullptr; -}; - -#endif // ANDROIDBINDER_H diff --git a/androidservice/nymeaappservice/nymeaappservice.cpp b/androidservice/nymeaappservice/nymeaappservice.cpp deleted file mode 100644 index cfb04866..00000000 --- a/androidservice/nymeaappservice/nymeaappservice.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "nymeaappservice.h" -#include "androidbinder.h" - -#include -#include -#include -#include - -#include "connection/discovery/nymeadiscovery.h" -#include "connection/nymeahosts.h" - -NymeaAppService::NymeaAppService(int argc, char **argv): - QAndroidService(argc, argv, [=](const QAndroidIntent &) { - return new AndroidBinder{this}; - }) -{ - setApplicationName("nymea-app"); - setOrganizationName("nymea"); - - QSettings settings; - - NymeaDiscovery *discovery = new NymeaDiscovery(this); - - settings.beginGroup("ConfiguredHosts"); - foreach (const QString &childGroup, settings.childGroups()) { - settings.beginGroup(childGroup); - QUuid lastConnected = settings.value("uuid").toUuid(); - QString cachedName = settings.value("cachedName").toString(); - settings.endGroup(); - - if (lastConnected.isNull()) { - continue; - } - NymeaHost *host = discovery->nymeaHosts()->find(lastConnected); - if (!host) { - continue; - } - - Engine *engine = new Engine(this); - engine->jsonRpcClient()->connectToHost(host); - m_engines.insert(host->uuid(), engine); - - - QObject::connect(engine->thingManager(), &ThingManager::thingStateChanged, [=](const QUuid &thingId, const QUuid &stateTypeId, const QVariant &value){ - QVariantMap params; - params.insert("nymeaId", engine->jsonRpcClient()->currentHost()->uuid()); - params.insert("thingId", thingId); - params.insert("stateTypeId", stateTypeId); - params.insert("value", value); - sendNotification("ThingStateChanged", params); - }); - - connect(engine->thingManager(), &ThingManager::fetchingDataChanged, [=]() { - qDebug() << "Fetching data changed"; - QVariantMap params; - params.insert("nymeaId", engine->jsonRpcClient()->currentHost()->uuid()); - params.insert("isReady", !engine->thingManager()->fetchingData()); - qDebug() << "Nymea host is ready" << engine->jsonRpcClient()->currentHost()->uuid(); - sendNotification("ReadyStateChanged", params); - }); - } - settings.endGroup(); - - qDebug() << "NymeaAppService started."; - -} - -QHash NymeaAppService::engines() const -{ - return m_engines; -} - -void NymeaAppService::sendNotification(const QString ¬ification, const QVariantMap ¶ms) -{ - QVariantMap data; - data.insert("notification", notification); - data.insert("params", params); - QString payload = QJsonDocument::fromVariant(data).toJson(); - QtAndroid::androidService().callMethod("sendBroadcast", - "(Ljava/lang/String;)V", - QJniObject::fromString(payload).object()); - -} diff --git a/androidservice/nymeaappservice/nymeaappservice.h b/androidservice/nymeaappservice/nymeaappservice.h deleted file mode 100644 index 093f9e60..00000000 --- a/androidservice/nymeaappservice/nymeaappservice.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef NYMEAAPPSERVICE_H -#define NYMEAAPPSERVICE_H - -#include -#include -#include - -#include "engine.h" - -class NymeaAppService : public QAndroidService -{ - Q_OBJECT -public: - explicit NymeaAppService(int argc, char** argv); - - QHash engines() const; - -private: - void sendNotification(const QString ¬ification, const QVariantMap ¶ms); - - -private: - QHash m_engines; - -}; - -#endif // NYMEAAPPSERVICE_H diff --git a/androidservice/service_main.cpp b/androidservice/service_main.cpp deleted file mode 100644 index 46efab22..00000000 --- a/androidservice/service_main.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include - -#include "nymeaappservice/nymeaappservice.h" -#include "controlviews/devicecontrolapplication.h" - -#include -#include - -int main(int argc, char *argv[]) -{ - qWarning() << "Service starting from a separate .so file"; - - QLoggingCategory::setFilterRules("qt.remoteobjects.debug=true\n"); - - QStringList args; - for (int i = 0; i < argc; i++) { - args.append(QByteArray(argv[i])); - qDebug() << "nymea-app: Added command line arg" << args.last(); - } - QCommandLineParser parser; - QCommandLineOption controlActivityOption("controlActivity"); - parser.addOption(controlActivityOption); - parser.parse(args); - - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - - QCoreApplication *app; - if (parser.isSet(controlActivityOption)) { - qDebug() << "nymea-app: Starting Device Control Activity"; - app = new DeviceControlApplication(argc, argv); - } else { - qDebug() << "nymea-app: Starting NymeaAppService background service"; - app = new NymeaAppService(argc, argv); - } - return app->exec(); -}