WIP
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This commit is contained in:
parent
106dc900c5
commit
844507bf25
|
@ -29,6 +29,7 @@
|
||||||
#include <libmalcontent/app-filter.h>
|
#include <libmalcontent/app-filter.h>
|
||||||
#include <libmalcontent/manager.h>
|
#include <libmalcontent/manager.h>
|
||||||
#include <libmalcontent/session-limits.h>
|
#include <libmalcontent/session-limits.h>
|
||||||
|
#include <systemd/sd-journal.h>
|
||||||
|
|
||||||
#include "libmalcontent/app-filter-private.h"
|
#include "libmalcontent/app-filter-private.h"
|
||||||
#include "libmalcontent/session-limits-private.h"
|
#include "libmalcontent/session-limits-private.h"
|
||||||
|
@ -1333,3 +1334,132 @@ mct_manager_set_session_limits_finish (MctManager *self,
|
||||||
|
|
||||||
return g_task_propagate_boolean (G_TASK (result), error);
|
return g_task_propagate_boolean (G_TASK (result), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (sd_journal, sd_journal_close)
|
||||||
|
|
||||||
|
/* TODO Docs */
|
||||||
|
MctSessionHistory *
|
||||||
|
mct_manager_get_session_history (MctManager *self,
|
||||||
|
uid_t user_id,
|
||||||
|
GDateTime *start,
|
||||||
|
GDateTime *end,
|
||||||
|
MctManagerGetValueFlags flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_auto(sd_journal) *journal = NULL;
|
||||||
|
int ret;
|
||||||
|
const gchar * const match_message_ids[] =
|
||||||
|
{
|
||||||
|
"MESSAGE_ID=8d45620c1a4348dbb17410da57c60c66", /* new session */
|
||||||
|
"MESSAGE_ID=3354939424b4456d9802ca8333ed424a", /* session ended */
|
||||||
|
"MESSAGE_ID=6bbd95ee977941e497c48be27c254128", /* entering sleep */
|
||||||
|
"MESSAGE_ID=8811e6df2a8e40f58a94cea26f8ebf14", /* leaving sleep */
|
||||||
|
"MESSAGE_ID=b07a249cd024414a82dd00cd181378ff", /* startup complete */
|
||||||
|
"MESSAGE_ID=98268866d1d54a499c4e98921d93bc40", /* starting to shut down */
|
||||||
|
/* TODO: need to add messages to gnome-shell for when the user locks and unlocks the screen,
|
||||||
|
* including logging in and out and switching user */
|
||||||
|
};
|
||||||
|
const size_t message_id_len = sizeof (match_message_ids[0]);
|
||||||
|
g_autoptr(GPtrArray) active_periods = g_ptr_array_new_with_free_func (NULL); /* TODO */
|
||||||
|
|
||||||
|
g_return_val_if_fail (MCT_IS_MANAGER (self), NULL);
|
||||||
|
g_return_val_if_fail (start != NULL, NULL);
|
||||||
|
g_return_val_if_fail (end != NULL, NULL);
|
||||||
|
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
|
||||||
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||||
|
|
||||||
|
ret = sd_journal_open (&journal, SD_JOURNAL_SYSTEM);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Error opening journal: %s", g_strerror (-ret));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: work out what data threshold is needed and set with sd_journal_set_data_threshold() */
|
||||||
|
|
||||||
|
/* Add matches. */
|
||||||
|
for (gsize i = 0; i < G_N_ELEMENTS (match_message_ids); i++)
|
||||||
|
{
|
||||||
|
ret = sd_journal_add_match (journal, "MESSAGE_ID=TODO", 0);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, /* TODO More specific error codes throughout */
|
||||||
|
"Error applying matches in journal: %s", g_strerror (-ret));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sd_journal_seek_realtime_usec (journal, (uint64_t) g_date_time_to_unix (start) * G_USEC_PER_SEC);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, /* TODO More specific error codes throughout */
|
||||||
|
"Error finding start entry in journal: %s", g_strerror (-ret));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
uint64_t entry_realtime = 0;
|
||||||
|
const void *data = NULL;
|
||||||
|
size_t data_len = 0;
|
||||||
|
|
||||||
|
ret = sd_journal_next (journal);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Error seeking journal: %s", g_strerror (-ret));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (ret == 0)
|
||||||
|
{
|
||||||
|
/* Reached EOF. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = sd_journal_get_realtime_usec (journal, &entry_realtime);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Error reading journal: %s", g_strerror (-ret));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry_realtime / G_USEC_PER_SEC >= g_date_time_to_unix (end))
|
||||||
|
{
|
||||||
|
/* Reached the end of the search range. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the type of the record. */
|
||||||
|
ret = sd_journal_get_data (journal, "MESSAGE_ID", &data, &data_len);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Error reading journal: %s", g_strerror (-ret));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data_len != message_id_len)
|
||||||
|
{
|
||||||
|
g_debug ("Unexpected field %s, ignoring", data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: need to filter by uid */
|
||||||
|
if (memcmp (data, "MESSAGE_ID=8d45620c1a4348dbb17410da57c60c66", message_id_len) == 0)
|
||||||
|
{
|
||||||
|
/* New session. */
|
||||||
|
g_ptr_array_add (active_periods, TODO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO */
|
||||||
|
"MESSAGE_ID=3354939424b4456d9802ca8333ed424a", /* session ended */
|
||||||
|
"MESSAGE_ID=6bbd95ee977941e497c48be27c254128", /* entering sleep */
|
||||||
|
"MESSAGE_ID=8811e6df2a8e40f58a94cea26f8ebf14", /* leaving sleep */
|
||||||
|
"MESSAGE_ID=b07a249cd024414a82dd00cd181378ff", /* startup complete */
|
||||||
|
"MESSAGE_ID=98268866d1d54a499c4e98921d93bc40", /* starting to shut down */
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -168,4 +168,13 @@ gboolean mct_manager_set_session_limits_finish (MctManager *
|
||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
/* TODO */
|
||||||
|
MctSessionHistory *mct_manager_get_session_history (MctManager *self,
|
||||||
|
uid_t user_id,
|
||||||
|
GDateTime *start,
|
||||||
|
GDateTime *end,
|
||||||
|
MctManagerGetValueFlags flags,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -3,16 +3,19 @@ libmalcontent_api_name = 'malcontent-' + libmalcontent_api_version
|
||||||
libmalcontent_sources = [
|
libmalcontent_sources = [
|
||||||
'app-filter.c',
|
'app-filter.c',
|
||||||
'manager.c',
|
'manager.c',
|
||||||
|
'session-history.c',
|
||||||
'session-limits.c',
|
'session-limits.c',
|
||||||
]
|
]
|
||||||
libmalcontent_headers = [
|
libmalcontent_headers = [
|
||||||
'app-filter.h',
|
'app-filter.h',
|
||||||
'malcontent.h',
|
'malcontent.h',
|
||||||
'manager.h',
|
'manager.h',
|
||||||
|
'session-history.h',
|
||||||
'session-limits.h',
|
'session-limits.h',
|
||||||
]
|
]
|
||||||
libmalcontent_private_headers = [
|
libmalcontent_private_headers = [
|
||||||
'app-filter-private.h',
|
'app-filter-private.h',
|
||||||
|
'session-history-private.h',
|
||||||
'session-limits-private.h',
|
'session-limits-private.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||||
|
*
|
||||||
|
* Copyright © 2020 Endless Mobile, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* - Philip Withnall <withnall@endlessm.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <libmalcontent/session-history.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
struct _MctSessionHistory
|
||||||
|
{
|
||||||
|
gint ref_count;
|
||||||
|
|
||||||
|
uid_t user_id;
|
||||||
|
|
||||||
|
GDateTime *start; /* (owned) */
|
||||||
|
GDateTime *end; /* (owned) */
|
||||||
|
};
|
||||||
|
|
||||||
|
G_END_DECLS
|
|
@ -0,0 +1,100 @@
|
||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||||
|
*
|
||||||
|
* Copyright © 2020 Endless Mobile, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* - Philip Withnall <withnall@endlessm.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
#include <glib/gi18n-lib.h>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include <libmalcontent/session-history.h>
|
||||||
|
|
||||||
|
#include "libmalcontent/session-history-private.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* struct _MctSessionHistory is defined in session-history-private.h */
|
||||||
|
|
||||||
|
G_DEFINE_BOXED_TYPE (MctSessionHistory, mct_session_history,
|
||||||
|
mct_session_history_ref, mct_session_history_unref)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mct_session_history_ref:
|
||||||
|
* @history: (transfer none): an #MctSessionHistory
|
||||||
|
*
|
||||||
|
* Increment the reference count of @history, and return the same pointer to it.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): the same pointer as @history
|
||||||
|
* Since: 0.5.0
|
||||||
|
*/
|
||||||
|
MctSessionHistory *
|
||||||
|
mct_session_history_ref (MctSessionHistory *history)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (history != NULL, NULL);
|
||||||
|
g_return_val_if_fail (history->ref_count >= 1, NULL);
|
||||||
|
g_return_val_if_fail (history->ref_count <= G_MAXINT - 1, NULL);
|
||||||
|
|
||||||
|
history->ref_count++;
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mct_session_history_unref:
|
||||||
|
* @history: (transfer full): an #MctSessionHistory
|
||||||
|
*
|
||||||
|
* Decrement the reference count of @history. If the reference count reaches
|
||||||
|
* zero, free the @history and all its resources.
|
||||||
|
*
|
||||||
|
* Since: 0.5.0
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mct_session_history_unref (MctSessionHistory *history)
|
||||||
|
{
|
||||||
|
g_return_if_fail (history != NULL);
|
||||||
|
g_return_if_fail (history->ref_count >= 1);
|
||||||
|
|
||||||
|
history->ref_count--;
|
||||||
|
|
||||||
|
if (history->ref_count <= 0)
|
||||||
|
{
|
||||||
|
g_clear_pointer (&history->start, g_date_time_unref);
|
||||||
|
g_clear_pointer (&history->end, g_date_time_unref);
|
||||||
|
g_free (history);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mct_session_history_get_user_id:
|
||||||
|
* @history: an #MctSessionHistory
|
||||||
|
*
|
||||||
|
* Get the user ID of the user this #MctSessionHistory is for.
|
||||||
|
*
|
||||||
|
* Returns: user ID of the relevant user
|
||||||
|
* Since: 0.5.0
|
||||||
|
*/
|
||||||
|
uid_t
|
||||||
|
mct_session_history_get_user_id (MctSessionHistory *history)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (history != NULL, (uid_t) -1);
|
||||||
|
g_return_val_if_fail (history->ref_count >= 1, (uid_t) -1);
|
||||||
|
|
||||||
|
return history->user_id;
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||||
|
*
|
||||||
|
* Copyright © 2020 Endless Mobile, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* - Philip Withnall <withnall@endlessm.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MctSessionHistory:
|
||||||
|
*
|
||||||
|
* TODO
|
||||||
|
* #MctSessionLimits is an opaque, immutable structure which contains a snapshot
|
||||||
|
* of the session limits settings for a user at a given time. This includes
|
||||||
|
* whether session limits are being enforced, and the limit policy — for
|
||||||
|
* example, the times of day when a user is allowed to use the computer.
|
||||||
|
*
|
||||||
|
* Typically, session limits settings can only be changed by the administrator,
|
||||||
|
* and are read-only for non-administrative users. The precise policy is set
|
||||||
|
* using polkit.
|
||||||
|
*
|
||||||
|
* Since: 0.5.0
|
||||||
|
*/
|
||||||
|
typedef struct _MctSessionHistory MctSessionHistory;
|
||||||
|
GType mct_session_history_get_type (void);
|
||||||
|
#define MCT_TYPE_SESSION_HISTORY mct_session_history_get_type ()
|
||||||
|
|
||||||
|
MctSessionHistory *mct_session_history_ref (MctSessionHistory *history);
|
||||||
|
void mct_session_history_unref (MctSessionHistory *history);
|
||||||
|
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MctSessionHistory, mct_session_history_unref)
|
||||||
|
|
||||||
|
uid_t mct_session_history_get_user_id (MctSessionHistory *history);
|
||||||
|
GDateTime *mct_session_history_get_start (MctSessionHistory *history);
|
||||||
|
GDateTime *mct_session_history_get_end (MctSessionHistory *history);
|
||||||
|
|
||||||
|
G_END_DECLS
|
Loading…
Reference in New Issue