Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package iio-sensor-proxy for
openSUSE:Factory checked in at 2026-03-06 18:16:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/iio-sensor-proxy (Old)
and /work/SRC/openSUSE:Factory/.iio-sensor-proxy.new.561 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "iio-sensor-proxy"
Fri Mar 6 18:16:56 2026 rev:27 rq:1336654 version:3.9
Changes:
--------
--- /work/SRC/openSUSE:Factory/iio-sensor-proxy/iio-sensor-proxy.changes
2025-08-12 17:03:46.721270507 +0200
+++
/work/SRC/openSUSE:Factory/.iio-sensor-proxy.new.561/iio-sensor-proxy.changes
2026-03-06 18:17:03.548336749 +0100
@@ -1,0 +2,13 @@
+Wed Mar 4 09:05:50 UTC 2026 - Bjørn Lie <[email protected]>
+
+- Update to version 3.9:
+ + SSC sensors are now supported through libssc. Light and compass
+ sensor are enabled by default. Accelerometer and proximity
+ remain experimental, but can be enabled through udev rules.
+ + SSC sensor support.
+ + Logging improvements for sensor discovery.
+ + Fix race condition during startup.
+- Pass ssc-support=disabled to meson setup, libssc is not available in
+ any current versions of openSUSE.
+
+-------------------------------------------------------------------
Old:
----
iio-sensor-proxy-3.8.tar.bz2
New:
----
iio-sensor-proxy-3.9.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ iio-sensor-proxy.spec ++++++
--- /var/tmp/diff_new_pack.pVcHuA/_old 2026-03-06 18:17:04.060358000 +0100
+++ /var/tmp/diff_new_pack.pVcHuA/_new 2026-03-06 18:17:04.060358000 +0100
@@ -1,7 +1,7 @@
#
# spec file for package iio-sensor-proxy
#
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
Name: iio-sensor-proxy
-Version: 3.8
+Version: 3.9
Release: 0
Summary: Proxy for IIO and input subsystems
License: GPL-3.0-only
@@ -54,7 +54,9 @@
%build
%meson -Dtests=false \
-Dgtk_doc=true \
- -Dgeoclue-user=srvGeoClue
+ -Dgeoclue-user=srvGeoClue \
+ -Dssc-support=disabled \
+ %{nil}
%meson_build
%install
++++++ iio-sensor-proxy-3.8.tar.bz2 -> iio-sensor-proxy-3.9.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/.gitlab-ci.yml
new/iio-sensor-proxy-3.9/.gitlab-ci.yml
--- old/iio-sensor-proxy-3.8/.gitlab-ci.yml 2025-08-09 13:57:19.000000000
+0200
+++ new/iio-sensor-proxy-3.9/.gitlab-ci.yml 2026-03-02 20:19:51.000000000
+0100
@@ -41,6 +41,28 @@
- "${CI_PROJECT_DIR}/_build/meson-dist"
- "${CI_PROJECT_DIR}/_build/docs/html/"
+build-debian-trixie-libssc:
+ before_script:
+ - apt-get update
+ - apt-get -y install eatmydata
+ - eatmydata apt-get -y install $DEPENDENCIES
+ - eatmydata apt-get -y install python3 python-is-python3 python3-dev
qrtr-tools libprotobuf-c-dev libprotobuf-dev protobuf-c-compiler
protobuf-compiler python3-gi libmbim-glib-dev libqmi-glib-dev python3-protobuf
libqrtr1
+ - git clone "https://codeberg.org/DylanVanAssche/libssc.git"
+ - cd libssc
+ - mkdir _build
+ - meson setup _build
+ - meson compile --verbose -C _build
+ - meson install --no-rebuild -C _build
+ - cd mocking
+ - ./ssc-server &
+ - cd ../..
+ script:
+ - meson -Dssc-support=enabled -Dtests=true -Dgtk_doc=true -Dgtk-tests=true
_build
+ - meson compile --verbose -C _build
+ - meson install -C _build
+ - meson dist -C _build
+ - meson test --verbose -C _build
+
pages:
needs:
- build-debian-trixie
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/NEWS
new/iio-sensor-proxy-3.9/NEWS
--- old/iio-sensor-proxy-3.8/NEWS 2025-08-09 13:57:19.000000000 +0200
+++ new/iio-sensor-proxy-3.9/NEWS 2026-03-02 20:19:51.000000000 +0100
@@ -1,3 +1,13 @@
+3.9
+---
+
+SSC sensors are now supported through libssc. Light and compass sensor are
enabled by default,
+accelerometer and proximity remain experimental, but can be enabled through
udev rules.
+
+- SSC sensor support.
+- Logging improvements for sensor discovery.
+- Fix race condition during startup.
+
3.8
---
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/data/80-iio-sensor-proxy.rules
new/iio-sensor-proxy-3.9/data/80-iio-sensor-proxy.rules
--- old/iio-sensor-proxy-3.8/data/80-iio-sensor-proxy.rules 2025-08-09
13:57:19.000000000 +0200
+++ new/iio-sensor-proxy-3.9/data/80-iio-sensor-proxy.rules 2026-03-02
20:19:51.000000000 +0100
@@ -18,6 +18,12 @@
SUBSYSTEM=="iio", TEST=="in_proximity0_raw",
ENV{IIO_SENSOR_PROXY_TYPE}+="iio-poll-proximity"
SUBSYSTEM=="input", ENV{ID_INPUT_ACCELEROMETER}=="1",
ENV{IIO_SENSOR_PROXY_TYPE}+="input-accel"
+# Set the sensor type for all the types we recognise for SDSP/ADSP with libssc.
+# Some devices expose the sensors via a separate SDSP while others re-use ADSP.
+# These DSPs expose itself as /dev/fastrpc-* in the misc subsystem.
+SUBSYSTEM=="misc", KERNEL=="fastrpc-adsp*",
ENV{IIO_SENSOR_PROXY_TYPE}+="ssc-light ssc-compass"
+SUBSYSTEM=="misc", KERNEL=="fastrpc-sdsp*",
ENV{IIO_SENSOR_PROXY_TYPE}+="ssc-light ssc-compass"
+
ENV{IIO_SENSOR_PROXY_TYPE}=="", GOTO="iio_sensor_proxy_end"
# We got here because we have a sensor type, which means we need the service
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/iio-sensor-proxy-3.8/data/iio-sensor-proxy.service.in
new/iio-sensor-proxy-3.9/data/iio-sensor-proxy.service.in
--- old/iio-sensor-proxy-3.8/data/iio-sensor-proxy.service.in 2025-08-09
13:57:19.000000000 +0200
+++ new/iio-sensor-proxy-3.9/data/iio-sensor-proxy.service.in 2026-03-02
20:19:51.000000000 +0100
@@ -14,6 +14,6 @@
ProtectHome=true
ProtectKernelModules=true
PrivateTmp=true
-RestrictAddressFamilies=AF_UNIX AF_LOCAL AF_NETLINK
+RestrictAddressFamilies=AF_UNIX AF_LOCAL AF_NETLINK AF_QIPCRTR
MemoryDenyWriteExecute=true
RestrictRealtime=true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/data/meson.build
new/iio-sensor-proxy-3.9/data/meson.build
--- old/iio-sensor-proxy-3.8/data/meson.build 2025-08-09 13:57:19.000000000
+0200
+++ new/iio-sensor-proxy-3.9/data/meson.build 2026-03-02 20:19:51.000000000
+0100
@@ -1,3 +1,7 @@
+rules = files(
+ '80-iio-sensor-proxy.rules'
+)
+
install_data(
'80-iio-sensor-proxy.rules',
install_dir: udev_rules_dir
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/meson.build
new/iio-sensor-proxy-3.9/meson.build
--- old/iio-sensor-proxy-3.8/meson.build 2025-08-09 13:57:19.000000000
+0200
+++ new/iio-sensor-proxy-3.9/meson.build 2026-03-02 20:19:51.000000000
+0100
@@ -1,5 +1,5 @@
project('iio-sensor-proxy', [ 'c' ],
- version: '3.8',
+ version: '3.9',
license: 'GPLv3+',
default_options: [
'buildtype=debugoptimized',
@@ -46,6 +46,7 @@
gudev_dep = dependency('gudev-1.0', version: '>= 237')
polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.91')
polkit_policy_directory =
polkit_gobject_dep.get_pkgconfig_variable('policydir')
+libssc_dep = dependency('libssc', version: '>=0.2.1', required:
get_option('ssc-support'))
xmllint = find_program('xmllint', required: false)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/meson_options.txt
new/iio-sensor-proxy-3.9/meson_options.txt
--- old/iio-sensor-proxy-3.8/meson_options.txt 2025-08-09 13:57:19.000000000
+0200
+++ new/iio-sensor-proxy-3.9/meson_options.txt 2026-03-02 20:19:51.000000000
+0100
@@ -18,6 +18,10 @@
description: 'The USER (existing) as which geoclue service is running',
type: 'string',
value: 'geoclue')
+option('ssc-support',
+ description: 'Enable Qualcomm SSC support',
+ type: 'feature',
+ value: 'auto')
option('gtk_doc',
type: 'boolean',
value: false,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/src/drivers.h
new/iio-sensor-proxy-3.9/src/drivers.h
--- old/iio-sensor-proxy-3.8/src/drivers.h 2025-08-09 13:57:19.000000000
+0200
+++ new/iio-sensor-proxy-3.9/src/drivers.h 2026-03-02 20:19:51.000000000
+0100
@@ -161,4 +161,11 @@
extern SensorDriver iio_poll_proximity;
extern SensorDriver input_proximity;
+#ifdef HAS_LIBSSC
+extern SensorDriver ssc_proximity;
+extern SensorDriver ssc_light;
+extern SensorDriver ssc_accel;
+extern SensorDriver ssc_compass;
+#endif
+
gboolean drv_check_udev_sensor_type (GUdevDevice *device, const gchar *match,
const char *name);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/src/drv-input-proximity.c
new/iio-sensor-proxy-3.9/src/drv-input-proximity.c
--- old/iio-sensor-proxy-3.8/src/drv-input-proximity.c 2025-08-09
13:57:19.000000000 +0200
+++ new/iio-sensor-proxy-3.9/src/drv-input-proximity.c 2026-03-02
20:19:51.000000000 +0100
@@ -73,31 +73,39 @@
gboolean ret = FALSE;
g_autofree gchar *contents = NULL;
g_autofree gchar *native_path = NULL;
- g_autofree gchar *path;
+ g_autofree gchar *path = NULL;
g_autoptr(GError) error = NULL;
gint num_bits;
- /* check if the input device has switch capabilities */
+ /* only process devices on the input subsystem */
+ if (g_strcmp0 (g_udev_device_get_subsystem (device), "input") != 0)
+ return FALSE;
+
+ /* ignore devices which do not report any switch capabilities */
native_path = g_strdup (g_udev_device_get_sysfs_path (device));
path = g_build_filename (native_path, "../capabilities/sw", NULL);
if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
- g_warning_once ("Not a switch [%s]", path);
return FALSE;
}
ret = g_file_get_contents (path, &contents, NULL, &error);
+ /* for completeness, report read failures */
if (!ret) {
- g_warning_once ("Failed to read contents of [%s]: %s",
+ g_warning ("Failed to read contents of [%s]: %s",
path, error->message);
return FALSE;
}
- /* convert attributes of input device into a bitmask */
+ /* confirm that the device has a usable switch */
num_bits = input_str_to_bitmask (contents, bitmask, sizeof (bitmask));
- if ((num_bits == 0) || (num_bits >= SW_CNT)) {
- g_warning_once ("Invalid bitmask entry for %s", native_path);
+ if (num_bits == 0) {
+ g_debug ("%s is not a valid switch", native_path);
+ } else if (num_bits >= SW_CNT) {
+ g_debug ("%s reports an invalid number of switches. Was
iio-sensor-proxy compiled with kernel headers not matching the running kernel?",
+ native_path);
return FALSE;
}
+
return TRUE;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/src/drv-ssc-accel.c
new/iio-sensor-proxy-3.9/src/drv-ssc-accel.c
--- old/iio-sensor-proxy-3.8/src/drv-ssc-accel.c 1970-01-01
01:00:00.000000000 +0100
+++ new/iio-sensor-proxy-3.9/src/drv-ssc-accel.c 2026-03-02
20:19:51.000000000 +0100
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2023-2025 Dylan Van Assche
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published by
+ * the Free Software Foundation.
+ */
+
+#include "drivers.h"
+#include "accel-mount-matrix.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <gio/gio.h>
+#include <libssc-sensor.h>
+#include <libssc-sensor-accelerometer.h>
+
+typedef struct DrvData {
+ SSCSensorAccelerometer *sensor;
+ gulong measurement_id;
+ AccelVec3 *mount_matrix;
+ AccelLocation location;
+ AccelScale scale;
+} DrvData;
+
+static gboolean
+ssc_accelerometer_discover (GUdevDevice *device)
+{
+ g_autoptr(SSCSensorAccelerometer) sensor = NULL;
+
+ /* Verify presence of FastRPC device */
+ if (!drv_check_udev_sensor_type (device, "ssc-accel", NULL))
+ return FALSE;
+
+ /* Open and close SSC accelerometer for discovering */
+ sensor = ssc_sensor_accelerometer_new_sync (NULL, NULL);
+ if (!sensor)
+ return FALSE;
+
+ if (!ssc_sensor_accelerometer_close_sync (sensor, NULL, NULL))
+ return FALSE;
+
+ g_debug ("Found SSC accelerometer at %s", g_udev_device_get_sysfs_path
(device));
+ return TRUE;
+}
+
+static void
+measurement_cb (SSCSensorAccelerometer *sensor, gfloat accel_x, gfloat
accel_y, gfloat accel_z, gpointer user_data)
+{
+ SensorDevice *sensor_device = user_data;
+ DrvData *drv_data = (DrvData *) sensor_device->priv;
+ AccelReadings readings;
+ AccelVec3 tmp;
+
+ tmp.x = accel_x;
+ tmp.y = accel_y;
+ tmp.z = accel_z;
+
+ if (!apply_mount_matrix (drv_data->mount_matrix, &tmp))
+ g_warning ("Could not apply mount matrix");
+
+ readings.accel_x = tmp.x;
+ readings.accel_y = tmp.y;
+ readings.accel_z = tmp.z;
+ copy_accel_scale (&readings.scale, drv_data->scale);
+
+ sensor_device->callback_func (sensor_device, (gpointer) &readings,
sensor_device->user_data);
+}
+
+static SensorDevice *
+ssc_accelerometer_open (GUdevDevice *device)
+{
+ g_autoptr(GError) error = NULL;
+ SensorDevice *sensor_device;
+ DrvData *drv_data;
+
+ sensor_device = g_new0 (SensorDevice, 1);
+ sensor_device->priv = g_new0 (DrvData, 1);
+
+ drv_data = (DrvData *) sensor_device->priv;
+ drv_data->sensor = ssc_sensor_accelerometer_new_sync (NULL, &error);
+ if (!drv_data->sensor)
+ g_warning ("Creating SSC accelerometer sensor failed: %s",
error->message);
+ else
+ g_object_get (drv_data->sensor,
+ SSC_SENSOR_NAME, &sensor_device->name,
+ NULL);
+
+ /* Setup accel attributes */
+ drv_data->mount_matrix = setup_mount_matrix (device);
+ drv_data->location = setup_accel_location (device);
+ set_accel_scale (&drv_data->scale, 1.0);
+
+ return sensor_device;
+}
+
+static void
+ssc_accelerometer_set_polling (SensorDevice *sensor_device, gboolean state)
+{
+ DrvData *drv_data = (DrvData *) sensor_device->priv;
+ g_autoptr(GError) error = NULL;
+ if (state) {
+ if (drv_data->measurement_id)
+ return;
+
+ /* Start listening for measurements */
+ drv_data->measurement_id = g_signal_connect (drv_data->sensor,
+ "measurement",
+ G_CALLBACK
(measurement_cb),
+ sensor_device);
+ /* Enable sensor */
+ if (!ssc_sensor_accelerometer_open_sync (drv_data->sensor,
NULL, &error)) {
+ g_warning ("Opening SSC accelerometer sensor failed:
%s", error->message);
+ return;
+ }
+ } else {
+ if (!drv_data->measurement_id)
+ return;
+
+ /* Stop listening for measurements */
+ g_clear_signal_handler (&drv_data->measurement_id,
drv_data->sensor);
+
+ /* Disable sensor */
+ if (!ssc_sensor_accelerometer_close_sync (drv_data->sensor,
NULL, &error))
+ g_warning ("Closing SSC accelerometer sensor failed:
%s", error->message);
+ }
+}
+
+static void
+ssc_accelerometer_close (SensorDevice *sensor_device)
+{
+ g_autoptr(GError) error = NULL;
+ DrvData *drv_data = (DrvData *) sensor_device->priv;
+
+ g_clear_object (&drv_data->sensor);
+ g_clear_pointer (&drv_data->mount_matrix, g_free);
+ g_clear_pointer (&sensor_device->priv, g_free);
+ g_free (sensor_device);
+}
+
+SensorDriver ssc_accel = {
+ .driver_name = "SSC accelerometer sensor",
+ .type = DRIVER_TYPE_ACCEL,
+
+ .discover = ssc_accelerometer_discover,
+ .open = ssc_accelerometer_open,
+ .set_polling = ssc_accelerometer_set_polling,
+ .close = ssc_accelerometer_close,
+};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/src/drv-ssc-compass.c
new/iio-sensor-proxy-3.9/src/drv-ssc-compass.c
--- old/iio-sensor-proxy-3.8/src/drv-ssc-compass.c 1970-01-01
01:00:00.000000000 +0100
+++ new/iio-sensor-proxy-3.9/src/drv-ssc-compass.c 2026-03-02
20:19:51.000000000 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2023-2025 Dylan Van Assche
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published by
+ * the Free Software Foundation.
+ */
+
+#include "drivers.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <gio/gio.h>
+#include <libssc-sensor.h>
+#include <libssc-sensor-compass.h>
+
+typedef struct DrvData {
+ SSCSensorCompass *sensor;
+ gulong measurement_id;
+} DrvData;
+
+static gboolean
+ssc_compass_discover (GUdevDevice *device)
+{
+ g_autoptr(SSCSensorCompass) sensor = NULL;
+
+ /* Verify presence of FastRPC device */
+ if (!drv_check_udev_sensor_type (device, "ssc-compass", NULL))
+ return FALSE;
+
+ /* Open and close SSC compass for discovering */
+ sensor = ssc_sensor_compass_new_sync (NULL, NULL);
+ if (!sensor)
+ return FALSE;
+
+ if (!ssc_sensor_compass_close_sync (sensor, NULL, NULL))
+ return FALSE;
+
+ g_debug ("Found SSC compass at %s", g_udev_device_get_sysfs_path
(device));
+ return TRUE;
+}
+
+static void
+measurement_cb (SSCSensorCompass *sensor, gfloat azimuth, gpointer user_data)
+{
+ SensorDevice *sensor_device = user_data;
+ CompassReadings readings;
+
+ readings.heading = azimuth;
+
+ sensor_device->callback_func (sensor_device, (gpointer) &readings,
sensor_device->user_data);
+}
+
+static SensorDevice *
+ssc_compass_open (GUdevDevice *device)
+{
+ g_autoptr(GError) error = NULL;
+ SensorDevice *sensor_device;
+ DrvData *drv_data;
+
+ sensor_device = g_new0 (SensorDevice, 1);
+ sensor_device->priv = g_new0 (DrvData, 1);
+
+ drv_data = (DrvData *) sensor_device->priv;
+ drv_data->sensor = ssc_sensor_compass_new_sync (NULL, &error);
+ if (!drv_data->sensor)
+ g_warning ("Creating SSC compass sensor failed: %s",
error->message);
+ else {
+ g_object_get (drv_data->sensor,
+ SSC_SENSOR_NAME, &sensor_device->name,
+ NULL);
+ }
+
+ return sensor_device;
+}
+
+static void
+ssc_compass_set_polling (SensorDevice *sensor_device, gboolean state)
+{
+ DrvData *drv_data = (DrvData *) sensor_device->priv;
+ g_autoptr(GError) error = NULL;
+
+ if (state) {
+ if (drv_data->measurement_id)
+ return;
+ /* Start listening for measurements */
+ drv_data->measurement_id = g_signal_connect (drv_data->sensor,
+ "measurement",
+ G_CALLBACK
(measurement_cb),
+ sensor_device);
+
+ /* Enable sensor */
+ if (!ssc_sensor_compass_open_sync (drv_data->sensor, NULL,
&error))
+ g_warning ("Opening SSC compass sensor failed: %s",
error->message);
+ } else {
+ if (!drv_data->measurement_id)
+ return;
+
+ /* Stop listening for measurements */
+ g_clear_signal_handler (&drv_data->measurement_id,
drv_data->sensor);
+
+ /* Disable sensor */
+ if (!ssc_sensor_compass_close_sync (drv_data->sensor, NULL,
&error))
+ g_warning ("Closing SSC compass sensor failed: %s",
error->message);
+ }
+}
+
+static void
+ssc_compass_close (SensorDevice *sensor_device)
+{
+ DrvData *drv_data = (DrvData *) sensor_device->priv;
+
+ g_clear_object (&drv_data->sensor);
+ g_clear_pointer (&sensor_device->name, g_free);
+ g_clear_pointer (&sensor_device->priv, g_free);
+ g_free (sensor_device);
+}
+
+SensorDriver ssc_compass = {
+ .driver_name = "SSC compass sensor",
+ .type = DRIVER_TYPE_COMPASS,
+
+ .discover = ssc_compass_discover,
+ .open = ssc_compass_open,
+ .set_polling = ssc_compass_set_polling,
+ .close = ssc_compass_close,
+};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/src/drv-ssc-light.c
new/iio-sensor-proxy-3.9/src/drv-ssc-light.c
--- old/iio-sensor-proxy-3.8/src/drv-ssc-light.c 1970-01-01
01:00:00.000000000 +0100
+++ new/iio-sensor-proxy-3.9/src/drv-ssc-light.c 2026-03-02
20:19:51.000000000 +0100
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2023-2025 Dylan Van Assche
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published by
+ * the Free Software Foundation.
+ */
+
+#include "drivers.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <gio/gio.h>
+#include <libssc-sensor.h>
+#include <libssc-sensor-light.h>
+
+typedef struct DrvData {
+ SSCSensorLight *sensor;
+ gulong measurement_id;
+} DrvData;
+
+static gboolean
+ssc_light_discover (GUdevDevice *device)
+{
+ g_autoptr(SSCSensorLight) sensor = NULL;
+
+ /* Verify presence of FastRPC device */
+ if (!drv_check_udev_sensor_type (device, "ssc-light", NULL))
+ return FALSE;
+
+ /* Open and close SSC light sensor for discovering */
+ sensor = ssc_sensor_light_new_sync (NULL, NULL);
+ if (!sensor)
+ return FALSE;
+
+ if (!ssc_sensor_light_close_sync (sensor, NULL, NULL))
+ return FALSE;
+
+ g_debug ("Found SSC light at %s", g_udev_device_get_sysfs_path
(device));
+ return TRUE;
+}
+
+static void
+measurement_cb (SSCSensorLight *sensor, gfloat intensity, gpointer user_data)
+{
+ SensorDevice *sensor_device = user_data;
+ LightReadings readings;
+
+ readings.level = intensity;
+ readings.uses_lux = TRUE;
+ sensor_device->callback_func (sensor_device, (gpointer) &readings,
sensor_device->user_data);
+}
+
+static SensorDevice *
+ssc_light_open (GUdevDevice *device)
+{
+ g_autoptr(GError) error = NULL;
+ SensorDevice *sensor_device;
+ DrvData *drv_data;
+
+ sensor_device = g_new0 (SensorDevice, 1);
+ sensor_device->priv = g_new0 (DrvData, 1);
+
+ drv_data = (DrvData *) sensor_device->priv;
+ drv_data->sensor = ssc_sensor_light_new_sync (NULL, &error);
+ if (!drv_data->sensor)
+ g_warning ("Creating SSC light sensor failed: %s",
error->message);
+ else
+ g_object_get (drv_data->sensor,
+ SSC_SENSOR_NAME, &sensor_device->name,
+ NULL);
+
+ return sensor_device;
+}
+
+static void
+ssc_light_set_polling (SensorDevice *sensor_device, gboolean state)
+{
+ DrvData *drv_data = (DrvData *) sensor_device->priv;
+ g_autoptr (GError) error = NULL;
+ if (state) {
+ if (drv_data->measurement_id)
+ return;
+ /* Start listening for measurements */
+ drv_data->measurement_id = g_signal_connect (drv_data->sensor,
+ "measurement",
+ G_CALLBACK
(measurement_cb),
+ sensor_device);
+ /* Enable sensor */
+ if (!ssc_sensor_light_open_sync (drv_data->sensor, NULL,
&error))
+ g_warning ("Opening SSC light sensor failed: %s",
error->message);
+ } else {
+ if (!drv_data->measurement_id)
+ return;
+
+ /* Stop listening for measurements */
+ g_clear_signal_handler (&drv_data->measurement_id,
drv_data->sensor);
+
+ /* Disable sensor */
+ if (!ssc_sensor_light_close_sync (drv_data->sensor, NULL,
&error))
+ g_warning ("Closing SSC light sensor failed: %s",
error->message);
+ }
+}
+
+static void
+ssc_light_close (SensorDevice *sensor_device)
+{
+ g_autoptr(GError) error = NULL;
+ DrvData *drv_data = (DrvData *) sensor_device->priv;
+
+ g_clear_object (&drv_data->sensor);
+ g_clear_pointer (&sensor_device->priv, g_free);
+ g_free (sensor_device);
+}
+
+SensorDriver ssc_light = {
+ .driver_name = "SSC light sensor",
+ .type = DRIVER_TYPE_LIGHT,
+
+ .discover = ssc_light_discover,
+ .open = ssc_light_open,
+ .set_polling = ssc_light_set_polling,
+ .close = ssc_light_close,
+};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/src/drv-ssc-proximity.c
new/iio-sensor-proxy-3.9/src/drv-ssc-proximity.c
--- old/iio-sensor-proxy-3.8/src/drv-ssc-proximity.c 1970-01-01
01:00:00.000000000 +0100
+++ new/iio-sensor-proxy-3.9/src/drv-ssc-proximity.c 2026-03-02
20:19:51.000000000 +0100
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2023-2025 Dylan Van Assche
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3 as published by
+ * the Free Software Foundation.
+ */
+
+#include "drivers.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <gio/gio.h>
+#include <libssc-sensor.h>
+#include <libssc-sensor-proximity.h>
+
+typedef struct DrvData {
+ SSCSensorProximity *sensor;
+ gulong measurement_id;
+} DrvData;
+
+static gboolean
+ssc_proximity_discover (GUdevDevice *device)
+{
+ SSCSensorProximity *sensor = NULL;
+
+ /* Verify presence of FastRPC device */
+ if (!drv_check_udev_sensor_type (device, "ssc-proximity", NULL))
+ return FALSE;
+
+ /* Open and close SSC proximity sensor for discovering */
+ sensor = ssc_sensor_proximity_new_sync (NULL, NULL);
+ if (!sensor)
+ return FALSE;
+
+ if (!ssc_sensor_proximity_close_sync (sensor, NULL, NULL)) {
+ g_clear_object (&sensor);
+ return FALSE;
+ }
+
+ g_clear_object (&sensor);
+
+ g_debug ("Found SSC proximity at %s", g_udev_device_get_sysfs_path
(device));
+ return TRUE;
+}
+
+static void
+measurement_cb (SSCSensorProximity *sensor, gboolean near, gpointer user_data)
+{
+ SensorDevice *sensor_device = user_data;
+ ProximityReadings readings;
+
+ readings.is_near = near ? PROXIMITY_NEAR_TRUE : PROXIMITY_NEAR_FALSE;
+ sensor_device->callback_func (sensor_device, (gpointer) &readings,
sensor_device->user_data);
+}
+
+static SensorDevice *
+ssc_proximity_open (GUdevDevice *device)
+{
+ g_autoptr(GError) error = NULL;
+ SensorDevice *sensor_device;
+ DrvData *drv_data;
+
+ sensor_device = g_new0 (SensorDevice, 1);
+ sensor_device->priv = g_new0 (DrvData, 1);
+ drv_data = (DrvData *) sensor_device->priv;
+ drv_data->sensor = ssc_sensor_proximity_new_sync (NULL, &error);
+ if (!drv_data->sensor)
+ g_warning ("Creating SSC proximity sensor failed: %s",
error->message);
+ else
+ g_object_get (drv_data->sensor,
+ SSC_SENSOR_NAME, &sensor_device->name,
+ NULL);
+
+ return sensor_device;
+}
+
+static void
+ssc_proximity_set_polling (SensorDevice *sensor_device, gboolean state)
+{
+ DrvData *drv_data = (DrvData *) sensor_device->priv;
+ g_autoptr(GError) error = NULL;
+ if (state) {
+ if (drv_data->measurement_id)
+ return;
+ /* Start listening for measurements */
+ drv_data->measurement_id = g_signal_connect (drv_data->sensor,
+ "measurement",
+ G_CALLBACK
(measurement_cb),
+ sensor_device);
+
+ /* Enable sensor */
+ if (!ssc_sensor_proximity_open_sync (drv_data->sensor, NULL,
&error)) {
+ g_warning ("Opening SSC proximity sensor failed: %s",
error ? error->message : "UNKNOWN");
+ return;
+ }
+ } else {
+ if (!drv_data->measurement_id)
+ return;
+ /* Stop listening for measurements */
+ g_clear_signal_handler (&drv_data->measurement_id,
drv_data->sensor);
+ /* Disable sensor */
+ if (!ssc_sensor_proximity_close_sync (drv_data->sensor, NULL,
&error))
+ g_warning ("Closing SSC proximity sensor failed: %s",
error->message);
+ }
+}
+
+static void
+ssc_proximity_close (SensorDevice *sensor_device)
+{
+ DrvData *drv_data = (DrvData *) sensor_device->priv;
+
+ g_clear_object (&drv_data->sensor);
+ g_clear_pointer (&sensor_device->priv, g_free);
+ g_free (sensor_device);
+}
+
+SensorDriver ssc_proximity = {
+ .driver_name = "SSC proximity sensor",
+ .type = DRIVER_TYPE_PROXIMITY,
+
+ .discover = ssc_proximity_discover,
+ .open = ssc_proximity_open,
+ .set_polling = ssc_proximity_set_polling,
+ .close = ssc_proximity_close,
+};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/src/iio-sensor-proxy.c
new/iio-sensor-proxy-3.9/src/iio-sensor-proxy.c
--- old/iio-sensor-proxy-3.8/src/iio-sensor-proxy.c 2025-08-09
13:57:19.000000000 +0200
+++ new/iio-sensor-proxy-3.9/src/iio-sensor-proxy.c 2026-03-02
20:19:51.000000000 +0100
@@ -79,6 +79,12 @@
&iio_buffer_compass,
&iio_poll_proximity,
&input_proximity,
+#ifdef HAS_LIBSSC
+ &ssc_proximity,
+ &ssc_light,
+ &ssc_accel,
+ &ssc_compass,
+#endif
};
static ReadingsUpdateFunc driver_type_to_callback_func (DriverType type);
@@ -128,6 +134,11 @@
platform = g_udev_client_query_by_subsystem (client, "platform");
devices = g_list_concat (devices, input);
devices = g_list_concat (devices, platform);
+#ifdef HAS_LIBSSC
+ GList *fastrpc;
+ fastrpc = g_udev_client_query_by_subsystem (client, "misc");
+ devices = g_list_concat (devices, fastrpc);
+#endif
/* Find the devices */
for (l = devices; l != NULL; l = l->next) {
@@ -701,6 +712,16 @@
gpointer user_data)
{
SensorData *data = user_data;
+ const gchar * const subsystems[] = {
+ "iio",
+ "input",
+ "platform",
+#ifdef HAS_LIBSSC
+ "misc",
+#endif
+ NULL
+ };
+ guint i;
g_dbus_connection_register_object (connection,
SENSOR_PROXY_DBUS_PATH,
@@ -718,6 +739,12 @@
NULL,
NULL);
+ /* Initialize DBus clients hash table before DBus is fully exposed */
+ data->client = g_udev_client_new (subsystems);
+
+ for (guint i = 0; i < NUM_SENSOR_TYPES; i++)
+ data->clients[i] = create_clients_hash_table ();
+
data->connection = g_object_ref (connection);
}
@@ -727,10 +754,8 @@
gpointer user_data)
{
SensorData *data = user_data;
- const gchar * const subsystems[] = { "iio", "input", "platform", NULL };
guint i;
- data->client = g_udev_client_new (subsystems);
if (!find_sensors (data->client, data))
goto bail;
@@ -740,7 +765,6 @@
for (i = 0; i < NUM_SENSOR_TYPES; i++) {
SensorDevice *sensor_device;
- data->clients[i] = create_clients_hash_table ();
data->sensor_startup_dbus_invocations_delayed[i] =
g_ptr_array_new ();
if (!driver_type_exists (data, i))
@@ -766,7 +790,7 @@
bail:
data->ret = 0;
- g_debug ("No sensors or missing kernel drivers for the sensors");
+ g_message ("No sensors or missing kernel drivers for the sensors.
Exiting");
g_main_loop_quit (data->loop);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/src/meson.build
new/iio-sensor-proxy-3.9/src/meson.build
--- old/iio-sensor-proxy-3.8/src/meson.build 2025-08-09 13:57:19.000000000
+0200
+++ new/iio-sensor-proxy-3.9/src/meson.build 2026-03-02 20:19:51.000000000
+0100
@@ -1,5 +1,8 @@
config_h = configuration_data()
config_h.set_quoted('VERSION', meson.project_version())
+if get_option('ssc-support').enabled()
+ config_h.set_quoted('HAS_LIBSSC', '1')
+endif
config_h_files = configure_file(
output: 'config.h',
configuration: config_h
@@ -7,6 +10,10 @@
deps = [ gio_dep, gudev_dep, mathlib_dep, polkit_gobject_dep ]
+if get_option('ssc-support').enabled()
+ deps = deps + [ libssc_dep ]
+endif
+
resources = gnome.compile_resources(
'iio-sensor-proxy-resources', 'iio-sensor-proxy.gresource.xml',
c_name: 'iio_sensor_proxy',
@@ -38,6 +45,15 @@
config_h_files,
]
+if get_option('ssc-support').enabled()
+ sources = sources + [
+ 'drv-ssc-proximity.c',
+ 'drv-ssc-light.c',
+ 'drv-ssc-accel.c',
+ 'drv-ssc-compass.c',
+ ]
+endif
+
executable('iio-sensor-proxy',
sources,
dependencies: deps,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/tests/integration-test.py
new/iio-sensor-proxy-3.9/tests/integration-test.py
--- old/iio-sensor-proxy-3.8/tests/integration-test.py 2025-08-09
13:57:19.000000000 +0200
+++ new/iio-sensor-proxy-3.9/tests/integration-test.py 2026-03-02
20:19:51.000000000 +0100
@@ -56,6 +56,7 @@
def setUpClass(cls):
# run from local build tree if we are in one, otherwise use system
instance
builddir = os.getenv('top_builddir', '.')
+ print(os.path.join(builddir, 'src', 'iio-sensor-proxy'))
if os.access(os.path.join(builddir, 'src', 'iio-sensor-proxy'),
os.X_OK):
cls.daemon_path = os.path.join(builddir, 'src', 'iio-sensor-proxy')
cls.monitor_sensor_path = os.path.join(builddir, 'src',
'monitor-sensor')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/tests/meson.build
new/iio-sensor-proxy-3.9/tests/meson.build
--- old/iio-sensor-proxy-3.8/tests/meson.build 2025-08-09 13:57:19.000000000
+0200
+++ new/iio-sensor-proxy-3.9/tests/meson.build 2026-03-02 20:19:51.000000000
+0100
@@ -16,3 +16,17 @@
env: envs,
)
endforeach
+
+if get_option('ssc-support').enabled()
+ r = run_command(unittest_inspector, files('ssc-test.py'), check: true)
+ unit_tests = r.stdout().strip().split('\n')
+ foreach ut: unit_tests
+ ut_args = files('ssc-test.py')
+ ut_args += ut
+ test(ut,
+ python3,
+ args: ut_args,
+ env: envs,
+ )
+ endforeach
+endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/iio-sensor-proxy-3.8/tests/ssc-test.py
new/iio-sensor-proxy-3.9/tests/ssc-test.py
--- old/iio-sensor-proxy-3.8/tests/ssc-test.py 1970-01-01 01:00:00.000000000
+0100
+++ new/iio-sensor-proxy-3.9/tests/ssc-test.py 2026-03-02 20:19:51.000000000
+0100
@@ -0,0 +1,375 @@
+#!/usr/bin/python3
+
+# iio-sensor-proxy integration test suite
+#
+# Run in built tree to test local built binaries, or from anywhere else to test
+# system installed binaries.
+#
+# Copyright: (C) 2011 Martin Pitt <[email protected]>
+# (C) 2021 Bastien Nocera <[email protected]>
+#
+# 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.
+
+import os
+import sys
+import dbus
+import dbusmock
+import gi
+import tempfile
+import psutil
+import subprocess
+import unittest
+import locale
+import time
+
+try:
+ from gi.repository import GLib
+ from gi.repository import Gio
+except ImportError as e:
+ sys.stderr.write('PyGobject not available for Python 3, or missing GI
typelibs: %s\n' % str(e))
+ sys.exit(1)
+
+try:
+ gi.require_version('UMockdev', '1.0')
+ from gi.repository import UMockdev
+except ImportError:
+ sys.stderr.write('umockdev not available
(https://github.com/martinpitt/umockdev)\n')
+ sys.exit(1)
+
+
+SP = 'net.hadess.SensorProxy'
+SP_PATH = '/net/hadess/SensorProxy'
+SP_COMPASS = 'net.hadess.SensorProxy.Compass'
+SP_COMPASS_PATH = '/net/hadess/SensorProxy/Compass'
+
+class Tests(dbusmock.DBusTestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ # run from local build tree if we are in one, otherwise use system
instance
+ builddir = os.getenv('top_builddir', '.')
+ print(os.path.join(builddir, 'src', 'iio-sensor-proxy'))
+ if os.access(os.path.join(builddir, 'src', 'iio-sensor-proxy'),
os.X_OK):
+ cls.daemon_path = os.path.join(builddir, 'src', 'iio-sensor-proxy')
+ cls.monitor_sensor_path = os.path.join(builddir, 'src',
'monitor-sensor')
+ print('Testing binaries from local build tree (%s)' %
cls.daemon_path)
+ elif os.environ.get('UNDER_JHBUILD', False):
+ jhbuild_prefix = os.environ['JHBUILD_PREFIX']
+ cls.daemon_path = os.path.join(jhbuild_prefix, 'libexec',
'iio-sensor-proxy')
+ cls.monitor_sensor_path = os.path.join(jhbuild_prefix, 'bin',
'monitor-sensor')
+ print('Testing binaries from JHBuild (%s)' % cls.daemon_path)
+ else:
+ cls.daemon_path = None
+ with open('/usr/lib/systemd/system/iio-sensor-proxy.service') as f:
+ for line in f:
+ if line.startswith('ExecStart='):
+ cls.daemon_path = line.split('=', 1)[1].strip()
+ break
+ assert cls.daemon_path, 'could not determine daemon path from
systemd .service file'
+ cls.monitor_sensor_path = '/usr/bin/monitor-sensor'
+ print('Testing installed system binary (%s)' % cls.daemon_path)
+
+ # fail on CRITICALs on client and server side
+ GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_WARNING |
+ GLib.LogLevelFlags.LEVEL_ERROR |
+ GLib.LogLevelFlags.LEVEL_CRITICAL)
+ os.environ['G_DEBUG'] = 'fatal_warnings'
+
+ # set up a fake system D-BUS
+ cls.test_bus = Gio.TestDBus.new(Gio.TestDBusFlags.NONE)
+ cls.test_bus.up()
+ try:
+ del os.environ['DBUS_SESSION_BUS_ADDRESS']
+ except KeyError:
+ pass
+ os.environ['DBUS_SYSTEM_BUS_ADDRESS'] = cls.test_bus.get_bus_address()
+
+ cls.dbus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
+ cls.dbus_con = cls.get_dbus(True)
+
+ # Some test outputs require the daemon to run under the fr locale:
+ # so check if that's available
+ try:
+ old_loc = locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8')
+ locale.setlocale(locale.LC_ALL, old_loc)
+ # We need to make sure the decimal point is correct as on musl libc
the above
+ # succeeds yet the tests just fail due to the output being in
unexpected format
+ cls.has_fr = locale.localeconv()["decimal_point"] == ","
+ except:
+ cls.has_fr = False
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.test_bus.down()
+ dbusmock.DBusTestCase.tearDownClass()
+
+ def setUp(self):
+ '''Set up a local umockdev testbed.
+
+ The testbed is initially empty.
+ '''
+ self.testbed = UMockdev.Testbed.new()
+ self.polkitd, obj_polkit = self.spawn_server_template(
+ 'polkitd', {}, stdout=subprocess.PIPE)
+ obj_polkit.SetAllowed(['net.hadess.SensorProxy.claim-sensor'])
+
+ self.proxy = None
+ self.log = None
+ self.daemon = None
+
+ def run(self, result=None):
+ super(Tests, self).run(result)
+ if result and len(result.errors) + len(result.failures) > 0 and
self.log:
+ with open(self.log.name) as f:
+ sys.stderr.write('\n-------------- daemon log:
----------------\n')
+ sys.stderr.write(f.read())
+ sys.stderr.write('------------------------------\n')
+
+ def tearDown(self):
+ del self.testbed
+ self.stop_daemon()
+
+ if self.polkitd:
+ try:
+ self.polkitd.kill()
+ except OSError:
+ pass
+ self.polkitd.wait()
+ self.polkitd = None
+
+ #
+ # Daemon control and D-BUS I/O
+ #
+
+ def start_daemon(self, env = None, wrapper = None):
+ '''Start daemon and create DBus proxy.
+
+ When done, this sets self.proxy as the Gio.DBusProxy for
power-profiles-daemon.
+ '''
+ if not env:
+ env = os.environ.copy()
+ env['G_DEBUG'] = 'fatal-criticals'
+ env['G_MESSAGES_DEBUG'] = 'all'
+ env['UMOCKDEV_DEBUG'] = 'all'
+ # note: Python doesn't propagate the setenv from Testbed.new(), so we
+ # have to do that ourselves
+ env['UMOCKDEV_DIR'] = self.testbed.get_root_dir()
+ self.log = tempfile.NamedTemporaryFile()
+ timeout_multiplier = 1
+ if wrapper:
+ daemon_path = wrapper + [ self.daemon_path ]
+ else:
+ daemon_path = [ self.daemon_path ]
+ if os.getenv('VALGRIND') != None:
+ daemon_path = ['valgrind'] + daemon_path + ['-v']
+ timeout_multiplier = 10
+ else:
+ daemon_path = daemon_path + ['-v']
+
+ self.daemon = subprocess.Popen(daemon_path,
+ env=env, stdout=self.log,
+ stderr=subprocess.STDOUT)
+
+ # wait until the daemon gets online
+ timeout = 100 * timeout_multiplier
+ while timeout > 0:
+ time.sleep(0.1)
+ timeout -= 1
+ try:
+ self.get_dbus_property('HasAccelerometer')
+ break
+ except GLib.GError:
+ pass
+ else:
+ self.fail('daemon did not start in 10 seconds')
+
+ self.proxy = Gio.DBusProxy.new_sync(
+ self.dbus, Gio.DBusProxyFlags.DO_NOT_AUTO_START, None, SP,
+ SP_PATH, SP, None)
+
+ self.assertEqual(self.daemon.poll(), None, 'daemon crashed')
+
+ def stop_daemon(self):
+ '''Stop the daemon if it is running.'''
+
+ if self.daemon:
+ try:
+ for child in
psutil.Process(self.daemon.pid).children(recursive=True):
+ child.kill()
+ self.daemon.kill()
+ except OSError:
+ pass
+ self.daemon.wait()
+ self.daemon = None
+ self.proxy = None
+
+ def get_dbus_property(self, name):
+ '''Get property value from daemon D-Bus interface.'''
+
+ proxy = Gio.DBusProxy.new_sync(
+ self.dbus, Gio.DBusProxyFlags.DO_NOT_AUTO_START, None, SP,
+ SP_PATH, 'org.freedesktop.DBus.Properties', None)
+ return proxy.Get('(ss)', SP, name)
+
+ def get_compass_dbus_property(self, name):
+ '''Get property value from daemon compass D-Bus interface.'''
+
+ proxy = Gio.DBusProxy.new_sync(
+ self.dbus, Gio.DBusProxyFlags.DO_NOT_AUTO_START, None, SP,
+ SP_COMPASS_PATH, 'org.freedesktop.DBus.Properties', None)
+ return proxy.Get('(ss)', SP_COMPASS, name)
+
+ def have_text_in_log(self, text):
+ return self.count_text_in_log(text) > 0
+
+ def count_text_in_log(self, text):
+ with open(self.log.name) as f:
+ return f.read().count(text)
+
+ def read_sysfs_attr(self, device, attribute):
+ with open(os.path.join(self.testbed.get_root_dir() + device,
attribute), 'rb') as f:
+ return f.read()
+ return None
+
+ def read_file(self, path):
+ with open(path, 'rb') as f:
+ return f.read()
+ return None
+
+ def assertEventually(self, condition, message=None, timeout=50):
+ '''Assert that condition function eventually returns True.
+
+ Timeout is in deciseconds, defaulting to 50 (5 seconds). message is
+ printed on failure.
+ '''
+ while timeout >= 0:
+ context = GLib.MainContext.default()
+ while context.iteration(False):
+ pass
+ if condition():
+ break
+ timeout -= 1
+ time.sleep(0.1)
+ else:
+ self.fail(message or 'timed out waiting for ' + str(condition))
+
+ #
+ # Actual test cases
+ #
+
+ @unittest.skip('Proximity SSC sensor is currently disabled via udev by
default.')
+ def test_ssc_proximity(self):
+ '''SSC proximity'''
+ prox = self.testbed.add_device('misc', 'ssc-proximity', None,
+ ['name', 'SSC Test Proximity Sensor'],
+ ['NAME', '"SSC Proximity Sensor"',
+ 'DEVNAME', '/dev/fastrpc-sdsp',
+ 'IIO_SENSOR_PROXY_TYPE', 'ssc-proximity']
+ )
+ self.start_daemon()
+ self.assertEqual(self.get_dbus_property('HasAmbientLight'), False)
+ self.assertEqual(self.get_dbus_property('HasAccelerometer'), False)
+ self.assertEqual(self.get_dbus_property('HasProximity'), True)
+ self.assertEqual(self.get_compass_dbus_property('HasCompass'), False)
+
+ # Default values
+ self.assertEqual(self.get_dbus_property('ProximityNear'), False)
+
+ self.proxy.ClaimProximity()
+ self.assertEqual(self.get_dbus_property('ProximityNear'), True)
+ self.assertEventually(lambda: self.get_dbus_property('ProximityNear')
== False)
+ self.assertEventually(lambda: self.get_dbus_property('ProximityNear')
== True)
+
+ self.stop_daemon()
+
+ @unittest.skip('Accelerometer SSC sensor is currently disabled via udev by
default.')
+ def test_ssc_accel(self):
+ '''SSC accelerometer'''
+ prox = self.testbed.add_device('misc', 'ssc-accel', None,
+ ['name', 'SSC Test Accelerometer Sensor'],
+ ['NAME', '"SSC Accelerometer Sensor"',
+ 'DEVNAME', '/dev/fastrpc-sdsp',
+ 'IIO_SENSOR_PROXY_TYPE', 'ssc-accel']
+ )
+ self.start_daemon()
+ self.assertEqual(self.get_dbus_property('HasAmbientLight'), False)
+ self.assertEqual(self.get_dbus_property('HasAccelerometer'), True)
+ self.assertEqual(self.get_dbus_property('HasProximity'), False)
+ self.assertEqual(self.get_compass_dbus_property('HasCompass'), False)
+
+ self.assertEqual(self.get_dbus_property('AccelerometerOrientation'),
'undefined')
+
+ self.proxy.ClaimAccelerometer()
+ self.assertEqual(self.get_dbus_property('AccelerometerOrientation'),
'left-up')
+
+ self.stop_daemon()
+
+ def test_ssc_light(self):
+ '''SSC light'''
+ prox = self.testbed.add_device('misc', 'ssc-light', None,
+ ['name', 'SSC Test Light Sensor'],
+ ['NAME', '"SSC Light Sensor"',
+ 'DEVNAME', '/dev/fastrpc-sdsp',
+ 'IIO_SENSOR_PROXY_TYPE', 'ssc-light']
+ )
+ self.start_daemon()
+ self.assertEqual(self.get_dbus_property('HasAmbientLight'), True)
+ self.assertEqual(self.get_dbus_property('HasAccelerometer'), False)
+ self.assertEqual(self.get_dbus_property('HasProximity'), False)
+ self.assertEqual(self.get_compass_dbus_property('HasCompass'), False)
+
+ # Default values
+ self.assertEqual(self.get_dbus_property('LightLevelUnit'), 'lux')
+ self.assertEqual(self.get_dbus_property('LightLevel'), 0)
+
+ self.proxy.ClaimLight()
+ self.assertEventually(lambda: self.get_dbus_property('LightLevel') ==
7)
+ self.assertEqual(self.get_dbus_property('LightLevelUnit'), 'lux')
+
+ self.stop_daemon()
+
+ def test_ssc_compass(self):
+ '''SSC compass'''
+ prox = self.testbed.add_device('misc', 'ssc-compass', None,
+ ['name', 'SSC Test Compass Sensor'],
+ ['NAME', '"SSC Compass Sensor"',
+ 'DEVNAME', '/dev/fastrpc-sdsp',
+ 'IIO_SENSOR_PROXY_TYPE', 'ssc-compass']
+ )
+ self.start_daemon()
+ self.assertEqual(self.get_dbus_property('HasAmbientLight'), False)
+ self.assertEqual(self.get_dbus_property('HasAccelerometer'), False)
+ self.assertEqual(self.get_dbus_property('HasProximity'), False)
+ self.assertEqual(self.get_compass_dbus_property('HasCompass'), True)
+
self.assertEqual(int(self.get_compass_dbus_property('CompassHeading')), 0)
+
+ self.stop_daemon()
+
+ #
+ # Helper methods
+ #
+
+ @classmethod
+ def _props_to_str(cls, properties):
+ '''Convert a properties dictionary to uevent text representation.'''
+
+ prop_str = ''
+ if properties:
+ for k, v in properties.items():
+ prop_str += '%s=%s\n' % (k, v)
+ return prop_str
+
+if __name__ == '__main__':
+ # run ourselves under umockdev
+ if 'umockdev' not in os.environ.get('LD_PRELOAD', ''):
+ os.execvp('umockdev-wrapper', ['umockdev-wrapper'] + sys.argv)
+
+ unittest.main()