[Sugar-devel] [PATCH Read] battery display (fullscreen mode): replace HAL with UPower

Sascha Silbe silbe at activitycentral.com
Thu Feb 24 11:17:11 EST 2011


HAL is deprecated, UPower is the designated replacement w.r.t. power
supplies.

Tested on XO-1.5 running Debian Squeeze with stock UPower (0.9.5-5) and a
2.6.35 OLPC kernel.

Signed-off-by: Sascha Silbe <silbe at activitycentral.com>
---
 readtopbar.py |  152 ++++++++++++++++-----------------------------------------
 1 files changed, 42 insertions(+), 110 deletions(-)

diff --git a/readtopbar.py b/readtopbar.py
index af7da4c..9725525 100644
--- a/readtopbar.py
+++ b/readtopbar.py
@@ -26,97 +26,10 @@ from sugar.graphics.icon import Icon, get_icon_state
 from gettext import gettext as _
 
 
-_LEVEL_PROP = 'battery.charge_level.percentage'
-_CHARGING_PROP = 'battery.rechargeable.is_charging'
-_DISCHARGING_PROP = 'battery.rechargeable.is_discharging'
-_PRESENT_PROP = 'battery.present'
-
 _ICON_NAME = 'battery'
 
-
-# Taken from sugar/extensions/deviceicon/battery.py
-class BattMan(gobject.GObject):
-
-    __gproperties__ = {
-        'level': (int, None, None, 0, 100, 0, gobject.PARAM_READABLE),
-        'charging': (bool, None, None, False, gobject.PARAM_READABLE),
-        'discharging': (bool, None, None, False, gobject.PARAM_READABLE),
-        'present': (bool, None, None, False, gobject.PARAM_READABLE),
-    }
-
-    def __init__(self, udi):
-        gobject.GObject.__init__(self)
-
-        bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
-        proxy = bus.get_object('org.freedesktop.Hal', udi,
-                               follow_name_owner_changes=True)
-        self._battery = dbus.Interface(proxy, 'org.freedesktop.Hal.Device')
-        bus.add_signal_receiver(self._battery_changed,
-                                'PropertyModified',
-                                'org.freedesktop.Hal.Device',
-                                'org.freedesktop.Hal',
-                                udi)
-
-        self._level = self._get_level()
-        self._charging = self._get_charging()
-        self._discharging = self._get_discharging()
-        self._present = self._get_present()
-
-    def _get_level(self):
-        try:
-            return self._battery.GetProperty(_LEVEL_PROP)
-        except dbus.DBusException:
-            logging.error('Cannot access %s' % _LEVEL_PROP)
-            return 0
-
-    def _get_charging(self):
-        try:
-            return self._battery.GetProperty(_CHARGING_PROP)
-        except dbus.DBusException:
-            logging.error('Cannot access %s' % _CHARGING_PROP)
-            return False
-
-    def _get_discharging(self):
-        try:
-            return self._battery.GetProperty(_DISCHARGING_PROP)
-        except dbus.DBusException:
-            logging.error('Cannot access %s' % _DISCHARGING_PROP)
-            return False
-
-    def _get_present(self):
-        try:
-            return self._battery.GetProperty(_PRESENT_PROP)
-        except dbus.DBusException:
-            logging.error('Cannot access %s' % _PRESENT_PROP)
-            return False
-
-    def do_get_property(self, pspec):
-        if pspec.name == 'level':
-            return self._level
-        if pspec.name == 'charging':
-            return self._charging
-        if pspec.name == 'discharging':
-            return self._discharging
-        if pspec.name == 'present':
-            return self._present
-
-    def get_type(self):
-        return 'battery'
-
-    def _battery_changed(self, num_changes, changes_list):
-        for change in changes_list:
-            if change[0] == _LEVEL_PROP:
-                self._level = self._get_level()
-                self.notify('level')
-            elif change[0] == _CHARGING_PROP:
-                self._charging = self._get_charging()
-                self.notify('charging')
-            elif change[0] == _DISCHARGING_PROP:
-                self._discharging = self._get_discharging()
-                self.notify('discharging')
-            elif change[0] == _PRESENT_PROP:
-                self._present = self._get_present()
-                self.notify('present')
+_UP_DEVICE_IFACE = 'org.freedesktop.UPower.Device'
+_UP_TYPE_BATTERY = 2
 
 
 class _TopBar(gtk.HBox):
@@ -133,25 +46,32 @@ class _TopBar(gtk.HBox):
 
         self._completion_level = 0
         self._progressbar = None
+        self._icon = None
+        self._battery_props = None
 
         try:
             bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
-            proxy = bus.get_object('org.freedesktop.Hal',
-                                    '/org/freedesktop/Hal/Manager')
-            hal_manager = dbus.Interface(proxy, 'org.freedesktop.Hal.Manager')
-            udis = hal_manager.FindDeviceByCapability('battery')
-            if len(udis) > 0:
-                self._battery = BattMan(udis[0]) # TODO: Support more than one battery
-                self._battery.connect('notify::level', \
-                    self._battery_level_changed_cb)
-            else:
-                self._battery = None
-        except dbus.exceptions.DBusException:
-            self._battery = None
-            logging.warning('Hardware manager service not found, no idle \
-                            suspend.')
+            up_proxy = bus.get_object('org.freedesktop.UPower',
+                                      '/org/freedesktop/UPower')
+            upower = dbus.Interface(up_proxy, 'org.freedesktop.UPower')
+
+            for device_path in upower.EnumerateDevices():
+                device = bus.get_object('org.freedesktop.UPower', device_path)
+                device_prop_iface = dbus.Interface(device, dbus.PROPERTIES_IFACE)
+                device_type = device_prop_iface.Get(_UP_DEVICE_IFACE, 'Type')
+                if device_type != _UP_TYPE_BATTERY:
+                    continue
+
+                device.connect_to_signal('Changed',
+                                         self.__battery_properties_changed_cb,
+                                         dbus_interface=_UP_DEVICE_IFACE)
+                self._battery_props = dbus.Interface(device,
+                                                     dbus.PROPERTIES_IFACE)
+                break
 
-        self._icon = None
+        except dbus.DBusException:
+            logging.warning("Could not connect to UPower, won't show battery"
+                            "level.")
 
         self._setup()
 
@@ -171,18 +91,30 @@ class _TopBar(gtk.HBox):
         self._completion_level = value
         self._progressbar.set_fraction(self._completion_level / 100.0)
 
+    def _get_battery_level(self):
+        try:
+            return self._battery_props.Get(_UP_DEVICE_IFACE,
+                                           'Percentage')
+        except dbus.DBusException:
+            logging.exception('Error determining battery level:')
+            return 0
+
     def _setup(self):
         self._progressbar = gtk.ProgressBar()
         self._progressbar.props.discrete_blocks = 10
         self._progressbar.set_fraction(self._completion_level / 100.0)
         self.pack_start(self._progressbar, expand=True, fill=True)
-        if self._battery is not None:
-            icon_name = get_icon_state(_ICON_NAME, self._battery.props.level, step=-5)
-            self._icon = Icon(icon_name=icon_name)
-            self.pack_start(self._icon, expand=False, fill=False)
+        if self._battery_props is None:
+            return
+
+        level = self._get_battery_level()
+        icon_name = get_icon_state(_ICON_NAME, level, step=-5)
+        self._icon = Icon(icon_name=icon_name)
+        self.pack_start(self._icon, expand=False, fill=False)
 
-    def _battery_level_changed_cb(self, pspec, param):
-        icon_name = get_icon_state(_ICON_NAME, self._battery.props.level, step=-5)
+    def __battery_properties_changed_cb(self):
+        level = self._get_battery_level()
+        icon_name = get_icon_state(_ICON_NAME, level, step=-5)
         self._icon.props.icon_name = icon_name
 
 
-- 
1.7.2.3



More information about the Sugar-devel mailing list