From 0de6b2d1d0f7a6035c1df02adb2b934e2baeb3a2 Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Thu, 20 Nov 2025 23:30:57 +0100 Subject: [PATCH] Added ability to start Sideband at device boot on Android --- sbapp/buildozer.spec | 2 +- sbapp/main.py | 14 ++++++++++---- sbapp/patches/AndroidManifest.tmpl.xml | 6 ++++++ sbapp/patches/PythonService.java | 24 ++++++++++++++++++++++++ sbapp/sideband/core.py | 11 +++++++++-- sbapp/ui/layouts.py | 15 +++++++++++++++ 6 files changed, 65 insertions(+), 7 deletions(-) diff --git a/sbapp/buildozer.spec b/sbapp/buildozer.spec index 5d5af68..ca77da4 100644 --- a/sbapp/buildozer.spec +++ b/sbapp/buildozer.spec @@ -29,7 +29,7 @@ android.presplash_color = #00000000 orientation = portrait fullscreen = 0 -android.permissions = INTERNET,POST_NOTIFICATIONS,WAKE_LOCK,FOREGROUND_SERVICE,CHANGE_WIFI_MULTICAST_STATE,BLUETOOTH_SCAN,BLUETOOTH_ADVERTISE,BLUETOOTH_CONNECT,ACCESS_NETWORK_STATE,ACCESS_FINE_LOCATION,ACCESS_COARSE_LOCATION,MANAGE_EXTERNAL_STORAGE,ACCESS_BACKGROUND_LOCATION,RECORD_AUDIO,REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,FOREGROUND_SERVICE_CONNECTED_DEVICE,MODIFY_AUDIO_SETTINGS +android.permissions = INTERNET,POST_NOTIFICATIONS,WAKE_LOCK,FOREGROUND_SERVICE,CHANGE_WIFI_MULTICAST_STATE,BLUETOOTH_SCAN,BLUETOOTH_ADVERTISE,BLUETOOTH_CONNECT,ACCESS_NETWORK_STATE,ACCESS_FINE_LOCATION,ACCESS_COARSE_LOCATION,MANAGE_EXTERNAL_STORAGE,ACCESS_BACKGROUND_LOCATION,RECORD_AUDIO,REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,FOREGROUND_SERVICE_CONNECTED_DEVICE,MODIFY_AUDIO_SETTINGS,RECEIVE_BOOT_COMPLETED android.api = 33 android.minapi = 24 diff --git a/sbapp/main.py b/sbapp/main.py index b16f5c0..7787f9a 100644 --- a/sbapp/main.py +++ b/sbapp/main.py @@ -3592,6 +3592,10 @@ class SidebandApp(MDApp): self.sideband.start_voice() else: self.sideband.stop_voice() + def save_start_at_boot(sender=None, event=None): + self.sideband.config["start_at_boot"] = self.settings_screen.ids.settings_start_at_boot.active + self.sideband.save_configuration() + def save_print_command(sender=None, event=None): if not sender.focus: in_cmd = self.settings_screen.ids.settings_print_command.text @@ -3671,11 +3675,10 @@ class SidebandApp(MDApp): else: self.settings_screen.ids.settings_print_command.text = self.sideband.config["print_command"] self.settings_screen.ids.settings_print_command.bind(focus=save_print_command) + self.settings_screen.ids.settings_start_at_boot.disabled = True - if self.sideband.config["lxmf_propagation_node"] == None: - prop_node_addr = "" - else: - prop_node_addr = RNS.hexrep(self.sideband.config["lxmf_propagation_node"], delimit=False) + if self.sideband.config["lxmf_propagation_node"] == None: prop_node_addr = "" + else: prop_node_addr = RNS.hexrep(self.sideband.config["lxmf_propagation_node"], delimit=False) self.settings_screen.ids.settings_propagation_node_address.text = prop_node_addr self.settings_screen.ids.settings_propagation_node_address.bind(focus=save_prop_addr) @@ -3705,6 +3708,9 @@ class SidebandApp(MDApp): self.settings_screen.ids.settings_advanced_statistics.active = self.sideband.config["advanced_stats"] self.settings_screen.ids.settings_advanced_statistics.bind(active=save_advanced_stats) + self.settings_screen.ids.settings_start_at_boot.active = self.sideband.config["start_at_boot"] + self.settings_screen.ids.settings_start_at_boot.bind(active=save_start_at_boot) + self.settings_screen.ids.settings_start_announce.active = self.sideband.config["start_announce"] self.settings_screen.ids.settings_start_announce.bind(active=save_start_announce) diff --git a/sbapp/patches/AndroidManifest.tmpl.xml b/sbapp/patches/AndroidManifest.tmpl.xml index c6cdd64..9ff83ec 100644 --- a/sbapp/patches/AndroidManifest.tmpl.xml +++ b/sbapp/patches/AndroidManifest.tmpl.xml @@ -121,6 +121,12 @@ {% endfor %} + + + + + + {% if args.billing_pubkey %} diff --git a/sbapp/patches/PythonService.java b/sbapp/patches/PythonService.java index ad7142c..72e853c 100644 --- a/sbapp/patches/PythonService.java +++ b/sbapp/patches/PythonService.java @@ -25,8 +25,32 @@ import android.graphics.drawable.Icon; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.MulticastLock; +import java.util.Objects; +import android.content.BroadcastReceiver; + +import io.unsigned.sideband.ServiceSidebandservice; + public class PythonService extends Service implements Runnable { + public static class ServiceBootReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + try { + if (Objects.equals(intent.getAction(), "android.intent.action.BOOT_COMPLETED")) { + boolean should_start = false; + String app_dir = context.getFilesDir().getParentFile().getParent(); + String toggle_path = context.getFilesDir()+"/app_storage/"; + File file = new File(toggle_path, "boot_toggle"); + if (file.exists()) { should_start = true; } + if (should_start) { + ServiceSidebandservice svc = new ServiceSidebandservice(); + svc.start(context, app_dir); + } + } + } catch (Exception e) { Log.e("sidebandservice", "Could not start Sideband service at boot: "+e); } + } + } + // Thread for Python code private Thread pythonThread = null; diff --git a/sbapp/sideband/core.py b/sbapp/sideband/core.py index 2aaf717..ba30abe 100644 --- a/sbapp/sideband/core.py +++ b/sbapp/sideband/core.py @@ -623,6 +623,7 @@ class SidebandCore(): if not "debug" in self.config: self.config["debug"] = False if not "dark_ui" in self.config: self.config["dark_ui"] = True if not "advanced_stats" in self.config: self.config["advanced_stats"] = True + if not "start_at_boot" in self.config: self.config["start_at_boot"] = False if not "lxmf_periodic_sync" in self.config: self.config["lxmf_periodic_sync"] = False if not "lxmf_ignore_unknown" in self.config: self.config["lxmf_ignore_unknown"] = False if not "lxmf_sync_interval" in self.config: self.config["lxmf_sync_interval"] = 43200 @@ -807,9 +808,15 @@ class SidebandCore(): time.sleep(0.15) try: self.saving_configuration = True - with open(self.config_path, "wb") as config_file: - config_file.write(msgpack.packb(self.config)) + with open(self.config_path, "wb") as config_file: config_file.write(msgpack.packb(self.config)) self.saving_configuration = False + if RNS.vendor.platformutils.is_android(): + boot_toggle_path = self.app_dir+"/app_storage/boot_toggle" + boot_toggle_exists = os.path.isfile(boot_toggle_path) + if self.config["start_at_boot"] == True and not boot_toggle_exists: + with open(boot_toggle_path, "w") as f: f.write("true") + elif self.config["start_at_boot"] == False and boot_toggle_exists: + os.unlink(boot_toggle_path) except Exception as e: self.saving_configuration = False RNS.log("Error while saving Sideband configuration: "+str(e), RNS.LOG_ERROR) diff --git a/sbapp/ui/layouts.py b/sbapp/ui/layouts.py index bcd2329..4909255 100644 --- a/sbapp/ui/layouts.py +++ b/sbapp/ui/layouts.py @@ -1666,6 +1666,21 @@ MDScreen: pos_hint: {"center_y": 0.3} active: False + MDBoxLayout: + orientation: "horizontal" + size_hint_y: None + padding: [0,0,dp(24),dp(0)] + height: dp(48) + + MDLabel: + text: "Start at boot" + font_style: "H6" + + MDSwitch: + id: settings_start_at_boot + pos_hint: {"center_y": 0.3} + active: False + MDLabel: text: "•" font_style: "H6"