From 24c19c14c6f3020b8e210a9da4d84b66f3df1837 Mon Sep 17 00:00:00 2001
From: Daniel Drake <dsd@laptop.org>
Date: Mon, 12 Jul 2010 11:30:18 -0600
Subject: [PATCH] Only show mesh device icon when mesh is active

Simon pointed out that there's no reason to have the mesh device
icon active when the mesh is not being used.

Adapt it to behave more like the wired network device icon in this
respect.
---
 extensions/deviceicon/network.py |  106 +++++++++++++++++++++++++-------------
 1 files changed, 70 insertions(+), 36 deletions(-)

diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py
index 399ef78..84914ef 100644
--- a/extensions/deviceicon/network.py
+++ b/extensions/deviceicon/network.py
@@ -587,7 +587,7 @@ class OlpcMeshDeviceView(ToolButton):
     _ICON_NAME = 'network-mesh'
     FRAME_POSITION_RELATIVE = 302
 
-    def __init__(self, device):
+    def __init__(self, device, state):
         ToolButton.__init__(self)
 
         self._bus = dbus.SystemBus()
@@ -613,42 +613,25 @@ class OlpcMeshDeviceView(ToolButton):
         self.set_palette(self._palette)
         self._palette.set_group_id('frame')
 
+        self.update_state(state)
+
         self._device_props = dbus.Interface(self._device,
                                             'org.freedesktop.DBus.Properties')
-        self._device_props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
-                              reply_handler=self.__get_device_props_reply_cb,
-                              error_handler=self.__get_device_props_error_cb)
         self._device_props.Get(_NM_OLPC_MESH_IFACE, 'ActiveChannel',
                             reply_handler=self.__get_active_channel_reply_cb,
                             error_handler=self.__get_active_channel_error_cb)
 
-        self._bus.add_signal_receiver(self.__state_changed_cb,
-                                      signal_name='StateChanged',
-                                      path=self._device.object_path,
-                                      dbus_interface=_NM_DEVICE_IFACE)
         self._bus.add_signal_receiver(self.__wireless_properties_changed_cb,
                                       signal_name='PropertiesChanged',
                                       path=device.object_path,
                                       dbus_interface=_NM_OLPC_MESH_IFACE)
 
     def disconnect(self):
-        self._bus.remove_signal_receiver(self.__state_changed_cb,
-                                         signal_name='StateChanged',
-                                         path=self._device.object_path,
-                                         dbus_interface=_NM_DEVICE_IFACE)
         self._bus.remove_signal_receiver(self.__wireless_properties_changed_cb,
                                          signal_name='PropertiesChanged',
                                          path=self._device.object_path,
                                          dbus_interface=_NM_OLPC_MESH_IFACE)
 
-    def __get_device_props_reply_cb(self, properties):
-        if 'State' in properties:
-            self._device_state = properties['State']
-            self._update()
-
-    def __get_device_props_error_cb(self, err):
-        logging.error('Error getting the device properties: %s', err)
-
     def __get_active_channel_reply_cb(self, channel):
         self._channel = channel
         self._update_text()
@@ -692,12 +675,12 @@ class OlpcMeshDeviceView(ToolButton):
             self._palette.set_connected_with_channel(self._channel, address)
             self._icon.props.base_color = profile.get_color()
             self._icon.props.pulsing = False
-        else:
-            self._icon.props.base_color = self._inactive_color
-            self._icon.props.pulsing = False
-            self._palette.set_disconnected()
         self._update_text()
 
+    def update_state(self, state):
+        self._device_state = state
+        self._update()
+
     def __deactivate_connection(self, palette, data=None):
         obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
         netmgr = dbus.Interface(obj, _NM_IFACE)
@@ -901,18 +884,11 @@ class GsmDeviceView(TrayIcon):
         self._palette.connection_time_label.set_text(text)
 
 class WirelessDeviceObserver(object):
-    def __init__(self, device, tray, device_type):
+    def __init__(self, device, tray):
         self._device = device
         self._device_view = None
         self._tray = tray
-
-        if device_type == network.DEVICE_TYPE_802_11_WIRELESS:
-            self._device_view = WirelessDeviceView(self._device)
-        elif device_type == network.DEVICE_TYPE_802_11_OLPC_MESH:
-            self._device_view = OlpcMeshDeviceView(self._device)
-        else:
-            raise ValueError('Unimplemented device type %d' % device_type)
-
+        self._device_view = WirelessDeviceView(self._device)
         self._tray.add_device(self._device_view)
 
     def disconnect(self):
@@ -922,6 +898,62 @@ class WirelessDeviceObserver(object):
         self._device_view = None
 
 
+class MeshDeviceObserver(object):
+    def __init__(self, device, tray):
+        self._bus = dbus.SystemBus()
+        self._device = device
+        self._device_view = None
+        self._tray = tray
+
+        props = dbus.Interface(self._device, dbus.PROPERTIES_IFACE)
+        props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
+                     reply_handler=self.__get_device_props_reply_cb,
+                     error_handler=self.__get_device_props_error_cb)
+
+        self._bus.add_signal_receiver(self.__state_changed_cb,
+                                      signal_name='StateChanged',
+                                      path=self._device.object_path,
+                                      dbus_interface=_NM_DEVICE_IFACE)
+
+    def _remove_device_view(self):
+        self._device_view.disconnect()
+        self._tray.remove_device(self._device_view)
+        del self._device_view
+        self._device_view = None
+
+    def disconnect(self):
+        if self._device_view is not None:
+            self._remove_device_view()
+
+        self._bus.remove_signal_receiver(self.__state_changed_cb,
+                                         signal_name='StateChanged',
+                                         path=self._device.object_path,
+                                         dbus_interface=_NM_DEVICE_IFACE)
+
+    def __get_device_props_reply_cb(self, properties):
+        if 'State' in properties:
+            self._update_state(properties['State'])
+
+    def __get_device_props_error_cb(self, err):
+        logging.error('Error getting the device properties: %s', err)
+
+    def __state_changed_cb(self, new_state, old_state, reason):
+        self._update_state(new_state)
+
+    def _update_state(self, state):
+        if state >= network.DEVICE_STATE_PREPARE \
+           and state <= network.DEVICE_STATE_ACTIVATED:
+            if self._device_view is not None:
+                self._device_view.update_state(state)
+                return
+
+            self._device_view = OlpcMeshDeviceView(self._device, state)
+            self._tray.add_device(self._device_view)
+        else:
+            if self._device_view is not None:
+                self._remove_device_view()
+
+
 class WiredDeviceObserver(object):
     def __init__(self, device, tray):
         self._bus = dbus.SystemBus()
@@ -1023,9 +1055,11 @@ class NetworkManagerObserver(object):
         if device_type == network.DEVICE_TYPE_802_3_ETHERNET:
             device = WiredDeviceObserver(nm_device, self._tray)
             self._devices[device_op] = device
-        elif device_type in [network.DEVICE_TYPE_802_11_WIRELESS,
-                             network.DEVICE_TYPE_802_11_OLPC_MESH]:
-            device = WirelessDeviceObserver(nm_device, self._tray, device_type)
+        elif device_type == network.DEVICE_TYPE_802_11_WIRELESS:
+            device = WirelessDeviceObserver(nm_device, self._tray)
+            self._devices[device_op] = device
+        elif device_type == network.DEVICE_TYPE_802_11_OLPC_MESH:
+            device = MeshDeviceObserver(nm_device, self._tray)
             self._devices[device_op] = device
         elif device_type == network.DEVICE_TYPE_GSM_MODEM:
             device = GsmDeviceObserver(nm_device, self._tray)
-- 
1.7.1.1

