# HG changeset patch # User Goffi # Date 1554570358 -7200 # Node ID 9aadf11b315b1096cb51db58646569e1e1b0700a # Parent b06cb71079faef87221f763a6771f67e68d75764 plugin android: check connectivity use Android API to retrieve connectivity informations (connection availability + kind of connection). Register to connectivity change broadcast, new client.networkEnabled/client.networkDisabled are called when suitable. diff -r b06cb71079fa -r 9aadf11b315b sat/plugins/plugin_misc_android.py --- a/sat/plugins/plugin_misc_android.py Sat Apr 06 19:05:57 2019 +0200 +++ b/sat/plugins/plugin_misc_android.py Sat Apr 06 19:05:58 2019 +0200 @@ -49,6 +49,9 @@ from plyer import notification, vibrator +from plyer.platforms.android import activity +from jnius import autoclass +from android.broadcast import BroadcastReceiver #: delay between a pause event and sending the inactive indication to server, in seconds #: we don't send the indication immediately because user can be just checking something @@ -64,6 +67,14 @@ STATE_PAUSED = "paused" STATE_STOPPED = "stopped" STATES = (STATE_RUNNING, STATE_PAUSED, STATE_STOPPED) +NET_TYPE_NONE = "no network" +NET_TYPE_WIFI = "wifi" +NET_TYPE_MOBILE = "mobile" +NET_TYPE_OTHER = "other" + + +Context = autoclass('android.content.Context') +ConnectivityManager = autoclass('android.net.ConnectivityManager') def determineLength_workaround(self, fObj): @@ -167,6 +178,20 @@ # plugins have done their job host.trigger.add("MessageReceived", self.messageReceivedTrigger, priority=-1000) + # Connectivity handling + self.cm = activity.getSystemService(Context.CONNECTIVITY_SERVICE) + self._net_type = None + self._checkConnectivity() + # XXX: we need to keep a reference to BroadcastReceiver to avoid + # "XXX has no attribute 'invoke'" error (looks like the same issue as + # https://github.com/kivy/pyjnius/issues/59) + self.br = BroadcastReceiver( + callback=lambda *args, **kwargs: reactor.callLater(0, + self.onConnectivityChange), + actions=[u"android.net.conn.CONNECTIVITY_CHANGE"]) + self.br.start() + + @property def state(self): return self._state @@ -248,3 +273,52 @@ self._csi_timer = None for client in self.host.getClients(C.PROF_KEY_ALL): self._csi.setActive(client) + + # Connectivity + + def _handleNetworkChange(self, previous, new): + """Notify the clients about network changes. + + This way the client can disconnect/reconnect transport, or change delays + """ + if new == NET_TYPE_NONE: + for client in self.host.getClients(C.PROF_KEY_ALL): + client.networkDisabled() + elif previous == NET_TYPE_NONE: + for client in self.host.getClients(C.PROF_KEY_ALL): + client.networkEnabled() + + def _checkConnectivity(self): + active_network = self.cm.getActiveNetworkInfo() + if active_network is None: + net_type = NET_TYPE_NONE + else: + net_type_android = active_network.getType() + if net_type_android == ConnectivityManager.TYPE_WIFI: + net_type = NET_TYPE_WIFI + elif net_type_android == ConnectivityManager.TYPE_MOBILE: + net_type = NET_TYPE_MOBILE + else: + net_type = NET_TYPE_OTHER + if net_type != self._net_type: + log.info(u"connectivity has changed") + previous = self._net_type + self._net_type = net_type + if net_type == NET_TYPE_NONE: + log.info(u"no network active") + elif net_type == NET_TYPE_WIFI: + log.info(u"WIFI activated") + elif net_type == NET_TYPE_MOBILE: + log.info(u"mobile data activated") + else: + log.info(u"network activated (type={net_type_android})" + .format(net_type_android=net_type_android)) + self._handleNetworkChange(previous, net_type) + else: + log.debug(u"_checkConnectivity called without network change ({net_type})" + .format(net_type = net_type)) + + + def onConnectivityChange(self): + log.debug(u"onConnectivityChange called") + self._checkConnectivity()