+static void unwatch_parent (NMActiveConnection *self);
+
+static void
+parent_destroyed (gpointer user_data, GObject *parent)
+{
+ NMActiveConnection *self = user_data;
+
+ unwatch_parent (self);
+ g_signal_emit (self, signals[PARENT_ACTIVE], 0, NULL);
+}
+
+static void
+parent_state_cb (NMActiveConnection *parent_ac,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ NMActiveConnection *self = user_data;
+ NMActiveConnectionState parent_state = nm_active_connection_get_state (parent_ac);
+
+ if (parent_state < NM_ACTIVE_CONNECTION_STATE_ACTIVATED)
+ return;
+
+ unwatch_parent (self);
+ g_signal_emit (self, signals[PARENT_ACTIVE], 0, parent_ac);
+}
+
+static void
+unwatch_parent (NMActiveConnection *self)
+{
+ NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
+
+ g_signal_handlers_disconnect_by_func (priv->parent,
+ (GCallback) parent_state_cb,
+ self);
+ g_object_weak_unref ((GObject *) priv->parent, parent_destroyed, self);
+ priv->parent = NULL;
+}
+
+/**
+ * nm_active_connection_set_parent:
+ * @self: the #NMActiveConnection
+ * @parent: The #NMActiveConnection that must be active before the manager
+ * can proceed progressing the device to disconnected state for us.
+ *
+ * Sets the parent connection of @self. A "parent-active" signal will be
+ * emitted when the parent connection becomes active.
+ */
+void
+nm_active_connection_set_parent (NMActiveConnection *self, NMActiveConnection *parent)
+{
+ NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
+
+ g_return_if_fail (priv->parent == NULL);
+ priv->parent = parent;
+ g_signal_connect (priv->parent,
+ "notify::" NM_ACTIVE_CONNECTION_STATE,
+ (GCallback) parent_state_cb,
+ self);
+ g_object_weak_ref ((GObject *) priv->parent, parent_destroyed, self);
+}
+
+/****************************************************************/
+