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:
parent
5ba92f9935
commit
8a74f0f70f
225
src/calls-policy-manager.c
Normal file
225
src/calls-policy-manager.c
Normal 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;
|
||||
}
|
47
src/calls-policy-manager.h
Normal file
47
src/calls-policy-manager.h
Normal 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
|
|
@ -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',
|
||||
|
|
Loading…
Reference in a new issue