1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
/*
* Copyright (C) 2024 The Phosh Developers
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "testlib-wait-for-shell-state.h"
static gboolean
check_shell_state (PhoshTestWaitForShellState *self)
{
PhoshShellStateFlags flags;
flags = phosh_shell_get_state (self->shell);
return ( ( self->state_enabled && (flags & self->state)) ||
(!self->state_enabled && !(flags & self->state)));
}
static void
on_shell_state (PhoshShell *shell, GParamSpec *pspec, PhoshTestWaitForShellState *self)
{
g_assert_nonnull (self);
if (check_shell_state (self)) {
g_signal_handler_disconnect (self->shell, self->signal_id);
g_async_queue_push (self->queue, (gpointer) TRUE);
}
}
PhoshTestWaitForShellState*
phosh_test_wait_for_shell_state_new (PhoshShell *shell)
{
PhoshTestWaitForShellState *self;
self = g_new0 (PhoshTestWaitForShellState, 1);
self->queue = g_async_queue_new ();
self->shell = shell;
return self;
}
void
phosh_test_wait_for_shell_state_dispose (PhoshTestWaitForShellState *self)
{
g_assert_nonnull (self);
g_clear_pointer (&self->queue, g_async_queue_unref);
g_free (self);
}
static void
on_shell_idle (gpointer data)
{
PhoshTestWaitForShellState *self;
self = (PhoshTestWaitForShellState*) data;
/* make sure the state we're checking for isn't already current.
* otherwise, we'll wait for a state change that never comes */
if (check_shell_state (self))
g_async_queue_push (self->queue, (gpointer)TRUE);
else
self->signal_id = g_signal_connect (self->shell, "notify::shell-state",
G_CALLBACK (on_shell_state), self);
}
void
phosh_test_wait_for_shell_state_wait (PhoshTestWaitForShellState *self, PhoshShellStateFlags state,
gboolean enabled, guint64 timeout_ms)
{
g_autofree char *str_state = NULL;
self->state = state;
self->state_enabled = enabled;
/* schedule an idle callback in the shell (default) context. we can't access the shell state
* or register signal handlers from here - we're in the wrong thread. */
g_idle_add_once (on_shell_idle, self);
if (g_async_queue_timeout_pop (self->queue, timeout_ms * 1000) == NULL) {
str_state = g_flags_to_string (PHOSH_TYPE_SHELL_STATE_FLAGS, state);
g_error ("Timed out waiting for %s to be %s", str_state, enabled ? "TRUE" : "FALSE");
}
}
|