Mercurial > libervia-backend
comparison sat/plugins/plugin_misc_android.py @ 3125:c3ce8c997fdf
plugin android: reconnect profiles with autoconnect if network is activated:
if network is activated, we check that all profiles with autoconnect are indeed connected,
and reconnect them if necesssary.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 26 Jan 2020 18:08:09 +0100 |
parents | b86060901278 |
children | 9d0df638c8b4 |
comparison
equal
deleted
inserted
replaced
3124:b86060901278 | 3125:c3ce8c997fdf |
---|---|
193 self.notif_player.prepare() | 193 self.notif_player.prepare() |
194 | 194 |
195 # Connectivity handling | 195 # Connectivity handling |
196 self.cm = activity.getSystemService(Context.CONNECTIVITY_SERVICE) | 196 self.cm = activity.getSystemService(Context.CONNECTIVITY_SERVICE) |
197 self._net_type = None | 197 self._net_type = None |
198 self._checkConnectivity() | 198 d = defer.ensureDeferred(self._checkConnectivity()) |
199 d.addErrback(host.logErrback) | |
200 | |
199 # XXX: we need to keep a reference to BroadcastReceiver to avoid | 201 # XXX: we need to keep a reference to BroadcastReceiver to avoid |
200 # "XXX has no attribute 'invoke'" error (looks like the same issue as | 202 # "XXX has no attribute 'invoke'" error (looks like the same issue as |
201 # https://github.com/kivy/pyjnius/issues/59) | 203 # https://github.com/kivy/pyjnius/issues/59) |
202 self.br = BroadcastReceiver( | 204 self.br = BroadcastReceiver( |
203 callback=lambda *args, **kwargs: reactor.callLater(0, | 205 callback=lambda *args, **kwargs: reactor.callLater(0, |
289 # Profile autoconnection | 291 # Profile autoconnection |
290 | 292 |
291 def _profileAutoconnectGet(self): | 293 def _profileAutoconnectGet(self): |
292 return defer.ensureDeferred(self.profileAutoconnectGet()) | 294 return defer.ensureDeferred(self.profileAutoconnectGet()) |
293 | 295 |
294 async def profileAutoconnectGet(self): | 296 async def _getProfilesAutoconnect(self): |
295 """Return profile to connect automatically by frontend, if any""" | |
296 autoconnect_dict = await self.host.memory.storage.getIndParamValues( | 297 autoconnect_dict = await self.host.memory.storage.getIndParamValues( |
297 category='Connection', name='autoconnect_backend', | 298 category='Connection', name='autoconnect_backend', |
298 ) | 299 ) |
299 profiles_autoconnect = [p for p, v in autoconnect_dict.items() if C.bool(v)] | 300 return [p for p, v in autoconnect_dict.items() if C.bool(v)] |
301 | |
302 async def profileAutoconnectGet(self): | |
303 """Return profile to connect automatically by frontend, if any""" | |
304 profiles_autoconnect = await self._getProfilesAutoconnect() | |
300 if not profiles_autoconnect: | 305 if not profiles_autoconnect: |
301 return None | 306 return None |
302 if len(profiles_autoconnect) > 1: | 307 if len(profiles_autoconnect) > 1: |
303 log.warning( | 308 log.warning( |
304 f"More that one profiles with backend autoconnection set found, picking " | 309 f"More that one profiles with backend autoconnection set found, picking " |
326 for client in self.host.getClients(C.PROF_KEY_ALL): | 331 for client in self.host.getClients(C.PROF_KEY_ALL): |
327 self._csi.setActive(client) | 332 self._csi.setActive(client) |
328 | 333 |
329 # Connectivity | 334 # Connectivity |
330 | 335 |
331 def _handleNetworkChange(self, previous, new): | 336 async def _handleNetworkChange(self, net_type): |
332 """Notify the clients about network changes. | 337 """Notify the clients about network changes. |
333 | 338 |
334 This way the client can disconnect/reconnect transport, or change delays | 339 This way the client can disconnect/reconnect transport, or change delays |
335 """ | 340 """ |
336 if new == NET_TYPE_NONE: | 341 log.debug(f"handling network change ({net_type})") |
342 if net_type == NET_TYPE_NONE: | |
337 for client in self.host.getClients(C.PROF_KEY_ALL): | 343 for client in self.host.getClients(C.PROF_KEY_ALL): |
338 client.networkDisabled() | 344 client.networkDisabled() |
339 elif previous == NET_TYPE_NONE: | 345 else: |
346 # client may be there but disabled (e.g. with stream management) | |
340 for client in self.host.getClients(C.PROF_KEY_ALL): | 347 for client in self.host.getClients(C.PROF_KEY_ALL): |
348 log.debug(f"enabling network for {client.profile}") | |
341 client.networkEnabled() | 349 client.networkEnabled() |
342 | 350 |
343 def _checkConnectivity(self): | 351 # profiles may have been disconnected and then purged, we try |
352 # to reconnect them in case | |
353 profiles_autoconnect = await self._getProfilesAutoconnect() | |
354 for profile in profiles_autoconnect: | |
355 if not self.host.isConnected(profile): | |
356 log.info(f"{profile} is not connected, reconnecting it") | |
357 try: | |
358 await self.host.connect(profile) | |
359 except Exception as e: | |
360 log.error(f"Can't connect profile {profile}: {e}") | |
361 | |
362 async def _checkConnectivity(self): | |
344 active_network = self.cm.getActiveNetworkInfo() | 363 active_network = self.cm.getActiveNetworkInfo() |
345 if active_network is None: | 364 if active_network is None: |
346 net_type = NET_TYPE_NONE | 365 net_type = NET_TYPE_NONE |
347 else: | 366 else: |
348 net_type_android = active_network.getType() | 367 net_type_android = active_network.getType() |
350 net_type = NET_TYPE_WIFI | 369 net_type = NET_TYPE_WIFI |
351 elif net_type_android == ConnectivityManager.TYPE_MOBILE: | 370 elif net_type_android == ConnectivityManager.TYPE_MOBILE: |
352 net_type = NET_TYPE_MOBILE | 371 net_type = NET_TYPE_MOBILE |
353 else: | 372 else: |
354 net_type = NET_TYPE_OTHER | 373 net_type = NET_TYPE_OTHER |
374 | |
355 if net_type != self._net_type: | 375 if net_type != self._net_type: |
356 log.info("connectivity has changed") | 376 log.info("connectivity has changed") |
357 previous = self._net_type | |
358 self._net_type = net_type | 377 self._net_type = net_type |
359 if net_type == NET_TYPE_NONE: | 378 if net_type == NET_TYPE_NONE: |
360 log.info("no network active") | 379 log.info("no network active") |
361 elif net_type == NET_TYPE_WIFI: | 380 elif net_type == NET_TYPE_WIFI: |
362 log.info("WIFI activated") | 381 log.info("WIFI activated") |
363 elif net_type == NET_TYPE_MOBILE: | 382 elif net_type == NET_TYPE_MOBILE: |
364 log.info("mobile data activated") | 383 log.info("mobile data activated") |
365 else: | 384 else: |
366 log.info("network activated (type={net_type_android})" | 385 log.info("network activated (type={net_type_android})" |
367 .format(net_type_android=net_type_android)) | 386 .format(net_type_android=net_type_android)) |
368 self._handleNetworkChange(previous, net_type) | |
369 else: | 387 else: |
370 log.debug("_checkConnectivity called without network change ({net_type})" | 388 log.debug("_checkConnectivity called without network change ({net_type})" |
371 .format(net_type = net_type)) | 389 .format(net_type = net_type)) |
372 | 390 |
391 # we always call _handleNetworkChange even if there is not connectivity change | |
392 # to be sure to reconnect when necessary | |
393 await self._handleNetworkChange(net_type) | |
394 | |
373 | 395 |
374 def onConnectivityChange(self): | 396 def onConnectivityChange(self): |
375 log.debug("onConnectivityChange called") | 397 log.debug("onConnectivityChange called") |
376 self._checkConnectivity() | 398 d = defer.ensureDeferred(self._checkConnectivity()) |
399 d.addErrback(self.host.logErrback) |