1
0
Fork 0
mirror of https://gitlab.gnome.org/GNOME/calls.git synced 2024-06-01 18:09:25 +00:00

wip: Introduce CallsPolicyManager

This commit is contained in:
Evangelos Ribeiro Tzaras 2023-05-19 17:09:34 +02:00
parent 5ba92f9935
commit 8a74f0f70f
3 changed files with 273 additions and 0 deletions

225
src/calls-policy-manager.c Normal file
View file

@ -0,0 +1,225 @@
/*
* Copyright (C) 2023 Purism SPC
*
* This file is part of Calls.
*
* Calls is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calls 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calls. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Evangelos Ribeiro Tzaras <devrtz@fortysixandtwo.eu>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*
*/
#define G_LOG_DOMAIN "CallsPolicyManager"
#include "calls-policy-engine.h"
#include "calls-policy-manager.h"
/**
* SECTION:calls-policy-manager
* @short_description: Manages call policy backends
* @Title: CallsPolicyManager
*
* Queries managed policy engines for their individual #CallsPolicyDecision
* and forms a final decision.
*/
enum {
PROP_0,
PROP_ENGINES,
PROP_LAST_PROP
};
static GParamSpec *props[PROP_LAST_PROP];
struct _CallsPolicyManager {
GObject parent_instance;
GListModel *engines;
GCancellable *cancel;
};
G_DEFINE_TYPE (CallsPolicyManager, calls_policy_manager, G_TYPE_OBJECT)
typedef struct {
char *id;
GVariant *decision;
guint n_decisions;
GAsyncReadyCallback callback;
gpointer user_data;
} DecisionAggregationData;
static void
aggregate_decision (DecisionAggregationData *data,
GVariant *new_decision)
{
g_autoptr (GError) error = NULL;
g_assert (data);
data->n_decisions++;
if (!calls_policy_decision_is_valid (new_decision, &error)) {
g_warning ("Invalid policy decision: %s", error->message);
if (new_decision)
g_variant_unref (new_decision);
return;
}
if (!data->decision) {
data->decision = new_decision;
} else {
CallsPolicyDecision new_decision_type;
CallsPolicyDecision old_decision_type;
g_variant_get (new_decision, CALLS_POLICY_DECISION_FORMAT, &new_decision_type, NULL);
g_variant_get (data->decision, CALLS_POLICY_DECISION_FORMAT, &old_decision_type, NULL);
if (new_decision_type > old_decision_type) {
g_variant_unref (data->decision);
data->decision = new_decision;
} else {
g_variant_unref (new_decision);
}
}
}
static void
on_decision_ready (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
;
}
static void
calls_policy_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
CallsPolicyManager *self = CALLS_POLICY_MANAGER (object);
switch (prop_id) {
case PROP_ENGINES:
self->engines = g_value_dup_object (value);
g_assert (g_list_model_get_item_type (self->engines) == CALLS_TYPE_POLICY_ENGINE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
calls_policy_manager_dispose (GObject *object)
{
CallsPolicyManager *self = CALLS_POLICY_MANAGER (object);
g_clear_object (&self->engines);
g_clear_object (&self->cancel);
G_OBJECT_CLASS (calls_policy_manager_parent_class)->dispose (object);
}
static void
calls_policy_manager_class_init (CallsPolicyManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->set_property = calls_policy_manager_set_property;
object_class->dispose = calls_policy_manager_dispose;
/**
* CallsPolicyManager:engines:
*
* A #GListModel of [type@CALLS_POLICY_ENGINE]s which get queried
* by @calls_policy_manager_decide
*/
props[PROP_ENGINES] =
g_param_spec_object ("engines",
"",
"",
G_TYPE_LIST_MODEL,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
}
static void
calls_policy_manager_init (CallsPolicyManager *self)
{
self->cancel = g_cancellable_new ();
}
CallsPolicyManager *
calls_policy_manager_new (void)
{
return g_object_new (CALLS_TYPE_POLICY_MANAGER, NULL);
}
void
calls_policy_manager_decide (CallsPolicyManager *self,
const char *id,
const char *protocol,
const char *origin_id,
guint timeout_msec,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
DecisionAggregationData *data;
guint n_engines;
g_return_if_fail (CALLS_IS_POLICY_MANAGER (self));
n_engines = g_list_model_get_n_items (self->engines);
if (n_engines == 0) {
GVariant *decision = calls_policy_decision_new (CALLS_POLICY_DECISION_PASS, NULL);
task = g_task_new (self, self->cancel, callback, user_data);
g_task_return_pointer (task, decision, (GDestroyNotify) g_variant_unref);
return;
}
data = g_new0 (DecisionAggregationData, 1);
data->id = g_strdup (id);
data->callback = callback;
data->user_data = user_data;
for (guint i = 0; i < n_engines; i++) {
g_autoptr (CallsPolicyEngine) engine = g_list_model_get_item (self->engines, i);
calls_policy_engine_decide (engine, id, protocol, origin_id, timeout_msec, on_decision_ready, data);
}
}
GVariant *
calls_policy_manager_decide_finish (CallsPolicyManager *self,
GAsyncResult *res,
GError **error)
{
return NULL;
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (C) 2023 Purism SPC
*
* This file is part of Calls.
*
* Calls is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calls 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calls. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Evangelos Ribeiro Tzaras <devrtz@fortysixandtwo.eu>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#pragma once
#include <gio/gio.h>
#include <glib-object.h>
G_BEGIN_DECLS
#define CALLS_TYPE_POLICY_MANAGER calls_policy_manager_get_type ()
G_DECLARE_FINAL_TYPE (CallsPolicyManager, calls_policy_manager, CALLS, POLICY_MANAGER, GObject);
CallsPolicyManager *calls_policy_manager_new (void);
void calls_policy_manager_decide (CallsPolicyManager *self,
const char *id,
const char *protocol,
const char *origin_id,
guint timeout_msec,
GAsyncReadyCallback callback,
gpointer user_data);
GVariant *calls_policy_manager_decide_finish (CallsPolicyManager *self,
GAsyncResult *res,
GError **error);
G_END_DECLS

View file

@ -122,6 +122,7 @@ calls_sources = files([
'calls-plugin.c', 'calls-plugin.h',
'calls-plugin-manager.c', 'calls-plugin-manager.h',
'calls-policy-engine.c', 'calls-policy-engine.h',
'calls-policy-manager.c', 'calls-policy-manager.h',
'calls-provider.c', 'calls-provider.h',
'calls-record-store.c', 'calls-record-store.h',
'calls-ringer.c', 'calls-ringer.h',