From 4b4cf9673c0afc7e220ff3c34023f3ce4537591a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 4 Apr 2007 23:48:09 -0400 Subject: [PATCH 1/2] Cleanup of sugar device handling code --- shell/hardware/nmclient.py | 56 ++++++++++++++++++------- shell/model/MeshModel.py | 15 ++++--- shell/model/devices/device.py | 28 +++++++++++++ shell/model/devices/devicesmodel.py | 50 +++++++++++++++------- shell/model/devices/network/mesh.py | 18 ++------ shell/model/devices/network/wired.py | 2 +- shell/model/devices/network/wireless.py | 18 ++------ shell/view/devices/network/mesh.py | 8 ++-- shell/view/devices/network/wireless.py | 7 ++-- 9 files changed, 129 insertions(+), 73 deletions(-) diff --git a/shell/hardware/nmclient.py b/shell/hardware/nmclient.py index d1178f25..3bb682d7 100644 --- a/shell/hardware/nmclient.py +++ b/shell/hardware/nmclient.py @@ -37,10 +37,10 @@ NM_DEVICE_STAGE_STRINGS=("Unknown", "IP Config", "IP Config Get", "IP Config Commit", - "Post-IP Start" + "Post-IP Start", "Activated", "Failed", - "Cancled" + "Canceled" ) NM_SERVICE = 'org.freedesktop.NetworkManager' @@ -192,6 +192,7 @@ class Device(gobject.GObject): self._type = DEVICE_TYPE_UNKNOWN self._udi = None self._active = False + self._act_stage = 0 self._strength = 0 self._link = False self._valid = False @@ -206,11 +207,22 @@ class Device(gobject.GObject): dev.getProperties(reply_handler=self._update_reply_cb, error_handler=self._update_error_cb) + def _is_activating(self): + if self._active and self._act_stage >= 1 and self._act_stage <= 7: + return True + return False + + def _is_activated(self): + if self._active and self._act_stage == 8: + return True + return False + def _update_reply_cb(self, *props): self._iface = props[1] self._type = props[2] self._udi = props[3] self._active = props[4] + self._act_stage = props[5] self._link = props[15] self._caps = props[17] @@ -218,17 +230,21 @@ class Device(gobject.GObject): old_strength = self._strength self._strength = props[14] if self._strength != old_strength: - self.emit('strength-changed') + if self._valid: + self.emit('strength-changed') self._update_networks(props[20], props[19]) elif self._type == DEVICE_TYPE_802_11_MESH_OLPC: old_strength = self._strength self._strength = props[14] if self._strength != old_strength: - self.emit('strength-changed') + if self._valid: + self.emit('strength-changed') self._valid = True - if self._active: + if self._is_activating(): + self.set_state(DEVICE_STATE_ACTIVATING) + elif self._is_activated(): self.set_state(DEVICE_STATE_ACTIVATED) else: self.set_state(DEVICE_STATE_INACTIVE) @@ -257,7 +273,8 @@ class Device(gobject.GObject): return # init success - self.emit('network-appeared', net) + if self._valid: + self.emit('network-appeared', net) if active_op and net_op == active_op: self.set_active_network(net) @@ -295,7 +312,8 @@ class Device(gobject.GObject): else: self._strength = 0 - self.emit('strength-changed') + if self._valid: + self.emit('strength-changed') def network_appeared(self, network): if self._networks.has_key(network): @@ -308,7 +326,8 @@ class Device(gobject.GObject): if not self._networks.has_key(network): return - self.emit('network-disappeared', self._networks[network]) + if self._valid: + self.emit('network-disappeared', self._networks[network]) del self._networks[network] @@ -323,10 +342,11 @@ class Device(gobject.GObject): self._active_network = network # don't emit ssid-changed for networks that are not yet valid - if self._active_network and self._active_network.is_valid(): - self.emit('ssid-changed') - elif not self._active_network: - self.emit('ssid-changed') + if self._valid: + if self._active_network and self._active_network.is_valid(): + self.emit('ssid-changed') + elif not self._active_network: + self.emit('ssid-changed') def _get_active_net_cb(self, state, net_op): if not self._networks.has_key(net_op): @@ -356,7 +376,8 @@ class Device(gobject.GObject): return self._state = state - self.emit('state-changed') + if self._valid: + self.emit('state-changed') if self._type == DEVICE_TYPE_802_11_WIRELESS: if state == DEVICE_STATE_INACTIVE: @@ -469,6 +490,7 @@ class NMClient(gobject.GObject): def _setup_dbus(self): self._sig_handlers = { + 'StateChange': self.state_changed_sig_handler, 'DeviceAdded': self.device_added_sig_handler, 'DeviceRemoved': self.device_removed_sig_handler, 'DeviceActivationStage': self.device_activation_stage_sig_handler, @@ -568,6 +590,9 @@ class NMClient(gobject.GObject): return self._key_dialog_destroy_cb(self._key_dialog) + def state_changed_sig_handler(self, new_state): + logging.debug('NM State Changed to %d' % new_state) + def device_activation_stage_sig_handler(self, device, stage): logging.debug('Device Activation Stage "%s" for device %s' % (NM_DEVICE_STAGE_STRINGS[stage], device)) @@ -605,8 +630,9 @@ class NMClient(gobject.GObject): if (old and len(old)) and (not new and not len(new)): # NM went away self._nm_present = False - for op in self._devices.keys(): - del self._devices[op] + devs = self._devices.keys() + for op in devs: + self._remove_device(op) self._devices = {} elif (not old and not len(old)) and (new and len(new)): # NM started up diff --git a/shell/model/MeshModel.py b/shell/model/MeshModel.py index 74dba266..db464f97 100644 --- a/shell/model/MeshModel.py +++ b/shell/model/MeshModel.py @@ -110,7 +110,9 @@ class MeshModel(gobject.GObject): self._add_access_point(nm_device, nm_network) def _nm_network_disappeared_cb(self, nm_device, nm_network): - self._remove_access_point(nm_network) + if self._access_points.has_key(nm_network.get_op()): + ap = self._access_points[nm_network.get_op()] + self._remove_access_point(ap) def _add_network_device(self, nm_device): dtype = nm_device.get_type() @@ -138,13 +140,14 @@ class MeshModel(gobject.GObject): def _add_access_point(self, nm_device, nm_network): model = AccessPointModel(nm_device, nm_network) - self._access_points[nm_network.get_op()] = model + self._access_points[model.get_id()] = model self.emit('access-point-added', model) - def _remove_access_point(self, nm_network): - self.emit('access-point-removed', - self._access_points[nm_network.get_op()]) - del self._access_points[nm_network.get_op()] + def _remove_access_point(self, ap): + if not self._access_points.has_key(ap.get_id()): + return + self.emit('access-point-removed', ap) + del self._access_points[ap.get_id()] def get_mesh(self): return self._mesh diff --git a/shell/model/devices/device.py b/shell/model/devices/device.py index 32bee0d2..815b1033 100644 --- a/shell/model/devices/device.py +++ b/shell/model/devices/device.py @@ -1,7 +1,35 @@ +# +# Copyright (C) 2007, Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + import gobject +from hardware import nmclient from sugar import util +STATE_ACTIVATING = 0 +STATE_ACTIVATED = 1 +STATE_INACTIVE = 2 + +_nm_state_to_state = { + nmclient.DEVICE_STATE_ACTIVATING : STATE_ACTIVATING, + nmclient.DEVICE_STATE_ACTIVATED : STATE_ACTIVATED, + nmclient.DEVICE_STATE_INACTIVE : STATE_INACTIVE +} + class Device(gobject.GObject): def __init__(self): gobject.GObject.__init__(self) diff --git a/shell/model/devices/devicesmodel.py b/shell/model/devices/devicesmodel.py index 2685b7c4..4a2148ce 100644 --- a/shell/model/devices/devicesmodel.py +++ b/shell/model/devices/devicesmodel.py @@ -1,3 +1,20 @@ +# +# Copyright (C) 2007, Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + import logging import gobject @@ -23,6 +40,7 @@ class DevicesModel(gobject.GObject): gobject.GObject.__init__(self) self._devices = {} + self._sigids = {} self.add_device(battery.Device()) self._observe_network_manager() @@ -45,7 +63,6 @@ class DevicesModel(gobject.GObject): self._network_device_removed_cb) def _network_device_added_cb(self, network_manager, nm_device): - logging.debug("got added isgnal for %s" % nm_device.get_op()) state = nm_device.get_state() if state == nmclient.DEVICE_STATE_ACTIVATING \ or state == nmclient.DEVICE_STATE_ACTIVATED: @@ -57,12 +74,8 @@ class DevicesModel(gobject.GObject): def _network_device_activated_cb(self, network_manager, nm_device): pass - def _network_device_removed_cb(self, nm_device): - self._remove_network_device(nm_device) - - def _network_device_state_changed_cb(self, nm_device): - if nm_device.get_state() == nmclient.DEVICE_STATE_INACTIVE: - self._remove_network_device(nm_device) + def _network_device_removed_cb(self, network_manager, nm_device): + self.remove_device(self._get_network_device(nm_device)) def _check_network_device(self, nm_device): if not nm_device.is_valid(): @@ -77,23 +90,26 @@ class DevicesModel(gobject.GObject): def _get_network_device(self, nm_device): return self._devices[str(nm_device.get_op())] + def _network_device_state_changed_cb(self, dev, param): + if dev.props.state == device.STATE_INACTIVE: + self.remove_device(dev) + def _add_network_device(self, nm_device): if self._devices.has_key(str(nm_device.get_op())): logging.debug("Tried to add device %s twice" % nm_device.get_op()) return dtype = nm_device.get_type() - logging.debug("Adding device %s type %d" % (nm_device.get_op(), dtype)) if dtype == nmclient.DEVICE_TYPE_802_11_WIRELESS: - self.add_device(wireless.Device(nm_device)) + dev = wireless.Device(nm_device) + self.add_device(dev) + sigid = dev.connect('notify::state', self._network_device_state_changed_cb) + self._sigids[dev] = sigid if dtype == nmclient.DEVICE_TYPE_802_11_MESH_OLPC: - self.add_device(mesh.Device(nm_device)) - - nm_device.connect('state-changed', - self._network_device_state_changed_cb) - - def _remove_network_device(self, nm_device): - self.remove_device(self._get_network_device(nm_device)) + dev = mesh.Device(nm_device) + self.add_device(dev) + sigid = dev.connect('notify::state', self._network_device_state_changed_cb) + self._sigids[dev] = sigid def __iter__(self): return iter(self._devices.values()) @@ -104,4 +120,6 @@ class DevicesModel(gobject.GObject): def remove_device(self, device): self.emit('device-disappeared', self._devices[device.get_id()]) + device.disconnect(self._sigids[device]) + del self._sigids[device] del self._devices[device.get_id()] diff --git a/shell/model/devices/network/mesh.py b/shell/model/devices/network/mesh.py index 63f7b23c..0bcc9fde 100644 --- a/shell/model/devices/network/mesh.py +++ b/shell/model/devices/network/mesh.py @@ -20,22 +20,12 @@ import gobject from model.devices import device from hardware import nmclient -STATE_ACTIVATING = 0 -STATE_ACTIVATED = 1 -STATE_INACTIVE = 2 - -_nm_state_to_state = { - nmclient.DEVICE_STATE_ACTIVATING : STATE_ACTIVATING, - nmclient.DEVICE_STATE_ACTIVATED : STATE_ACTIVATED, - nmclient.DEVICE_STATE_INACTIVE : STATE_INACTIVE -} - class Device(device.Device): __gproperties__ = { 'strength' : (int, None, None, 0, 100, 0, gobject.PARAM_READABLE), - 'state' : (int, None, None, STATE_ACTIVATING, - STATE_INACTIVE, 0, gobject.PARAM_READABLE) + 'state' : (int, None, None, device.STATE_ACTIVATING, + device.STATE_INACTIVE, 0, gobject.PARAM_READABLE) } def __init__(self, nm_device): @@ -58,10 +48,10 @@ class Device(device.Device): return self._nm_device.get_strength() elif pspec.name == 'state': nm_state = self._nm_device.get_state() - return _nm_state_to_state[nm_state] + return device._nm_state_to_state[nm_state] def get_type(self): return 'network.mesh' def get_id(self): - return self._nm_device.get_op() + return str(self._nm_device.get_op()) diff --git a/shell/model/devices/network/wired.py b/shell/model/devices/network/wired.py index ff791be3..1712a64f 100644 --- a/shell/model/devices/network/wired.py +++ b/shell/model/devices/network/wired.py @@ -6,7 +6,7 @@ class Device(device.Device): self._nm_device = device def get_id(self): - return self._nm_device.get_op() + return str(self._nm_device.get_op()) def get_type(self): return 'network.wired' diff --git a/shell/model/devices/network/wireless.py b/shell/model/devices/network/wireless.py index 826f726e..1ae4ff52 100644 --- a/shell/model/devices/network/wireless.py +++ b/shell/model/devices/network/wireless.py @@ -20,24 +20,14 @@ import gobject from model.devices import device from hardware import nmclient -STATE_ACTIVATING = 0 -STATE_ACTIVATED = 1 -STATE_INACTIVE = 2 - -_nm_state_to_state = { - nmclient.DEVICE_STATE_ACTIVATING : STATE_ACTIVATING, - nmclient.DEVICE_STATE_ACTIVATED : STATE_ACTIVATED, - nmclient.DEVICE_STATE_INACTIVE : STATE_INACTIVE -} - class Device(device.Device): __gproperties__ = { 'name' : (str, None, None, None, gobject.PARAM_READABLE), 'strength' : (int, None, None, 0, 100, 0, gobject.PARAM_READABLE), - 'state' : (int, None, None, STATE_ACTIVATING, - STATE_INACTIVE, 0, gobject.PARAM_READABLE) + 'state' : (int, None, None, device.STATE_ACTIVATING, + device.STATE_INACTIVE, 0, gobject.PARAM_READABLE) } def __init__(self, nm_device): @@ -67,10 +57,10 @@ class Device(device.Device): return self._nm_device.get_ssid() elif pspec.name == 'state': nm_state = self._nm_device.get_state() - return _nm_state_to_state[nm_state] + return device._nm_state_to_state[nm_state] def get_type(self): return 'network.wireless' def get_id(self): - return self._nm_device.get_op() + return str(self._nm_device.get_op()) diff --git a/shell/view/devices/network/mesh.py b/shell/view/devices/network/mesh.py index 78442cb5..c9259464 100644 --- a/shell/view/devices/network/mesh.py +++ b/shell/view/devices/network/mesh.py @@ -18,7 +18,7 @@ from sugar.graphics import canvasicon from sugar.graphics import color from sugar.graphics import units -from model.devices.network import mesh +from model.devices import device class DeviceView(canvasicon.CanvasIcon): def __init__(self, model): @@ -35,12 +35,12 @@ class DeviceView(canvasicon.CanvasIcon): def _update_state(self): # FIXME Change icon colors once we have real icons state = self._model.props.state - if state == mesh.STATE_ACTIVATING: + if state == device.STATE_ACTIVATING: self.props.fill_color = color.ICON_FILL_INACTIVE self.props.stroke_color = color.ICON_STROKE_INACTIVE - elif state == mesh.STATE_ACTIVATED: + elif state == device.STATE_ACTIVATED: self.props.fill_color = None self.props.stroke_color = None - elif state == mesh.STATE_INACTIVE: + elif state == device.STATE_INACTIVE: self.props.fill_color = color.ICON_FILL_INACTIVE self.props.stroke_color = color.ICON_STROKE_INACTIVE diff --git a/shell/view/devices/network/wireless.py b/shell/view/devices/network/wireless.py index dd079cca..a949f1c7 100644 --- a/shell/view/devices/network/wireless.py +++ b/shell/view/devices/network/wireless.py @@ -20,6 +20,7 @@ from sugar.graphics import color from sugar.graphics import units from model.devices.network import wireless from sugar.graphics.canvasicon import CanvasIcon +from model.devices import device _ICON_NAME = 'device-network-wireless' @@ -57,12 +58,12 @@ class DeviceView(CanvasIcon): def _update_state(self): # FIXME Change icon colors once we have real icons state = self._model.props.state - if state == wireless.STATE_ACTIVATING: + if state == device.STATE_ACTIVATING: self.props.fill_color = color.ICON_FILL_INACTIVE self.props.stroke_color = color.ICON_STROKE_INACTIVE - elif state == wireless.STATE_ACTIVATED: + elif state == device.STATE_ACTIVATED: self.props.fill_color = None self.props.stroke_color = None - elif state == wireless.STATE_INACTIVE: + elif state == device.STATE_INACTIVE: self.props.fill_color = color.ICON_FILL_INACTIVE self.props.stroke_color = color.ICON_STROKE_INACTIVE From 396ca0e64ea40fdaade2dfc4a13028dfc0a4f89b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 5 Apr 2007 00:22:13 -0400 Subject: [PATCH 2/2] Don't hiccup on NM start/stop --- shell/model/devices/devicesmodel.py | 3 ++- shell/view/home/MeshBox.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/shell/model/devices/devicesmodel.py b/shell/model/devices/devicesmodel.py index 4a2148ce..8b0dc9dd 100644 --- a/shell/model/devices/devicesmodel.py +++ b/shell/model/devices/devicesmodel.py @@ -75,7 +75,8 @@ class DevicesModel(gobject.GObject): pass def _network_device_removed_cb(self, network_manager, nm_device): - self.remove_device(self._get_network_device(nm_device)) + if self._devices.has_key(str(nm_device.get_op())): + self.remove_device(self._get_network_device(nm_device)) def _check_network_device(self, nm_device): if not nm_device.is_valid(): diff --git a/shell/view/home/MeshBox.py b/shell/view/home/MeshBox.py index 322d07fb..20829a0e 100644 --- a/shell/view/home/MeshBox.py +++ b/shell/view/home/MeshBox.py @@ -239,7 +239,7 @@ class MeshBox(SpreadBox): self._add_mesh_icon(mesh) def _mesh_removed_cb(self, model): - self._remove_mesh_icon() + self._remove_mesh() def _buddy_added_cb(self, model, buddy_model): self._add_alone_buddy(buddy_model) @@ -270,7 +270,7 @@ class MeshBox(SpreadBox): self._mesh = MeshDeviceView(mesh) self.add_item(self._mesh) - def _remove_access_point(self): + def _remove_mesh(self): if not self._mesh: return self.remove_item(self._mesh)