mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-18 08:28:14 +02:00
session-item: refactor export to use a process similar to activate
+ expose the export transition in the session item class + make the export-related flags immutable + add an export error flag + update and improve documentation
This commit is contained in:
parent
441a778b2e
commit
49b63b6045
6 changed files with 212 additions and 178 deletions
|
|
@ -383,7 +383,6 @@ impl_request_state (void *object, enum pw_endpoint_link_state state)
|
|||
|
||||
switch (state) {
|
||||
case PW_ENDPOINT_LINK_STATE_ACTIVE:
|
||||
wp_session_item_deactivate (WP_SESSION_ITEM (self->item));
|
||||
wp_session_item_activate (WP_SESSION_ITEM (self->item),
|
||||
(GAsyncReadyCallback) on_item_activated, self);
|
||||
break;
|
||||
|
|
@ -440,7 +439,7 @@ on_si_link_flags_changed (WpSiLink * item, WpSiFlags flags,
|
|||
{
|
||||
enum pw_endpoint_link_state old_state = self->info.state;
|
||||
|
||||
if (flags & WP_SI_FLAG_IN_ERROR)
|
||||
if (flags & WP_SI_FLAG_EXPORT_ERROR)
|
||||
self->info.state = PW_ENDPOINT_LINK_STATE_ERROR;
|
||||
else if (flags & WP_SI_FLAG_ACTIVE)
|
||||
self->info.state = PW_ENDPOINT_LINK_STATE_ACTIVE;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#define G_LOG_DOMAIN "wp-si"
|
||||
|
||||
#include "session-item.h"
|
||||
#include "debug.h"
|
||||
#include "private.h"
|
||||
#include "error.h"
|
||||
#include "wpenums.h"
|
||||
|
|
@ -169,7 +170,7 @@ wp_session_item_default_get_associated_proxy (WpSessionItem * self,
|
|||
}
|
||||
|
||||
static guint
|
||||
wp_session_item_default_get_next_step (WpSessionItem * self,
|
||||
wp_session_item_default_activate_get_next_step (WpSessionItem * self,
|
||||
WpTransition * transition, guint step)
|
||||
{
|
||||
/* the default implementation just activates instantly,
|
||||
|
|
@ -181,32 +182,25 @@ enum {
|
|||
EXPORT_STEP_ENDPOINT = WP_TRANSITION_STEP_CUSTOM_START,
|
||||
EXPORT_STEP_STREAMS,
|
||||
EXPORT_STEP_LINK,
|
||||
EXPORT_STEP_FINISH,
|
||||
};
|
||||
|
||||
static guint
|
||||
default_export_get_next_step (WpSessionItem * self, WpTransition * transition,
|
||||
guint step)
|
||||
wp_session_item_default_export_get_next_step (WpSessionItem * self,
|
||||
WpTransition * transition, guint step)
|
||||
{
|
||||
WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self);
|
||||
|
||||
switch (step) {
|
||||
case WP_TRANSITION_STEP_NONE:
|
||||
if (WP_IS_SI_ENDPOINT (self)) {
|
||||
priv->flags |= WP_SI_FLAG_EXPORTING;
|
||||
g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
|
||||
if (WP_IS_SI_ENDPOINT (self))
|
||||
return EXPORT_STEP_ENDPOINT;
|
||||
}
|
||||
else if (WP_IS_SI_LINK (self)) {
|
||||
priv->flags |= WP_SI_FLAG_EXPORTING;
|
||||
g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
|
||||
else if (WP_IS_SI_LINK (self))
|
||||
return EXPORT_STEP_LINK;
|
||||
}
|
||||
else {
|
||||
wp_transition_return_error (transition, g_error_new (
|
||||
WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVALID_ARGUMENT,
|
||||
"Cannot export WpSessionItem of unknown type (%s:%p)",
|
||||
G_OBJECT_TYPE_NAME (self), self));
|
||||
"Cannot export WpSessionItem of unknown type " WP_OBJECT_FORMAT,
|
||||
WP_OBJECT_ARGS (self)));
|
||||
return WP_TRANSITION_STEP_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -221,15 +215,12 @@ default_export_get_next_step (WpSessionItem * self, WpTransition * transition,
|
|||
/* go to next step only when all impl proxies are augmented */
|
||||
if (g_hash_table_size (priv->impl_streams) ==
|
||||
wp_si_endpoint_get_n_streams (WP_SI_ENDPOINT (self)))
|
||||
return EXPORT_STEP_FINISH;
|
||||
return WP_TRANSITION_STEP_NONE;
|
||||
else
|
||||
return step;
|
||||
|
||||
case EXPORT_STEP_LINK:
|
||||
g_return_val_if_fail (WP_IS_SI_LINK (self), WP_TRANSITION_STEP_ERROR);
|
||||
return EXPORT_STEP_FINISH;
|
||||
|
||||
case EXPORT_STEP_FINISH:
|
||||
return WP_TRANSITION_STEP_NONE;
|
||||
|
||||
default:
|
||||
|
|
@ -263,8 +254,8 @@ on_export_proxy_augmented (WpProxy * proxy, GAsyncResult * res, gpointer data)
|
|||
}
|
||||
|
||||
static void
|
||||
default_export_execute_step (WpSessionItem * self, WpTransition * transition,
|
||||
guint step)
|
||||
wp_session_item_default_export_execute_step (WpSessionItem * self,
|
||||
WpTransition * transition, guint step)
|
||||
{
|
||||
WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self);
|
||||
g_autoptr (WpSession) session = g_weak_ref_get (&priv->session);
|
||||
|
|
@ -312,67 +303,18 @@ default_export_execute_step (WpSessionItem * self, WpTransition * transition,
|
|||
transition);
|
||||
break;
|
||||
|
||||
case EXPORT_STEP_FINISH:
|
||||
priv->flags &= ~WP_SI_FLAG_EXPORTING;
|
||||
priv->flags |= WP_SI_FLAG_EXPORTED;
|
||||
g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
|
||||
wp_transition_advance (transition);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_return_if_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
default_export_rollback (WpSessionItem * self)
|
||||
wp_session_item_default_export_rollback (WpSessionItem * self)
|
||||
{
|
||||
WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self);
|
||||
static const guint flags = (WP_SI_FLAG_EXPORTING | WP_SI_FLAG_EXPORTED);
|
||||
|
||||
g_clear_pointer (&priv->impl_streams, g_hash_table_unref);
|
||||
g_clear_object (&priv->impl_proxy);
|
||||
g_weak_ref_set (&priv->session, NULL);
|
||||
|
||||
if (priv->flags & flags) {
|
||||
priv->flags &= ~flags;
|
||||
g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wp_session_item_default_export (WpSessionItem * self,
|
||||
WpSession * session, GCancellable * cancellable,
|
||||
GAsyncReadyCallback callback, gpointer callback_data)
|
||||
{
|
||||
WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self);
|
||||
WpTransition *transition;
|
||||
|
||||
g_weak_ref_set (&priv->session, session);
|
||||
|
||||
transition = wp_transition_new (wp_si_transition_get_type (),
|
||||
self, cancellable, callback, callback_data);
|
||||
wp_transition_set_source_tag (transition, wp_session_item_default_export);
|
||||
|
||||
WP_SI_TRANSITION (transition)->get_next_step = default_export_get_next_step;
|
||||
WP_SI_TRANSITION (transition)->execute_step = default_export_execute_step;
|
||||
WP_SI_TRANSITION (transition)->rollback = default_export_rollback;
|
||||
wp_transition_advance (transition);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
wp_session_item_default_export_finish (WpSessionItem * self,
|
||||
GAsyncResult * res, GError ** error)
|
||||
{
|
||||
g_return_val_if_fail (
|
||||
g_async_result_is_tagged (res, wp_session_item_default_export), FALSE);
|
||||
|
||||
return wp_transition_finish (res, error);
|
||||
}
|
||||
|
||||
static void
|
||||
wp_session_item_default_unexport (WpSessionItem * self)
|
||||
{
|
||||
default_export_rollback (self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -385,10 +327,10 @@ wp_session_item_class_init (WpSessionItemClass * klass)
|
|||
|
||||
klass->reset = wp_session_item_default_reset;
|
||||
klass->get_associated_proxy = wp_session_item_default_get_associated_proxy;
|
||||
klass->get_next_step = wp_session_item_default_get_next_step;
|
||||
klass->export = wp_session_item_default_export;
|
||||
klass->export_finish = wp_session_item_default_export_finish;
|
||||
klass->unexport = wp_session_item_default_unexport;
|
||||
klass->activate_get_next_step = wp_session_item_default_activate_get_next_step;
|
||||
klass->export_get_next_step = wp_session_item_default_export_get_next_step;
|
||||
klass->export_execute_step = wp_session_item_default_export_execute_step;
|
||||
klass->export_rollback = wp_session_item_default_export_rollback;
|
||||
|
||||
/**
|
||||
* WpSessionItem::flags-changed:
|
||||
|
|
@ -574,17 +516,14 @@ wp_session_item_get_configuration (WpSessionItem * self)
|
|||
}
|
||||
|
||||
static void
|
||||
on_transition_completed (WpTransition * transition, GParamSpec * pspec,
|
||||
on_activate_transition_completed (WpTransition * transition, GParamSpec * pspec,
|
||||
WpSessionItem * self)
|
||||
{
|
||||
WpSessionItemPrivate *priv =
|
||||
wp_session_item_get_instance_private (self);
|
||||
|
||||
if (wp_transition_had_error (transition))
|
||||
priv->flags |= WP_SI_FLAG_IN_ERROR;
|
||||
else
|
||||
priv->flags |= WP_SI_FLAG_ACTIVE;
|
||||
|
||||
priv->flags |= wp_transition_had_error (transition) ?
|
||||
WP_SI_FLAG_ACTIVATE_ERROR : WP_SI_FLAG_ACTIVE;
|
||||
priv->flags &= ~WP_SI_FLAG_ACTIVATING;
|
||||
g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
|
||||
}
|
||||
|
|
@ -595,15 +534,30 @@ on_transition_completed (WpTransition * transition, GParamSpec * pspec,
|
|||
* @callback: (scope async): a callback to call when activation is finished
|
||||
* @callback_data: (closure): data passed to @callback
|
||||
*
|
||||
* Activates the item asynchronously. This internally starts a #WpTransition
|
||||
* that calls into #WpSessionItemClass.get_next_step() and
|
||||
* #WpSessionItemClass.execute_step() to advance.
|
||||
*
|
||||
* You can use wp_session_item_activate_finish() in the @callback to figure out
|
||||
* Activates the item asynchronously.
|
||||
* You can use wp_session_item_activate_finish() in the @callback to get
|
||||
* the result of this operation.
|
||||
*
|
||||
* Normally this function is called internally by the session; there is no need
|
||||
* to activate an item externally, except for unit testing purposes.
|
||||
* This internally starts a #WpTransition that calls into
|
||||
* #WpSessionItemClass.activate_get_next_step() and
|
||||
* #WpSessionItemClass.activate_execute_step() to advance.
|
||||
* If the transition fails, #WpSessionItemClass.activate_rollback() is called
|
||||
* to reverse previous actions.
|
||||
*
|
||||
* The default implementation of the above virtual functions activates the
|
||||
* item successfully without doing anything. In order to implement a meaningful
|
||||
* session item, you should override all 3 of them.
|
||||
*
|
||||
* When this method is called, the %WP_SI_FLAG_ACTIVATING flag is set. When
|
||||
* the operation finishes successfully, that flag is cleared and replaced with
|
||||
* either %WP_SI_FLAG_ACTIVE or %WP_SI_FLAG_ACTIVATE_ERROR, depending on the
|
||||
* success outcome of the operation. In order to clear
|
||||
* %WP_SI_FLAG_ACTIVATE_ERROR, you can either call wp_session_item_deactivate()
|
||||
* or wp_session_item_activate() to try activating again.
|
||||
*
|
||||
* This method cannot be called if another operation (activation or export) is
|
||||
* in progress (%WP_SI_FLAGS_MASK_OPERATION_IN_PROGRESS) or if the item is
|
||||
* already activated.
|
||||
*/
|
||||
void
|
||||
wp_session_item_activate (WpSessionItem * self,
|
||||
|
|
@ -615,24 +569,26 @@ wp_session_item_activate (WpSessionItem * self,
|
|||
WpSessionItemPrivate *priv =
|
||||
wp_session_item_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (!(priv->flags & (WP_SI_FLAG_ACTIVATING | WP_SI_FLAG_ACTIVE)));
|
||||
g_return_if_fail (!(priv->flags &
|
||||
(WP_SI_FLAGS_MASK_OPERATION_IN_PROGRESS | WP_SI_FLAG_ACTIVE)));
|
||||
|
||||
/* TODO: add a way to cancel the transition if reset() is called in the meantime */
|
||||
/* TODO: add a way to cancel the transition if deactivate() is called in the meantime */
|
||||
WpTransition *transition = wp_transition_new (wp_si_transition_get_type (),
|
||||
self, NULL, callback, callback_data);
|
||||
wp_transition_set_source_tag (transition, wp_session_item_activate);
|
||||
g_signal_connect (transition, "notify::completed",
|
||||
(GCallback) on_transition_completed, self);
|
||||
(GCallback) on_activate_transition_completed, self);
|
||||
|
||||
priv->flags &= ~WP_SI_FLAG_ACTIVATE_ERROR;
|
||||
priv->flags |= WP_SI_FLAG_ACTIVATING;
|
||||
g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
|
||||
|
||||
WP_SI_TRANSITION (transition)->get_next_step =
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->get_next_step;
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->activate_get_next_step;
|
||||
WP_SI_TRANSITION (transition)->execute_step =
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->execute_step;
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->activate_execute_step;
|
||||
WP_SI_TRANSITION (transition)->rollback =
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->rollback;
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->activate_rollback;
|
||||
wp_transition_advance (transition);
|
||||
}
|
||||
|
||||
|
|
@ -648,6 +604,7 @@ gboolean
|
|||
wp_session_item_activate_finish (WpSessionItem * self, GAsyncResult * res,
|
||||
GError ** error)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_SESSION_ITEM (self), FALSE);
|
||||
g_return_val_if_fail (
|
||||
g_async_result_is_tagged (res, wp_session_item_activate), FALSE);
|
||||
return wp_transition_finish (res, error);
|
||||
|
|
@ -667,14 +624,13 @@ wp_session_item_deactivate (WpSessionItem * self)
|
|||
g_return_if_fail (WP_IS_SESSION_ITEM (self));
|
||||
|
||||
WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self);
|
||||
static const guint flags =
|
||||
(WP_SI_FLAG_ACTIVATING | WP_SI_FLAG_ACTIVE | WP_SI_FLAG_IN_ERROR);
|
||||
static const guint flags = 0xf; /* all activation flags */
|
||||
|
||||
//TODO cancel job if ACTIVATING
|
||||
|
||||
if (priv->flags & WP_SI_FLAG_ACTIVE &&
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->rollback)
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->rollback (self);
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->activate_rollback)
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->activate_rollback (self);
|
||||
|
||||
if (priv->flags & flags) {
|
||||
priv->flags &= ~flags;
|
||||
|
|
@ -682,19 +638,52 @@ wp_session_item_deactivate (WpSessionItem * self)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_export_transition_completed (WpTransition * transition, GParamSpec * pspec,
|
||||
WpSessionItem * self)
|
||||
{
|
||||
WpSessionItemPrivate *priv =
|
||||
wp_session_item_get_instance_private (self);
|
||||
|
||||
priv->flags |= wp_transition_had_error (transition) ?
|
||||
WP_SI_FLAG_EXPORT_ERROR : WP_SI_FLAG_EXPORTED;
|
||||
priv->flags &= ~WP_SI_FLAG_EXPORTING;
|
||||
g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_session_item_export: (virtual export)
|
||||
* wp_session_item_export:
|
||||
* @self: the session item
|
||||
* @session: the session on which to export this item
|
||||
* @callback: (scope async): a callback to call when exporting is finished
|
||||
* @callback_data: (closure): data passed to @callback
|
||||
*
|
||||
* Exports this item asynchronously on PipeWire, making it part of the
|
||||
* specified @session.
|
||||
* specified @session. You can use wp_session_item_export_finish() in the
|
||||
* @callback to get the result of this operation.
|
||||
*
|
||||
* Exporting only makes sense for endpoints (items that implement #WpSiEndpoint)
|
||||
* and endpoint links (items that implement #WpSiLink). On other items the
|
||||
* default implementation will immediately call the @callback, reporting error.
|
||||
* This internally starts a #WpTransition that calls into
|
||||
* #WpSessionItemClass.export_get_next_step() and
|
||||
* #WpSessionItemClass.export_execute_step() to advance.
|
||||
* If the transition fails, #WpSessionItemClass.export_rollback() is called
|
||||
* to reverse previous actions.
|
||||
*
|
||||
* Exporting is internally implemented for endpoints (items that implement
|
||||
* #WpSiEndpoint) and endpoint links (items that implement #WpSiLink). On other
|
||||
* items the default implementation will immediately call the @callback,
|
||||
* reporting error. You can extend this to export custom interfaces by
|
||||
* overriding the virtual functions mentioned above.
|
||||
*
|
||||
* When this method is called, the %WP_SI_FLAG_EXPORTING flag is set. When
|
||||
* the operation finishes successfully, that flag is cleared and replaced with
|
||||
* either %WP_SI_FLAG_EXPORTED or %WP_SI_FLAG_EXPORT_ERROR, depending on the
|
||||
* success outcome of the operation. In order to clear
|
||||
* %WP_SI_FLAG_EXPORT_ERROR, you can either call wp_session_item_unexport()
|
||||
* or wp_session_item_export() to try exporting again.
|
||||
*
|
||||
* This method cannot be called if another operation (activation or export) is
|
||||
* in progress (%WP_SI_FLAGS_MASK_OPERATION_IN_PROGRESS) or if the item is
|
||||
* already exported.
|
||||
*/
|
||||
void
|
||||
wp_session_item_export (WpSessionItem * self, WpSession * session,
|
||||
|
|
@ -702,19 +691,37 @@ wp_session_item_export (WpSessionItem * self, WpSession * session,
|
|||
{
|
||||
g_return_if_fail (WP_IS_SESSION_ITEM (self));
|
||||
g_return_if_fail (WP_IS_SESSION (session));
|
||||
g_return_if_fail (WP_SESSION_ITEM_GET_CLASS (self)->export);
|
||||
|
||||
WpSessionItemPrivate *priv =
|
||||
wp_session_item_get_instance_private (self);
|
||||
|
||||
g_return_if_fail (!(priv->flags & (WP_SI_FLAG_EXPORTING | WP_SI_FLAG_EXPORTED)));
|
||||
g_return_if_fail (!(priv->flags &
|
||||
(WP_SI_FLAGS_MASK_OPERATION_IN_PROGRESS | WP_SI_FLAG_EXPORTED)));
|
||||
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->export (self, session, NULL,
|
||||
callback, callback_data);
|
||||
g_weak_ref_set (&priv->session, session);
|
||||
|
||||
/* TODO: add a way to cancel the transition if unexport() is called in the meantime */
|
||||
WpTransition *transition = wp_transition_new (wp_si_transition_get_type (),
|
||||
self, NULL, callback, callback_data);
|
||||
wp_transition_set_source_tag (transition, wp_session_item_export);
|
||||
g_signal_connect (transition, "notify::completed",
|
||||
(GCallback) on_export_transition_completed, self);
|
||||
|
||||
priv->flags &= ~WP_SI_FLAG_EXPORT_ERROR;
|
||||
priv->flags |= WP_SI_FLAG_EXPORTING;
|
||||
g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
|
||||
|
||||
WP_SI_TRANSITION (transition)->get_next_step =
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->export_get_next_step;
|
||||
WP_SI_TRANSITION (transition)->execute_step =
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->export_execute_step;
|
||||
WP_SI_TRANSITION (transition)->rollback =
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->export_rollback;
|
||||
wp_transition_advance (transition);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_session_item_export_finish: (virtual export_finish)
|
||||
* wp_session_item_export_finish:
|
||||
* @self: the session item
|
||||
* @res: the async operation result
|
||||
* @error: (out) (optional): the error of the operation, if any
|
||||
|
|
@ -726,13 +733,13 @@ wp_session_item_export_finish (WpSessionItem * self, GAsyncResult * res,
|
|||
GError ** error)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_SESSION_ITEM (self), FALSE);
|
||||
g_return_val_if_fail (WP_SESSION_ITEM_GET_CLASS (self)->export_finish, FALSE);
|
||||
|
||||
return WP_SESSION_ITEM_GET_CLASS (self)->export_finish (self, res, error);
|
||||
g_return_val_if_fail (
|
||||
g_async_result_is_tagged (res, wp_session_item_export), FALSE);
|
||||
return wp_transition_finish (res, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* wp_session_item_unexport: (virtual unexport)
|
||||
* wp_session_item_unexport:
|
||||
* @self: the session item
|
||||
*
|
||||
* Reverses the effects of a previous call to wp_session_item_export().
|
||||
|
|
@ -747,9 +754,18 @@ void
|
|||
wp_session_item_unexport (WpSessionItem * self)
|
||||
{
|
||||
g_return_if_fail (WP_IS_SESSION_ITEM (self));
|
||||
g_return_if_fail (WP_SESSION_ITEM_GET_CLASS (self)->unexport);
|
||||
|
||||
WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self);
|
||||
static const guint flags = 0xf0; /* all export flags */
|
||||
|
||||
//TODO cancel job if EXPORTING
|
||||
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->unexport (self);
|
||||
if (priv->flags & WP_SI_FLAG_EXPORTED &&
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->export_rollback)
|
||||
WP_SESSION_ITEM_GET_CLASS (self)->export_rollback (self);
|
||||
|
||||
if (priv->flags & flags) {
|
||||
priv->flags &= ~flags;
|
||||
g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,30 +28,42 @@ G_DECLARE_DERIVABLE_TYPE (WpSessionItem, wp_session_item,
|
|||
* WpSiFlags:
|
||||
* @WP_SI_FLAG_ACTIVATING: set when an activation transition is in progress
|
||||
* @WP_SI_FLAG_ACTIVE: set when an activation transition completes successfully
|
||||
* @WP_SI_FLAG_IN_ERROR: set when there was an error in the activation process;
|
||||
* to recover, the handler must call wp_session_item_reset() before anything
|
||||
* else
|
||||
* @WP_SI_FLAG_CONFIGURED: must be set by subclasses when all the required
|
||||
* (%WP_SI_CONFIG_OPTION_REQUIRED) configuration options have been set
|
||||
* @WP_SI_FLAG_ACTIVATE_ERROR: set when there was an error in the activation
|
||||
* process; to clear, call wp_session_item_deactivate()
|
||||
* @WP_SI_FLAG_EXPORTING: set when an export operation is in progress
|
||||
* @WP_SI_FLAG_EXPORTED: set when the item has exported all necessary objects
|
||||
* to PipeWire
|
||||
* @WP_SI_FLAG_EXPORT_ERROR: set when there was an error in the export
|
||||
* process; to clear, call wp_session_item_unexport()
|
||||
* @WP_SI_FLAG_CONFIGURED: must be set by subclasses when all the required
|
||||
* (%WP_SI_CONFIG_OPTION_REQUIRED) configuration options have been set
|
||||
*/
|
||||
typedef enum {
|
||||
/* immutable flags, set internally */
|
||||
WP_SI_FLAG_ACTIVATING = (1<<0),
|
||||
WP_SI_FLAG_ACTIVE = (1<<1),
|
||||
WP_SI_FLAG_IN_ERROR = (1<<4),
|
||||
WP_SI_FLAG_ACTIVATE_ERROR = (1<<2),
|
||||
|
||||
WP_SI_FLAG_EXPORTING = (1<<4),
|
||||
WP_SI_FLAG_EXPORTED = (1<<5),
|
||||
WP_SI_FLAG_EXPORT_ERROR = (1<<6),
|
||||
|
||||
/* flags that can be changed by subclasses */
|
||||
WP_SI_FLAG_CONFIGURED = (1<<8),
|
||||
WP_SI_FLAG_EXPORTING = (1<<9),
|
||||
WP_SI_FLAG_EXPORTED = (1<<10),
|
||||
|
||||
/* implementation-specific flags */
|
||||
WP_SI_FLAG_CUSTOM_START = (1<<16),
|
||||
} WpSiFlags;
|
||||
|
||||
/**
|
||||
* WP_SI_FLAGS_MASK_OPERATION_IN_PROGRESS:
|
||||
*
|
||||
* A #WpSiFlags mask that can be used to test if an async operation
|
||||
* (activate or export) is currently in progress.
|
||||
*/
|
||||
#define WP_SI_FLAGS_MASK_OPERATION_IN_PROGRESS \
|
||||
(WP_SI_FLAG_ACTIVATING | WP_SI_FLAG_EXPORTING)
|
||||
|
||||
/**
|
||||
* WpSiConfigOptionFlags:
|
||||
* @WP_SI_CONFIG_OPTION_WRITEABLE: the option can be set externally
|
||||
|
|
@ -68,14 +80,18 @@ typedef enum {
|
|||
* @get_associated_proxy: See wp_session_item_get_associated_proxy()
|
||||
* @configure: See wp_session_item_configure()
|
||||
* @get_configuration: See wp_session_item_get_configuration()
|
||||
* @get_next_step: Implements #WpTransitionClass.get_next_step() for the
|
||||
* transition of wp_session_item_activate()
|
||||
* @execute_step: Implements #WpTransitionClass.execute_step() for the
|
||||
* transition of wp_session_item_activate()
|
||||
* @rollback:
|
||||
* @export: See wp_session_item_export()
|
||||
* @export_finish: See wp_session_item_export_finish()
|
||||
* @unexport: See wp_session_item_unexport()
|
||||
* @activate_get_next_step: Implements #WpTransitionClass.get_next_step()
|
||||
* for the transition of wp_session_item_activate()
|
||||
* @activate_execute_step: Implements #WpTransitionClass.execute_step()
|
||||
* for the transition of wp_session_item_activate()
|
||||
* @activate_rollback: Reverses any effects of the activation process;
|
||||
* see wp_session_item_activate()
|
||||
* @export_get_next_step: Implements #WpTransitionClass.get_next_step()
|
||||
* for the transition of wp_session_item_export()
|
||||
* @export_execute_step: Implements #WpTransitionClass.execute_step()
|
||||
* for the transition of wp_session_item_export()
|
||||
* @export_rollback: Reverses any effects of the export process;
|
||||
* see wp_session_item_export()
|
||||
*/
|
||||
struct _WpSessionItemClass
|
||||
{
|
||||
|
|
@ -88,18 +104,17 @@ struct _WpSessionItemClass
|
|||
gboolean (*configure) (WpSessionItem * self, GVariant * args);
|
||||
GVariant * (*get_configuration) (WpSessionItem * self);
|
||||
|
||||
guint (*get_next_step) (WpSessionItem * self, WpTransition * transition,
|
||||
guint step);
|
||||
void (*execute_step) (WpSessionItem * self, WpTransition * transition,
|
||||
guint step);
|
||||
void (*rollback) (WpSessionItem * self);
|
||||
guint (*activate_get_next_step) (WpSessionItem * self,
|
||||
WpTransition * transition, guint step);
|
||||
void (*activate_execute_step) (WpSessionItem * self,
|
||||
WpTransition * transition, guint step);
|
||||
void (*activate_rollback) (WpSessionItem * self);
|
||||
|
||||
void (*export) (WpSessionItem * self,
|
||||
WpSession * session, GCancellable * cancellable,
|
||||
GAsyncReadyCallback callback, gpointer callback_data);
|
||||
gboolean (*export_finish) (WpSessionItem * self, GAsyncResult * res,
|
||||
GError ** error);
|
||||
void (*unexport) (WpSessionItem * self);
|
||||
guint (*export_get_next_step) (WpSessionItem * self,
|
||||
WpTransition * transition, guint step);
|
||||
void (*export_execute_step) (WpSessionItem * self,
|
||||
WpTransition * transition, guint step);
|
||||
void (*export_rollback) (WpSessionItem * self);
|
||||
};
|
||||
|
||||
WP_API
|
||||
|
|
|
|||
|
|
@ -69,15 +69,6 @@ si_adapter_reset (WpSessionItem * item)
|
|||
g_clear_object (&self->node);
|
||||
}
|
||||
|
||||
static void
|
||||
si_adapter_rollback (WpSessionItem * item)
|
||||
{
|
||||
WpSiAdapter *self = WP_SI_ADAPTER (item);
|
||||
|
||||
g_clear_object (&self->ports_om);
|
||||
wp_session_item_clear_flag (item, WP_SI_FLAG_CONFIGURED);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
si_adapter_get_associated_proxy (WpSessionItem * item, GType proxy_type)
|
||||
{
|
||||
|
|
@ -186,7 +177,7 @@ si_adapter_configure (WpSessionItem * item, GVariant * args)
|
|||
}
|
||||
|
||||
static guint
|
||||
si_adapter_get_next_step (WpSessionItem * item,
|
||||
si_adapter_activate_get_next_step (WpSessionItem * item,
|
||||
WpTransition * transition, guint step)
|
||||
{
|
||||
switch (step) {
|
||||
|
|
@ -270,8 +261,8 @@ on_ports_changed (WpObjectManager *om, WpTransition * transition)
|
|||
}
|
||||
|
||||
static void
|
||||
si_adapter_execute_step (WpSessionItem * item, WpTransition * transition,
|
||||
guint step)
|
||||
si_adapter_activate_execute_step (WpSessionItem * item,
|
||||
WpTransition * transition, guint step)
|
||||
{
|
||||
WpSiAdapter *self = WP_SI_ADAPTER (item);
|
||||
|
||||
|
|
@ -356,6 +347,15 @@ si_adapter_execute_step (WpSessionItem * item, WpTransition * transition,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
si_adapter_activate_rollback (WpSessionItem * item)
|
||||
{
|
||||
WpSiAdapter *self = WP_SI_ADAPTER (item);
|
||||
|
||||
g_clear_object (&self->ports_om);
|
||||
wp_session_item_clear_flag (item, WP_SI_FLAG_CONFIGURED);
|
||||
}
|
||||
|
||||
static void
|
||||
si_adapter_class_init (WpSiAdapterClass * klass)
|
||||
{
|
||||
|
|
@ -365,9 +365,9 @@ si_adapter_class_init (WpSiAdapterClass * klass)
|
|||
si_class->get_associated_proxy = si_adapter_get_associated_proxy;
|
||||
si_class->configure = si_adapter_configure;
|
||||
si_class->get_configuration = si_adapter_get_configuration;
|
||||
si_class->get_next_step = si_adapter_get_next_step;
|
||||
si_class->execute_step = si_adapter_execute_step;
|
||||
si_class->rollback = si_adapter_rollback;
|
||||
si_class->activate_get_next_step = si_adapter_activate_get_next_step;
|
||||
si_class->activate_execute_step = si_adapter_activate_execute_step;
|
||||
si_class->activate_rollback = si_adapter_activate_rollback;
|
||||
}
|
||||
|
||||
static guint
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ si_standard_link_configure (WpSessionItem * item, GVariant * args)
|
|||
}
|
||||
|
||||
static guint
|
||||
si_standard_link_get_next_step (WpSessionItem * item,
|
||||
si_standard_link_activate_get_next_step (WpSessionItem * item,
|
||||
WpTransition * transition, guint step)
|
||||
{
|
||||
WpSiStandardLink *self = wp_transition_get_source_object (transition);
|
||||
|
|
@ -320,8 +320,8 @@ create_links (WpSiStandardLink * self, GVariant * out_ports, GVariant * in_ports
|
|||
}
|
||||
|
||||
static void
|
||||
si_standard_link_execute_step (WpSessionItem * item, WpTransition * transition,
|
||||
guint step)
|
||||
si_standard_link_activate_execute_step (WpSessionItem * item,
|
||||
WpTransition * transition, guint step)
|
||||
{
|
||||
WpSiStandardLink *self = WP_SI_STANDARD_LINK (item);
|
||||
|
||||
|
|
@ -379,7 +379,7 @@ si_standard_link_execute_step (WpSessionItem * item, WpTransition * transition,
|
|||
}
|
||||
|
||||
static void
|
||||
si_standard_link_rollback (WpSessionItem * item)
|
||||
si_standard_link_activate_rollback (WpSessionItem * item)
|
||||
{
|
||||
WpSiStandardLink *self = WP_SI_STANDARD_LINK (item);
|
||||
WpSiEndpoint *out_endpoint, *in_endpoint;
|
||||
|
|
@ -410,9 +410,9 @@ si_standard_link_class_init (WpSiStandardLinkClass * klass)
|
|||
si_class->reset = si_standard_link_reset;
|
||||
si_class->configure = si_standard_link_configure;
|
||||
si_class->get_configuration = si_standard_link_get_configuration;
|
||||
si_class->get_next_step = si_standard_link_get_next_step;
|
||||
si_class->execute_step = si_standard_link_execute_step;
|
||||
si_class->rollback = si_standard_link_rollback;
|
||||
si_class->activate_get_next_step = si_standard_link_activate_get_next_step;
|
||||
si_class->activate_execute_step = si_standard_link_activate_execute_step;
|
||||
si_class->activate_rollback = si_standard_link_activate_rollback;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ si_dummy_configure (WpSessionItem * item, GVariant * args)
|
|||
}
|
||||
|
||||
static guint
|
||||
si_dummy_get_next_step (WpSessionItem * item,
|
||||
si_dummy_activate_get_next_step (WpSessionItem * item,
|
||||
WpTransition * transition, guint step)
|
||||
{
|
||||
switch (step) {
|
||||
|
|
@ -94,7 +94,7 @@ si_dummy_step_1 (gpointer data)
|
|||
}
|
||||
|
||||
static void
|
||||
si_dummy_execute_step (WpSessionItem * item, WpTransition * transition,
|
||||
si_dummy_activate_execute_step (WpSessionItem * item, WpTransition * transition,
|
||||
guint step)
|
||||
{
|
||||
TestSiDummy *self = TEST_SI_DUMMY (item);
|
||||
|
|
@ -117,7 +117,7 @@ si_dummy_execute_step (WpSessionItem * item, WpTransition * transition,
|
|||
}
|
||||
|
||||
static void
|
||||
si_dummy_rollback (WpSessionItem * item)
|
||||
si_dummy_activate_rollback (WpSessionItem * item)
|
||||
{
|
||||
TestSiDummy *self = TEST_SI_DUMMY (item);
|
||||
|
||||
|
|
@ -133,9 +133,9 @@ si_dummy_class_init (TestSiDummyClass * klass)
|
|||
|
||||
si_class->configure = si_dummy_configure;
|
||||
si_class->get_configuration = si_dummy_get_configuration;
|
||||
si_class->get_next_step = si_dummy_get_next_step;
|
||||
si_class->execute_step = si_dummy_execute_step;
|
||||
si_class->rollback = si_dummy_rollback;
|
||||
si_class->activate_get_next_step = si_dummy_activate_get_next_step;
|
||||
si_class->activate_execute_step = si_dummy_activate_execute_step;
|
||||
si_class->activate_rollback = si_dummy_activate_rollback;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -159,11 +159,13 @@ test_flags (void)
|
|||
g_assert_cmpint (wp_session_item_get_flags (item), ==, WP_SI_FLAG_CUSTOM_START);
|
||||
g_assert_cmpint (signalled_flags, ==, WP_SI_FLAG_CUSTOM_START);
|
||||
|
||||
/* internal flag, cannot be set */
|
||||
signalled_flags = 0;
|
||||
wp_session_item_set_flag (item, WP_SI_FLAG_ACTIVATING);
|
||||
g_assert_cmpint (wp_session_item_get_flags (item), ==, WP_SI_FLAG_CUSTOM_START);
|
||||
g_assert_cmpint (signalled_flags, ==, 0);
|
||||
/* internal flags cannot be set */
|
||||
for (gint i = 0; i < 8; i++) {
|
||||
signalled_flags = 0;
|
||||
wp_session_item_set_flag (item, 1 << i);
|
||||
g_assert_cmpint (wp_session_item_get_flags (item), ==, WP_SI_FLAG_CUSTOM_START);
|
||||
g_assert_cmpint (signalled_flags, ==, 0);
|
||||
}
|
||||
|
||||
signalled_flags = WP_SI_FLAG_CUSTOM_START;
|
||||
wp_session_item_clear_flag (item, WP_SI_FLAG_CUSTOM_START);
|
||||
|
|
@ -297,13 +299,15 @@ test_activation_error (void)
|
|||
g_main_loop_run (loop);
|
||||
|
||||
g_assert_cmpint (wp_session_item_get_flags (item), ==,
|
||||
WP_SI_FLAG_CONFIGURED | WP_SI_FLAG_IN_ERROR);
|
||||
WP_SI_FLAG_ACTIVATE_ERROR | WP_SI_FLAG_CONFIGURED);
|
||||
g_assert_cmpint (signalled_flags, ==,
|
||||
WP_SI_FLAG_CONFIGURED | WP_SI_FLAG_IN_ERROR);
|
||||
WP_SI_FLAG_ACTIVATE_ERROR | WP_SI_FLAG_CONFIGURED);
|
||||
g_assert_false (dummy->step_1_done);
|
||||
g_assert_false (dummy->step_2_done);
|
||||
g_assert_true (dummy->cleaned_up);
|
||||
|
||||
/* deactivate should not call activate_rollback,
|
||||
it should only clear the error flag */
|
||||
dummy->cleaned_up = FALSE;
|
||||
wp_session_item_deactivate (item);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue