From 8b76b39bfcc29d1382c85a7c334e5e037d1487b9 Mon Sep 17 00:00:00 2001 From: dcastelo Date: Tue, 1 Jun 2010 11:36:35 -0300 Subject: [PATCH] Showing-Errors-Pallete-Mockup-V5.patch --- extensions/deviceicon/network.py | 189 ++++++++++++++++++++++++++------------ src/jarabe/model/network.py | 160 ++++++++++++++++++++++++++++++-- 2 files changed, 280 insertions(+), 69 deletions(-) diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py index 94a4293..d695fad 100644 --- a/extensions/deviceicon/network.py +++ b/extensions/deviceicon/network.py @@ -39,6 +39,8 @@ from sugar.graphics.tray import TrayIcon from sugar.graphics import xocolor from sugar.util import unique_id from sugar import profile +from sugar.graphics.icon import Icon +from sugar.graphics.menuitem import MenuItem from jarabe.model import network from jarabe.model.network import Settings @@ -63,7 +65,7 @@ _GSM_STATE_NOT_READY = 0 _GSM_STATE_DISCONNECTED = 1 _GSM_STATE_CONNECTING = 2 _GSM_STATE_CONNECTED = 3 -_GSM_STATE_NEED_AUTH = 4 +_GSM_STATE_FAILED = 4 def frequency_to_channel(frequency): ftoc = { 2412: 1, 2417: 2, 2422: 3, 2427: 4, @@ -214,6 +216,7 @@ class WiredPalette(Palette): ip_address_text = "" self._ip_address_label.set_text(ip_address_text) + class GsmPalette(Palette): __gtype_name__ = 'SugarGsmPalette' @@ -227,36 +230,53 @@ class GsmPalette(Palette): def __init__(self): Palette.__init__(self, label=_('Wireless modem')) - self._current_state = None + self._alert = False - self._toggle_state_item = gtk.MenuItem('') + self._toggle_state_item = MenuItem('') self._toggle_state_item.connect('activate', self.__toggle_state_cb) self.menu.append(self._toggle_state_item) self._toggle_state_item.show() - self.set_state(_GSM_STATE_NOT_READY) - self.info_box = gtk.VBox() - self.data_label = gtk.Label() - self.data_label.props.xalign = 0.0 - label_alignment = self._add_widget_with_padding(self.data_label) - self.info_box.pack_start(label_alignment) - self.data_label.show() + self.error_description_label = gtk.Label("") + self.error_description_label.set_line_wrap(True) + self.info_box.pack_start(self.error_description_label) + + self.connection_info_box = gtk.HBox() + + icon = Icon(icon_name='data-upload', icon_size=gtk.ICON_SIZE_MENU) + self.connection_info_box.pack_start(icon) + icon.show() + self._data_label_up = gtk.Label() + self._data_label_up.props.xalign = 0.0 + label_alignment = self._add_widget_with_padding(self._data_label_up) + self.connection_info_box.pack_start(label_alignment) + self._data_label_up.show() label_alignment.show() - self.connection_time_label = gtk.Label() - self.connection_time_label.props.xalign = 0.0 - label_alignment = self._add_widget_with_padding( \ - self.connection_time_label) - self.info_box.pack_start(label_alignment) - self.connection_time_label.show() + icon = Icon(icon_name='data-download', icon_size=gtk.ICON_SIZE_MENU) + self.connection_info_box.pack_start(icon) + icon.show() + self._data_label_down = gtk.Label() + self._data_label_down.props.xalign = 0.0 + label_alignment = self._add_widget_with_padding(self._data_label_down) + self.connection_info_box.pack_start(label_alignment) + self._data_label_down.show() label_alignment.show() + + self.info_box.pack_start(self.connection_info_box) + self._error_accept_item = MenuItem('') + self._error_accept_item.connect('activate', self.__error_accept_cb) + self.menu.append(self._error_accept_item) + self.info_box.show() self.set_content(self.info_box) + self.set_state(_GSM_STATE_NOT_READY) + def _add_widget_with_padding(self, child, xalign=0, yalign=0.5): alignment = gtk.Alignment(xalign=xalign, yalign=yalign, xscale=1, yscale=0.33) @@ -267,35 +287,90 @@ class GsmPalette(Palette): alignment.add(child) return alignment - def set_state(self, state): + def set_state(self, state, reason=0): self._current_state = state - self._update_label_and_text() + self._update_label_and_text(reason) - def _update_label_and_text(self): + def _update_label_and_text(self, reason=0): + if self._current_state == _GSM_STATE_NOT_READY: self._toggle_state_item.get_child().set_label('...') self.props.secondary_text = _('Please wait...') - + elif self._current_state == _GSM_STATE_DISCONNECTED: self._toggle_state_item.get_child().set_label(_('Connect')) - self.props.secondary_text = _('Disconnected') - + if not self._alert: + self.props.secondary_text = _('Disconnected') + icon = Icon(icon_name='dialog-ok', \ + icon_size=gtk.ICON_SIZE_MENU) + self._toggle_state_item.set_image(icon) + elif self._current_state == _GSM_STATE_CONNECTING: self._toggle_state_item.get_child().set_label(_('Cancel')) self.props.secondary_text = _('Connecting...') + icon = Icon(icon_name='dialog-cancel', \ + icon_size=gtk.ICON_SIZE_MENU) + self._toggle_state_item.set_image(icon) elif self._current_state == _GSM_STATE_CONNECTED: self._toggle_state_item.get_child().set_label(_('Disconnect')) - self.props.secondary_text = _('Connected') - - elif self._current_state == _GSM_STATE_NEED_AUTH: - self._toggle_state_item.get_child().set_label(_('Sim requires Pin/Puk')) - self.props.secondary_text = _('Authentication Error') - + self.update_connection_time() + icon = Icon(icon_name='media-eject', \ + icon_size=gtk.ICON_SIZE_MENU) + self._toggle_state_item.set_image(icon) + + elif self._current_state == _GSM_STATE_FAILED: + message_error = self._get_error_by_nm_reason(reason) + self.add_alert(_('Error: %s') % message_error[0], \ + message_error[1]) else: raise ValueError('Invalid GSM state while updating label and ' \ 'text, %s' % str(self._current_state)) - + + def add_alert(self, title, message): + self._alert = True + self.props.secondary_text = _("Connection Error") + self._error_accept_item.get_child().set_label(title) + self._error_accept_item.show() + self.error_description_label.set_text(message) + self.error_description_label.show() + self._toggle_state_item.set_sensitive(False) + + def __error_accept_cb(self, alert): + self._alert = False + self._update_label_and_text() + self._error_accept_item.get_child().set_label('') + self._error_accept_item.hide() + self.error_description_label.hide() + self._toggle_state_item.set_sensitive(True) + self._full_request = [0, 0] + + def update_connection_time(self, connection_time=None): + if (connection_time is not None): + self.props.secondary_text = _('Connected for ' + \ + connection_time.strftime('%H:%M:%S')) + else: + self.props.secondary_text = _('Connected for ' \ + + '00:00:00') + + def update_stats(self, in_bytes, out_bytes): + in_KBytes = in_bytes / 1024 + out_KBytes = out_bytes / 1024 + self._data_label_up.set_text(_("%d KB") % (out_KBytes)) + self._data_label_down.set_text(_("%d KB") % (in_KBytes)) + + def _get_error_by_nm_reason(self, reason): + if reason in [network.NM_DEVICE_STATE_REASON_NO_SECRETS, network.NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED]: + message = _('Suggestion: Check your Pin/Puk configuration.') + elif reason in [network.NM_DEVICE_STATE_REASON_PPP_DISCONNECT, network.NM_DEVICE_STATE_REASON_PPP_FAILED]: + message = _('Suggestion: Check your Access Point Name (APN) configuration') + elif reason in [network.NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER, network.NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT]: + message = _('Suggestion: Check the Number configuration.') + else: + message = '' + message_tuple = (network.NM_DEVICE_STATE_REASON_DESCRIPTION[reason], message) + return message_tuple + def __toggle_state_cb(self, menuitem): if self._current_state == _GSM_STATE_NOT_READY: pass @@ -305,12 +380,10 @@ class GsmPalette(Palette): self.emit('gsm-disconnect') elif self._current_state == _GSM_STATE_CONNECTED: self.emit('gsm-disconnect') - elif self._current_state == _GSM_STATE_NEED_AUTH: - self.emit('gsm-disconnect') else: raise ValueError('Invalid GSM state while emitting signal, %s' % \ str(self._current_state)) - + class WirelessDeviceView(ToolButton): @@ -747,6 +820,7 @@ class GsmDeviceView(TrayIcon): signal_name='PppStats', path=self._device.object_path, dbus_interface=_NM_SERIAL_IFACE) + def create_palette(self): palette = GsmPalette() @@ -774,6 +848,9 @@ class GsmDeviceView(TrayIcon): '/', reply_handler=self.__connect_cb, error_handler=self.__connect_error_cb) + else: + self._palette.add_alert(_('Connection Error'), \ + _('There is no gsm connection available')) def __connect_cb(self, active_connection): logging.debug('Connected successfully to gsm device, %s', @@ -807,15 +884,15 @@ class GsmDeviceView(TrayIcon): def __state_changed_cb(self, new_state, old_state, reason): logging.debug('State: %s to %s, reason %s', old_state, new_state, reason) - self._update_state(int(new_state)) + self._update_state(int(new_state), int(old_state), int(reason)) def __current_state_check_cb(self, properties): - self._update_state(int(properties['State'])) + self._update_state(int(properties['State']), 0, 0) def __current_state_check_error_cb(self, error): raise RuntimeError('Error when checking gsm device state, %s' % error) - def _update_state(self, state): + def _update_state(self, state, old_state, reason): gsm_state = None if state is network.DEVICE_STATE_ACTIVATED: @@ -823,20 +900,22 @@ class GsmDeviceView(TrayIcon): connection = network.find_gsm_connection() if connection is not None: connection.set_connected() - self._connection_timestamp = time.time() - \ + self._connection_timestamp = time.time() - \ connection.get_settings().connection.timestamp self._connection_time_handler = gobject.timeout_add_seconds( \ 1, self.__connection_timecount_cb) - self._update_stats(0, 0) - self._update_connection_time() - self._palette.info_box.show() + self._palette.update_connection_time() + self._palette.update_stats(0, 0) + if self._palette is not None: + self._palette.connection_info_box.show() elif state is network.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) - self._palette.info_box.hide() + if self._palette is not None: + self._palette.connection_info_box.hide() elif state in [network.DEVICE_STATE_UNMANAGED, network.DEVICE_STATE_UNAVAILABLE, @@ -845,14 +924,15 @@ class GsmDeviceView(TrayIcon): elif state in [network.DEVICE_STATE_PREPARE, network.DEVICE_STATE_CONFIG, - network.DEVICE_STATE_IP_CONFIG]: + network.DEVICE_STATE_IP_CONFIG, + network.DEVICE_STATE_NEED_AUTH]: gsm_state = _GSM_STATE_CONNECTING - - elif state in [network.DEVICE_STATE_NEED_AUTH]: - gsm_state = _GSM_STATE_NEED_AUTH + + elif state == network.DEVICE_STATE_FAILED: + gsm_state = _GSM_STATE_FAILED if self._palette is not None: - self._palette.set_state(gsm_state) + self._palette.set_state(gsm_state, reason) def disconnect(self): self._bus.remove_signal_receiver(self.__state_changed_cb, @@ -861,25 +941,17 @@ class GsmDeviceView(TrayIcon): dbus_interface=_NM_DEVICE_IFACE) def __ppp_stats_changed_cb(self, in_bytes, out_bytes): - self._update_stats(in_bytes, out_bytes) - - def _update_stats(self, in_bytes, out_bytes): - in_KBytes = in_bytes / 1024 - out_KBytes = out_bytes / 1024 - text = _("Data sent %d KB / received %d KB") % (out_KBytes, in_KBytes) - self._palette.data_label.set_text(text) + self._palette.update_stats(in_bytes, out_bytes) def __connection_timecount_cb(self): self._connection_timestamp = self._connection_timestamp + 1 - self._update_connection_time() + connection_time = \ + datetime.datetime.fromtimestamp(self._connection_timestamp) + self._palette.update_connection_time(connection_time) return True - def _update_connection_time(self): - connection_time = datetime.datetime.fromtimestamp( \ - self._connection_timestamp) - text = _("Connection time ") + connection_time.strftime('%H : %M : %S') - self._palette.connection_time_label.set_text(text) + class WirelessDeviceObserver(object): def __init__(self, device, tray, device_type): self._device = device @@ -950,6 +1022,7 @@ class WiredDeviceObserver(object): del self._device_view self._device_view = None + class GsmDeviceObserver(object): def __init__(self, device, tray): self._device = device diff --git a/src/jarabe/model/network.py b/src/jarabe/model/network.py index 3a949da..04391f8 100644 --- a/src/jarabe/model/network.py +++ b/src/jarabe/model/network.py @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +from gettext import gettext as _ import logging import os import time @@ -54,6 +55,138 @@ NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0 NM_ACTIVE_CONNECTION_STATE_ACTIVATING = 1 NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2 + +NM_DEVICE_STATE_REASON_UNKNOWN = 0 +NM_DEVICE_STATE_REASON_NONE = 1 +NM_DEVICE_STATE_REASON_NOW_MANAGED = 2 +NM_DEVICE_STATE_REASON_NOW_UNMANAGED = 3 +NM_DEVICE_STATE_REASON_CONFIG_FAILED = 4 +NM_DEVICE_STATE_REASON_CONFIG_UNAVAILABLE = 5 +NM_DEVICE_STATE_REASON_CONFIG_EXPIRED = 6 +NM_DEVICE_STATE_REASON_NO_SECRETS = 7 +NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT = 8 +NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED = 9 +NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED = 10 +NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT = 11 +NM_DEVICE_STATE_REASON_PPP_START_FAILED = 12 +NM_DEVICE_STATE_REASON_PPP_DISCONNECT = 13 +NM_DEVICE_STATE_REASON_PPP_FAILED = 14 +NM_DEVICE_STATE_REASON_DHCP_START_FAILED = 15 +NM_DEVICE_STATE_REASON_DHCP_ERROR = 16 +NM_DEVICE_STATE_REASON_DHCP_FAILED = 17 +NM_DEVICE_STATE_REASON_SHARED_START_FAILED = 18 +NM_DEVICE_STATE_REASON_SHARED_FAILED = 19 +NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED = 20 +NM_DEVICE_STATE_REASON_AUTOIP_ERROR = 21 +NM_DEVICE_STATE_REASON_AUTOIP_FAILED = 22 +NM_DEVICE_STATE_REASON_MODEM_BUSY = 23 +NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE = 24 +NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER = 25 +NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT = 26 +NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED = 27 +NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED = 28 +NM_DEVICE_STATE_REASON_GSM_APN_FAILED = 29 +NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING = 30 +NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED = 31 +NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT = 32 +NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED = 33 +NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED = 34 +NM_DEVICE_STATE_REASON_FIRMWARE_MISSING = 35 +NM_DEVICE_STATE_REASON_REMOVED = 36 +NM_DEVICE_STATE_REASON_SLEEPING = 37 +NM_DEVICE_STATE_REASON_CONNECTION_REMOVED = 38 +NM_DEVICE_STATE_REASON_USER_REQUESTED = 39 +NM_DEVICE_STATE_REASON_CARRIER = 40 + + + +NM_DEVICE_STATE_REASON_DESCRIPTION = { + NM_DEVICE_STATE_REASON_UNKNOWN: \ + _("The reason for the device state change \ is unknown"), + NM_DEVICE_STATE_REASON_NONE: \ + _("The state change is normal."), + NM_DEVICE_STATE_REASON_NOW_MANAGED: \ + _("The device is now managed."), + NM_DEVICE_STATE_REASON_NOW_UNMANAGED: \ + _("The device is no longer managed."), + NM_DEVICE_STATE_REASON_CONFIG_FAILED: \ + _("The device could not be readied for configuration."), + NM_DEVICE_STATE_REASON_CONFIG_UNAVAILABLE : \ + _("IP configuration could not be reserved \ + (no available address, timeout, etc)."), + NM_DEVICE_STATE_REASON_CONFIG_EXPIRED : \ + _("The IP configuration is no longer valid."), + NM_DEVICE_STATE_REASON_NO_SECRETS : \ + _("Secrets were required, but not provided."), + NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT : \ + _("The 802.1X supplicant disconnected from \ + the access point or authentication server."), + NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED : \ + _("Configuration of the 802.1X supplicant failed."), + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED : \ + _("The 802.1X supplicant quit or failed unexpectedly."), + NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT : \ + _("The 802.1X supplicant took too long to authenticate."), + NM_DEVICE_STATE_REASON_PPP_START_FAILED : \ + _("The PPP service failed to start within the allowed time."), + NM_DEVICE_STATE_REASON_PPP_DISCONNECT : \ + _("The PPP service disconnected unexpectedly."), + NM_DEVICE_STATE_REASON_PPP_FAILED : \ + _("The PPP service quit or failed unexpectedly."), + NM_DEVICE_STATE_REASON_DHCP_START_FAILED : \ + _("The DHCP service failed to start within the allowed time."), + NM_DEVICE_STATE_REASON_DHCP_ERROR : \ + _("The DHCP service reported an unexpected error"), + NM_DEVICE_STATE_REASON_DHCP_FAILED : \ + _("The DHCP service quit or failed unexpectedly."), + NM_DEVICE_STATE_REASON_SHARED_START_FAILED : \ + _("The shared connection service failed to start."), + NM_DEVICE_STATE_REASON_SHARED_FAILED : \ + _("The shared connection service quit or failed unexpectedly"), + NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED : \ + _("The AutoIP service failed to start."), + NM_DEVICE_STATE_REASON_AUTOIP_ERROR : + _("The AutoIP service reported an unexpected error."), + NM_DEVICE_STATE_REASON_AUTOIP_FAILED : \ + _("The AutoIP service quit or failed unexpectedly."), + NM_DEVICE_STATE_REASON_MODEM_BUSY : \ + _("Dialing failed because the line was busy."), + NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE : \ + _("Dialing failed because there was no dial tone. "), + NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER : \ + _("Dialing failed because there was carrier."), + NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT : \ + _("Dialing timed out."), + NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED : \ + _("Dialing failed."), + NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED : \ + _("Modem initialization failed."), + NM_DEVICE_STATE_REASON_GSM_APN_FAILED : \ + _("Failed to select the specified GSM APN."), + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING : \ + _("Not searching for networks."), + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED : \ + _("Network registration was denied."), + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT : \ + _("Network registration timed out."), + NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED : \ + _("Failed to register with the requested GSM network."), + NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED : \ + _("PIN check failed."), + NM_DEVICE_STATE_REASON_FIRMWARE_MISSING : \ + _("Necessary firmware for the device may be missing."), + NM_DEVICE_STATE_REASON_REMOVED : \ + _("The device was removed."), + NM_DEVICE_STATE_REASON_SLEEPING : \ + _("NetworkManager went to sleep."), + NM_DEVICE_STATE_REASON_CONNECTION_REMOVED : \ + _("The device's active connection was removed or disappeared."), + NM_DEVICE_STATE_REASON_USER_REQUESTED : + _("A user or client requested the disconnection."), + NM_DEVICE_STATE_REASON_CARRIER : + _("The device's carrier/link changed.") +} + NM_802_11_AP_FLAGS_NONE = 0x00000000 NM_802_11_AP_FLAGS_PRIVACY = 0x00000001 @@ -444,17 +577,22 @@ class NMSettingsConnection(dbus.service.Object): def GetSecrets(self, setting_name, hints, request_new, reply, error): logging.debug('Secrets requested for connection %s request_new=%s', self.path, request_new) - if request_new or self._secrets is None: - # request_new is for example the case when the pw on the AP changes - response = SecretsResponse(self, reply, error) - try: - self.secrets_request.send(self, response=response) - except Exception: - logging.exception('Error requesting the secrets via dialog') - else: - reply(self._secrets.get_dict()) - - + if self._settings.connection.type is not 'gsm': + if request_new or self._secrets is None: + # request_new is for example the case when the pw on the AP changes + response = SecretsResponse(self, reply, error) + try: + self.secrets_request.send(self, response=response) + except Exception: + logging.exception('Error requesting the secrets via dialog') + else: + reply(self._secrets.get_dict()) + else: + if not request_new: + reply(self._secrets.get_dict()) + else: + raise Exception('The stored GSM secret has already been supplied ') + class AccessPoint(gobject.GObject): __gsignals__ = { 'props-changed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, -- 1.6.2.5