Merge branch 'media-roles' into 'main'
sound: Allow to set media roles See merge request agx/feedbackd!174
This commit is contained in:
@@ -45,6 +45,7 @@ Sound feedbacks specify an event name from a XDG sound theme. Sound themes
|
|||||||
are described in the ``Sound theme spec`` at https://freedesktop.org/wiki/Specifications/sound-theme-spec/
|
are described in the ``Sound theme spec`` at https://freedesktop.org/wiki/Specifications/sound-theme-spec/
|
||||||
|
|
||||||
- `event-name`: The sound event name to use.
|
- `event-name`: The sound event name to use.
|
||||||
|
- `media-role`: The media role to set played audio stream. Defaults to `event`.
|
||||||
|
|
||||||
VibraRumble feedback
|
VibraRumble feedback
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|||||||
+7
-2
@@ -203,6 +203,7 @@ fbd_dev_sound_play (FbdDevSound *self, FbdFeedbackSound *feedback, FbdDevSoundPl
|
|||||||
{
|
{
|
||||||
FbdAsyncData *data;
|
FbdAsyncData *data;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
|
const char *role;
|
||||||
|
|
||||||
g_return_val_if_fail (FBD_IS_DEV_SOUND (self), FALSE);
|
g_return_val_if_fail (FBD_IS_DEV_SOUND (self), FALSE);
|
||||||
g_return_val_if_fail (GSOUND_IS_CONTEXT (self->ctx), FALSE);
|
g_return_val_if_fail (GSOUND_IS_CONTEXT (self->ctx), FALSE);
|
||||||
@@ -212,6 +213,10 @@ fbd_dev_sound_play (FbdDevSound *self, FbdFeedbackSound *feedback, FbdDevSoundPl
|
|||||||
if (!g_hash_table_insert (self->playbacks, feedback, data))
|
if (!g_hash_table_insert (self->playbacks, feedback, data))
|
||||||
g_warning ("Feedback %p already present", feedback);
|
g_warning ("Feedback %p already present", feedback);
|
||||||
|
|
||||||
|
role = fbd_feedback_sound_get_media_role (feedback);
|
||||||
|
if (!role)
|
||||||
|
role = "event";
|
||||||
|
|
||||||
filename = fbd_feedback_sound_get_file_name (feedback);
|
filename = fbd_feedback_sound_get_file_name (feedback);
|
||||||
if (filename) {
|
if (filename) {
|
||||||
gsound_context_play_full (self->ctx, data->cancel,
|
gsound_context_play_full (self->ctx, data->cancel,
|
||||||
@@ -219,7 +224,7 @@ fbd_dev_sound_play (FbdDevSound *self, FbdFeedbackSound *feedback, FbdDevSoundPl
|
|||||||
data,
|
data,
|
||||||
GSOUND_ATTR_MEDIA_FILENAME, filename,
|
GSOUND_ATTR_MEDIA_FILENAME, filename,
|
||||||
GSOUND_ATTR_EVENT_DESCRIPTION, "Feedbackd custom sound feedback",
|
GSOUND_ATTR_EVENT_DESCRIPTION, "Feedbackd custom sound feedback",
|
||||||
GSOUND_ATTR_MEDIA_ROLE, "event",
|
GSOUND_ATTR_MEDIA_ROLE, role,
|
||||||
NULL);
|
NULL);
|
||||||
} else {
|
} else {
|
||||||
gsound_context_play_full (self->ctx, data->cancel,
|
gsound_context_play_full (self->ctx, data->cancel,
|
||||||
@@ -227,7 +232,7 @@ fbd_dev_sound_play (FbdDevSound *self, FbdFeedbackSound *feedback, FbdDevSoundPl
|
|||||||
data,
|
data,
|
||||||
GSOUND_ATTR_EVENT_ID, fbd_feedback_sound_get_effect (feedback),
|
GSOUND_ATTR_EVENT_ID, fbd_feedback_sound_get_effect (feedback),
|
||||||
GSOUND_ATTR_EVENT_DESCRIPTION, "Feedbackd sound feedback",
|
GSOUND_ATTR_EVENT_DESCRIPTION, "Feedbackd sound feedback",
|
||||||
GSOUND_ATTR_MEDIA_ROLE, "event",
|
GSOUND_ATTR_MEDIA_ROLE, role,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ enum {
|
|||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_EFFECT,
|
PROP_EFFECT,
|
||||||
PROP_FILE_NAME,
|
PROP_FILE_NAME,
|
||||||
|
PROP_MEDIA_ROLE,
|
||||||
PROP_LAST_PROP,
|
PROP_LAST_PROP,
|
||||||
};
|
};
|
||||||
static GParamSpec *props[PROP_LAST_PROP];
|
static GParamSpec *props[PROP_LAST_PROP];
|
||||||
@@ -33,6 +34,7 @@ typedef struct _FbdFeedbackSound {
|
|||||||
|
|
||||||
char *effect;
|
char *effect;
|
||||||
char *file_name;
|
char *file_name;
|
||||||
|
char *media_role;
|
||||||
} FbdFeedbackSound;
|
} FbdFeedbackSound;
|
||||||
|
|
||||||
G_DEFINE_TYPE (FbdFeedbackSound, fbd_feedback_sound, FBD_TYPE_FEEDBACK_BASE);
|
G_DEFINE_TYPE (FbdFeedbackSound, fbd_feedback_sound, FBD_TYPE_FEEDBACK_BASE);
|
||||||
@@ -91,6 +93,9 @@ fbd_feedback_sound_set_property (GObject *object,
|
|||||||
case PROP_FILE_NAME:
|
case PROP_FILE_NAME:
|
||||||
self->file_name = g_value_dup_string (value);
|
self->file_name = g_value_dup_string (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MEDIA_ROLE:
|
||||||
|
self->media_role = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -112,6 +117,9 @@ fbd_feedback_sound_get_property (GObject *object,
|
|||||||
case PROP_FILE_NAME:
|
case PROP_FILE_NAME:
|
||||||
g_value_set_string (value, fbd_feedback_sound_get_file_name (self));
|
g_value_set_string (value, fbd_feedback_sound_get_file_name (self));
|
||||||
break;
|
break;
|
||||||
|
case PROP_MEDIA_ROLE:
|
||||||
|
g_value_set_string (value, fbd_feedback_sound_get_media_role (self));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -125,6 +133,7 @@ fbd_feedback_sound_finalize (GObject *object)
|
|||||||
|
|
||||||
g_clear_pointer (&self->effect, g_free);
|
g_clear_pointer (&self->effect, g_free);
|
||||||
g_clear_pointer (&self->file_name, g_free);
|
g_clear_pointer (&self->file_name, g_free);
|
||||||
|
g_clear_pointer (&self->media_role, g_free);
|
||||||
|
|
||||||
G_OBJECT_CLASS (fbd_feedback_sound_parent_class)->finalize (object);
|
G_OBJECT_CLASS (fbd_feedback_sound_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@@ -143,18 +152,34 @@ fbd_feedback_sound_class_init (FbdFeedbackSoundClass *klass)
|
|||||||
base_class->end = fbd_feedback_sound_end;
|
base_class->end = fbd_feedback_sound_end;
|
||||||
base_class->is_available = fbd_feedback_sound_is_available;
|
base_class->is_available = fbd_feedback_sound_is_available;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FbdFeedbackSound:effect:
|
||||||
|
*
|
||||||
|
* The sound effect name
|
||||||
|
*/
|
||||||
props[PROP_EFFECT] =
|
props[PROP_EFFECT] =
|
||||||
g_param_spec_string (
|
g_param_spec_string ("effect", "", "",
|
||||||
"effect",
|
NULL,
|
||||||
"Effect",
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
"The sound effects name",
|
/**
|
||||||
"",
|
* FbdFeedbackSound:file-name:
|
||||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
*
|
||||||
|
* The file name to use for the sound effect. This overrides the
|
||||||
|
* effect name.
|
||||||
|
*/
|
||||||
props[PROP_FILE_NAME] =
|
props[PROP_FILE_NAME] =
|
||||||
g_param_spec_string ("file-name", "", "",
|
g_param_spec_string ("file-name", "", "",
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
/**
|
||||||
|
* FbdFeedbackSound:media-role:
|
||||||
|
*
|
||||||
|
* The media-role to use when playing the sound.
|
||||||
|
*/
|
||||||
|
props[PROP_MEDIA_ROLE] =
|
||||||
|
g_param_spec_string ("media-role", "", "",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
|
g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
|
||||||
}
|
}
|
||||||
@@ -178,8 +203,16 @@ fbd_feedback_sound_get_effect (FbdFeedbackSound *self)
|
|||||||
return self->effect;
|
return self->effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
fbd_feedback_sound_get_file_name (FbdFeedbackSound *self)
|
fbd_feedback_sound_get_file_name (FbdFeedbackSound *self)
|
||||||
{
|
{
|
||||||
return self->file_name;
|
return self->file_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
fbd_feedback_sound_get_media_role (FbdFeedbackSound *self)
|
||||||
|
{
|
||||||
|
return self->media_role;
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,5 +16,6 @@ G_DECLARE_FINAL_TYPE (FbdFeedbackSound, fbd_feedback_sound, FBD, FEEDBACK_SOUND,
|
|||||||
FbdFeedbackSound *fbd_feedback_sound_new_from_file_name (const char *filename);
|
FbdFeedbackSound *fbd_feedback_sound_new_from_file_name (const char *filename);
|
||||||
const char *fbd_feedback_sound_get_effect (FbdFeedbackSound *self);
|
const char *fbd_feedback_sound_get_effect (FbdFeedbackSound *self);
|
||||||
const char *fbd_feedback_sound_get_file_name (FbdFeedbackSound *self);
|
const char *fbd_feedback_sound_get_file_name (FbdFeedbackSound *self);
|
||||||
|
const char *fbd_feedback_sound_get_media_role (FbdFeedbackSound *self);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ if get_option('tests')
|
|||||||
fbd_tests = [
|
fbd_tests = [
|
||||||
'fbd-feedback-led',
|
'fbd-feedback-led',
|
||||||
'fbd-feedback-profile',
|
'fbd-feedback-profile',
|
||||||
|
'fbd-feedback-sound',
|
||||||
'fbd-feedback-vibra',
|
'fbd-feedback-vibra',
|
||||||
'fbd-feedback-theme',
|
'fbd-feedback-theme',
|
||||||
'fbd-event',
|
'fbd-event',
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2025 The Phosh Developers
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0+
|
||||||
|
*
|
||||||
|
* Author: Guido Günther <agx@sigxcpu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define GMOBILE_USE_UNSTABLE_API
|
||||||
|
#include "fbd-feedback-manager.h"
|
||||||
|
#include "fbd-feedback-sound.h"
|
||||||
|
|
||||||
|
#include <json-glib/json-glib.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_fbd_feedback_sound_event (void)
|
||||||
|
{
|
||||||
|
/* Create manager upfront so we can dispose it, otherwise creating
|
||||||
|
* any feedback would create it implicitly */
|
||||||
|
FbdFeedbackManager *manager = fbd_feedback_manager_get_default ();
|
||||||
|
g_autoptr (GError) err = NULL;
|
||||||
|
g_autoptr (JsonNode) node = NULL;
|
||||||
|
GObject *object;
|
||||||
|
g_autofree char *event_name = NULL, *file_name = NULL, *effect = NULL, *media_role = NULL;
|
||||||
|
|
||||||
|
node = json_from_string ("{"
|
||||||
|
" \"event-name\" : \"message-new-cellbroadcast\","
|
||||||
|
" \"type\" : \"Sound\","
|
||||||
|
" \"effect\" : \"cellbroadcast\","
|
||||||
|
" \"media-role\" : \"emergency\""
|
||||||
|
"}", &err);
|
||||||
|
g_assert_no_error (err);
|
||||||
|
|
||||||
|
object = json_gobject_deserialize (FBD_TYPE_FEEDBACK_SOUND, node);
|
||||||
|
g_test_assert_expected_messages ();
|
||||||
|
|
||||||
|
g_object_get (object,
|
||||||
|
"event-name", &event_name,
|
||||||
|
"file-name", &file_name,
|
||||||
|
"effect", &effect,
|
||||||
|
"media-role", &media_role,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_assert_cmpstr (event_name, ==, "message-new-cellbroadcast");
|
||||||
|
g_assert_cmpstr (effect, ==, "cellbroadcast");
|
||||||
|
g_assert_null (file_name);
|
||||||
|
g_assert_cmpstr (media_role, ==, "emergency");
|
||||||
|
|
||||||
|
g_assert_finalize_object (object);
|
||||||
|
g_assert_finalize_object (manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gint
|
||||||
|
main (gint argc, gchar *argv[])
|
||||||
|
{
|
||||||
|
g_test_init (&argc, &argv, NULL);
|
||||||
|
|
||||||
|
g_test_add_func ("/feedbackd/fbd/feedback-sound/event", test_fbd_feedback_sound_event);
|
||||||
|
|
||||||
|
return g_test_run ();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user