Commit 460c0c6c authored by Bob Ham's avatar Bob Ham
Browse files

Turn providers into plugins courtesy of libpeas

This is an initial, static implementation of plugins.  The
CallsApplication has a plugin name which can be changed with a new
--provider command line option.  This plugin name is used to
instantiate the appropriate plugin when the application is activated.
From then on, the plugin cannot change.

In future, we can expand this support to include loading multiple
plugins at once, configurable through some UI.  This will have
far-reaching implications though, and complicate things like
enumerating the provider hierarchy.  There is also no practical
benefit right now; the mm and ofono plugins can't be used at the same
time because ModemManager and oFono don't play nice together, and the
whole raison d'être of the dummy plugin is undermined if you can make
use of one of the others.  So for now, we just implement one static
plugin.
parent b6cd5a3f
...@@ -9,6 +9,7 @@ Build-Depends: ...@@ -9,6 +9,7 @@ Build-Depends:
modemmanager-dev, modemmanager-dev,
libmm-glib-dev, libmm-glib-dev,
libgsound-dev, libgsound-dev,
libpeas-dev,
meson, meson,
pkg-config, pkg-config,
# to run the tests # to run the tests
......
gnome = import('gnome')
dbus_interfaces = ['manager', 'modem', 'call']
gdbus_src = []
foreach iface: dbus_interfaces
gdbus_src += gnome.gdbus_codegen('gdbo-' + iface,
iface + '.xml',
interface_prefix: 'org.ofono.',
namespace: 'GDBO')
endforeach
deps = [ dependency('gio-2.0'),
dependency('gio-unix-2.0'),
]
gdbofono_lib = static_library('gdbofono',
gdbus_src,
include_directories : include_directories('..'),
dependencies : deps )
...@@ -19,11 +19,17 @@ ...@@ -19,11 +19,17 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
# #
project('call', 'c', project(
version: '0.0.0', 'calls',
license: 'GPLv3+', 'c',
meson_version: '>= 0.42.0', version: '0.0.0',
default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ], license: 'GPLv3+',
meson_version: '>= 0.46.0',
default_options: [
'warning_level=1',
'buildtype=debugoptimized',
'c_std=gnu11'
]
) )
calls_id = 'sm.puri.Calls' calls_id = 'sm.puri.Calls'
...@@ -31,9 +37,26 @@ calls_homepage = 'https://source.puri.sm/Librem5/calls' ...@@ -31,9 +37,26 @@ calls_homepage = 'https://source.puri.sm/Librem5/calls'
calls_name = meson.project_name() calls_name = meson.project_name()
calls_version = meson.project_version() calls_version = meson.project_version()
subdir('libgdbofono') top_include = include_directories('.')
prefix = get_option('prefix')
libdir = get_option('libdir')
localedir = get_option('localedir')
full_localedir = join_paths(prefix, localedir)
full_calls_plugin_libdir = join_paths(prefix, libdir, calls_name, 'plugins')
config_data = configuration_data()
config_data.set_quoted('APP_ID', calls_id)
config_data.set_quoted('GETTEXT_PACKAGE', calls_name)
config_data.set_quoted('LOCALEDIR', full_localedir)
config_data.set_quoted('PLUGIN_LIBDIR', full_calls_plugin_libdir)
config_data.set_quoted('PACKAGE_URL', calls_homepage)
config_data.set_quoted('PACKAGE_VERSION', calls_version)
config_data.set('PACKAGE_URL_RAW', calls_homepage)
subdir('po') subdir('po')
subdir('src') subdir('src')
subdir('plugins')
subdir('doc') subdir('doc')
subdir('data') subdir('data')
subdir('tests') subdir('tests')
...@@ -27,6 +27,9 @@ ...@@ -27,6 +27,9 @@
#include "calls-provider.h" #include "calls-provider.h"
#include "calls-dummy-origin.h" #include "calls-dummy-origin.h"
#include <libpeas/peas.h>
struct _CallsDummyProvider struct _CallsDummyProvider
{ {
GObject parent_instance; GObject parent_instance;
...@@ -37,12 +40,26 @@ struct _CallsDummyProvider ...@@ -37,12 +40,26 @@ struct _CallsDummyProvider
static void calls_dummy_provider_message_source_interface_init (CallsProviderInterface *iface); static void calls_dummy_provider_message_source_interface_init (CallsProviderInterface *iface);
static void calls_dummy_provider_provider_interface_init (CallsProviderInterface *iface); static void calls_dummy_provider_provider_interface_init (CallsProviderInterface *iface);
G_DEFINE_TYPE_WITH_CODE (CallsDummyProvider, calls_dummy_provider, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (CALLS_TYPE_MESSAGE_SOURCE,
calls_dummy_provider_message_source_interface_init)
G_IMPLEMENT_INTERFACE (CALLS_TYPE_PROVIDER,
calls_dummy_provider_provider_interface_init))
#ifdef FOR_TESTING
G_DEFINE_TYPE_WITH_CODE
(CallsDummyProvider, calls_dummy_provider, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (CALLS_TYPE_MESSAGE_SOURCE,
calls_dummy_provider_message_source_interface_init)
G_IMPLEMENT_INTERFACE (CALLS_TYPE_PROVIDER,
calls_dummy_provider_provider_interface_init))
#else
G_DEFINE_DYNAMIC_TYPE_EXTENDED
(CallsDummyProvider, calls_dummy_provider, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE_DYNAMIC (CALLS_TYPE_MESSAGE_SOURCE,
calls_dummy_provider_message_source_interface_init)
G_IMPLEMENT_INTERFACE_DYNAMIC (CALLS_TYPE_PROVIDER,
calls_dummy_provider_provider_interface_init))
#endif /* FOR_TESTING */
enum { enum {
PROP_0, PROP_0,
...@@ -65,10 +82,15 @@ get_origins (CallsProvider *iface) ...@@ -65,10 +82,15 @@ get_origins (CallsProvider *iface)
} }
CallsDummyProvider * static void
calls_dummy_provider_new () constructed (GObject *object)
{ {
return g_object_new (CALLS_TYPE_DUMMY_PROVIDER, NULL); GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
CallsDummyProvider *self = CALLS_DUMMY_PROVIDER (object);
calls_dummy_provider_add_origin (self, "Dummy origin");
parent_class->constructed (object);
} }
...@@ -108,8 +130,9 @@ calls_dummy_provider_class_init (CallsDummyProviderClass *klass) ...@@ -108,8 +130,9 @@ calls_dummy_provider_class_init (CallsDummyProviderClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = dispose; object_class->constructed = constructed;
object_class->get_property = get_property; object_class->get_property = get_property;
object_class->dispose = dispose;
g_object_class_override_property (object_class, PROP_STATUS, "status"); g_object_class_override_property (object_class, PROP_STATUS, "status");
} }
...@@ -142,3 +165,31 @@ calls_dummy_provider_add_origin (CallsDummyProvider *self, ...@@ -142,3 +165,31 @@ calls_dummy_provider_add_origin (CallsDummyProvider *self,
self->origins = g_list_append (self->origins, self->origins = g_list_append (self->origins,
calls_dummy_origin_new (name)); calls_dummy_origin_new (name));
} }
CallsDummyProvider *
calls_dummy_provider_new ()
{
return g_object_new (CALLS_TYPE_DUMMY_PROVIDER, NULL);
}
#ifndef FOR_TESTING
static void
calls_dummy_provider_class_finalize (CallsDummyProviderClass *klass)
{
}
G_MODULE_EXPORT void
peas_register_types (PeasObjectModule *module)
{
calls_dummy_provider_register_type (G_TYPE_MODULE (module));
peas_object_module_register_extension_type (module,
CALLS_TYPE_PROVIDER,
CALLS_TYPE_DUMMY_PROVIDER);
}
#endif /* FOR_TESTING */
[Plugin]
Module=dummy
Name=Dummy
Description=Dummy calls provider
Authors=Bob Ham <rah@settrans.net>
Copyright=Copyright (C) 2018 Purism SPC
Website=@PACKAGE_URL_RAW@
#
# Copyright (C) 2018 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: Bob Ham <bob.ham@puri.sm>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
dummy_include = include_directories('.')
dummy_install_dir = join_paths(full_calls_plugin_libdir, 'dummy')
dummy_plugin = configure_file(
input: 'dummy.plugin.in',
output: 'dummy.plugin',
configuration: config_data,
install_dir: dummy_install_dir
)
dummy_deps = [
dependency('gobject-2.0'),
dependency('gtk+-3.0'),
dependency('libpeas-1.0'),
]
dummy_sources = files(
[
'calls-dummy-call.c', 'calls-dummy-call.h',
'calls-dummy-origin.c', 'calls-dummy-origin.h',
'calls-dummy-provider.c', 'calls-dummy-provider.h'
]
)
shared_module(
'dummy',
dummy_sources,
dependencies: dummy_deps,
include_directories: src_include,
install: true,
install_dir: dummy_install_dir
)
subdir('mm')
subdir('dummy')
subdir('ofono')
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "calls-origin.h" #include "calls-origin.h"
#include <libmm-glib.h> #include <libmm-glib.h>
#include <libpeas/peas.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
struct _CallsMMProvider struct _CallsMMProvider
...@@ -48,11 +49,13 @@ struct _CallsMMProvider ...@@ -48,11 +49,13 @@ struct _CallsMMProvider
static void calls_mm_provider_message_source_interface_init (CallsProviderInterface *iface); static void calls_mm_provider_message_source_interface_init (CallsProviderInterface *iface);
static void calls_mm_provider_provider_interface_init (CallsProviderInterface *iface); static void calls_mm_provider_provider_interface_init (CallsProviderInterface *iface);
G_DEFINE_TYPE_WITH_CODE (CallsMMProvider, calls_mm_provider, G_TYPE_OBJECT, G_DEFINE_DYNAMIC_TYPE_EXTENDED
G_IMPLEMENT_INTERFACE (CALLS_TYPE_MESSAGE_SOURCE, (CallsMMProvider, calls_mm_provider, G_TYPE_OBJECT, 0,
calls_mm_provider_message_source_interface_init) G_IMPLEMENT_INTERFACE_DYNAMIC (CALLS_TYPE_MESSAGE_SOURCE,
G_IMPLEMENT_INTERFACE (CALLS_TYPE_PROVIDER, calls_mm_provider_message_source_interface_init)
calls_mm_provider_provider_interface_init)) G_IMPLEMENT_INTERFACE_DYNAMIC (CALLS_TYPE_PROVIDER,
calls_mm_provider_provider_interface_init))
enum { enum {
PROP_0, PROP_0,
...@@ -436,6 +439,11 @@ calls_mm_provider_class_init (CallsMMProviderClass *klass) ...@@ -436,6 +439,11 @@ calls_mm_provider_class_init (CallsMMProviderClass *klass)
} }
static void
calls_mm_provider_class_finalize (CallsMMProviderClass *klass)
{
}
static void static void
calls_mm_provider_message_source_interface_init (CallsProviderInterface *iface) calls_mm_provider_message_source_interface_init (CallsProviderInterface *iface)
{ {
...@@ -459,8 +467,12 @@ calls_mm_provider_init (CallsMMProvider *self) ...@@ -459,8 +467,12 @@ calls_mm_provider_init (CallsMMProvider *self)
} }
CallsMMProvider * G_MODULE_EXPORT void
calls_mm_provider_new () peas_register_types (PeasObjectModule *module)
{ {
return g_object_new (CALLS_TYPE_MM_PROVIDER, NULL); calls_mm_provider_register_type (G_TYPE_MODULE (module));
peas_object_module_register_extension_type (module,
CALLS_TYPE_PROVIDER,
CALLS_TYPE_MM_PROVIDER);
} }
...@@ -34,8 +34,6 @@ G_BEGIN_DECLS ...@@ -34,8 +34,6 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (CallsMMProvider, calls_mm_provider, CALLS, MM_PROVIDER, GObject); G_DECLARE_FINAL_TYPE (CallsMMProvider, calls_mm_provider, CALLS, MM_PROVIDER, GObject);
CallsMMProvider *calls_mm_provider_new ();
G_END_DECLS G_END_DECLS
#endif /* CALLS_MM_PROVIDER_H__ */ #endif /* CALLS_MM_PROVIDER_H__ */
#
# Copyright (C) 2018 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: Bob Ham <bob.ham@puri.sm>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
mm_install_dir = join_paths(full_calls_plugin_libdir, 'mm')
mm_plugin = configure_file(
input: 'mm.plugin.in',
output: 'mm.plugin',
configuration: config_data,
install_dir: mm_install_dir
)
mm_deps = [
dependency('gobject-2.0'),
dependency('gtk+-3.0'),
dependency('ModemManager'),
dependency('mm-glib'),
dependency('libpeas-1.0'),
]
mm_sources = files(
[
'calls-mm-call.c', 'calls-mm-call.h',
'calls-mm-origin.c', 'calls-mm-origin.h',
'calls-mm-provider.c', 'calls-mm-provider.h'
]
)
shared_module(
'mm',
mm_sources,
dependencies: mm_deps,
include_directories: src_include,
install: true,
install_dir: mm_install_dir
)
[Plugin]
Module=mm
Name=ModemManager
Description=ModemManager calls provider
Authors=Bob Ham <rah@settrans.net>
Copyright=Copyright (C) 2018 Purism SPC
Website=@PACKAGE_URL_RAW@
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include <libgdbofono/gdbo-modem.h> #include <libgdbofono/gdbo-modem.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <libpeas/peas.h>
struct _CallsOfonoProvider struct _CallsOfonoProvider
{ {
...@@ -47,21 +49,17 @@ struct _CallsOfonoProvider ...@@ -47,21 +49,17 @@ struct _CallsOfonoProvider
GHashTable *origins; GHashTable *origins;
}; };
static void calls_ofono_provider_message_source_interface_init (CallsProviderInterface *iface); static void calls_ofono_provider_message_source_interface_init (CallsProviderInterface *iface);
static void calls_ofono_provider_provider_interface_init (CallsProviderInterface *iface); static void calls_ofono_provider_provider_interface_init (CallsProviderInterface *iface);
G_DEFINE_TYPE_WITH_CODE (CallsOfonoProvider, calls_ofono_provider, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (CALLS_TYPE_MESSAGE_SOURCE,
calls_ofono_provider_message_source_interface_init)
G_IMPLEMENT_INTERFACE (CALLS_TYPE_PROVIDER,
calls_ofono_provider_provider_interface_init))
enum { G_DEFINE_DYNAMIC_TYPE_EXTENDED
PROP_0, (CallsOfonoProvider, calls_ofono_provider, G_TYPE_OBJECT, 0,
PROP_CONNECTION, G_IMPLEMENT_INTERFACE_DYNAMIC (CALLS_TYPE_MESSAGE_SOURCE,
PROP_LAST_PROP, calls_ofono_provider_message_source_interface_init)
}; G_IMPLEMENT_INTERFACE_DYNAMIC (CALLS_TYPE_PROVIDER,
static GParamSpec *props[PROP_LAST_PROP]; calls_ofono_provider_provider_interface_init))
static const gchar * static const gchar *
...@@ -70,6 +68,7 @@ get_name (CallsProvider *iface) ...@@ -70,6 +68,7 @@ get_name (CallsProvider *iface)
return "oFono"; return "oFono";
} }
static void static void
add_origin_to_list (const gchar *path, add_origin_to_list (const gchar *path,
CallsOfonoOrigin *origin, CallsOfonoOrigin *origin,
...@@ -78,6 +77,7 @@ add_origin_to_list (const gchar *path, ...@@ -78,6 +77,7 @@ add_origin_to_list (const gchar *path,
*list = g_list_prepend (*list, origin); *list = g_list_prepend (*list, origin);
} }
static GList * static GList *
get_origins (CallsProvider *iface) get_origins (CallsProvider *iface)
{ {
...@@ -90,36 +90,6 @@ get_origins (CallsProvider *iface) ...@@ -90,36 +90,6 @@ get_origins (CallsProvider *iface)
return g_list_reverse (list); return g_list_reverse (list);
} }
CallsOfonoProvider *
calls_ofono_provider_new (GDBusConnection *connection)
{
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
return g_object_new (CALLS_TYPE_OFONO_PROVIDER,
"connection", connection,
NULL);
}
static void
set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
CallsOfonoProvider *self = CALLS_OFONO_PROVIDER (object);
switch (property_id) {
case PROP_CONNECTION:
g_set_object (&self->connection,
g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void static void
add_origin (CallsOfonoProvider *self, add_origin (CallsOfonoProvider *self,
...@@ -137,6 +107,7 @@ add_origin (CallsOfonoProvider *self, ...@@ -137,6 +107,7 @@ add_origin (CallsOfonoProvider *self,
"origin-added", origin); "origin-added", origin);
} }
static void static void
remove_origin (CallsOfonoProvider *self, remove_origin (CallsOfonoProvider *self,
const gchar *path, const gchar *path,
...@@ -151,6 +122,7 @@ remove_origin (CallsOfonoProvider *self, ...@@ -151,6 +122,7 @@ remove_origin (CallsOfonoProvider *self,
g_object_unref (origin); g_object_unref (origin);
} }
static gboolean static gboolean
object_array_includes (GVariantIter *iter, object_array_includes (GVariantIter *iter,
const gchar *needle) const gchar *needle)
...@@ -170,6 +142,7 @@ object_array_includes (GVariantIter *iter, ...@@ -170,6 +142,7 @@ object_array_includes (GVariantIter *iter,
return found; return found;
} }
static void static void
modem_check_ifaces (CallsOfonoProvider *self, modem_check_ifaces (CallsOfonoProvider *self,
GDBOModem *modem, GDBOModem *modem,
...@@ -199,6 +172,7 @@ modem_check_ifaces (CallsOfonoProvider *self, ...@@ -199,6 +172,7 @@ modem_check_ifaces (CallsOfonoProvider *self,
} }
} }
static void static void
modem_property_changed_cb (GDBOModem *modem, modem_property_changed_cb (GDBOModem *modem,
const gchar *name, const gchar *name,
...