Merge branch 'plugins' into 'master'

Turn providers into plugins courtesy of libpeas

See merge request Librem5/calls!35
This commit is contained in:
Bob Ham 2018-11-23 15:54:36 +00:00
commit 2d4ac90ff4
39 changed files with 672 additions and 181 deletions

1
debian/control vendored
View File

@ -9,6 +9,7 @@ Build-Depends:
modemmanager-dev,
libmm-glib-dev,
libgsound-dev,
libpeas-dev,
meson,
pkg-config,
# to run the tests

View File

@ -1,19 +0,0 @@
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 )

View File

@ -19,11 +19,17 @@
# SPDX-License-Identifier: GPL-3.0-or-later
#
project('call', 'c',
version: '0.0.0',
license: 'GPLv3+',
meson_version: '>= 0.42.0',
default_options: [ 'warning_level=1', 'buildtype=debugoptimized', 'c_std=gnu11' ],
project(
'calls',
'c',
version: '0.0.0',
license: 'GPLv3+',
meson_version: '>= 0.46.0',
default_options: [
'warning_level=1',
'buildtype=debugoptimized',
'c_std=gnu11'
]
)
calls_id = 'sm.puri.Calls'
@ -31,9 +37,26 @@ calls_homepage = 'https://source.puri.sm/Librem5/calls'
calls_name = meson.project_name()
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('src')
subdir('plugins')
subdir('doc')
subdir('data')
subdir('tests')

View File

@ -27,6 +27,9 @@
#include "calls-provider.h"
#include "calls-dummy-origin.h"
#include <libpeas/peas.h>
struct _CallsDummyProvider
{
GObject parent_instance;
@ -37,12 +40,26 @@ struct _CallsDummyProvider
static void calls_dummy_provider_message_source_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 {
PROP_0,
@ -65,10 +82,15 @@ get_origins (CallsProvider *iface)
}
CallsDummyProvider *
calls_dummy_provider_new ()
static void
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)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = dispose;
object_class->constructed = constructed;
object_class->get_property = get_property;
object_class->dispose = dispose;
g_object_class_override_property (object_class, PROP_STATUS, "status");
}
@ -142,3 +165,31 @@ calls_dummy_provider_add_origin (CallsDummyProvider *self,
self->origins = g_list_append (self->origins,
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 */

View File

@ -0,0 +1,7 @@
[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@

56
plugins/dummy/meson.build Normal file
View File

@ -0,0 +1,56 @@
#
# 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
)

3
plugins/meson.build Normal file
View File

@ -0,0 +1,3 @@
subdir('mm')
subdir('dummy')
subdir('ofono')

View File

@ -29,6 +29,7 @@
#include "calls-origin.h"
#include <libmm-glib.h>
#include <libpeas/peas.h>
#include <glib/gi18n.h>
struct _CallsMMProvider
@ -48,11 +49,13 @@ struct _CallsMMProvider
static void calls_mm_provider_message_source_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_IMPLEMENT_INTERFACE (CALLS_TYPE_MESSAGE_SOURCE,
calls_mm_provider_message_source_interface_init)
G_IMPLEMENT_INTERFACE (CALLS_TYPE_PROVIDER,
calls_mm_provider_provider_interface_init))
G_DEFINE_DYNAMIC_TYPE_EXTENDED
(CallsMMProvider, calls_mm_provider, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE_DYNAMIC (CALLS_TYPE_MESSAGE_SOURCE,
calls_mm_provider_message_source_interface_init)
G_IMPLEMENT_INTERFACE_DYNAMIC (CALLS_TYPE_PROVIDER,
calls_mm_provider_provider_interface_init))
enum {
PROP_0,
@ -436,6 +439,11 @@ calls_mm_provider_class_init (CallsMMProviderClass *klass)
}
static void
calls_mm_provider_class_finalize (CallsMMProviderClass *klass)
{
}
static void
calls_mm_provider_message_source_interface_init (CallsProviderInterface *iface)
{
@ -459,8 +467,12 @@ calls_mm_provider_init (CallsMMProvider *self)
}
CallsMMProvider *
calls_mm_provider_new ()
G_MODULE_EXPORT void
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);
}

View File

@ -34,8 +34,6 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (CallsMMProvider, calls_mm_provider, CALLS, MM_PROVIDER, GObject);
CallsMMProvider *calls_mm_provider_new ();
G_END_DECLS
#endif /* CALLS_MM_PROVIDER_H__ */

56
plugins/mm/meson.build Normal file
View File

@ -0,0 +1,56 @@
#
# 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
)

7
plugins/mm/mm.plugin.in Normal file
View File

@ -0,0 +1,7 @@
[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@

View File

@ -32,6 +32,8 @@
#include <libgdbofono/gdbo-modem.h>
#include <glib/gi18n.h>
#include <libpeas/peas.h>
struct _CallsOfonoProvider
{
@ -47,21 +49,17 @@ struct _CallsOfonoProvider
GHashTable *origins;
};
static void calls_ofono_provider_message_source_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 {
PROP_0,
PROP_CONNECTION,
PROP_LAST_PROP,
};
static GParamSpec *props[PROP_LAST_PROP];
G_DEFINE_DYNAMIC_TYPE_EXTENDED
(CallsOfonoProvider, calls_ofono_provider, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE_DYNAMIC (CALLS_TYPE_MESSAGE_SOURCE,
calls_ofono_provider_message_source_interface_init)
G_IMPLEMENT_INTERFACE_DYNAMIC (CALLS_TYPE_PROVIDER,
calls_ofono_provider_provider_interface_init))
static const gchar *
@ -70,6 +68,7 @@ get_name (CallsProvider *iface)
return "oFono";
}
static void
add_origin_to_list (const gchar *path,
CallsOfonoOrigin *origin,
@ -78,6 +77,7 @@ add_origin_to_list (const gchar *path,
*list = g_list_prepend (*list, origin);
}
static GList *
get_origins (CallsProvider *iface)
{
@ -90,36 +90,6 @@ get_origins (CallsProvider *iface)
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
add_origin (CallsOfonoProvider *self,
@ -137,6 +107,7 @@ add_origin (CallsOfonoProvider *self,
"origin-added", origin);
}
static void
remove_origin (CallsOfonoProvider *self,
const gchar *path,
@ -151,6 +122,7 @@ remove_origin (CallsOfonoProvider *self,
g_object_unref (origin);
}
static gboolean
object_array_includes (GVariantIter *iter,
const gchar *needle)
@ -170,6 +142,7 @@ object_array_includes (GVariantIter *iter,
return found;
}
static void
modem_check_ifaces (CallsOfonoProvider *self,
GDBOModem *modem,
@ -199,6 +172,7 @@ modem_check_ifaces (CallsOfonoProvider *self,
}
}
static void
modem_property_changed_cb (GDBOModem *modem,
const gchar *name,
@ -220,6 +194,7 @@ modem_property_changed_cb (GDBOModem *modem,
modem_check_ifaces (self, modem, modem_name, value);
}
struct CallsModemProxyNewData
{
CallsOfonoProvider *self;
@ -227,6 +202,7 @@ struct CallsModemProxyNewData
GVariant *ifaces;
};
static void
modem_proxy_new_cb (GDBusConnection *connection,
GAsyncResult *res,
@ -274,6 +250,7 @@ modem_proxy_new_cb (GDBusConnection *connection,
g_debug ("Modem `%s' added", path);
}
static gchar *
modem_properties_get_name (GVariant *properties)
{
@ -297,6 +274,7 @@ modem_properties_get_name (GVariant *properties)
return NULL;
}
static void
modem_added_cb (GDBOManager *manager,
const gchar *path,
@ -336,6 +314,7 @@ modem_added_cb (GDBOManager *manager,
g_debug ("Modem `%s' addition in progress", path);
}
static void
modem_removed_cb (GDBOManager *manager,
const gchar *path,
@ -405,6 +384,13 @@ constructed (GObject *object)
CallsOfonoProvider *self = CALLS_OFONO_PROVIDER (object);
GError *error = NULL;
self->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (!self->connection)
{
g_error ("Error creating D-Bus connection: %s",
error->message);
}
self->manager = gdbo_manager_proxy_new_sync
(self->connection,
G_DBUS_PROXY_FLAGS_NONE,
@ -416,7 +402,6 @@ constructed (GObject *object)
{
g_error ("Error creating ModemManager object manager proxy: %s",
error->message);
return;
}
g_signal_connect (self->manager, "modem-added",
@ -440,14 +425,13 @@ dispose (GObject *object)
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
CallsOfonoProvider *self = CALLS_OFONO_PROVIDER (object);
// FIXME
g_clear_object (&self->manager);
g_clear_object (&self->connection);
parent_class->dispose (object);
}
static void
finalize (GObject *object)
{
@ -466,26 +450,24 @@ calls_ofono_provider_class_init (CallsOfonoProviderClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->set_property = set_property;
object_class->constructed = constructed;
object_class->dispose = dispose;
object_class->finalize = finalize;
props[PROP_CONNECTION] =
g_param_spec_object ("connection",
_("Connection"),
_("The D-Bus connection to use for communication with oFono"),
G_TYPE_DBUS_CONNECTION,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
}
static void
calls_ofono_provider_class_finalize (CallsOfonoProviderClass *klass)
{
}
static void
calls_ofono_provider_message_source_interface_init (CallsProviderInterface *iface)
{
}
static void
calls_ofono_provider_provider_interface_init (CallsProviderInterface *iface)
{
@ -493,6 +475,7 @@ calls_ofono_provider_provider_interface_init (CallsProviderInterface *iface)
iface->get_origins = get_origins;
}
static void
calls_ofono_provider_init (CallsOfonoProvider *self)
{
@ -501,3 +484,14 @@ calls_ofono_provider_init (CallsOfonoProvider *self)
self->origins = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL);
}
G_MODULE_EXPORT void
peas_register_types (PeasObjectModule *module)
{
calls_ofono_provider_register_type (G_TYPE_MODULE (module));
peas_object_module_register_extension_type (module,
CALLS_TYPE_PROVIDER,
CALLS_TYPE_OFONO_PROVIDER);
}

View File

@ -34,8 +34,6 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (CallsOfonoProvider, calls_ofono_provider, CALLS, OFONO_PROVIDER, GObject);
CallsOfonoProvider *calls_ofono_provider_new (GDBusConnection *connection);
G_END_DECLS
#endif /* CALLS_OFONO_PROVIDER_H__ */

View File

@ -0,0 +1,51 @@
#
# 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
#
gnome = import('gnome')
dbus_interfaces = ['manager', 'modem', 'call']
gdbofono_src = []
gdbofono_headers = []
foreach iface: dbus_interfaces
src = gnome.gdbus_codegen(
'gdbo-' + iface,
iface + '.xml',
interface_prefix: 'org.ofono.',
namespace: 'GDBO'
)
gdbofono_src += src
gdbofono_headers += src[1]
endforeach
gdbofono_deps = [
dependency('gio-2.0'),
dependency('gio-unix-2.0'),
]
gdbofono_lib = static_library(
'gdbofono',
gdbofono_src,
include_directories: top_include,
dependencies: gdbofono_deps
)

60
plugins/ofono/meson.build Normal file
View File

@ -0,0 +1,60 @@
#
# 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
#
subdir('libgdbofono')
ofono_install_dir = join_paths(full_calls_plugin_libdir, 'ofono')
ofono_plugin = configure_file(
input: 'ofono.plugin.in',
output: 'ofono.plugin',
configuration: config_data,
install_dir: ofono_install_dir
)
ofono_deps = [
dependency('gobject-2.0'),
dependency('gtk+-3.0'),
dependency('libpeas-1.0'),
]
ofono_sources = files(
[
'calls-ofono-call.c', 'calls-ofono-call.h',
'calls-ofono-origin.c', 'calls-ofono-origin.h',
'calls-ofono-provider.c', 'calls-ofono-provider.h'
]
)
shared_module(
'ofono',
ofono_sources, gdbofono_headers,
dependencies: ofono_deps,
include_directories: [
src_include,
include_directories('.')
],
link_with: gdbofono_lib,
install: true,
install_dir: ofono_install_dir
)

View File

@ -0,0 +1,7 @@
[Plugin]
Module=ofono
Name=oFono
Description=oFono calls provider
Authors=Bob Ham <rah@settrans.net>
Copyright=Copyright (C) 2018 Purism SPC
Website=@PACKAGE_URL_RAW@

View File

@ -25,23 +25,23 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <glib/gi18n.h>
#define HANDY_USE_UNSTABLE_API
#include <handy.h>
#include "config.h"
#include "calls-new-call-header-bar.h"
#include "calls-history-header-bar.h"
#include "calls-history-box.h"
#include "calls-new-call-box.h"
#include "calls-encryption-indicator.h"
#include "calls-mm-provider.h"
#include "calls-ringer.h"
#include "calls-call-window.h"
#include "calls-main-window.h"
#include "calls-application.h"
#define HANDY_USE_UNSTABLE_API
#include <handy.h>
#include <libpeas/peas.h>
#include <glib/gi18n.h>
/**
* SECTION: calls-application
* @title: CallsApplication
@ -49,10 +49,13 @@
* @include: "calls-application.h"
*/
#define DEFAULT_PROVIDER_PLUGIN "mm"
struct _CallsApplication
{
GtkApplication parent_instance;
GString *provider_name;
CallsProvider *provider;
CallsRinger *ringer;
};
@ -60,6 +63,217 @@ struct _CallsApplication
G_DEFINE_TYPE (CallsApplication, calls_application, GTK_TYPE_APPLICATION)
static gint
handle_local_options (GApplication *application,
GVariantDict *options)
{
gboolean ok;
g_autoptr(GError) error = NULL;
const gchar *name;
g_debug ("Registering application");
ok = g_application_register (application, NULL, &error);
if (!ok)
{
g_error ("Error registering application: %s",
error->message);
}
ok = g_variant_dict_lookup (options, "provider", "&s", &name);
if (ok)
{
g_action_group_activate_action (G_ACTION_GROUP (application),
"set-provider-name",
g_variant_new_string (name));
}
return -1; // Continue processing signal
}
static void
set_provider_name_action (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
CallsApplication *self = CALLS_APPLICATION (user_data);
const gchar *name;
name = g_variant_get_string (parameter, NULL);
g_return_if_fail (name != NULL);
if (self->provider)
{
g_warning ("Cannot set provider name to `%s'"
" because provider is already created",
name);
return;
}
g_string_assign (self->provider_name, name);
g_debug ("Provider name set to `%s'",
self->provider_name->str);
}
static const GActionEntry actions[] =
{
{ "set-provider-name", set_provider_name_action, "s" },
};
static void
startup (GApplication *application)
{
G_APPLICATION_CLASS (calls_application_parent_class)->startup (application);
g_set_prgname (APP_ID);
g_set_application_name (_("Calls"));
g_action_map_add_action_entries (G_ACTION_MAP (application),
actions,
G_N_ELEMENTS (actions),
application);
}
static void
load_provider_plugin (CallsApplication *self)
{
const gchar * const name = self->provider_name->str;
PeasEngine *plugins;
PeasPluginInfo *info;
PeasExtension *extension;
g_assert (self->provider == NULL);
// Add Calls search path and rescan
plugins = peas_engine_get_default ();
peas_engine_add_search_path (plugins, PLUGIN_LIBDIR, PLUGIN_LIBDIR);
g_debug ("Scanning for plugins in `%s'", PLUGIN_LIBDIR);
// Find the plugin
info = peas_engine_get_plugin_info (plugins, name);
if (!info)
{
g_critical ("Could not find plugin `%s'", name);
return;
}
// Possibly load the plugin
if (!peas_plugin_info_is_loaded (info))
{
g_autoptr(GError) error = NULL;
peas_engine_load_plugin (plugins, info);
if (!peas_plugin_info_is_available (info, &error))
{
if (error)
{
g_critical ("Error loading plugin `%s': %s",
name, error->message);
}
else
{
g_critical ("Could not load plugin `%s'", name);
}
return;
}
g_debug ("Loaded plugin `%s'", name);
}
// Check the plugin provides CallsProvider
if (!peas_engine_provides_extension
(plugins, info, CALLS_TYPE_PROVIDER))
{
g_critical ("Plugin `%s' does not have a provider extension",
name);
return;
}
// Get the extension
extension = peas_engine_create_extensionv
(plugins, info, CALLS_TYPE_PROVIDER, 0, NULL);
if (!extension)
{
g_critical ("Could not create provider from plugin `%s'",
name);
return;
}
g_debug ("Created provider from plugin `%s'", name);
self->provider = CALLS_PROVIDER (extension);
}
static void
activate (GApplication *application)
{
GtkApplication *gtk_app;
GtkWindow *window;
g_assert (GTK_IS_APPLICATION (application));
gtk_app = GTK_APPLICATION (application);
window = gtk_application_get_active_window (gtk_app);
if (window == NULL)
{
CallsApplication *self = CALLS_APPLICATION (application);
// Later we will make provider loading/unloaded a dynamic
// process but that will have far-reaching consequences and is
// of no use immediately so for now, we just load one provider
// at startup. We can't put this in the actual startup() method
// though, because we need to be able to set the provider name
// from the command line and we use actions to do that, which
// depend on the application already being started up.
if (!self->provider)
{
load_provider_plugin (self);
if (!self->provider)
{
g_application_quit (application);
return;
}
self->ringer = calls_ringer_new (self->provider);
g_assert (self->ringer != NULL);
}
/*
* We don't track the memory created. Ideally, we might have to.
* But we assume that the application is closed by closing the
* window. In that case, GTK+ frees the resources right.
*/
window = GTK_WINDOW (calls_main_window_new (gtk_app, self->provider));
calls_call_window_new (gtk_app, self->provider);
}
gtk_window_present (window);
}
static void
constructed (GObject *object)
{
GObjectClass *parent_class = g_type_class_peek (GTK_TYPE_APPLICATION);
CallsApplication *self = CALLS_APPLICATION (object);
GSimpleActionGroup *action_group;
action_group = g_simple_action_group_new ();
g_action_map_add_action_entries (G_ACTION_MAP (action_group),
actions, G_N_ELEMENTS (actions), self);
g_object_unref (action_group);
parent_class->constructed (object);
}
static void
dispose (GObject *object)
{
@ -68,51 +282,20 @@ dispose (GObject *object)
g_clear_object (&self->ringer);
g_clear_object (&self->provider);
G_OBJECT_CLASS (calls_application_parent_class)->dispose (object);
}
static void
finalize (GObject *object)
{
CallsApplication *self = (CallsApplication *)object;
g_string_free (self->provider_name, TRUE);
G_OBJECT_CLASS (calls_application_parent_class)->finalize (object);
}
static void
startup (GApplication *application)
{
CallsApplication *self = (CallsApplication *)application;
g_autoptr(GError) error = NULL;
G_APPLICATION_CLASS (calls_application_parent_class)->startup (application);
g_set_prgname (APP_ID);
g_set_application_name (_("Calls"));
self->provider = CALLS_PROVIDER (calls_mm_provider_new ());
g_assert (self->provider != NULL);
self->ringer = calls_ringer_new (self->provider);
g_assert (self->ringer != NULL);
}
static void
activate (GApplication *application)
{
CallsApplication *self = (CallsApplication *)application;
GtkApplication *app = (GtkApplication *)application;
GtkWindow *window;
g_assert (GTK_IS_APPLICATION (app));
window = gtk_application_get_active_window (app);
if (window == NULL)
{
/*
* We don't track the memory created. Ideally, we might have to.
* But we assume that the application is closed by closing the
* window. In that case, GTK+ frees the resources right.
*/
window = GTK_WINDOW (calls_main_window_new (app, self->provider));
calls_call_window_new (app, self->provider);
}
gtk_window_present (window);
}
static void
calls_application_class_init (CallsApplicationClass *klass)
@ -120,8 +303,11 @@ calls_application_class_init (CallsApplicationClass *klass)
GApplicationClass *application_class = G_APPLICATION_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = constructed;
object_class->dispose = dispose;
object_class->finalize = finalize;
application_class->handle_local_options = handle_local_options;
application_class->startup = startup;
application_class->activate = activate;
@ -133,11 +319,28 @@ calls_application_class_init (CallsApplicationClass *klass)
g_type_ensure (HDY_TYPE_DIALER);
}
static void
calls_application_init (CallsApplication *self)
{
const GOptionEntry options[] = {
{
"provider", 'p', G_OPTION_FLAG_NONE,
G_OPTION_ARG_STRING, NULL,
_("The name of the plugin to use for the call Provider"),
_("PLUGIN")
},
{
NULL
}
};
g_application_add_main_option_entries (G_APPLICATION (self), options);
self->provider_name = g_string_new (DEFAULT_PROVIDER_PLUGIN);
}
CallsApplication *
calls_application_new (void)
{

View File

@ -23,12 +23,13 @@
gnome = import('gnome')
src_include = include_directories('.')
calls_deps = [ dependency('gobject-2.0'),
dependency('gtk+-3.0'),
dependency('libhandy-0.0'),
dependency('ModemManager'),
dependency('mm-glib'),
dependency('gsound'),
dependency('libpeas-1.0'),
]
calls_sources = files(['calls-message-source.c', 'calls-message-source.h',
@ -37,12 +38,6 @@ calls_sources = files(['calls-message-source.c', 'calls-message-source.h',
'calls-provider.c', 'calls-provider.h',
'calls-enumerate-params.c', 'calls-enumerate-params.h',
'calls-enumerate.c', 'calls-enumerate.h',
'calls-ofono-call.c', 'calls-ofono-call.h',
'calls-ofono-origin.c', 'calls-ofono-origin.h',
'calls-ofono-provider.c', 'calls-ofono-provider.h',
'calls-mm-call.c', 'calls-mm-call.h',
'calls-mm-origin.c', 'calls-mm-origin.h',
'calls-mm-provider.c', 'calls-mm-provider.h',
'calls-party.c', 'calls-party.h',
'calls-call-data.c', 'calls-call-data.h',
'calls-call-holder.c', 'calls-call-holder.h',
@ -60,23 +55,12 @@ calls_sources = files(['calls-message-source.c', 'calls-message-source.h',
'util.c', 'util.h',
])
calls_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',
])
prefix = get_option('prefix')
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', join_paths(prefix, get_option('localedir')))
config_data.set_quoted('PACKAGE_URL', calls_homepage)
config_data.set_quoted('PACKAGE_VERSION', calls_version)
config_data.set_quoted('VCS_TAG', '@VCS_TAG@')
calls_config_data = config_data
calls_config_data.set_quoted('VCS_TAG', '@VCS_TAG@')
config_h_in = configure_file(
output: 'config.h.in',
configuration: config_data
configuration: calls_config_data
)
config_h = vcs_tag(
@ -99,6 +83,6 @@ calls_resources = gnome.compile_resources(
executable('calls',
calls_sources, calls_enum_sources, calls_resources, 'main.c',
dependencies : calls_deps,
link_with : gdbofono_lib,
export_dynamic : true,
include_directories : include_directories('..'),
install : true)

View File

@ -11,6 +11,7 @@ test_env = [
test_cflags = [
'-fPIE',
'-DFOR_TESTING'
]
test_link_args = [
@ -38,13 +39,16 @@ foreach test : tests
'common.h' ]
t = executable(name, test_sources,
calls_sources, calls_dummy_sources, calls_enum_sources, calls_resources,
calls_sources, dummy_sources, calls_enum_sources, calls_resources,
c_args : test_cflags,
link_args: test_link_args,
link_with : gdbofono_lib,
dependencies: calls_deps,
include_directories : include_directories('..',
join_paths('..', 'src')),
include_directories : [
top_include,
src_include,
dummy_include
]
)
test(name, t, env: test_env)
endforeach

View File

@ -7,7 +7,7 @@
#include "setup-provider.h"
#include "calls-dummy-origin.h"
#define TEST_ORIGIN_NAME "Test origin"
#define TEST_ORIGIN_NAME "Dummy origin"
#define TEST_CALL_NUMBER "0123456789"

View File

@ -43,14 +43,9 @@ test_dummy_provider_origins (ProviderFixture *fixture,
{
GList *origins;
calls_dummy_provider_add_origin (fixture->dummy_provider,
"Test origin 1");
calls_dummy_provider_add_origin (fixture->dummy_provider,
"Test origin 2");
origins = calls_provider_get_origins
(CALLS_PROVIDER (fixture->dummy_provider));
g_assert_cmpuint (g_list_length (origins), ==, 2);
g_assert_cmpuint (g_list_length (origins), ==, 1);
g_list_free (origins);
}