Added basic structure for android service proxy

This commit is contained in:
Mark Qvist 2022-10-01 11:18:14 +02:00
parent 48d7dda21b
commit e1d7c2c12c
4 changed files with 124 additions and 57 deletions

View File

@ -5,10 +5,12 @@ import sys
import os import os
import plyer import plyer
import base64 import base64
import threading
from kivy.logger import Logger, LOG_LEVELS from kivy.logger import Logger, LOG_LEVELS
# Logger.setLevel(LOG_LEVELS["debug"]) # TODO: Reset
Logger.setLevel(LOG_LEVELS["error"]) Logger.setLevel(LOG_LEVELS["debug"])
# Logger.setLevel(LOG_LEVELS["error"])
if RNS.vendor.platformutils.get_platform() != "android": if RNS.vendor.platformutils.get_platform() != "android":
local = os.path.dirname(__file__) local = os.path.dirname(__file__)
@ -61,12 +63,22 @@ class SidebandApp(MDApp):
PAUSED = 0x02 PAUSED = 0x02
STOPPING = 0x03 STOPPING = 0x03
PKGNAME = "io.unsigned.sideband"
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.title = "Sideband" self.title = "Sideband"
self.app_state = SidebandApp.STARTING self.app_state = SidebandApp.STARTING
self.android_service = None
self.sideband = SidebandCore(self) self.app_dir = plyer.storagepath.get_application_dir()
# TODO: Remove
RNS.log("Application directory is: "+str(self.app_dir))
if RNS.vendor.platformutils.get_platform() == "android":
self.sideband = SidebandCore(self, is_client=True, android_app_dir=self.app_dir)
else:
self.sideband = SidebandCore(self, is_client=False)
self.conversations_view = None self.conversations_view = None
@ -81,7 +93,8 @@ class SidebandApp(MDApp):
self.notification_icon = self.sideband.asset_dir+"/notification_icon.png" self.notification_icon = self.sideband.asset_dir+"/notification_icon.png"
def start_core(self, dt): def start_core(self, dt):
self.sideband.start() self.start_service()
self.open_conversations() self.open_conversations()
Clock.schedule_interval(self.jobs, 1) Clock.schedule_interval(self.jobs, 1)
@ -97,14 +110,27 @@ class SidebandApp(MDApp):
self.app_state = SidebandApp.ACTIVE self.app_state = SidebandApp.ACTIVE
def start_service(self):
RNS.log("Launching platform service for RNS and LXMF")
if RNS.vendor.platformutils.get_platform() == "android": if RNS.vendor.platformutils.get_platform() == "android":
self.start_android_service() # TODO: Check if service is running and start as necessary
self.android_service = autoclass('io.unsigned.sideband.ServiceSidebandservice')
mActivity = autoclass('org.kivy.android.PythonActivity').mActivity
argument = self.app_dir
self.android_service.start(mActivity, argument)
def start_android_service(self): # TODO: Remove and add real service started check here
service = autoclass('io.unsigned.sideband.ServiceSidebandservice') RNS.log("Service instance: "+str(self.android_service))
mActivity = autoclass('org.kivy.android.PythonActivity').mActivity RNS.log("Waiting for service start")
argument = "" time.sleep(7)
service.start(mActivity, argument)
# Start local core instance
# TODO: Remove log
RNS.log("Starting local core")
self.sideband.start()
else:
self.sideband.start()
################################################# #################################################

View File

@ -1,58 +1,83 @@
import time import time
import RNS import RNS
from sideband.core import SidebandCore
from os import environ from os import environ
from jnius import autoclass, cast
Context = autoclass('android.content.Context') from kivy.logger import Logger, LOG_LEVELS
# TODO: Reset
Logger.setLevel(LOG_LEVELS["debug"])
# Logger.setLevel(LOG_LEVELS["error"])
class RnsService(): if RNS.vendor.platformutils.get_platform() == "android":
from jnius import autoclass, cast
Context = autoclass('android.content.Context')
from sideband.core import SidebandCore
else:
from sbapp.sideband.core import SidebandCore
class AppProxy():
def __init__(self): def __init__(self):
pass pass
def start(self): class SidebandService():
pass
def stop(self):
pass
def restart(self):
self.stop()
self.start()
class sidebandservice():
def __init__(self): def __init__(self):
self.argument = environ.get('PYTHON_SERVICE_ARGUMENT', '') self.argument = environ.get('PYTHON_SERVICE_ARGUMENT', '')
self.app_dir = self.argument
self.multicast_lock = None self.multicast_lock = None
self.wake_lock = None self.wake_lock = None
self.should_run = False
self.service = autoclass('org.kivy.android.PythonService').mService self.app_proxy = AppProxy()
self.app_context = self.service.getApplication().getApplicationContext()
self.wifi_manager = self.app_context.getSystemService(Context.WIFI_SERVICE)
# The returned instance is an android.net.wifi.WifiManager
print("Sideband Service created") self.android_service = None
self.app_context = None
self.wifi_manager = None
if RNS.vendor.platformutils.get_platform() == "android":
self.android_service = autoclass('org.kivy.android.PythonService').mService
self.app_context = self.android_service.getApplication().getApplicationContext()
self.wifi_manager = self.app_context.getSystemService(Context.WIFI_SERVICE)
# The returned instance is an android.net.wifi.WifiManager
# TODO: Remove?
RNS.log("Sideband background service created, starting core...", RNS.LOG_DEBUG)
self.sideband = SidebandCore(self.app_proxy, is_service=True, android_app_dir=self.app_dir)
self.sideband.start()
def start(self):
self.should_run = True
self.take_locks() self.take_locks()
self.run() self.run()
def take_locks(self): def stop(self):
if self.multicast_lock == None: self.should_run = False
self.multicast_lock = self.wifi_manager.createMulticastLock("sideband_service")
if not self.multicast_lock.isHeld(): def take_locks(self):
RNS.log("Taking multicast lock") if RNS.vendor.platformutils.get_platform() == "android":
self.multicast_lock.acquire() if self.multicast_lock == None:
RNS.log("Took lock") self.multicast_lock = self.wifi_manager.createMulticastLock("sideband_service")
if not self.multicast_lock.isHeld():
RNS.log("Taking multicast lock")
self.multicast_lock.acquire()
RNS.log("Took lock")
def release_locks(): def release_locks():
if not self.multicast_lock == None and self.multicast_lock.isHeld(): if RNS.vendor.platformutils.get_platform() == "android":
self.multicast_lock.release() if not self.multicast_lock == None and self.multicast_lock.isHeld():
self.multicast_lock.release()
def run(self): def run(self):
while True: while self.should_run:
print("Service ping") time.sleep(1)
time.sleep(5)
sbs = sidebandservice() self.release_locks()
sbs = SidebandService()
sbs.start()
# TODO: Remove
print("SBS: Service thread done")
RNS.log("Service thread done")

View File

@ -66,15 +66,29 @@ class SidebandCore():
# stream logger # stream logger
self.log_announce(destination_hash, app_data, dest_type=SidebandCore.aspect_filter) self.log_announce(destination_hash, app_data, dest_type=SidebandCore.aspect_filter)
def __init__(self, owner_app): def __init__(self, owner_app, is_service=False, is_client=False, android_app_dir=None):
self.is_service = is_service
self.is_client = is_client
if not self.is_service and not self.is_client:
self.is_standalone = True
else:
self.is_standalone = False
if self.is_client:
from .serviceproxy import ServiceProxy
self.serviceproxy = ServiceProxy(self)
else:
self.serviceproxy = None
self.owner_app = owner_app self.owner_app = owner_app
self.reticulum = None self.reticulum = None
self.app_dir = plyer.storagepath.get_home_dir()+"/.sideband" self.app_dir = plyer.storagepath.get_home_dir()+"/.config/sideband"
self.rns_configdir = None self.rns_configdir = None
if RNS.vendor.platformutils.get_platform() == "android": if RNS.vendor.platformutils.get_platform() == "android":
self.app_dir = plyer.storagepath.get_application_dir()+"/io.unsigned.sideband/files/" self.app_dir = android_app_dir+"/io.unsigned.sideband/files/"
self.rns_configdir = self.app_dir+"/app_storage/reticulum" self.rns_configdir = self.app_dir+"/app_storage/reticulum"
if not os.path.isdir(self.app_dir+"/app_storage"): if not os.path.isdir(self.app_dir+"/app_storage"):
@ -410,7 +424,6 @@ class SidebandCore():
return convs return convs
def _db_announces(self): def _db_announces(self):
db = sqlite3.connect(self.db_path) db = sqlite3.connect(self.db_path)
dbc = db.cursor() dbc = db.cursor()
@ -438,7 +451,6 @@ class SidebandCore():
return announces return announces
def _db_conversation(self, context_dest): def _db_conversation(self, context_dest):
db = sqlite3.connect(self.db_path) db = sqlite3.connect(self.db_path)
dbc = db.cursor() dbc = db.cursor()
@ -464,7 +476,6 @@ class SidebandCore():
conv["data"] = msgpack.unpackb(c[7]) conv["data"] = msgpack.unpackb(c[7])
return conv return conv
def _db_clear_conversation(self, context_dest): def _db_clear_conversation(self, context_dest):
RNS.log("Clearing conversation with "+RNS.prettyhexrep(context_dest)) RNS.log("Clearing conversation with "+RNS.prettyhexrep(context_dest))
db = sqlite3.connect(self.db_path) db = sqlite3.connect(self.db_path)
@ -624,7 +635,6 @@ class SidebandCore():
return messages return messages
def _db_save_lxm(self, lxm, context_dest): def _db_save_lxm(self, lxm, context_dest):
state = lxm.state state = lxm.state
@ -702,6 +712,7 @@ class SidebandCore():
def __start_jobs_deferred(self): def __start_jobs_deferred(self):
if self.config["start_announce"]: if self.config["start_announce"]:
# TODO: (Service) Handle this in service
self.lxmf_destination.announce() self.lxmf_destination.announce()
def __start_jobs_immediate(self): def __start_jobs_immediate(self):
@ -817,14 +828,19 @@ class SidebandCore():
RNS.log("Error while adding I2P Interface. The contained exception was: "+str(e)) RNS.log("Error while adding I2P Interface. The contained exception was: "+str(e))
self.interface_i2p = None self.interface_i2p = None
RNS.log("Reticulum started, activating LXMF...") if self.is_service or self.is_standalone:
self.message_router = LXMF.LXMRouter(identity = self.identity, storagepath = self.lxmf_storage, autopeer = True) RNS.log("Reticulum started, activating LXMF...")
self.message_router.register_delivery_callback(self.lxmf_delivery) self.message_router = LXMF.LXMRouter(identity = self.identity, storagepath = self.lxmf_storage, autopeer = True)
self.message_router.register_delivery_callback(self.lxmf_delivery)
self.lxmf_destination = self.message_router.register_delivery_identity(self.identity, display_name=self.config["display_name"]) self.lxmf_destination = self.message_router.register_delivery_identity(self.identity, display_name=self.config["display_name"])
self.lxmf_destination.set_default_app_data(self.get_display_name_bytes) self.lxmf_destination.set_default_app_data(self.get_display_name_bytes)
self.rns_dir = RNS.Reticulum.configdir self.rns_dir = RNS.Reticulum.configdir
else:
self.message_router = self.serviceproxy
self.lxmf_destination = self.serviceproxy
if self.config["lxmf_propagation_node"] != None and self.config["lxmf_propagation_node"] != "": if self.config["lxmf_propagation_node"] != None and self.config["lxmf_propagation_node"] != "":
self.set_active_propagation_node(self.config["lxmf_propagation_node"]) self.set_active_propagation_node(self.config["lxmf_propagation_node"])

View File

@ -58,6 +58,6 @@ setuptools.setup(
'sideband=sbapp:main.run', 'sideband=sbapp:main.run',
] ]
}, },
install_requires=['rns>=0.3.12', 'lxmf>=0.1.7', 'kivy==2.1.0', 'plyer'], install_requires=['rns>=0.3.12', 'lxmf>=0.1.8', 'kivy==2.1.0', 'plyer'],
python_requires='>=3.6', python_requires='>=3.6',
) )