[Sugar-devel] [PATCH sugar] Partial fix for GSM connection time (see SL#2992; fixes SL#1727)

Sascha Silbe silbe at activitycentral.com
Mon Jan 9 16:19:29 EST 2012


The connection time has apparently been off by a couple of hours (depending
on the time zone; see SL#2992 [1]) ever since we had this feature (commit
f5daf6e).

In addition the code depends on a bug in Sugar 0.88: We managed the GSM modem
using our built-in Network Manager User Settings service, which only updated
the timestamp on connect, instead of regularly updating it as the
NetworkManager settings specification [2] mandated (and still does [3]). And
because of implementing a User Settings service rather using System Settings,
GSM connections couldn't persist across Sugar restarts either, so we always
knew when the connection was actually started.

Since the migration to NetworkManager 0.9, the above assumptions don't hold
anymore: The GSM connection can have been started any time before the current
Sugar session and NetworkManager periodically updates the timestamp.

Currently there seems to be no way to determine the connection time [4], so
as a partial fix we try to track the connection time ourselves. This will be
off in case Sugar gets restarted (or the connection established during boot
before Sugar is running), but is still better than being completely off in
_all_ cases.

Almost incidentally, we also fix SL#1727 [5].

[1] https://bugs.sugarlabs.org/ticket/2992
[2] http://projects.gnome.org/NetworkManager/developers/api/08/settings-spec-08.html
[3] http://projects.gnome.org/NetworkManager/developers/api/09/ref-settings.html#id408437
[4] http://mail.gnome.org/archives/networkmanager-list/2012-January/thread.html#00022
[5] https://bugs.sugarlabs.org/ticket/1727

Signed-off-by: Sascha Silbe <silbe at activitycentral.com>
---
 extensions/deviceicon/network.py |   73 ++++++++++++++++++++++++-------------
 1 files changed, 47 insertions(+), 26 deletions(-)

diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py
index 213fa41..51d0ecc 100644
--- a/extensions/deviceicon/network.py
+++ b/extensions/deviceicon/network.py
@@ -330,11 +330,10 @@ class GsmPalette(Palette):
         self.error_description_label.set_text(message)
         self.error_description_label.show()
 
-    def update_connection_time(self, connection_time=None):
-        if connection_time is not None:
-            formatted_time = connection_time.strftime('%H:%M:%S')
-        else:
-            formatted_time = '00:00:00'
+    def update_connection_time(self, connection_time=0):
+        """Set the time we have been connected for, in seconds"""
+        formatted_time = time.strftime('%H:%M:%S',
+                                       time.gmtime(connection_time))
         text = _('Connected for %s') % (formatted_time, )
         self.props.secondary_text = glib.markup_escape_text(text)
 
@@ -708,6 +707,8 @@ class GsmDeviceView(TrayIcon):
     def __init__(self, device):
         self._connection_time_handler = None
         self._connection_timestamp = 0
+        self._gsm_state = _GSM_STATE_NOT_READY
+        self._traffic_stats = (0, 0)
 
         client = gconf.client_get_default()
         color = xocolor.XoColor(client.get_string('/desktop/sugar/user/color'))
@@ -728,21 +729,40 @@ class GsmDeviceView(TrayIcon):
                                       path=self._device.object_path,
                                       dbus_interface=network.NM_MODEM_IFACE)
 
+        props = dbus.Interface(self._device, dbus.PROPERTIES_IFACE)
+        props.GetAll(network.NM_DEVICE_IFACE, byte_arrays=True,
+                     reply_handler=self.__current_state_check_cb,
+                     error_handler=self.__current_state_check_error_cb)
+
     def create_palette(self):
         palette = GsmPalette()
 
         palette.set_group_id('frame')
         palette.connect('gsm-connect', self.__gsm_connect_cb)
         palette.connect('gsm-disconnect', self.__gsm_disconnect_cb)
+        palette.connect('popup', self.__palette_up_cb)
+        palette.connect('popdown', self.__palette_down_cb)
+        palette.update_state(self._gsm_state, None)
+        palette.update_stats(*self._traffic_stats)
+        if self._gsm_state == _GSM_STATE_CONNECTED:
+            palette.connection_info_box.show()
 
         self._palette = palette
+        return palette
 
-        props = dbus.Interface(self._device, dbus.PROPERTIES_IFACE)
-        props.GetAll(network.NM_DEVICE_IFACE, byte_arrays=True,
-                     reply_handler=self.__current_state_check_cb,
-                     error_handler=self.__current_state_check_error_cb)
+    def __palette_up_cb(self, palette):
+        if self._gsm_state != _GSM_STATE_CONNECTED:
+            return
 
-        return palette
+        connection_time = time.time() - self._connection_timestamp
+        palette.update_connection_time(connection_time)
+        self._connection_time_handler = gobject.timeout_add_seconds(1,
+            self.__connection_timecount_cb)
+
+    def __palette_down_cb(self, palette):
+        if self._connection_time_handler is not None:
+            gobject.source_remove(self._connection_time_handler)
+            self._connection_time_handler = None
 
     def __gsm_connect_cb(self, palette, data=None):
         connection = network.find_gsm_connection()
@@ -801,24 +821,16 @@ class GsmDeviceView(TrayIcon):
 
         if state is network.NM_DEVICE_STATE_ACTIVATED:
             gsm_state = _GSM_STATE_CONNECTED
-            connection = network.find_gsm_connection()
-            if connection is not None:
-                self._connection_timestamp = time.time() - \
-                        connection.get_settings('connection')['timestamp']
-                self._connection_time_handler = gobject.timeout_add_seconds( \
-                        1, self.__connection_timecount_cb)
+            self._connection_timestamp = time.time()
+            if self._palette is not None:
+                self._connection_time_handler = gobject.timeout_add_seconds(1,
+                    self.__connection_timecount_cb)
                 self._palette.update_connection_time()
                 self._palette.update_stats(0, 0)
-                if self._palette is not None:
-                    self._palette.connection_info_box.show()
+                self._palette.connection_info_box.show()
 
         elif state is network.NM_DEVICE_STATE_DISCONNECTED:
             gsm_state = _GSM_STATE_DISCONNECTED
-            self._connection_timestamp = 0
-            if self._connection_time_handler is not None:
-                gobject.source_remove(self._connection_time_handler)
-            if self._palette is not None:
-                self._palette.connection_info_box.hide()
 
         elif state in [network.NM_DEVICE_STATE_UNMANAGED,
                        network.NM_DEVICE_STATE_UNAVAILABLE,
@@ -832,6 +844,16 @@ class GsmDeviceView(TrayIcon):
         elif state == network.NM_DEVICE_STATE_FAILED:
             gsm_state = _GSM_STATE_FAILED
 
+        self._gsm_state = gsm_state
+
+        if state != network.NM_DEVICE_STATE_ACTIVATED:
+            self._connection_timestamp = None
+            if self._connection_time_handler is not None:
+                gobject.source_remove(self._connection_time_handler)
+                self._connection_time_handler = None
+            if self._palette is not None:
+                self._palette.connection_info_box.hide()
+
         if self._palette is not None:
             self._palette.update_state(gsm_state, reason)
 
@@ -842,12 +864,11 @@ class GsmDeviceView(TrayIcon):
                                          dbus_interface=network.NM_DEVICE_IFACE)
 
     def __ppp_stats_changed_cb(self, in_bytes, out_bytes):
+        self._traffic_stats = (in_bytes, out_bytes)
         self._palette.update_stats(in_bytes, out_bytes)
 
     def __connection_timecount_cb(self):
-        self._connection_timestamp = self._connection_timestamp + 1
-        connection_time = \
-            datetime.datetime.fromtimestamp(self._connection_timestamp)
+        connection_time = time.time() - self._connection_timestamp
         self._palette.update_connection_time(connection_time)
         return True
 
-- 
1.7.7.3



More information about the Sugar-devel mailing list