ratbagd: always return an empty list for array-like properties []

In some cases we get Piper trying to use None as a list, see
https://github.com/libratbag/piper/issues/237

This can be reproduced by returning an error (e.g. -ENOMEM) from
ratbagd_get_devices(). That error isn't handled anywhere on the client side,
the effective result is that the property is None when calling
proxy.get_cached_property().

The error is visible on the bus:

method call time=1535084121.223284 sender=:1.1311 -> destination=:1.1310
  serial=7 path=/org/freedesktop/ratbag1;
  interface=org.freedesktop.DBus.Properties; member=GetAll
  string "org.freedesktop.ratbag1.Manager"
error time=1535084121.223433 sender=:1.1310 -> destination=:1.1311
  error_name=org.freedesktop.DBus.Error.NoMemory reply_serial=7
  string "Cannot allocate memory"

Make ratbagd.py more robust here and always return an empty list for those
properties where we expect an array. This papers over the real bug which is
that a) we need better logging in ratbagd on errors and b) something on the
other side needs to handle this error.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer
2018-08-24 14:03:17 +10:00
committed by Jente Hidskes
parent b738136154
commit f24cb6dc66

View File

@@ -253,7 +253,7 @@ class Ratbagd(_RatbagdDBus):
def __init__(self):
_RatbagdDBus.__init__(self, "Manager", None)
result = self._get_dbus_property("Devices")
result = self._get_dbus_property("Devices") or []
self._devices = [RatbagdDevice(objpath) for objpath in result]
def _on_properties_changed(self, proxy, changed_props, invalidated_props):
@@ -286,7 +286,7 @@ class Ratbagd(_RatbagdDBus):
def themes(self):
"""A list of theme names. The theme 'default' is guaranteed to be
available."""
return self._get_dbus_property("Themes")
return self._get_dbus_property("Themes") or []
def __enter__(self):
return self
@@ -321,7 +321,7 @@ class RatbagdDevice(_RatbagdDBus):
# FIXME: if we start adding and removing objects from this list,
# things will break!
result = self._get_dbus_property("Profiles")
result = self._get_dbus_property("Profiles") or []
self._profiles = [RatbagdProfile(objpath) for objpath in result]
for profile in self._profiles:
profile.connect("notify::is-active", self._on_active_profile_changed)
@@ -343,7 +343,7 @@ class RatbagdDevice(_RatbagdDBus):
if RatbagdDevice.CAP_SWITCHABLE_RESOLUTION is in device.capabilities:
do something
"""
return self._get_dbus_property("Capabilities")
return self._get_dbus_property("Capabilities") or []
@GObject.Property
def name(self):
@@ -448,7 +448,7 @@ class RatbagdProfile(_RatbagdDBus):
if RatbagdProfile.CAP_WRITABLE_NAME is in profile.capabilities:
do something
"""
return self._get_dbus_property("Capabilities")
return self._get_dbus_property("Capabilities") or []
@GObject.Property
def name(self):
@@ -565,7 +565,7 @@ class RatbagdResolution(_RatbagdDBus):
if RatbagdResolution.CAP_SEPARATE_XY_RESOLUTION is in resolution.capabilities:
do something
"""
return self._get_dbus_property("Capabilities")
return self._get_dbus_property("Capabilities") or []
@GObject.Property
def resolution(self):
@@ -596,12 +596,12 @@ class RatbagdResolution(_RatbagdDBus):
@GObject.Property
def resolutions(self):
"""The list of supported DPI values"""
return self._get_dbus_property("Resolutions")
return self._get_dbus_property("Resolutions") or []
@GObject.Property
def report_rates(self):
"""The list of supported report rates"""
return self._get_dbus_property("ReportRates")
return self._get_dbus_property("ReportRates") or []
@GObject.Property
def is_active(self):