libnm: add flag to control whether to_dbus_fcn() should handle default values

Usually, properties that are set to their default are not serialized on
D-Bus. That is, to_dbus_fcn() returns NULL.

In some cases, we explicitly want to always serialize the property. For
example, if we changed behavior and the libnm default value changed.
Then we want that the message on D-Bus is always clear about the used
value and not rely on the default value on the receiving side.
This commit is contained in:
Thomas Haller 2021-06-18 16:36:40 +02:00
parent e435fdfedf
commit acc3a66bf2
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
3 changed files with 22 additions and 2 deletions

View file

@ -543,7 +543,8 @@ _nm_setting_property_to_dbus_fcn_get_boolean(const NMSettInfoSetting *
gboolean val;
val = !!property_info->to_dbus_data.get_boolean(setting);
if (val == NM_G_PARAM_SPEC_GET_DEFAULT_BOOLEAN(property_info->param_spec))
if (!property_info->to_dbus_data.including_default
&& val == NM_G_PARAM_SPEC_GET_DEFAULT_BOOLEAN(property_info->param_spec))
return NULL;
return g_variant_ref(nm_g_variant_singleton_b(val));
}
@ -559,7 +560,13 @@ _nm_setting_property_to_dbus_fcn_get_string(const NMSettInfoSetting *
const NMSettInfoProperty *property_info = &sett_info->property_infos[property_idx];
const char * val;
/* For string properties that are implemented via this function, the default is always NULL.
* In general, having strings default to NULL is most advisable.
*
* Setting "including_default" for a string makes no sense because a
* GVariant of type "s" cannot express NULL. */
nm_assert(!NM_G_PARAM_SPEC_GET_DEFAULT_STRING(property_info->param_spec));
nm_assert(!property_info->to_dbus_data.including_default);
val = property_info->to_dbus_data.get_string(setting);
if (!val)
@ -593,7 +600,8 @@ _nm_setting_property_to_dbus_fcn_gprop(const NMSettInfoSetting * s
g_object_get_property(G_OBJECT(setting), property->param_spec->name, &prop_value);
if (g_param_value_defaults(property->param_spec, &prop_value))
if (!property->to_dbus_data.including_default
&& g_param_value_defaults(property->param_spec, &prop_value))
return NULL;
switch (property->property_type->typdata_to_dbus.gprop_type) {

View file

@ -4358,6 +4358,7 @@ test_setting_metadata(void)
const NMSettInfoProperty *sip = &sis->property_infos[prop_idx];
GArray * property_types_data;
guint prop_idx_val;
gboolean can_set_including_default = FALSE;
g_assert(sip->name);
@ -4402,11 +4403,13 @@ check_done:;
if (sip->property_type->typdata_to_dbus.gprop_type
!= NM_SETTING_PROPERTY_TO_DBUS_FCN_GPROP_TYPE_DEFAULT)
g_assert(!sip->to_dbus_data.gprop_to_dbus_fcn);
can_set_including_default = TRUE;
} else if (sip->property_type->to_dbus_fcn
== _nm_setting_property_to_dbus_fcn_get_boolean) {
g_assert(sip->param_spec);
g_assert(sip->param_spec->value_type == G_TYPE_BOOLEAN);
g_assert(sip->to_dbus_data.get_boolean);
can_set_including_default = TRUE;
} else if (sip->property_type->to_dbus_fcn
== _nm_setting_property_to_dbus_fcn_get_string) {
g_assert(sip->param_spec);
@ -4414,6 +4417,9 @@ check_done:;
g_assert(sip->to_dbus_data.get_string);
}
if (!can_set_including_default)
g_assert(!sip->to_dbus_data.including_default);
g_assert(!sip->property_type->from_dbus_fcn
|| !sip->property_type->gprop_from_dbus_fcn);

View file

@ -714,6 +714,12 @@ struct _NMSettInfoProperty {
gboolean (*get_boolean)(NMSetting *);
const char *(*get_string)(NMSetting *);
};
/* Usually, properties that are set to the default value for the GParamSpec
* are not serialized to GVariant (and NULL is returned by to_dbus_data().
* Set this flag to force always converting the property even if the value
* is the default. */
bool including_default : 1;
} to_dbus_data;
};