libnm: let all property types implement to_dbus_fcn() handler

If a property can be converted to D-Bus, then always set the
to_dbus_fcn() handler. The only caller of to_dbus_fcn() is
property_to_dbus(), so this means that property_to_dbus()
has no more default implementation and always delegates to
to_dbus_fcn().

The code is easier to understand if all properties implement
to_dbus_fcn() the same way.

Also, there is supposed to be a split between NMSettInfoProperty (info about
the property) and NMSettInfoPropertType (the type). The idea is that
each property (obviously) requires its distinct NMSettInfoProperty, but
they can share a common type implementation.
With NMSettInfoPropertType.gprop_to_dbus_fcn that is often violated because
many properties that implement NMSettInfoPropertType.gprop_to_dbus_fcn
require a special type implementation. As such, gprop_to_dbus_fcn should
be part of the property info and not the property type. The first step towards
that is unifying all properties to use to_dbus_fcn().
This commit is contained in:
Thomas Haller
2021-06-18 08:59:12 +02:00
parent c54be51f99
commit c161439b73
11 changed files with 100 additions and 66 deletions

View File

@@ -1995,7 +1995,7 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
_nm_properties_override_gobj( _nm_properties_override_gobj(
properties_override, properties_override,
obj_properties[PROP_INTERFACE_NAME], obj_properties[PROP_INTERFACE_NAME],
NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_STRING, NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_STRING,
.missing_from_dbus_fcn = .missing_from_dbus_fcn =
nm_setting_connection_no_interface_name, )); nm_setting_connection_no_interface_name, ));

View File

@@ -764,6 +764,7 @@ _nm_setting_dcb_uint_array_from_dbus(GVariant *dbus_value, GValue *prop_value)
static const NMSettInfoPropertType nm_sett_info_propert_type_dcb_au = { static const NMSettInfoPropertType nm_sett_info_propert_type_dcb_au = {
.dbus_type = NM_G_VARIANT_TYPE("au"), .dbus_type = NM_G_VARIANT_TYPE("au"),
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_gprop,
.gprop_to_dbus_fcn = _nm_setting_dcb_uint_array_to_dbus, .gprop_to_dbus_fcn = _nm_setting_dcb_uint_array_to_dbus,
.gprop_from_dbus_fcn = _nm_setting_dcb_uint_array_from_dbus, .gprop_from_dbus_fcn = _nm_setting_dcb_uint_array_from_dbus,
}; };

View File

@@ -5766,10 +5766,10 @@ _nm_sett_info_property_override_create_array_ip_config(void)
{ {
GArray *properties_override = _nm_sett_info_property_override_create_array(); GArray *properties_override = _nm_sett_info_property_override_create_array();
_nm_properties_override_gobj(properties_override, _nm_properties_override_gobj(
properties_override,
obj_properties[PROP_GATEWAY], obj_properties[PROP_GATEWAY],
NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_STRING, NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_STRING, .from_dbus_fcn = ip_gateway_set, ));
.from_dbus_fcn = ip_gateway_set, ));
/* ---dbus--- /* ---dbus---
* property: routing-rules * property: routing-rules

View File

@@ -943,7 +943,7 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass)
_nm_properties_override_gobj( _nm_properties_override_gobj(
properties_override, properties_override,
g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_DNS), g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_DNS),
NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("au"), NM_SETT_INFO_PROPERT_TYPE_GPROP(NM_G_VARIANT_TYPE("au"),
.gprop_to_dbus_fcn = ip4_dns_to_dbus, .gprop_to_dbus_fcn = ip4_dns_to_dbus,
.gprop_from_dbus_fcn = ip4_dns_from_dbus, )); .gprop_from_dbus_fcn = ip4_dns_from_dbus, ));

View File

@@ -1012,7 +1012,7 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass)
_nm_properties_override_gobj( _nm_properties_override_gobj(
properties_override, properties_override,
g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_DNS), g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_DNS),
NM_SETT_INFO_PROPERT_TYPE(.dbus_type = NM_G_VARIANT_TYPE("aay"), NM_SETT_INFO_PROPERT_TYPE_GPROP(NM_G_VARIANT_TYPE("aay"),
.gprop_to_dbus_fcn = ip6_dns_to_dbus, .gprop_to_dbus_fcn = ip6_dns_to_dbus,
.gprop_from_dbus_fcn = ip6_dns_from_dbus, )); .gprop_from_dbus_fcn = ip6_dns_from_dbus, ));

View File

@@ -265,6 +265,13 @@ gboolean _nm_setting_aggregate(NMSetting *setting, NMConnectionAggregateType typ
gboolean _nm_setting_slave_type_is_valid(const char *slave_type, const char **out_port_type); gboolean _nm_setting_slave_type_is_valid(const char *slave_type, const char **out_port_type);
GVariant *_nm_setting_property_to_dbus_fcn_gprop(const NMSettInfoSetting * sett_info,
guint property_idx,
NMConnection * connection,
NMSetting * setting,
NMConnectionSerializationFlags flags,
const NMConnectionSerializationOptions *options);
GVariant *_nm_setting_to_dbus(NMSetting * setting, GVariant *_nm_setting_to_dbus(NMSetting * setting,
NMConnection * connection, NMConnection * connection,
NMConnectionSerializationFlags flags, NMConnectionSerializationFlags flags,
@@ -326,6 +333,11 @@ _nm_setting_class_commit(NMSettingClass *setting_class, NMMetaSettingType meta_t
&_g; \ &_g; \
}) })
#define NM_SETT_INFO_PROPERT_TYPE_GPROP(_dbus_type, ...) \
NM_SETT_INFO_PROPERT_TYPE(.dbus_type = _dbus_type, \
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_gprop, \
__VA_ARGS__)
#define NM_SETT_INFO_PROPERTY(...) (&((const NMSettInfoProperty){__VA_ARGS__})) #define NM_SETT_INFO_PROPERTY(...) (&((const NMSettInfoProperty){__VA_ARGS__}))
gboolean _nm_properties_override_assert(const NMSettInfoProperty *prop_info); gboolean _nm_properties_override_assert(const NMSettInfoProperty *prop_info);

View File

@@ -311,7 +311,7 @@ nm_setting_serial_class_init(NMSettingSerialClass *klass)
_nm_properties_override_gobj( _nm_properties_override_gobj(
properties_override, properties_override,
obj_properties[PROP_PARITY], obj_properties[PROP_PARITY],
NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_BYTE, NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_BYTE,
.gprop_to_dbus_fcn = parity_to_dbus, .gprop_to_dbus_fcn = parity_to_dbus,
.gprop_from_dbus_fcn = parity_from_dbus, )); .gprop_from_dbus_fcn = parity_from_dbus, ));

View File

@@ -1927,7 +1927,7 @@ nm_setting_wireless_security_class_init(NMSettingWirelessSecurityClass *klass)
_nm_properties_override_gobj( _nm_properties_override_gobj(
properties_override, properties_override,
obj_properties[PROP_WEP_KEY_TYPE], obj_properties[PROP_WEP_KEY_TYPE],
NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_UINT32, NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_UINT32,
.gprop_to_dbus_fcn = wep_key_type_to_dbus, )); .gprop_to_dbus_fcn = wep_key_type_to_dbus, ));
/** /**

View File

@@ -190,8 +190,10 @@ _nm_properties_override_assert(const NMSettInfoProperty *prop_info)
/* we always require a dbus_type. */ /* we always require a dbus_type. */
nm_assert(property_type->dbus_type); nm_assert(property_type->dbus_type);
if (!property_type->to_dbus_fcn)
nm_assert(!property_type->gprop_to_dbus_fcn);
/* {to,from}_dbus_fcn and gprop_{to,from}_dbus_fcn cannot both be set. */ /* {to,from}_dbus_fcn and gprop_{to,from}_dbus_fcn cannot both be set. */
nm_assert(!property_type->to_dbus_fcn || !property_type->gprop_to_dbus_fcn);
nm_assert(!property_type->from_dbus_fcn || !property_type->gprop_from_dbus_fcn); nm_assert(!property_type->from_dbus_fcn || !property_type->gprop_from_dbus_fcn);
if (!prop_info->param_spec) { if (!prop_info->param_spec) {
@@ -378,34 +380,34 @@ _nm_setting_class_commit_full(NMSettingClass * setting_class,
vtype = p->param_spec->value_type; vtype = p->param_spec->value_type;
if (vtype == G_TYPE_BOOLEAN) if (vtype == G_TYPE_BOOLEAN)
p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_BOOLEAN); p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_BOOLEAN);
else if (vtype == G_TYPE_UCHAR) else if (vtype == G_TYPE_UCHAR)
p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_BYTE); p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_BYTE);
else if (vtype == G_TYPE_INT) else if (vtype == G_TYPE_INT)
p->property_type = &nm_sett_info_propert_type_plain_i; p->property_type = &nm_sett_info_propert_type_plain_i;
else if (vtype == G_TYPE_UINT) else if (vtype == G_TYPE_UINT)
p->property_type = &nm_sett_info_propert_type_plain_u; p->property_type = &nm_sett_info_propert_type_plain_u;
else if (vtype == G_TYPE_INT64) else if (vtype == G_TYPE_INT64)
p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_INT64); p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_INT64);
else if (vtype == G_TYPE_UINT64) else if (vtype == G_TYPE_UINT64)
p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_UINT64); p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_UINT64);
else if (vtype == G_TYPE_STRING) else if (vtype == G_TYPE_STRING)
p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_STRING); p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_STRING);
else if (vtype == G_TYPE_DOUBLE) else if (vtype == G_TYPE_DOUBLE)
p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_DOUBLE); p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_DOUBLE);
else if (vtype == G_TYPE_STRV) else if (vtype == G_TYPE_STRV)
p->property_type = NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_STRING_ARRAY); p->property_type = NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_STRING_ARRAY);
else if (vtype == G_TYPE_BYTES) { else if (vtype == G_TYPE_BYTES) {
p->property_type = p->property_type =
NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_BYTESTRING, NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_BYTESTRING,
.gprop_to_dbus_fcn = _gprop_to_dbus_fcn_bytes); .gprop_to_dbus_fcn = _gprop_to_dbus_fcn_bytes);
} else if (g_type_is_a(vtype, G_TYPE_ENUM)) { } else if (g_type_is_a(vtype, G_TYPE_ENUM)) {
p->property_type = p->property_type =
NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_INT32, NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_INT32,
.gprop_to_dbus_fcn = _gprop_to_dbus_fcn_enum); .gprop_to_dbus_fcn = _gprop_to_dbus_fcn_enum);
} else if (g_type_is_a(vtype, G_TYPE_FLAGS)) { } else if (g_type_is_a(vtype, G_TYPE_FLAGS)) {
p->property_type = p->property_type =
NM_SETT_INFO_PROPERT_TYPE(.dbus_type = G_VARIANT_TYPE_UINT32, NM_SETT_INFO_PROPERT_TYPE_GPROP(G_VARIANT_TYPE_UINT32,
.gprop_to_dbus_fcn = _gprop_to_dbus_fcn_flags); .gprop_to_dbus_fcn = _gprop_to_dbus_fcn_flags);
} else } else
nm_assert_not_reached(); nm_assert_not_reached();
@@ -552,6 +554,34 @@ _nm_setting_use_legacy_property(NMSetting * setting,
/*****************************************************************************/ /*****************************************************************************/
GVariant *
_nm_setting_property_to_dbus_fcn_gprop(const NMSettInfoSetting * sett_info,
guint property_idx,
NMConnection * connection,
NMSetting * setting,
NMConnectionSerializationFlags flags,
const NMConnectionSerializationOptions *options)
{
const NMSettInfoProperty *const property = &sett_info->property_infos[property_idx];
nm_auto_unset_gvalue GValue prop_value = {
0,
};
nm_assert(property->param_spec);
g_value_init(&prop_value, property->param_spec->value_type);
g_object_get_property(G_OBJECT(setting), property->param_spec->name, &prop_value);
if (g_param_value_defaults(property->param_spec, &prop_value))
return NULL;
if (property->property_type->gprop_to_dbus_fcn)
return property->property_type->gprop_to_dbus_fcn(&prop_value);
return g_dbus_gvalue_to_gvariant(&prop_value, property->property_type->dbus_type);
}
static GVariant * static GVariant *
property_to_dbus(const NMSettInfoSetting * sett_info, property_to_dbus(const NMSettInfoSetting * sett_info,
guint property_idx, guint property_idx,
@@ -566,12 +596,15 @@ property_to_dbus(const NMSettInfoSetting * sett_info,
nm_assert(property->property_type->dbus_type); nm_assert(property->property_type->dbus_type);
if (!property->param_spec) { if (!property->property_type->to_dbus_fcn) {
if (!property->property_type->to_dbus_fcn) nm_assert(!property->param_spec);
nm_assert(!property->property_type->gprop_to_dbus_fcn);
return NULL; return NULL;
} else if (!ignore_flags }
&& !NM_FLAGS_HAS(property->param_spec->flags,
NM_SETTING_PARAM_TO_DBUS_IGNORE_FLAGS)) { if (property->param_spec
&& (!ignore_flags
&& !NM_FLAGS_HAS(property->param_spec->flags, NM_SETTING_PARAM_TO_DBUS_IGNORE_FLAGS))) {
if (!NM_FLAGS_HAS(property->param_spec->flags, G_PARAM_WRITABLE)) if (!NM_FLAGS_HAS(property->param_spec->flags, G_PARAM_WRITABLE))
return NULL; return NULL;
@@ -598,32 +631,10 @@ property_to_dbus(const NMSettInfoSetting * sett_info,
} }
} }
if (property->property_type->to_dbus_fcn) {
variant = property->property_type variant = property->property_type
->to_dbus_fcn(sett_info, property_idx, connection, setting, flags, options); ->to_dbus_fcn(sett_info, property_idx, connection, setting, flags, options);
nm_g_variant_take_ref(variant); nm_g_variant_take_ref(variant);
} else {
nm_auto_unset_gvalue GValue prop_value = {
0,
};
nm_assert(property->param_spec);
g_value_init(&prop_value, property->param_spec->value_type);
g_object_get_property(G_OBJECT(setting), property->param_spec->name, &prop_value);
if (g_param_value_defaults(property->param_spec, &prop_value))
return NULL;
if (property->property_type->gprop_to_dbus_fcn) {
variant = property->property_type->gprop_to_dbus_fcn(&prop_value);
nm_g_variant_take_ref(variant);
} else
variant = g_dbus_gvalue_to_gvariant(&prop_value, property->property_type->dbus_type);
}
nm_assert(!variant || !g_variant_is_floating(variant));
nm_assert(!variant || g_variant_is_of_type(variant, property->property_type->dbus_type)); nm_assert(!variant || g_variant_is_of_type(variant, property->property_type->dbus_type));
return variant; return variant;
@@ -2334,10 +2345,12 @@ const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_u = {
const NMSettInfoPropertType nm_sett_info_propert_type_plain_i = { const NMSettInfoPropertType nm_sett_info_propert_type_plain_i = {
.dbus_type = G_VARIANT_TYPE_INT32, .dbus_type = G_VARIANT_TYPE_INT32,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_gprop,
}; };
const NMSettInfoPropertType nm_sett_info_propert_type_plain_u = { const NMSettInfoPropertType nm_sett_info_propert_type_plain_u = {
.dbus_type = G_VARIANT_TYPE_UINT32, .dbus_type = G_VARIANT_TYPE_UINT32,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_gprop,
}; };
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -781,6 +781,7 @@ _nm_utils_strdict_from_dbus(GVariant *dbus_value, GValue *prop_value)
const NMSettInfoPropertType nm_sett_info_propert_type_strdict = { const NMSettInfoPropertType nm_sett_info_propert_type_strdict = {
.dbus_type = NM_G_VARIANT_TYPE("a{ss}"), .dbus_type = NM_G_VARIANT_TYPE("a{ss}"),
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_gprop,
.gprop_to_dbus_fcn = _nm_utils_strdict_to_dbus, .gprop_to_dbus_fcn = _nm_utils_strdict_to_dbus,
.gprop_from_dbus_fcn = _nm_utils_strdict_from_dbus, .gprop_from_dbus_fcn = _nm_utils_strdict_from_dbus,
}; };
@@ -4156,6 +4157,7 @@ _nm_utils_hwaddr_from_dbus(GVariant *dbus_value, GValue *prop_value)
const NMSettInfoPropertType nm_sett_info_propert_type_mac_address = { const NMSettInfoPropertType nm_sett_info_propert_type_mac_address = {
.dbus_type = G_VARIANT_TYPE_BYTESTRING, .dbus_type = G_VARIANT_TYPE_BYTESTRING,
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_gprop,
.gprop_to_dbus_fcn = _nm_utils_hwaddr_to_dbus, .gprop_to_dbus_fcn = _nm_utils_hwaddr_to_dbus,
.gprop_from_dbus_fcn = _nm_utils_hwaddr_from_dbus, .gprop_from_dbus_fcn = _nm_utils_hwaddr_from_dbus,
}; };

View File

@@ -4368,7 +4368,13 @@ test_setting_metadata(void)
g_assert(sip->property_type->dbus_type); g_assert(sip->property_type->dbus_type);
g_assert(g_variant_type_string_is_valid((const char *) sip->property_type->dbus_type)); g_assert(g_variant_type_string_is_valid((const char *) sip->property_type->dbus_type));
g_assert(!sip->property_type->to_dbus_fcn || !sip->property_type->gprop_to_dbus_fcn); if (!sip->property_type->to_dbus_fcn) {
/* it's allowed to have no to_dbus_fcn(), to ignore a property. But such
* properties must not have a param_spec and no gprop_to_dbus_fcn. */
g_assert(!sip->param_spec);
g_assert(!sip->property_type->gprop_to_dbus_fcn);
}
g_assert(!sip->property_type->from_dbus_fcn g_assert(!sip->property_type->from_dbus_fcn
|| !sip->property_type->gprop_from_dbus_fcn); || !sip->property_type->gprop_from_dbus_fcn);