mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-14 22:40:35 +01:00
libnm: add direct_offset for boolean properties
Introduce a new mechanism for how to handle properties generically. We have NMSettInfoSetting, NMSettInfoProperty and NMSettInfoPropertType with meta data about settings and their properties. For example, we have a simple boolean property. Then (usually) we have a boolean GParamSpec, and a plain boolean field in the NMSetting's private data. We need very little to get (and convert to keyfile, GVariant), set (from keyfile, GVariant) and compare this property. All we need to know, is the GParamSpec and the offset of the bool field. Introduce a new mechanism for that, and as example implement NM_SETTING_CONNECTION_AUTOCONNECT property this way. Note that this patch only changes the to_dbus_fcn() for the boolean property. But this opens up all kind of further improvements. What we eventually also can do is replace GObjectClass.get_property() with a generic variant, that knows how to get and set the property.
This commit is contained in:
parent
d6f802abcd
commit
8024279cf7
5 changed files with 137 additions and 14 deletions
|
|
@ -93,8 +93,8 @@ typedef struct {
|
|||
NMSettingConnectionAutoconnectSlaves autoconnect_slaves;
|
||||
NMMetered metered;
|
||||
NMSettingConnectionLldp lldp;
|
||||
bool autoconnect;
|
||||
bool read_only : 1;
|
||||
bool autoconnect : 1;
|
||||
} NMSettingConnectionPrivate;
|
||||
|
||||
/**
|
||||
|
|
@ -2078,13 +2078,14 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
|
|||
* description: Whether the connection should be autoconnected (not only while booting).
|
||||
* ---end---
|
||||
*/
|
||||
_nm_setting_property_define_boolean(properties_override,
|
||||
obj_properties,
|
||||
NM_SETTING_CONNECTION_AUTOCONNECT,
|
||||
PROP_AUTOCONNECT,
|
||||
TRUE,
|
||||
NM_SETTING_PARAM_FUZZY_IGNORE,
|
||||
nm_setting_connection_get_autoconnect);
|
||||
_nm_setting_property_define_direct_boolean(properties_override,
|
||||
obj_properties,
|
||||
NM_SETTING_CONNECTION_AUTOCONNECT,
|
||||
PROP_AUTOCONNECT,
|
||||
TRUE,
|
||||
NM_SETTING_PARAM_FUZZY_IGNORE,
|
||||
NMSettingConnectionPrivate,
|
||||
autoconnect);
|
||||
|
||||
/**
|
||||
* NMSettingConnection:autoconnect-priority:
|
||||
|
|
|
|||
|
|
@ -253,6 +253,8 @@ extern const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_u
|
|||
extern const NMSettInfoPropertType nm_sett_info_propert_type_plain_i;
|
||||
extern const NMSettInfoPropertType nm_sett_info_propert_type_plain_u;
|
||||
|
||||
extern const NMSettInfoPropertType nm_sett_info_propert_type_direct_boolean;
|
||||
|
||||
extern const NMSettInfoPropertType nm_sett_info_propert_type_boolean;
|
||||
extern const NMSettInfoPropertType nm_sett_info_propert_type_string;
|
||||
|
||||
|
|
@ -275,6 +277,13 @@ GVariant *_nm_setting_property_to_dbus_fcn_gprop(const NMSettInfoSetting *
|
|||
NMConnectionSerializationFlags flags,
|
||||
const NMConnectionSerializationOptions *options);
|
||||
|
||||
GVariant *_nm_setting_property_to_dbus_fcn_direct(const NMSettInfoSetting * sett_info,
|
||||
guint property_idx,
|
||||
NMConnection * connection,
|
||||
NMSetting * setting,
|
||||
NMConnectionSerializationFlags flags,
|
||||
const NMConnectionSerializationOptions *options);
|
||||
|
||||
GVariant *
|
||||
_nm_setting_property_to_dbus_fcn_get_boolean(const NMSettInfoSetting * sett_info,
|
||||
guint property_idx,
|
||||
|
|
@ -376,11 +385,14 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p
|
|||
g_array_append_vals(properties_override, prop_info, 1);
|
||||
}
|
||||
|
||||
#define _nm_properties_override_gobj(properties_override, p_param_spec, p_property_type, ...) \
|
||||
_nm_properties_override((properties_override), \
|
||||
NM_SETT_INFO_PROPERTY(.name = NULL, \
|
||||
.param_spec = (p_param_spec), \
|
||||
.property_type = (p_property_type), \
|
||||
#define _nm_properties_override_gobj(properties_override, \
|
||||
p_param_spec, \
|
||||
p_property_type, \
|
||||
... /* extra NMSettInfoProperty fields */) \
|
||||
_nm_properties_override((properties_override), \
|
||||
NM_SETT_INFO_PROPERTY(.name = NULL, \
|
||||
.param_spec = (p_param_spec), \
|
||||
.property_type = (p_property_type), \
|
||||
__VA_ARGS__))
|
||||
|
||||
#define _nm_properties_override_dbus(properties_override, p_name, p_property_type) \
|
||||
|
|
@ -390,6 +402,58 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Define "direct" properties. These are properties that have a GParamSpec and
|
||||
* NMSettInfoPropertType.direct_type != NM_VALUE_TYPE_NONE.
|
||||
*
|
||||
* With this, the location of the data is known at
|
||||
*
|
||||
* _nm_setting_get_private(setting, sett_info, property_info->direct_offset)
|
||||
*
|
||||
* which allows to generically handle the property operations (like get, set, compare).
|
||||
*/
|
||||
|
||||
#define _nm_setting_property_define_direct_boolean(properties_override, \
|
||||
obj_properties, \
|
||||
prop_name, \
|
||||
prop_id, \
|
||||
default_value, \
|
||||
param_flags, \
|
||||
private_struct_type, \
|
||||
private_struct_field, \
|
||||
... /* extra NMSettInfoProperty fields */) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
const gboolean _default_value = (default_value); \
|
||||
GParamSpec * _param_spec; \
|
||||
\
|
||||
G_STATIC_ASSERT( \
|
||||
!NM_FLAGS_ANY((param_flags), \
|
||||
~(NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_INFERRABLE \
|
||||
| NM_SETTING_PARAM_REAPPLY_IMMEDIATELY))); \
|
||||
\
|
||||
nm_assert(NM_IN_SET(_default_value, 0, 1)); \
|
||||
\
|
||||
_param_spec = \
|
||||
g_param_spec_boolean("" prop_name "", \
|
||||
"", \
|
||||
"", \
|
||||
_default_value, \
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (param_flags)); \
|
||||
\
|
||||
(obj_properties)[(prop_id)] = _param_spec; \
|
||||
\
|
||||
_nm_properties_override_gobj( \
|
||||
(properties_override), \
|
||||
_param_spec, \
|
||||
&nm_sett_info_propert_type_direct_boolean, \
|
||||
.direct_offset = \
|
||||
NM_STRUCT_OFFSET_ENSURE_TYPE(bool, private_struct_type, private_struct_field), \
|
||||
__VA_ARGS__); \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _nm_setting_property_define_boolean_full(properties_override, \
|
||||
obj_properties, \
|
||||
prop_name, \
|
||||
|
|
|
|||
|
|
@ -544,6 +544,32 @@ _nm_setting_use_legacy_property(NMSetting * setting,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
GVariant *
|
||||
_nm_setting_property_to_dbus_fcn_direct(const NMSettInfoSetting * sett_info,
|
||||
guint property_idx,
|
||||
NMConnection * connection,
|
||||
NMSetting * setting,
|
||||
NMConnectionSerializationFlags flags,
|
||||
const NMConnectionSerializationOptions *options)
|
||||
{
|
||||
const NMSettInfoProperty *property_info = &sett_info->property_infos[property_idx];
|
||||
|
||||
switch (property_info->property_type->direct_type) {
|
||||
case NM_VALUE_TYPE_BOOL:
|
||||
{
|
||||
gboolean val;
|
||||
|
||||
val = *((bool *) _nm_setting_get_private(setting, sett_info, property_info->direct_offset));
|
||||
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));
|
||||
}
|
||||
default:
|
||||
return nm_assert_unreachable_val(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
GVariant *
|
||||
_nm_setting_property_to_dbus_fcn_get_boolean(const NMSettInfoSetting * sett_info,
|
||||
guint property_idx,
|
||||
|
|
@ -2415,6 +2441,11 @@ const NMSettInfoPropertType nm_sett_info_propert_type_plain_i =
|
|||
const NMSettInfoPropertType nm_sett_info_propert_type_plain_u =
|
||||
NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT(G_VARIANT_TYPE_UINT32);
|
||||
|
||||
const NMSettInfoPropertType nm_sett_info_propert_type_direct_boolean =
|
||||
NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(G_VARIANT_TYPE_BOOLEAN,
|
||||
.direct_type = NM_VALUE_TYPE_BOOL,
|
||||
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_direct);
|
||||
|
||||
const NMSettInfoPropertType nm_sett_info_propert_type_boolean = NM_SETT_INFO_PROPERT_TYPE_DBUS_INIT(
|
||||
G_VARIANT_TYPE_BOOLEAN,
|
||||
.to_dbus_fcn = _nm_setting_property_to_dbus_fcn_get_boolean);
|
||||
|
|
|
|||
|
|
@ -4433,6 +4433,19 @@ test_setting_metadata(void)
|
|||
g_assert(sip->property_type->dbus_type);
|
||||
g_assert(g_variant_type_string_is_valid((const char *) sip->property_type->dbus_type));
|
||||
|
||||
if (sip->property_type->direct_type == NM_VALUE_TYPE_NONE) {
|
||||
g_assert_cmpint(sip->direct_offset, ==, 0);
|
||||
} else if (sip->property_type->direct_type == NM_VALUE_TYPE_BOOL) {
|
||||
g_assert(sip->property_type == &nm_sett_info_propert_type_direct_boolean);
|
||||
g_assert(g_variant_type_equal(sip->property_type->dbus_type, "b"));
|
||||
g_assert(sip->property_type->to_dbus_fcn
|
||||
== _nm_setting_property_to_dbus_fcn_direct);
|
||||
g_assert(sip->param_spec);
|
||||
g_assert(sip->param_spec->value_type == G_TYPE_BOOLEAN);
|
||||
can_set_including_default = TRUE;
|
||||
} else
|
||||
g_assert_not_reached();
|
||||
|
||||
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. */
|
||||
|
|
@ -4598,7 +4611,7 @@ check_done:;
|
|||
const NMSettInfoPropertType *pt_2 = a_property_types[prop_idx_2];
|
||||
|
||||
if (!g_variant_type_equal(pt->dbus_type, pt_2->dbus_type)
|
||||
|| pt->to_dbus_fcn != pt_2->to_dbus_fcn
|
||||
|| pt->direct_type != pt_2->direct_type || pt->to_dbus_fcn != pt_2->to_dbus_fcn
|
||||
|| pt->from_dbus_fcn != pt_2->from_dbus_fcn
|
||||
|| pt->missing_from_dbus_fcn != pt_2->missing_from_dbus_fcn
|
||||
|| pt->gprop_from_dbus_fcn != pt_2->gprop_from_dbus_fcn
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@
|
|||
#include "nm-vpn-dbus-interface.h"
|
||||
#include "nm-vpn-editor-plugin.h"
|
||||
#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
|
||||
#include "libnm-glib-aux/nm-value-type.h"
|
||||
|
||||
/* NM_SETTING_COMPARE_FLAG_INFERRABLE: check whether a device-generated
|
||||
* connection can be replaced by a already-defined connection. This flag only
|
||||
|
|
@ -684,6 +685,14 @@ typedef enum _nm_packed {
|
|||
typedef struct {
|
||||
const GVariantType *dbus_type;
|
||||
|
||||
/* If this is not NM_VALUE_TYPE_UNSPEC, then this is a "direct" property,
|
||||
* meaning that _nm_setting_get_private() at NMSettInfoProperty.direct_offset
|
||||
* gives direct access to the field.
|
||||
*
|
||||
* Direct properties can use this information to generically implement access
|
||||
* to the property value. */
|
||||
NMValueType direct_type;
|
||||
|
||||
NMSettInfoPropToDBusFcn to_dbus_fcn;
|
||||
NMSettInfoPropFromDBusFcn from_dbus_fcn;
|
||||
NMSettInfoPropMissingFromDBusFcn missing_from_dbus_fcn;
|
||||
|
|
@ -707,6 +716,11 @@ struct _NMSettInfoProperty {
|
|||
|
||||
const NMSettInfoPropertType *property_type;
|
||||
|
||||
/* This only has meaning for direct properties (property_type->direct_type != NM_VALUE_TYPE_UNSPEC).
|
||||
* In that case, this is the offset where _nm_setting_get_private() can find
|
||||
* the direct location. */
|
||||
guint16 direct_offset;
|
||||
|
||||
struct {
|
||||
union {
|
||||
gpointer none;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue