class Receiver(object): def __init__(self): self.registered = False self.intentName = '' self.actionName = '' def register(self, intentName, actionName, callback): self.br = BroadcastReceiver(self.on_broadcast, actions=[intentName + actionName]) self.intentName = intentName self.actionName = actionName self.callback = callback self.registered = True def stop(self): if self.registered: self.br.stop() def start(self): if self.registered: self.br.start() def on_broadcast(self, context, intent): actionName = self.actionName action = intent.getAction() if self.intentName + actionName == action: self.callback(actionName)
class Receiver: def __init__(self): self.registered = False self.intentName = '' self.actionName = '' def register(self, intentName, actionName, callback): self.br = BroadcastReceiver(self.on_broadcast, actions=[intentName+actionName]) self.intentName = intentName self.actionName = actionName self.callback = callback self.registered = True def stop(self): if self.registered: self.br.stop() def start(self): if self.registered: self.br.start() def on_broadcast(self, context, intent): actionName = self.actionName action = intent.getAction() if self.intentName + actionName == action: self.callback(actionName)
class MainApp(MDApp): def build(self): self.title = "Bluetooth Input Reader" self.theme_cls.primary_palette = "Pink" self.theme_cls.primary_hue = "400" self.icon = '/res/images/poolleaf_16619.png' self.use_kivy_settings = False self.br = None self.br_strt = False if platform == 'android': self.br = BroadcastReceiver(self.on_broadcast, actions=['state_changed']) def build_config(self, config): config.setdefaults('bluetoothsettings', { 'optionsbluetuuid': '00001101-0000-1000-8000-00805f9b34fb', 'optionsbluetencoding': 'LATIN-1'}) def build_settings(self, settings): settings.add_json_panel('Bluetooth Settings', self.config, data=bluetooth_settings_json) def on_start(self): BluetoothHelper().run() def start_broadcats(self): if self.br and not self.br_strt: self.br.start() self.br_strt = True def stop_broadcats(self): if self.br and self.br_strt: self.br.stop() self.br_strt = False def on_broadcast(self, context, intent): listen = intent.getAction() state = None if listen == BluetoothAdapter.ACTION_STATE_CHANGED: state = intent.getIntExtra( BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR) if state == BluetoothAdapter.STATE_ON: self.root.ids.is_bluetooth.text = 'ON' self.root.get_devices() elif BluetoothAdapter.STATE_OFF: self.root.ids.is_bluetooth.text = 'OFF' def on_pause(self): self.stop_broadcats() self.root.cancel_scale() return True def on_stop(self): self.stop_broadcats() self.root.cancel_scale() return True def on_resume(self): self.br = BroadcastReceiver(self.on_broadcast, actions=['state_changed']) self.start_broadcats() return True
class CurrentGameScreen(Screen, FloatLayout): def __init__ (self, *args, **kwargs): super(CurrentGameScreen, self).__init__(*args, **kwargs) self.eliminate = self.ids['eliminate'] self.status = self.ids['status'] self.eliminate.disabled = True self.BluetoothAdapter = autoclass('android.bluetooth.BluetoothAdapter') self.BluetoothDevice = autoclass('android.bluetooth.BluetoothDevice') self.BluetoothSocket = autoclass('android.bluetooth.BluetoothSocket') self.UUID = autoclass('java.util.UUID') self.Bundle = autoclass('android.os.Bundle') self.Intent = autoclass('android.content.Intent') self.IntentFilter = autoclass('android.content.IntentFilter') self.Context = autoclass('android.content.Context') self.Toast = autoclass('android.widget.Toast') self.PythonActivity = autoclass('org.renpy.android.PythonActivity') self.myBTA = self.BluetoothAdapter.getDefaultAdapter() self.popup = Popup(title='Notification', content=Label(text='Searching For Target. . .'), size_hint=(.9, .3), size=(800, 800)) self.popup1 = Popup(title='Notification', content=Label(text='Target Found!'), size_hint=(.9, .3), size=(800, 800)) def goback(self): sm.current = "Home" def findTarget(self): self.popup.open() self.br = BroadcastReceiver(self.onReceive, actions=['main'], myFilter = self.BluetoothDevice.ACTION_FOUND) self.br.start() self.myBTA.startDiscovery() def onReceive(self, context, intent): action = intent.getAction(); if (self.BluetoothDevice.ACTION_FOUND == action): extras = intent.getParcelableExtra(self.BluetoothDevice.EXTRA_DEVICE) device = cast('android.bluetooth.BluetoothDevice', extras) deviceName = device.getAddress() if deviceName == user.target: self.eliminate.disabled = False self.eliminate.color = (1,0,0,1) self.popup.dismiss() self.popup1.open() self.br.stop() def eliminateUser(self): query = retrieve("SELECT target FROM users WHERE bt_ID = '%s'" % (user.target)) update("UPDATE users SET target = '',status = '0' WHERE bt_ID = '%s'" % (user.target)) user.target = query[0] print user.target, '**************************************' create("UPDATE users SET target = '%s' WHERE uid = '%s'" % (user.target, user.uid)) updateUser() query1 = retrieve("SELECT firstname,lastname FROM users WHERE bt_ID = '%s'" % (user.target)) tfirstname, tlastname = query1[0] self.status.text = str("Your Current Target is %s %s" % (tfirstname, tlastname))
class DeviceManagerService(object): def __init__(self, **kwargs): self.debug_params = dict() self.addit_params = dict() for key, val in kwargs.items(): mo = re.search('^debug_([^_]+)_(.+)', key) if mo: kk = mo.group(1) ll = self.debug_params.get(kk, dict()) ll[mo.group(2)] = val self.debug_params[kk] = ll elif key.startswith('ab_'): self.addit_params[key[3:]] = val else: setattr(self, key, val) _LOGGER.debug( f'Addit params for DM {self.addit_params} AND {self.debug_params}') self.db = None self.oscer = None self.notification_formatter_info = dict() self.connectors_format = False self.devicemanager_class_by_type = dict() self.devicemanagers_pre_actions = dict() self.devicemanagers_by_id = dict() self.devicemanagers_by_uid = dict() self.connectors_info = [] self.users = [] self.views = [] self.devices = [] self.devicemanagers_active = [] self.devicemanagers_active_done = [] self.timer_obj = None self.main_session = None self.last_user = None self.devicemanagers_active_info = dict() self.stop_event = asyncio.Event() self.last_notify_ms = time() * 1000 if self.android: from jnius import autoclass from android.broadcast import BroadcastReceiver self.Context = autoclass('android.content.Context') self.AndroidString = autoclass('java.lang.String') self.NotificationCompatInboxStyle = autoclass( 'android.app.Notification$InboxStyle') NotificationBuilder = autoclass('android.app.Notification$Builder') self.PythonActivity = autoclass('org.kivy.android.PythonActivity') self.service = autoclass('org.kivy.android.PythonService').mService NOTIFICATION_CHANNEL_ID = self.AndroidString( self.service.getPackageName().encode('utf-8')) self.NOTIFICATION_GROUP = 'pyMovizGroup' self.FOREGROUND_NOTIFICATION_ID = 4563 app_context = self.service.getApplication().getApplicationContext() self.app_context = app_context self.notification_service = self.service.getSystemService( self.Context.NOTIFICATION_SERVICE) self.CONNECT_ACTION = 'device_manager_service.view.CONNECT' self.DISCONNECT_ACTION = 'device_manager_service.view.DISCONNECT' self.STOP_ACTION = 'device_manager_service.STOP' self.br = BroadcastReceiver(self.on_broadcast, actions=[ self.CONNECT_ACTION, PRESENCE_REQUEST_ACTION, self.DISCONNECT_ACTION, self.STOP_ACTION ]) self.br.start() Intent = autoclass('android.content.Intent') self.Intent = Intent PendingIntent = autoclass('android.app.PendingIntent') NotificationActionBuilder = autoclass( 'android.app.Notification$Action$Builder') Notification = autoclass('android.app.Notification') Color = autoclass("android.graphics.Color") NotificationChannel = autoclass('android.app.NotificationChannel') NotificationManager = autoclass('android.app.NotificationManager') channelName = self.AndroidString( 'DeviceManagerService'.encode('utf-8')) chan = NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_DEFAULT) chan.setLightColor(Color.BLUE) chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE) self.notification_service.createNotificationChannel(chan) BitmapFactory = autoclass("android.graphics.BitmapFactory") Icon = autoclass("android.graphics.drawable.Icon") BitmapFactoryOptions = autoclass( "android.graphics.BitmapFactory$Options") # Drawable = jnius.autoclass("{}.R$drawable".format(service.getPackageName())) # icon = getattr(Drawable, 'icon') options = BitmapFactoryOptions() # options.inMutable = True # declaredField = options.getClass().getDeclaredField("inPreferredConfig") # declaredField.set(cast('java.lang.Object',options), cast('java.lang.Object', BitmapConfig.ARGB_8888)) # options.inPreferredConfig = BitmapConfig.ARGB_8888; notification_image = join(dirname(__file__), '..', 'images', 'device_manager.png') bm = BitmapFactory.decodeFile(notification_image, options) notification_icon = Icon.createWithBitmap(bm) notification_image = join(dirname(__file__), '..', 'images', 'lan-connect.png') bm = BitmapFactory.decodeFile(notification_image, options) icon = Icon.createWithBitmap(bm) broadcastIntent = Intent(self.CONNECT_ACTION) actionIntent = PendingIntent.getBroadcast( self.service, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT) connect_action = NotificationActionBuilder( icon, self.AndroidString('CONNECT'.encode('utf-8')), actionIntent).build() notification_image = join(dirname(__file__), '..', 'images', 'lan-disconnect.png') bm = BitmapFactory.decodeFile(notification_image, options) icon = Icon.createWithBitmap(bm) broadcastIntent = Intent(self.DISCONNECT_ACTION) actionIntent = PendingIntent.getBroadcast( self.service, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT) disconnect_action = NotificationActionBuilder( icon, self.AndroidString('DISCONNECT'.encode('utf-8')), actionIntent).build() notification_image = join(dirname(__file__), '..', 'images', 'stop.png') bm = BitmapFactory.decodeFile(notification_image, options) icon = Icon.createWithBitmap(bm) broadcastIntent = Intent(self.STOP_ACTION) actionIntent = PendingIntent.getBroadcast( self.service, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT) stop_action = NotificationActionBuilder( icon, self.AndroidString('STOP'.encode('utf-8')), actionIntent).build() notification_intent = Intent(app_context, self.PythonActivity) notification_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK) notification_intent.setAction(Intent.ACTION_MAIN) notification_intent.addCategory(Intent.CATEGORY_LAUNCHER) notification_intent = PendingIntent.getActivity( self.service, 0, notification_intent, 0) self.notification_builder = NotificationBuilder(app_context, NOTIFICATION_CHANNEL_ID)\ .setContentIntent(notification_intent)\ .setSmallIcon(notification_icon)\ .addAction(connect_action)\ .addAction(disconnect_action)\ .addAction(stop_action) self.notification_builder_no_action = NotificationBuilder(app_context, NOTIFICATION_CHANNEL_ID)\ .setContentIntent(notification_intent)\ .setSmallIcon(notification_icon) def on_broadcast(self, context, intent): action = intent.getAction() _LOGGER.info(f'on_broadcast action {action}') if action == self.CONNECT_ACTION: self.loop.call_soon_threadsafe(self.on_command_condisc, 'c', self.last_user) elif action == self.DISCONNECT_ACTION: self.loop.call_soon_threadsafe(self.on_command_condisc, 'd') elif action == PRESENCE_REQUEST_ACTION: self.app_context.sendBroadcast( self.Intent(PRESENCE_RESPONSE_ACTION)) else: self.loop.call_soon_threadsafe(self.on_command_stop) def change_service_notification(self, dm, **kwargs): if self.android: alias = dm.get_device().get_alias() if alias not in self.notification_formatter_info: idnot = self.FOREGROUND_NOTIFICATION_ID + len( self.notification_formatter_info) self.notification_formatter_info[alias] =\ DeviceNotiication(dm, idnot, self) self.notification_formatter_info[alias].format(**kwargs) async def init_osc(self): self.oscer = OSCManager(hostlisten=self.hostlisten, portlisten=self.portlisten) await self.oscer.init(on_init_ok=self.on_osc_init_ok) def on_osc_init_ok(self, exception=None): if not exception: self.oscer.handle(COMMAND_STOP, self.on_command_stop) self.oscer.handle(COMMAND_LOGLEVEL, self.on_command_loglevel) self.oscer.handle(COMMAND_NEWDEVICE, self.on_command_newdevice) self.oscer.handle(COMMAND_QUERY, self.on_command_query, do_split=True) self.oscer.handle(COMMAND_CONNECT, self.on_command_condisc, 'c') self.oscer.handle(COMMAND_DISCONNECT, self.on_command_condisc, 'd') self.oscer.handle(COMMAND_CONNECTORS, self.on_command_connectors) self.oscer.handle(COMMAND_LISTDEVICES, self.on_command_listdevices) self.oscer.handle(COMMAND_LISTUSERS, self.on_command_listusers) self.oscer.handle(COMMAND_LISTVIEWS, self.on_command_listviews) self.oscer.handle( COMMAND_SAVEVIEW, partial(self.on_command_dbelem, asyncmethod=self.on_command_saveelem_async, lst=self.views, cls=View, on_ok=self.set_devicemanagers_active)) self.oscer.handle( COMMAND_DELVIEW, partial(self.on_command_dbelem, asyncmethod=self.on_command_delelem_async, lst=self.views, cls=View, on_ok=self.set_devicemanagers_active)) self.oscer.handle( COMMAND_SAVEUSER, partial(self.on_command_dbelem, asyncmethod=self.on_command_saveelem_async, lst=self.users, cls=User)) self.oscer.handle( COMMAND_DELUSER, partial(self.on_command_dbelem, asyncmethod=self.on_command_delelem_async, lst=self.users, cls=User)) self.create_device_managers() def on_command_condisc(self, cmd, *args, sender=None, **kwargs): _LOGGER.info(f'On Command condisc: {cmd}') if cmd == 'c': if args and isinstance(args[0], User) and args[0] in self.users: self.last_user = args[0] else: self.oscer.send(COMMAND_CONFIRM, CONFIRM_FAILED_1, MSG_INVALID_USER, dest=sender) return self.oscer.send(COMMAND_CONFIRM, CONFIRM_OK, cmd, dest=sender) for dm in self.devicemanagers_active_done.copy(): self.devicemanagers_active.append(dm) self.devicemanagers_active_done.remove(dm) from device.manager import GenericDeviceManager GenericDeviceManager.sort(self.devicemanagers_active) for _, info in self.devicemanagers_active_info.items(): info['operation'] = cmd info['retry'] = 0 Timer( 0, partial(self.start_remaining_connection_operations, bytimer=False)) def on_command_listviews(self, *args, sender=None, **kwargs): _LOGGER.info('List view before send:') for v in self.views: _LOGGER.info(f'View = {v}') self.oscer.send(COMMAND_LISTVIEWS_RV, *self.views, dest=sender) def on_command_listusers(self, *args, sender=None, **kwargs): self.oscer.send(COMMAND_LISTUSERS_RV, *self.users, dest=sender) def on_command_connectors(self, connectors_info, *args, sender=None, **kwargs): connectors_info = json.loads(connectors_info) if connectors_info: for ci in connectors_info: if not exists(ci['temp']): self.oscer.send(COMMAND_CONFIRM, CONFIRM_FAILED_1, dest=sender) return self.connectors_format = True Timer( 0, partial(TcpClient.init_connectors_async, self.loop, connectors_info)) self.oscer.send(COMMAND_CONFIRM, CONFIRM_OK, dest=sender) def on_command_listdevices(self, *args, sender=None, **kwargs): out = [] for uid, dm in self.devicemanagers_by_uid.items(): out.append(uid) out.append(dm.get_device()) self.oscer.send(COMMAND_LISTDEVICES_RV, *out, dest=sender) async def on_command_delelem_async(self, elem, *args, lst=None, on_ok=None, sender=None, **kwargs): try: _LOGGER.info(f'on_command_delelem_async {elem}') rv = await elem.delete(self.db) if rv: if elem in lst: lst.remove(elem) self.oscer.send(COMMAND_CONFIRM, CONFIRM_OK, elem, dest=sender) if on_ok: on_ok(elem) TcpClient.reset_templates() else: self.oscer.send(COMMAND_CONFIRM, CONFIRM_FAILED_1, MSG_DB_SAVE_ERROR % str(elem), dest=sender) except Exception: _LOGGER.error( f'on_command_delelem_async exception {traceback.format_exc()}') async def on_command_saveelem_async(self, elem, *args, lst=None, on_ok=None, sender=None, **kwargs): try: _LOGGER.info(f'on_command_saveelem_async {elem}') rv = await elem.to_db(self.db) if rv: if elem not in lst: lst.append(elem) else: lst[lst.index(elem)] = elem self.oscer.send(COMMAND_CONFIRM, CONFIRM_OK, elem, dest=sender) if on_ok: on_ok(elem) TcpClient.reset_templates() else: self.oscer.send(COMMAND_CONFIRM, CONFIRM_FAILED_1, MSG_DB_SAVE_ERROR % str(elem), dest=sender) except Exception: _LOGGER.error( f'on_command_saveelem_async exception {traceback.format_exc()}' ) def on_command_dbelem(self, elem, *args, asyncmethod=None, lst=None, cls=None, on_ok=None, sender=None, **kwargs): _LOGGER.info(f'on_command_dbelem {elem}') if isinstance(elem, cls): if self.devicemanagers_all_stopped(): Timer(0, partial(asyncmethod, elem, lst=lst, on_ok=on_ok)) else: self.oscer.send(COMMAND_CONFIRM, CONFIRM_FAILED_2, MSG_CONNECTION_STATE_INVALID, dest=sender) else: self.oscer.send(COMMAND_CONFIRM, CONFIRM_FAILED_1, MSG_INVALID_ITEM, dest=sender) def on_event_command_handle(self, dm, command, *args): _LOGGER.debug(f'On Command Handle dm={dm} comm={command} a={args}') exitv = args[0] if args else None if command == COMMAND_NEWSESSION and exitv == CONFIRM_OK: if self.connectors_format: TcpClient.format(dm.get_device(), manager=dm, session=args[2], user=self.last_user) self.change_service_notification(dm, manager=dm, session=args[2], user=self.last_user) if self.main_session: args[1].set_main_session_id(self.main_session.get_id()) else: self.main_session = args[2] elif command == COMMAND_DEVICEFIT and exitv == CONFIRM_OK: if self.connectors_format: TcpClient.format(args[1], fitobj=args[2], manager=dm, device=args[1]) self.change_service_notification(dm, fitobj=args[2], manager=dm) elif command == COMMAND_DELDEVICE and exitv == CONFIRM_OK: ids = f'{dm.get_id()}' if ids in self.devicemanagers_by_id: del self.devicemanagers_by_id[ids] ids = dm.get_uid() if ids in self.devicemanagers_active_info: del self.devicemanagers_active_info[ids] if ids in self.devicemanagers_by_uid: del self.devicemanagers_by_uid[ids] if dm in self.devicemanagers_active: self.devicemanagers_active.remove(dm) if dm in self.devicemanagers_active_done: self.devicemanagers_active_done.remove(dm) self.set_formatters_device() elif command == COMMAND_SAVEDEVICE and exitv == CONFIRM_OK: ids = f'{dm.get_id()}' if ids not in self.devicemanagers_by_id: self.devicemanagers_by_id[ids] = dm TcpClient.reset_templates() self.set_formatters_device() self.on_command_listviews() elif command == COMMAND_SEARCH and exitv == CONFIRM_OK: if dm.get_state() != DEVSTATE_SEARCHING: if self.devicemanagers_all_stopped(): dm.search(True) else: dm.search(False) def generate_uid(self): while True: uid = OSCManager.generate_uid() if uid not in self.devicemanagers_by_uid: return uid def devicemanagers_all_stopped(self): if not self.devicemanagers_active or not self.timer_obj: for _, x in self.devicemanagers_by_uid.items(): if not x.is_stopped_state(): return False return True else: return False def on_command_newdevice(self, typev, *args, sender=None, **kwargs): if typev not in self.devicemanager_class_by_type: self.oscer.send(COMMAND_CONFIRM, CONFIRM_FAILED_1, MSG_TYPE_DEVICE_UNKNOWN, dest=sender) elif not self.devicemanagers_all_stopped(): self.oscer.send(COMMAND_CONFIRM, CONFIRM_FAILED_1, MSG_CONNECTION_STATE_INVALID, dest=sender) else: uid = self.generate_uid() self.devicemanagers_by_uid[uid] = self.devicemanager_class_by_type[ typev](self.oscer, uid, service=True, db=self.db, loop=self.loop, params=self.addit_params, debug_params=self.debug_params.get(typev, dict()), on_command_handle=self.on_event_command_handle, on_state_transition=self.on_event_state_transition) self.oscer.send(COMMAND_CONFIRM, CONFIRM_OK, uid, dest=sender) async def db_query_single(self, txt): result = dict(error='', rows=[], cols=[], rowcount=0, changes=0, lastrowid=-1) try: async with self.db.cursor() as cursor: result['changes_before'] = self.db.total_changes await cursor.execute(txt) lst = result['rows'] result['rowcount'] = cursor.rowcount result['lastrowid'] = cursor.lastrowid result['changes_after'] = self.db.total_changes async for row in cursor: if not result['cols']: result['cols'] = list(row.keys()) item = '' for r in result['cols']: item += f'\t{row[r]}' lst.append(item.strip()) await self.db.commit() except Exception as ex: result['error'] = str(ex) _LOGGER.error(f'Query Error {traceback.format_exc()}') _LOGGER.info(f'Query {txt} result obtained') _LOGGER.debug(f'Query result {result}') return result async def db_query(self, txt, sender=None): queries = re.split(r';[\r\n]*', txt) results = [] for q in queries: q = q.strip() if q: r = await self.db_query_single(q) results.append(r) self.oscer.send(COMMAND_CONFIRM, CONFIRM_OK, results, do_split=True, dest=sender) def on_command_query(self, txt, *args, sender=None, **kwargs): _LOGGER.debug(f'on_command_query {txt}') if not self.db: self.oscer.send(COMMAND_CONFIRM, CONFIRM_FAILED_1, MSG_DB_SAVE_ERROR % self.db_fname, do_split=True, dest=sender) elif not txt: self.oscer.send(COMMAND_CONFIRM, CONFIRM_FAILED_2, MSG_INVALID_PARAM, do_split=True, dest=sender) elif self.devicemanagers_all_stopped(): Timer(0, partial(self.db_query, txt, sender=None)) else: self.oscer.send(COMMAND_CONFIRM, CONFIRM_FAILED_2, MSG_CONNECTION_STATE_INVALID, do_split=True, dest=sender) def on_command_loglevel(self, level, notify_screen_on, notify_every_ms, *args, sender=None, **kwargs): init_logger(__name__, level) self.verbose = level if notify_screen_on >= 0: self.notify_screen_on = notify_screen_on if notify_every_ms >= 0: self.notify_every_ms = notify_every_ms def on_command_stop(self, *args, sender=None, **kwargs): self.loop.stop() def reset_service_notifications(self): for _, no in self.notification_formatter_info.items(): no.clear() self.cancel_service_notification(no.idnot) if len(self.notification_formatter_info) > 1: self.cancel_service_notification(self.FOREGROUND_NOTIFICATION_ID - 1) self.notification_formatter_info.clear() def cancel_service_notification(self, idnot): if idnot == self.FOREGROUND_NOTIFICATION_ID: self.set_service_notification(idnot, self.build_service_notification()) else: self.notification_service.cancel(idnot) def set_service_notification(self, idnot, notif): self.notification_service.notify(idnot, notif) def set_summary_notification(self): if len(self.notification_formatter_info) > 1: summary = '' lines = [] message = f'{len(self.notification_formatter_info)} active devices' for t, no in self.notification_formatter_info.items(): if no.last_txt: lines.append(no.last_txt) summary += f' {no.title}' if summary and len(lines) > 1: summary = summary[1:] self.set_service_notification( self.FOREGROUND_NOTIFICATION_ID - 1, self.build_service_notification(summary, message, lines)) def build_service_notification(self, title=None, message=None, lines=None, idnot=0): group = None nb = self.notification_builder if not title and not message: title = "Fit.py" message = "DeviceManagerService" elif len(self.notification_formatter_info) > 1: nb = self.notification_builder if idnot == self.FOREGROUND_NOTIFICATION_ID else self.notification_builder_no_action group = self.NOTIFICATION_GROUP title = self.AndroidString((title if title else 'N/A').encode('utf-8')) message = self.AndroidString(message.encode('utf-8')) nb.setContentTitle(title)\ .setGroup(group)\ .setContentText(message)\ .setOnlyAlertOnce(self.notify_screen_on <= 0) if lines is not None: style = self.NotificationCompatInboxStyle()\ .setSummaryText(title)\ .setBigContentTitle(message) for l in lines: style.addLine(self.AndroidString(l.encode('utf-8'))) nb.setStyle(style)\ .setGroupSummary(True) else: nb.setStyle(None)\ .setGroupSummary(False) return nb.getNotification() def insert_service_notification(self): self.service.setAutoRestartService(False) self.service.startForeground(self.FOREGROUND_NOTIFICATION_ID, self.build_service_notification()) async def start(self): if self.android: self.insert_service_notification() self.devicemanager_class_by_type = find_devicemanager_classes(_LOGGER) for tp, cls in self.devicemanager_class_by_type.items(): if cls.__pre_action__: nm = cls.__pre_action__.__name__ if nm not in self.devicemanagers_pre_actions: self.devicemanagers_pre_actions[nm] = cls.__pre_action__ await self.init_db(self.db_fname) await self.load_db() await self.init_osc() def set_devicemanagers_active(self, *args, **kwargs): del self.devicemanagers_active_done[:] del self.devicemanagers_active[:] self.devicemanagers_active_info.clear() self.reset_service_notifications() for v in self.views: if v.active: for c in v.get_connected_devices(): d = self.devicemanagers_by_id[str(c)] if d not in self.devicemanagers_active_done: self.devicemanagers_active_done.append(d) for d in self.devicemanagers_active_done: self.devicemanagers_active_info[d.get_uid()] = dict(retry=0, operation='') def set_formatters_device(self): views2save = [] for v in self.views: saveview = False for i in range(len(v.items) - 1, -1, -1): lab = v.items[i] ids = str(lab.device) if ids in self.devicemanagers_by_id: lab.set_device(self.devicemanagers_by_id[ids].get_device()) else: del v.items[i] saveview = True if saveview: views2save.append(v) if views2save: Timer(0, partial(self.save_modified_views, views2save)) async def save_modified_views(self, views2save): for v in views2save: rv = await v.to_db(self.db) _LOGGER.info(f'Saving view {v} -> {rv}') self.on_command_listviews() def create_device_managers(self): for d in self.devices: uid = self.generate_uid() typev = d.get_type() if typev in self.devicemanager_class_by_type: dm = self.devicemanager_class_by_type[typev]( self.oscer, uid, service=True, loop=self.loop, db=self.db, device=d, params=self.addit_params, debug_params=self.debug_params.get(typev, dict()), on_command_handle=self.on_event_command_handle, on_state_transition=self.on_event_state_transition) self.devicemanagers_by_id[f'{d.get_id()}'] = dm self.devicemanagers_by_uid[uid] = dm self.set_devicemanagers_active() self.set_formatters_device() async def load_db(self): try: self.users = await User.loadbyid(self.db) self.devices = await Device.loadbyid(self.db) self.views = await View.load1m(self.db) # _LOGGER.debug(f'List view[0] {self.views[0]}') except Exception: _LOGGER.error(f'Load DB error {traceback.format_exc()}') async def start_remaining_connection_operations(self, bytimer=True): try: _LOGGER.info(f'Starting remaining con timer={bytimer}') if bytimer: self.timer_obj = None elif self.timer_obj: self.timer_obj.cancel() self.timer_obj = None for dm in self.devicemanagers_active.copy(): info = self.devicemanagers_active_info[dm.get_uid()] _LOGGER.info( f'Processing[{dm.get_uid()}] {dm.get_device()} -> {info["operation"]}' ) if info['operation'] == 'd': if dm.get_state() == DEVSTATE_CONNECTING: self.oscer.send( COMMAND_PRINTMSG, MSG_WAITING_FOR_CONNECTING.format( dm.get_device().get_alias())) break elif not dm.is_connected_state(): self.devicemanagers_active.remove(dm) self.devicemanagers_active_done.append(dm) else: dm.disconnect() break elif info['operation'] == 'c': if dm.is_connected_state(): self.devicemanagers_active.remove(dm) self.devicemanagers_active_done.append(dm) elif bytimer: dm.set_user(self.last_user) if dm.connect(): break else: self.oscer.send( COMMAND_PRINTMSG, MSG_DEVICE_NOT_STOPPED.format( dm.get_device().get_alias())) else: if info['retry'] < self.connect_retry: self.timer_obj = Timer( 0 if not info['retry'] else self.connect_secs, self.start_remaining_connection_operations) info['retry'] += 1 break else: _LOGGER.info( f'Retry FINISH for device[{dm.get_uid()}] {dm.get_device()}' ) except Exception: _LOGGER.error(f'Rem op error {traceback.format_exc()}') def set_operation_ended(self, info): info['operation'] = '' info['retry'] = 0 def on_event_state_transition(self, dm, oldstate, newstate, reason): if self.connectors_format: TcpClient.format(dm.get_device(), state=newstate, manager=dm) self.change_service_notification(dm, state=newstate, manager=dm) uid = dm.get_uid() if uid in self.devicemanagers_active_info: # assenza significa che stiamo facendo una ricerca info = self.devicemanagers_active_info[uid] from device.manager import GenericDeviceManager if GenericDeviceManager.is_connected_state_s( newstate) and oldstate == DEVSTATE_CONNECTING: if info['operation'] == 'c': if dm in self.devicemanagers_active: self.devicemanagers_active.remove(dm) self.devicemanagers_active_done.append(dm) self.set_operation_ended(info) Timer( 0, partial(self.start_remaining_connection_operations, bytimer=False)) elif oldstate == DEVSTATE_CONNECTING and newstate == DEVSTATE_DISCONNECTED: if reason == DEVREASON_PREPARE_ERROR or reason == DEVREASON_BLE_DISABLED: for dm in self.devicemanagers_active: info = self.devicemanagers_active_info[dm.get_uid()] self.set_operation_ended(info) if dm not in self.devicemanagers_active_done: self.devicemanagers_active_done.append(dm) del self.devicemanagers_active[:] else: Timer( 0, partial(self.start_remaining_connection_operations, bytimer=False)) elif (GenericDeviceManager.is_connected_state_s(oldstate) or oldstate == DEVSTATE_DISCONNECTING ) and newstate == DEVSTATE_DISCONNECTED: oper = 'c' if info['operation'] != 'd' else 'd' if reason != DEVREASON_REQUESTED: info['operation'] = oper if dm in self.devicemanagers_active_done: self.devicemanagers_active_done.remove(dm) if dm not in self.devicemanagers_active: self.devicemanagers_active.append(dm) GenericDeviceManager.sort(self.devicemanagers_active) else: self.set_operation_ended(info) self.main_session = None if dm in self.devicemanagers_active: self.devicemanagers_active.remove(dm) self.devicemanagers_active_done.append(dm) Timer( 0, partial(self.start_remaining_connection_operations, bytimer=False)) async def init_db(self, file): self.db = await aiosqlite.connect(file) if not isinstance(self.db, aiosqlite.Connection): self.db = None else: self.db.row_factory = aiosqlite.Row modules = glob.glob(join(dirname(__file__), "..", "db", "*.py*")) pls = [splitext(basename(f))[0] for f in modules if isfile(f)] import importlib import inspect for x in pls: try: m = importlib.import_module(f"db.{x}") clsmembers = inspect.getmembers(m, inspect.isclass) for cla in clsmembers: query = getattr(cla[1], '__create_table_query__') if query: # _LOGGER.debug(f'Executing query {query}') await self.db.execute(query) cla[1].set_update_columns() await self.db.execute('PRAGMA foreign_keys = ON') except Exception: _LOGGER.warning(traceback.format_exc()) await self.db.commit() def on_bluetooth_disabled(self, inst, wasdisabled, ok): self.undo_enable_operations() def undo_enable_operations(self): for nm, act in self.devicemanagers_pre_actions.items(): if nm in self.undo_info and self.undo_info[nm]: del self.undo_info[nm] preact = act(self.loop) preact.undo(self.on_bluetooth_disabled) break self.stop_event.set() async def uninit_db(self): if self.db: await self.db.commit() await self.db.close() async def stop(self): self.undo_enable_operations() await self.stop_event.wait() self.oscer.uninit() await self.uninit_db() if self.android: self.br.stop() self.stop_service() def stop_service(self): if self.android: self.reset_service_notifications() self.service.stopForeground(True) self.service.stopSelf()
class AndroidWiFiManager(WiFiManager): def __init__(self, config, logger, api): super(AndroidWiFiManager, self).__init__(config, logger, api) self.general_android_conn = GeneralAndroidConnectivity( self.logger, self.api) self.wifi_android_controller = WiFiAndroidController( self.logger, self.general_android_conn) self.context = PythonService.mService self.wifi_manager = self.context.getSystemService(Context.WIFI_SERVICE) self.conn_manager = self.context.getSystemService( Context.CONNECTIVITY_SERVICE) self.conn_change_br = BroadcastReceiver( self.handle_conn_change_alert, actions=[ConnectivityManager.CONNECTIVITY_ACTION]) self.addConnectionAlert( self.general_android_conn.updateConnectivityMgmtObj) def start(self): super(AndroidWiFiManager, self).start() ip_addr = self.general_android_conn.getLocalIpAddress() if ip_addr is not None and ip_addr != "": self.general_android_conn.updateConnectivityMgmtObj( "{\"status\":\"CONNECTED\", \"ip_address\":\"" + ip_addr + "\", \"ssid\":\" \"}") #GeneralConnectivity.setOpenMTCIntentAction(self.internalIntentAction) #GeneralConnectivity.setOpenMTCAndroidAppPackageName(self.android_app_package) #WiFiController.startConnectionAlert() results = self.wifi_android_controller.scanWiFiNetworks() #results = WiFiAndroidController.scanWiFiNetworks() # results = Hardware.getWiFiNetworks() self.logger.info("the result of wifi scan was " + results) # WiFiController.addNetworks(String(str(json.dumps(self.config["networks"],separators=(',', ':'))))) network_array = json.loads( json.dumps(self.config["networks"], separators=(',', ':'))) for network in network_array: self.logger.info("network info is " + str(network)) network_str = str(json.dumps(network, separators=(',', ':'))) self.logger.info("network info is " + network_str) self.wifi_android_controller.addConfiguredNetwork(network_str) #WiFiController.addConfiguredNetwork(String(network_str)) # default_network = "guest_open" # default_network = "guest_wpa_preshared" default_network = self.config["default_network"] self.logger.info("default_network is " + default_network) self.wifi_android_controller.connectToNetwork(default_network) #WiFiController.connectToNetwork(default_network) def connectToNetwork(self, networkSSID, conn_callback=None): self.wifi_android_controller.connectToNetwork(networkSSID, conn_callback) def addConnectionAlert(self, callback): if len(self.conn_change_callback_list) == 0: self.conn_change_br.start() super(AndroidWiFiManager, self).addConnectionAlert(callback) def removeConnectionAlert(self, callback): super(AndroidWiFiManager, self).removeConnectionAlert(callback) if len(self.conn_change_callback_list) == 0: self.conn_change_br.stop() def handle_conn_change_alert(self, context, intent): action = intent.getAction() ssid = "" ip_address = "" self.logger.info("received intent on " + action) if action != ConnectivityManager.CONNECTIVITY_ACTION: return if intent.hasExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY): #intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true)){ self.logger.info( "received information that the device disconnected and no network is available" ) self.conn_change_callback("DISCONNECTED", "", "") return net_type = intent.getIntExtra("networkType", -1) self.logger.info("network type is " + str(net_type)) if net_type != ConnectivityManager.TYPE_WIFI: return info = self.conn_manager.getNetworkInfo(net_type) state = info.getState() self.logger.info("wifi connectivity state is " + str(state.toString())) if str(state.toString()) != "CONNECTED": return self.logger.info( "received information about connectivity change for WiFi") # send intent to update connectivity status self.logger.info( "received information that the device connected on WiFi") wifiInfo = self.wifi_manager.getConnectionInfo() ssid = wifiInfo.getSSID() self.logger.info("device is now connected on WiFi on SSID " + str(ssid)) # ip_address = self.general_android_conn.getLocalIpAddress() ip_address = GeneralConnectivity.getLocalIpAddress() if ip_address is None: self.logger.info("device is not having any IP assigned") self.conn_change_callback("NO IP ADDRESS", "", ssid) else: self.logger.info("device is now connected with IP " + str(ip_address)) #TODO: handle any promise that is waiting for the reply self.conn_change_callback("CONNECTED", ip_address, ssid) self.current_ssid = ssid[1:-1] return
class Application(MDApp): results = set() wifi = None br = None def build(self): return Builder.load_string(KV) def register_broadcats_receiver(self): if not self.br: self.br = BroadcastReceiver( self.on_broadcast, actions=['SCAN_RESULTS_AVAILABLE_ACTION']) self.br.start() def on_broadcast(self, context, intent): success = intent.getBooleanExtra( WifiManager.EXTRA_RESULTS_UPDATED, False) if success: self.scan_success() else: self.scan_failure() def start_scan(self): self.register_broadcats_receiver() context = mActivity.getApplicationContext() wifiManager = cast( WifiManager, context.getSystemService(Context.WIFI_SERVICE)) self.wifi = wifiManager success = self.wifi.startScan() if not success: self.scan_failure() def scan_success(self): self.root.ids.lbl.text = '' if not self.wifi: return results = self.wifi.getScanResults() for i in range(results.size()): result = results.get(i) self.results.add(result) self.root.ids.lbl.text += f'{result.SSID}\n' def on_start(self): self.register_broadcats_receiver() request_permissions([Permission.ACCESS_FINE_LOCATION]) def on_resume(self): self.register_broadcats_receiver() def on_pause(self): self.stop_scan() return True def stop_scan(self): if self.br: self.br.stop() self.br = None self.root.ids.lbl.text = '' def scan_failure(self): if self.results: for result in self.results: self.root.ids.lbl.text += f'{result}\n' else: self.root.ids.lbl.text = 'something went wrong' self.stop_scan()