diff --git a/src/libnm-core-impl/nm-setting.c b/src/libnm-core-impl/nm-setting.c index ce40c61d38..3f32e181d8 100644 --- a/src/libnm-core-impl/nm-setting.c +++ b/src/libnm-core-impl/nm-setting.c @@ -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) { diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c index 77edf4afa4..066cdb24d9 100644 --- a/src/libnm-core-impl/tests/test-setting.c +++ b/src/libnm-core-impl/tests/test-setting.c @@ -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); diff --git a/src/libnm-core-intern/nm-core-internal.h b/src/libnm-core-intern/nm-core-internal.h index c4e420f0d8..2ef2520956 100644 --- a/src/libnm-core-intern/nm-core-internal.h +++ b/src/libnm-core-intern/nm-core-internal.h @@ -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; };