diff --git a/sbapp/main.py b/sbapp/main.py index 016859d..59524b8 100644 --- a/sbapp/main.py +++ b/sbapp/main.py @@ -5,10 +5,12 @@ import sys import os import plyer import base64 +import threading from kivy.logger import Logger, LOG_LEVELS -# Logger.setLevel(LOG_LEVELS["debug"]) -Logger.setLevel(LOG_LEVELS["error"]) +# TODO: Reset +Logger.setLevel(LOG_LEVELS["debug"]) +# Logger.setLevel(LOG_LEVELS["error"]) if RNS.vendor.platformutils.get_platform() != "android": local = os.path.dirname(__file__) @@ -61,12 +63,22 @@ class SidebandApp(MDApp): PAUSED = 0x02 STOPPING = 0x03 + PKGNAME = "io.unsigned.sideband" + def __init__(self, **kwargs): super().__init__(**kwargs) self.title = "Sideband" 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 @@ -81,7 +93,8 @@ class SidebandApp(MDApp): self.notification_icon = self.sideband.asset_dir+"/notification_icon.png" def start_core(self, dt): - self.sideband.start() + self.start_service() + self.open_conversations() Clock.schedule_interval(self.jobs, 1) @@ -97,14 +110,27 @@ class SidebandApp(MDApp): 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": - 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): - service = autoclass('io.unsigned.sideband.ServiceSidebandservice') - mActivity = autoclass('org.kivy.android.PythonActivity').mActivity - argument = "" - service.start(mActivity, argument) + # TODO: Remove and add real service started check here + RNS.log("Service instance: "+str(self.android_service)) + RNS.log("Waiting for service start") + time.sleep(7) + + # Start local core instance + # TODO: Remove log + RNS.log("Starting local core") + self.sideband.start() + + else: + self.sideband.start() ################################################# diff --git a/sbapp/services/sidebandservice.py b/sbapp/services/sidebandservice.py index b3625d3..89e87d5 100644 --- a/sbapp/services/sidebandservice.py +++ b/sbapp/services/sidebandservice.py @@ -1,58 +1,83 @@ import time import RNS -from sideband.core import SidebandCore 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): pass - def start(self): - pass - - def stop(self): - pass - - def restart(self): - self.stop() - self.start() - -class sidebandservice(): +class SidebandService(): def __init__(self): self.argument = environ.get('PYTHON_SERVICE_ARGUMENT', '') + self.app_dir = self.argument self.multicast_lock = None self.wake_lock = None + self.should_run = False - self.service = autoclass('org.kivy.android.PythonService').mService - 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 + self.app_proxy = AppProxy() + + 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 - print("Sideband Service created") + # 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.run() - def take_locks(self): - if self.multicast_lock == None: - self.multicast_lock = self.wifi_manager.createMulticastLock("sideband_service") + def stop(self): + self.should_run = False - if not self.multicast_lock.isHeld(): - RNS.log("Taking multicast lock") - self.multicast_lock.acquire() - RNS.log("Took lock") + def take_locks(self): + if RNS.vendor.platformutils.get_platform() == "android": + if self.multicast_lock == None: + 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(): - if not self.multicast_lock == None and self.multicast_lock.isHeld(): - self.multicast_lock.release() + if RNS.vendor.platformutils.get_platform() == "android": + if not self.multicast_lock == None and self.multicast_lock.isHeld(): + self.multicast_lock.release() def run(self): - while True: - print("Service ping") - time.sleep(5) + while self.should_run: + time.sleep(1) -sbs = sidebandservice() \ No newline at end of file + self.release_locks() + +sbs = SidebandService() +sbs.start() + +# TODO: Remove +print("SBS: Service thread done") +RNS.log("Service thread done") \ No newline at end of file diff --git a/sbapp/sideband/core.py b/sbapp/sideband/core.py index c504696..eed9460 100644 --- a/sbapp/sideband/core.py +++ b/sbapp/sideband/core.py @@ -66,15 +66,29 @@ class SidebandCore(): # stream logger 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.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 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" if not os.path.isdir(self.app_dir+"/app_storage"): @@ -410,7 +424,6 @@ class SidebandCore(): return convs - def _db_announces(self): db = sqlite3.connect(self.db_path) dbc = db.cursor() @@ -438,7 +451,6 @@ class SidebandCore(): return announces - def _db_conversation(self, context_dest): db = sqlite3.connect(self.db_path) dbc = db.cursor() @@ -464,7 +476,6 @@ class SidebandCore(): conv["data"] = msgpack.unpackb(c[7]) return conv - def _db_clear_conversation(self, context_dest): RNS.log("Clearing conversation with "+RNS.prettyhexrep(context_dest)) db = sqlite3.connect(self.db_path) @@ -624,7 +635,6 @@ class SidebandCore(): return messages - def _db_save_lxm(self, lxm, context_dest): state = lxm.state @@ -702,6 +712,7 @@ class SidebandCore(): def __start_jobs_deferred(self): if self.config["start_announce"]: + # TODO: (Service) Handle this in service self.lxmf_destination.announce() def __start_jobs_immediate(self): @@ -817,14 +828,19 @@ class SidebandCore(): RNS.log("Error while adding I2P Interface. The contained exception was: "+str(e)) self.interface_i2p = None - RNS.log("Reticulum started, activating LXMF...") - self.message_router = LXMF.LXMRouter(identity = self.identity, storagepath = self.lxmf_storage, autopeer = True) - self.message_router.register_delivery_callback(self.lxmf_delivery) + if self.is_service or self.is_standalone: + RNS.log("Reticulum started, activating LXMF...") + 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.set_default_app_data(self.get_display_name_bytes) + 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.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"] != "": self.set_active_propagation_node(self.config["lxmf_propagation_node"]) diff --git a/setup.py b/setup.py index dd1ded6..cf05c39 100644 --- a/setup.py +++ b/setup.py @@ -58,6 +58,6 @@ setuptools.setup( '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', )