Commits (12)
......@@ -31,6 +31,9 @@ build:native-debian-buster:full:
script:
- meson --werror . _build
- ninja -C _build
except:
variables:
- $PKG_ONLY == "1"
# Minimal build for e.g. submodule usage
build:native-debian-buster:lib:
......@@ -40,6 +43,9 @@ build:native-debian-buster:lib:
script:
- meson --werror -Ddaemon=false -Dgtk_doc=false . _build
- ninja -C _build
except:
variables:
- $PKG_ONLY == "1"
build:native-debian-bullseye:
<<: *tags
......@@ -51,6 +57,9 @@ build:native-debian-bullseye:
script:
- meson -Db_coverage=true --werror . _build
- ninja -C _build
except:
variables:
- $PKG_ONLY == "1"
test:native-debian-bullseye:
<<: *tags
......@@ -61,6 +70,9 @@ test:native-debian-bullseye:
coverage: '/^\s+lines\.+:\s+([\d.]+\%)\s+/'
script:
- dbus-run-session ninja -C _build test coverage
except:
variables:
- $PKG_ONLY == "1"
package:deb-debian-buster:
extends: .l5-build-debian-package
......
......@@ -72,7 +72,7 @@ applications which will use the Feedback Theme Specification.
- power-plug: The power cable has been plugged in.
- power-unplug: The power cable has been unplugged.
- alarm-clock-elapsed: A user configured alarm elapsed.
- timeout-completed: A user configured timout completed (e.g. a stop watch).
- timeout-completed: A user configured timeout completed (e.g. a stop watch).
### Actions
......
......@@ -65,7 +65,7 @@ uses a format [similar to the above in JSON](./data/default.json).
# Recommendations
- The silent theme shoud not produce any audible feedback. This includes
- The silent theme should not produce any audible feedback. This includes
the buzzing of haptic motors.
- The quiet theme should not play any sounds. Haptic motors and LEDs can
be used.
......
#!/usr/bin/python3
import os
import subprocess
import sys
destdir = os.environ.get('DESTDIR', '')
if not destdir and len(sys.argv) > 1:
datadir = sys.argv[1]
print('Compiling gsettings schemas...')
subprocess.call(['glib-compile-schemas', os.path.join(datadir, 'glib-2.0', 'schemas')])
......@@ -53,7 +53,7 @@ install_data(
if json_glib_validate.found()
jsons = []
foreach theme : theme_json
jsons += (join_paths(meson.current_source_dir(), theme_json))
jsons += (join_paths(meson.current_source_dir(), theme))
endforeach
custom_target('validate-json',
build_by_default: true,
......
feedbackd (0.0.0+git20210125) amber-phone; urgency=medium
[ Dylan Van Assche ]
* meson.build: compile GLib schemas on install.
Run a script as a post install to make sure that all GLib schemas are compiled
* fbd-feedback-manager: Allow device-specific feedbackd themes.
[ Guido Günther ]
* feedback-manager: Fix formatting.
-- Guido Günther <agx@sigxcpu.org> Mon, 25 Jan 2021 10:50:15 +0100
feedbackd (0.0.0+git20201114) amber-phone; urgency=high
[ Guido Günther ]
* sound: Set 'event' media role. This allows pa to cork, duck, etc.
* gitlab-ci: Honor PKG_ONLY. This allow us to get debs quicker
* udev: Update led maching for the librem5. The names changed in device
tree which tickles up into userspace.
* debian: Don't abuse the video group. Use a separate group for users that
should be able to access the LED devices.
[ Luca Weiss ]
* fbd-dev-leds: fix brightness parameter.
The fbd_dev_led_set_brightness function is only getting called with
parameter 0 at the moment so this was never noticed.
* Fix typos
-- Guido Günther <agx@sigxcpu.org> Sat, 14 Nov 2020 15:54:23 +0100
feedbackd (0.0.0+git20200726) amber-phone; urgency=medium
[ Arnaud Ferraris ]
......@@ -34,7 +64,7 @@ feedbackd (0.0.0+git20200726) amber-phone; urgency=medium
reason in the actual test function anyway.
* tests: Test event not found case too
* feedback-manager: Deeply free the feedback list.
Instead of freeing each elemnt after each iteration and then the list
Instead of freeing each element after each iteration and then the list
itself at the very end just fully free the list. g_autoslist does
not work well on oder glib so do that manually.
This is just cosmetics.
......@@ -59,7 +89,7 @@ feedbackd (0.0.0+git20200714) amber-phone; urgency=medium
[ Guido Günther ]
* lfb-event: Clarify return values of `finished` functions.
They just inidicate that we talked to feedbackd succesfully.
They just inidicate that we talked to feedbackd successfully.
* lfb-event: Connect done handler in async case too.
Otherwise the event state is not updated properly
* tests: Don't quit mainloop on event end.
......@@ -97,7 +127,7 @@ feedbackd (0.0.0+git20200707) amber-phone; urgency=medium
* docs: Add manpages (Closes: #12)
* data: Drop phone-missed-call in 'quiet' profile. Only want LEDs there.
* feedbackd: Add helper to set up permissions for LEDs.
This helper knows about the tiggers and necessary permission.
This helper knows about the triggers and necessary permission.
It's intended to be run via udev.
* debian: Setup leds via udev.
This allows feedbackd to set periodic feedback and makes usable
......
#!/bin/sh
# postinst script for feedbackd
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see https://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
configure)
if ! getent group feedbackd >/dev/null; then
addgroup --quiet --system feedbackd
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0
......@@ -6,9 +6,11 @@ ACTION=="remove", GOTO="feedbackd_end"
SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT}=="1", ENV{ID_PATH}=="platform-vibrator", TAG+="uaccess", ENV{FEEDBACKD_TYPE}="vibra"
# Front leds of the Librem5
SUBSYSTEM=="leds", DEVPATH=="*/phone:*:front", ENV{FEEDBACKD_TYPE}="led", RUN+="/usr/libexec/fbd-ledctrl -p %S%p -t pattern -G video"
# Front leds of the Librem5 (pre 5.9)
SUBSYSTEM=="leds", DEVPATH=="*/phone:*:front", ENV{FEEDBACKD_TYPE}="led", RUN+="/usr/libexec/fbd-ledctrl -p %S%p -t pattern -G feedbackd"
# Front leds of the Librem5 (5.9 and later)
SUBSYSTEM=="leds", DEVPATH=="*/*:status", ENV{FEEDBACKD_TYPE}="led", RUN+="/usr/libexec/fbd-ledctrl -p %S%p -t pattern -G feedbackd"
# Front leds of the PinePhone
SUBSYSTEM=="leds", DEVPATH=="*/*:indicator", ENV{FEEDBACKD_TYPE}="led", RUN+="/usr/libexec/fbd-ledctrl -p %S%p -t pattern -G video"
SUBSYSTEM=="leds", DEVPATH=="*/*:indicator", ENV{FEEDBACKD_TYPE}="led", RUN+="/usr/libexec/fbd-ledctrl -p %S%p -t pattern -G feedbackd"
LABEL="feedbackd_end"
......@@ -96,13 +96,13 @@
recommended.
</para>
<para>
You can also acknoledge this with the definition option of your C compiler, like <literal>-DFEEDBACK_USE_UNSTABLE_API</literal>.
You can also acknowledge this with the definition option of your C compiler, like <literal>-DFEEDBACK_USE_UNSTABLE_API</literal>.
This is required from Vala.
</para>
<para>
To use &package_name; from Vala, you must define the acknowledgment in C via <literal>-X -DFEEDBACK_USE_UNSTABLE_API</literal>.
If your build system uses a two pass compilation and hence your Vala compiler outputs C (Meson, Automake, or using the <literal>--ccode</literal> Vala compiler option trigger that) then you must add <literal>-DLIBFEEDBACK_USE_UNSTABLE_API</literal> to your C compiler argments instead.
If your build system uses a two pass compilation and hence your Vala compiler outputs C (Meson, Automake, or using the <literal>--ccode</literal> Vala compiler option trigger that) then you must add <literal>-DLIBFEEDBACK_USE_UNSTABLE_API</literal> to your C compiler arguments instead.
</para>
</simplesect>
......
......@@ -16,7 +16,7 @@ G_BEGIN_DECLS
/**
* LfbEventState:
* @LFB_EVENT_STATE_ERRORED: An error occured triggering feedbacks
* @LFB_EVENT_STATE_ERRORED: An error occurred triggering feedbacks
* @LFB_EVENT_STATE_NONE: No state information yet
* @LFB_EVENT_STATE_RUNNING: The feedbacks for this event are currently running
* @LFB_EVENT_STATE_ENDED: All feedbacks for this event ended
......
......@@ -98,6 +98,11 @@ libname = 'libfeedback-' + apiversion
json_glib_validate = find_program('json-glib-validate', required: false)
meson.add_install_script(
join_paths('build-aux', 'post_install.py'),
datadir
)
subdir('data')
subdir('libfeedback')
subdir('src')
......
......@@ -63,7 +63,7 @@ fbd_dev_led_set_brightness (FbdDevLed *led, guint brightness)
{
g_autoptr (GError) err = NULL;
if (!fbd_udev_set_sysfs_path_attr_as_int (led->dev, LED_BRIGHTNESS_ATTR, 0, &err)) {
if (!fbd_udev_set_sysfs_path_attr_as_int (led->dev, LED_BRIGHTNESS_ATTR, brightness, &err)) {
g_warning ("Failed to setup brightness: %s", err->message);
return FALSE;
}
......
......@@ -174,6 +174,7 @@ fbd_dev_sound_play (FbdDevSound *self, FbdFeedbackSound *feedback, FbdDevSoundPl
data,
GSOUND_ATTR_EVENT_ID, fbd_feedback_sound_get_effect (feedback),
GSOUND_ATTR_EVENT_DESCRIPTION, "Feedbackd sound feedback",
GSOUND_ATTR_MEDIA_ROLE, "event",
NULL);
return TRUE;
}
......@@ -103,7 +103,7 @@ fbd_feedback_led_run (FbdFeedbackBase *base)
FbdDevLeds *dev = fbd_feedback_manager_get_dev_leds (manager);
g_return_if_fail (FBD_IS_DEV_LEDS (dev));
g_debug ("Periodic led feeedback: self->max_brightness, self->frequency");
g_debug ("Periodic led feedback: self->max_brightness, self->frequency");
/* FIXME: handle priority */
fbd_dev_leds_start_periodic (dev,
......
......@@ -21,10 +21,14 @@
#define FEEDBACKD_SCHEMA_ID "org.sigxcpu.feedbackd"
#define FEEDBACKD_KEY_PROFILE "profile"
#define FEEDBACKD_THEME_VAR "FEEDBACK_THEME"
#define APP_SCHEMA FEEDBACKD_SCHEMA_ID ".application"
#define APP_PREFIX "/org/sigxcpu/feedbackd/application/"
#define DEVICE_TREE_PATH "/sys/firmware/devicetree/base/compatible"
#define DEVICE_NAME_MAX 1024
/**
* SECTION:fbd-feedback-manager
......@@ -38,18 +42,18 @@
typedef struct _FbdFeedbackManager {
LfbGdbusFeedbackSkeleton parent;
GSettings *settings;
FbdFeedbackProfileLevel level;
FbdFeedbackTheme *theme;
guint next_id;
GSettings *settings;
FbdFeedbackProfileLevel level;
FbdFeedbackTheme *theme;
guint next_id;
GHashTable *events;
GHashTable *events;
/* Hardware interaction */
GUdevClient *client;
FbdDevVibra *vibra;
FbdDevSound *sound;
FbdDevLeds *leds;
GUdevClient *client;
FbdDevVibra *vibra;
FbdDevSound *sound;
FbdDevLeds *leds;
} FbdFeedbackManager;
static void fbd_feedback_manager_feedback_iface_init (LfbGdbusFeedbackIface *iface);
......@@ -173,7 +177,7 @@ on_event_feedbacks_ended (FbdFeedbackManager *self, FbdEvent *event)
g_return_if_fail (fbd_event_get_feedbacks_ended (event));
lfb_gdbus_feedback_emit_feedback_ended (LFB_GDBUS_FEEDBACK(self), event_id,
lfb_gdbus_feedback_emit_feedback_ended (LFB_GDBUS_FEEDBACK (self), event_id,
fbd_event_get_end_reason (event));
g_debug ("All feedbacks for event %d finished", event_id);
......@@ -239,12 +243,12 @@ parse_hints (GVariant *hints, FbdFeedbackProfileLevel *level)
}
static gboolean
fbd_feedback_manager_handle_trigger_feedback (LfbGdbusFeedback *object,
fbd_feedback_manager_handle_trigger_feedback (LfbGdbusFeedback *object,
GDBusMethodInvocation *invocation,
const gchar *arg_app_id,
const gchar *arg_event,
GVariant *arg_hints,
gint arg_timeout)
const gchar *arg_app_id,
const gchar *arg_event,
GVariant *arg_hints,
gint arg_timeout)
{
FbdFeedbackManager *self;
FbdEvent *event;
......@@ -298,8 +302,8 @@ fbd_feedback_manager_handle_trigger_feedback (LfbGdbusFeedback *object,
FbdFeedbackBase *fb = l->data;
if (fbd_feedback_is_available (FBD_FEEDBACK_BASE (fb))) {
fbd_event_add_feedback (event, fb);
found_fb = TRUE;
fbd_event_add_feedback (event, fb);
found_fb = TRUE;
}
}
g_slist_free_full (feedbacks, g_object_unref);
......@@ -316,7 +320,7 @@ fbd_feedback_manager_handle_trigger_feedback (LfbGdbusFeedback *object,
fbd_event_run_feedbacks (event);
} else {
g_hash_table_remove (self->events, GUINT_TO_POINTER (event_id));
lfb_gdbus_feedback_emit_feedback_ended (LFB_GDBUS_FEEDBACK(self), event_id,
lfb_gdbus_feedback_emit_feedback_ended (LFB_GDBUS_FEEDBACK (self), event_id,
FBD_EVENT_END_REASON_NOT_FOUND);
}
......@@ -325,9 +329,9 @@ fbd_feedback_manager_handle_trigger_feedback (LfbGdbusFeedback *object,
}
static gboolean
fbd_feedback_manager_handle_end_feedback (LfbGdbusFeedback *object,
fbd_feedback_manager_handle_end_feedback (LfbGdbusFeedback *object,
GDBusMethodInvocation *invocation,
guint event_id)
guint event_id)
{
FbdFeedbackManager *self;
FbdEvent *event;
......@@ -352,6 +356,52 @@ fbd_feedback_manager_handle_end_feedback (LfbGdbusFeedback *object,
return TRUE;
}
static const gchar *
find_themefile (void)
{
gint i = 0;
gsize len;
const gchar *comp;
g_autoptr (GError) err = NULL;
gchar **xdg_data_dirs = (gchar **) g_get_system_data_dirs ();
g_autofree gchar *config_path = NULL;
g_autofree gchar *compatibles = NULL;
// Try to read the device name
if (g_file_test (DEVICE_TREE_PATH, (G_FILE_TEST_EXISTS))) {
g_debug ("Found device tree device compatible at %s", DEVICE_TREE_PATH);
// Check if feedbackd has a proper config available this device
if (!g_file_get_contents (DEVICE_TREE_PATH, &compatibles, &len, &err))
g_warning ("Unable to read: %s", err->message);
comp = compatibles;
while (comp - compatibles < len) {
// Iterate over $XDG_DATA_DIRS
for (i = 0; i < g_strv_length (xdg_data_dirs); i++) {
config_path = g_strconcat (xdg_data_dirs[i], "feedbackd/themes/", comp, ".json", NULL);
g_debug ("Searching for device specific themefile in %s", config_path);
// Check if file exist
if (g_file_test (config_path, (G_FILE_TEST_EXISTS))) {
g_debug ("Found themefile for this device at: %s", config_path);
return g_strdup (config_path);
}
}
// Next compatible
comp = strchr (comp, 0);
comp++;
}
}else {
g_debug ("Device tree path does not exist: %s", DEVICE_TREE_PATH);
}
return NULL;
}
static void
fbd_feedback_manager_constructed (GObject *object)
{
......@@ -361,14 +411,22 @@ fbd_feedback_manager_constructed (GObject *object)
G_OBJECT_CLASS (fbd_feedback_manager_parent_class)->constructed (object);
themefile = g_getenv ("FEEDBACK_THEME");
// Overide themefile with environment variable if requested
themefile = g_getenv (FEEDBACKD_THEME_VAR);
// Search for device-specific configuration
if (!themefile)
themefile = find_themefile ();
// Fallback to default configuration if needed
if (!themefile)
themefile = FEEDBACKD_THEME_DIR "/default.json";
g_info ("Using themefile: %s", themefile);
self->theme = fbd_feedback_theme_new_from_file (themefile, &err);
if (!self->theme) {
/* No point to carry on */
g_error ("Failed to load default theme: %s", err->message);
g_error ("Failed to load theme: %s", err->message);
}
g_signal_connect (self, "notify::profile", (GCallback)on_profile_changed, NULL);
......