2022-09-17 10:00:55 -04:00
import time
2022-09-20 11:28:39 -04:00
import RNS
from os import environ
2022-10-01 05:18:14 -04:00
from kivy . logger import Logger , LOG_LEVELS
2022-10-02 20:30:21 -04:00
# Logger.setLevel(LOG_LEVELS["debug"])
Logger . setLevel ( LOG_LEVELS [ " error " ] )
2022-09-17 10:00:55 -04:00
2022-10-01 05:18:14 -04:00
if RNS . vendor . platformutils . get_platform ( ) == " android " :
from jnius import autoclass , cast
2022-10-01 19:14:29 -04:00
from android import python_act
2022-10-01 05:18:14 -04:00
Context = autoclass ( ' android.content.Context ' )
2022-10-01 19:14:29 -04:00
Intent = autoclass ( ' android.content.Intent ' )
BitmapFactory = autoclass ( ' android.graphics.BitmapFactory ' )
Icon = autoclass ( " android.graphics.drawable.Icon " )
PendingIntent = autoclass ( ' android.app.PendingIntent ' )
AndroidString = autoclass ( ' java.lang.String ' )
NotificationManager = autoclass ( ' android.app.NotificationManager ' )
Context = autoclass ( ' android.content.Context ' )
NotificationBuilder = autoclass ( ' android.app.Notification$Builder ' )
NotificationChannel = autoclass ( ' android.app.NotificationChannel ' )
2022-10-01 05:18:14 -04:00
from sideband . core import SidebandCore
2022-09-28 07:12:14 -04:00
2022-10-01 05:18:14 -04:00
else :
from sbapp . sideband . core import SidebandCore
2022-09-28 07:12:14 -04:00
2022-10-01 05:18:14 -04:00
class SidebandService ( ) :
2022-10-01 19:14:29 -04:00
def android_notification ( self , title = " " , content = " " , ticker = " " , group = None , context_id = None ) :
package_name = " io.unsigned.sideband "
if not self . notification_service :
self . notification_service = cast ( NotificationManager , self . app_context . getSystemService (
Context . NOTIFICATION_SERVICE
) )
channel_id = package_name
group_id = " "
if group != None :
channel_id + = " . " + str ( group )
group_id + = str ( group )
if context_id != None :
channel_id + = " . " + str ( context_id )
group_id + = " . " + str ( context_id )
if not title or title == " " :
channel_name = " Sideband "
else :
channel_name = title
self . notification_channel = NotificationChannel ( channel_id , channel_name , NotificationManager . IMPORTANCE_DEFAULT )
self . notification_channel . enableVibration ( True )
self . notification_channel . setShowBadge ( True )
self . notification_service . createNotificationChannel ( self . notification_channel )
notification = NotificationBuilder ( self . app_context , channel_id )
notification . setContentTitle ( title )
notification . setContentText ( AndroidString ( content ) )
# if group != None:
# notification.setGroup(group_id)
if not self . notification_small_icon :
path = self . sideband . notification_icon
bitmap = BitmapFactory . decodeFile ( path )
self . notification_small_icon = Icon . createWithBitmap ( bitmap )
notification . setSmallIcon ( self . notification_small_icon )
# large_icon_path = self.sideband.icon
# bitmap_icon = BitmapFactory.decodeFile(large_icon_path)
# notification.setLargeIcon(bitmap_icon)
if not self . notification_intent :
notification_intent = Intent ( self . app_context , python_act )
notification_intent . setFlags ( Intent . FLAG_ACTIVITY_SINGLE_TOP )
notification_intent . setAction ( Intent . ACTION_MAIN )
notification_intent . addCategory ( Intent . CATEGORY_LAUNCHER )
2022-10-01 20:26:58 -04:00
self . notification_intent = PendingIntent . getActivity ( self . app_context , 0 , notification_intent , 0 )
2022-10-01 19:14:29 -04:00
notification . setContentIntent ( self . notification_intent )
notification . setAutoCancel ( True )
built_notification = notification . build ( )
self . notification_service . notify ( 0 , built_notification )
2022-09-17 10:00:55 -04:00
def __init__ ( self ) :
2022-09-20 11:28:39 -04:00
self . argument = environ . get ( ' PYTHON_SERVICE_ARGUMENT ' , ' ' )
2022-10-01 05:18:14 -04:00
self . app_dir = self . argument
2022-09-20 11:28:39 -04:00
self . multicast_lock = None
self . wake_lock = None
2022-10-01 05:18:14 -04:00
self . should_run = False
2022-09-20 11:28:39 -04:00
2022-10-01 05:18:14 -04:00
self . android_service = None
self . app_context = None
self . wifi_manager = None
2022-10-01 20:26:58 -04:00
self . power_manager = None
2022-10-01 05:18:14 -04:00
2022-10-01 19:14:29 -04:00
self . notification_service = None
self . notification_channel = None
self . notification_intent = None
self . notification_small_icon = None
2022-10-01 05:18:14 -04:00
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 )
2022-10-01 20:26:58 -04:00
self . power_manager = self . app_context . getSystemService ( Context . POWER_SERVICE )
2022-10-01 19:14:29 -04:00
# The returned instance /\ is an android.net.wifi.WifiManager
2022-09-20 11:28:39 -04:00
2022-10-01 20:26:58 -04:00
self . sideband = SidebandCore ( self , is_service = True , android_app_dir = self . app_dir )
2022-10-01 19:14:29 -04:00
self . sideband . service_context = self . android_service
self . sideband . owner_service = self
2022-10-01 05:18:14 -04:00
self . sideband . start ( )
2022-10-02 14:43:56 -04:00
self . update_connectivity_type ( )
2022-10-01 05:18:14 -04:00
def start ( self ) :
self . should_run = True
2022-09-20 11:28:39 -04:00
self . take_locks ( )
2022-09-17 10:00:55 -04:00
self . run ( )
2022-10-01 05:18:14 -04:00
def stop ( self ) :
self . should_run = False
2022-09-20 11:28:39 -04:00
def take_locks ( self ) :
2022-10-01 05:18:14 -04:00
if RNS . vendor . platformutils . get_platform ( ) == " android " :
if self . multicast_lock == None :
self . multicast_lock = self . wifi_manager . createMulticastLock ( " sideband_service " )
2022-09-20 11:28:39 -04:00
2022-10-01 05:18:14 -04:00
if not self . multicast_lock . isHeld ( ) :
RNS . log ( " Taking multicast lock " )
self . multicast_lock . acquire ( )
2022-09-20 11:28:39 -04:00
2022-10-01 20:26:58 -04:00
if self . wake_lock == None :
self . wake_lock = self . power_manager . newWakeLock ( self . power_manager . PARTIAL_WAKE_LOCK , " sideband_service " )
if not self . wake_lock . isHeld ( ) :
RNS . log ( " Taking wake lock " )
self . wake_lock . acquire ( )
def release_locks ( self ) :
2022-10-01 05:18:14 -04:00
if RNS . vendor . platformutils . get_platform ( ) == " android " :
if not self . multicast_lock == None and self . multicast_lock . isHeld ( ) :
2022-10-02 04:58:00 -04:00
RNS . log ( " Releasing multicast lock " )
2022-10-01 05:18:14 -04:00
self . multicast_lock . release ( )
2022-09-20 11:28:39 -04:00
2022-10-01 20:26:58 -04:00
if not self . wake_lock == None and self . wake_lock . isHeld ( ) :
2022-10-02 04:58:00 -04:00
RNS . log ( " Releasing wake lock " )
2022-10-01 20:26:58 -04:00
self . wake_lock . release ( )
2022-10-02 14:43:56 -04:00
def update_connectivity_type ( self ) :
if self . sideband . reticulum . is_connected_to_shared_instance :
is_controlling = False
else :
is_controlling = True
self . sideband . setpersistent ( " service.is_controlling_connectivity " , is_controlling )
def get_connectivity_status ( self ) :
if self . sideband . reticulum . is_connected_to_shared_instance :
return " [size=22dp][b]Connectivity Status[/b][/size] \n \n Sideband is connected via a shared Reticulum instance running on this system. Use the rnstatus utility to obtain full connectivity info. "
else :
ws = " Disabled "
ts = " Disabled "
i2s = " Disabled "
if self . sideband . interface_local != None :
np = len ( self . sideband . interface_local . peers )
if np == 1 :
ws = " 1 reachable peer "
else :
ws = str ( np ) + " reachable peers "
if self . sideband . interface_tcp != None :
if self . sideband . interface_tcp . online :
ts = " Connected to " + str ( self . sideband . interface_tcp . target_ip ) + " : " + str ( self . sideband . interface_tcp . target_port )
else :
ts = " Interface Down "
if self . sideband . interface_i2p != None :
if self . sideband . interface_i2p . online :
i2s = " Connected "
else :
i2s = " Connecting to I2P "
return " [size=22dp][b]Connectivity Status[/b][/size] \n \n [b]Local[/b] \n {ws} \n \n [b]TCP[/b] \n {ts} \n \n [b]I2P[/b] \n {i2s} " . format ( ws = ws , ts = ts , i2s = i2s )
2022-09-17 10:00:55 -04:00
def run ( self ) :
2022-10-01 05:18:14 -04:00
while self . should_run :
2022-10-01 20:26:58 -04:00
sleep_time = 1
2022-10-01 19:31:47 -04:00
self . sideband . setstate ( " service.heartbeat " , time . time ( ) )
2022-10-02 14:43:56 -04:00
self . sideband . setstate ( " service.connectivity_status " , self . get_connectivity_status ( ) )
2022-10-01 20:26:58 -04:00
if self . sideband . getstate ( " wants.service_stop " ) :
self . should_run = False
sleep_time = 0
2022-10-02 06:15:37 -04:00
if self . sideband . getstate ( " wants.clear_notifications " ) :
self . sideband . setstate ( " wants.clear_notifications " , False )
if self . notification_service != None :
self . notification_service . cancelAll ( )
2022-10-02 06:45:06 -04:00
if self . sideband . getstate ( " wants.settings_reload " ) :
self . sideband . setstate ( " wants.settings_reload " , False )
self . sideband . reload_configuration ( )
2022-10-01 20:26:58 -04:00
time . sleep ( sleep_time )
2022-10-01 05:18:14 -04:00
self . release_locks ( )
2022-10-01 20:26:58 -04:00
SidebandService ( ) . start ( )