diff options
132 files changed, 2648 insertions, 7427 deletions
@@ -11,6 +11,7 @@ *.gcda *.gcno *.gcov +\#*\# /data/*.valid /data/gschemas.compiled /doc/reference/*/html @@ -3,7 +3,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) TELEPATHY_MISSION_CONTROL_BUILT_SOURCES := \ - mission-control.pc \ + mission-control-plugins.pc \ src/Android.mk \ server/Android.mk \ mission-control-plugins/Android.mk \ diff --git a/Makefile.am b/Makefile.am index d5af95c3..ce56b120 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,14 +22,10 @@ SUBDIRS = \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = mission-control-plugins.pc -if ENABLE_MCD_PLUGINS -pkgconfig_DATA += mission-control.pc -endif - DISTCHECK_CONFIGURE_FLAGS = \ --enable-gtk-doc \ --disable-gnome-keyring \ - --disable-mcd-plugins + $(NULL) maintainer-upload-release: _maintainer-upload-release-local _maintainer-upload-release-local: _maintainer-upload-release-check @@ -1,27 +1,28 @@ -telepathy-mission-control 5.12.4 (UNRELEASED) +telepathy-mission-control 5.13.2 (UNRELEASED) ============================================= -... - -telepathy-mission-control 5.12.3 (2012-09-20) -============================================= - -The "put it with the other Kryptonite" release. - Fixes: • Recover from incomplete password migrations caused by upgrading to Empathy 3 while running MC 5.12.1 or older, by deleting the old (MC) copy of the password if Empathy has already copied it (fd.o #42088, Simon) • Omit generated file mcp-signals-marshal.h from tarballs (Simon) -• Fix distcheck in out-of-tree builds (Simon) -• Backport a patch from 5.13.1 to make the gnome-keyring regression test - work with modern gnome-keyring (Simon) -telepathy-mission-control 5.12.2 (2012-09-06) +telepathy-mission-control 5.13.1 (2012-09-06) ============================================= -The "Parasaurolophus" release. +The "Triceratops" release. + +Changes: + +• On Unix platforms, umask() is now required. (Simon) +• If a connection manager announces two or more channels in the same + NewChannels signal, behave as if it had announced each channel + separately. Simplify things that previously had to cope with + multiple channels at a time. (fd.o #52305, Simon) +• Improve mc-tool: display Account.Storage settings, add Supersedes, + add "dump" subcommand (fd.o #53202; Guillaume, Xavier) +• More internal reorganisation (fd.o #54151, Simon) Fixes: @@ -37,18 +38,31 @@ Fixes: and o.fd.Telepathy.AccountManager simultaneously, avoid one or both failing to activate due to a race condition (fd.o #53220, Simon) • When built for Android, don't use GSettings (fd.o #53497, Simon) -• Revert the change from 5.12.1 that stopped using deprecated symbols, - which wasn't really necessary for a stable branch; ignore deprecation - warnings instead. (Simon) -telepathy-mission-control 5.12.1 (2012-07-11) +telepathy-mission-control 5.13.0 (2012-07-23) ============================================= +Changes: + +• Remove support for many deprecated interfaces (fd.o #49753, fd.o #24762, + fd.o #24899, fd.o #24914, fd.o #49648; Simon): + · old-style (mcd_*) plugins, including McdPlugin and McdFilter + · an obsolete auto-away mechanism + · the non-standard Compat and Query interfaces + · tracking group members in McdChannel + · Capabilities (the predecessor of ContactCapabilities) + · some remnants of ContactCapabilities draft 1 + Fixes: • Stop using deprecated telepathy-glib symbols. (Jonny) • fdo#51842 - fix access to freed memory. (Xavier) • fix existing channel dispatching after using present/delegate. (Jonny) +• Invalid GValue in libaccounts storage plugin (fd.o#48646, fledermaus) +• fdo#52259 - Do not change RequestedPresence when disabling the account, + otherwise it won't reconnect when enabling it. +• fdo#52231 - Let client decide which storage provider to use when creating an + account. telepathy-mission-control 5.12.0 (2012-04-02) ============================================= diff --git a/configure.ac b/configure.ac index 4a09169a..32779a7e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Set the version number to e.g. 5.x.y immediately before a release. dnl Set the version number to e.g. 5.x.y+ immediately after (this will dnl enable -Werror). -AC_INIT([telepathy-mission-control], [5.12.3+]) +AC_INIT([telepathy-mission-control], [5.13.1+]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR(Makefile.am) @@ -45,9 +45,9 @@ AC_SUBST([MCP_API_VERSION]) # set revision to 0 # else if library source has changed since last release # increment revision -MCP_LT_CURRENT=3 -MCP_LT_REVISION=3 -MCP_LT_AGE=3 +MCP_LT_CURRENT=4 +MCP_LT_REVISION=0 +MCP_LT_AGE=4 AC_SUBST([MCP_LT_CURRENT]) AC_SUBST([MCP_LT_REVISION]) AC_SUBST([MCP_LT_AGE]) @@ -73,7 +73,6 @@ TP_COMPILER_WARNINGS([ERROR_CFLAGS], init-self \ ], [missing-field-initializers \ - deprecated-declarations \ unused-parameter]) AC_SUBST([ERROR_CFLAGS]) @@ -151,54 +150,6 @@ fi AC_SUBST(ACCOUNTS_CACHE_DIR) AC_DEFINE_UNQUOTED(ACCOUNTS_CACHE_DIR,"$ACCOUNTS_CACHE_DIR", [Directory for account/connection mapping for crash recovery]) -server_enabled="yes" -AC_MSG_CHECKING(whether to build the daemon) -AC_ARG_ENABLE(server, - [ --enable-server build server. default=yes], - [ - AC_MSG_RESULT(${enableval}) - server_enabled="${enableval}" - ], - [ - AC_MSG_RESULT(yes) - server_enabled="yes" - ] -) -AM_CONDITIONAL(HAVE_SERVER, [test x$server_enabled = xyes]) - -ENABLE_MC_SERVER_SO6="no" -AC_MSG_CHECKING(whether to pretend libmissioncontrol-server is stable) -AC_ARG_ENABLE(mcserver-so6, - [ --enable-mcserver-so6 pretend libmissioncontrol-server is ABI-stable], - [ - AC_MSG_RESULT(${enableval}) - ENABLE_MC_SERVER_SO6="${enableval}" - ], - [ - AC_MSG_RESULT(no) - ENABLE_MC_SERVER_SO6="no" - ] -) -AM_CONDITIONAL(ENABLE_MC_SERVER_SO6, [test "x$ENABLE_MC_SERVER_SO6" = xyes]) - -AC_MSG_CHECKING(whether to support plugins) -AC_ARG_ENABLE(mcd-plugins, - [ --enable-mcd-plugins support plugins that use internal APIs. default=no], - [ - AC_MSG_RESULT(${enableval}) - mcd_plugins_enabled="${enableval}" - ], - [ - AC_MSG_RESULT(no) - mcd_plugins_enabled="no" - ] -) -AM_CONDITIONAL(ENABLE_MCD_PLUGINS, [test x$mcd_plugins_enabled = xyes]) -if test "x$mcd_plugins_enabled" = xyes -then - AC_DEFINE([ENABLE_MCD_PLUGINS], [1], [Define if MCD plugins should be enabled]) -fi - aegis_enabled="no" AC_MSG_CHECKING([whether to build with Aegis (libcreds) support]) AC_ARG_ENABLE(aegis, @@ -305,18 +256,19 @@ PKG_CHECK_MODULES(DBUS, [dbus-1 >= 0.95, dbus-glib-1 >= 0.82]) AC_SUBST(DBUS_CFLAGS) AC_SUBST(DBUS_LIBS) -PKG_CHECK_MODULES([TELEPATHY], [telepathy-glib >= 0.17.5]) -AC_SUBST(TELEPATHY_LIBS) -AC_SUBST(TELEPATHY_CFLAGS) +PKG_CHECK_MODULES([TELEPATHY], [telepathy-glib >= 0.19.0]) +AC_DEFINE([TP_VERSION_MIN_REQUIRED], [TP_VERSION_0_18], + [Ignore post-0.18 deprecations]) +AC_DEFINE([TP_VERSION_MAX_ALLOWED], [TP_VERSION_0_20], + [Prevent post-0.20 APIs]) PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.30, gobject-2.0, gmodule-no-export-2.0, gio-2.0]) AC_SUBST(GLIB_LIBS) AC_SUBST(GLIB_CFLAGS) -PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.28]) -AC_SUBST(GIO_LIBS) -AC_SUBST(GIO_CFLAGS) +AC_DEFINE([GLIB_VERSION_MIN_REQUIRED], [GLIB_VERSION_2_30], [Ignore post 2.30 deprecations]) +AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_30], [Prevent post 2.30 APIs]) dnl Check for MCE, a Maemo service used to determine when the device is idle. PKG_CHECK_MODULES([MCE], mce >= 1.5, [HAVE_MCE=yes], [HAVE_MCE=no]) @@ -436,7 +388,6 @@ doc/Makefile \ doc/reference/Makefile \ doc/reference/mission-control-plugins/Makefile \ m4/Makefile \ -mission-control.pc \ mission-control-plugins.pc \ mission-control-plugins-uninstalled.pc \ mission-control-plugins/Makefile \ diff --git a/mission-control-plugins/Makefile.am b/mission-control-plugins/Makefile.am index 2c1209aa..1c6abf15 100644 --- a/mission-control-plugins/Makefile.am +++ b/mission-control-plugins/Makefile.am @@ -2,7 +2,6 @@ INCLUDES = \ $(TELEPATHY_CFLAGS) \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ - $(GIO_CFLAGS) \ -I$(top_srcdir) \ -I$(top_builddir) \ -DG_LOG_DOMAIN=\"mc-plugins\" \ @@ -43,7 +42,7 @@ libmission_control_plugins_la_LIBADD = \ $(TELEPATHY_LIBS) \ $(DBUS_LIBS) \ $(GLIB_LIBS) \ - $(GIO_LIBS) + $(NULL) nodist_libmission_control_plugins_la_SOURCES = \ mcp-signals-marshal.c \ diff --git a/mission-control-plugins/account-storage.c b/mission-control-plugins/account-storage.c index d59977af..050914ca 100644 --- a/mission-control-plugins/account-storage.c +++ b/mission-control-plugins/account-storage.c @@ -75,6 +75,8 @@ * an account storage plugin in an account storage object, though. */ +#include "config.h" + #include <mission-control-plugins/mission-control-plugins.h> #include <mission-control-plugins/mcp-signals-marshal.h> #include <mission-control-plugins/implementation.h> @@ -102,6 +104,7 @@ enum TOGGLED, DELETED, ALTERED_ONE, + RECONNECT, NO_SIGNAL }; @@ -130,7 +133,7 @@ class_init (gpointer klass, /** * McpAccountStorage::altered - * @account: the unique name of the created account + * @account: the unique name of the altered account * * emitted if an external entity alters an account * in the backend the emitting plugin handles @@ -147,7 +150,7 @@ class_init (gpointer klass, /** * McpAccountStorage::altered-one - * @account: the unique name of the created account + * @account: the unique name of the altered account * @name: the name of the altered property (its key) * * emitted if an external entity alters an account @@ -166,7 +169,7 @@ class_init (gpointer klass, /** * McpAccountStorage::deleted - * @account: the unique name of the created account + * @account: the unique name of the deleted account * * emitted if an external entity deletes an account * in the backend the emitting plugin handles @@ -181,7 +184,7 @@ class_init (gpointer klass, /** * McpAccountStorage::toggled - * @account: the unique name of the created account + * @account: the unique name of the toggled account * @enabled: #gboolean indicating whether the account is enabled * * emitted if an external entity enables/disables an account @@ -195,6 +198,19 @@ class_init (gpointer klass, _mcp_marshal_VOID__STRING_BOOLEAN, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_BOOLEAN); + /** + * McpAccountStorage::reconnect + * @account: the unique name of the account to reconnect + * + * emitted if an external entity modified important parameters of the + * account and a reconnection is required in order to apply them. + * + * Should not be fired until mcp_account_storage_ready() has been called + **/ + signals[RECONNECT] = g_signal_new ("reconnect", + type, G_SIGNAL_RUN_LAST, 0, NULL, NULL, + g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, + 1, G_TYPE_STRING); } GType @@ -330,6 +346,14 @@ mcp_account_storage_iface_implement_get_restrictions ( iface->get_restrictions = method; } +void +mcp_account_storage_iface_implement_create ( + McpAccountStorageIface *iface, + McpAccountStorageCreate method) +{ + iface->create = method; +} + /** * mcp_account_storage_priority: * @storage: an #McpAccountStorage instance @@ -440,6 +464,52 @@ mcp_account_storage_set (const McpAccountStorage *storage, } /** + * mcp_account_storage_create: + * @storage: an #McpAccountStorage instance + * @manager: the name of the manager + * @protocol: the name of the protocol + * @params: A gchar * / GValue * hash table of account parameters + * @error: a GError to fill + * + * Inform the plugin that a new account is being created. @manager, @protocol + * and @params are given to help determining the account's unique name, but does + * not need to be stored on the account yet, mcp_account_storage_set() and + * mcp_account_storage_commit() will be called later. + * + * It is recommended to use mcp_account_manager_get_unique_name() to create the + * unique name, but it's not mandatory. One could base the unique name on an + * internal storage identifier, prefixed with the provider's name + * (e.g. goa__1234). + * + * #McpAccountStorage::created signal should not be emitted for this account, + * not even when mcp_account_storage_commit() will be called. + * + * Returns: the newly allocated account name, which should be freed + * once the caller is done with it, or %NULL if that couldn't be done. + */ +gchar * +mcp_account_storage_create (const McpAccountStorage *storage, + const McpAccountManager *am, + const gchar *manager, + const gchar *protocol, + GHashTable *params, + GError **error) +{ + McpAccountStorageIface *iface = MCP_ACCOUNT_STORAGE_GET_IFACE (storage); + + g_return_val_if_fail (iface != NULL, NULL); + + if (iface->create == NULL) + { + g_set_error (error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, + "This storage does not implement create function"); + return NULL; + } + + return iface->create (storage, am, manager, protocol, params, error); +} + +/** * mcp_account_storage_delete: * @storage: an #McpAccountStorage instance * @am: an #McpAccountManager instance @@ -736,3 +806,90 @@ mcp_account_storage_provider (const McpAccountStorage *storage) return iface->provider != NULL ? iface->provider : ""; } + +/** + * mcp_account_storage_emit_create: + * @storage: an #McpAccountStorage instance + * @account: the unique name of the created account + * + * Emits ::created signal + */ +void +mcp_account_storage_emit_created (McpAccountStorage *storage, + const gchar *account) +{ + g_signal_emit (storage, signals[CREATED], 0, account); +} + +/** + * mcp_account_storage_emit_altered: + * @storage: an #McpAccountStorage instance + * @account: the unique name of the altered account + * + * Emits ::altered signal + */ +void +mcp_account_storage_emit_altered (McpAccountStorage *storage, + const gchar *account) +{ + g_signal_emit (storage, signals[ALTERED], 0, account); +} + +/** + * mcp_account_storage_emit_altered_one: + * @storage: an #McpAccountStorage instance + * @account: the unique name of the altered account + * @key: the key of the altered property + * + * Emits ::created-one signal + */ +void +mcp_account_storage_emit_altered_one (McpAccountStorage *storage, + const gchar *account, + const gchar *key) +{ + g_signal_emit (storage, signals[ALTERED_ONE], 0, account, key); +} + +/** + * mcp_account_storage_emit_deleted: + * @storage: an #McpAccountStorage instance + * @account: the unique name of the deleted account + * + * Emits ::deleted signal + */ +void +mcp_account_storage_emit_deleted (McpAccountStorage *storage, + const gchar *account) +{ + g_signal_emit (storage, signals[DELETED], 0, account); +} + +/** + * mcp_account_storage_emit_toggled: + * @storage: an #McpAccountStorage instance + * @account: the unique name of the account + * + * Emits ::toggled signal + */ +void +mcp_account_storage_emit_toggled (McpAccountStorage *storage, + const gchar *account, + gboolean enabled) +{ + g_signal_emit (storage, signals[TOGGLED], 0, account, enabled); +} + +/** + * mcp_account_storage_emit_reconnect: + * @storage: an #McpAccountStorage instance + * @account: the unique name of the account to reconnect + * + * Emits ::reconnect signal + */ +void +mcp_account_storage_emit_reconnect (McpAccountStorage *storage, + const gchar *account) +{ + g_signal_emit (storage, signals[RECONNECT], 0, account); +} diff --git a/mission-control-plugins/account-storage.h b/mission-control-plugins/account-storage.h index 056674b1..ee1c65a9 100644 --- a/mission-control-plugins/account-storage.h +++ b/mission-control-plugins/account-storage.h @@ -63,6 +63,13 @@ typedef gboolean (*McpAccountStorageSetFunc) ( const gchar *account, const gchar *key, const gchar *val); +typedef gchar * (*McpAccountStorageCreate) ( + const McpAccountStorage *storage, + const McpAccountManager *am, + const gchar *manager, + const gchar *protocol, + GHashTable *params, + GError **error); typedef gboolean (*McpAccountStorageDeleteFunc) ( const McpAccountStorage *storage, const McpAccountManager *am, @@ -112,6 +119,7 @@ struct _McpAccountStorageIface McpAccountStorageGetIdentifierFunc get_identifier; McpAccountStorageGetAdditionalInfoFunc get_additional_info; McpAccountStorageGetRestrictionsFunc get_restrictions; + McpAccountStorageCreate create; }; /* functions with which to fill in the vtable */ @@ -131,6 +139,9 @@ void mcp_account_storage_iface_implement_get (McpAccountStorageIface *iface, McpAccountStorageGetFunc method); void mcp_account_storage_iface_implement_set (McpAccountStorageIface *iface, McpAccountStorageSetFunc method); +void mcp_account_storage_iface_implement_create ( + McpAccountStorageIface *iface, + McpAccountStorageCreate method); void mcp_account_storage_iface_implement_delete (McpAccountStorageIface *iface, McpAccountStorageDeleteFunc method); void mcp_account_storage_iface_implement_list (McpAccountStorageIface *iface, @@ -166,6 +177,13 @@ gboolean mcp_account_storage_set (const McpAccountStorage *storage, const gchar *key, const gchar *value); +gchar * mcp_account_storage_create (const McpAccountStorage *storage, + const McpAccountManager *am, + const gchar *manager, + const gchar *protocol, + GHashTable *params, + GError **error); + gboolean mcp_account_storage_delete (const McpAccountStorage *storage, const McpAccountManager *am, const gchar *account, @@ -202,6 +220,21 @@ const gchar *mcp_account_storage_name (const McpAccountStorage *storage); const gchar *mcp_account_storage_description (const McpAccountStorage *storage); const gchar *mcp_account_storage_provider (const McpAccountStorage *storage); +void mcp_account_storage_emit_created (McpAccountStorage *storage, + const gchar *account); +void mcp_account_storage_emit_altered (McpAccountStorage *storage, + const gchar *account); +void mcp_account_storage_emit_altered_one (McpAccountStorage *storage, + const gchar *account, + const gchar *key); +void mcp_account_storage_emit_deleted (McpAccountStorage *storage, + const gchar *account); +void mcp_account_storage_emit_toggled (McpAccountStorage *storage, + const gchar *account, + gboolean enabled); +void mcp_account_storage_emit_reconnect (McpAccountStorage *storage, + const gchar *account); + G_END_DECLS #endif diff --git a/mission-control-plugins/account.c b/mission-control-plugins/account.c index 849c3204..5db6d608 100644 --- a/mission-control-plugins/account.c +++ b/mission-control-plugins/account.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" + #include <mission-control-plugins/mission-control-plugins.h> #include <mission-control-plugins/implementation.h> #include <mission-control-plugins/debug-internal.h> diff --git a/mission-control-plugins/dbus-acl.h b/mission-control-plugins/dbus-acl.h index dda620af..deba7b72 100644 --- a/mission-control-plugins/dbus-acl.h +++ b/mission-control-plugins/dbus-acl.h @@ -26,7 +26,7 @@ #endif #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/dbus.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/mission-control-plugins/dispatch-operation-policy.c b/mission-control-plugins/dispatch-operation-policy.c index 622364f5..35817044 100644 --- a/mission-control-plugins/dispatch-operation-policy.c +++ b/mission-control-plugins/dispatch-operation-policy.c @@ -60,6 +60,8 @@ * may be useful to combine this interface with #McpRequestPolicy. */ +#include "config.h" + #include <mission-control-plugins/mission-control-plugins.h> GType diff --git a/mission-control-plugins/dispatch-operation-policy.h b/mission-control-plugins/dispatch-operation-policy.h index a5587217..0ec87248 100644 --- a/mission-control-plugins/dispatch-operation-policy.h +++ b/mission-control-plugins/dispatch-operation-policy.h @@ -26,8 +26,7 @@ #endif #include <mission-control-plugins/dispatch-operation.h> - -#include <telepathy-glib/client.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/mission-control-plugins/dispatch-operation.c b/mission-control-plugins/dispatch-operation.c index e7534ccf..cbe1f21b 100644 --- a/mission-control-plugins/dispatch-operation.c +++ b/mission-control-plugins/dispatch-operation.c @@ -37,12 +37,13 @@ * Only Mission Control should implement this interface. */ +#include "config.h" + #include <mission-control-plugins/mission-control-plugins.h> #include <mission-control-plugins/implementation.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> GType mcp_dispatch_operation_get_type (void) diff --git a/mission-control-plugins/dispatch-operation.h b/mission-control-plugins/dispatch-operation.h index 649c57cd..7cb4dd64 100644 --- a/mission-control-plugins/dispatch-operation.h +++ b/mission-control-plugins/dispatch-operation.h @@ -25,7 +25,7 @@ #error Use <mission-control-plugins/mission-control-plugins.h> instead #endif -#include <telepathy-glib/channel.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/mission-control-plugins/loader.c b/mission-control-plugins/loader.c index 7fa600a6..640d1d87 100644 --- a/mission-control-plugins/loader.c +++ b/mission-control-plugins/loader.c @@ -41,6 +41,8 @@ * the plugins. */ +#include "config.h" + #include <gmodule.h> #include <mission-control-plugins/mission-control-plugins.h> #include <mission-control-plugins/debug.h> diff --git a/mission-control-plugins/request-policy.c b/mission-control-plugins/request-policy.c index aa4338e8..fe13907f 100644 --- a/mission-control-plugins/request-policy.c +++ b/mission-control-plugins/request-policy.c @@ -57,6 +57,8 @@ * may be useful to combine this interface with #McpDispatchOperationPolicy. */ +#include "config.h" + #include <mission-control-plugins/mission-control-plugins.h> /** diff --git a/mission-control-plugins/request.c b/mission-control-plugins/request.c index c985238c..36dac1dc 100644 --- a/mission-control-plugins/request.c +++ b/mission-control-plugins/request.c @@ -26,11 +26,13 @@ * @include: mission-control-plugins/mission-control-plugins.h */ +#include "config.h" + #include <mission-control-plugins/mission-control-plugins.h> #include <mission-control-plugins/implementation.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> GType mcp_request_get_type (void) diff --git a/mission-control.pc.in b/mission-control.pc.in deleted file mode 100644 index cbd5c324..00000000 --- a/mission-control.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -pluginlibdir=@pluginlibdir@ - -Name: mission-control -Description: Mission control filters interface library -Requires: dbus-1 >= 0.50 -Requires.private: telepathy-glib, dbus-1, dbus-glib-1, gmodule-2.0, glib-2.0, gobject-2.0 -Version: @VERSION@ -Libs: -L${libdir} -lmissioncontrol-server -Cflags: -I${includedir}/mission-control diff --git a/plugins/mcp-dbus-aegis-acl.c b/plugins/mcp-dbus-aegis-acl.c index b67a8681..1eda98e6 100644 --- a/plugins/mcp-dbus-aegis-acl.c +++ b/plugins/mcp-dbus-aegis-acl.c @@ -29,9 +29,9 @@ #define DEBUG(_f, ...) MCP_DEBUG (MCP_DEBUG_DBUS_ACL, _f, ##__VA_ARGS__) #include <dbus/dbus-glib.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/util.h> -#include <telepathy-glib/defs.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <mission-control-plugins/mission-control-plugins.h> @@ -413,7 +413,7 @@ handler_is_suitable_async (McpDispatchOperationPolicy *self, if (!ok) { - g_simple_async_result_set_error (simple, TP_ERRORS, + g_simple_async_result_set_error (simple, TP_ERROR, TP_ERROR_PERMISSION_DENIED, "insufficient Aegis credentials"); } diff --git a/server/Makefile.am b/server/Makefile.am index eb74a3cd..5be1cdc1 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -10,8 +10,6 @@ AM_CPPFLAGS = \ AM_CFLAGS = $(ERROR_CFLAGS) -if HAVE_SERVER - EXTRA_DIST = org.freedesktop.Telepathy.MissionControl5.service.in \ org.freedesktop.Telepathy.AccountManager.service.in \ mission-control-5.8.in @@ -40,7 +38,7 @@ mission_control_5_LDADD = \ $(GLIB_LIBS) \ $(TELEPATHY_LIBS) \ $(DBUS_LIBS) \ - $(top_builddir)/src/libmissioncontrol-server.la \ + $(top_builddir)/src/libmcd-convenience.la \ $(top_builddir)/mission-control-plugins/libmission-control-plugins.la Android.mk: Makefile.am @@ -52,8 +50,6 @@ Android.mk: Makefile.am -:CPPFLAGS $(CPPFLAGS) $(AM_CPPFLAGS) $(INCLUDES) \ -DBUILD_AS_ANDROID_SERVICE \ -:LDFLAGS $(mission_control_5_LDADD) \ - -:LIBFILTER_STATIC missioncontrol-server mission-control-plugins \ + -:LIBFILTER_STATIC mcd-convenience mission-control-plugins \ mcclient \ > $@ - -endif diff --git a/server/mc-server.c b/server/mc-server.c index 033ef873..ff692f04 100644 --- a/server/mc-server.c +++ b/server/mc-server.c @@ -37,7 +37,6 @@ #endif #include <telepathy-glib/telepathy-glib.h> -#include <telepathy-glib/debug-sender.h> #include "mcd-service.h" @@ -83,7 +82,10 @@ signal_handler (int sig) "Unable to write to quit pipe - buffer full?\n" "Will exit instead.\n"; - write (STDERR_FILENO, message, strlen (message)); + if (write (STDERR_FILENO, message, strlen (message)) == -1) + { + /* Ignore, we are returning anyway */ + } _exit (1); } break; diff --git a/src/Makefile.am b/src/Makefile.am index 9f9f06a3..041b7701 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,20 +24,14 @@ mc_headers = \ mcd-mission.h \ mcd-operation.h \ mcd-master.h \ - mcd-controller.h \ mcd-manager.h \ mcd-connection.h \ mcd-connection-plugin.h \ mcd-connection-service-points.h \ - mcd-plugin.h \ mcd-channel.h \ - mcd-proxy.h \ mcd-dispatcher.h \ - mcd-dispatcher-context.h \ mcd-service.h \ mcd-transport.h \ - mcd-provisioning.h \ - mcd-provisioning-factory.h \ mcd-storage.h if ENABLE_LIBACCOUNTS_SSO @@ -58,13 +52,10 @@ mc_gen_headers = \ _gen/enums.h \ _gen/gtypes.h \ _gen/interfaces.h \ - _gen/svc-Account_Interface_Addressing.h \ - _gen/svc-Account_Interface_Compat.h \ _gen/svc-Account_Interface_Conditions.h \ _gen/svc-Account_Interface_External_Password_Storage.h \ _gen/svc-Account_Interface_Hidden.h \ _gen/svc-Account_Manager_Interface_Hidden.h \ - _gen/svc-Account_Manager_Interface_Query.h \ _gen/svc-dispatcher.h nodist_libmcd_convenience_la_SOURCES = \ @@ -75,18 +66,13 @@ nodist_libmcd_convenience_la_SOURCES = \ _gen/signals-marshal.c \ _gen/signals-marshal.h \ _gen/signals-marshal.list \ - _gen/svc-Account_Interface_Addressing.c \ - _gen/svc-Account_Interface_Compat.c \ _gen/svc-Account_Interface_Conditions.c \ _gen/svc-Account_Interface_External_Password_Storage.c \ _gen/svc-Account_Interface_Hidden.c \ - _gen/svc-Account_Manager_Interface_Query.c \ _gen/svc-Account_Manager_Interface_Hidden.c \ _gen/svc-dispatcher.c \ mcd-enum-types.c \ mcd-enum-types.h \ - mcd-signals-marshal.c \ - mcd-signals-marshal.h \ $(mc_gen_headers) BUILT_SOURCES = \ @@ -121,44 +107,9 @@ endif noinst_LTLIBRARIES = libmcd-convenience.la -if ENABLE_MCD_PLUGINS -# When this older plugin API is enabled, libmissioncontrol-server.la is a -# shared library that wraps the convenience library -lib_LTLIBRARIES = libmissioncontrol-server.la -libmissioncontrol_server_la_SOURCES = -libmissioncontrol_server_la_LIBADD = libmcd-convenience.la - -libmissioncontrol_server_la_LDFLAGS = \ - -export-symbols-regex '^((mc_)|(mcd_)|(mission_control_))' - -if ENABLE_MC_SERVER_SO6 -# the redundant quoting here is to prevent the libtool command line from -# looking like an error message in an oddly named file -libmissioncontrol_server_la_LDFLAGS += -version-info "10":"0":"4" -else -libmissioncontrol_server_la_LDFLAGS += -release $(VERSION) -endif - -mission_control_includedir = $(includedir)/mission-control -mission_control_include_HEADERS = $(mc_headers) - -genincludedir = $(mission_control_includedir)/_gen -nodist_geninclude_HEADERS = $(mc_gen_headers) - -INCLUDES += \ - -DMCD_DEFAULT_FILTER_PLUGIN_DIR=\"@pluginlibdir@\" -else # ! ENABLE_MCD_PLUGINS -# When this older plugin API is not enabled, libmissioncontrol-server.la is -# just a copy of the convenience library -noinst_LTLIBRARIES += libmissioncontrol-server.la -libmissioncontrol_server_la_SOURCES = -libmissioncontrol_server_la_LIBADD = libmcd-convenience.la -endif # ! ENABLE_MCD_PLUGINS - libmcd_convenience_la_SOURCES = \ mcd-account.c \ mcd-account-addressing.h \ - mcd-account-compat.c \ mcd-account-conditions.c \ mcd-account-config.h \ mcd-account-connection.c \ @@ -166,7 +117,6 @@ libmcd_convenience_la_SOURCES = \ mcd-account-addressing.c \ mcd-account-manager.c \ mcd-account-manager-priv.h \ - mcd-account-manager-query.c \ mcd-account-manager-default.c \ mcd-account-priv.h \ mcd-client.c \ @@ -192,7 +142,6 @@ libmcd_convenience_la_SOURCES = \ mcd-mission.c \ mcd-mission-priv.h \ mcd-operation.c \ - mcd-controller.c \ mcd-master.c \ mcd-master-priv.h \ mcd-manager.c \ @@ -207,21 +156,15 @@ libmcd_convenience_la_SOURCES = \ mcd-service.c \ mcd-slacker.c \ mcd-slacker.h \ - mcd-proxy.c \ mcd-transport.c \ - mcd-provisioning.c \ - mcd-provisioning-factory.c \ mcd-storage.c \ mcd-storage.h \ - mcd-storage-priv.h \ plugin-dispatch-operation.c \ plugin-dispatch-operation.h \ plugin-loader.c \ plugin-loader.h \ plugin-request.c \ plugin-request.h \ - plugin-account.c \ - plugin-account.h \ request.c \ request.h \ sp_timestamp.h \ @@ -240,19 +183,11 @@ endif endif -%-signals-marshal.h: %-signals-marshal.list Makefile - $(AM_V_GEN)glib-genmarshal --header --prefix=_$(subst -,_,$*)_marshal $< > $*-signals-marshal.h - -%-signals-marshal.c: %-signals-marshal.list Makefile - $(AM_V_GEN){ echo '#include "$*-signals-marshal.h"' && \ - glib-genmarshal --body --prefix=_$(subst -,_,$*)_marshal $<; } \ - > $*-signals-marshal.c - mcd-enum-types.h: stamp-mcd-enum-types.h $(AM_V_GEN)true stamp-mcd-enum-types.h: Makefile $(mc_headers) mcd-enum-types.c $(AM_V_GEN)( cd $(srcdir) && glib-mkenums \ - --fhead "#ifndef __MCD_ENUM_TYPES_H__\n#define __MCD_ENUM_TYPES_H__\n\n#include \"mcd-mission.h\"\n#include \"mcd-channel.h\"\n#include \"mcd-provisioning.h\"\n#include \"mcd-transport.h\"\n\nG_BEGIN_DECLS\n" \ + --fhead "#ifndef __MCD_ENUM_TYPES_H__\n#define __MCD_ENUM_TYPES_H__\n\n#include \"mcd-mission.h\"\n#include \"mcd-channel.h\"\n#include \"mcd-transport.h\"\n\nG_BEGIN_DECLS\n" \ --fprod "/* enumerations from \"@filename@\" */\n" \ --vhead "GType @enum_name@_get_type (void) G_GNUC_CONST;\n#define MCD_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \ --ftail "G_END_DECLS\n\n#endif /* __MCD_ENUM_TYPES_H__ */" \ @@ -276,12 +211,11 @@ mcd-enum-types.c: Makefile $(mc_headers) EXTRA_DIST = \ mcd.xml \ dispatcher.xml \ - mcd-signals-marshal.list \ stamp-mcd-enum-types.h Android.mk: Makefile.am $(nodist_libmcd_convenience_la_SOURCES) androgenizer -:PROJECT telepathy-mission-control \ - -:STATIC libmissioncontrol-server \ + -:STATIC libmcd-convenience \ -:TAGS eng debug \ -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \ -:SOURCES $(libmcd_convenience_la_SOURCES) $(nodist_libmcd_convenience_la_SOURCES) \ @@ -379,7 +313,7 @@ _gen/svc-%.c _gen/svc-%.h: _gen/%.xml \ $(AM_V_GEN)$(PYTHON) $(tools_dir)/glib-ginterface-gen.py \ --filename=_gen/svc-$* \ --signal-marshal-prefix=_mcd_ext \ - --include='<telepathy-glib/dbus.h>' \ + --include='<telepathy-glib/telepathy-glib.h>' \ --include='"_gen/signals-marshal.h"' \ --not-implemented-func='tp_dbus_g_method_return_not_implemented' \ --allow-unstable \ diff --git a/src/channel-utils.c b/src/channel-utils.c index 21cf80f6..492b54be 100644 --- a/src/channel-utils.c +++ b/src/channel-utils.c @@ -24,11 +24,12 @@ * */ +#include "config.h" + #include "channel-utils.h" -#include <telepathy-glib/channel.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "mcd-channel.h" #include "mcd-debug.h" @@ -81,7 +82,7 @@ static void _channel_details_array_append (GPtrArray *channel_array, TpChannel *channel) { GType type = TP_STRUCT_TYPE_CHANNEL_DETAILS; - GValue channel_val = { 0, }; + GValue channel_val = G_VALUE_INIT; GHashTable *properties; const gchar *object_path; diff --git a/src/channel-utils.h b/src/channel-utils.h index 01428cc9..0dcb5062 100644 --- a/src/channel-utils.h +++ b/src/channel-utils.h @@ -28,7 +28,8 @@ #define CHANNEL_UTILS_H #include <glib.h> -#include <telepathy-glib/channel.h> + +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/src/client-registry.c b/src/client-registry.c index dc58f640..acc65e78 100644 --- a/src/client-registry.c +++ b/src/client-registry.c @@ -19,9 +19,10 @@ * */ +#include "config.h" + #include "client-registry.h" -#include <telepathy-glib/handle-repo-dynamic.h> #include <telepathy-glib/telepathy-glib.h> #include "mcd-debug.h" @@ -55,10 +56,6 @@ struct _McdClientRegistryPrivate TpDBusDaemon *dbus_daemon; - /* Not really handles as such, but TpHandleRepoIface gives us a convenient - * reference-counted string pool */ - TpHandleRepoIface *string_pool; - /* We don't want to start dispatching until startup has finished. This * is defined as: * - activatable clients have been enumerated (ListActivatableNames) @@ -155,8 +152,7 @@ _mcd_client_registry_found_name (McdClientRegistry *self, DEBUG ("Registering client %s", well_known_name); client = _mcd_client_proxy_new (self->priv->dbus_daemon, - self->priv->string_pool, well_known_name, unique_name_if_known, - activatable); + well_known_name, unique_name_if_known, activatable); g_hash_table_insert (self->priv->clients, g_strdup (well_known_name), client); @@ -336,33 +332,13 @@ mcd_client_registry_name_owner_filter (DBusConnection *conn, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static gboolean -add_match (DBusConnection *conn, - const gchar const *rule, - const gchar *msg) -{ - DBusError error = { 0 }; - - dbus_error_init (&error); - dbus_bus_add_match (conn, rule, &error); - - if (dbus_error_is_set (&error)) - { - g_warning ("Could not add %s match rule: %s", msg, error.message); - dbus_error_free (&error); - return FALSE; - } - - return TRUE; -} - static void watch_clients (McdClientRegistry *self) { TpDBusDaemon *dbus_daemon = self->priv->dbus_daemon; DBusGConnection *gconn = tp_proxy_get_dbus_connection (dbus_daemon); DBusConnection *dconn = dbus_g_connection_get_connection (gconn); - gboolean arg0_filtered = FALSE; + DBusError error = { 0 }; #define MATCH_ITEM(t,x) #t "='" x "'" @@ -376,13 +352,28 @@ watch_clients (McdClientRegistry *self) NAME_OWNER_RULE "," \ MATCH_ITEM (arg0namespace, "org.freedesktop.Telepathy.Client") - arg0_filtered = dbus_connection_add_filter (dconn, - mcd_client_registry_name_owner_filter, - self, - NULL); + if (!dbus_connection_add_filter (dconn, mcd_client_registry_name_owner_filter, + self, NULL)) + g_critical ("Could not add filter for NameOwnerChanged (out of memory?)"); + + dbus_error_init (&error); + + dbus_bus_add_match (dconn, CLIENT_MATCH_RULE, &error); + if (dbus_error_is_set (&error)) + { + DEBUG ("Could not add client names match rule (D-Bus 1.6 required): %s", + error.message); + + dbus_error_free (&error); - if (arg0_filtered && !add_match (dconn, CLIENT_MATCH_RULE, "client names")) - add_match (dconn, NAME_OWNER_RULE, "all dbus names"); + dbus_bus_add_match (dconn, NAME_OWNER_RULE, &error); + if (dbus_error_is_set (&error)) + { + g_critical ("Could not add all dbus names match rule: %s", + error.message); + dbus_error_free (&error); + } + } } static void @@ -403,10 +394,6 @@ mcd_client_registry_constructed (GObject *object) tp_cli_dbus_daemon_call_list_names (self->priv->dbus_daemon, -1, mcd_client_registry_list_names_cb, NULL, NULL, object); - - /* Dummy handle type, we're just using this as a string pool */ - self->priv->string_pool = tp_dynamic_handle_repo_new (TP_HANDLE_TYPE_CONTACT, - NULL, NULL); } static void @@ -469,7 +456,6 @@ mcd_client_registry_dispose (GObject *object) } tp_clear_object (&self->priv->dbus_daemon); - tp_clear_object (&self->priv->string_pool); if (self->priv->clients != NULL) { @@ -618,11 +604,10 @@ GList * _mcd_client_registry_list_possible_handlers (McdClientRegistry *self, const gchar *preferred_handler, GHashTable *request_props, - const GList *channels, + TpChannel *channel, const gchar *must_have_unique_name) { GList *handlers = NULL; - const GList *iter; GList *handlers_iter; GHashTableIter client_iter; gpointer client_p; @@ -632,7 +617,8 @@ _mcd_client_registry_list_possible_handlers (McdClientRegistry *self, while (g_hash_table_iter_next (&client_iter, NULL, &client_p)) { McdClientProxy *client = MCD_CLIENT_PROXY (client_p); - gsize total_quality = 0; + GHashTable *properties; + gsize quality; if (must_have_unique_name != NULL && tp_strdiff (must_have_unique_name, @@ -650,48 +636,33 @@ _mcd_client_registry_list_possible_handlers (McdClientRegistry *self, continue; } - if (channels == NULL) + if (channel == NULL) { - /* We don't know any channels' properties (the next loop will not + /* We don't know the channel's properties (the next part will not * execute), so we must work out the quality of match from the * channel request. We can assume that the request will return one * channel, with the requested properties, plus Requested == TRUE. */ g_assert (request_props != NULL); - total_quality = _mcd_client_match_filters (request_props, + quality = _mcd_client_match_filters (request_props, _mcd_client_proxy_get_handler_filters (client), TRUE); } - - for (iter = channels; iter != NULL; iter = iter->next) + else { - TpChannel *channel = iter->data; - GHashTable *properties; - guint quality; - g_assert (TP_IS_CHANNEL (channel)); properties = tp_channel_borrow_immutable_properties (channel); quality = _mcd_client_match_filters (properties, _mcd_client_proxy_get_handler_filters (client), FALSE); - - if (quality == 0) - { - total_quality = 0; - break; - } - else - { - total_quality += quality; - } } - if (total_quality > 0) + if (quality > 0) { PossibleHandler *ph = g_slice_new0 (PossibleHandler); ph->client = client; ph->bypass = _mcd_client_proxy_get_bypass_approval (client); - ph->quality = total_quality; + ph->quality = quality; handlers = g_list_prepend (handlers, ph); } diff --git a/src/client-registry.h b/src/client-registry.h index 5b9ade3c..ec2e167c 100644 --- a/src/client-registry.h +++ b/src/client-registry.h @@ -23,8 +23,8 @@ #define MCD_CLIENT_REGISTRY_H #include <glib-object.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/handle-repo.h> + +#include <telepathy-glib/telepathy-glib.h> #include "mcd-client-priv.h" @@ -82,7 +82,7 @@ G_GNUC_INTERNAL void _mcd_client_registry_init_hash_iter ( G_GNUC_INTERNAL GList *_mcd_client_registry_list_possible_handlers ( McdClientRegistry *self, const gchar *preferred_handler, - GHashTable *request_props, const GList *channels, + GHashTable *request_props, TpChannel *channel, const gchar *must_have_unique_name); G_END_DECLS diff --git a/src/connectivity-monitor.c b/src/connectivity-monitor.c index 2c22a571..5e6e425b 100644 --- a/src/connectivity-monitor.c +++ b/src/connectivity-monitor.c @@ -42,7 +42,7 @@ #include <upower.h> #endif -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> #include "mcd-debug.h" diff --git a/src/gtypes.c b/src/gtypes.c index ca4cf05f..90c4fb18 100644 --- a/src/gtypes.c +++ b/src/gtypes.c @@ -1,3 +1,5 @@ +#include "config.h" + #include <dbus/dbus-glib.h> #include "_gen/gtypes.h" diff --git a/src/kludge-transport.c b/src/kludge-transport.c index 636f9cfa..c8e2ba1d 100644 --- a/src/kludge-transport.c +++ b/src/kludge-transport.c @@ -21,7 +21,7 @@ #include "kludge-transport.h" -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> #include "mcd-debug.h" @@ -128,15 +128,6 @@ mcd_kludge_transport_class_init (McdKludgeTransportClass *klass) g_type_class_add_private (klass, sizeof (McdKludgeTransportPrivate)); } -static const gchar * -mcd_kludge_transport_get_name ( - McdTransportPlugin *plugin) -{ - g_return_val_if_fail (MCD_IS_KLUDGE_TRANSPORT (plugin), NULL); - - return "McdKludgeTransport"; -} - static const GList * mcd_kludge_transport_get_transports ( McdTransportPlugin *plugin) @@ -188,7 +179,6 @@ transport_iface_init ( { McdTransportPluginIface *klass = g_iface; - klass->get_name = mcd_kludge_transport_get_name; klass->get_transports = mcd_kludge_transport_get_transports; klass->get_transport_name = mcd_kludge_transport_get_transport_name; klass->get_transport_status = mcd_kludge_transport_get_transport_status; @@ -267,13 +257,12 @@ mcd_kludge_transport_new (void) } void -mcd_kludge_transport_install ( - McdPlugin *plugin) +mcd_kludge_transport_install (McdMaster *master) { McdTransportPlugin *self = mcd_kludge_transport_new (); - mcd_plugin_register_transport (plugin, self); - mcd_plugin_register_account_connection (plugin, + mcd_master_register_transport (master, self); + mcd_master_register_account_connection (master, mcd_kludge_transport_account_connection_cb, MCD_ACCOUNT_CONNECTION_PRIORITY_TRANSPORT, self); } diff --git a/src/kludge-transport.h b/src/kludge-transport.h index b52d3a7a..7f270435 100644 --- a/src/kludge-transport.h +++ b/src/kludge-transport.h @@ -21,7 +21,7 @@ #define MCD_KLUDGE_TRANSPORT_H #include <glib-object.h> -#include "mcd-plugin.h" +#include "mcd-master.h" #include "mcd-transport.h" typedef struct _McdKludgeTransport McdKludgeTransport; @@ -40,8 +40,7 @@ struct _McdKludgeTransport { GType mcd_kludge_transport_get_type (void); -void mcd_kludge_transport_install ( - McdPlugin *plugin); +void mcd_kludge_transport_install (McdMaster *master); /* TYPE MACROS */ #define MCD_TYPE_KLUDGE_TRANSPORT \ diff --git a/src/mcd-account-addressing.c b/src/mcd-account-addressing.c index 013cf574..fe9ce6a7 100644 --- a/src/mcd-account-addressing.c +++ b/src/mcd-account-addressing.c @@ -21,23 +21,21 @@ * 02110-1301 USA * */ +#include "config.h" #include "mcd-account-addressing.h" -#include <config.h> - -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/util.h> -#include <telepathy-glib/svc-generic.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "mcd-account.h" #include "mcd-account-priv.h" #include "_gen/interfaces.h" -#define SCHEMES MC_IFACE_ACCOUNT_INTERFACE_ADDRESSING ".URISchemes" +#define SCHEMES TP_IFACE_ACCOUNT_INTERFACE_ADDRESSING ".URISchemes" static void -addressing_set_uri_scheme_association (McSvcAccountInterfaceAddressing *iface, +addressing_set_uri_scheme_association (TpSvcAccountInterfaceAddressing *iface, const gchar *uri_scheme, gboolean association, DBusGMethodInvocation *context) @@ -80,7 +78,7 @@ addressing_set_uri_scheme_association (McSvcAccountInterfaceAddressing *iface, } tp_g_value_slice_free (stored_value); - mc_svc_account_interface_addressing_return_from_set_uri_scheme_association ( + tp_svc_account_interface_addressing_return_from_set_uri_scheme_association ( context); } @@ -107,10 +105,10 @@ const McdDBusProp account_addressing_properties[] = { }; void -account_addressing_iface_init (McSvcAccountInterfaceAddressingClass *iface, +account_addressing_iface_init (TpSvcAccountInterfaceAddressingClass *iface, gpointer data) { - #define IMPLEMENT(x) mc_svc_account_interface_addressing_implement_##x (\ + #define IMPLEMENT(x) tp_svc_account_interface_addressing_implement_##x (\ iface, addressing_##x) IMPLEMENT(set_uri_scheme_association); #undef IMPLEMENT diff --git a/src/mcd-account-addressing.h b/src/mcd-account-addressing.h index a91e110d..61740463 100644 --- a/src/mcd-account-addressing.h +++ b/src/mcd-account-addressing.h @@ -32,7 +32,7 @@ G_BEGIN_DECLS G_GNUC_INTERNAL extern const McdDBusProp account_addressing_properties[]; G_GNUC_INTERNAL void account_addressing_iface_init ( - McSvcAccountInterfaceAddressingClass *iface, + TpSvcAccountInterfaceAddressingClass *iface, gpointer data); G_END_DECLS diff --git a/src/mcd-account-compat.c b/src/mcd-account-compat.c deleted file mode 100644 index 56e0ff09..00000000 --- a/src/mcd-account-compat.c +++ /dev/null @@ -1,160 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* - * This file is part of mission-control - * - * Copyright (C) 2008-2009 Nokia Corporation. - * Copyright (C) 2009 Collabora Ltd. - * - * Contact: Alberto Mardegan <alberto.mardegan@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include <stdio.h> -#include <string.h> -#include <glib/gstdio.h> -#include <config.h> - -#include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/util.h> - -#include "mcd-account.h" -#include "mcd-account-priv.h" -#include "mcd-account-manager.h" -#include "mcd-misc.h" -#include "mcd-service.h" - -#define COMPAT_REQ_DATA "compat_req" - -typedef struct -{ - guint requestor_serial; - gchar *requestor_client_id; -} McdAccountCompatReq; - -static void -emit_compat_property_changed (McdAccount *account, const gchar *key, - const GValue *value) -{ - GHashTable *properties; - - properties = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_insert (properties, (gpointer)key, (gpointer)value); - - mc_svc_account_interface_compat_emit_compat_property_changed (account, - properties); - g_hash_table_unref (properties); -} - -static void -get_avatar_file (TpSvcDBusProperties *self, const gchar *name, GValue *value) -{ - McdAccount *account = MCD_ACCOUNT (self); - gchar *string; - - string = _mcd_account_get_avatar_filename (account); - g_value_init (value, G_TYPE_STRING); - g_value_take_string (value, string); -} - -static gboolean -set_secondary_vcard_fields (TpSvcDBusProperties *self, const gchar *name, - const GValue *value, GError **error) -{ - McdAccount *account = MCD_ACCOUNT (self); - McdStorage *storage = _mcd_account_get_storage (account); - const gchar *account_name = mcd_account_get_unique_name (account); - GStrv fields; - const GValue *set = NULL; - - /* FIXME: some sort of validation beyond just the type? */ - - if (!G_VALUE_HOLDS (value, G_TYPE_STRV)) - { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Expected string-array for SecondaryVCardFields, but " - "got %s", G_VALUE_TYPE_NAME (value)); - return FALSE; - } - - fields = g_value_get_boxed (value); - - if (fields != NULL) - set = value; - - mcd_storage_set_value (storage, account_name, name, set, FALSE); - mcd_storage_commit (storage, account_name); - - emit_compat_property_changed (account, name, value); - - return TRUE; -} - -static void -get_secondary_vcard_fields (TpSvcDBusProperties *self, const gchar *name, - GValue *value) -{ - McdAccount *account = MCD_ACCOUNT (self); - McdStorage *storage = _mcd_account_get_storage (account); - const gchar *account_name = mcd_account_get_unique_name (account); - GValue *fetched; - - g_value_init (value, G_TYPE_STRV); - fetched = - mcd_storage_dup_value (storage, account_name, name, G_TYPE_STRV, NULL); - - if (fetched != NULL) - { - GStrv fields = g_value_get_boxed (fetched); - - g_value_take_boxed (value, fields); - g_slice_free (GValue, fetched); - fetched = NULL; - } - else - { - g_value_take_boxed (value, NULL); - } -} - - -const McdDBusProp account_compat_properties[] = { - { "AvatarFile", NULL, get_avatar_file }, - { "SecondaryVCardFields", set_secondary_vcard_fields, get_secondary_vcard_fields }, - { 0 }, -}; - -static void -compat_set_has_been_online (McSvcAccountInterfaceCompat *iface, - DBusGMethodInvocation *context) -{ - _mcd_account_set_has_been_online (MCD_ACCOUNT (iface)); - mc_svc_account_interface_compat_return_from_set_has_been_online (context); -} - -void -account_compat_iface_init (McSvcAccountInterfaceCompatClass *iface, - gpointer iface_data) -{ -#define IMPLEMENT(x) mc_svc_account_interface_compat_implement_##x (\ - iface, compat_##x) - IMPLEMENT (set_has_been_online); -#undef IMPLEMENT -} diff --git a/src/mcd-account-conditions.c b/src/mcd-account-conditions.c index 8385efcd..8a6af964 100644 --- a/src/mcd-account-conditions.c +++ b/src/mcd-account-conditions.c @@ -24,14 +24,14 @@ * */ +#include "config.h" + #include <stdio.h> #include <string.h> #include <glib/gstdio.h> -#include <config.h> -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "mcd-account.h" #include "mcd-account-priv.h" @@ -67,7 +67,7 @@ set_condition (TpSvcDBusProperties *self, const gchar *name, if (!G_VALUE_HOLDS (value, TP_HASH_TYPE_STRING_STRING_MAP)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Expected a{s:s} for Condition, but got %s", G_VALUE_TYPE_NAME (value)); return FALSE; @@ -75,7 +75,7 @@ set_condition (TpSvcDBusProperties *self, const gchar *name, if (_mcd_account_get_always_on (account)) { - g_set_error (error, TP_ERRORS, TP_ERROR_PERMISSION_DENIED, + g_set_error (error, TP_ERROR, TP_ERROR_PERMISSION_DENIED, "Account %s conditions cannot be changed", mcd_account_get_unique_name (account)); return FALSE; diff --git a/src/mcd-account-connection.c b/src/mcd-account-connection.c index 7710d444..6d7dbf7f 100644 --- a/src/mcd-account-connection.c +++ b/src/mcd-account-connection.c @@ -24,10 +24,11 @@ * */ +#include "config.h" + #include <stdio.h> #include <string.h> #include <glib/gstdio.h> -#include <config.h> #include "mcd-master.h" #include "mcd-master-priv.h" diff --git a/src/mcd-account-manager-default.c b/src/mcd-account-manager-default.c index 2fb03000..ffd522fb 100644 --- a/src/mcd-account-manager-default.c +++ b/src/mcd-account-manager-default.c @@ -579,6 +579,25 @@ _get (const McpAccountStorage *self, return TRUE; } +static gchar * +_create (const McpAccountStorage *self, + const McpAccountManager *am, + const gchar *manager, + const gchar *protocol, + GHashTable *params, + GError **error) +{ + gchar *unique_name; + + /* See comment in plugin-account.c::_storage_create_account() before changing + * this implementation, it's more subtle than it looks */ + unique_name = mcp_account_manager_get_unique_name (MCP_ACCOUNT_MANAGER (am), + manager, protocol, params); + g_return_val_if_fail (unique_name != NULL, NULL); + + return unique_name; +} + static gboolean _delete (const McpAccountStorage *self, const McpAccountManager *am, @@ -701,6 +720,7 @@ account_storage_iface_init (McpAccountStorageIface *iface, mcp_account_storage_iface_implement_get (iface, _get); mcp_account_storage_iface_implement_set (iface, _set); + mcp_account_storage_iface_implement_create (iface, _create); mcp_account_storage_iface_implement_delete (iface, _delete); mcp_account_storage_iface_implement_commit_one (iface, _commit); mcp_account_storage_iface_implement_list (iface, _list); diff --git a/src/mcd-account-manager-priv.h b/src/mcd-account-manager-priv.h index 839fafc3..80a1e0fa 100644 --- a/src/mcd-account-manager-priv.h +++ b/src/mcd-account-manager-priv.h @@ -30,7 +30,6 @@ /* auto-generated stubs */ #include "_gen/svc-Account_Manager_Interface_Hidden.h" -#include "_gen/svc-Account_Manager_Interface_Query.h" G_BEGIN_DECLS @@ -51,15 +50,6 @@ G_GNUC_INTERNAL void _mcd_account_manager_create_account const gchar *display_name, GHashTable *params, GHashTable *properties, McdGetAccountCb callback, gpointer user_data, GDestroyNotify destroy); -G_GNUC_INTERNAL -void _mcd_account_manager_store_account_connections - (McdAccountManager *manager); - -extern const McdDBusProp account_manager_query_properties[]; - -void account_manager_query_iface_init (McSvcAccountManagerInterfaceQueryClass *iface, - gpointer iface_data); - G_END_DECLS #endif diff --git a/src/mcd-account-manager-query.c b/src/mcd-account-manager-query.c deleted file mode 100644 index 24306a4e..00000000 --- a/src/mcd-account-manager-query.c +++ /dev/null @@ -1,368 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* - * This file is part of mission-control - * - * Copyright (C) 2008-2009 Nokia Corporation. - * Copyright (C) 2009 Collabora Ltd. - * - * Contact: Alberto Mardegan <alberto.mardegan@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include <stdio.h> -#include <string.h> -#include <glib/gstdio.h> -#include <config.h> - -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/util.h> -#include "mcd-account.h" -#include "mcd-account-manager.h" -#include "mcd-account-manager-priv.h" -#include "mcd-account-priv.h" - -typedef struct -{ - const gchar *name; - const GValue *value; -} McdFindParam; - -typedef struct -{ - gchar *iface; - const gchar *name; - const GValue *value; -} McdIfaceProperty; - -typedef struct -{ - const gchar *manager; - const gchar *protocol; - guint requested_presence; - const gchar *requested_status; - guint current_presence; - const gchar *current_status; - GArray *params; - GArray *properties; - gint n_accounts; - GPtrArray *accounts; - GError *error; -} McdFindData; - -static const gchar *supported_keywords[] = { - "Manager", "Protocol", - "RequestedPresence", "RequestedStatus", - "CurrentPresence", "CurrentStatus", - NULL -}; - -static void -get_keywords (TpSvcDBusProperties *self, const gchar *name, - GValue *value) -{ - g_value_init (value, G_TYPE_STRV); - g_value_set_static_boxed (value, supported_keywords); -} - - -const McdDBusProp account_manager_query_properties[] = { - { "Keywords", NULL, get_keywords }, - { 0 }, -}; - - -static gboolean -match_account_parameter (McdAccount *account, const gchar *name, - const GValue *value) -{ - gboolean match = FALSE; - McdStorage *storage = _mcd_account_get_storage (account); - const gchar *account_name = mcd_account_get_unique_name (account); - GType vtype = G_VALUE_TYPE (value); - - if (mcd_storage_has_value (storage, account_name, name)) - { - GValue *conf = NULL; - - switch (vtype) - { - case G_TYPE_STRING: - case G_TYPE_UINT: - case G_TYPE_BOOLEAN: - conf = mcd_storage_dup_value (storage, account_name, name, vtype, - NULL); - break; - default: - g_warning ("Unexpected type %s", G_VALUE_TYPE_NAME (value)); - } - - if (conf != NULL) - { - if (G_VALUE_TYPE (conf) == vtype) - { - switch (vtype) - { - case G_TYPE_STRING: - match = g_strcmp0 (g_value_get_string (value), - g_value_get_string (conf)) == 0; - break; - - case G_TYPE_UINT: - match = g_value_get_uint (value) == g_value_get_uint (conf); - break; - - case G_TYPE_BOOLEAN: - match = - g_value_get_boolean (value) == g_value_get_boolean (conf); - break; - - default: - break; - } - } - - tp_g_value_slice_free (conf); - } - } - - return match; -} - -static gboolean -match_account_property (McdAccount *account, McdIfaceProperty *prop) -{ - const gchar *unique_name; - gboolean match = FALSE; - GValue value = { 0 }; - GError *error = NULL; - - DEBUG ("prop %s, value type %s", prop->name, G_VALUE_TYPE_NAME (prop->value)); - unique_name = mcd_account_get_unique_name (account); - mcd_dbusprop_get_property (TP_SVC_DBUS_PROPERTIES (account), - prop->iface, prop->name, &value, - &error); - if (error) - { - g_warning ("%s on %s: %s", G_STRFUNC, unique_name, error->message); - g_error_free (error); - return FALSE; - } - - if (G_VALUE_TYPE (&value) == G_VALUE_TYPE (prop->value)) - { - switch (G_VALUE_TYPE (&value)) - { - case G_TYPE_CHAR: - case G_TYPE_UCHAR: - case G_TYPE_BOOLEAN: - case G_TYPE_INT: - case G_TYPE_UINT: - case G_TYPE_LONG: - case G_TYPE_ULONG: - case G_TYPE_INT64: - case G_TYPE_UINT64: - case G_TYPE_FLOAT: - case G_TYPE_DOUBLE: - case G_TYPE_POINTER: - /* this assumes the GValue was previously initialized to 0, which - * should always be the case */ - match = (value.data[0].v_uint64 == prop->value->data[0].v_uint64); - break; - case G_TYPE_STRING: - match = !tp_strdiff (g_value_get_string (&value), - g_value_get_string (prop->value)); - break; - default: - g_warning ("%s: unsupported value type: %s", - G_STRFUNC, G_VALUE_TYPE_NAME (&value)); - } - } - g_value_unset (&value); - return match; -} - -static void -find_accounts (gpointer key, gpointer value, gpointer userdata) -{ - McdAccount *account = MCD_ACCOUNT (value); - McdFindData *fd = userdata; - TpConnectionPresenceType presence; - const gchar *object_path, *string, *status, *message; - guint i; - - DEBUG ("%s", (gchar *)key); - if (fd->manager) - { - string = mcd_account_get_manager_name (account); - if (!string || strcmp (fd->manager, string) != 0) return; - } - if (fd->protocol) - { - string = mcd_account_get_protocol_name (account); - if (!string || strcmp (fd->protocol, string) != 0) return; - } - if (fd->requested_presence > 0) - { - mcd_account_get_requested_presence (account, &presence, - &status, &message); - if (fd->requested_presence != presence) return; - } - if (fd->requested_status) - { - mcd_account_get_requested_presence (account, &presence, - &status, &message); - if (!status || strcmp (fd->requested_status, status) != 0) return; - } - if (fd->current_presence > 0) - { - mcd_account_get_current_presence (account, &presence, - &status, &message); - if (fd->current_presence != presence) return; - } - if (fd->current_status) - { - mcd_account_get_current_presence (account, &presence, - &status, &message); - if (!status || strcmp (fd->current_status, status) != 0) return; - } - - DEBUG ("checking parameters"); - for (i = 0; i < fd->params->len; i++) - { - McdFindParam *param; - param = &g_array_index (fd->params, McdFindParam, i); - if (!match_account_parameter (account, param->name, param->value)) - return; - } - - DEBUG ("checking properties"); - for (i = 0; i < fd->properties->len; i++) - { - McdIfaceProperty *prop; - prop = &g_array_index (fd->properties, McdIfaceProperty, i); - if (!match_account_property (account, prop)) - return; - } - object_path = mcd_account_get_object_path (account); - DEBUG ("%s", object_path); - g_ptr_array_add (fd->accounts, (gpointer)object_path); -} - -static void -parse_query (gpointer key, gpointer val, gpointer userdata) -{ - McdFindData *fd = userdata; - gchar *name = key, *dot; - GValue *value = val; - - if (fd->error) return; - - if (strcmp (name, "Manager") == 0) - fd->manager = g_value_get_string (value); - else if (strcmp (name, "Protocol") == 0) - fd->protocol = g_value_get_string (value); - else if (strcmp (name, "RequestedPresence") == 0) - fd->requested_presence = g_value_get_uint (value); - else if (strcmp (name, "RequestedStatus") == 0) - fd->requested_status = g_value_get_string (value); - else if (strcmp (name, "CurrentPresence") == 0) - fd->current_presence = g_value_get_uint (value); - else if (strcmp (name, "CurrentStatus") == 0) - fd->current_status = g_value_get_string (value); - else if (strncmp (name, "param-", 6) == 0) - { - McdFindParam param; - - param.name = name; - param.value = value; - g_array_append_val (fd->params, param); - } - else if ((dot = strrchr (name, '.')) != NULL) - { - McdIfaceProperty prop; - - prop.iface = g_strndup (name, dot - name); - prop.name = dot + 1; - prop.value = value; - g_array_append_val (fd->properties, prop); - } - else - { - g_set_error (&fd->error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, - "Unrecognized query parameter: %s", name); - } -} - -static void -account_manager_find_accounts (McSvcAccountManagerInterfaceQuery *self, - GHashTable *query, - DBusGMethodInvocation *context) -{ - McdAccountManager *account_manager = MCD_ACCOUNT_MANAGER (self); - McdFindData fd; - guint i; - - DEBUG ("called"); - memset (&fd, 0, sizeof (fd)); - fd.params = g_array_new (FALSE, FALSE, sizeof (McdFindParam)); - fd.properties = g_array_new (FALSE, FALSE, sizeof (McdIfaceProperty)); - - /* break the hash table into the McdFindData struct, to avoid having to - * iterate over it for every account */ - g_hash_table_foreach (query, parse_query, &fd); - if (!fd.error) - { - GHashTable *accounts; - - fd.accounts = g_ptr_array_sized_new (16); - accounts = _mcd_account_manager_get_accounts (account_manager); - g_hash_table_foreach (accounts, find_accounts, &fd); - } - g_array_unref (fd.params); - for (i = 0; i < fd.properties->len; i++) - { - McdIfaceProperty *prop; - prop = &g_array_index (fd.properties, McdIfaceProperty, i); - g_free (prop->iface); - } - g_array_unref (fd.properties); - - if (fd.error) - { - dbus_g_method_return_error (context, fd.error); - g_error_free (fd.error); - return; - } - - mc_svc_account_manager_interface_query_return_from_find_accounts (context, - fd.accounts); - g_ptr_array_unref (fd.accounts); -} - - -void -account_manager_query_iface_init (McSvcAccountManagerInterfaceQueryClass *iface, - gpointer iface_data) -{ -#define IMPLEMENT(x) mc_svc_account_manager_interface_query_implement_##x (\ - iface, account_manager_##x) - IMPLEMENT(find_accounts); -#undef IMPLEMENT -} - diff --git a/src/mcd-account-manager-sso.c b/src/mcd-account-manager-sso.c index 0cf4e41e..8e22dedc 100644 --- a/src/mcd-account-manager-sso.c +++ b/src/mcd-account-manager-sso.c @@ -23,7 +23,10 @@ #include "mcd-account-manager-sso.h" #include "mcd-debug.h" -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> + +#include <libaccounts-glib/ag-account.h> +#include <libaccounts-glib/ag-service.h> #include <string.h> #include <ctype.h> @@ -345,7 +348,7 @@ _maybe_set_account_param_from_service ( { Setting *setting = setting_data (AG_ACCOUNT_KEY, SETTING_AG); AgSettingSource source = AG_SETTING_SOURCE_NONE; - GValue ag_value = { 0 }; + GValue ag_value = G_VALUE_INIT; g_return_if_fail (setting != NULL); g_return_if_fail (ag_account != NULL); @@ -486,7 +489,7 @@ static void _sso_updated (AgAccount *account, if (g_str_has_prefix (mc_key, MCPP)) params_updated = TRUE; else - g_signal_emit_by_name (mcpa, "altered-one", name, mc_key); + mcp_account_storage_emit_altered_one (mcpa, name, mc_key); } } @@ -515,14 +518,14 @@ static void _sso_updated (AgAccount *account, if (g_str_has_prefix (deleted_key, MCPP)) params_updated = TRUE; else - g_signal_emit_by_name (mcpa, "altered-one", name, deleted_key); + mcp_account_storage_emit_altered_one (mcpa, name, deleted_key); } g_hash_table_unref (unseen); g_strfreev (keys); if (params_updated) - g_signal_emit_by_name (mcpa, "altered-one", name, "Parameters"); + mcp_account_storage_emit_altered_one (mcpa, name, "Parameters"); /* put the selected service back the way it was when we found it */ ag_account_select_service (account, service); @@ -587,7 +590,7 @@ static void _sso_toggled (GObject *object, McpAccountManager *am = sso->manager_interface; mcp_account_manager_set_value (am, name, "Enabled", value); - g_signal_emit_by_name (mcpa, "toggled", name, on); + mcp_account_storage_emit_toggled (mcpa, name, on); } else { @@ -620,7 +623,7 @@ static void _sso_deleted (GObject *object, /* stop watching for updates */ unwatch_account_keys (sso, id); - g_signal_emit_by_name (mcpa, "deleted", signalled_name); + mcp_account_storage_emit_deleted (mcpa, signalled_name); g_free (signalled_name); } @@ -739,7 +742,7 @@ static void _sso_created (GObject *object, ag_account_store (account, _ag_account_stored_cb, sso); - g_signal_emit_by_name (mcpa, "created", name); + mcp_account_storage_emit_created (mcpa, name); clear_setting_data (setting); } @@ -817,7 +820,7 @@ _ag_account_stored_cb ( gpointer user_data) { McdAccountManagerSso *self = MCD_ACCOUNT_MANAGER_SSO (user_data); - GValue uid = { 0 }; + GValue uid = G_VALUE_INIT; const gchar *name = NULL; AgSettingSource src = AG_SETTING_SOURCE_NONE; @@ -846,7 +849,7 @@ _ag_accountid_to_mc_key (McdAccountManagerSso *sso, AgAccount *account = ag_manager_get_account (sso->ag_manager, id); AgSettingSource src = AG_SETTING_SOURCE_NONE; AgService *service = NULL; - GValue value = { 0 }; + GValue value = G_VALUE_INIT; if (account == NULL) { @@ -870,14 +873,13 @@ _ag_accountid_to_mc_key (McdAccountManagerSso *sso, g_value_unset (&value); return uid; } - else + + if (!create) { g_value_unset (&value); + return NULL; } - if (!create) - return NULL; - DEBUG ("no " MC_IDENTITY_KEY " found, synthesising one:"); src = _ag_account_global_value (account, AG_ACCOUNT_KEY, &value); @@ -894,8 +896,8 @@ _ag_accountid_to_mc_key (McdAccountManagerSso *sso, AgAccountSettingIter iter; const gchar *k; const GValue *v; - GValue cmanager = { 0 }; - GValue protocol = { 0 }; + GValue cmanager = G_VALUE_INIT; + GValue protocol = G_VALUE_INIT; const gchar *cman, *proto; McpAccountManager *am = sso->manager_interface; GHashTable *params = g_hash_table_new_full (g_str_hash, g_str_equal, @@ -1033,7 +1035,7 @@ save_setting ( if (setting->readable) { - GValue old = { 0 }; + GValue old = G_VALUE_INIT; AgSettingSource src = AG_SETTING_SOURCE_NONE; g_value_init (&old, G_TYPE_STRING); @@ -1066,7 +1068,7 @@ save_setting ( if (val != NULL) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, val); @@ -1184,7 +1186,7 @@ account_manager_sso_get_one ( } else { - GValue v = { 0 }; + GValue v = G_VALUE_INIT; AgSettingSource src = AG_SETTING_SOURCE_NONE; Setting *setting = setting_data (key, SETTING_MC); diff --git a/src/mcd-account-manager-sso.h b/src/mcd-account-manager-sso.h index 108d0704..12e616f8 100644 --- a/src/mcd-account-manager-sso.h +++ b/src/mcd-account-manager-sso.h @@ -21,7 +21,6 @@ #include <mission-control-plugins/mission-control-plugins.h> #include <libaccounts-glib/ag-manager.h> -#include <libaccounts-glib/ag-account.h> #ifndef __MCD_ACCOUNT_MANAGER_SSO_H__ #define __MCD_ACCOUNT_MANAGER_SSO_H__ diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c index e4a81f79..e7b2161c 100644 --- a/src/mcd-account-manager.c +++ b/src/mcd-account-manager.c @@ -21,24 +21,18 @@ * 02110-1301 USA * */ +#include "config.h" #include "mcd-account-manager.h" #include <string.h> #include <stdio.h> #include <stdlib.h> -#include <config.h> #include <dbus/dbus-glib-lowlevel.h> #include <dbus/dbus.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/enums.h> -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/svc-account.h> -#include <telepathy-glib/util.h> -#include <telepathy-glib/errors.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/svc-account-manager.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "mcd-account-manager-priv.h" #include "mcd-storage.h" @@ -50,9 +44,9 @@ #include "mcd-dbusprop.h" #include "mcd-master-priv.h" #include "mcd-misc.h" +#include "mcd-storage.h" #include "mission-control-plugins/mission-control-plugins.h" #include "mission-control-plugins/implementation.h" -#include "plugin-account.h" #include "plugin-loader.h" #include "_gen/interfaces.h" @@ -80,9 +74,6 @@ static const McdInterfaceData account_manager_interfaces[] = { MCD_IMPLEMENT_IFACE (tp_svc_account_manager_get_type, account_manager, TP_IFACE_ACCOUNT_MANAGER), - MCD_IMPLEMENT_IFACE (mc_svc_account_manager_interface_query_get_type, - account_manager_query, - MC_IFACE_ACCOUNT_MANAGER_INTERFACE_QUERY), MCD_IMPLEMENT_IFACE (mc_svc_account_manager_interface_hidden_get_type, account_manager_hidden, MC_IFACE_ACCOUNT_MANAGER_INTERFACE_HIDDEN), @@ -100,7 +91,7 @@ struct _McdAccountManagerPrivate /* DBUS connection */ TpDBusDaemon *dbus_daemon; - McdPluginAccountManager *plugin_manager; + McdStorage *storage; GHashTable *accounts; gchar *account_connections_dir; /* directory for temporary file */ @@ -112,7 +103,7 @@ struct _McdAccountManagerPrivate typedef struct { McdAccountManager *account_manager; - McpAccountStorage *storage; + McpAccountStorage *storage_plugin; McdAccount *account; gint account_lock; } McdLoadAccountsData; @@ -299,7 +290,7 @@ async_created_manager_cb (McdManager *cm, const GError *error, gpointer data) McdLoadAccountsData *lad = data; McdAccount *account = lad->account; McdAccountManager *am = lad->account_manager; - McpAccountStorage *plugin = lad->storage; + McpAccountStorage *plugin = lad->storage_plugin; const gchar *name = NULL; if (cm != NULL) @@ -328,27 +319,29 @@ async_created_manager_cb (McdManager *cm, const GError *error, gpointer data) * to fetch the named account explicitly at this point (ie it's a read, not * * not a write, from the plugin's POV: */ static void -created_cb (GObject *storage, const gchar *name, gpointer data) +created_cb (GObject *storage_plugin_obj, + const gchar *name, + gpointer data) { - McpAccountStorage *plugin = MCP_ACCOUNT_STORAGE (storage); + McpAccountStorage *plugin = MCP_ACCOUNT_STORAGE (storage_plugin_obj); McdAccountManager *am = MCD_ACCOUNT_MANAGER (data); McdAccountManagerPrivate *priv = MCD_ACCOUNT_MANAGER_PRIV (am); - McdAccountManagerClass *mclass = MCD_ACCOUNT_MANAGER_GET_CLASS (am); McdLoadAccountsData *lad = g_slice_new (McdLoadAccountsData); McdAccount *account = NULL; - McdPluginAccountManager *pa = priv->plugin_manager; + McdStorage *storage = priv->storage; McdMaster *master = mcd_master_get_default (); McdManager *cm = NULL; const gchar *cm_name = NULL; lad->account_manager = am; - lad->storage = plugin; + lad->storage_plugin = plugin; lad->account_lock = 1; /* will be released at the end of this function */ /* actually fetch the data into our cache from the plugin: */ - if (mcp_account_storage_get (plugin, MCP_ACCOUNT_MANAGER (pa), name, NULL)) + if (mcp_account_storage_get (plugin, MCP_ACCOUNT_MANAGER (storage), + name, NULL)) { - account = mclass->account_new (am, name); + account = mcd_account_new (am, name); lad->account = account; } else @@ -390,7 +383,7 @@ finish: static void toggled_cb (GObject *plugin, const gchar *name, gboolean on, gpointer data) { - McpAccountStorage *storage = MCP_ACCOUNT_STORAGE (plugin); + McpAccountStorage *storage_plugin = MCP_ACCOUNT_STORAGE (plugin); McdAccountManager *manager = MCD_ACCOUNT_MANAGER (data); McdAccount *account = NULL; GError *error = NULL; @@ -398,12 +391,12 @@ toggled_cb (GObject *plugin, const gchar *name, gboolean on, gpointer data) account = mcd_account_manager_lookup_account (manager, name); DEBUG ("%s plugin reports %s became %sabled", - mcp_account_storage_name (storage), name, on ? "en" : "dis"); + mcp_account_storage_name (storage_plugin), name, on ? "en" : "dis"); if (account == NULL) { g_warning ("%s: Unknown account %s from %s plugin", - G_STRFUNC, name, mcp_account_storage_name (storage)); + G_STRFUNC, name, mcp_account_storage_name (storage_plugin)); return; } @@ -417,6 +410,30 @@ toggled_cb (GObject *plugin, const gchar *name, gboolean on, gpointer data) } static void +reconnect_cb (GObject *plugin, const gchar *name, gpointer data) +{ + McpAccountStorage *storage_plugin = MCP_ACCOUNT_STORAGE (plugin); + McdAccountManager *manager = MCD_ACCOUNT_MANAGER (data); + McdAccount *account = NULL; + + account = mcd_account_manager_lookup_account (manager, name); + + DEBUG ("%s plugin request %s reconnection", + mcp_account_storage_name (storage_plugin), name); + + if (account == NULL) + { + g_warning ("%s: Unknown account %s from %s plugin", + G_STRFUNC, name, mcp_account_storage_name (storage_plugin)); + return; + } + + /* Storage ask to reconnect when important parameters changed, which is an + * user action. */ + _mcd_account_reconnect (account, TRUE); +} + +static void _mcd_account_delete_cb (McdAccount *account, const GError *error, gpointer data) { /* no need to do anything other than release the account ref, which * @@ -428,14 +445,14 @@ _mcd_account_delete_cb (McdAccount *account, const GError *error, gpointer data) static void deleted_cb (GObject *plugin, const gchar *name, gpointer data) { - McpAccountStorage *storage = MCP_ACCOUNT_STORAGE (plugin); + McpAccountStorage *storage_plugin = MCP_ACCOUNT_STORAGE (plugin); McdAccountManager *manager = MCD_ACCOUNT_MANAGER (data); McdAccount *account = NULL; account = g_hash_table_lookup (manager->priv->accounts, name); DEBUG ("%s reported deletion of %s (%p)", - mcp_account_storage_name (storage), name, account); + mcp_account_storage_name (storage_plugin), name, account); if (account != NULL) { @@ -588,12 +605,6 @@ list_connection_names_cb (const gchar * const *names, gsize n, g_free (contents); } -static McdAccount * -account_new (McdAccountManager *account_manager, const gchar *name) -{ - return mcd_account_new (account_manager, name); -} - static void on_account_validity_changed (McdAccount *account, gboolean valid, McdAccountManager *account_manager) @@ -619,7 +630,7 @@ static void on_account_removed (McdAccount *account, McdAccountManager *account_manager) { McdAccountManagerPrivate *priv = account_manager->priv; - McdStorage *storage = MCD_STORAGE (priv->plugin_manager); + McdStorage *storage = priv->storage; const gchar *name, *object_path; object_path = mcd_account_get_object_path (account); @@ -664,6 +675,9 @@ unref_account (gpointer data) g_object_unref (account); } +static void _mcd_account_manager_store_account_connections ( + McdAccountManager *); + static void add_account (McdAccountManager *account_manager, McdAccount *account, const gchar *source) @@ -691,6 +705,9 @@ add_account (McdAccountManager *account_manager, McdAccount *account, account_manager); g_signal_connect (account, "removed", G_CALLBACK (on_account_removed), account_manager); + tp_g_signal_connect_object (account, "connection-path-changed", + G_CALLBACK (_mcd_account_manager_store_account_connections), + account_manager, G_CONNECT_SWAPPED); /* some reports indicate this doesn't always fire for async backend * * accounts: testing here hasn't shown this, but at least we will be * @@ -740,7 +757,7 @@ set_new_account_properties (McdAccount *account, } else { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Malformed property name: %s", name); ok = FALSE; } @@ -854,17 +871,18 @@ _mcd_account_manager_create_account (McdAccountManager *account_manager, GDestroyNotify destroy) { McdAccountManagerPrivate *priv = account_manager->priv; - McpAccountManager *ma = MCP_ACCOUNT_MANAGER (priv->plugin_manager); - McdStorage *storage = MCD_STORAGE (priv->plugin_manager); + McdStorage *storage = priv->storage; McdCreateAccountData *cad; McdAccount *account; - gchar *unique_name; + gchar *unique_name = NULL; + const gchar *provider; + GError *e = NULL; DEBUG ("called"); if (G_UNLIKELY (manager == NULL || manager[0] == 0 || - protocol == NULL || protocol[0] == 0)) + protocol == NULL || protocol[0] == 0)) { - GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Invalid parameters"}; callback (account_manager, NULL, &error, user_data); if (destroy) @@ -872,9 +890,21 @@ _mcd_account_manager_create_account (McdAccountManager *account_manager, return; } - unique_name = - mcp_account_manager_get_unique_name (ma, manager, protocol, params); - g_return_if_fail (unique_name != NULL); + provider = tp_asv_get_string (properties, + TP_PROP_ACCOUNT_INTERFACE_STORAGE_STORAGE_PROVIDER); + + unique_name = mcd_storage_create_account (storage, provider, + manager, protocol, params, + &e); + + if (unique_name == NULL) + { + callback (account_manager, NULL, e, user_data); + g_clear_error (&e); + if (destroy) + destroy (user_data); + return; + } /* create the basic account keys */ mcd_storage_set_string (storage, unique_name, @@ -887,8 +917,7 @@ _mcd_account_manager_create_account (McdAccountManager *account_manager, MC_ACCOUNTS_KEY_DISPLAY_NAME, display_name, FALSE); - account = MCD_ACCOUNT_MANAGER_GET_CLASS (account_manager)->account_new - (account_manager, unique_name); + account = mcd_account_new (account_manager, unique_name); g_free (unique_name); if (G_LIKELY (account)) @@ -905,7 +934,7 @@ _mcd_account_manager_create_account (McdAccountManager *account_manager, } else { - GError error = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, "" }; + GError error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "" }; callback (account_manager, NULL, &error, user_data); if (destroy) destroy (user_data); @@ -1030,8 +1059,8 @@ get_supported_account_properties (TpSvcDBusProperties *svc, TP_IFACE_ACCOUNT ".RequestedPresence", TP_IFACE_ACCOUNT ".Supersedes", TP_IFACE_ACCOUNT_INTERFACE_AVATAR ".Avatar", - MC_IFACE_ACCOUNT_INTERFACE_COMPAT ".SecondaryVCardFields", MC_IFACE_ACCOUNT_INTERFACE_CONDITIONS ".Condition", + TP_PROP_ACCOUNT_INTERFACE_STORAGE_STORAGE_PROVIDER, NULL }; @@ -1133,7 +1162,7 @@ uncork_storage_plugins (McdAccountManager *account_manager) McdAccountManagerPrivate *priv = MCD_ACCOUNT_MANAGER_PRIV (account_manager); mcd_account_manager_write_conf_async (account_manager, NULL, NULL, NULL); - _mcd_plugin_account_manager_ready (priv->plugin_manager); + mcd_storage_ready (priv->storage); } typedef struct @@ -1208,8 +1237,8 @@ migrate_butterfly_haze_ready (McdManager *manager, { MigrateCtx *ctx = user_data; gchar *display_name; - GValue v = {0,}; - GValue password_v = {0,}; + GValue v = G_VALUE_INIT; + GValue password_v = G_VALUE_INIT; GHashTable *parameters, *properties; gchar *str; GPtrArray *supersedes; @@ -1374,7 +1403,7 @@ void _mcd_account_manager_setup (McdAccountManager *account_manager) { McdAccountManagerPrivate *priv = account_manager->priv; - McdStorage *storage = MCD_STORAGE (priv->plugin_manager); + McdStorage *storage = priv->storage; McdLoadAccountsData *lad; gchar **accounts, **name; @@ -1403,8 +1432,7 @@ _mcd_account_manager_setup (McdAccountManager *account_manager) continue; } - account = MCD_ACCOUNT_MANAGER_GET_CLASS (account_manager)->account_new - (account_manager, *name); + account = mcd_account_new (account_manager, *name); if (G_UNLIKELY (!account)) { @@ -1518,11 +1546,11 @@ _mcd_account_manager_finalize (GObject *object) if (write_conf_id) { - write_conf (priv->plugin_manager); + write_conf (priv->storage); g_assert (write_conf_id == 0); } - tp_clear_object (&priv->plugin_manager); + tp_clear_object (&priv->storage); g_free (priv->account_connections_dir); remove (priv->account_connections_file); g_free (priv->account_connections_file); @@ -1554,8 +1582,6 @@ mcd_account_manager_class_init (McdAccountManagerClass *klass) object_class->get_property = get_property; object_class->constructed = _mcd_account_manager_constructed; - klass->account_new = account_new; - g_object_class_install_property (object_class, PROP_DBUS_DAEMON, g_param_spec_object ("dbus-daemon", "DBus daemon", "DBus daemon", @@ -1585,6 +1611,18 @@ static void mcd_account_manager_init (McdAccountManager *account_manager) { McdAccountManagerPrivate *priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE ((account_manager), + MCD_TYPE_ACCOUNT_MANAGER, + McdAccountManagerPrivate); + account_manager->priv = priv; +} + +static void +_mcd_account_manager_constructed (GObject *obj) +{ + McdAccountManager *account_manager = MCD_ACCOUNT_MANAGER (obj); + McdAccountManagerPrivate *priv = account_manager->priv; guint i = 0; static struct { const gchar *name; GCallback handler; } sig[] = { { "created", G_CALLBACK (created_cb) }, @@ -1592,16 +1630,12 @@ mcd_account_manager_init (McdAccountManager *account_manager) { "toggled", G_CALLBACK (toggled_cb) }, { "deleted", G_CALLBACK (deleted_cb) }, { "altered-one", G_CALLBACK (altered_one_cb) }, + { "reconnect", G_CALLBACK (reconnect_cb) }, { NULL, NULL } }; DEBUG (""); - priv = G_TYPE_INSTANCE_GET_PRIVATE ((account_manager), - MCD_TYPE_ACCOUNT_MANAGER, - McdAccountManagerPrivate); - account_manager->priv = priv; - - priv->plugin_manager = mcd_plugin_account_manager_new (); + priv->storage = mcd_storage_new (priv->dbus_daemon); priv->accounts = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, unref_account); @@ -1611,32 +1645,19 @@ mcd_account_manager_init (McdAccountManager *account_manager) NULL); DEBUG ("loading plugins"); - mcd_storage_load (MCD_STORAGE (priv->plugin_manager)); + mcd_storage_load (priv->storage); /* hook up all the storage plugin signals to their handlers: */ for (i = 0; sig[i].name != NULL; i++) - _mcd_plugin_account_manager_connect_signal (sig[i].name, - sig[i].handler, - account_manager); + { + mcd_storage_connect_signal (sig[i].name, sig[i].handler, + account_manager); + } /* initializes the interfaces */ mcd_dbus_init_interfaces_instances (account_manager); } -static void -_mcd_account_manager_constructed (GObject *obj) -{ - McdAccountManager *manager = MCD_ACCOUNT_MANAGER (obj); - McdAccountManagerPrivate *priv = MCD_ACCOUNT_MANAGER_PRIV (manager); - McdPluginAccountManager *pa = priv->plugin_manager; - - /* FIXME: I'm pretty sure we should just move most of the above code out of - * _init() to here and then mcd_plugin_account_manager_new() could take the - * TpDBusDaemon * as it should and everyone wins. - */ - _mcd_plugin_account_manager_set_dbus_daemon (pa, priv->dbus_daemon); -} - McdAccountManager * mcd_account_manager_new (TpDBusDaemon *dbus_daemon) { @@ -1693,7 +1714,7 @@ mcd_account_manager_write_conf_async (McdAccountManager *account_manager, g_return_if_fail (MCD_IS_ACCOUNT_MANAGER (account_manager)); - storage = MCD_STORAGE (account_manager->priv->plugin_manager); + storage = account_manager->priv->storage; if (account != NULL) { @@ -1758,7 +1779,7 @@ mcd_account_manager_lookup_account_by_path (McdAccountManager *account_manager, * The data is stored in a temporary file, and can be read when MC restarts * after a crash. */ -void +static void _mcd_account_manager_store_account_connections (McdAccountManager *manager) { McdAccountManagerPrivate *priv; @@ -1799,6 +1820,6 @@ _mcd_account_manager_store_account_connections (McdAccountManager *manager) McdStorage * mcd_account_manager_get_storage (McdAccountManager *account_manager) { - return MCD_STORAGE (account_manager->priv->plugin_manager); + return account_manager->priv->storage; } diff --git a/src/mcd-account-manager.h b/src/mcd-account-manager.h index 42d071ea..373dffa9 100644 --- a/src/mcd-account-manager.h +++ b/src/mcd-account-manager.h @@ -24,7 +24,7 @@ #ifndef __MCD_ACCOUNT_MANAGER_H__ #define __MCD_ACCOUNT_MANAGER_H__ -#include <telepathy-glib/dbus.h> +#include <telepathy-glib/telepathy-glib.h> #include "mission-control-plugins/mission-control-plugins.h" #include "mcd-storage.h" @@ -56,14 +56,6 @@ struct _McdAccountManager struct _McdAccountManagerClass { GObjectClass parent_class; - McdAccount *(*account_new) (McdAccountManager *account_manager, - const gchar *name); - void (*_mc_reserved2) (void); - void (*_mc_reserved3) (void); - void (*_mc_reserved4) (void); - void (*_mc_reserved5) (void); - void (*_mc_reserved6) (void); - void (*_mc_reserved7) (void); }; GType mcd_account_manager_get_type (void); @@ -72,8 +64,6 @@ McdAccountManager *mcd_account_manager_new (TpDBusDaemon *dbus_daemon); TpDBusDaemon *mcd_account_manager_get_dbus_daemon (McdAccountManager *account_manager); -GKeyFile *mcd_account_manager_get_config (McdAccountManager *account_manager); - typedef void (McdAccountManagerWriteConfCb) (McdAccountManager *account_manager, const GError *error, gpointer user_data); diff --git a/src/mcd-account-priv.h b/src/mcd-account-priv.h index 624227a6..a00b398e 100644 --- a/src/mcd-account-priv.h +++ b/src/mcd-account-priv.h @@ -34,11 +34,8 @@ #include "request.h" #include <telepathy-glib/proxy-subclass.h> -#include "mcd-signals-marshal.h" /* auto-generated stubs */ -#include "_gen/svc-Account_Interface_Addressing.h" -#include "_gen/svc-Account_Interface_Compat.h" #include "_gen/svc-Account_Interface_Conditions.h" #include "_gen/svc-Account_Interface_External_Password_Storage.h" #include "_gen/svc-Account_Interface_Hidden.h" @@ -86,7 +83,6 @@ G_GNUC_INTERNAL gchar *_mcd_account_get_avatar_token (McdAccount *account); G_GNUC_INTERNAL void _mcd_account_set_alias (McdAccount *account, const gchar *alias); -G_GNUC_INTERNAL gchar *_mcd_account_get_avatar_filename (McdAccount *account); G_GNUC_INTERNAL GPtrArray *_mcd_account_get_supersedes (McdAccount *self); G_GNUC_INTERNAL void _mcd_account_tp_connection_changed (McdAccount *account, @@ -122,13 +118,6 @@ _mcd_account_write_conf (McdAccount *account) mcd_storage_commit (storage, mcd_account_get_unique_name (account)); } -G_GNUC_INTERNAL void _mcd_account_compat_class_init (McdAccountClass *klass); - -extern const McdDBusProp account_compat_properties[]; - -void account_compat_iface_init (McSvcAccountInterfaceCompatClass *iface, - gpointer iface_data); - G_GNUC_INTERNAL void _mcd_account_connection_begin (McdAccount *account, gboolean user_initiated); G_GNUC_INTERNAL void _mcd_account_connection_class_init (McdAccountClass *klass); @@ -189,4 +178,8 @@ gboolean _mcd_account_is_hidden (McdAccount *account); G_GNUC_INTERNAL gboolean _mcd_account_needs_dispatch (McdAccount *account); +G_GNUC_INTERNAL void _mcd_account_reconnect (McdAccount *self, + gboolean user_initiated); + + #endif /* __MCD_ACCOUNT_PRIV_H__ */ diff --git a/src/mcd-account-requests.c b/src/mcd-account-requests.c index da8a1e2b..84aaeb10 100644 --- a/src/mcd-account-requests.c +++ b/src/mcd-account-requests.c @@ -23,18 +23,16 @@ * 02110-1301 USA * */ +#include "config.h" #include <stdio.h> #include <string.h> #include <glib/gstdio.h> -#include <config.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/svc-channel-request.h> -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "mcd-account.h" #include "mcd-account-priv.h" diff --git a/src/mcd-account.c b/src/mcd-account.c index 1864e7db..ecc10358 100644 --- a/src/mcd-account.c +++ b/src/mcd-account.c @@ -23,19 +23,14 @@ #include "config.h" #include "mcd-account.h" -#include "mcd-storage-priv.h" #include <stdio.h> #include <string.h> #include <dbus/dbus.h> #include <glib/gstdio.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/protocol.h> -#include <telepathy-glib/svc-account.h> -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "mcd-account-priv.h" #include "mcd-account-conditions.h" @@ -44,7 +39,6 @@ #include "mcd-connection-plugin.h" #include "mcd-connection-priv.h" #include "mcd-misc.h" -#include "mcd-signals-marshal.h" #include "mcd-manager.h" #include "mcd-manager-priv.h" #include "mcd-master.h" @@ -88,18 +82,15 @@ static const McdInterfaceData account_interfaces[] = { MCD_IMPLEMENT_IFACE (tp_svc_account_interface_avatar_get_type, account_avatar, TP_IFACE_ACCOUNT_INTERFACE_AVATAR), - MCD_IMPLEMENT_IFACE (mc_svc_account_interface_compat_get_type, - account_compat, - MC_IFACE_ACCOUNT_INTERFACE_COMPAT), MCD_IMPLEMENT_IFACE (mc_svc_account_interface_conditions_get_type, account_conditions, MC_IFACE_ACCOUNT_INTERFACE_CONDITIONS), MCD_IMPLEMENT_IFACE (tp_svc_account_interface_storage_get_type, account_storage, TP_IFACE_ACCOUNT_INTERFACE_STORAGE), - MCD_IMPLEMENT_IFACE (mc_svc_account_interface_addressing_get_type, + MCD_IMPLEMENT_IFACE (tp_svc_account_interface_addressing_get_type, account_addressing, - MC_IFACE_ACCOUNT_INTERFACE_ADDRESSING), + TP_IFACE_ACCOUNT_INTERFACE_ADDRESSING), MCD_IMPLEMENT_IFACE (mc_svc_account_interface_hidden_get_type, account_hidden, MC_IFACE_ACCOUNT_INTERFACE_HIDDEN), @@ -206,6 +197,7 @@ enum { CONNECTION_STATUS_CHANGED, VALIDITY_CHANGED, + CONNECTION_PATH_CHANGED, LAST_SIGNAL }; @@ -337,7 +329,7 @@ mcd_account_loaded (McdAccount *account) if (!mcd_account_is_valid (account) || !account->priv->enabled) { /* FIXME: pick better errors and put them in telepathy-spec? */ - GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "account isn't Valid (not enough information to put it " "online)" }; GList *list; @@ -863,7 +855,7 @@ mcd_account_request_presence_int (McdAccount *account, if (changed) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; g_value_init (&value, TP_STRUCT_TYPE_SIMPLE_PRESENCE); g_value_take_boxed (&value, @@ -1071,7 +1063,7 @@ mcd_account_set_string_val (McdAccount *account, const gchar *key, if (!G_VALUE_HOLDS_STRING (value)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Expected string for %s, but got %s", key, G_VALUE_TYPE_NAME (value)); return SET_RESULT_ERROR; @@ -1194,7 +1186,7 @@ _mcd_account_set_enabled (McdAccount *account, if (priv->always_on && !enabled) { - g_set_error (error, TP_ERRORS, TP_ERROR_PERMISSION_DENIED, + g_set_error (error, TP_ERROR, TP_ERROR_PERMISSION_DENIED, "Account %s cannot be disabled", priv->unique_name); return FALSE; @@ -1202,13 +1194,14 @@ _mcd_account_set_enabled (McdAccount *account, if (priv->enabled != enabled) { - GValue value = { 0, }; + GValue value = G_VALUE_INIT; const gchar *name = mcd_account_get_unique_name (account); - if (!enabled) - mcd_account_request_presence (account, - TP_CONNECTION_PRESENCE_TYPE_OFFLINE, - "offline", NULL); + if (!enabled && priv->connection != NULL) + _mcd_connection_request_presence (priv->connection, + TP_CONNECTION_PRESENCE_TYPE_OFFLINE, + "offline", + NULL); priv->enabled = enabled; @@ -1247,7 +1240,7 @@ set_enabled (TpSvcDBusProperties *self, const gchar *name, const GValue *value, if (!G_VALUE_HOLDS_BOOLEAN (value)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Expected boolean for Enabled, but got %s", G_VALUE_TYPE_NAME (value)); return FALSE; @@ -1299,7 +1292,7 @@ set_service (TpSvcDBusProperties *self, const gchar *name, } else { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Invalid service '%s': Must consist of ASCII alphanumeric " "characters, underscores (_) and hyphens (-) only, and " "start with a letter", @@ -1363,7 +1356,7 @@ set_avatar (TpSvcDBusProperties *self, const gchar *name, const GValue *value, if (!G_VALUE_HOLDS (value, TP_STRUCT_TYPE_AVATAR)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unexpected type for Avatar: wanted (ay,s), got %s", G_VALUE_TYPE_NAME (value)); return FALSE; @@ -1469,7 +1462,7 @@ set_automatic_presence (TpSvcDBusProperties *self, if (!G_VALUE_HOLDS (value, TP_STRUCT_TYPE_SIMPLE_PRESENCE)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unexpected type for AutomaticPresence: wanted (u,s,s), " "got %s", G_VALUE_TYPE_NAME (value)); return FALSE; @@ -1482,7 +1475,7 @@ set_automatic_presence (TpSvcDBusProperties *self, if (!_presence_type_is_online (type)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "AutomaticPresence must be an online presence, not %d", type); return FALSE; @@ -1492,7 +1485,7 @@ set_automatic_presence (TpSvcDBusProperties *self, if (priv->auto_presence_type != type) { - GValue presence = { 0 }; + GValue presence = G_VALUE_INIT; g_value_init (&presence, G_TYPE_INT); g_value_set_int (&presence, type); @@ -1583,7 +1576,7 @@ set_connect_automatically (TpSvcDBusProperties *self, if (!G_VALUE_HOLDS_BOOLEAN (value)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Expected boolean for ConnectAutomatically, but got %s", G_VALUE_TYPE_NAME (value)); return FALSE; @@ -1593,7 +1586,7 @@ set_connect_automatically (TpSvcDBusProperties *self, if (priv->always_on && !connect_automatically) { - g_set_error (error, TP_ERRORS, TP_ERROR_PERMISSION_DENIED, + g_set_error (error, TP_ERROR, TP_ERROR_PERMISSION_DENIED, "Account %s always connects automatically", priv->unique_name); return FALSE; @@ -1727,7 +1720,7 @@ set_requested_presence (TpSvcDBusProperties *self, if (!G_VALUE_HOLDS (value, TP_STRUCT_TYPE_SIMPLE_PRESENCE)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unexpected type for RequestedPresence: wanted (u,s,s), " "got %s", G_VALUE_TYPE_NAME (value)); return FALSE; @@ -1740,14 +1733,14 @@ set_requested_presence (TpSvcDBusProperties *self, if (priv->always_on && !_presence_type_is_online (type)) { - g_set_error (error, TP_ERRORS, TP_ERROR_PERMISSION_DENIED, + g_set_error (error, TP_ERROR, TP_ERROR_PERMISSION_DENIED, "Account %s cannot be taken offline", priv->unique_name); return FALSE; } if (!_mcd_account_presence_type_is_settable (type)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "RequestedPresence %d cannot be set on yourself", type); return FALSE; } @@ -1812,7 +1805,7 @@ set_supersedes (TpSvcDBusProperties *svc, if (!G_VALUE_HOLDS (value, TP_ARRAY_TYPE_OBJECT_PATH_LIST)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unexpected type for Supersedes: wanted 'ao', got %s", G_VALUE_TYPE_NAME (value)); return FALSE; @@ -1877,6 +1870,27 @@ get_storage_provider (TpSvcDBusProperties *self, g_value_set_static_string (value, ""); } +static gboolean +set_storage_provider (TpSvcDBusProperties *self, + const gchar *name, + const GValue *value, + GError **error) +{ + McdAccount *account = MCD_ACCOUNT (self); + McpAccountStorage *storage_plugin = get_storage_plugin (account); + const gchar *current_provider = mcp_account_storage_provider (storage_plugin); + + if (!G_VALUE_HOLDS_STRING (value) || + tp_strdiff (g_value_get_string (value), current_provider)) + { + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + "Cannot change provider, it is defined at account creation only"); + return FALSE; + } + + return TRUE; +} + static void get_storage_identifier (TpSvcDBusProperties *self, const gchar *name, GValue *value) @@ -1884,7 +1898,7 @@ get_storage_identifier (TpSvcDBusProperties *self, McdAccount *account = MCD_ACCOUNT (self); McpAccountStorage *storage_plugin = get_storage_plugin (account); - GValue identifier = { 0 }; + GValue identifier = G_VALUE_INIT; g_value_init (value, G_TYPE_VALUE); @@ -1973,7 +1987,7 @@ static const McdDBusProp account_avatar_properties[] = { }; static const McdDBusProp account_storage_properties[] = { - { "StorageProvider", NULL, get_storage_provider }, + { "StorageProvider", set_storage_provider, get_storage_provider }, { "StorageIdentifier", NULL, get_storage_identifier }, { "StorageSpecificInformation", NULL, get_storage_specific_info }, { "StorageRestrictions", NULL, get_storage_restrictions }, @@ -2012,7 +2026,7 @@ set_hidden (TpSvcDBusProperties *self, if (!G_VALUE_HOLDS_BOOLEAN (value)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Hidden must be set to a boolean, not a %s", G_VALUE_TYPE_NAME (value)); return FALSE; @@ -2125,7 +2139,7 @@ account_external_password_storage_forget_password ( if (!tp_proxy_has_interface_by_id (cm, MC_IFACE_QUARK_CONNECTION_MANAGER_INTERFACE_ACCOUNT_STORAGE)) { - GError *error = g_error_new (TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + GError *error = g_error_new (TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "CM for this Account does not implement AccountStorage iface"); dbus_g_method_return_error (context, error); @@ -2294,7 +2308,7 @@ mcd_account_property_changed (McdAccount *account, const gchar *name) if (prop->getprop != NULL) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; prop->getprop (self, name, &value); @@ -2337,7 +2351,7 @@ mcd_account_check_parameters (McdAccount *account, if (protocol == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "CM '%s' doesn't implement protocol '%s'", priv->manager_name, priv->protocol_name); goto out; @@ -2350,7 +2364,7 @@ mcd_account_check_parameters (McdAccount *account, if (!mcd_account_get_parameter (account, param->name, NULL, NULL)) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "missing required parameter '%s'", param->name); goto out; } @@ -2452,7 +2466,7 @@ check_one_parameter_update (McdAccount *account, if (param == NULL) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Protocol '%s' does not have parameter '%s'", protocol->name, name); return FALSE; @@ -2463,7 +2477,7 @@ check_one_parameter_update (McdAccount *account, if (G_VALUE_TYPE (new_value) != type) { /* FIXME: use D-Bus type names, not GType names. */ - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "parameter '%s' must be of type %s, not %s", param->name, g_type_name (type), G_VALUE_TYPE_NAME (new_value)); @@ -2473,7 +2487,7 @@ check_one_parameter_update (McdAccount *account, if (mcd_account_get_connection_status (account) == TP_CONNECTION_STATUS_CONNECTED) { - GValue current_value = { 0, }; + GValue current_value = G_VALUE_INIT; /* Check if the parameter's current value (or its default, if it has * one and it's not set to anything) matches the new value. @@ -2519,7 +2533,7 @@ check_one_parameter_unset (McdAccount *account, mcd_account_get_connection_status (account) == TP_CONNECTION_STATUS_CONNECTED) { - GValue current_value = { 0, }; + GValue current_value = G_VALUE_INIT; if (mcd_account_get_parameter (account, param->name, ¤t_value, NULL)) @@ -2527,7 +2541,7 @@ check_one_parameter_unset (McdAccount *account, /* There's an existing value; let's see if it's the same as the * default, if any. */ - GValue default_value = { 0, }; + GValue default_value = G_VALUE_INIT; if (tp_connection_manager_param_get_default (param, &default_value)) { @@ -2618,7 +2632,7 @@ _mcd_account_set_parameters (McdAccount *account, GHashTable *params, * would like to hit this path) yet. So in practice we hit the next * block for nonexistant CMs too. */ - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Manager '%s' not found", priv->manager_name); goto out; } @@ -2627,7 +2641,7 @@ _mcd_account_set_parameters (McdAccount *account, GHashTable *params, if (G_UNLIKELY (protocol == NULL)) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Protocol '%s' not found on CM '%s'", priv->protocol_name, priv->manager_name); goto out; @@ -2665,7 +2679,7 @@ account_update_parameters_cb (McdAccount *account, GPtrArray *not_yet, DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data; const gchar *account_name = mcd_account_get_unique_name (account); GHashTable *params; - GValue value = { 0 }; + GValue value = G_VALUE_INIT; if (error != NULL) { @@ -2704,6 +2718,20 @@ account_update_parameters (TpSvcAccount *self, GHashTable *set, account_update_parameters_cb, context); } +void +_mcd_account_reconnect (McdAccount *self, + gboolean user_initiated) +{ + /* FIXME: this isn't quite right. If we've just called RequestConnection + * (possibly with out of date parameters) but we haven't got a Connection + * back from the CM yet, the old parameters will still be used, I think + * (I can't quite make out what actually happens). */ + if (self->priv->connection) + mcd_connection_close (self->priv->connection); + + _mcd_account_connection_begin (self, user_initiated); +} + static void account_reconnect (TpSvcAccount *service, DBusGMethodInvocation *context) @@ -2727,15 +2755,8 @@ account_reconnect (TpSvcAccount *service, return; } - /* FIXME: this isn't quite right. If we've just called RequestConnection - * (possibly with out of date parameters) but we haven't got a Connection - * back from the CM yet, the old parameters will still be used, I think - * (I can't quite make out what actually happens). */ - if (priv->connection) - mcd_connection_close (priv->connection); - /* Reconnect() counts as user-initiated */ - _mcd_account_connection_begin (self, TRUE); + _mcd_account_reconnect (self, TRUE); /* FIXME: we shouldn't really return from this method until the * reconnection has actually happened, but that would require less tangled @@ -3021,7 +3042,7 @@ _mcd_account_dispose (GObject *object) GError *error; GList *list = priv->online_requests; - error = g_error_new (TP_ERRORS, TP_ERROR_DISCONNECTED, + error = g_error_new (TP_ERROR, TP_ERROR_DISCONNECTED, "Disposing account %s", priv->unique_name); while (list) { @@ -3143,7 +3164,7 @@ mcd_account_class_init (McdAccountClass * klass) G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, - NULL, NULL, _mcd_marshal_VOID__UINT_UINT, + NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); _mcd_account_signals[VALIDITY_CHANGED] = @@ -3154,6 +3175,13 @@ mcd_account_class_init (McdAccountClass * klass) NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + _mcd_account_signals[CONNECTION_PATH_CHANGED] = + g_signal_new ("connection-path-changed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, NULL, g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); _mcd_account_connection_class_init (klass); @@ -3229,13 +3257,6 @@ _mcd_account_get_storage (McdAccount *account) return account->priv->storage; } -TpDBusDaemon * -mcd_account_get_dbus_daemon (McdAccount *account) -{ - return account->priv->dbus_daemon; -} - - /* * mcd_account_is_valid: * @account: the #McdAccount. @@ -3341,7 +3362,7 @@ _mcd_account_dup_parameters (McdAccount *account) for (param = protocol->params; param->name != NULL; param++) { - GValue v = { 0, }; + GValue v = G_VALUE_INIT; if (mcd_account_get_parameter (account, param->name, &v, NULL)) { @@ -3382,7 +3403,7 @@ mcd_account_update_self_presence (McdAccount *account, { McdAccountPrivate *priv = account->priv; gboolean changed = FALSE; - GValue value = { 0 }; + GValue value = G_VALUE_INIT; if (priv->curr_presence_type != presence) { @@ -3473,13 +3494,6 @@ mcd_account_get_current_presence (McdAccount *account, *message = priv->curr_presence_message; } -gboolean -mcd_account_get_connect_automatically (McdAccount *account) -{ - McdAccountPrivate *priv = MCD_ACCOUNT_PRIV (account); - return priv->connect_automatically; -} - /* * mcd_account_would_like_to_connect: * @account: an account @@ -3527,25 +3541,6 @@ mcd_account_would_like_to_connect (McdAccount *account) } /* TODO: remove when the relative members will become public */ -void -mcd_account_get_automatic_presence (McdAccount *account, - TpConnectionPresenceType *presence, - const gchar **status, - const gchar **message) -{ - McdAccountPrivate *priv = account->priv; - - if (presence != NULL) - *presence = priv->auto_presence_type; - - if (status != NULL) - *status = priv->auto_presence_status; - - if (message != NULL) - *message = priv->auto_presence_message; -} - -/* TODO: remove when the relative members will become public */ const gchar * mcd_account_get_manager_name (McdAccount *account) { @@ -3586,7 +3581,7 @@ void _mcd_account_set_normalized_name (McdAccount *account, const gchar *name) { McdAccountPrivate *priv = account->priv; - GValue value = { 0, }; + GValue value = G_VALUE_INIT; const gchar *account_name = mcd_account_get_unique_name (account); DEBUG ("called (%s)", name); @@ -3605,17 +3600,6 @@ _mcd_account_set_normalized_name (McdAccount *account, const gchar *name) g_value_unset (&value); } -gchar * -mcd_account_get_normalized_name (McdAccount *account) -{ - McdAccountPrivate *priv = account->priv; - const gchar *account_name = mcd_account_get_unique_name (account); - - return mcd_storage_dup_string (priv->storage, - account_name, - MC_ACCOUNTS_KEY_NORMALIZED_NAME); -} - void _mcd_account_set_avatar_token (McdAccount *account, const gchar *token) { @@ -3717,6 +3701,8 @@ _mcd_account_set_avatar (McdAccount *account, const GArray *avatar, return TRUE; } +static gchar *_mcd_account_get_avatar_filename (McdAccount *account); + void _mcd_account_get_avatar (McdAccount *account, GArray **avatar, gchar **mime_type) @@ -3770,7 +3756,7 @@ mcd_account_connection_self_nickname_changed_cb (McdAccount *account, const gchar *alias, McdConnection *connection) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; g_value_init (&value, G_TYPE_STRING); g_value_set_static_string (&value, alias); @@ -3778,7 +3764,7 @@ mcd_account_connection_self_nickname_changed_cb (McdAccount *account, g_value_unset (&value); } -gchar * +static gchar * mcd_account_get_alias (McdAccount *account) { McdAccountPrivate *priv = MCD_ACCOUNT_PRIV (account); @@ -3823,7 +3809,7 @@ process_online_requests (McdAccount *account, error = NULL; break; case TP_CONNECTION_STATUS_DISCONNECTED: - error = g_error_new (TP_ERRORS, TP_ERROR_DISCONNECTED, + error = g_error_new (TP_ERROR, TP_ERROR_DISCONNECTED, "Account %s disconnected with reason %d", priv->unique_name, reason); break; @@ -3866,7 +3852,7 @@ clear_register (McdAccount *self) if (tp_asv_get_boolean (params, "register", NULL)) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; const gchar *account_name = mcd_account_get_unique_name (self); _mcd_account_set_parameter (self, "register", NULL); @@ -3975,7 +3961,7 @@ _mcd_account_set_connection_status (McdAccount *account, if (changed) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; _mcd_account_tp_connection_changed (account, priv->tp_connection); @@ -4016,18 +4002,14 @@ mcd_account_get_connection_status (McdAccount *account) return priv->conn_status; } -TpConnectionStatusReason -mcd_account_get_connection_status_reason (McdAccount *account) -{ - McdAccountPrivate *priv = MCD_ACCOUNT_PRIV (account); - return priv->conn_reason; -} - +/* FIXME: if this was only called from _mcd_account_set_connection_status, + * we could combine CONNECTION_STATUS_CHANGED and CONNECTION_PATH_CHANGED + * into one signal... but for now, this is also called from McdConnection */ void _mcd_account_tp_connection_changed (McdAccount *account, TpConnection *tp_conn) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH); @@ -4041,9 +4023,10 @@ _mcd_account_tp_connection_changed (McdAccount *account, } mcd_account_changed_property (account, "Connection", &value); - g_value_unset (&value); - _mcd_storage_store_connections (account->priv->storage); + g_signal_emit (account, _mcd_account_signals[CONNECTION_PATH_CHANGED], 0, + g_value_get_boxed (&value)); + g_value_unset (&value); } McdConnection * @@ -4077,7 +4060,7 @@ check_validity_check_parameters_cb (McdAccount *account, if (was_valid != now_valid) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; DEBUG ("Account validity changed (old: %d, new: %d)", was_valid, now_valid); g_signal_emit (account, _mcd_account_signals[VALIDITY_CHANGED], 0, @@ -4180,7 +4163,7 @@ _mcd_account_online_request (McdAccount *account, if (priv->loaded && !mcd_account_is_valid (account)) { /* FIXME: pick a better error and put it in telepathy-spec? */ - GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "account isn't Valid (not enough information to put it online)" }; DEBUG ("%s: %s", priv->unique_name, e.message); @@ -4191,7 +4174,7 @@ _mcd_account_online_request (McdAccount *account, if (priv->loaded && !priv->enabled) { /* FIXME: pick a better error and put it in telepathy-spec? */ - GError e = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "account isn't Enabled" }; DEBUG ("%s: %s", priv->unique_name, e.message); @@ -4219,8 +4202,7 @@ _mcd_account_get_keyfile (McdAccount *account) return priv->keyfile; } -/* this is public because of mcd-account-compat */ -gchar * +static gchar * _mcd_account_get_avatar_filename (McdAccount *account) { McdAccountPrivate *priv = account->priv; @@ -4234,35 +4216,13 @@ _mcd_account_get_avatar_filename (McdAccount *account) } static void -mcd_account_self_handle_inspected_cb (TpConnection *connection, - const gchar **names, - const GError *error, - gpointer user_data, - GObject *weak_object) -{ - McdAccount *self = MCD_ACCOUNT (weak_object); - - if (error) - { - g_warning ("%s: InspectHandles failed: %s", G_STRFUNC, error->message); - return; - } - - if (names != NULL && names[0] != NULL) - { - _mcd_account_set_normalized_name (self, names[0]); - } -} - -static void mcd_account_connection_ready_cb (McdAccount *account, McdConnection *connection) { McdAccountPrivate *priv = account->priv; gchar *nickname; TpConnection *tp_connection; - GArray *self_handle_array; - guint self_handle; + TpContact *self_contact; TpConnectionStatus status; TpConnectionStatusReason reason; const gchar *dbus_error = NULL; @@ -4275,22 +4235,18 @@ mcd_account_connection_ready_cb (McdAccount *account, g_return_if_fail (tp_connection != NULL); g_return_if_fail (priv->tp_connection == NULL || tp_connection == priv->tp_connection); + g_assert (tp_proxy_is_prepared (tp_connection, + TP_CONNECTION_FEATURE_CONNECTED)); status = tp_connection_get_status (tp_connection, &reason); dbus_error = tp_connection_get_detailed_error (tp_connection, &details); _mcd_account_set_connection_status (account, status, reason, tp_connection, dbus_error, details); - self_handle_array = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1); - self_handle = tp_connection_get_self_handle (tp_connection); - g_array_append_val (self_handle_array, self_handle); - tp_cli_connection_call_inspect_handles (tp_connection, -1, - TP_HANDLE_TYPE_CONTACT, - self_handle_array, - mcd_account_self_handle_inspected_cb, - NULL, NULL, - (GObject *) account); - g_array_unref (self_handle_array); + self_contact = tp_connection_get_self_contact (tp_connection); + g_assert (self_contact != NULL); + _mcd_account_set_normalized_name (account, tp_contact_get_identifier ( + self_contact)); /* FIXME: ideally, on protocols with server-stored nicknames, this should * only be done if the local Nickname has been changed since last time we @@ -4390,7 +4346,7 @@ _mcd_account_set_has_been_online (McdAccount *account) { if (!account->priv->has_been_online) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; const gchar *account_name = mcd_account_get_unique_name (account); g_value_init (&value, G_TYPE_BOOLEAN); @@ -4408,20 +4364,6 @@ _mcd_account_set_has_been_online (McdAccount *account) } } -void -_mcd_account_request_temporary_presence (McdAccount *self, - TpConnectionPresenceType type, - const gchar *status) -{ - if (self->priv->connection != NULL) - { - _mcd_account_set_changing_presence (self, TRUE); - - _mcd_connection_request_presence (self->priv->connection, - type, status, ""); - } -} - /** * mcd_account_connection_bind_transport: * @account: the #McdAccount. @@ -4527,7 +4469,7 @@ void _mcd_account_set_changing_presence (McdAccount *self, gboolean value) { McdAccountPrivate *priv = self->priv; - GValue changing_presence = { 0 }; + GValue changing_presence = G_VALUE_INIT; priv->changing_presence = value; diff --git a/src/mcd-account.h b/src/mcd-account.h index 90e429af..458287ee 100644 --- a/src/mcd-account.h +++ b/src/mcd-account.h @@ -24,8 +24,7 @@ #ifndef __MCD_ACCOUNT_H__ #define __MCD_ACCOUNT_H__ -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/enums.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS #define MCD_TYPE_ACCOUNT (mcd_account_get_type ()) @@ -83,8 +82,6 @@ GType mcd_account_get_type (void); McdAccount *mcd_account_new (McdAccountManager *account_manager, const gchar *name); -TpDBusDaemon *mcd_account_get_dbus_daemon (McdAccount *account); - void mcd_account_delete (McdAccount *account, McdAccountDeleteCb callback, gpointer user_data); @@ -118,19 +115,9 @@ void mcd_account_get_requested_presence (McdAccount *account, const gchar **status, const gchar **message); -gboolean mcd_account_get_connect_automatically (McdAccount *account); gboolean mcd_account_would_like_to_connect (McdAccount *account); -void mcd_account_get_automatic_presence (McdAccount *account, - TpConnectionPresenceType *presence, - const gchar **status, - const gchar **message); - -gchar *mcd_account_get_normalized_name (McdAccount *account); - -gchar *mcd_account_get_alias (McdAccount *account); TpConnectionStatus mcd_account_get_connection_status (McdAccount *account); -TpConnectionStatusReason mcd_account_get_connection_status_reason (McdAccount *account); McdConnection *mcd_account_get_connection (McdAccount *account); diff --git a/src/mcd-channel.c b/src/mcd-channel.c index 64d12a4d..3d6b0660 100644 --- a/src/mcd-channel.c +++ b/src/mcd-channel.c @@ -35,14 +35,12 @@ * FIXME */ +#include "config.h" + #include "mcd-channel.h" -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/svc-channel-request.h> -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "channel-utils.h" #include "mcd-account-priv.h" @@ -65,9 +63,6 @@ struct _McdChannelPrivate /* boolean properties */ guint outgoing : 1; - guint has_group_if : 1; - guint members_accepted : 1; - guint missed : 1; guint is_disposed : 1; guint is_aborted : 1; guint constructing : 1; @@ -110,67 +105,6 @@ static void on_proxied_channel_status_changed (McdChannel *source, McdChannel *dest); static void -on_members_changed (TpChannel *proxy, const gchar *message, - const GArray *added, const GArray *removed, - const GArray *l_pending, const GArray *r_pending, - guint actor, guint reason, McdChannel *channel) -{ - McdChannelPrivate *priv = channel->priv; - TpHandle self_handle; - TpHandle conn_self_handle = 0; - TpHandle removed_handle = 0; - guint i; - - self_handle = tp_channel_group_get_self_handle (proxy); - conn_self_handle = - tp_connection_get_self_handle (tp_channel_borrow_connection (proxy)); - - DEBUG ("called (actor %u, reason %u, self_handle %u, conn_self_handle %u)", - actor, reason, tp_channel_group_get_self_handle (proxy), - conn_self_handle); - - if (added && added->len > 0) - { - DEBUG ("%u added members", added->len); - for (i = 0; i < added->len; i++) - { - guint added_member = g_array_index (added, guint, i); - DEBUG ("added member %u", added_member); - - /* see whether we are the added member */ - if (added_member == self_handle) - { - DEBUG ("This should appear only when the call was accepted"); - priv->members_accepted = TRUE; - g_signal_emit_by_name (channel, "members-accepted"); - break; - } - } - } - - if (removed && removed->len > 0 && - (actor == 0 || - reason == TP_CHANNEL_GROUP_CHANGE_REASON_ERROR || - (actor != self_handle && actor != conn_self_handle) || - reason == TP_CHANNEL_GROUP_CHANGE_REASON_NO_ANSWER)) - { - for (i = 0; i < removed->len; i++) - { - removed_handle = g_array_index (removed, guint, i); - DEBUG ("removed member %u", removed_handle); - if (removed_handle == self_handle || - removed_handle == conn_self_handle) - { - /* We are removed (end of call), marking as missed, if not - * already accespted the call */ - if (!priv->members_accepted) priv->missed = TRUE; - break; - } - } - } -} - -static void proxy_destroyed (TpProxy *self, guint domain, gint code, gchar *message, gpointer user_data) { @@ -181,21 +115,21 @@ proxy_destroyed (TpProxy *self, guint domain, gint code, gchar *message, mcd_mission_abort (MCD_MISSION (channel)); } -static inline void -_mcd_channel_setup_group (McdChannel *channel) -{ - McdChannelPrivate *priv = channel->priv; - - g_signal_connect (priv->tp_chan, "group-members-changed", - G_CALLBACK (on_members_changed), channel); -} - static void -on_channel_ready (TpChannel *tp_chan, const GError *error, gpointer user_data) +on_channel_ready (GObject *source_object, GAsyncResult *result, gpointer user_data) { + TpChannel *tp_chan = TP_CHANNEL (source_object); McdChannel *channel, **channel_ptr = user_data; McdChannelPrivate *priv; gboolean requested, valid; + GError *error = NULL; + + if (!tp_proxy_prepare_finish (tp_chan, result, &error)) + { + DEBUG ("failed to prepare channel: %s", error->message); + g_clear_error (&error); + return; + } channel = *channel_ptr; if (channel) @@ -217,11 +151,6 @@ on_channel_ready (TpChannel *tp_chan, const GError *error, gpointer user_data) TP_IFACE_CHANNEL ".Requested", &valid); if (valid) priv->outgoing = requested; - - priv->has_group_if = tp_proxy_has_interface_by_id (priv->tp_chan, - TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP); - if (priv->has_group_if) - _mcd_channel_setup_group (channel); } void @@ -275,9 +204,6 @@ _mcd_channel_release_tp_channel (McdChannel *channel) McdChannelPrivate *priv = MCD_CHANNEL_PRIV (channel); if (priv->tp_chan) { - g_signal_handlers_disconnect_by_func (G_OBJECT (priv->tp_chan), - G_CALLBACK (on_members_changed), - channel); g_signal_handlers_disconnect_by_func (G_OBJECT (priv->tp_chan), G_CALLBACK (proxy_destroyed), channel); @@ -296,7 +222,7 @@ _mcd_channel_setup (McdChannel *channel, McdChannelPrivate *priv) channel_ptr = g_slice_alloc (sizeof (McdChannel *)); *channel_ptr = channel; g_object_add_weak_pointer ((GObject *)channel, (gpointer)channel_ptr); - tp_channel_call_when_ready (priv->tp_chan, on_channel_ready, channel_ptr); + tp_proxy_prepare_async (priv->tp_chan, NULL, on_channel_ready, channel_ptr); g_signal_connect (priv->tp_chan, "invalidated", G_CALLBACK (proxy_destroyed), channel); @@ -498,7 +424,7 @@ mcd_channel_abort (McdMission *mission) /* this code-path can only happen if the connection is aborted, as in * the other cases we handle the error in McdChannel; for this reason, * we use the DISCONNECTED error code */ - GError *error = g_error_new (TP_ERRORS, TP_ERROR_DISCONNECTED, + GError *error = g_error_new (TP_ERROR, TP_ERROR_DISCONNECTED, "Channel aborted"); mcd_channel_take_error (channel, error); } @@ -553,7 +479,7 @@ mcd_channel_status_changed (McdChannel *channel, McdChannelStatus status) g_critical ("Requested channel's status changed to FAILED " "without a proper error"); _mcd_request_set_failure (channel->priv->request, - TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + TP_ERROR, TP_ERROR_NOT_AVAILABLE, "MC bug! FAILED but no error"); } } @@ -593,14 +519,6 @@ mcd_channel_class_init (McdChannelClass * klass) status_changed_signal), NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); - mcd_channel_signals[MEMBERS_ACCEPTED] = - g_signal_new ("members-accepted", G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (McdChannelClass, - members_accepted_signal), - NULL, - NULL, g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); /* properties */ g_object_class_install_property @@ -739,9 +657,9 @@ mcd_channel_new_from_path (TpConnection *connection, const gchar *object_path, TpHandleType handle_type) { GHashTable *props; - GValue v_type = { 0 }; - GValue v_handle = { 0 }; - GValue v_handle_type = { 0 }; + GValue v_type = G_VALUE_INIT; + GValue v_handle = G_VALUE_INIT; + GValue v_handle_type = G_VALUE_INIT; McdChannel *channel; props = g_hash_table_new (g_str_hash, g_str_equal); @@ -826,40 +744,6 @@ mcd_channel_get_status (McdChannel *channel) return MCD_CHANNEL_PRIV (channel)->status; } -gboolean -mcd_channel_get_members_accepted (McdChannel *channel) -{ - return MCD_CHANNEL_PRIV (channel)->members_accepted; -} - -const gchar * -mcd_channel_get_channel_type (McdChannel *channel) -{ - return g_quark_to_string (mcd_channel_get_channel_type_quark (channel)); -} - -GQuark -mcd_channel_get_channel_type_quark (McdChannel *channel) -{ - McdChannelPrivate *priv; - - g_return_val_if_fail (MCD_IS_CHANNEL (channel), 0); - priv = channel->priv; - if (priv->tp_chan) - return tp_channel_get_channel_type_id (priv->tp_chan); - - if (G_LIKELY (priv->request != NULL)) - { - GHashTable *properties = _mcd_request_get_properties (priv->request); - const gchar *type = tp_asv_get_string (properties, - TP_IFACE_CHANNEL ".ChannelType"); - - return g_quark_from_string (type); - } - - return 0; -} - const gchar * mcd_channel_get_object_path (McdChannel *channel) { @@ -868,120 +752,6 @@ mcd_channel_get_object_path (McdChannel *channel) return priv->tp_chan ? TP_PROXY (priv->tp_chan)->object_path : NULL; } -guint -mcd_channel_get_handle (McdChannel *channel) -{ - McdChannelPrivate *priv; - - g_return_val_if_fail (MCD_IS_CHANNEL (channel), 0); - priv = channel->priv; - if (priv->tp_chan) - return tp_channel_get_handle (priv->tp_chan, NULL); - - if (G_LIKELY (priv->request != NULL)) - { - GHashTable *properties = _mcd_request_get_properties (priv->request); - - return tp_asv_get_uint32 (properties, - TP_IFACE_CHANNEL ".TargetHandle", NULL); - } - - return 0; -} - -TpHandleType -mcd_channel_get_handle_type (McdChannel *channel) -{ - McdChannelPrivate *priv; - guint handle_type = TP_HANDLE_TYPE_NONE; - - g_return_val_if_fail (MCD_IS_CHANNEL (channel), 0); - priv = channel->priv; - if (priv->tp_chan) - { - tp_channel_get_handle (priv->tp_chan, &handle_type); - } - else if (G_LIKELY (priv->request != NULL)) - { - GHashTable *properties = _mcd_request_get_properties (priv->request); - - handle_type = tp_asv_get_uint32 (properties, - TP_IFACE_CHANNEL ".TargetHandle", NULL); - } - - return handle_type; -} - -/** - * mcd_channel_get_name: - * @channel: the #McdChannel. - * - * Get the Telepathy name of @channel (calls InspectHandles on the channel - * handle). - * - * Returns: a const string holding the channel name. - */ -const gchar * -mcd_channel_get_name (McdChannel *channel) -{ - McdChannelPrivate *priv; - GHashTable *properties = NULL; - - g_return_val_if_fail (MCD_IS_CHANNEL (channel), NULL); - priv = channel->priv; - - if (priv->tp_chan) - properties = tp_channel_borrow_immutable_properties (priv->tp_chan); - else if (G_LIKELY (priv->request != NULL)) - properties = _mcd_request_get_properties (priv->request); - - if (!properties) return NULL; - - return tp_asv_get_string (properties, TP_IFACE_CHANNEL ".TargetID"); -} - -/** - * mcd_channel_get_inviter: - * @channel: the #McdChannel. - * - * Get the address of the inviter (i.e. the actor who put us in the pending - * local members list). - * - * Returns: a const string holding the inviter address. - */ -const gchar * -mcd_channel_get_inviter (McdChannel *channel) -{ - McdChannelPrivate *priv; - GHashTable *properties = NULL; - - g_return_val_if_fail (MCD_IS_CHANNEL (channel), NULL); - priv = channel->priv; - if (priv->tp_chan) - { - properties = tp_channel_borrow_immutable_properties (priv->tp_chan); - if (properties) - return tp_asv_get_string (properties, - TP_IFACE_CHANNEL ".InitiatorID"); - } - return NULL; -} - -/** - * mcd_channel_is_missed: - * @channel: the #McdChannel. - * - * Return %TRUE if the remote party removed itself before we could join the - * channel. - * - * Returns: %TRUE if the channel is missed. - */ -gboolean -mcd_channel_is_missed (McdChannel *channel) -{ - return MCD_CHANNEL_PRIV (channel)->missed; -} - /* * _mcd_channel_get_immutable_properties: * @channel: the #McdChannel. @@ -1069,7 +839,7 @@ _mcd_channel_request_cancelling_cb (McdRequest *request, g_object_ref (self); DEBUG ("%p in status %u", self, status); - mcd_channel_take_error (self, g_error_new (TP_ERRORS, + mcd_channel_take_error (self, g_error_new (TP_ERROR, TP_ERROR_CANCELLED, "Cancelled")); @@ -1389,18 +1159,21 @@ typedef struct { } DepartData; static void -mcd_channel_ready_to_depart_cb (TpChannel *channel, - const GError *error, +mcd_channel_ready_to_depart_cb (GObject *source_object, + GAsyncResult *result, gpointer data) { + TpChannel *channel = TP_CHANNEL (source_object); DepartData *d = data; + GError *error = NULL; - if (error != NULL) + if (!tp_proxy_prepare_finish (channel, result, &error)) { DEBUG ("%s %d: %s", g_quark_to_string (error->domain), error->code, error->message); g_free (d->message); g_slice_free (DepartData, d); + g_clear_error (&error); return; } @@ -1456,8 +1229,8 @@ _mcd_channel_depart (McdChannel *channel, d->reason = reason; d->message = g_strdup (message); - tp_channel_call_when_ready (channel->priv->tp_chan, - mcd_channel_ready_to_depart_cb, d); + tp_proxy_prepare_async (channel->priv->tp_chan, NULL, + mcd_channel_ready_to_depart_cb, d); } /* diff --git a/src/mcd-channel.h b/src/mcd-channel.h index 53819ebc..cdfac247 100644 --- a/src/mcd-channel.h +++ b/src/mcd-channel.h @@ -29,8 +29,7 @@ #include <glib.h> #include <glib-object.h> -#include <telepathy-glib/channel.h> -#include <telepathy-glib/dbus-properties-mixin.h> +#include <telepathy-glib/telepathy-glib.h> #include "mcd-mission.h" @@ -80,7 +79,7 @@ struct _McdChannelClass /* signals */ void (*status_changed_signal) (McdChannel * channel, McdChannelStatus status); - void (*members_accepted_signal) (McdChannel *channel); + void (*_former_members_accepted_signal) (void); TpDBusPropertiesMixinClass _former_dbus_properties_class; void (*_mc_reserved1) (void); void (*_mc_reserved2) (void); @@ -101,15 +100,7 @@ McdChannel *mcd_channel_new_from_path (TpConnection *connection, TpHandleType handle_type); McdChannelStatus mcd_channel_get_status (McdChannel * channel); -gboolean mcd_channel_get_members_accepted (McdChannel *channel); -const gchar* mcd_channel_get_channel_type (McdChannel *channel); -GQuark mcd_channel_get_channel_type_quark (McdChannel *channel); const gchar* mcd_channel_get_object_path (McdChannel *channel); -guint mcd_channel_get_handle (McdChannel *channel); -TpHandleType mcd_channel_get_handle_type (McdChannel *channel); -const gchar *mcd_channel_get_name (McdChannel *channel); -const gchar *mcd_channel_get_inviter (McdChannel *channel); -gboolean mcd_channel_is_missed (McdChannel *channel); gboolean mcd_channel_is_requested (McdChannel *channel); McdAccount *mcd_channel_get_account (McdChannel *channel); TpChannel *mcd_channel_get_tp_channel (McdChannel *channel); diff --git a/src/mcd-client-priv.h b/src/mcd-client-priv.h index f20f9e99..00b5f32e 100644 --- a/src/mcd-client-priv.h +++ b/src/mcd-client-priv.h @@ -29,9 +29,7 @@ #include <glib.h> #include <glib-object.h> -#include <telepathy-glib/channel.h> -#include <telepathy-glib/client.h> -#include <telepathy-glib/handle-repo.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS @@ -69,8 +67,9 @@ G_GNUC_INTERNAL GType _mcd_client_proxy_get_type (void); McdClientProxyClass)) G_GNUC_INTERNAL McdClientProxy *_mcd_client_proxy_new ( - TpDBusDaemon *dbus_daemon, TpHandleRepoIface *string_pool, - const gchar *well_known_name, const gchar *unique_name_if_known, + TpDBusDaemon *dbus_daemon, + const gchar *well_known_name, + const gchar *unique_name_if_known, gboolean activatable); G_GNUC_INTERNAL gboolean _mcd_client_proxy_is_ready (McdClientProxy *self); diff --git a/src/mcd-client.c b/src/mcd-client.c index fceba819..7cb9e8a3 100644 --- a/src/mcd-client.c +++ b/src/mcd-client.c @@ -28,13 +28,10 @@ #include <errno.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/defs.h> -#include <telepathy-glib/errors.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> + #include <telepathy-glib/proxy-subclass.h> -#include <telepathy-glib/util.h> #include "channel-utils.h" #include "mcd-channel-priv.h" @@ -64,10 +61,7 @@ static guint signals[N_SIGNALS] = { 0 }; struct _McdClientProxyPrivate { - TpHandleRepoIface *string_pool; - /* Handler.Capabilities, represented as handles taken from - * dispatcher->priv->string_pool */ - TpHandleSet *capability_tokens; + GStrv capability_tokens; gchar *unique_name; guint ready_lock; @@ -330,8 +324,8 @@ parse_client_filter (GKeyFile *file, const gchar *group) return filter; } -static void _mcd_client_proxy_add_cap_tokens (McdClientProxy *self, - const gchar * const *cap_tokens); +static void _mcd_client_proxy_set_cap_tokens (McdClientProxy *self, + GStrv cap_tokens); static void _mcd_client_proxy_add_interfaces (McdClientProxy *self, const gchar * const *interfaces); @@ -422,8 +416,7 @@ parse_client_file (McdClientProxy *client, TP_IFACE_CLIENT_HANDLER ".Capabilities", NULL, NULL); - _mcd_client_proxy_add_cap_tokens (client, - (const gchar * const *) cap_tokens); + _mcd_client_proxy_set_cap_tokens (client, cap_tokens); g_strfreev (cap_tokens); } @@ -522,22 +515,11 @@ _mcd_client_proxy_set_filters (McdClientProxy *client, /* This is NULL-safe for the last argument, for ease of use with * tp_asv_get_boxed */ static void -_mcd_client_proxy_add_cap_tokens (McdClientProxy *self, - const gchar * const *cap_tokens) +_mcd_client_proxy_set_cap_tokens (McdClientProxy *self, + GStrv cap_tokens) { - guint i; - - if (cap_tokens == NULL) - return; - - for (i = 0; cap_tokens[i] != NULL; i++) - { - TpHandle handle = tp_handle_ensure (self->priv->string_pool, - cap_tokens[i], NULL, NULL); - - tp_handle_set_add (self->priv->capability_tokens, handle); - tp_handle_unref (self->priv->string_pool, handle); - } + g_strfreev (self->priv->capability_tokens); + self->priv->capability_tokens = g_strdupv (cap_tokens); } static void @@ -691,7 +673,7 @@ _mcd_client_proxy_handler_get_all_cb (TpProxy *proxy, * any capabilities */ if (self->priv->unique_name[0] != '\0' || self->priv->activatable) { - _mcd_client_proxy_add_cap_tokens (self, + _mcd_client_proxy_set_cap_tokens (self, tp_asv_get_boxed (properties, "Capabilities", G_TYPE_STRV)); g_signal_emit (self, signals[S_HANDLER_CAPABILITIES_CHANGED], 0); } @@ -1023,16 +1005,7 @@ mcd_client_proxy_dispose (GObject *object) mcd_client_proxy_unique_name_cb, self); - if (self->priv->string_pool != NULL) - { - if (self->priv->capability_tokens != NULL) - { - tp_handle_set_destroy (self->priv->capability_tokens); - self->priv->capability_tokens = NULL; - } - - tp_clear_object (&self->priv->string_pool); - } + tp_clear_pointer (&self->priv->capability_tokens, g_strfreev); if (chain_up != NULL) { @@ -1074,8 +1047,7 @@ mcd_client_proxy_constructed (GObject *object) bus_name = tp_proxy_get_bus_name (self); - self->priv->capability_tokens = tp_handle_set_new ( - self->priv->string_pool); + self->priv->capability_tokens = NULL; DEBUG ("%s", bus_name); @@ -1109,11 +1081,6 @@ mcd_client_proxy_set_property (GObject *object, self->priv->activatable = g_value_get_boolean (value); break; - case PROP_STRING_POOL: - g_assert (self->priv->string_pool == NULL); - self->priv->string_pool = g_value_dup_object (value); - break; - case PROP_UNIQUE_NAME: g_assert (self->priv->unique_name == NULL); self->priv->unique_name = g_value_dup_string (value); @@ -1179,14 +1146,6 @@ _mcd_client_proxy_class_init (McdClientProxyClass *klass) "TRUE if this client can be service-activated", FALSE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, PROP_STRING_POOL, - g_param_spec_object ("string-pool", "String pool", - "TpHandleRepoIface used to intern strings representing capability " - "tokens", - G_TYPE_OBJECT, - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, PROP_UNIQUE_NAME, g_param_spec_string ("unique-name", "Unique name", "The D-Bus unique name of this client, \"\" if not running or " @@ -1205,7 +1164,7 @@ _mcd_client_check_valid_name (const gchar *name_suffix, if (!g_ascii_isalpha (*name_suffix)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Client names must start with a letter"); return FALSE; } @@ -1214,7 +1173,7 @@ _mcd_client_check_valid_name (const gchar *name_suffix, { if (i > (255 - MC_CLIENT_BUS_NAME_BASE_LEN)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Client name too long"); } @@ -1227,7 +1186,7 @@ _mcd_client_check_valid_name (const gchar *name_suffix, { if (name_suffix[i-1] == '.') { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Client names must not have a digit or dot " "following a dot"); return FALSE; @@ -1235,7 +1194,7 @@ _mcd_client_check_valid_name (const gchar *name_suffix, } else { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Client names must not contain '%c'", name_suffix[i]); return FALSE; } @@ -1243,7 +1202,7 @@ _mcd_client_check_valid_name (const gchar *name_suffix, if (name_suffix[i-1] == '.') { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Client names must not end with a dot"); return FALSE; } @@ -1253,7 +1212,6 @@ _mcd_client_check_valid_name (const gchar *name_suffix, McdClientProxy * _mcd_client_proxy_new (TpDBusDaemon *dbus_daemon, - TpHandleRepoIface *string_pool, const gchar *well_known_name, const gchar *unique_name_if_known, gboolean activatable) @@ -1278,7 +1236,6 @@ _mcd_client_proxy_new (TpDBusDaemon *dbus_daemon, self = g_object_new (MCD_TYPE_CLIENT_PROXY, "dbus-daemon", dbus_daemon, - "string-pool", string_pool, "object-path", object_path, "bus-name", well_known_name, "unique-name", unique_name_if_known, @@ -1430,15 +1387,18 @@ _mcd_client_proxy_get_delay_approvers (McdClientProxy *self) static void _mcd_client_proxy_become_incapable (McdClientProxy *self) { - gboolean handler_was_capable = (self->priv->handler_filters != NULL || - tp_handle_set_size (self->priv->capability_tokens) > 0); + gboolean handler_was_capable = (self->priv->handler_filters != NULL); + + if (self->priv->capability_tokens != NULL && + self->priv->capability_tokens[0] != NULL) + { + handler_was_capable = TRUE; + } _mcd_client_proxy_take_approver_filters (self, NULL); _mcd_client_proxy_take_observer_filters (self, NULL); _mcd_client_proxy_take_handler_filters (self, NULL); - tp_handle_set_destroy (self->priv->capability_tokens); - self->priv->capability_tokens = tp_handle_set_new ( - self->priv->string_pool); + tp_clear_pointer (&self->priv->capability_tokens, g_strfreev); if (handler_was_capable) { @@ -1446,29 +1406,14 @@ _mcd_client_proxy_become_incapable (McdClientProxy *self) } } -typedef struct { - TpHandleRepoIface *repo; - GPtrArray *array; -} TokenAppendContext; - -static void -append_token_to_ptrs (TpHandleSet *unused G_GNUC_UNUSED, - TpHandle handle, - gpointer data) -{ - TokenAppendContext *context = data; - - g_ptr_array_add (context->array, - g_strdup (tp_handle_inspect (context->repo, handle))); -} - GValueArray * _mcd_client_proxy_dup_handler_capabilities (McdClientProxy *self) { GPtrArray *filters; - GPtrArray *cap_tokens; + GStrv cap_tokens; GValueArray *va; const GList *list; + gchar *empty_strv[] = { NULL }; g_return_val_if_fail (MCD_IS_CLIENT_PROXY (self), NULL); @@ -1486,22 +1431,10 @@ _mcd_client_proxy_dup_handler_capabilities (McdClientProxy *self) g_ptr_array_add (filters, copy); } - if (self->priv->capability_tokens == NULL) - { - cap_tokens = g_ptr_array_sized_new (1); - } - else - { - TokenAppendContext context = { self->priv->string_pool, NULL }; - - cap_tokens = g_ptr_array_sized_new ( - tp_handle_set_size (self->priv->capability_tokens) + 1); - context.array = cap_tokens; - tp_handle_set_foreach (self->priv->capability_tokens, - append_token_to_ptrs, &context); - } + cap_tokens = self->priv->capability_tokens; - g_ptr_array_add (cap_tokens, NULL); + if (cap_tokens == NULL) + cap_tokens = empty_strv; if (DEBUGGING) { @@ -1510,11 +1443,11 @@ _mcd_client_proxy_dup_handler_capabilities (McdClientProxy *self) DEBUG ("%s:", tp_proxy_get_bus_name (self)); DEBUG ("- %u channel filters", filters->len); - DEBUG ("- %u capability tokens:", cap_tokens->len - 1); + DEBUG ("- %u capability tokens:", g_strv_length (cap_tokens)); - for (i = 0; i < cap_tokens->len - 1; i++) + for (i = 0; cap_tokens[i] != NULL; i++) { - DEBUG (" %s", (gchar *) g_ptr_array_index (cap_tokens, i)); + DEBUG (" %s", cap_tokens[i]); } DEBUG ("-end-"); @@ -1531,7 +1464,7 @@ _mcd_client_proxy_dup_handler_capabilities (McdClientProxy *self) g_value_set_string (va->values + 0, tp_proxy_get_bus_name (self)); g_value_take_boxed (va->values + 1, filters); - g_value_take_boxed (va->values + 2, g_ptr_array_free (cap_tokens, FALSE)); + g_value_set_boxed (va->values + 2, cap_tokens); return va; } diff --git a/src/mcd-connection-plugin.h b/src/mcd-connection-plugin.h index 748d9390..3ab255b5 100644 --- a/src/mcd-connection-plugin.h +++ b/src/mcd-connection-plugin.h @@ -28,15 +28,12 @@ #include <glib.h> #include <glib-object.h> -#include "mcd-plugin.h" #include "mcd-transport.h" -#include <telepathy-glib/enums.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS -typedef void (*McdAccountConnectionFunc) (McdAccount *account, GHashTable *parameters, gpointer userdata); - void mcd_account_connection_proceed (McdAccount *account, gboolean success); void mcd_account_connection_proceed_with_reason (McdAccount *account, gboolean success, TpConnectionStatusReason reason); @@ -48,11 +45,6 @@ gboolean mcd_account_connection_is_user_initiated (McdAccount *account); #define MCD_ACCOUNT_CONNECTION_PRIORITY_TRANSPORT 20000 #define MCD_ACCOUNT_CONNECTION_PRIORITY_PARAMS 30000 -void mcd_plugin_register_account_connection (McdPlugin *plugin, - McdAccountConnectionFunc func, - gint priority, - gpointer userdata); - G_END_DECLS #endif /* __MCD_CONNECTION_PLUGIN_H__ */ diff --git a/src/mcd-connection-priv.h b/src/mcd-connection-priv.h index be811e15..4aefa632 100644 --- a/src/mcd-connection-priv.h +++ b/src/mcd-connection-priv.h @@ -62,7 +62,7 @@ G_GNUC_INTERNAL void _mcd_connection_take_emergency_numbers (McdConnection *self GSList *numbers); G_GNUC_INTERNAL void _mcd_connection_take_emergency_handles (McdConnection *self, - TpIntSet *handles); + TpIntset *handles); G_GNUC_INTERNAL void _mcd_connection_clear_emergency_data (McdConnection *self); @@ -72,9 +72,6 @@ G_GNUC_INTERNAL gboolean _mcd_connection_target_id_is_urgent (McdConnection *con G_GNUC_INTERNAL gboolean _mcd_connection_target_handle_is_urgent (McdConnection *self, guint handle); -G_GNUC_INTERNAL gboolean _mcd_connection_channel_is_urgent (McdConnection *self, - McdChannel *channel); - G_END_DECLS #endif diff --git a/src/mcd-connection-service-points.c b/src/mcd-connection-service-points.c index b869f4c4..0e690056 100644 --- a/src/mcd-connection-service-points.c +++ b/src/mcd-connection-service-points.c @@ -22,10 +22,13 @@ * */ +#include "config.h" + #include "mcd-connection-service-points.h" #include "mcd-connection-priv.h" -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/util.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> static void service_handles_fetched_cb (TpConnection *tp_conn, @@ -39,7 +42,7 @@ service_handles_fetched_cb (TpConnection *tp_conn, { guint i; McdConnection *connection = MCD_CONNECTION (weak); - TpIntSet *e_handles = tp_intset_new (); + TpIntset *e_handles = tp_intset_new (); if (error != NULL) return; diff --git a/src/mcd-connection.c b/src/mcd-connection.c index 40a59520..f2518491 100644 --- a/src/mcd-connection.c +++ b/src/mcd-connection.c @@ -33,6 +33,8 @@ * FIXME */ +#include "config.h" + #include "mcd-connection.h" #include "mcd-connection-service-points.h" @@ -47,25 +49,20 @@ #include <stdlib.h> #include <dlfcn.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/connection.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> + #include <telepathy-glib/proxy-subclass.h> -#include <telepathy-glib/util.h> #include "mcd-account-priv.h" #include "mcd-channel-priv.h" #include "mcd-connection-priv.h" #include "mcd-dispatcher-priv.h" #include "mcd-channel.h" -#include "mcd-provisioning-factory.h" #include "mcd-misc.h" #include "mcd-slacker.h" #include "sp_timestamp.h" -#include "mcd-signals-marshal.h" - #define INITIAL_RECONNECTION_TIME 3 /* seconds */ #define RECONNECTION_MULTIPLIER 3 #define MAXIMUM_RECONNECTION_TIME 30 * 60 /* half an hour */ @@ -140,7 +137,7 @@ struct _McdConnectionPrivate struct { - TpIntSet *handles; + TpIntset *handles; GSList *numbers; } emergency; }; @@ -576,9 +573,8 @@ on_new_channel (TpConnection *proxy, const gchar *chan_obj_path, * AddDispatchOperation or HandleChannels. * * We assume that channels without suppress_handler are incoming. */ - _mcd_dispatcher_take_channels (priv->dispatcher, - g_list_prepend (NULL, channel), - suppress_handler, suppress_handler); + _mcd_dispatcher_add_channel (priv->dispatcher, channel, + suppress_handler, suppress_handler); } } @@ -592,55 +588,6 @@ _foreach_channel_remove (McdMission * mission, McdOperation * operation) } static void -capabilities_advertise_cb (TpConnection *proxy, const GPtrArray *out0, - const GError *error, gpointer user_data, - GObject *weak_object) -{ - if (error) - { - g_warning ("%s: AdvertiseCapabilities failed: %s", G_STRFUNC, error->message); - } - -} - -static void -_mcd_connection_setup_capabilities (McdConnection *connection) -{ - McdConnectionPrivate *priv = MCD_CONNECTION_PRIV (connection); - GPtrArray *capabilities; - const gchar *removed = NULL; - GType type; - guint i; - - if (priv->has_contact_capabilities_if) - { - DEBUG ("ContactCapabilities in use, avoiding Capabilities"); - return; - } - - if (!priv->has_capabilities_if) - { - DEBUG ("connection does not support capabilities interface"); - return; - } - capabilities = _mcd_dispatcher_get_channel_capabilities (priv->dispatcher); - DEBUG ("advertising capabilities"); - tp_cli_connection_interface_capabilities_call_advertise_capabilities (priv->tp_conn, -1, - capabilities, - &removed, - capabilities_advertise_cb, - priv, NULL, - (GObject *) connection); - - /* free the connection capabilities */ - type = dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, - G_TYPE_UINT, G_TYPE_INVALID); - for (i = 0; i < capabilities->len; i++) - g_boxed_free (type, g_ptr_array_index (capabilities, i)); - g_ptr_array_unref (capabilities); -} - -static void avatars_set_avatar_cb (TpConnection *proxy, const gchar *token, const GError *error, gpointer user_data, GObject *weak_object) @@ -1223,6 +1170,10 @@ connect_cb (TpConnection *tp_conn, const GError *error, } } +static gboolean +_mcd_connection_request_channel (McdConnection *connection, + McdChannel *channel); + static void request_unrequested_channels (McdConnection *connection) { @@ -1268,16 +1219,16 @@ mcd_connection_find_channel_by_path (McdConnection *connection, return NULL; } +static gboolean mcd_connection_need_dispatch (McdConnection *connection, + const gchar *object_path, + GHashTable *props); + static void on_new_channels (TpConnection *proxy, const GPtrArray *channels, gpointer user_data, GObject *weak_object) { McdConnection *connection = MCD_CONNECTION (weak_object); McdConnectionPrivate *priv = user_data; - McdChannel *channel; - GList *channel_list = NULL; - gboolean requested = FALSE; - gboolean only_observe = FALSE; guint i; if (DEBUGGING) @@ -1308,9 +1259,6 @@ on_new_channels (TpConnection *proxy, const GPtrArray *channels, * FALSE: they'll also be in Channels in the GetAll(Requests) result */ if (!priv->dispatched_initial_channels) return; - only_observe = ! MCD_CONNECTION_GET_CLASS (connection)->need_dispatch ( - connection, channels); - sp_timestamp ("NewChannels received"); for (i = 0; i < channels->len; i++) { @@ -1318,11 +1266,17 @@ on_new_channels (TpConnection *proxy, const GPtrArray *channels, const gchar *object_path; GHashTable *props; GValue *value; + gboolean requested = FALSE; + gboolean only_observe = FALSE; + McdChannel *channel; va = g_ptr_array_index (channels, i); object_path = g_value_get_boxed (va->values); props = g_value_get_boxed (va->values + 1); + only_observe = !mcd_connection_need_dispatch (connection, object_path, + props); + /* Don't do anything for requested channels */ value = g_hash_table_lookup (props, TP_IFACE_CHANNEL ".Requested"); if (value && g_value_get_boolean (value)) @@ -1341,17 +1295,15 @@ on_new_channels (TpConnection *proxy, const GPtrArray *channels, MCD_MISSION (channel)); } - channel_list = g_list_prepend (channel_list, channel); - } + if (!requested) + { + /* we always dispatch unrequested (incoming) channels */ + only_observe = FALSE; + } - if (!requested) - { - /* we always dispatch unrequested (incoming) channels */ - only_observe = FALSE; + _mcd_dispatcher_add_channel (priv->dispatcher, channel, requested, + only_observe); } - - _mcd_dispatcher_take_channels (priv->dispatcher, channel_list, requested, - only_observe); } static void @@ -1561,21 +1513,25 @@ mcd_connection_setup_pre_requests (McdConnection *connection) } static void -on_connection_ready (TpConnection *tp_conn, const GError *error, - gpointer user_data) +on_connection_ready (GObject *source_object, GAsyncResult *result, + gpointer user_data) { + TpConnection *tp_conn = TP_CONNECTION (source_object); McdConnection *connection, **connection_ptr = user_data; McdConnectionPrivate *priv; + GError *error = NULL; connection = *connection_ptr; if (connection) g_object_remove_weak_pointer ((GObject *)connection, (gpointer)connection_ptr); g_slice_free (McdConnection *, connection_ptr); - if (error) + + if (!tp_proxy_prepare_finish (tp_conn, result, &error)) { DEBUG ("got error: %s", error->message); - return; + g_clear_error (&error); + return; } if (!connection) return; @@ -1599,9 +1555,6 @@ on_connection_ready (TpConnection *tp_conn, const GError *error, if (priv->has_presence_if) _mcd_connection_setup_presence (connection); - if (priv->has_capabilities_if) - _mcd_connection_setup_capabilities (connection); - if (priv->has_avatars_if) _mcd_connection_setup_avatar (connection); @@ -2176,18 +2129,19 @@ _mcd_connection_get_property (GObject * obj, guint prop_id, /* * mcd_connection_need_dispatch: * @connection: the #McdConnection. - * @channels: array of #McdChannel elements. + * @object_path: the object path of the new channel (only for debugging) + * @props: the properties of the new channel * * This functions must be called in response to a NewChannels signals, and is * responsible for deciding whether MC must handle the channels or not. */ static gboolean mcd_connection_need_dispatch (McdConnection *connection, - const GPtrArray *channels) + const gchar *object_path, + GHashTable *props) { McdAccount *account = mcd_connection_get_account (connection); - gboolean any_requested = FALSE, requested_by_us = FALSE; - guint i; + gboolean requested = FALSE, requested_by_us = FALSE; if (_mcd_account_needs_dispatch (account)) { @@ -2200,31 +2154,18 @@ mcd_connection_need_dispatch (McdConnection *connection, * have no McdChannel object associated: these are the channels directly * requested to the CM by some other application, and we must ignore them */ - for (i = 0; i < channels->len; i++) - { - GValueArray *va; - const gchar *object_path; - GHashTable *props; - gboolean requested; - - va = g_ptr_array_index (channels, i); - object_path = g_value_get_boxed (va->values); - props = g_value_get_boxed (va->values + 1); - - requested = tp_asv_get_boolean (props, TP_IFACE_CHANNEL ".Requested", - NULL); - if (requested) - { - any_requested = TRUE; - if (mcd_connection_find_channel_by_path (connection, object_path)) - requested_by_us = TRUE; - } + requested = tp_asv_get_boolean (props, TP_IFACE_CHANNEL ".Requested", + NULL); + if (requested) + { + if (mcd_connection_find_channel_by_path (connection, object_path)) + requested_by_us = TRUE; } /* handle only bundles which were not requested or that were requested * through MC */ - return !any_requested || requested_by_us; + return !requested || requested_by_us; } gboolean @@ -2255,32 +2196,9 @@ _mcd_connection_target_handle_is_urgent (McdConnection *self, guint handle) return FALSE; } -gboolean -_mcd_connection_channel_is_urgent (McdConnection *self, McdChannel *channel) -{ - const gchar *name = NULL; - - if (mcd_channel_get_handle_type (channel) != TP_HANDLE_TYPE_CONTACT) - return FALSE; - - name = mcd_channel_get_name (channel); - - if (tp_str_empty (name)) - { - TpHandle handle = mcd_channel_get_handle (channel); - - return _mcd_connection_target_handle_is_urgent (self, handle); - } - else - { - return _mcd_connection_target_id_is_urgent (self, name); - } - - return FALSE; -} - static gboolean -_mcd_connection_request_channel (McdConnection *connection, McdChannel *channel) +_mcd_connection_request_channel (McdConnection *connection, + McdChannel *channel) { McdConnectionPrivate *priv = MCD_CONNECTION_PRIV (connection); gboolean ret; @@ -2288,7 +2206,7 @@ _mcd_connection_request_channel (McdConnection *connection, McdChannel *channel) g_return_val_if_fail (priv->tp_conn != NULL, FALSE); g_return_val_if_fail (TP_IS_CONNECTION (priv->tp_conn), FALSE); - if (!tp_connection_is_ready (priv->tp_conn)) + if (!tp_proxy_is_prepared (priv->tp_conn, TP_CONNECTION_FEATURE_CONNECTED)) { /* don't request any channel until the connection is ready (because we * don't know if the CM implements the Requests interface). The channel @@ -2304,7 +2222,7 @@ _mcd_connection_request_channel (McdConnection *connection, McdChannel *channel) else { mcd_channel_take_error (channel, - g_error_new (TP_ERRORS, + g_error_new (TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "No Requests interface")); mcd_mission_abort ((McdMission *) channel); @@ -2328,9 +2246,6 @@ mcd_connection_class_init (McdConnectionClass * klass) object_class->set_property = _mcd_connection_set_property; object_class->get_property = _mcd_connection_get_property; - klass->need_dispatch = mcd_connection_need_dispatch; - klass->request_channel = _mcd_connection_request_channel; - _mcd_ext_register_dbus_glib_marshallers (); tp_connection_init_known_interfaces (); @@ -2380,7 +2295,7 @@ mcd_connection_class_init (McdConnectionClass * klass) signals[SELF_PRESENCE_CHANGED] = g_signal_new ("self-presence-changed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, - NULL, NULL, _mcd_marshal_VOID__UINT_STRING_STRING, + NULL, NULL, NULL, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING); signals[SELF_NICKNAME_CHANGED] = g_signal_new ("self-nickname-changed", @@ -2392,7 +2307,7 @@ mcd_connection_class_init (McdConnectionClass * klass) signals[CONNECTION_STATUS_CHANGED] = g_signal_new ( "connection-status-changed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, - NULL, NULL, _mcd_marshal_VOID__UINT_UINT_OBJECT, + NULL, NULL, NULL, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, TP_TYPE_CONNECTION); signals[READY] = g_signal_new ("ready", @@ -2554,46 +2469,7 @@ mcd_connection_request_channel (McdConnection *connection, mcd_operation_take_mission (MCD_OPERATION (connection), MCD_MISSION (channel)); - return MCD_CONNECTION_GET_CLASS (connection)->request_channel (connection, - channel); -} - -gboolean -mcd_connection_cancel_channel_request (McdConnection *connection, - guint operation_id, - const gchar *requestor_client_id, - GError **error) -{ - const GList *channels, *node; - McdChannel *channel; - - /* first, see if the channel is in the list of the pending channels */ - - channels = mcd_operation_get_missions (MCD_OPERATION (connection)); - if (!channels) return FALSE; - - for (node = channels; node; node = node->next) - { - guint chan_requestor_serial; - gchar *chan_requestor_client_id; - - channel = MCD_CHANNEL (node->data); - g_object_get (channel, - "requestor-serial", &chan_requestor_serial, - "requestor-client-id", &chan_requestor_client_id, - NULL); - if (chan_requestor_serial == operation_id && - strcmp (chan_requestor_client_id, requestor_client_id) == 0) - { - DEBUG ("requested channel found (%p)", channel); - mcd_mission_abort (MCD_MISSION (channel)); - g_free (chan_requestor_client_id); - return TRUE; - } - g_free (chan_requestor_client_id); - } - DEBUG ("requested channel not found!"); - return FALSE; + return _mcd_connection_request_channel (connection, channel); } void @@ -2716,6 +2592,10 @@ _mcd_connection_set_tp_connection (McdConnection *connection, { McdConnection **connection_ptr; McdConnectionPrivate *priv; + GQuark features[] = { + TP_CONNECTION_FEATURE_CONNECTED, + 0 + }; g_return_if_fail (MCD_IS_CONNECTION (connection)); priv = connection->priv; @@ -2763,8 +2643,8 @@ _mcd_connection_set_tp_connection (McdConnection *connection, *connection_ptr = connection; g_object_add_weak_pointer ((GObject *)connection, (gpointer)connection_ptr); - tp_connection_call_when_ready (priv->tp_conn, on_connection_ready, - connection_ptr); + tp_proxy_prepare_async (priv->tp_conn, features, + on_connection_ready, connection_ptr); } /** @@ -2786,7 +2666,7 @@ _mcd_connection_is_ready (McdConnection *self) g_return_val_if_fail (MCD_IS_CONNECTION (self), FALSE); return (self->priv->tp_conn != NULL) && - tp_connection_is_ready (self->priv->tp_conn); + tp_proxy_is_prepared (self->priv->tp_conn, TP_CONNECTION_FEATURE_CONNECTED); } gboolean @@ -2799,30 +2679,6 @@ _mcd_connection_presence_info_is_ready (McdConnection *self) static void clear_emergency_handles (McdConnectionPrivate *priv) { - guint n_handles = 0; - - if (priv->emergency.handles != NULL) - n_handles = tp_intset_size (priv->emergency.handles); - - /* trawl through the handles and unref them */ - if (n_handles > 0) - { - TpIntSetFastIter iter; - TpHandle *handles = g_new0 (TpHandle, n_handles); - TpHandle handle; - guint i = 0; - - tp_intset_fast_iter_init (&iter, priv->emergency.handles); - - while (tp_intset_fast_iter_next (&iter, &handle)) - handles[i++] = handle; - - tp_connection_unref_handles (priv->tp_conn, TP_HANDLE_TYPE_CONTACT, - n_handles, handles); - - g_free (handles); - } - tp_clear_pointer (&priv->emergency.handles, tp_intset_destroy); } @@ -2852,7 +2708,7 @@ void _mcd_connection_take_emergency_numbers (McdConnection *self, GSList *number } void -_mcd_connection_take_emergency_handles (McdConnection *self, TpIntSet *handles) +_mcd_connection_take_emergency_handles (McdConnection *self, TpIntset *handles) { McdConnectionPrivate *priv = self->priv; diff --git a/src/mcd-connection.h b/src/mcd-connection.h index 719f3faf..8f450b92 100644 --- a/src/mcd-connection.h +++ b/src/mcd-connection.h @@ -28,7 +28,7 @@ #include <glib.h> #include <glib-object.h> -#include <telepathy-glib/connection-manager.h> +#include <telepathy-glib/telepathy-glib.h> #include "mcd-operation.h" @@ -55,15 +55,6 @@ struct _McdConnection struct _McdConnectionClass { McdOperationClass parent_class; - gboolean (*need_dispatch) (McdConnection *connection, - const GPtrArray *channels); - void (*_mc_reserved2) (void); - gboolean (*request_channel) (McdConnection *connection, - McdChannel *channel); - void (*_mc_reserved3) (void); - void (*_mc_reserved4) (void); - void (*_mc_reserved5) (void); - void (*_mc_reserved6) (void); }; #include "mcd-dispatcher.h" @@ -81,11 +72,6 @@ TpConnection *mcd_connection_get_tp_connection (McdConnection *connection); gboolean mcd_connection_request_channel (McdConnection *connection, McdChannel *channel); -gboolean mcd_connection_cancel_channel_request (McdConnection *connection, - guint operation_id, - const gchar *requestor_client_id, - GError **error); - void mcd_connection_close (McdConnection *connection); McdChannel * mcd_connection_find_channel_by_path (McdConnection *connection, diff --git a/src/mcd-controller.c b/src/mcd-controller.c deleted file mode 100644 index cb6b9265..00000000 --- a/src/mcd-controller.c +++ /dev/null @@ -1,139 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* - * This file is part of mission-control - * - * Copyright (C) 2007-2009 Nokia Corporation. - * - * Contact: Naba Kumar <naba.kumar@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -/** - * SECTION:mcd-controller - * @title: McdController - * @short_description: Server controller class - * @see_also: - * @stability: Unstable - * @include: mcd-controller.h - * - * This class implements the logic to control mission-control based on all - * external device events and states. It also controls mission-control - * life-cycle based on such events. - */ - -#include "mcd-controller.h" - -/* Milliseconds to wait for Connectivity coming back up before exiting MC */ -#define EXIT_COUNTDOWN_TIME 5000 - -#define MCD_CONTROLLER_PRIV(controller) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((controller), \ - MCD_TYPE_CONTROLLER, \ - McdControllerPrivate)) - -G_DEFINE_TYPE (McdController, mcd_controller, MCD_TYPE_OPERATION); - -/* Private */ -typedef struct _McdControllerPrivate -{ - /* Current pending sleep timer */ - gint shutdown_timeout_id; - - gboolean is_disposed; -} McdControllerPrivate; - -static void -mcd_controller_class_init (McdControllerClass * klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - g_type_class_add_private (object_class, sizeof (McdControllerPrivate)); -} - -static void -mcd_controller_init (McdController * obj) -{ -} - -/* Public */ - -McdController * -mcd_controller_new () -{ - McdController *obj; - obj = MCD_CONTROLLER (g_object_new (MCD_TYPE_CONTROLLER, NULL)); - return obj; -} - -static gboolean -_mcd_controller_exit_by_timeout (gpointer data) -{ - McdController *controller; - McdControllerPrivate *priv; - - controller = MCD_CONTROLLER (data); - priv = MCD_CONTROLLER_PRIV (controller); - - priv->shutdown_timeout_id = 0; - - /* Notify sucide */ - mcd_mission_abort (MCD_MISSION (controller)); - - return FALSE; -} - -void -mcd_controller_shutdown (McdController *controller, const gchar *reason) -{ - McdControllerPrivate *priv; - - g_return_if_fail (MCD_IS_CONTROLLER (controller)); - priv = MCD_CONTROLLER_PRIV (controller); - - if(!priv->shutdown_timeout_id) - { - DEBUG ("MC will bail out because of \"%s\" out exit after %i", - reason ? reason : "No reason specified", - EXIT_COUNTDOWN_TIME); - - priv->shutdown_timeout_id = g_timeout_add (EXIT_COUNTDOWN_TIME, - _mcd_controller_exit_by_timeout, - controller); - } - else - { - DEBUG ("Already shutting down. This one has the reason %s", - reason ? reason:"No reason specified"); - } - mcd_debug_print_tree (controller); -} - -void -mcd_controller_cancel_shutdown (McdController *controller) -{ - McdControllerPrivate *priv; - - g_return_if_fail (MCD_IS_CONTROLLER (controller)); - priv = MCD_CONTROLLER_PRIV (controller); - - if (priv->shutdown_timeout_id) - { - DEBUG ("Cancelling exit timeout"); - g_source_remove (priv->shutdown_timeout_id); - priv->shutdown_timeout_id = 0; - } -} diff --git a/src/mcd-controller.h b/src/mcd-controller.h deleted file mode 100644 index 73b25b5f..00000000 --- a/src/mcd-controller.h +++ /dev/null @@ -1,63 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* - * This file is part of mission-control - * - * Copyright (C) 2007 Nokia Corporation. - * - * Contact: Naba Kumar <naba.kumar@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef MCD_CONTROLLER_H -#define MCD_CONTROLLER_H - -#include <glib.h> -#include <glib-object.h> - -#include "mcd-operation.h" - -G_BEGIN_DECLS - -#define MCD_TYPE_CONTROLLER (mcd_controller_get_type ()) -#define MCD_CONTROLLER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MCD_TYPE_CONTROLLER, McdController)) -#define MCD_CONTROLLER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MCD_TYPE_CONTROLLER, McdControllerClass)) -#define MCD_IS_CONTROLLER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MCD_TYPE_CONTROLLER)) -#define MCD_IS_CONTROLLER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), MCD_TYPE_CONTROLLER)) -#define MCD_CONTROLLER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MCD_TYPE_CONTROLLER, McdControllerClass)) - -typedef struct _McdController McdController; -typedef struct _McdControllerClass McdControllerClass; - -struct _McdController -{ - McdOperation parent; -}; - -struct _McdControllerClass -{ - McdOperationClass parent_class; -}; - -GType mcd_controller_get_type (void); -McdController *mcd_controller_new (void); -void mcd_controller_shutdown (McdController *controller, const gchar *reason); -void mcd_controller_cancel_shutdown (McdController *controller); - -G_END_DECLS - -#endif /* MCD_CONTROLLER_H */ diff --git a/src/mcd-dbusprop.c b/src/mcd-dbusprop.c index 0e233608..f15bd85b 100644 --- a/src/mcd-dbusprop.c +++ b/src/mcd-dbusprop.c @@ -24,15 +24,14 @@ * */ +#include "config.h" + #include <string.h> -#include <telepathy-glib/errors.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> + #include "mcd-dbusprop.h" #include "mcd-debug.h" -#include "mission-control-plugins/mission-control-plugins.h" -#include "mission-control-plugins/implementation.h" - #define MCD_INTERFACES_QUARK get_interfaces_quark() static GQuark @@ -139,7 +138,7 @@ get_mcddbusprop (TpSvcDBusProperties *self, prop_array = get_interface_properties (self, interface_name); if (!prop_array) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "invalid interface: %s", interface_name); return NULL; } @@ -151,7 +150,7 @@ get_mcddbusprop (TpSvcDBusProperties *self, if (!property->name) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "invalid property: %s", property_name); return NULL; } @@ -175,7 +174,7 @@ mcd_dbusprop_set_property (TpSvcDBusProperties *self, if (!property->setprop) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "property %s cannot be written", property_name); return FALSE; } @@ -186,25 +185,6 @@ mcd_dbusprop_set_property (TpSvcDBusProperties *self, } void -dbusprop_acl_set (TpSvcDBusProperties *self, - const gchar *interface, - const gchar *property, - const GValue *value, - DBusGMethodInvocation *context, - TpDBusDaemon *dbus, - GHashTable *params) -{ - gchar *name = g_strdup_printf ("%s.%s", interface, property); - gboolean ok = mcp_dbus_acl_authorised (dbus, context, - DBUS_ACL_TYPE_SET_PROPERTY, - name, params); - g_free (name); - - if (ok) - dbusprop_set (self, interface, property, value, context); -} - -void dbusprop_set (TpSvcDBusProperties *self, const gchar *interface_name, const gchar *property_name, @@ -241,7 +221,7 @@ mcd_dbusprop_get_property (TpSvcDBusProperties *self, if (!property->getprop) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "property %s cannot be read", property_name); return FALSE; } @@ -251,31 +231,12 @@ mcd_dbusprop_get_property (TpSvcDBusProperties *self, } void -dbusprop_acl_get (TpSvcDBusProperties *self, - const gchar *interface, - const gchar *property, - DBusGMethodInvocation *context, - TpDBusDaemon *dbus, - GHashTable *params) -{ - gchar *name = g_strdup_printf ("%s.%s", interface, property); - gboolean ok = mcp_dbus_acl_authorised (dbus, context, - DBUS_ACL_TYPE_GET_PROPERTY, - name, params); - g_free (name); - - if (ok) - dbusprop_get (self, interface, property, context); -} - - -void dbusprop_get (TpSvcDBusProperties *self, const gchar *interface_name, const gchar *property_name, DBusGMethodInvocation *context) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; GError *error = NULL; DEBUG ("%s, %s", interface_name, property_name); @@ -337,24 +298,6 @@ get_all_iter (GetAllData *data) } } -void -dbusprop_acl_get_all (TpSvcDBusProperties *self, - const gchar *interface, - DBusGMethodInvocation *context, - TpDBusDaemon *dbus, - GHashTable *params) -{ - gchar *name = g_strdup_printf ("%s.*", interface); - gboolean ok = mcp_dbus_acl_authorised (dbus, context, - DBUS_ACL_TYPE_GET_PROPERTY, - name, params); - - g_free (name); - - if (ok) - dbusprop_get_all (self, interface, context); -} - typedef struct { TpSvcDBusProperties *tp_svc_props; @@ -362,53 +305,6 @@ typedef struct gchar *property; } DBusPropAsyncData; -static void -dbusprop_acl_get_all_async_complete (DBusGMethodInvocation *context, - gpointer data) -{ - DBusPropAsyncData *ad = data; - - dbusprop_get_all (ad->tp_svc_props, ad->interface, context); -} - -static void -dbusprop_acl_get_all_async_cleanup (gpointer data) -{ - DBusPropAsyncData *ad = data; - - g_object_unref (ad->tp_svc_props); - g_free (ad->interface); - g_free (ad->property); - g_slice_free (DBusPropAsyncData, data); -} - -void -dbusprop_acl_get_all_async_start (TpSvcDBusProperties *self, - const gchar *interface, - DBusGMethodInvocation *context, - TpDBusDaemon *dbus, - GHashTable *params) -{ - DBusPropAsyncData *data = g_slice_new0 (DBusPropAsyncData); - gchar *name = g_strdup_printf ("%s.*", interface); - - data->tp_svc_props = g_object_ref (self); - data->interface = g_strdup (interface); - data->property = NULL; - - mcp_dbus_acl_authorised_async (dbus, - context, - DBUS_ACL_TYPE_GET_PROPERTY, - name, - params, - dbusprop_acl_get_all_async_complete, - data, - dbusprop_acl_get_all_async_cleanup); - - g_free (name); -} - - void dbusprop_get_all (TpSvcDBusProperties *self, const gchar *interface_name, @@ -423,7 +319,7 @@ dbusprop_get_all (TpSvcDBusProperties *self, prop_array = get_interface_properties (self, interface_name); if (!prop_array) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "invalid interface: %s", interface_name); dbus_g_method_return_error (context, error); g_error_free (error); diff --git a/src/mcd-dbusprop.h b/src/mcd-dbusprop.h index be393b6f..fa5091c2 100644 --- a/src/mcd-dbusprop.h +++ b/src/mcd-dbusprop.h @@ -27,8 +27,8 @@ #ifndef __MCD_DBUSPROP_H__ #define __MCD_DBUSPROP_H__ -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/dbus.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> G_BEGIN_DECLS @@ -119,34 +119,6 @@ gboolean mcd_dbusprop_get_property (TpSvcDBusProperties *self, GValue *value, GError **error); -void dbusprop_acl_set (TpSvcDBusProperties *self, - const gchar *interface, - const gchar *property, - const GValue *value, - DBusGMethodInvocation *context, - TpDBusDaemon *dbus, - GHashTable *params); - -void dbusprop_acl_get (TpSvcDBusProperties *self, - const gchar *interface, - const gchar *property, - DBusGMethodInvocation *context, - TpDBusDaemon *dbus, - GHashTable * params); - -void dbusprop_acl_get_all (TpSvcDBusProperties *self, - const gchar *interface, - DBusGMethodInvocation *context, - TpDBusDaemon *dbus, - GHashTable *params); - -void -dbusprop_acl_get_all_async_start (TpSvcDBusProperties *self, - const gchar *interface, - DBusGMethodInvocation *context, - TpDBusDaemon *dbus, - GHashTable *params); - void dbusprop_set (TpSvcDBusProperties *self, const gchar *interface_name, const gchar *property_name, diff --git a/src/mcd-debug.c b/src/mcd-debug.c index 350299bc..41246fce 100644 --- a/src/mcd-debug.c +++ b/src/mcd-debug.c @@ -39,9 +39,8 @@ #include <stdlib.h> -#include <telepathy-glib/debug.h> -#include <telepathy-glib/debug-sender.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include <mission-control-plugins/mission-control-plugins.h> @@ -50,22 +49,6 @@ gint mcd_debug_level = 0; -gpointer -mcd_debug_ref (gpointer obj, - const gchar *filename G_GNUC_UNUSED, - gint linenum G_GNUC_UNUSED) -{ - return g_object_ref (obj); -} - -void -mcd_debug_unref (gpointer obj, - const gchar *filename G_GNUC_UNUSED, - gint linenum G_GNUC_UNUSED) -{ - g_object_unref (obj); -} - static void mcd_debug_print_tree_real (gpointer object, gint level) { diff --git a/src/mcd-debug.h b/src/mcd-debug.h index bf2cc477..66fdafcc 100644 --- a/src/mcd-debug.h +++ b/src/mcd-debug.h @@ -57,11 +57,6 @@ static inline gint _mcd_debug_get_level (void) return mcd_debug_level; } -gpointer mcd_debug_ref (gpointer obj, const gchar *filename, gint linenum) - G_GNUC_DEPRECATED; -void mcd_debug_unref (gpointer obj, const gchar *filename, gint linenum) - G_GNUC_DEPRECATED; - void mcd_debug_print_tree (gpointer obj); void mcd_debug (const gchar *format, ...); diff --git a/src/mcd-dispatch-operation-priv.h b/src/mcd-dispatch-operation-priv.h index ae0d7998..ce168fc3 100644 --- a/src/mcd-dispatch-operation-priv.h +++ b/src/mcd-dispatch-operation-priv.h @@ -24,8 +24,7 @@ #ifndef __MCD_DISPATCH_OPERATION_PRIV_H__ #define __MCD_DISPATCH_OPERATION_PRIV_H__ -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/enums.h> +#include <telepathy-glib/telepathy-glib.h> #include "client-registry.h" #include "mcd-handler-map-priv.h" @@ -70,15 +69,18 @@ G_GNUC_INTERNAL void _mcd_dispatch_operation_approve #define MCD_DISPATCH_OPERATION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MCD_TYPE_DISPATCH_OPERATION, McdDispatchOperationClass)) G_GNUC_INTERNAL McdDispatchOperation *_mcd_dispatch_operation_new ( - McdClientRegistry *client_registry, McdHandlerMap *handler_map, - gboolean needs_approval, gboolean observe_only, GList *channels, + McdClientRegistry *client_registry, + McdHandlerMap *handler_map, + gboolean needs_approval, + gboolean observe_only, + McdChannel *channel, const gchar * const *possible_handlers); G_GNUC_INTERNAL gboolean _mcd_dispatch_operation_has_channel ( McdDispatchOperation *self, McdChannel *channel); -G_GNUC_INTERNAL const GList *_mcd_dispatch_operation_peek_channels ( +G_GNUC_INTERNAL McdChannel *_mcd_dispatch_operation_peek_channel ( McdDispatchOperation *self); -G_GNUC_INTERNAL GList *_mcd_dispatch_operation_dup_channels ( +G_GNUC_INTERNAL McdChannel *_mcd_dispatch_operation_dup_channel ( McdDispatchOperation *self); G_GNUC_INTERNAL gboolean _mcd_dispatch_operation_is_finished ( diff --git a/src/mcd-dispatch-operation.c b/src/mcd-dispatch-operation.c index dfb87d13..ac036f0c 100644 --- a/src/mcd-dispatch-operation.c +++ b/src/mcd-dispatch-operation.c @@ -33,12 +33,8 @@ #include <glib/gstdio.h> -#include <telepathy-glib/defs.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/svc-channel-dispatch-operation.h> -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "channel-utils.h" #include "mcd-channel-priv.h" @@ -200,14 +196,14 @@ struct _McdDispatchOperationPrivate McdAccount *account; McdConnection *connection; - /* Owned McdChannels we're dispatching */ - GList *channels; - /* Owned McdChannels for which we can't emit ChannelLost yet, in - * reverse chronological order */ - GList *lost_channels; + /* Owned McdChannel we're dispatching */ + McdChannel *channel; + /* If non-NULL, we have lost the McdChannel but can't emit + * ChannelLost yet */ + McdChannel *lost_channel; - /* If TRUE, either the channels being dispatched were requested, or they - * were pre-approved by being returned as a response to another request, + /* If TRUE, either the channel being dispatched was requested, or it + * was pre-approved by being returned as a response to another request, * or a client approved processing with arbitrary handlers */ gboolean approved; @@ -250,7 +246,7 @@ struct _McdDispatchOperationPrivate /* If TRUE, we're dispatching a channel request and it was cancelled */ gboolean cancelled; - /* if TRUE, these channels were requested "behind our back", so stop + /* if TRUE, this channel was requested "behind our back", so stop * after observers */ gboolean observe_only; @@ -349,7 +345,7 @@ _mcd_dispatch_operation_dec_ado_pending (McdDispatchOperation *self) if (self->priv->ado_pending == 0 && !self->priv->accepted_by_an_approver) { - DEBUG ("No approver accepted the channels; considering them to be " + DEBUG ("No approver accepted the channel; considering it to be " "approved"); g_queue_push_tail (self->priv->approvals, approval_new (APPROVAL_TYPE_NO_APPROVERS)); @@ -433,7 +429,7 @@ _mcd_dispatch_operation_check_client_locks (McdDispatchOperation *self) if (!self->priv->tried_handlers_before_approval && !_mcd_dispatch_operation_handlers_can_bypass_approval (self) && self->priv->delay_approver_observers_pending == 0 - && self->priv->channels != NULL && + && self->priv->channel != NULL && ! _mcd_plugin_dispatch_operation_will_terminate ( self->priv->plugin_api)) { @@ -467,7 +463,7 @@ _mcd_dispatch_operation_check_client_locks (McdDispatchOperation *self) return; } - /* if a handler has claimed or accepted the channels, we have nothing to + /* if a handler has claimed or accepted the channel, we have nothing to * do */ if (self->priv->result != NULL) { @@ -485,24 +481,21 @@ _mcd_dispatch_operation_check_client_locks (McdDispatchOperation *self) if (_mcd_dispatch_operation_is_internal (self)) { - guint i = 0; - GList *list = self->priv->channels; - DEBUG ("Invoking internal handlers for requests"); - for (; list != NULL; list = g_list_next (list), i++) + if (self->priv->channel != NULL) { - McdChannel *channel = list->data; + McdChannel *channel = self->priv->channel; McdRequest *request = _mcd_channel_get_request (channel); - if (request == NULL) - continue; - - DEBUG ("Internal handler for request channel #%u", i); - _mcd_handler_map_set_channel_handled_internally ( - self->priv->handler_map, - mcd_channel_get_tp_channel (channel), - _mcd_dispatch_operation_get_account_path (self)); - _mcd_request_handle_internally (request, channel, TRUE); + if (request != NULL) + { + DEBUG ("Internal handler for request channel"); + _mcd_handler_map_set_channel_handled_internally ( + self->priv->handler_map, + mcd_channel_get_tp_channel (channel), + _mcd_dispatch_operation_get_account_path (self)); + _mcd_request_handle_internally (request, channel, TRUE); + } } /* The rest of this function deals with externally handled requests: * @@ -515,7 +508,7 @@ _mcd_dispatch_operation_check_client_locks (McdDispatchOperation *self) * want to run approvers in this case */ if (self->priv->possible_handlers == NULL) { - GError incapable = { TP_ERRORS, TP_ERROR_NOT_CAPABLE, + GError incapable = { TP_ERROR, TP_ERROR_NOT_CAPABLE, "No possible handlers, giving up" }; DEBUG ("%s", incapable.message); @@ -528,7 +521,6 @@ _mcd_dispatch_operation_check_client_locks (McdDispatchOperation *self) /* if we've been claimed, respond, then do not call HandleChannels */ if (approval != NULL && approval->type == APPROVAL_TYPE_CLAIM) { - const GList *list; /* this needs to be copied because we don't use it til after we've * freed approval->context */ gchar *caller = g_strdup (dbus_g_method_get_sender ( @@ -538,9 +530,9 @@ _mcd_dispatch_operation_check_client_locks (McdDispatchOperation *self) * failure */ g_queue_pop_head (self->priv->approvals); - for (list = self->priv->channels; list != NULL; list = list->next) + if (self->priv->channel != NULL) { - McdChannel *channel = MCD_CHANNEL (list->data); + McdChannel *channel = self->priv->channel; mcd_dispatch_operation_set_channel_handled_by (self, channel, caller, NULL); @@ -552,7 +544,7 @@ _mcd_dispatch_operation_check_client_locks (McdDispatchOperation *self) approval->context); approval->context = NULL; - _mcd_dispatch_operation_finish (self, TP_ERRORS, TP_ERROR_NOT_YOURS, + _mcd_dispatch_operation_finish (self, TP_ERROR, TP_ERROR_NOT_YOURS, "Channel successfully claimed by %s", caller); g_free (caller); @@ -586,7 +578,7 @@ _mcd_dispatch_operation_check_client_locks (McdDispatchOperation *self) if (!_mcd_dispatch_operation_try_next_handler (self)) { - GError incapable = { TP_ERRORS, TP_ERROR_NOT_CAPABLE, + GError incapable = { TP_ERROR, TP_ERROR_NOT_CAPABLE, "No possible handler still exists, giving up" }; DEBUG ("ran out of handlers"); @@ -619,7 +611,7 @@ _mcd_dispatch_operation_check_client_locks (McdDispatchOperation *self) enum { PROP_0, - PROP_CHANNELS, + PROP_CHANNEL, PROP_CLIENT_REGISTRY, PROP_HANDLER_MAP, PROP_POSSIBLE_HANDLERS, @@ -728,8 +720,16 @@ get_channels (TpSvcDBusProperties *iface, const gchar *name, GValue *value) DEBUG ("called for %s", self->priv->unique_name); g_value_init (value, TP_ARRAY_TYPE_CHANNEL_DETAILS_LIST); + + if (self->priv->channel == NULL) + { + g_value_take_boxed (value, g_ptr_array_sized_new (0)); + return; + } + g_value_take_boxed (value, - _mcd_tp_channel_details_build_from_list (self->priv->channels)); + _mcd_tp_channel_details_build_from_tp_chan ( + mcd_channel_get_tp_channel (self->priv->channel))); } static void @@ -872,7 +872,8 @@ _mcd_dispatch_operation_finish (McdDispatchOperation *operation, else { /* Handling finished for some other reason: perhaps the - * channel was claimed, or perhaps we ran out of channels. + * channel was claimed, or perhaps it closed or we were + * told to forget about it. */ DEBUG ("HandleWith -> error: %s %d: %s", g_quark_to_string (priv->result->domain), @@ -1077,7 +1078,7 @@ mcd_dispatch_operation_constructor (GType type, guint n_params, g_return_val_if_fail (operation != NULL, NULL); priv = operation->priv; - if (!priv->client_registry || !priv->handler_map) + if (!priv->client_registry || !priv->handler_map || !priv->channel) goto error; if (priv->needs_approval && priv->observe_only) @@ -1091,14 +1092,12 @@ mcd_dispatch_operation_constructor (GType type, guint n_params, DEBUG ("%s/%p: needs_approval=%c", priv->unique_name, object, priv->needs_approval ? 'T' : 'F'); - if (DEBUGGING) + if (priv->channel != NULL) { - GList *list; - - for (list = priv->channels; list != NULL; list = list->next) - { - DEBUG ("Channel: %s", mcd_channel_get_object_path (list->data)); - } + DEBUG ("Channel: %s", + mcd_channel_get_object_path (priv->channel)); + g_assert (mcd_channel_get_account (priv->channel) == + priv->account); } /* If approval is not needed, we don't appear on D-Bus (and approvers @@ -1153,7 +1152,7 @@ mcd_dispatch_operation_channel_aborted_cb (McdChannel *channel, _mcd_dispatch_operation_lose_channel (self, channel); - if (_mcd_dispatch_operation_peek_channels (self) == NULL) + if (self->priv->channel == NULL) { DEBUG ("Nothing left in this context"); } @@ -1167,7 +1166,6 @@ mcd_dispatch_operation_set_property (GObject *obj, guint prop_id, { McdDispatchOperation *operation = MCD_DISPATCH_OPERATION (obj); McdDispatchOperationPrivate *priv = operation->priv; - GList *list; switch (prop_id) { @@ -1181,21 +1179,19 @@ mcd_dispatch_operation_set_property (GObject *obj, guint prop_id, priv->handler_map = MCD_HANDLER_MAP (g_value_dup_object (val)); break; - case PROP_CHANNELS: + case PROP_CHANNEL: /* because this is construct-only, we can assert that: */ - g_assert (priv->channels == NULL); + g_assert (priv->channel == NULL); g_assert (g_queue_is_empty (priv->approvals)); - priv->channels = g_list_copy (g_value_get_pointer (val)); + priv->channel = g_value_dup_object (val); - if (G_LIKELY (priv->channels)) + if (G_LIKELY (priv->channel)) { - /* get the connection and account from the first channel */ - McdChannel *channel = MCD_CHANNEL (priv->channels->data); const gchar *preferred_handler; priv->connection = (McdConnection *) - mcd_mission_get_parent (MCD_MISSION (channel)); + mcd_mission_get_parent (MCD_MISSION (priv->channel)); if (G_LIKELY (priv->connection)) { @@ -1207,10 +1203,10 @@ mcd_dispatch_operation_set_property (GObject *obj, guint prop_id, g_warning ("Channel has no Connection?!"); } - /* if the first channel is actually a channel request, get the + /* if the channel is actually a channel request, get the * preferred handler from it */ preferred_handler = - _mcd_channel_get_request_preferred_handler (channel); + _mcd_channel_get_request_preferred_handler (priv->channel); if (preferred_handler != NULL && g_str_has_prefix (preferred_handler, TP_CLIENT_BUS_NAME_BASE) && @@ -1224,7 +1220,7 @@ mcd_dispatch_operation_set_property (GObject *obj, guint prop_id, approval_new_requested (preferred_handler)); } - priv->account = mcd_channel_get_account (channel); + priv->account = mcd_channel_get_account (priv->channel); if (G_LIKELY (priv->account != NULL)) { @@ -1237,16 +1233,10 @@ mcd_dispatch_operation_set_property (GObject *obj, guint prop_id, "Account?!"); } - /* reference the channels and connect to their signals */ - for (list = priv->channels; list != NULL; list = list->next) - { - g_object_ref (list->data); - - g_signal_connect_after (list->data, "abort", - G_CALLBACK (mcd_dispatch_operation_channel_aborted_cb), - operation); - - } + /* connect to its signals */ + g_signal_connect_after (priv->channel, "abort", + G_CALLBACK (mcd_dispatch_operation_channel_aborted_cb), + operation); } break; @@ -1321,32 +1311,18 @@ static void mcd_dispatch_operation_dispose (GObject *object) { McdDispatchOperationPrivate *priv = MCD_DISPATCH_OPERATION_PRIV (object); - GList *list; tp_clear_object (&priv->plugin_api); tp_clear_object (&priv->successful_handler); - if (priv->channels != NULL) - { - for (list = priv->channels; list != NULL; list = list->next) - { - g_signal_handlers_disconnect_by_func (list->data, - mcd_dispatch_operation_channel_aborted_cb, object); - g_object_unref (list->data); - } - - tp_clear_pointer (&priv->channels, g_list_free); - } - - if (priv->lost_channels != NULL) + if (priv->channel != NULL) { - for (list = priv->lost_channels; list != NULL; list = list->next) - g_object_unref (list->data); - - tp_clear_pointer (&priv->lost_channels, g_list_free); + g_signal_handlers_disconnect_by_func (priv->channel, + mcd_dispatch_operation_channel_aborted_cb, object); } - tp_clear_object (&priv->connection); + tp_clear_object (&priv->channel); + tp_clear_object (&priv->lost_channel); tp_clear_object (&priv->account); tp_clear_object (&priv->handler_map); tp_clear_object (&priv->client_registry); @@ -1387,9 +1363,11 @@ _mcd_dispatch_operation_class_init (McdDispatchOperationClass * klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, PROP_CHANNELS, - g_param_spec_pointer ("channels", "channels", "channels", - G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_CHANNEL, + g_param_spec_object ("channel", "Channel", "the channel to dispatch", + MCD_TYPE_CHANNEL, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_POSSIBLE_HANDLERS, g_param_spec_boxed ("possible-handlers", "Possible handlers", @@ -1433,31 +1411,31 @@ _mcd_dispatch_operation_init (McdDispatchOperation *operation) * _mcd_dispatch_operation_new: * @client_registry: the client registry. * @handler_map: the handler map - * @channels: a #GList of #McdChannel elements to dispatch. - * @possible_handlers: the bus names of possible handlers for these channels. + * @channel: the channel to dispatch + * @possible_handlers: the bus names of possible handlers for this channel * - * Creates a #McdDispatchOperation. The #GList @channels will be no longer - * valid after this function has been called. + * Creates a #McdDispatchOperation. */ McdDispatchOperation * _mcd_dispatch_operation_new (McdClientRegistry *client_registry, McdHandlerMap *handler_map, gboolean needs_approval, gboolean observe_only, - GList *channels, + McdChannel *channel, const gchar * const *possible_handlers) { gpointer *obj; - /* If we're only observing, then the channels were requested "behind MC's + /* If we're only observing, then the channel was requested "behind MC's * back", so they can't need approval (i.e. observe_only implies * !needs_approval) */ g_return_val_if_fail (!observe_only || !needs_approval, NULL); + g_return_val_if_fail (MCD_IS_CHANNEL (channel), NULL); obj = g_object_new (MCD_TYPE_DISPATCH_OPERATION, "client-registry", client_registry, "handler-map", handler_map, - "channels", channels, + "channel", channel, "possible-handlers", possible_handlers, "needs-approval", needs_approval, "observe-only", observe_only, @@ -1568,7 +1546,7 @@ mcd_dispatch_operation_check_handle_with (McdDispatchOperation *self, if (!g_queue_is_empty (self->priv->approvals)) { DEBUG ("NotYours: already finished or approved"); - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_YOURS, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_YOURS, "CDO already finished or approved"); return FALSE; } @@ -1584,7 +1562,7 @@ mcd_dispatch_operation_check_handle_with (McdDispatchOperation *self, TP_DBUS_NAME_TYPE_WELL_KNOWN, NULL)) { DEBUG ("InvalidArgument: handler name %s is bad", handler_name); - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Invalid handler name"); return FALSE; } @@ -1624,16 +1602,18 @@ static void _mcd_dispatch_operation_lose_channel (McdDispatchOperation *self, McdChannel *channel) { - GList *li = g_list_find (self->priv->channels, channel); const gchar *object_path; const GError *error = NULL; - if (li == NULL) + if (G_UNLIKELY (channel != self->priv->channel)) { + g_warning ("%s: apparently lost %p but my channel is %p", + G_STRFUNC, channel, self->priv->channel); return; } - self->priv->channels = g_list_delete_link (self->priv->channels, li); + /* steal the reference */ + self->priv->channel = NULL; object_path = mcd_channel_get_object_path (channel); error = mcd_channel_get_error (channel); @@ -1654,9 +1634,8 @@ _mcd_dispatch_operation_lose_channel (McdDispatchOperation *self, "%" G_GSIZE_FORMAT " approvers", self->priv->unique_name, self, object_path, self->priv->observers_pending, self->priv->ado_pending); - self->priv->lost_channels = - g_list_prepend (self->priv->lost_channels, - g_object_ref (channel)); + g_assert (self->priv->lost_channel == NULL); + self->priv->lost_channel = g_object_ref (channel); } else { @@ -1671,15 +1650,12 @@ _mcd_dispatch_operation_lose_channel (McdDispatchOperation *self, g_free (error_name); } - /* We previously had a ref in the linked list - drop it */ + /* We previously stole this ref from self->priv->channel - drop it */ g_object_unref (channel); - if (self->priv->channels == NULL) - { - /* no channels left, so the CDO finishes (if it hasn't already) */ - _mcd_dispatch_operation_finish (self, error->domain, error->code, - "%s", error->message); - } + /* no channels left, so the CDO finishes (if it hasn't already) */ + _mcd_dispatch_operation_finish (self, error->domain, error->code, + "%s", error->message); } static void @@ -1687,28 +1663,26 @@ _mcd_dispatch_operation_check_finished (McdDispatchOperation *self) { if (mcd_dispatch_operation_may_signal_finished (self)) { - GList *lost_channels; + McdChannel *lost_channel = self->priv->lost_channel; - /* get the lost channels into chronological order, and steal them from - * the object*/ - lost_channels = g_list_reverse (self->priv->lost_channels); - self->priv->lost_channels = NULL; + /* steal it */ + self->priv->lost_channel = NULL; - while (lost_channels != NULL) + if (lost_channel != NULL) { - McdChannel *channel = lost_channels->data; - const gchar *object_path = mcd_channel_get_object_path (channel); + const gchar *object_path = mcd_channel_get_object_path ( + lost_channel); if (object_path == NULL) { /* This shouldn't happen, but McdChannel is twisty enough * that I can't be sure */ g_critical ("McdChannel has already lost its TpChannel: %p", - channel); + lost_channel); } else { - const GError *error = mcd_channel_get_error (channel); + const GError *error = mcd_channel_get_error (lost_channel); gchar *error_name = _mcd_build_error_string (error); DEBUG ("%s/%p losing channel %s: %s: %s", @@ -1719,8 +1693,7 @@ _mcd_dispatch_operation_check_finished (McdDispatchOperation *self) g_free (error_name); } - g_object_unref (channel); - lost_channels = g_list_delete_link (lost_channels, lost_channels); + g_object_unref (lost_channel); } if (self->priv->result != NULL) @@ -1888,25 +1861,28 @@ _mcd_dispatch_operation_has_channel (McdDispatchOperation *self, McdChannel *channel) { g_return_val_if_fail (MCD_IS_DISPATCH_OPERATION (self), FALSE); - return (g_list_find (self->priv->channels, channel) != NULL); + + return (self->priv->channel != NULL && + self->priv->channel == channel); } -const GList * -_mcd_dispatch_operation_peek_channels (McdDispatchOperation *self) +McdChannel * +_mcd_dispatch_operation_peek_channel (McdDispatchOperation *self) { g_return_val_if_fail (MCD_IS_DISPATCH_OPERATION (self), NULL); - return self->priv->channels; + + return self->priv->channel; } -GList * -_mcd_dispatch_operation_dup_channels (McdDispatchOperation *self) +McdChannel * +_mcd_dispatch_operation_dup_channel (McdDispatchOperation *self) { - GList *copy; - g_return_val_if_fail (MCD_IS_DISPATCH_OPERATION (self), NULL); - copy = g_list_copy (self->priv->channels); - g_list_foreach (copy, (GFunc) g_object_ref, NULL); - return copy; + + if (self->priv->channel != NULL) + return g_object_ref (self->priv->channel); + + return NULL; } static void @@ -1926,11 +1902,10 @@ _mcd_dispatch_operation_handle_channels_cb (TpClient *client, } else { - const GList *list; - - for (list = self->priv->channels; list != NULL; list = list->next) + /* FIXME: can channel ever be NULL here? */ + if (self->priv->channel != NULL) { - McdChannel *channel = list->data; + McdChannel *channel = MCD_CHANNEL (self->priv->channel); const gchar *unique_name; unique_name = _mcd_client_proxy_get_unique_name (MCD_CLIENT_PROXY (client)); @@ -1959,18 +1934,19 @@ _mcd_dispatch_operation_handle_channels_cb (TpClient *client, g_warning ("Closing channel %s as a result", mcd_channel_get_object_path (channel)); _mcd_channel_undispatchable (channel); - continue; } - - mcd_dispatch_operation_set_channel_handled_by (self, channel, - unique_name, tp_proxy_get_bus_name (client)); + else + { + mcd_dispatch_operation_set_channel_handled_by (self, channel, + unique_name, tp_proxy_get_bus_name (client)); + } } /* emit Finished, if we haven't already; but first make a note of the * handler we used, so we can reply to all the HandleWith calls with * success or failure */ self->priv->successful_handler = g_object_ref (client); - _mcd_dispatch_operation_finish (self, TP_ERRORS, TP_ERROR_NOT_YOURS, + _mcd_dispatch_operation_finish (self, TP_ERROR, TP_ERROR_NOT_YOURS, "Channel successfully handled by %s", tp_proxy_get_bus_name (client)); } @@ -2002,36 +1978,25 @@ observe_channels_cb (TpClient *proxy, const GError *error, * request-properties for Observer_Info or Handler_Info */ static void -collect_satisfied_requests (const GList *channels, +collect_satisfied_requests (McdChannel *channel, GPtrArray **paths_out, GHashTable **props_out) { - const GList *c; - GHashTable *set; GHashTableIter it; gpointer path, value; GPtrArray *satisfied_requests; GHashTable *request_properties; + GHashTable *reqs; - set = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_object_unref); - - for (c = channels; c != NULL; c = c->next) - { - GHashTable *reqs = _mcd_channel_get_satisfied_requests (c->data, - NULL); - tp_g_hash_table_update (set, reqs, - (GBoxedCopyFunc) g_strdup, (GBoxedCopyFunc) g_object_ref); - g_hash_table_unref (reqs); - } + reqs = _mcd_channel_get_satisfied_requests (channel, NULL); - satisfied_requests = g_ptr_array_sized_new (g_hash_table_size (set)); + satisfied_requests = g_ptr_array_sized_new (g_hash_table_size (reqs)); g_ptr_array_set_free_func (satisfied_requests, g_free); request_properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_unref); - g_hash_table_iter_init (&it, set); + g_hash_table_iter_init (&it, reqs); while (g_hash_table_iter_next (&it, &path, &value)) { @@ -2043,7 +2008,7 @@ collect_satisfied_requests (const GList *channels, g_hash_table_insert (request_properties, g_strdup (path), props); } - g_hash_table_unref (set); + g_hash_table_unref (reqs); if (paths_out != NULL) *paths_out = satisfied_requests; @@ -2059,7 +2024,6 @@ collect_satisfied_requests (const GList *channels, static void _mcd_dispatch_operation_run_observers (McdDispatchOperation *self) { - const GList *cl; const gchar *dispatch_operation_path = "/"; GHashTable *observer_info; GHashTableIter iter; @@ -2072,7 +2036,7 @@ _mcd_dispatch_operation_run_observers (McdDispatchOperation *self) while (g_hash_table_iter_next (&iter, NULL, &client_p)) { McdClientProxy *client = MCD_CLIENT_PROXY (client_p); - GList *observed = NULL; + gboolean observed = FALSE; const gchar *account_path, *connection_path; GPtrArray *channels_array, *satisfied_requests; GHashTable *request_properties; @@ -2081,9 +2045,9 @@ _mcd_dispatch_operation_run_observers (McdDispatchOperation *self) TP_IFACE_QUARK_CLIENT_OBSERVER)) continue; - for (cl = self->priv->channels; cl != NULL; cl = cl->next) + if (self->priv->channel != NULL) { - McdChannel *channel = MCD_CHANNEL (cl->data); + McdChannel *channel = MCD_CHANNEL (self->priv->channel); GHashTable *properties; properties = _mcd_channel_get_immutable_properties (channel); @@ -2092,8 +2056,10 @@ _mcd_dispatch_operation_run_observers (McdDispatchOperation *self) if (_mcd_client_match_filters (properties, _mcd_client_proxy_get_observer_filters (client), FALSE)) - observed = g_list_prepend (observed, channel); + observed = TRUE; } + + /* in particular this happens if there is no channel at all */ if (!observed) continue; /* build up the parameters and invoke the observer */ @@ -2103,9 +2069,10 @@ _mcd_dispatch_operation_run_observers (McdDispatchOperation *self) /* TODO: there's room for optimization here: reuse the channels_array, * if the observed list is the same */ - channels_array = _mcd_tp_channel_details_build_from_list (observed); + channels_array = _mcd_tp_channel_details_build_from_tp_chan ( + mcd_channel_get_tp_channel (self->priv->channel)); - collect_satisfied_requests (observed, &satisfied_requests, + collect_satisfied_requests (self->priv->channel, &satisfied_requests, &request_properties); /* transfer ownership into observer_info */ @@ -2133,8 +2100,6 @@ _mcd_dispatch_operation_run_observers (McdDispatchOperation *self) g_ptr_array_unref (satisfied_requests); _mcd_tp_channel_details_free (channels_array); - - g_list_free (observed); } g_hash_table_unref (observer_info); @@ -2177,7 +2142,6 @@ add_dispatch_operation_cb (TpClient *proxy, static void _mcd_dispatch_operation_run_approvers (McdDispatchOperation *self) { - const GList *cl; GHashTableIter iter; gpointer client_p; @@ -2199,9 +2163,9 @@ _mcd_dispatch_operation_run_approvers (McdDispatchOperation *self) TP_IFACE_QUARK_CLIENT_APPROVER)) continue; - for (cl = self->priv->channels; cl != NULL; cl = cl->next) + if (self->priv->channel != NULL) { - McdChannel *channel = MCD_CHANNEL (cl->data); + McdChannel *channel = MCD_CHANNEL (self->priv->channel); GHashTable *channel_properties; channel_properties = _mcd_channel_get_immutable_properties (channel); @@ -2212,15 +2176,17 @@ _mcd_dispatch_operation_run_approvers (McdDispatchOperation *self) FALSE)) { matched = TRUE; - break; } } + + /* in particular, after this point, self->priv->channel can't + * be NULL */ if (!matched) continue; dispatch_operation = _mcd_dispatch_operation_get_path (self); properties = _mcd_dispatch_operation_get_properties (self); - channel_details = - _mcd_tp_channel_details_build_from_list (self->priv->channels); + channel_details = _mcd_tp_channel_details_build_from_tp_chan ( + mcd_channel_get_tp_channel (self->priv->channel)); DEBUG ("Calling AddDispatchOperation on approver %s for CDO %s @ %p", tp_proxy_get_bus_name (client), dispatch_operation, self); @@ -2266,7 +2232,7 @@ _mcd_dispatch_operation_run_clients (McdDispatchOperation *self) g_object_ref (self); DEBUG ("%s %p", self->priv->unique_name, self); - if (self->priv->channels != NULL) + if (self->priv->channel != NULL) { const GList *mini_plugins; @@ -2312,6 +2278,7 @@ _mcd_dispatch_operation_run_clients (McdDispatchOperation *self) static void mcd_dispatch_operation_handle_channels (McdDispatchOperation *self) { + GList *channels = NULL; GHashTable *handler_info; GHashTable *request_properties; @@ -2334,19 +2301,31 @@ mcd_dispatch_operation_handle_channels (McdDispatchOperation *self) return; } + /* FIXME: it shouldn't be possible to get here without a channel */ + if (self->priv->channel != NULL) + { + collect_satisfied_requests (self->priv->channel, NULL, + &request_properties); + channels = g_list_prepend (NULL, self->priv->channel); + } + else + { + request_properties = g_hash_table_new_full (g_str_hash, + g_str_equal, g_free, (GDestroyNotify) g_hash_table_unref); + } + handler_info = tp_asv_new (NULL, NULL); - collect_satisfied_requests (self->priv->channels, NULL, - &request_properties); tp_asv_take_boxed (handler_info, "request-properties", TP_HASH_TYPE_OBJECT_IMMUTABLE_PROPERTIES_MAP, request_properties); request_properties = NULL; _mcd_client_proxy_handle_channels (self->priv->trying_handler, - -1, self->priv->channels, self->priv->handle_with_time, + -1, channels, self->priv->handle_with_time, handler_info, _mcd_dispatch_operation_handle_channels_cb, g_object_ref (self), g_object_unref, NULL); g_hash_table_unref (handler_info); + g_list_free (channels); } static void @@ -2389,9 +2368,7 @@ mcd_dispatch_operation_try_handler (McdDispatchOperation *self, self->priv->handler_suitable_pending = 0; - DEBUG ("%s: channel ACL verification [%u channels]", - self->priv->unique_name, - g_list_length (self->priv->channels)); + DEBUG ("%s: channel ACL verification", self->priv->unique_name); for (p = mcp_list_objects (); p != NULL; p = g_list_next (p)) { @@ -2458,7 +2435,7 @@ _mcd_dispatch_operation_try_next_handler (McdDispatchOperation *self) * can legitimately try more handlers. */ if (approval->type == APPROVAL_TYPE_HANDLE_WITH) { - GError gone = { TP_ERRORS, + GError gone = { TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "The requested Handler does not exist" }; @@ -2499,8 +2476,6 @@ static void _mcd_dispatch_operation_close_as_undispatchable (McdDispatchOperation *self, const GError *error) { - GList *channels, *list; - /* All of the usable handlers vanished while we were thinking about it * (this can only happen if non-activatable handlers exit after we * include them in the list of possible handlers, but before we . @@ -2511,20 +2486,17 @@ _mcd_dispatch_operation_close_as_undispatchable (McdDispatchOperation *self, _mcd_dispatch_operation_finish (self, error->domain, error->code, "%s", error->message); - channels = _mcd_dispatch_operation_dup_channels (self); - - for (list = channels; list != NULL; list = list->next) + if (self->priv->channel != NULL) { - McdChannel *channel = MCD_CHANNEL (list->data); + McdChannel *channel = MCD_CHANNEL (self->priv->channel); GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Handler no longer available" }; + g_object_ref (channel); mcd_channel_take_error (channel, g_error_copy (&e)); _mcd_channel_undispatchable (channel); g_object_unref (channel); } - - g_list_free (channels); } void @@ -2553,20 +2525,18 @@ _mcd_dispatch_operation_end_plugin_delay (McdDispatchOperation *self) void _mcd_dispatch_operation_forget_channels (McdDispatchOperation *self) { - /* make a temporary copy, which is destroyed during the loop - otherwise - * we'll be trying to iterate over the list at the same time - * that mcd_mission_abort results in modifying it, which would be bad */ - GList *list = _mcd_dispatch_operation_dup_channels (self); - - while (list != NULL) + if (self->priv->channel != NULL) { - mcd_mission_abort (list->data); - g_object_unref (list->data); - list = g_list_delete_link (list, list); + /* Take a temporary copy, because self->priv->channels is going + * to be modified as a result of mcd_mission_abort() */ + McdChannel *channel = g_object_ref (self->priv->channel); + + mcd_mission_abort (MCD_MISSION (channel)); + g_object_unref (channel); } - /* There should now be none left (they all aborted) */ - g_return_if_fail (self->priv->channels == NULL); + /* There should now be no channel left (it was aborted) */ + g_return_if_fail (self->priv->channel == NULL); } void @@ -2574,20 +2544,19 @@ _mcd_dispatch_operation_leave_channels (McdDispatchOperation *self, TpChannelGroupChangeReason reason, const gchar *message) { - GList *list; - if (message == NULL) { message = ""; } - list = _mcd_dispatch_operation_dup_channels (self); - - while (list != NULL) + if (self->priv->channel != NULL) { - _mcd_channel_depart (list->data, reason, message); - g_object_unref (list->data); - list = g_list_delete_link (list, list); + /* Take a temporary copy, because self->priv->channels could + * be modified as a result */ + McdChannel *channel = g_object_ref (self->priv->channel); + + _mcd_channel_depart (channel, reason, message); + g_object_unref (channel); } _mcd_dispatch_operation_forget_channels (self); @@ -2596,13 +2565,14 @@ _mcd_dispatch_operation_leave_channels (McdDispatchOperation *self, void _mcd_dispatch_operation_close_channels (McdDispatchOperation *self) { - GList *list = _mcd_dispatch_operation_dup_channels (self); - - while (list != NULL) + if (self->priv->channel != NULL) { - _mcd_channel_close (list->data); - g_object_unref (list->data); - list = g_list_delete_link (list, list); + /* Take a temporary copy, because self->priv->channels could + * be modified as a result */ + McdChannel *channel = g_object_ref (self->priv->channel); + + _mcd_channel_close (channel); + g_object_unref (channel); } _mcd_dispatch_operation_forget_channels (self); @@ -2611,13 +2581,14 @@ _mcd_dispatch_operation_close_channels (McdDispatchOperation *self) void _mcd_dispatch_operation_destroy_channels (McdDispatchOperation *self) { - GList *list = _mcd_dispatch_operation_dup_channels (self); - - while (list != NULL) + if (self->priv->channel != NULL) { - _mcd_channel_undispatchable (list->data); - g_object_unref (list->data); - list = g_list_delete_link (list, list); + /* Take a temporary copy, because self->priv->channels could + * be modified as a result */ + McdChannel *channel = g_object_ref (self->priv->channel); + + _mcd_channel_undispatchable (channel); + g_object_unref (channel); } _mcd_dispatch_operation_forget_channels (self); diff --git a/src/mcd-dispatcher-context.h b/src/mcd-dispatcher-context.h deleted file mode 100644 index 4f2f6b39..00000000 --- a/src/mcd-dispatcher-context.h +++ /dev/null @@ -1,113 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* - * This file is part of mission-control - * - * Copyright (C) 2007-2009 Nokia Corporation. - * - * Contact: Naba Kumar <naba.kumar@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef __MCD_DISPATCHER_CONTEXT_H__ -#define __MCD_DISPATCHER_CONTEXT_H__ - -#include "mcd-dispatcher.h" -#include "mcd-connection.h" - -G_BEGIN_DECLS - -/* Filter flag definitions */ -#define MCD_FILTER_IN 1<<0 -#define MCD_FILTER_OUT 1<<1 - -/* The context of the current filter chain execution. Should be kept - * intact by filter implementation and passed transparently to - * getters/setters and state machine functions - */ -typedef struct _McdDispatcherContext McdDispatcherContext; - -/* Filter function type */ -typedef void (*McdFilterFunc) (McdDispatcherContext * ctx, gpointer user_data); - -/* Filter priorities */ -#define MCD_FILTER_PRIORITY_CRITICAL 10000 -#define MCD_FILTER_PRIORITY_SYSTEM 20000 -#define MCD_FILTER_PRIORITY_USER 30000 -#define MCD_FILTER_PRIORITY_NOTICE 40000 -#define MCD_FILTER_PRIORITY_LOW 50000 - -typedef struct filter_t { - McdFilterFunc func; - guint priority; - gpointer user_data; -} McdFilter; - -void mcd_dispatcher_add_filter (McdDispatcher *dispatcher, - McdFilterFunc filter, - guint priority, - gpointer user_data); -void mcd_dispatcher_add_filters (McdDispatcher *dispatcher, - const McdFilter *filters); - -/* Context API section - * - * The use of gpointer is intentional; we want to make accessing the - * internals of the context restricted to make it unlikely that - * somebody shoots [him|her]self in the foot while doing fancy - * tricks. This also minimizes the amount of necessary includes. - */ - -/* Getters */ - -McdDispatcher* mcd_dispatcher_context_get_dispatcher (McdDispatcherContext * ctx); - -TpChannel *mcd_dispatcher_context_get_channel_object (McdDispatcherContext * ctx) G_GNUC_DEPRECATED; - -TpConnection *mcd_dispatcher_context_get_connection_object (McdDispatcherContext * ctx) G_GNUC_DEPRECATED; - -McdChannel * mcd_dispatcher_context_get_channel (McdDispatcherContext * ctx); -const GList *mcd_dispatcher_context_get_channels - (McdDispatcherContext *context); -McdChannel *mcd_dispatcher_context_get_channel_by_type - (McdDispatcherContext *context, GQuark type); - -McdConnection *mcd_dispatcher_context_get_connection - (McdDispatcherContext *context); - -void mcd_dispatcher_context_close_all (McdDispatcherContext *context, - TpChannelGroupChangeReason reason, - const gchar *message); - -void mcd_dispatcher_context_destroy_all (McdDispatcherContext *context); - -void mcd_dispatcher_context_forget_all (McdDispatcherContext *context); - -/* Statemachine API section */ - -/* Will step through the state machine. - * @param ctx: The context - * @param result: The return code - */ - -void mcd_dispatcher_context_proceed (McdDispatcherContext *context); - -void mcd_dispatcher_context_process (McdDispatcherContext * ctx, gboolean result); - -G_END_DECLS - -#endif diff --git a/src/mcd-dispatcher-priv.h b/src/mcd-dispatcher-priv.h index 9e65f7f8..639d751a 100644 --- a/src/mcd-dispatcher-priv.h +++ b/src/mcd-dispatcher-priv.h @@ -33,19 +33,11 @@ G_BEGIN_DECLS -/* retrieves the channel handlers' capabilities, in a format suitable for being - * used as a parameter for the telepathy "AdvertiseCapabilities" method */ -G_GNUC_INTERNAL GPtrArray *_mcd_dispatcher_get_channel_capabilities ( - McdDispatcher *dispatcher); - -/* retrieves the channel handlers' capabilities, in a format suitable for being - * used as a parameter for the telepathy "SetSelfCapabilities" method */ -G_GNUC_INTERNAL GPtrArray *_mcd_dispatcher_get_channel_enhanced_capabilities ( - McdDispatcher *dispatcher); - /* not exported */ -G_GNUC_INTERNAL void _mcd_dispatcher_take_channels ( - McdDispatcher *dispatcher, GList *channels, gboolean requested, +G_GNUC_INTERNAL void _mcd_dispatcher_add_channel ( + McdDispatcher *dispatcher, + McdChannel *channel, + gboolean requested, gboolean only_observe); G_GNUC_INTERNAL void _mcd_dispatcher_add_channel_request (McdDispatcher *dispatcher, @@ -62,9 +54,6 @@ G_GNUC_INTERNAL void _mcd_dispatcher_add_connection (McdDispatcher *self, G_GNUC_INTERNAL GPtrArray *_mcd_dispatcher_dup_client_caps ( McdDispatcher *self); -G_GNUC_INTERNAL McdClientRegistry *_mcd_dispatcher_get_client_registry ( - McdDispatcher *self); - G_END_DECLS #endif /* MCD_DISPATCHER_H */ diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c index 3abbd388..48ebc833 100644 --- a/src/mcd-dispatcher.c +++ b/src/mcd-dispatcher.c @@ -35,6 +35,8 @@ * FIXME */ +#include "config.h" + #include <dlfcn.h> #include <glib.h> #include <glib/gprintf.h> @@ -44,7 +46,6 @@ #include "mission-control-plugins/mission-control-plugins.h" #include "client-registry.h" -#include "mcd-signals-marshal.h" #include "mcd-account-priv.h" #include "mcd-client-priv.h" #include "mcd-connection.h" @@ -52,7 +53,6 @@ #include "mcd-channel.h" #include "mcd-master.h" #include "mcd-channel-priv.h" -#include "mcd-dispatcher-context.h" #include "mcd-dispatcher-priv.h" #include "mcd-dispatch-operation-priv.h" #include "mcd-handler-map-priv.h" @@ -61,15 +61,10 @@ #include "_gen/svc-dispatcher.h" -#include <telepathy-glib/defs.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/handle-repo.h> -#include <telepathy-glib/handle-repo-dynamic.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> + #include <telepathy-glib/proxy-subclass.h> -#include <telepathy-glib/svc-channel-dispatcher.h> -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/util.h> #include <stdlib.h> #include <string.h> @@ -86,7 +81,7 @@ static void dispatcher_iface_init (gpointer, gpointer); static void messages_iface_init (gpointer, gpointer); -G_DEFINE_TYPE_WITH_CODE (McdDispatcher, mcd_dispatcher, MCD_TYPE_MISSION, +G_DEFINE_TYPE_WITH_CODE (McdDispatcher, mcd_dispatcher, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_DISPATCHER, dispatcher_iface_init); G_IMPLEMENT_INTERFACE (MC_TYPE_SVC_CHANNEL_DISPATCHER_INTERFACE_MESSAGES_DRAFT, @@ -97,21 +92,6 @@ G_DEFINE_TYPE_WITH_CODE (McdDispatcher, mcd_dispatcher, MCD_TYPE_MISSION, G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, tp_dbus_properties_mixin_iface_init)) -struct _McdDispatcherContext -{ - gint ref_count; - - McdDispatcher *dispatcher; - - McdDispatchOperation *operation; - - /* State-machine internal data fields: */ - GList *chain; - - /* Next function in chain */ - guint next_func_index; -}; - typedef struct { McdDispatcher *dispatcher; @@ -141,9 +121,6 @@ struct _McdDispatcherPrivate TpDBusDaemon *dbus_daemon; - /* list of McdFilter elements */ - GList *filters; - /* hash table containing clients * char *bus_name -> McdClientProxy */ McdClientRegistry *clients; @@ -181,113 +158,15 @@ enum PROP_DISPATCH_OPERATIONS, }; -static void mcd_dispatcher_context_unref (McdDispatcherContext * ctx, - const gchar *tag); static void on_operation_finished (McdDispatchOperation *operation, McdDispatcher *self); - -static inline void -mcd_dispatcher_context_ref (McdDispatcherContext *context, - const gchar *tag) -{ - g_return_if_fail (context != NULL); - DEBUG ("%s on %p (ref = %d)", tag, context, context->ref_count); - context->ref_count++; -} - -static GList * -chain_add_filter (GList *chain, - McdFilterFunc filter, - guint priority, - gpointer user_data) -{ - GList *elem; - McdFilter *filter_data; - - filter_data = g_slice_new (McdFilter); - filter_data->func = filter; - filter_data->priority = priority; - filter_data->user_data = user_data; - for (elem = chain; elem; elem = elem->next) - if (((McdFilter *)elem->data)->priority >= priority) break; - - return g_list_insert_before (chain, elem, filter_data); -} - -/* Returns # of times particular channel type has been used */ -gint -mcd_dispatcher_get_channel_type_usage (McdDispatcher * dispatcher, - GQuark chan_type_quark) -{ - const GList *managers, *connections, *channels; - McdDispatcherPrivate *priv = dispatcher->priv; - gint usage_counter = 0; - - managers = mcd_operation_get_missions (MCD_OPERATION (priv->master)); - while (managers) - { - connections = - mcd_operation_get_missions (MCD_OPERATION (managers->data)); - while (connections) - { - channels = - mcd_operation_get_missions (MCD_OPERATION (connections->data)); - while (channels) - { - McdChannel *channel = MCD_CHANNEL (channels->data); - McdChannelStatus status; - - status = mcd_channel_get_status (channel); - if ((status == MCD_CHANNEL_STATUS_DISPATCHING || - status == MCD_CHANNEL_STATUS_HANDLER_INVOKED || - status == MCD_CHANNEL_STATUS_DISPATCHED) && - mcd_channel_get_channel_type_quark (channel) == - chan_type_quark) - { - DEBUG ("Channel %p is active", channel); - usage_counter++; - } - channels = channels->next; - } - connections = connections->next; - } - managers = managers->next; - } - - return usage_counter; -} - static void on_master_abort (McdMaster *master, McdDispatcherPrivate *priv) { tp_clear_object (&priv->master); } -/* return TRUE if the two channel classes are equals - */ -static gboolean -channel_classes_equals (GHashTable *channel_class1, GHashTable *channel_class2) -{ - GHashTableIter iter; - gchar *property_name; - GValue *property_value; - - if (g_hash_table_size (channel_class1) != - g_hash_table_size (channel_class2)) - return FALSE; - - g_hash_table_iter_init (&iter, channel_class1); - while (g_hash_table_iter_next (&iter, (gpointer *) &property_name, - (gpointer *) &property_value)) - { - if (!_mcd_client_match_property (channel_class2, property_name, - property_value)) - return FALSE; - } - return TRUE; -} - static GStrv mcd_dispatcher_dup_internal_handlers (void) { @@ -299,14 +178,14 @@ mcd_dispatcher_dup_internal_handlers (void) static GStrv mcd_dispatcher_dup_possible_handlers (McdDispatcher *self, McdRequest *request, - const GList *channels, + TpChannel *channel, const gchar *must_have_unique_name) { GList *handlers = _mcd_client_registry_list_possible_handlers ( self->priv->clients, request != NULL ? _mcd_request_get_preferred_handler (request) : NULL, request != NULL ? _mcd_request_get_properties (request) : NULL, - channels, must_have_unique_name); + channel, must_have_unique_name); guint n_handlers = g_list_length (handlers); guint i; GStrv ret; @@ -329,42 +208,6 @@ mcd_dispatcher_dup_possible_handlers (McdDispatcher *self, return ret; } -/* - * _mcd_dispatcher_context_abort: - * - * Abort processing of all the channels in the @context, as if they could not - * be dispatched. - * - * This should only be invoked because filter plugins want to terminate a - * channel. - */ -static void -_mcd_dispatcher_context_abort (McdDispatcherContext *context, - const GError *error) -{ - GList *list; - - g_return_if_fail (context); - - /* make a temporary copy, which is destroyed during the loop - otherwise - * we'll be trying to iterate over the list at the same time - * that mcd_mission_abort results in modifying it, which would be bad */ - list = _mcd_dispatch_operation_dup_channels (context->operation); - - while (list != NULL) - { - McdChannel *channel = MCD_CHANNEL (list->data); - - if (mcd_channel_get_error (channel) == NULL) - mcd_channel_take_error (channel, g_error_copy (error)); - - _mcd_channel_undispatchable (channel); - - g_object_unref (channel); - list = g_list_delete_link (list, list); - } -} - static void on_operation_finished (McdDispatchOperation *operation, McdDispatcher *self) @@ -395,21 +238,20 @@ on_operation_finished (McdDispatchOperation *operation, static void _mcd_dispatcher_enter_state_machine (McdDispatcher *dispatcher, - GList *channels, + McdChannel *channel, const gchar * const *possible_handlers, gboolean requested, gboolean only_observe) { - McdDispatcherContext *context; + McdDispatchOperation *operation; McdDispatcherPrivate *priv; McdAccount *account; g_return_if_fail (MCD_IS_DISPATCHER (dispatcher)); - g_return_if_fail (channels != NULL); - g_return_if_fail (MCD_IS_CHANNEL (channels->data)); + g_return_if_fail (MCD_IS_CHANNEL (channel)); g_return_if_fail (requested || !only_observe); - account = mcd_channel_get_account (channels->data); + account = mcd_channel_get_account (channel); if (G_UNLIKELY (!account)) { g_warning ("%s called with no account", G_STRFUNC); @@ -418,26 +260,13 @@ _mcd_dispatcher_enter_state_machine (McdDispatcher *dispatcher, priv = dispatcher->priv; - /* Preparing and filling the context */ - context = g_new0 (McdDispatcherContext, 1); - DEBUG ("CTXREF11 on %p", context); - context->ref_count = 1; - context->dispatcher = dispatcher; - context->chain = priv->filters; - - DEBUG ("new dispatcher context %p for %s channel %p (%s): %s", - context, requested ? "requested" : "unrequested", - channels->data, - channels->next == NULL ? "only" : "and more", - mcd_channel_get_object_path (channels->data)); - - /* FIXME: what should we do when the channels are a mixture of Requested - * and unRequested? At the moment we act as though they're all Requested; - * perhaps we should act as though they're all unRequested, or split up the - * bundle? */ - - context->operation = _mcd_dispatch_operation_new (priv->clients, - priv->handler_map, !requested, only_observe, channels, + DEBUG ("new dispatch operation for %s channel %p: %s", + requested ? "requested" : "unrequested", + channel, + mcd_channel_get_object_path (channel)); + + operation = _mcd_dispatch_operation_new (priv->clients, + priv->handler_map, !requested, only_observe, channel, (const gchar * const *) possible_handlers); if (!requested) @@ -446,25 +275,45 @@ _mcd_dispatcher_enter_state_machine (McdDispatcher *dispatcher, { tp_svc_channel_dispatcher_interface_operation_list_emit_new_dispatch_operation ( dispatcher, - _mcd_dispatch_operation_get_path (context->operation), - _mcd_dispatch_operation_get_properties (context->operation)); + _mcd_dispatch_operation_get_path (operation), + _mcd_dispatch_operation_get_properties (operation)); } priv->operations = g_list_prepend (priv->operations, - g_object_ref (context->operation)); + g_object_ref (operation)); - g_signal_connect (context->operation, "finished", + g_signal_connect (operation, "finished", G_CALLBACK (on_operation_finished), dispatcher); } - DEBUG ("entering state machine for context %p", context); + if (_mcd_dispatch_operation_get_cancelled (operation)) + { + GError error = { TP_ERROR, TP_ERROR_CANCELLED, + "Channel request cancelled" }; + McdChannel *cancelled; + + cancelled = _mcd_dispatch_operation_dup_channel (operation); - sp_timestamp ("invoke internal filters"); + if (cancelled != NULL) + { + if (mcd_channel_get_error (cancelled) == NULL) + mcd_channel_take_error (cancelled, g_error_copy (&error)); - mcd_dispatcher_context_ref (context, "CTXREF01"); - mcd_dispatcher_context_proceed (context); + _mcd_channel_undispatchable (cancelled); - mcd_dispatcher_context_unref (context, "CTXREF11"); + g_object_unref (cancelled); + } + } + else if (_mcd_dispatch_operation_peek_channel (operation) == NULL) + { + DEBUG ("No channels left"); + } + else + { + _mcd_dispatch_operation_run_clients (operation); + } + + g_object_unref (operation); } static void @@ -571,22 +420,6 @@ _mcd_dispatcher_get_property (GObject * obj, guint prop_id, } static void -_mcd_dispatcher_finalize (GObject * object) -{ - McdDispatcherPrivate *priv = MCD_DISPATCHER_PRIV (object); - - if (priv->filters) - { - GList *list; - for (list = priv->filters; list != NULL; list = list->next) - g_slice_free (McdFilter, list->data); - g_list_free (priv->filters); - } - - G_OBJECT_CLASS (mcd_dispatcher_parent_class)->finalize (object); -} - -static void mcd_dispatcher_client_handling_channel_cb (McdClientProxy *client, const gchar *object_path, McdDispatcher *self) @@ -699,7 +532,6 @@ _mcd_dispatcher_lookup_handler (McdDispatcher *self, if (handler == NULL) { GList *possible_handlers; - GList *channels; /* Failing that, maybe the Handler it was dispatched to was temporary; * try to pick another Handler that can deal with it, on the same @@ -707,12 +539,11 @@ _mcd_dispatcher_lookup_handler (McdDispatcher *self, * It can also happen in the case an Observer/Approver Claimed the * channel; in that case we did not get its handler well known name. */ - channels = g_list_prepend (NULL, channel); possible_handlers = _mcd_client_registry_list_possible_handlers ( self->priv->clients, request != NULL ? _mcd_request_get_preferred_handler (request) : NULL, request != NULL ? _mcd_request_get_properties (request) : NULL, - channels, unique_name); + channel, unique_name); if (possible_handlers != NULL) { @@ -729,7 +560,6 @@ _mcd_dispatcher_lookup_handler (McdDispatcher *self, unique_name, object_path); } - g_list_free (channels); g_list_free (possible_handlers); } @@ -785,11 +615,11 @@ mcd_dispatcher_client_needs_recovery_cb (McdClientProxy *client, if (_mcd_dispatch_operation_has_invoked_observers (op)) { - for (channels = _mcd_dispatch_operation_peek_channels (op); - channels != NULL; - channels = channels->next) + McdChannel *mcd_channel = + _mcd_dispatch_operation_peek_channel (op); + + if (mcd_channel != NULL) { - McdChannel *mcd_channel = channels->data; GHashTable *properties = _mcd_channel_get_immutable_properties (mcd_channel); @@ -1009,7 +839,6 @@ mcd_dispatcher_class_init (McdDispatcherClass * klass) object_class->constructed = mcd_dispatcher_constructed; object_class->set_property = _mcd_dispatcher_set_property; object_class->get_property = _mcd_dispatcher_get_property; - object_class->finalize = _mcd_dispatcher_finalize; object_class->dispose = _mcd_dispatcher_dispose; /* Properties */ @@ -1050,26 +879,6 @@ mcd_dispatcher_class_init (McdDispatcherClass * klass) } static void -_build_channel_capabilities (const gchar *channel_type, guint type_flags, - GPtrArray *capabilities) -{ - GValue cap = {0,}; - GType cap_type; - - cap_type = dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, - G_TYPE_UINT, G_TYPE_INVALID); - g_value_init (&cap, cap_type); - g_value_take_boxed (&cap, dbus_g_type_specialized_construct (cap_type)); - - dbus_g_type_struct_set (&cap, - 0, channel_type, - 1, type_flags, - G_MAXUINT); - - g_ptr_array_add (capabilities, g_value_get_boxed (&cap)); -} - -static void mcd_dispatcher_init (McdDispatcher * dispatcher) { McdDispatcherPrivate *priv; @@ -1097,366 +906,32 @@ mcd_dispatcher_new (TpDBusDaemon *dbus_daemon, McdMaster *master) return obj; } -/** - * mcd_dispatcher_context_proceed: - * @context: a #McdDispatcherContext - * - * Must be called by plugin filters exactly once per invocation of the filter - * function, to proceed with processing of the @context. This does nothing - * if @context has already finished. - */ -void -mcd_dispatcher_context_proceed (McdDispatcherContext *context) -{ - GError error = { TP_ERRORS, 0, NULL }; - McdFilter *filter; - - if (_mcd_dispatch_operation_get_cancelled (context->operation)) - { - error.code = TP_ERROR_CANCELLED; - error.message = "Channel request cancelled"; - _mcd_dispatcher_context_abort (context, &error); - goto no_more; - } - - if (_mcd_dispatch_operation_peek_channels (context->operation) == NULL) - { - DEBUG ("No channels left"); - goto no_more; - } - - filter = g_list_nth_data (context->chain, context->next_func_index); - - if (filter != NULL) - { - context->next_func_index++; - DEBUG ("Next filter"); - mcd_dispatcher_context_ref (context, "CTXREF10"); - filter->func (context, filter->user_data); - mcd_dispatcher_context_unref (context, "CTXREF10"); - /* The state machine goes on... this function will be invoked again - * (perhaps recursively, or perhaps later) by filter->func. */ - return; - } - -no_more: /* either no more filters, or no more channels */ - _mcd_dispatch_operation_run_clients (context->operation); - mcd_dispatcher_context_unref (context, "CTXREF01"); -} - -/** - * mcd_dispatcher_context_forget_all: - * @context: a #McdDispatcherContext - * - * Stop processing channels in @context, but do not close them. They will - * no longer be dispatched, and the ChannelDispatchOperation (if any) - * will emit ChannelLost. - */ -void -mcd_dispatcher_context_forget_all (McdDispatcherContext *context) -{ - g_return_if_fail (context); - _mcd_dispatch_operation_forget_channels (context->operation); -} - -/** - * mcd_dispatcher_context_destroy_all: - * @context: a #McdDispatcherContext - * - * Consider all channels in the #McdDispatcherContext to be undispatchable, - * and close them destructively. Information loss might result. - * - * Plugins must still call mcd_dispatcher_context_proceed() afterwards, - * to release their reference to the dispatcher context. - */ -void -mcd_dispatcher_context_destroy_all (McdDispatcherContext *context) -{ - g_return_if_fail (context); - _mcd_dispatch_operation_destroy_channels (context->operation); -} - -/** - * mcd_dispatcher_context_close_all: - * @context: a #McdDispatcherContext - * @reason: a reason code - * @message: a message to be used if applicable, which should be "" if - * no message is appropriate - * - * Close all channels in the #McdDispatcherContext. If @reason is not - * %TP_CHANNEL_GROUP_CHANGE_REASON_NONE and/or @message is non-empty, - * attempt to use the RemoveMembersWithReason D-Bus method to specify - * a message and reason, falling back to the Close method if that doesn't - * work. - * - * Plugins must still call mcd_dispatcher_context_proceed() afterwards, - * to release their reference to the dispatcher context. - */ -void -mcd_dispatcher_context_close_all (McdDispatcherContext *context, - TpChannelGroupChangeReason reason, - const gchar *message) -{ - g_return_if_fail (context); - _mcd_dispatch_operation_leave_channels (context->operation, reason, - message); -} - -/** - * mcd_dispatcher_context_process: - * @context: a #McdDispatcherContext - * @result: %FALSE if the channels are to be destroyed - * - * Continue to process the @context. - * - * mcd_dispatcher_context_process (c, TRUE) is exactly equivalent to - * mcd_dispatcher_context_proceed (c), which should be used instead in new - * code. - * - * mcd_dispatcher_context_process (c, FALSE) is exactly equivalent to - * mcd_dispatcher_context_destroy_all (c) followed by - * mcd_dispatcher_context_proceed (c), which should be used instead in new - * code. - */ -void -mcd_dispatcher_context_process (McdDispatcherContext * context, gboolean result) -{ - if (!result) - { - _mcd_dispatch_operation_destroy_channels (context->operation); - } - - mcd_dispatcher_context_proceed (context); -} - -static void -mcd_dispatcher_context_unref (McdDispatcherContext * context, - const gchar *tag) -{ - /* FIXME: check for leaks */ - g_return_if_fail (context); - g_return_if_fail (context->ref_count > 0); - - DEBUG ("%s on %p (ref = %d)", tag, context, context->ref_count); - context->ref_count--; - if (context->ref_count == 0) - { - DEBUG ("freeing the context %p", context); - g_object_unref (context->operation); - g_free (context); - } -} - -/* CONTEXT API */ - -/* Context getters */ -TpChannel * -mcd_dispatcher_context_get_channel_object (McdDispatcherContext * ctx) -{ - TpChannel *tp_chan; - g_return_val_if_fail (ctx, 0); - g_object_get (G_OBJECT (mcd_dispatcher_context_get_channel (ctx)), - "tp-channel", &tp_chan, NULL); - g_object_unref (G_OBJECT (tp_chan)); - return tp_chan; -} - -McdDispatcher* -mcd_dispatcher_context_get_dispatcher (McdDispatcherContext * ctx) -{ - return ctx->dispatcher; -} - -/** - * mcd_dispatcher_context_get_connection: - * @context: the #McdDispatcherContext. - * - * Returns: the #McdConnection. - */ -McdConnection * -mcd_dispatcher_context_get_connection (McdDispatcherContext *context) -{ - const GList *channels = mcd_dispatcher_context_get_channels (context); - - g_return_val_if_fail (channels != NULL, NULL); - return MCD_CONNECTION (mcd_mission_get_parent - (MCD_MISSION (channels->data))); -} - -TpConnection * -mcd_dispatcher_context_get_connection_object (McdDispatcherContext * ctx) -{ - const McdConnection *connection; - TpConnection *tp_conn; - - connection = mcd_dispatcher_context_get_connection (ctx); - g_object_get (G_OBJECT (connection), "tp-connection", - &tp_conn, NULL); - - g_object_unref (tp_conn); - return tp_conn; -} - -McdChannel * -mcd_dispatcher_context_get_channel (McdDispatcherContext * ctx) -{ - const GList *channels = mcd_dispatcher_context_get_channels (ctx); - - return channels ? MCD_CHANNEL (channels->data) : NULL; -} - -/** - * mcd_dispatcher_context_get_channels: - * @context: the #McdDispatcherContext. - * - * Returns: a #GList of #McdChannel elements. - */ -const GList * -mcd_dispatcher_context_get_channels (McdDispatcherContext *context) -{ - g_return_val_if_fail (context != NULL, NULL); - return _mcd_dispatch_operation_peek_channels (context->operation); -} - -/** - * mcd_dispatcher_context_get_channel_by_type: - * @context: the #McdDispatcherContext. - * @type: the #GQuark representing the channel type. - * - * Returns: the first #McdChannel of the requested type, or %NULL. - */ -McdChannel * -mcd_dispatcher_context_get_channel_by_type (McdDispatcherContext *context, - GQuark type) -{ - const GList *list; - - g_return_val_if_fail (context != NULL, NULL); - for (list = mcd_dispatcher_context_get_channels (context); - list != NULL; - list = list->next) - { - McdChannel *channel = MCD_CHANNEL (list->data); - - if (mcd_channel_get_channel_type_quark (channel) == type) - return channel; - } - return NULL; -} - -GPtrArray * -_mcd_dispatcher_get_channel_capabilities (McdDispatcher *dispatcher) -{ - McdDispatcherPrivate *priv = dispatcher->priv; - GPtrArray *channel_handler_caps; - GHashTableIter iter; - gpointer key, value; - - channel_handler_caps = g_ptr_array_new (); - - /* Add the capabilities from the new-style clients */ - _mcd_client_registry_init_hash_iter (priv->clients, &iter); - while (g_hash_table_iter_next (&iter, &key, &value)) - { - McdClientProxy *client = value; - const GList *list; - - for (list = _mcd_client_proxy_get_handler_filters (client); - list != NULL; - list = list->next) - { - GHashTable *channel_class = list->data; - const gchar *channel_type; - guint type_flags; - - channel_type = tp_asv_get_string (channel_class, - TP_IFACE_CHANNEL ".ChannelType"); - if (!channel_type) continue; - - /* There is currently no way to map the HandlerChannelFilter client - * property into type-specific capabilities. Let's pretend we - * support everything. */ - type_flags = 0xffffffff; - - _build_channel_capabilities (channel_type, type_flags, - channel_handler_caps); - } - } - return channel_handler_caps; -} - -GPtrArray * -_mcd_dispatcher_get_channel_enhanced_capabilities (McdDispatcher *dispatcher) -{ - McdDispatcherPrivate *priv = dispatcher->priv; - GHashTableIter iter; - gpointer key, value; - GPtrArray *caps = g_ptr_array_new (); - - _mcd_client_registry_init_hash_iter (priv->clients, &iter); - while (g_hash_table_iter_next (&iter, &key, &value)) - { - McdClientProxy *client = value; - const GList *list; - - for (list = _mcd_client_proxy_get_handler_filters (client); - list != NULL; - list = list->next) - { - GHashTable *channel_class = list->data; - guint i; - gboolean already_in_caps = FALSE; - - /* Check if the filter is already in the caps variable */ - for (i = 0 ; i < caps->len ; i++) - { - GHashTable *channel_class2 = g_ptr_array_index (caps, i); - if (channel_classes_equals (channel_class, channel_class2)) - { - already_in_caps = TRUE; - break; - } - } - - if (! already_in_caps) - g_ptr_array_add (caps, channel_class); - } - } - - return caps; -} - /* - * _mcd_dispatcher_take_channels: + * _mcd_dispatcher_add_channel: * @dispatcher: the #McdDispatcher. - * @channels: a #GList of #McdChannel elements, each of which must own a - * #TpChannel + * @channel: (transfer none): a #McdChannel which must own a #TpChannel * @requested: whether the channels were requested by MC. * - * Dispatch @channels. The #GList @channels will be no longer valid after this - * function has been called. + * Add @channel to the dispatching state machine. */ void -_mcd_dispatcher_take_channels (McdDispatcher *dispatcher, GList *channels, - gboolean requested, gboolean only_observe) +_mcd_dispatcher_add_channel (McdDispatcher *dispatcher, + McdChannel *channel, + gboolean requested, + gboolean only_observe) { - GList *list; - GList *tp_channels = NULL; + TpChannel *tp_channel = NULL; GStrv possible_handlers; McdRequest *request = NULL; gboolean internal_request = FALSE; - if (channels == NULL) - { - DEBUG ("trivial case - no channels"); - return; - } + g_return_if_fail (MCD_IS_DISPATCHER (dispatcher)); + g_return_if_fail (MCD_IS_CHANNEL (channel)); - DEBUG ("%s channel %p (%s): %s", + DEBUG ("%s channel %p: %s", requested ? "requested" : "unrequested", - channels->data, - channels->next == NULL ? "only" : "and more", - mcd_channel_get_object_path (channels->data)); + channel, + mcd_channel_get_object_path (channel)); if (only_observe) { @@ -1464,29 +939,17 @@ _mcd_dispatcher_take_channels (McdDispatcher *dispatcher, GList *channels, /* these channels were requested "behind our back", so only call * ObserveChannels on them */ - _mcd_dispatcher_enter_state_machine (dispatcher, channels, NULL, + _mcd_dispatcher_enter_state_machine (dispatcher, channel, NULL, TRUE, TRUE); - g_list_free (channels); return; } - /* These channels must have the TpChannel part of McdChannel's double life. - * They might also have the McdRequest part. */ - for (list = channels; list != NULL; list = list->next) - { - TpChannel *tp_channel = mcd_channel_get_tp_channel (list->data); - - g_assert (tp_channel != NULL); - tp_channels = g_list_prepend (tp_channels, g_object_ref (tp_channel)); - - /* We take the channel request from the first McdChannel that (has|is) - * one.*/ - if (request == NULL) - { - request = _mcd_channel_get_request (list->data); - } - } + /* The channel must have the TpChannel part of McdChannel's double life. + * It might also have the McdRequest part. */ + tp_channel = mcd_channel_get_tp_channel (channel); + g_assert (tp_channel != NULL); + request = _mcd_channel_get_request (channel); internal_request = _mcd_request_is_internal (request); /* See if there are any handlers that can take all these channels */ @@ -1495,98 +958,28 @@ _mcd_dispatcher_take_channels (McdDispatcher *dispatcher, GList *channels, else possible_handlers = mcd_dispatcher_dup_possible_handlers (dispatcher, request, - tp_channels, + tp_channel, NULL); - g_list_foreach (tp_channels, (GFunc) g_object_unref, NULL); - g_list_free (tp_channels); - if (possible_handlers == NULL) { - if (channels->next == NULL) - { - DEBUG ("One channel, which cannot be handled - making a CDO " - "anyway, to get Observers run"); - } - else - { - DEBUG ("Two or more channels, which cannot all be handled - " - "will split up the batch and try again"); - - while (channels != NULL) - { - list = channels; - channels = g_list_remove_link (channels, list); - _mcd_dispatcher_take_channels (dispatcher, list, requested, - FALSE); - } - - return; - } + DEBUG ("Channel cannot be handled - making a CDO " + "anyway, to get Observers run"); } else { - DEBUG ("%s handler(s) found, dispatching %u channels", - internal_request ? "internal" : "possible", - g_list_length (channels)); + DEBUG ("%s handler(s) found, dispatching channel", + internal_request ? "internal" : "possible"); } - for (list = channels; list != NULL; list = list->next) - _mcd_channel_set_status (MCD_CHANNEL (list->data), - MCD_CHANNEL_STATUS_DISPATCHING); + _mcd_channel_set_status (channel, MCD_CHANNEL_STATUS_DISPATCHING); - _mcd_dispatcher_enter_state_machine (dispatcher, channels, + _mcd_dispatcher_enter_state_machine (dispatcher, channel, (const gchar * const *) possible_handlers, requested, FALSE); - g_list_free (channels); g_strfreev (possible_handlers); } -/** - * mcd_dispatcher_add_filter: - * @dispatcher: The #McdDispatcher. - * @filter: the filter function to be registered. - * @priority: The priority of the filter. - * @user_data: user data to be passed to @filter on invocation. - * - * Register a filter into the dispatcher chain: @filter will be invoked - * whenever channels need to be dispatched. - */ -void -mcd_dispatcher_add_filter (McdDispatcher *dispatcher, - McdFilterFunc filter, - guint priority, - gpointer user_data) -{ - McdDispatcherPrivate *priv; - - g_return_if_fail (MCD_IS_DISPATCHER (dispatcher)); - priv = dispatcher->priv; - priv->filters = - chain_add_filter (priv->filters, filter, priority, user_data); -} - -/** - * mcd_dispatcher_add_filters: - * @dispatcher: The #McdDispatcher. - * @filters: a zero-terminated array of #McdFilter elements. - * - * Convenience function to add a batch of filters at once. - */ -void -mcd_dispatcher_add_filters (McdDispatcher *dispatcher, - const McdFilter *filters) -{ - const McdFilter *filter; - - g_return_if_fail (filters != NULL); - - for (filter = filters; filter->func != NULL; filter++) - mcd_dispatcher_add_filter (dispatcher, filter->func, - filter->priority, - filter->user_data); -} - static void mcd_dispatcher_finish_reinvocation (McdChannel *request) { @@ -1793,10 +1186,7 @@ _mcd_dispatcher_recover_channel (McdDispatcher *dispatcher, DEBUG ("%s is unhandled, redispatching", path); requested = mcd_channel_is_requested (channel); - _mcd_dispatcher_take_channels (dispatcher, - g_list_prepend (NULL, channel), - requested, - FALSE); + _mcd_dispatcher_add_channel (dispatcher, channel, requested, FALSE); } } @@ -1815,14 +1205,14 @@ check_preferred_handler (const gchar *preferred_handler, { /* The error is TP_DBUS_ERROR_INVALID_BUS_NAME, which has no D-Bus * representation; re-map to InvalidArgument. */ - (*error)->domain = TP_ERRORS; + (*error)->domain = TP_ERROR; (*error)->code = TP_ERROR_INVALID_ARGUMENT; return FALSE; } if (!g_str_has_prefix (preferred_handler, TP_CLIENT_BUS_NAME_BASE)) { - g_set_error (error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Not a Telepathy Client: %s", preferred_handler); return FALSE; } @@ -1862,7 +1252,7 @@ dispatcher_request_channel (McdDispatcher *self, if (account == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "No such account: %s", account_path); goto despair; } @@ -2131,13 +1521,6 @@ _mcd_dispatcher_add_connection (McdDispatcher *self, * for it */ } -McdClientRegistry * -_mcd_dispatcher_get_client_registry (McdDispatcher *self) -{ - g_return_val_if_fail (MCD_IS_DISPATCHER (self), NULL); - return self->priv->clients; -} - /* org.freedesktop.Telepathy.ChannelDispatcher.Messages */ typedef struct { @@ -2223,7 +1606,7 @@ message_context_free (gpointer ctx) { GError *error; - error = g_error_new_literal (TP_ERRORS, TP_ERROR_TERMINATED, + error = g_error_new_literal (TP_ERROR, TP_ERROR_TERMINATED, "Channel request failed"); dbus_g_method_return_error (context->dbus_context, error); g_error_free (error); @@ -2305,7 +1688,7 @@ send_message_got_channel (McdRequest *request, } else { - GError *error = g_error_new_literal (TP_ERRORS, TP_ERROR_CANCELLED, + GError *error = g_error_new_literal (TP_ERROR, TP_ERROR_CANCELLED, "Channel closed by owner"); _mcd_request_unblock_account (message->account_path); @@ -2336,9 +1719,9 @@ messages_send_message_start (DBusGMethodInvocation *dbus_context, McdRequest *request = NULL; GError *error = NULL; GHashTable *props = NULL; - GValue c_type = { 0 }; - GValue h_type = { 0 }; - GValue target = { 0 }; + GValue c_type = G_VALUE_INIT; + GValue h_type = G_VALUE_INIT; + GValue target = G_VALUE_INIT; McdDispatcher *self = message->dispatcher; DEBUG ("messages_send_message_acl_success [attempt #%u]", message->tries); @@ -2347,7 +1730,7 @@ messages_send_message_start (DBusGMethodInvocation *dbus_context, if (tp_str_empty (message->account_path)) { - g_set_error_literal (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error_literal (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Account path not specified"); goto failure; } @@ -2361,7 +1744,7 @@ messages_send_message_start (DBusGMethodInvocation *dbus_context, if (account == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "No such account: %s", message->account_path); goto failure; } @@ -2392,7 +1775,7 @@ messages_send_message_start (DBusGMethodInvocation *dbus_context, if (channel == NULL || request == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_RESOURCE_UNAVAILABLE, + g_set_error (&error, TP_ERROR, TP_ERROR_RESOURCE_UNAVAILABLE, "Could not create channel request"); goto failure; } @@ -2632,11 +2015,11 @@ try_delegating (ChannelToDelegate *to_delegate) if (to_delegate->error == NULL) { - g_set_error (&to_delegate->error, TP_ERRORS, TP_ERROR_NOT_CAPABLE, + g_set_error (&to_delegate->error, TP_ERROR, TP_ERROR_NOT_CAPABLE, "There is no other suitable handler"); } - if (to_delegate->error->domain == TP_ERRORS) + if (to_delegate->error->domain == TP_ERROR) dbus_error = tp_error_get_dbus_name (to_delegate->error->code); else dbus_error = TP_ERROR_STR_NOT_AVAILABLE; @@ -2681,16 +2064,11 @@ add_possible_handlers (McdDispatcher *self, const gchar *sender, const gchar *preferred_handler) { - GList *channels = NULL; GStrv possible_handlers; guint i; - channels = g_list_prepend (channels, tp_channel); - possible_handlers = mcd_dispatcher_dup_possible_handlers (self, - NULL, channels, NULL); - - g_list_free (channels); + NULL, tp_channel, NULL); for (i = 0; possible_handlers[i] != NULL; i++) { @@ -2742,7 +2120,7 @@ dispatcher_delegate_channels ( if (channels->len == 0) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Need at least one channel to delegate"); goto error; } @@ -2769,7 +2147,7 @@ dispatcher_delegate_channels ( if (chan_account == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unknown channel: %s", chan_path); goto error; } @@ -2783,7 +2161,7 @@ dispatcher_delegate_channels ( chan_path, NULL); if (tp_strdiff (sender, handler)) { - g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_YOURS, + g_set_error (&error, TP_ERROR, TP_ERROR_NOT_YOURS, "Your are not handling channel %s", chan_path); goto error; } @@ -2871,7 +2249,7 @@ dispatcher_present_channel ( if (chan_account == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Unknown channel: %s", channel_path); goto error; } @@ -2898,7 +2276,7 @@ dispatcher_present_channel ( _mcd_channel_get_request (mcd_channel)); if (client == NULL) { - g_set_error (&error, TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, + g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Channel %s is currently not handled", channel_path); goto error; } diff --git a/src/mcd-dispatcher.h b/src/mcd-dispatcher.h index 9875d353..ba4c7367 100644 --- a/src/mcd-dispatcher.h +++ b/src/mcd-dispatcher.h @@ -30,7 +30,7 @@ #include <glib.h> #include <glib-object.h> #include <dbus/dbus-glib.h> -#include <telepathy-glib/dbus-properties-mixin.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS @@ -50,13 +50,13 @@ typedef struct _McdDispatcherPrivate McdDispatcherPrivate; struct _McdDispatcher { - McdMission parent; + GObject parent; McdDispatcherPrivate *priv; }; struct _McdDispatcherClass { - McdMissionClass parent_class; + GObjectClass parent_class; /* signals */ void (*_former_channel_added_signal) (void); @@ -80,9 +80,6 @@ GType mcd_dispatcher_get_type (void); McdDispatcher *mcd_dispatcher_new (TpDBusDaemon *dbus_daemon, McdMaster * master); -gint mcd_dispatcher_get_channel_type_usage (McdDispatcher * dispatcher, - GQuark chan_type_quark); - G_END_DECLS #endif /* MCD_DISPATCHER_H */ diff --git a/src/mcd-handler-map-priv.h b/src/mcd-handler-map-priv.h index c90603f9..cc7109f7 100644 --- a/src/mcd-handler-map-priv.h +++ b/src/mcd-handler-map-priv.h @@ -26,8 +26,7 @@ #ifndef MCD_HANDLER_MAP_H_ #define MCD_HANDLER_MAP_H_ -#include <telepathy-glib/channel.h> -#include <telepathy-glib/dbus.h> +#include <telepathy-glib/telepathy-glib.h> G_BEGIN_DECLS diff --git a/src/mcd-handler-map.c b/src/mcd-handler-map.c index 18d76d17..ee8371e8 100644 --- a/src/mcd-handler-map.c +++ b/src/mcd-handler-map.c @@ -26,7 +26,7 @@ #include "config.h" #include "mcd-handler-map-priv.h" -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> #include "channel-utils.h" #include "mcd-channel-priv.h" diff --git a/src/mcd-manager.c b/src/mcd-manager.c index d19cfc09..5c0e9fbf 100644 --- a/src/mcd-manager.c +++ b/src/mcd-manager.c @@ -79,45 +79,21 @@ enum static GQuark readiness_quark = 0; static void -on_manager_ready (TpConnectionManager *tp_conn_mgr, const GError *error, - gpointer user_data, GObject *weak_object) +on_manager_ready (GObject *source_object, + GAsyncResult *result, gpointer user_data) { - McdManager *manager = MCD_MANAGER (weak_object); + TpConnectionManager *tp_conn_mgr = TP_CONNECTION_MANAGER (source_object); + McdManager *manager = MCD_MANAGER (user_data); McdManagerPrivate *priv; + GError *error = NULL; + + tp_proxy_prepare_finish (tp_conn_mgr, result, &error); priv = manager->priv; DEBUG ("manager %s is ready", priv->name); priv->ready = TRUE; _mcd_object_ready (manager, readiness_quark, error); -} - -static gint -_find_connection_by_path (gconstpointer data, gconstpointer user_data) -{ - TpConnection *tp_conn; - McdConnection *connection = MCD_CONNECTION (data); - const gchar *object_path = (const gchar *)user_data; - const gchar *conn_object_path = NULL; - gint ret; - - if (!data) return 1; - - g_object_get (G_OBJECT (connection), "tp-connection", - &tp_conn, NULL); - if (!tp_conn) - return 1; - conn_object_path = TP_PROXY (tp_conn)->object_path; - if (strcmp (conn_object_path, object_path) == 0) - { - ret = 0; - } - else - { - ret = 1; - } - - g_object_unref (G_OBJECT (tp_conn)); - return ret; + g_clear_error (&error); } static void @@ -198,8 +174,7 @@ mcd_manager_setup (McdManager *manager) goto error; } - tp_connection_manager_call_when_ready (priv->tp_conn_mgr, on_manager_ready, - NULL, NULL, (GObject *)manager); + tp_proxy_prepare_async (priv->tp_conn_mgr, NULL, on_manager_ready, manager); DEBUG ("Manager %s created", priv->name); return TRUE; @@ -284,20 +259,6 @@ _mcd_manager_get_property (GObject * obj, guint prop_id, } } -static McdConnection * -create_connection (McdManager *manager, McdAccount *account) -{ - McdManagerPrivate *priv = manager->priv; - - return g_object_new (MCD_TYPE_CONNECTION, - "dbus-daemon", priv->dbus_daemon, - "tp-manager", priv->tp_conn_mgr, - "dispatcher", priv->dispatcher, - "account", account, - "slacker", priv->slacker, - NULL); -} - static void mcd_manager_class_init (McdManagerClass * klass) { @@ -315,8 +276,6 @@ mcd_manager_class_init (McdManagerClass * klass) mission_class->connect = _mcd_manager_connect; mission_class->disconnect = _mcd_manager_disconnect; - klass->create_connection = create_connection; - /* Properties */ g_object_class_install_property (object_class, PROP_NAME, @@ -364,48 +323,6 @@ mcd_manager_new (const gchar *unique_name, return obj; } -McdConnection * -mcd_manager_get_connection (McdManager * manager, const gchar *object_path) -{ - const GList *connections; - const GList *node; - - connections = mcd_operation_get_missions (MCD_OPERATION (manager)); - node = g_list_find_custom ((GList*)connections, object_path, - _find_connection_by_path); - - if (node != NULL) - { - return MCD_CONNECTION (node->data); - } - - else - { - return NULL; - } -} - -gboolean -mcd_manager_cancel_channel_request (McdManager *manager, guint operation_id, - const gchar *requestor_client_id, - GError **error) -{ - const GList *connections, *node; - - connections = mcd_operation_get_missions (MCD_OPERATION (manager)); - if (!connections) return FALSE; - - for (node = connections; node; node = node->next) - { - if (mcd_connection_cancel_channel_request (MCD_CONNECTION (node->data), - operation_id, - requestor_client_id, - error)) - return TRUE; - } - return FALSE; -} - /** * mcd_manager_get_unique_name: * @manager: the #McdManager. @@ -468,8 +385,14 @@ mcd_manager_create_connection (McdManager *manager, McdAccount *account) g_return_val_if_fail (MCD_IS_MANAGER (manager), NULL); g_return_val_if_fail (manager->priv->tp_conn_mgr != NULL, NULL); - connection = MCD_MANAGER_GET_CLASS (manager)->create_connection - (manager, account); + connection = g_object_new (MCD_TYPE_CONNECTION, + "dbus-daemon", manager->priv->dbus_daemon, + "tp-manager", manager->priv->tp_conn_mgr, + "dispatcher", manager->priv->dispatcher, + "account", account, + "slacker", manager->priv->slacker, + NULL); + mcd_operation_take_mission (MCD_OPERATION (manager), MCD_MISSION (connection)); DEBUG ("Created a connection %p for account: %s", @@ -492,19 +415,6 @@ mcd_manager_get_tp_proxy (McdManager *manager) } /** - * mcd_manager_get_dispatcher: - * @manager: the #McdManager. - * - * Returns: the #McdDispatcher. - */ -McdDispatcher * -mcd_manager_get_dispatcher (McdManager *manager) -{ - g_return_val_if_fail (MCD_IS_MANAGER (manager), NULL); - return manager->priv->dispatcher; -} - -/** * mcd_manager_call_when_ready: * @manager: the #McdManager. * @callbacks: the #McdManagerReadyCb to invoke. diff --git a/src/mcd-manager.h b/src/mcd-manager.h index 949f87c3..d02c0060 100644 --- a/src/mcd-manager.h +++ b/src/mcd-manager.h @@ -57,8 +57,6 @@ struct _McdManager struct _McdManagerClass { McdOperationClass parent_class; - McdConnection *(*create_connection) (McdManager *manager, - McdAccount *account); void (*_mc_reserved1) (void); void (*_mc_reserved2) (void); void (*_mc_reserved3) (void); @@ -81,13 +79,7 @@ mcd_manager_get_protocol_param (McdManager *manager, const gchar *protocol, McdConnection *mcd_manager_create_connection (McdManager *manager, McdAccount *account); -gboolean mcd_manager_cancel_channel_request (McdManager *manager, guint operation_id, - const gchar *requestor_client_pid, GError **error); - -McdConnection *mcd_manager_get_connection (McdManager *manager, - const gchar *object_path); TpConnectionManager *mcd_manager_get_tp_proxy (McdManager *manager); -McdDispatcher *mcd_manager_get_dispatcher (McdManager *manager); typedef void (*McdManagerReadyCb) (McdManager *manager, const GError *error, gpointer user_data); diff --git a/src/mcd-master.c b/src/mcd-master.c index 45d30d9a..ccf34d6d 100644 --- a/src/mcd-master.c +++ b/src/mcd-master.c @@ -43,9 +43,6 @@ * It is basically a container for all McdManager objects and * takes care of their management. It also takes care of sleep and awake * cycles (e.g. translates to auto away somewhere down the hierarchy). - * - * McdMaster is a subclass of McdConroller, which essentially means it - * is subject to all device control. */ #include <config.h> @@ -71,36 +68,41 @@ #include "kludge-transport.h" #include "mcd-master.h" #include "mcd-master-priv.h" -#include "mcd-proxy.h" #include "mcd-manager.h" #include "mcd-dispatcher.h" #include "mcd-account-manager.h" #include "mcd-account-manager-priv.h" #include "mcd-account-conditions.h" #include "mcd-account-priv.h" -#include "mcd-plugin.h" #include "mcd-transport.h" #include "plugin-loader.h" +#ifdef G_OS_UNIX +# ifndef HAVE_UMASK +# error On Unix, MC relies on umask() for account privacy +# endif +#endif + #define MCD_MASTER_PRIV(master) (G_TYPE_INSTANCE_GET_PRIVATE ((master), \ MCD_TYPE_MASTER, \ McdMasterPrivate)) -G_DEFINE_TYPE (McdMaster, mcd_master, MCD_TYPE_CONTROLLER); +G_DEFINE_TYPE (McdMaster, mcd_master, MCD_TYPE_OPERATION); typedef struct _McdMasterPrivate { McdAccountManager *account_manager; McdDispatcher *dispatcher; - McdProxy *proxy; /* We create this for our member objects */ TpDBusDaemon *dbus_daemon; - GPtrArray *mcd_plugins; GPtrArray *transport_plugins; GList *account_connections; + /* Current pending sleep timer */ + gint shutdown_timeout_id; + gboolean is_disposed; gboolean low_memory; gboolean idle; @@ -259,90 +261,6 @@ on_transport_status_changed (McdTransportPlugin *plugin, } } -#ifdef ENABLE_MCD_PLUGINS -static void -mcd_master_unload_mcd_plugins (McdMaster *master) -{ - McdMasterPrivate *priv = MCD_MASTER_PRIV (master); - GModule *module; - guint i; - - for (i = 0; i < priv->mcd_plugins->len; i++) - { - module = g_ptr_array_index (priv->mcd_plugins, i); - g_module_close (module); - } - g_ptr_array_unref (priv->mcd_plugins); - priv->mcd_plugins = NULL; -} - -static const gchar * -mcd_master_get_plugin_dir (void) -{ - const gchar *dir = g_getenv ("MC_FILTER_PLUGIN_DIR"); - - if (dir == NULL) - dir = MCD_DEFAULT_FILTER_PLUGIN_DIR; - - return dir; -} - -static void -mcd_master_load_mcd_plugins (McdMaster *master) -{ - McdMasterPrivate *priv = MCD_MASTER_PRIV (master); - const gchar *plugin_dir; - GDir *dir = NULL; - GError *error = NULL; - const gchar *name; - - plugin_dir = mcd_master_get_plugin_dir (); - - dir = g_dir_open (plugin_dir, 0, &error); - if (!dir) - { - DEBUG ("Could not open plugin directory %s: %s", plugin_dir, - error->message); - g_error_free (error); - return; - } - - DEBUG ("Looking for plugins in %s", plugin_dir); - - priv->mcd_plugins = g_ptr_array_new (); - while ((name = g_dir_read_name (dir))) - { - GModule *module; - gchar *path; - - if (name[0] == '.' || !g_str_has_suffix (name, ".so")) continue; - - path = g_build_filename (plugin_dir, name, NULL); - module = g_module_open (path, 0); - g_free (path); - if (module) - { - McdPluginInitFunc init_func; - if (g_module_symbol (module, MCD_PLUGIN_INIT_FUNC, - (gpointer)&init_func)) - { - DEBUG ("Initializing plugin %s", name); - init_func ((McdPlugin *)master); - g_ptr_array_add (priv->mcd_plugins, module); - } - else - DEBUG ("Error looking up symbol " MCD_PLUGIN_INIT_FUNC - " from plugin %s: %s", name, g_module_error ()); - } - else - { - DEBUG ("Error opening plugin: %s: %s", name, g_module_error ()); - } - } - g_dir_close (dir); -} -#endif - static void _mcd_master_finalize (GObject * object) { @@ -431,19 +349,9 @@ _mcd_master_dispose (GObject * object) priv->transport_plugins = NULL; } -#ifdef ENABLE_MCD_PLUGINS - if (priv->mcd_plugins) - { - mcd_master_unload_mcd_plugins (MCD_MASTER (object)); - } -#endif - tp_clear_object (&priv->account_manager); tp_clear_object (&priv->dbus_daemon); - - /* Don't unref() the dispatcher: it will be unref()ed by the McdProxy */ - priv->dispatcher = NULL; - g_object_unref (priv->proxy); + tp_clear_object (&priv->dispatcher); if (default_master == (McdMaster *) object) { @@ -484,16 +392,7 @@ mcd_master_constructor (GType type, guint n_params, TP_PROXY (priv->dbus_daemon)->dbus_connection), TRUE); - /* propagate the signals to dispatcher, too */ - priv->proxy = mcd_proxy_new (MCD_MISSION (master)); - mcd_operation_take_mission (MCD_OPERATION (priv->proxy), - MCD_MISSION (priv->dispatcher)); - -#ifdef ENABLE_MCD_PLUGINS - mcd_master_load_mcd_plugins (master); -#endif - - mcd_kludge_transport_install ((McdPlugin *) master); + mcd_kludge_transport_install (master); /* we assume that at this point all transport plugins have been registered. * We get the active transports and check whether some accounts should be @@ -621,36 +520,6 @@ _mcd_master_lookup_manager (McdMaster *master, } /** - * mcd_master_get_dispatcher: - * @master: the #McdMaster. - * - * Returns: the #McdDispatcher. It will go away when @master is disposed, - * unless you keep a reference to it. - */ -McdDispatcher * -mcd_master_get_dispatcher (McdMaster *master) -{ - g_return_val_if_fail (MCD_IS_MASTER (master), NULL); - return MCD_MASTER_PRIV (master)->dispatcher; -} - -/** - * mcd_plugin_get_dispatcher: - * @plugin: the #McdPlugin - * - * Gets the McdDispatcher, to be used for registering channel filters. The - * reference count of the returned object is not incremented, and the object is - * guaranteed to stay alive during the whole lifetime of the plugin. - * - * Returns: the #McdDispatcher - */ -McdDispatcher * -mcd_plugin_get_dispatcher (McdPlugin *plugin) -{ - return MCD_MASTER_PRIV (plugin)->dispatcher; -} - -/** * mcd_master_get_dbus_daemon: * @master: the #McdMaster. * @@ -665,33 +534,33 @@ mcd_master_get_dbus_daemon (McdMaster *master) /** * mcd_plugin_register_transport: - * @plugin: the #McdPlugin. + * @master: the #McdMaster. * @transport_plugin: the #McdTransportPlugin. * * Registers @transport_plugin as a transport monitoring object. - * The @plugin takes ownership of the transport (i.e., it doesn't increment its + * The @master takes ownership of the transport (i.e., it doesn't increment its * reference count). */ void -mcd_plugin_register_transport (McdPlugin *plugin, +mcd_master_register_transport (McdMaster *master, McdTransportPlugin *transport_plugin) { - McdMasterPrivate *priv = MCD_MASTER_PRIV (plugin); + McdMasterPrivate *priv = MCD_MASTER_PRIV (master); DEBUG ("called"); g_signal_connect (transport_plugin, "status-changed", G_CALLBACK (on_transport_status_changed), - MCD_MASTER (plugin)); + master); g_ptr_array_add (priv->transport_plugins, transport_plugin); } void -mcd_plugin_register_account_connection (McdPlugin *plugin, +mcd_master_register_account_connection (McdMaster *master, McdAccountConnectionFunc func, gint priority, gpointer userdata) { - McdMasterPrivate *priv = MCD_MASTER_PRIV (plugin); + McdMasterPrivate *priv = MCD_MASTER_PRIV (master); McdAccountConnectionData *acd; GList *list; @@ -793,81 +662,45 @@ _mcd_master_account_replace_transport (McdMaster *master, return connected; } -gboolean -mcd_master_has_low_memory (McdMaster *master) -{ - McdMasterPrivate *priv = MCD_MASTER_PRIV (master); - - return priv->low_memory; -} +/* Milliseconds to wait for Connectivity coming back up before exiting MC */ +#define EXIT_COUNTDOWN_TIME 5000 -/* For the moment, this is implemented in terms of McdSystemFlags. */ -void -mcd_master_set_low_memory (McdMaster *master, - gboolean low_memory) +static gboolean +_mcd_master_exit_by_timeout (gpointer data) { - McdMasterPrivate *priv = MCD_MASTER_PRIV (master); + McdMaster *self = MCD_MASTER (data); + McdMasterPrivate *priv = MCD_MASTER_PRIV (self); + + priv->shutdown_timeout_id = 0; - priv->low_memory = low_memory; + /* Notify sucide */ + mcd_mission_abort (MCD_MISSION (self)); + return FALSE; } -/* For the moment, this is implemented in terms of McdSystemFlags. When - * McdSystemFlags are abolished, move the processing from set_flags to - * this function. */ void -mcd_master_set_idle (McdMaster *master, - gboolean idle) +mcd_master_shutdown (McdMaster *self, + const gchar *reason) { - McdMasterPrivate *priv = MCD_MASTER_PRIV (master); - gboolean idle_flag_old; + McdMasterPrivate *priv; - idle_flag_old = priv->idle; - priv->idle = idle != 0; + g_return_if_fail (MCD_IS_MASTER (self)); + priv = MCD_MASTER_PRIV (self); - if (idle_flag_old != priv->idle) + if(!priv->shutdown_timeout_id) { - GHashTableIter iter; - gpointer v; + DEBUG ("MC will bail out because of \"%s\" out exit after %i", + reason ? reason : "No reason specified", + EXIT_COUNTDOWN_TIME); - g_hash_table_iter_init (&iter, - _mcd_account_manager_get_accounts (priv->account_manager)); - - while (g_hash_table_iter_next (&iter, NULL, &v)) - { - McdAccount *account = MCD_ACCOUNT (v); - - if (priv->idle) - { - TpConnectionPresenceType presence; - - /* If the current presence is not Available then we don't go - * auto-away - this avoids (a) manipulating offline accounts - * and (b) messing up people's busy or invisible status */ - mcd_account_get_current_presence (account, &presence, NULL, - NULL); - - if (presence != TP_CONNECTION_PRESENCE_TYPE_AVAILABLE) - { - continue; - } - - /* Set the Connection to be "away" if the CM supports it - * (if not, it'll just fail - no harm done) */ - _mcd_account_request_temporary_presence (account, - TP_CONNECTION_PRESENCE_TYPE_AWAY, "away"); - } - else - { - TpConnectionPresenceType presence; - const gchar *status; - const gchar *message; - - /* Go back to the requested presence */ - mcd_account_get_requested_presence (account, &presence, - &status, &message); - mcd_account_request_presence (account, presence, status, - message); - } - } + priv->shutdown_timeout_id = g_timeout_add (EXIT_COUNTDOWN_TIME, + _mcd_master_exit_by_timeout, + self); + } + else + { + DEBUG ("Already shutting down. This one has the reason %s", + reason ? reason : "No reason specified"); } + mcd_debug_print_tree (self); } diff --git a/src/mcd-master.h b/src/mcd-master.h index 666b96cf..3a247bbc 100644 --- a/src/mcd-master.h +++ b/src/mcd-master.h @@ -28,7 +28,6 @@ #include <glib.h> #include <glib-object.h> -#include "mcd-controller.h" G_BEGIN_DECLS #define MCD_TYPE_MASTER (mcd_master_get_type ()) @@ -47,12 +46,12 @@ typedef struct _McdMasterClass McdMasterClass; struct _McdMaster { - McdController parent; + McdOperation parent; }; struct _McdMasterClass { - McdControllerClass parent_class; + McdOperationClass parent_class; McdManager *(*create_manager) (McdMaster *master, const gchar *unique_name); void (*_mc_reserved1) (void); @@ -66,12 +65,20 @@ struct _McdMasterClass GType mcd_master_get_type (void); McdMaster *mcd_master_get_default (void); -McdDispatcher *mcd_master_get_dispatcher (McdMaster *master); TpDBusDaemon *mcd_master_get_dbus_daemon (McdMaster *master); +void mcd_master_shutdown (McdMaster *self, const gchar *reason); -gboolean mcd_master_has_low_memory (McdMaster *master); -void mcd_master_set_low_memory (McdMaster *master, gboolean low_memory); -void mcd_master_set_idle (McdMaster *master, gboolean idle); +void mcd_master_register_transport (McdMaster *master, + McdTransportPlugin *transport_plugin); + +typedef void (*McdAccountConnectionFunc) (McdAccount *account, + GHashTable *parameters, + gpointer userdata); + +void mcd_master_register_account_connection (McdMaster *master, + McdAccountConnectionFunc func, + gint priority, + gpointer userdata); G_END_DECLS #endif /* MCD_MASTER_H */ diff --git a/src/mcd-misc.c b/src/mcd-misc.c index 22168579..294d2a78 100644 --- a/src/mcd-misc.c +++ b/src/mcd-misc.c @@ -24,6 +24,8 @@ * */ +#include "config.h" + #include "mcd-misc.h" #include <errno.h> #include <glib/gstdio.h> @@ -31,8 +33,7 @@ #include <stdio.h> #include <string.h> #include <unistd.h> -#include <telepathy-glib/errors.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> #include "mcd-debug.h" @@ -66,7 +67,7 @@ _mcd_build_error_string (const GError *error) GEnumClass *klass; const gchar *prefix; - if (error->domain == TP_ERRORS) + if (error->domain == TP_ERROR) { klass = g_type_class_ref (TP_TYPE_ERROR); prefix = TP_ERROR_PREFIX; @@ -114,7 +115,7 @@ mcd_ready_data_free (McdReadyData *rd) { if (rd->strukt) { - GError error = { TP_ERRORS, TP_ERROR_CANCELLED, "Object disposed" }; + GError error = { TP_ERROR, TP_ERROR_CANCELLED, "Object disposed" }; mcd_object_invoke_ready_callbacks (rd, &error); } g_slice_free (McdReadyData, rd); @@ -175,40 +176,6 @@ _mcd_object_ready (gpointer object, GQuark quark, const GError *error) g_object_unref (object); } -gboolean -_mcd_file_set_contents (const gchar *filename, const gchar *contents, - gssize length, GError **error) -{ - gchar *old_contents = NULL; - gsize old_length = 0; - - g_return_val_if_fail (filename != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - g_return_val_if_fail (contents != NULL || length == 0, FALSE); - g_return_val_if_fail (length >= -1, FALSE); - - if (length == -1) - length = strlen (contents); - - /* no real error handling needed here - if g_file_get_contents fails - * (probably because the file doesn't exist), then old_contents remains - * NULL, and we do want to rewrite the file */ - if (g_file_get_contents (filename, &old_contents, &old_length, NULL)) - { - gboolean unchanged = (((gsize) length) == old_length && - memcmp (contents, old_contents, length) == 0); - - g_free (old_contents); - - if (unchanged) - { - return TRUE; - } - } - - return g_file_set_contents (filename, contents, length, error); -} - int _mcd_chmod_private (const gchar *filename) { diff --git a/src/mcd-misc.h b/src/mcd-misc.h index 35bf2a82..e69ee728 100644 --- a/src/mcd-misc.h +++ b/src/mcd-misc.h @@ -29,8 +29,9 @@ #include <glib.h> #include <glib-object.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/gtypes.h> + +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> G_BEGIN_DECLS @@ -48,9 +49,6 @@ void _mcd_object_call_on_struct_when_ready (gpointer object, gpointer strukt, void _mcd_object_ready (gpointer object, GQuark quark, const GError *error); G_GNUC_INTERNAL -gboolean _mcd_file_set_contents (const gchar *filename, const gchar *contents, - gssize length, GError **error); -G_GNUC_INTERNAL void _mcd_ext_register_dbus_glib_marshallers (void); G_GNUC_INTERNAL int _mcd_chmod_private (const gchar *filename); diff --git a/src/mcd-mission.c b/src/mcd-mission.c index ca494799..bf97b0d4 100644 --- a/src/mcd-mission.c +++ b/src/mcd-mission.c @@ -49,6 +49,8 @@ * object specific state managements. */ +#include "config.h" + #include "mcd-mission-priv.h" #include <telepathy-glib/telepathy-glib.h> @@ -155,7 +157,6 @@ _mcd_mission_set_parent (McdMission * mission, McdMission * parent) tp_clear_object (&priv->parent); priv->parent = parent; - g_signal_emit_by_name (mission, "parent-set", parent); } static void @@ -270,21 +271,6 @@ mcd_mission_class_init (McdMissionClass * klass) disconnected_signal), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - mcd_mission_signals[PARENT_SET] = - g_signal_new ("parent-set", G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (McdMissionClass, - parent_set_signal), - NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, - 0); - - /* Properties */ - g_object_class_install_property - (object_class, PROP_PARENT, - g_param_spec_object ("parent", - "Parent mission", - "Parent mission", - MCD_TYPE_MISSION, - G_PARAM_READWRITE)); } static void diff --git a/src/mcd-mission.h b/src/mcd-mission.h index 71fe510e..f88050b9 100644 --- a/src/mcd-mission.h +++ b/src/mcd-mission.h @@ -52,27 +52,13 @@ struct _McdMissionClass GObjectClass parent_class; /* Signals */ - void (*parent_set_signal) (McdMission * mission, McdMission * parent); void (*connected_signal) (McdMission * mission); void (*disconnected_signal) (McdMission * mission); - - void (*_former_flags_changed_signal) (void); - void (*_former_mode_set_signal) (void); - void (*abort_signal) (McdMission * mission); - + /* Virtual methods */ - void (*_former_set_parent) (void); - void (*connect) (McdMission * mission); void (*disconnect) (McdMission * mission); - - void (*_former_set_flags) (void); - void (*_former_get_flags) (void); - - void (*_former_set_mode) (void); - void (*_former_get_mode) (void); - void (*abort) (McdMission * mission); }; diff --git a/src/mcd-operation.c b/src/mcd-operation.c index 6c1595c4..7ddba663 100644 --- a/src/mcd-operation.c +++ b/src/mcd-operation.c @@ -38,6 +38,8 @@ * established. */ +#include "config.h" + #include "mcd-operation.h" #include "mcd-mission-priv.h" diff --git a/src/mcd-plugin.h b/src/mcd-plugin.h deleted file mode 100644 index 8f999c3d..00000000 --- a/src/mcd-plugin.h +++ /dev/null @@ -1,46 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* - * mcd-plugin.h - Loadable plugin support - * - * Copyright (C) 2008 Nokia Corporation - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __MCD_PLUGIN_H__ -#define __MCD_PLUGIN_H__ - -#include <glib.h> - -G_BEGIN_DECLS - -typedef struct _McdPlugin McdPlugin; - -#include "mcd-dispatcher.h" -#include "mcd-transport.h" - -typedef void (*McdPluginInitFunc) (McdPlugin *plugin); - -#define MCD_PLUGIN_INIT_FUNC "mcd_plugin_init" - -McdDispatcher *mcd_plugin_get_dispatcher (McdPlugin *plugin); -void mcd_plugin_register_transport (McdPlugin *plugin, - McdTransportPlugin *transport_plugin); - - -G_END_DECLS - -#endif diff --git a/src/mcd-provisioning-factory.c b/src/mcd-provisioning-factory.c deleted file mode 100644 index 2c28d2b5..00000000 --- a/src/mcd-provisioning-factory.c +++ /dev/null @@ -1,135 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* -* This file is part of mission-control -* -* Copyright (C) 2007 Nokia Corporation. -* -* Contact: Naba Kumar <naba.kumar@nokia.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public License -* version 2.1 as published by the Free Software Foundation. -* -* 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 St, Fifth Floor, Boston, MA -* 02110-1301 USA -* -*/ - -#include "mcd-provisioning-factory.h" - -#define MCD_PROVISIONING_FACTORY_GET_PRIV(master) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((master), \ - MCD_TYPE_PROVISIONING_FACTORY, \ - McdProvisioningFactoryPriv)) - -G_DEFINE_TYPE (McdProvisioningFactory, mcd_provisioning_factory, G_TYPE_OBJECT); - - -struct _McdProvisioningFactoryPriv -{ - GHashTable *provs; -}; - -static void -mcd_provisioning_factory_init (McdProvisioningFactory *object) -{ - McdProvisioningFactoryPriv *priv = MCD_PROVISIONING_FACTORY_GET_PRIV (object); - priv->provs = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_object_unref); -} - -static void -mcd_provisioning_factory_dispose (GObject *object) -{ - McdProvisioningFactoryPriv *priv = MCD_PROVISIONING_FACTORY_GET_PRIV (object); - if (priv->provs) - { - g_hash_table_unref (priv->provs); - priv->provs = NULL; - } - G_OBJECT_CLASS (mcd_provisioning_factory_parent_class)->dispose (object); -} - -static void -mcd_provisioning_factory_class_init (McdProvisioningFactoryClass *klass) -{ - GObjectClass* object_class = G_OBJECT_CLASS (klass); - g_type_class_add_private (object_class, sizeof (McdProvisioningFactoryPriv)); - - object_class->dispose = mcd_provisioning_factory_dispose; -} - -/** - * mcd_provisioning_factory_lookup: - * @prov_factory: the #McdProvisioningFactory. - * @service: name of the service for which provisioning will be retrieved. - * - * Gets a #McdProvisioning object for @service. - * - * Returns: a #McdProvisioning, or %NULL if none found. The reference count - * will not be incremented. - */ -McdProvisioning* -mcd_provisioning_factory_lookup (McdProvisioningFactory* prov_factory, - const gchar *service) -{ - McdProvisioningFactoryPriv *priv; - - g_return_val_if_fail (service != NULL, NULL); - g_return_val_if_fail (MCD_IS_PROVISIONING_FACTORY (prov_factory), NULL); - - priv = MCD_PROVISIONING_FACTORY_GET_PRIV (prov_factory); - return g_hash_table_lookup (priv->provs, service); -} - -/** - * mcd_provisioning_factory_add: - * @prov_factory: the #McdProvisioningFactory. - * @service: name of the service for which provisioning will be provided. - * @provisioning: the #McdProvisioning object to add. - * - * Add a new provisioning object to the factory. Note that the factory will - * take ownership of the @provisioning object. - */ -void -mcd_provisioning_factory_add (McdProvisioningFactory* prov_factory, - const gchar *service, - McdProvisioning *provisioning) -{ - McdProvisioningFactoryPriv *priv; - - g_return_if_fail (service != NULL); - g_return_if_fail (MCD_IS_PROVISIONING_FACTORY (prov_factory)); - g_return_if_fail (MCD_IS_PROVISIONING (provisioning)); - - priv = MCD_PROVISIONING_FACTORY_GET_PRIV (prov_factory); - g_hash_table_insert (priv->provs, g_strdup (service), provisioning); -} - -/** - * mcd_provisioning_factory_get: - * - * Get the #McdProvisioningFactory. One doesn't have to hold a reference to the - * returned object: just call this function whenever needed. - * - * Returns: a #McdProvisioningFactory. - */ -McdProvisioningFactory* -mcd_provisioning_factory_get (void) -{ - static McdProvisioningFactory *factory = NULL; - if (!factory) - { - factory = g_object_new (MCD_TYPE_PROVISIONING_FACTORY, NULL); - } - return factory; -} diff --git a/src/mcd-provisioning-factory.h b/src/mcd-provisioning-factory.h deleted file mode 100644 index f87d7934..00000000 --- a/src/mcd-provisioning-factory.h +++ /dev/null @@ -1,65 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* - * This file is part of mission-control - * - * Copyright (C) 2007 Nokia Corporation. - * - * Contact: Naba Kumar <naba.kumar@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef _MCD_PROVISIONING_FACTORY_H_ -#define _MCD_PROVISIONING_FACTORY_H_ - -#include <glib-object.h> -#include "mcd-provisioning.h" - -G_BEGIN_DECLS - -#define MCD_TYPE_PROVISIONING_FACTORY (mcd_provisioning_factory_get_type ()) -#define MCD_PROVISIONING_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MCD_TYPE_PROVISIONING_FACTORY, McdProvisioningFactory)) -#define MCD_PROVISIONING_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MCD_TYPE_PROVISIONING_FACTORY, McdProvisioningFactoryClass)) -#define MCD_IS_PROVISIONING_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MCD_TYPE_PROVISIONING_FACTORY)) -#define MCD_IS_PROVISIONING_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MCD_TYPE_PROVISIONING_FACTORY)) -#define MCD_PROVISIONING_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MCD_TYPE_PROVISIONING_FACTORY, McdProvisioningFactoryClass)) - -typedef struct _McdProvisioningFactoryClass McdProvisioningFactoryClass; -typedef struct _McdProvisioningFactoryPriv McdProvisioningFactoryPriv; -typedef struct _McdProvisioningFactory McdProvisioningFactory; - -struct _McdProvisioningFactoryClass -{ - GObjectClass parent_class; -}; - -struct _McdProvisioningFactory -{ - GObject parent_instance; -}; - -GType mcd_provisioning_factory_get_type (void) G_GNUC_CONST; -McdProvisioning* mcd_provisioning_factory_lookup (McdProvisioningFactory* prov_factory, - const gchar *service); -void mcd_provisioning_factory_add (McdProvisioningFactory* prov_factory, - const gchar *service, - McdProvisioning *provisioning); -McdProvisioningFactory* mcd_provisioning_factory_get (void); - -G_END_DECLS - -#endif /* _MCD_PROVISIONING_FACTORY_H_ */ diff --git a/src/mcd-provisioning.c b/src/mcd-provisioning.c deleted file mode 100644 index 1d5cdd60..00000000 --- a/src/mcd-provisioning.c +++ /dev/null @@ -1,122 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* - * This file is part of mission-control - * - * Copyright (C) 2007 Nokia Corporation. - * - * Contact: Naba Kumar <naba.kumar@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include "mcd-provisioning.h" - -GQuark -mcd_provisioning_error_quark (void) -{ - static GQuark quark = 0; - - if (quark == 0) { - quark = g_quark_from_static_string ("mcd-provisioning-error-quark"); - } - return quark; -} - -static void -mcd_provisioning_base_init (gpointer gclass) -{ - static gboolean initialized = FALSE; - - if (!initialized) { - initialized = TRUE; - } -} - -GType -mcd_provisioning_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (McdProvisioningIface), - mcd_provisioning_base_init, - NULL, - NULL, - NULL, - NULL, - 0, - 0, - NULL - }; - type = g_type_register_static (G_TYPE_INTERFACE, - "McdProvisioning", - &info, - 0); - g_type_interface_add_prerequisite (type, G_TYPE_OBJECT); - } - return type; -} - -/** - * mcd_provisioning_request_parameters: - * @prov: the #McdProvisioning object. - * @url: URL of the provisioning server. - * @username: username for connecting to the server. - * @password: password for connecting to the server. - * @callback: #McdProvisioningCallback which will receive the parameters. - * @user_data: extra argument for @callback. - * - * Queries the provisioning service and registers the @callback function for - * handling the result. - */ -void -mcd_provisioning_request_parameters (McdProvisioning *prov, - const gchar *url, - const gchar *username, - const gchar *password, - McdProvisioningCallback callback, - gpointer user_data) -{ - g_return_if_fail (MCD_IS_PROVISIONING (prov)); - - MCD_PROVISIONING_GET_IFACE (prov)->request_parameters (prov, url, - username, - password, - callback, - user_data); -} - -/** - * mcd_provisioning_cancel_request: - * @prov: the #McdProvisioning object. - * @callback: #McdProvisioningCallback to disconnect. - * @user_data: extra argument for @callback. - * - * Cancel a provisioning request, preventing @callback from being invoked. - */ -void -mcd_provisioning_cancel_request (McdProvisioning *prov, - McdProvisioningCallback callback, - gpointer user_data) -{ - g_return_if_fail (MCD_IS_PROVISIONING (prov)); - - MCD_PROVISIONING_GET_IFACE (prov)->cancel_request (prov, - callback, user_data); -} - diff --git a/src/mcd-provisioning.h b/src/mcd-provisioning.h deleted file mode 100644 index 3e890e8b..00000000 --- a/src/mcd-provisioning.h +++ /dev/null @@ -1,82 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* - * This file is part of mission-control - * - * Copyright (C) 2007 Nokia Corporation. - * - * Contact: Naba Kumar <naba.kumar@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ -#ifndef __MCD_PROVISIONING_H__ -#define __MCD_PROVISIONING_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS - -#define MCD_TYPE_PROVISIONING (mcd_provisioning_get_type ()) -#define MCD_PROVISIONING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MCD_TYPE_PROVISIONING, McdProvisioning)) -#define MCD_IS_PROVISIONING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MCD_TYPE_PROVISIONING)) -#define MCD_PROVISIONING_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MCD_TYPE_PROVISIONING, McdProvisioningIface)) -#define MCD_PROVISIONING_ERROR (mcd_provisioning_error_quark()) - -typedef struct _McdProvisioning McdProvisioning; -typedef struct _McdProvisioningIface McdProvisioningIface; - -typedef enum -{ - MCD_PROVISIONING_ERROR_NOT_FOUND, - MCD_PROVISIONING_ERROR_NO_RESPONSE, - MCD_PROVISIONING_ERROR_BAD_RESULT, -} McdProvisioningError; - -typedef void (*McdProvisioningCallback) (McdProvisioning *prov, - GHashTable *parameters, - GError *error, - gpointer user_data); - -struct _McdProvisioningIface { - GTypeInterface g_iface; - - void (*request_parameters) (McdProvisioning *prov, - const gchar *url, - const gchar *username, - const gchar *password, - McdProvisioningCallback callback, - gpointer user_data); - void (*cancel_request) (McdProvisioning *prov, - McdProvisioningCallback callback, - gpointer user_data); -}; - -GQuark mcd_provisioning_error_quark (void); -GType mcd_provisioning_get_type (void); - -void mcd_provisioning_request_parameters (McdProvisioning *prov, - const gchar *url, - const gchar *username, - const gchar *password, - McdProvisioningCallback callback, - gpointer user_data); - -void mcd_provisioning_cancel_request (McdProvisioning *prov, - McdProvisioningCallback callback, - gpointer user_data); -G_END_DECLS - -#endif diff --git a/src/mcd-proxy.c b/src/mcd-proxy.c deleted file mode 100644 index 5c3ef740..00000000 --- a/src/mcd-proxy.c +++ /dev/null @@ -1,226 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* - * This file is part of mission-control - * - * Copyright (C) 2007 Nokia Corporation. - * - * Contact: Naba Kumar <naba.kumar@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -/** - * SECTION:mcd-proxy - * @title: McdProxy - * @short_description: Mission proxy class - * @see_also: - * @stability: Unstable - * @include: mcd-proxy.h - * - * This is a simple container class that proxies the events from a proxy - * object to self container. - */ - -#include "mcd-proxy.h" - -#include <telepathy-glib/telepathy-glib.h> - -#define MCD_PROXY_PRIV(proxy) (G_TYPE_INSTANCE_GET_PRIVATE ((proxy), \ - MCD_TYPE_PROXY, \ - McdProxyPrivate)) - -G_DEFINE_TYPE (McdProxy, mcd_proxy, MCD_TYPE_OPERATION); - -/* Private */ - -typedef struct _McdProxyPrivate -{ - McdMission *proxy_object; - gboolean is_disposed; -} McdProxyPrivate; - -enum -{ - PROP_0, - PROP_PROXY_OBJECT -}; - -static void -_mcd_proxy_abort (McdProxy * proxy) -{ - /* Releases the reference */ - g_object_set (proxy, "proxy-object", NULL, NULL); - /* Propagate the "abort" event to our listeners */ - mcd_mission_abort (MCD_MISSION (proxy)); -} - -static void -_mcd_proxy_connect_signals (McdProxy * proxy) -{ - McdProxyPrivate *priv = MCD_PROXY_PRIV (proxy); - - g_signal_connect_swapped (priv->proxy_object, "connected", - G_CALLBACK (mcd_mission_connect), proxy); - g_signal_connect_swapped (priv->proxy_object, "disconnected", - G_CALLBACK (mcd_mission_disconnect), proxy); - g_signal_connect_swapped (priv->proxy_object, "abort", - G_CALLBACK (_mcd_proxy_abort), proxy); -} - -static void -_mcd_proxy_disconnect_signals (McdProxy * proxy) -{ - McdProxyPrivate *priv = MCD_PROXY_PRIV (proxy); - - g_signal_handlers_disconnect_by_func (priv->proxy_object, - G_CALLBACK (mcd_mission_connect), - proxy); - g_signal_handlers_disconnect_by_func (priv->proxy_object, - G_CALLBACK (mcd_mission_disconnect), - proxy); - g_signal_handlers_disconnect_by_func (priv->proxy_object, - G_CALLBACK (_mcd_proxy_abort), proxy); -} - -static void -_mcd_proxy_finalize (GObject * object) -{ - G_OBJECT_CLASS (mcd_proxy_parent_class)->finalize (object); -} - -static void -_mcd_proxy_dispose (GObject * object) -{ - McdProxyPrivate *priv = MCD_PROXY_PRIV (object); - - if (priv->is_disposed) - { - return; - } - - priv->is_disposed = TRUE; - DEBUG ("proxy disposed\n"); - - if (priv->proxy_object) - { - /* Disconnect proxy signals */ - _mcd_proxy_disconnect_signals (MCD_PROXY (object)); - } - - tp_clear_object (&priv->proxy_object); - - G_OBJECT_CLASS (mcd_proxy_parent_class)->dispose (object); -} - -static void -_mcd_proxy_set_property (GObject * obj, guint prop_id, - const GValue * val, GParamSpec * pspec) -{ - McdMission *proxy_object; - McdProxyPrivate *priv = MCD_PROXY_PRIV (obj); - - switch (prop_id) - { - case PROP_PROXY_OBJECT: - proxy_object = g_value_get_object (val); - if (proxy_object) - { - g_return_if_fail (MCD_IS_MISSION (proxy_object)); - g_object_ref (proxy_object); - } - - if (priv->proxy_object) - { - /* Disconnect proxy signals */ - _mcd_proxy_disconnect_signals (MCD_PROXY (obj)); - g_object_unref (priv->proxy_object); - } - priv->proxy_object = proxy_object; - if (priv->proxy_object) - { - /* Connect proxy signals */ - _mcd_proxy_connect_signals (MCD_PROXY (obj)); - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); - break; - } -} - -static void -_mcd_proxy_get_property (GObject * obj, guint prop_id, - GValue * val, GParamSpec * pspec) -{ - McdProxyPrivate *priv = MCD_PROXY_PRIV (obj); - - switch (prop_id) - { - case PROP_PROXY_OBJECT: - g_value_set_pointer (val, priv->proxy_object); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); - break; - } -} - -static void -mcd_proxy_class_init (McdProxyClass * klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (McdProxyPrivate)); - - object_class->finalize = _mcd_proxy_finalize; - object_class->dispose = _mcd_proxy_dispose; - object_class->set_property = _mcd_proxy_set_property; - object_class->get_property = _mcd_proxy_get_property; - - g_object_class_install_property - (object_class, PROP_PROXY_OBJECT, - g_param_spec_object ("proxy-object", - "Proxy object", - "Object to be monitored for McdMission signals", - MCD_TYPE_MISSION, - G_PARAM_READWRITE)); -} - -static void -mcd_proxy_init (McdProxy * obj) -{ - McdProxyPrivate *priv = MCD_PROXY_PRIV (obj); - priv->proxy_object = NULL; -} - -/* Public */ - -McdProxy * -mcd_proxy_new (McdMission * proxy_object) -{ - McdProxy *obj; - obj = MCD_PROXY (g_object_new (MCD_TYPE_PROXY, "proxy-object", - proxy_object, NULL)); - return obj; -} - -const McdMission * -mcd_proxy_get_proxy_object (McdProxy * proxy) -{ - McdProxyPrivate *priv = MCD_PROXY_PRIV (proxy); - return priv->proxy_object; -} diff --git a/src/mcd-proxy.h b/src/mcd-proxy.h deleted file mode 100644 index 791d663e..00000000 --- a/src/mcd-proxy.h +++ /dev/null @@ -1,59 +0,0 @@ -/* vi: set et sw=4 ts=8 cino=t0,(0: */ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/* - * This file is part of mission-control - * - * Copyright (C) 2007 Nokia Corporation. - * - * Contact: Naba Kumar <naba.kumar@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef MCD_PROXY_H -#define MCD_PROXY_H - -#include <glib.h> -#include <glib-object.h> - -#include "mcd-operation.h" - -G_BEGIN_DECLS -#define MCD_TYPE_PROXY (mcd_proxy_get_type ()) -#define MCD_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MCD_TYPE_PROXY, McdProxy)) -#define MCD_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MCD_TYPE_PROXY, McdProxyClass)) -#define MCD_IS_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MCD_TYPE_PROXY)) -#define MCD_IS_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), MCD_TYPE_PROXY)) -#define MCD_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MCD_TYPE_PROXY, McdProxyClass)) -typedef struct _McdProxy McdProxy; -typedef struct _McdProxyClass McdProxyClass; - -struct _McdProxy -{ - McdOperation parent; -}; - -struct _McdProxyClass -{ - McdOperationClass parent_class; -}; - -GType mcd_proxy_get_type (void); -McdProxy *mcd_proxy_new (McdMission * proxy_mission); -const McdMission *mcd_proxy_get_proxy_object (McdProxy * proxy); - -G_END_DECLS -#endif /* MCD_PROXY_H */ diff --git a/src/mcd-service.c b/src/mcd-service.c index 71e9dfc8..17c94b04 100644 --- a/src/mcd-service.c +++ b/src/mcd-service.c @@ -38,6 +38,8 @@ * dbus interface. */ +#include "config.h" + #include <dbus/dbus.h> #include <string.h> #include <dlfcn.h> @@ -50,9 +52,6 @@ #include <dbus/dbus.h> #include <telepathy-glib/telepathy-glib.h> -#include "mcd-signals-marshal.h" -#include "mcd-dispatcher.h" -#include "mcd-dispatcher-context.h" #include "mcd-connection.h" #include "mcd-misc.h" #include "mcd-service.h" @@ -98,7 +97,7 @@ static void mcd_service_disconnect (McdMission *mission) { MCD_MISSION_CLASS (mcd_service_parent_class)->disconnect (mission); - mcd_controller_shutdown (MCD_CONTROLLER (mission), "Disconnected"); + mcd_master_shutdown (MCD_MASTER (mission), "Disconnected"); } static void @@ -167,19 +166,17 @@ McdService * mcd_service_new (void) { McdService *obj; - DBusGConnection *dbus_connection; TpDBusDaemon *dbus_daemon; GError *error = NULL; /* Initialize DBus connection */ - dbus_connection = dbus_g_bus_get (DBUS_BUS_STARTER, &error); - if (dbus_connection == NULL) + dbus_daemon = tp_dbus_daemon_dup (&error); + if (dbus_daemon == NULL) { g_printerr ("Failed to open connection to bus: %s", error->message); g_error_free (error); return NULL; } - dbus_daemon = tp_dbus_daemon_new (dbus_connection); obj = g_object_new (MCD_TYPE_SERVICE, "dbus-daemon", dbus_daemon, NULL); diff --git a/src/mcd-signals-marshal.list b/src/mcd-signals-marshal.list deleted file mode 100644 index 2fdd5724..00000000 --- a/src/mcd-signals-marshal.list +++ /dev/null @@ -1,19 +0,0 @@ -VOID:UINT,UINT,UINT,STRING -VOID:UINT,STRING,UINT -VOID:STRING,UINT -VOID:UINT,STRING -VOID:UINT,UINT -VOID:UINT,UINT,OBJECT -VOID:OBJECT,ENUM,STRING -VOID:ENUM,STRING -VOID:OBJECT,ENUM,ENUM -VOID:INT,STRING -VOID:OBJECT,INT,STRING -VOID:OBJECT,INT,INT -VOID:OBJECT,POINTER -VOID:UINT,BOOLEAN -VOID:UINT,STRING,STRING -VOID:BOXED,STRING -VOID:POINTER,UINT -VOID:UINT,BOXED -VOID:BOOLEAN diff --git a/src/mcd-slacker.c b/src/mcd-slacker.c index b3ffbef2..76e34f7f 100644 --- a/src/mcd-slacker.c +++ b/src/mcd-slacker.c @@ -19,9 +19,9 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" #include "mcd-slacker.h" -#include "config.h" #include <dbus/dbus.h> #include <dbus/dbus-glib.h> @@ -52,7 +52,6 @@ #endif /* HAVE_MCE */ #include "mcd-debug.h" -#include "mcd-signals-marshal.h" struct _McdSlackerPrivate { DBusGConnection *bus; @@ -293,8 +292,7 @@ mcd_slacker_class_init (McdSlackerClass *klass) */ signals[SIG_INACTIVITY_CHANGED] = g_signal_new ("inactivity-changed", MCD_TYPE_SLACKER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, - _mcd_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + NULL, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); if (!mce_signal_interface_quark) { diff --git a/src/mcd-storage-ag-hidden.c b/src/mcd-storage-ag-hidden.c index 0b3ff022..ee857a74 100644 --- a/src/mcd-storage-ag-hidden.c +++ b/src/mcd-storage-ag-hidden.c @@ -19,11 +19,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" + #include "mcd-storage-ag-hidden.h" -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> -#include "config.h" #include "mcd-debug.h" /* FIXME: if we weren't in-tree, we wouldn't be able to include this header and * we'd have to re-hardcode magic strings like "Hidden". diff --git a/src/mcd-storage-priv.h b/src/mcd-storage-priv.h deleted file mode 100644 index 1b550d8f..00000000 --- a/src/mcd-storage-priv.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Mission Control storage API - interface which provides access to account - * parameter/setting storage - * - * Copyright © 2010 Nokia Corporation - * Copyright © 2010 Collabora Ltd. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <glib-object.h> -#include <mission-control-plugins/mission-control-plugins.h> -#include "mcd-storage.h" - -#ifndef MCD_STORAGE_PRIV_H -#define MCD_STORAGE_PRIV_H - -G_BEGIN_DECLS - -G_GNUC_INTERNAL void _mcd_storage_store_connections (McdStorage *storage); - -G_END_DECLS - -#endif /* MCD_STORAGE_H */ diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 6ae8c564..0ab1ff2e 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -1,189 +1,348 @@ -/* Mission Control storage API - interface which provides access to account - * parameter/setting storage +/* Representation of the account manager as presented to plugins. This is + * deliberately a "smaller" API than McdAccountManager. * * Copyright © 2010 Nokia Corporation - * Copyright © 2010 Collabora Ltd. + * Copyright © 2010-2012 Collabora Ltd. * * 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 + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * */ +#include "config.h" +#include "mcd-storage.h" + +#include "mcd-account.h" +#include "mcd-account-config.h" +#include "mcd-debug.h" +#include "plugin-loader.h" + +#include <string.h> + +#include <telepathy-glib/telepathy-glib.h> + +#include "mission-control-plugins/implementation.h" + +/* these pseudo-plugins take care of the actual account storage/retrieval */ +#include "mcd-account-manager-default.h" + +#if ENABLE_LIBACCOUNTS_SSO +#include "mcd-account-manager-sso.h" +# ifdef ACCOUNTS_GLIB_HIDDEN_SERVICE_TYPE +# include "mcd-storage-ag-hidden.h" +# endif +#endif -#include "mcd-storage-priv.h" -#include "mcd-master.h" -#include "mcd-account-manager-priv.h" +static GList *stores = NULL; +static void sort_and_cache_plugins (void); + +enum { + PROP_DBUS_DAEMON = 1, +}; + +struct _McdStorageClass { + GObjectClass parent; +}; + +static void plugin_iface_init (McpAccountManagerIface *iface, + gpointer unused G_GNUC_UNUSED); + +G_DEFINE_TYPE_WITH_CODE (McdStorage, mcd_storage, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (MCP_TYPE_ACCOUNT_MANAGER, plugin_iface_init)) + +static void +mcd_storage_init (McdStorage *self) +{ + self->keyfile = g_key_file_new (); + self->secrets = g_key_file_new (); +} -GType -mcd_storage_get_type (void) +static void +storage_finalize (GObject *object) { - static gsize once = 0; - static GType type = 0; + McdStorage *self = MCD_STORAGE (object); + GObjectFinalizeFunc finalize = + G_OBJECT_CLASS (mcd_storage_parent_class)->finalize; - if (g_once_init_enter (&once)) + g_key_file_free (self->keyfile); + g_key_file_free (self->secrets); + self->keyfile = NULL; + self->secrets = NULL; + + if (finalize != NULL) + finalize (object); +} + +static void +storage_dispose (GObject *object) +{ + McdStorage *self = MCD_STORAGE (object); + GObjectFinalizeFunc dispose = + G_OBJECT_CLASS (mcd_storage_parent_class)->dispose; + + tp_clear_object (&self->dbusd); + + if (dispose != NULL) + dispose (object); +} + +static void +storage_set_property (GObject *obj, guint prop_id, + const GValue *val, GParamSpec *pspec) +{ + McdStorage *self = MCD_STORAGE (obj); + + switch (prop_id) { - static const GTypeInfo info = { - sizeof (McdStorageIface), - NULL, /* base_init */ - NULL, /* base_finalize */ - NULL, /* class_init */ - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, /* instance_size */ - 0, /* n_preallocs */ - NULL, /* instance_init */ - NULL /* value_table */ - }; - - type = g_type_register_static (G_TYPE_INTERFACE, "McdStorage", &info, 0); - g_type_interface_add_prerequisite (type, G_TYPE_OBJECT); - g_once_init_leave (&once, 1); + case PROP_DBUS_DAEMON: + tp_clear_object (&self->dbusd); + self->dbusd = TP_DBUS_DAEMON (g_value_dup_object (val)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); + break; } +} - return type; +static void +storage_get_property (GObject *obj, guint prop_id, + GValue *val, GParamSpec *pspec) +{ + McdStorage *self = MCD_STORAGE (obj); + + switch (prop_id) + { + case PROP_DBUS_DAEMON: + g_value_set_object (val, self->dbusd); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); + break; + } } -/** - * mcd_storage_set_string: - * @storage: An object implementing the #McdStorage interface - * @account: the unique name of an account - * @key: the key (name) of the parameter or setting - * @value: the value to be stored (or %NULL to erase it) - * @secret: whether the value is confidential (might get stored in the - * keyring, for example) - * - * Copies and stores the supplied @value (or removes it if %NULL) to the - * internal cache. - * - * Returns: a #gboolean indicating whether the cache actually required an - * update (so that the caller can decide whether to request a commit to - * long term storage or not). %TRUE indicates the cache was updated and - * may not be in sync with the store any longer, %FALSE indicates we already - * held the value supplied. - */ -gboolean -mcd_storage_set_string (McdStorage *storage, - const gchar *account, - const gchar *key, - const gchar *value, - gboolean secret) +static void +mcd_storage_class_init (McdStorageClass *cls) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); + GObjectClass *object_class = (GObjectClass *) cls; + GParamSpec *spec = g_param_spec_object ("dbus-daemon", + "DBus daemon", + "DBus daemon", + TP_TYPE_DBUS_DAEMON, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_assert (iface != NULL); - g_return_val_if_fail (account != NULL, FALSE); - g_return_val_if_fail (key != NULL, FALSE); - g_return_val_if_fail (iface->set_string != NULL, FALSE); + object_class->set_property = storage_set_property; + object_class->get_property = storage_get_property; + object_class->dispose = storage_dispose; + object_class->finalize = storage_finalize; - return iface->set_string (storage, account, key, value, secret); + g_object_class_install_property (object_class, PROP_DBUS_DAEMON, spec); } -/** - * mcd_storage_set_value: - * @storage: An object implementing the #McdStorage interface - * @account: the unique name of an account - * @key: the key (name) of the parameter or setting - * @value: the value to be stored (or %NULL to erase it) - * @secret: whether the value is confidential (might get stored in the - * keyring, for example) - * - * Copies and stores the supplied @value (or removes it if %NULL) to the - * internal cache. - * - * Returns: a #gboolean indicating whether the cache actually required an - * update (so that the caller can decide whether to request a commit to - * long term storage or not). %TRUE indicates the cache was updated and - * may not be in sync with the store any longer, %FALSE indicates we already - * held the value supplied. - */ -gboolean -mcd_storage_set_value (McdStorage *storage, +McdStorage * +mcd_storage_new (TpDBusDaemon *dbus_daemon) +{ + return g_object_new (MCD_TYPE_STORAGE, + "dbus-daemon", dbus_daemon, + NULL); +} + +static gchar * +get_value (const McpAccountManager *ma, + const gchar *account, + const gchar *key) +{ + McdStorage *self = MCD_STORAGE (ma); + return g_key_file_get_value (self->keyfile, account, key, NULL); +} + +static void +set_value (const McpAccountManager *ma, const gchar *account, const gchar *key, - const GValue *value, - gboolean secret) + const gchar *value) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); + McdStorage *self = MCD_STORAGE (ma); - g_assert (iface != NULL); - g_return_val_if_fail (account != NULL, FALSE); - g_return_val_if_fail (key != NULL, FALSE); - g_return_val_if_fail (iface->set_value != NULL, FALSE); + if (value != NULL) + g_key_file_set_value (self->keyfile, account, key, value); + else + g_key_file_remove_key (self->keyfile, account, key, NULL); +} - return iface->set_value (storage, account, key, value, secret); +static GStrv +list_keys (const McpAccountManager *ma, + const gchar * account) +{ + McdStorage *self = MCD_STORAGE (ma); + + return g_key_file_get_keys (self->keyfile, account, NULL, NULL); } -/** - * mcd_storage_set_strv: - * @storage: An object implementing the #McdStorage interface - * @account: the unique name of an account - * @key: the key (name) of the parameter or setting - * @strv: the string vector to be stored (where %NULL is treated as equivalent - * to an empty vector) - * @secret: whether the value is confidential (might get stored in the - * keyring, for example) - * - * Copies and stores the supplied string vector to the internal cache. - * - * Returns: a #gboolean indicating whether the cache actually required an - * update (so that the caller can decide whether to request a commit to - * long term storage or not). %TRUE indicates the cache was updated and - * may not be in sync with the store any longer, %FALSE indicates we already - * held the value supplied. - */ -gboolean -mcd_storage_set_strv (McdStorage *storage, +static gboolean +is_secret (const McpAccountManager *ma, const gchar *account, - const gchar *key, - const gchar * const *strv, - gboolean secret) + const gchar *key) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); - GValue v = { 0, }; - static const gchar * const *empty = { NULL }; - gboolean ret; + McdStorage *self = MCD_STORAGE (ma); - g_assert (iface != NULL); - g_return_val_if_fail (account != NULL, FALSE); - g_return_val_if_fail (key != NULL, FALSE); - g_return_val_if_fail (iface->set_value != NULL, FALSE); + return g_key_file_get_boolean (self->secrets, account, key, NULL); +} - g_value_init (&v, G_TYPE_STRV); - g_value_set_static_boxed (&v, strv == NULL ? empty : strv); - ret = iface->set_value (storage, account, key, &v, secret); - g_value_unset (&v); - return ret; +static void +make_secret (const McpAccountManager *ma, + const gchar *account, + const gchar *key) +{ + McdStorage *self = MCD_STORAGE (ma); + DEBUG ("flagging %s.%s as secret", account, key); + g_key_file_set_boolean (self->secrets, account, key, TRUE); +} + +static gchar * +unique_name (const McpAccountManager *ma, + const gchar *manager, + const gchar *protocol, + const GHashTable *params) +{ + McdStorage *self = MCD_STORAGE (ma); + const gchar *base = NULL; + gchar *esc_manager, *esc_protocol, *esc_base; + guint i; + gsize base_len = strlen (TP_ACCOUNT_OBJECT_PATH_BASE); + DBusGConnection *connection = tp_proxy_get_dbus_connection (self->dbusd); + + base = tp_asv_get_string (params, "account"); + + if (base == NULL) + base = "account"; + + esc_manager = tp_escape_as_identifier (manager); + esc_protocol = g_strdelimit (g_strdup (protocol), "-", '_'); + esc_base = tp_escape_as_identifier (base); + + for (i = 0; i < G_MAXUINT; i++) + { + gchar *path = g_strdup_printf ( + TP_ACCOUNT_OBJECT_PATH_BASE "%s/%s/%s%u", + esc_manager, esc_protocol, esc_base, i); + + if (!g_key_file_has_group (self->keyfile, path + base_len) && + dbus_g_connection_lookup_g_object (connection, path) == NULL) + { + gchar *ret = g_strdup (path + base_len); + + g_free (path); + return ret; + } + + g_free (path); + } + + return NULL; +} + +/* sort in descending order of priority (ie higher prio => earlier in list) */ +static gint +account_storage_cmp (gconstpointer a, gconstpointer b) +{ + gint pa = mcp_account_storage_priority (a); + gint pb = mcp_account_storage_priority (b); + + if (pa > pb) return -1; + if (pa < pb) return 1; + + return 0; +} + +static void +add_storage_plugin (McpAccountStorage *plugin) +{ + stores = g_list_insert_sorted (stores, plugin, account_storage_cmp); +} + +static void +add_libaccounts_plugins_if_enabled (void) +{ +#if ENABLE_LIBACCOUNTS_SSO + add_storage_plugin (MCP_ACCOUNT_STORAGE (mcd_account_manager_sso_new ())); +# ifdef ACCOUNTS_GLIB_HIDDEN_SERVICE_TYPE + add_storage_plugin (MCP_ACCOUNT_STORAGE (mcd_storage_ag_hidden_new ())); +# endif +#endif +} + +static void +sort_and_cache_plugins () +{ + const GList *p; + static gboolean plugins_cached = FALSE; + + if (plugins_cached) + return; + + /* not guaranteed to have been called, but idempotent: */ + _mcd_plugin_loader_init (); + + /* Add compiled-in plugins */ + add_storage_plugin (MCP_ACCOUNT_STORAGE (mcd_account_manager_default_new ())); + add_libaccounts_plugins_if_enabled (); + + for (p = mcp_list_objects(); p != NULL; p = g_list_next (p)) + { + if (MCP_IS_ACCOUNT_STORAGE (p->data)) + { + McpAccountStorage *plugin = g_object_ref (p->data); + + add_storage_plugin (plugin); + } + } + + for (p = stores; p != NULL; p = g_list_next (p)) + { + McpAccountStorage *plugin = p->data; + + DEBUG ("found plugin %s [%s; priority %d]\n%s", + mcp_account_storage_name (plugin), + g_type_name (G_TYPE_FROM_INSTANCE (plugin)), + mcp_account_storage_priority (plugin), + mcp_account_storage_description (plugin)); + } + + plugins_cached = TRUE; } -/** - * mcd_storage_commit: - * @storage: An object implementing the #McdStorage interface - * @account: the unique name of an account - * - * Sync the long term storage (whatever it might be) with the current - * state of our internal cache. - */ void -mcd_storage_commit (McdStorage *storage, const gchar *account) +mcd_storage_connect_signal (const gchar *signame, + GCallback func, + gpointer user_data) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); + GList *p; - g_assert (iface != NULL); - g_return_if_fail (iface->commit != NULL); + for (p = stores; p != NULL; p = g_list_next (p)) + { + McpAccountStorage *plugin = p->data; - iface->commit (storage, account); + DEBUG ("connecting handler to %s plugin signal %s ", + mcp_account_storage_name (plugin), signame); + g_signal_connect (plugin, signame, func, user_data); + } } -/** +/* * mcd_storage_load: * @storage: An object implementing the #McdStorage interface * @@ -192,36 +351,62 @@ mcd_storage_commit (McdStorage *storage, const gchar *account) * have been claimed and other people might be relying on responses from us. */ void -mcd_storage_load (McdStorage *storage) +mcd_storage_load (McdStorage *self) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); + McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + GList *store = NULL; + + g_return_if_fail (MCD_IS_STORAGE (self)); + + sort_and_cache_plugins (); + + store = g_list_last (stores); + + /* fetch accounts stored in plugins, in reverse priority so higher prio * + * plugins can overwrite lower prio ones' account data */ + while (store != NULL) + { + GList *account; + McpAccountStorage *plugin = store->data; + GList *stored = mcp_account_storage_list (plugin, ma); + const gchar *pname = mcp_account_storage_name (plugin); + const gint prio = mcp_account_storage_priority (plugin); + + DEBUG ("listing from plugin %s [prio: %d]", pname, prio); + for (account = stored; account != NULL; account = g_list_next (account)) + { + gchar *name = account->data; - g_assert (iface != NULL); - g_return_if_fail (iface->load != NULL); + DEBUG ("fetching %s from plugin %s [prio: %d]", name, pname, prio); + mcp_account_storage_get (plugin, ma, name, NULL); - iface->load (storage); + g_free (name); + } + + /* already freed the contents, just need to free the list itself */ + g_list_free (stored); + store = g_list_previous (store); + } } -/** +/* * mcd_storage_dup_accounts: * @storage: An object implementing the #McdStorage interface * @n: place for the number of accounts to be written to (or %NULL) * * Returns: a newly allocated GStrv containing the unique account names, * which must be freed by the caller with g_strfreev(). - **/ + */ GStrv -mcd_storage_dup_accounts (McdStorage *storage, gsize *n) +mcd_storage_dup_accounts (McdStorage *self, + gsize *n) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); - - g_assert (iface != NULL); - g_return_val_if_fail (iface->dup_accounts != NULL, NULL); + g_return_val_if_fail (MCD_IS_STORAGE (self), NULL); - return iface->dup_accounts (storage, n); + return g_key_file_get_groups (self->keyfile, n); } -/** +/* * mcd_storage_dup_settings: * @storage: An object implementing the #McdStorage interface * @account: unique name of the account @@ -230,42 +415,97 @@ mcd_storage_dup_accounts (McdStorage *storage, gsize *n) * Returns: a newly allocated GStrv containing the names of all the * settings or parameters currently stored for @account. Must be * freed by the caller with g_strfreev(). - **/ + */ GStrv -mcd_storage_dup_settings (McdStorage *storage, const gchar *account, gsize *n) +mcd_storage_dup_settings (McdStorage *self, + const gchar *account, + gsize *n) +{ + g_return_val_if_fail (MCD_IS_STORAGE (self), NULL); + + return g_key_file_get_keys (self->keyfile, account, n, NULL); +} + +/* + * mcd_storage_get_plugin: + * @storage: An object implementing the #McdStorage interface + * @account: unique name of the account + * + * Returns: the #McpAccountStorage object which is handling the account, + * if any (if a new account has not yet been flushed to storage this can + * be %NULL). + * + * Plugins are kept in permanent storage and can never be unloaded, so + * the returned pointer need not be reffed or unreffed. (Indeed, it's + * probably safer not to) + */ +McpAccountStorage * +mcd_storage_get_plugin (McdStorage *self, + const gchar *account) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); + GList *store = stores; + McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + McpAccountStorage *owner = NULL; - g_assert (iface != NULL); + g_return_val_if_fail (MCD_IS_STORAGE (self), NULL); g_return_val_if_fail (account != NULL, NULL); - g_return_val_if_fail (iface->dup_settings != NULL, NULL); - return iface->dup_settings (storage, account, n); + for (; store != NULL && owner == NULL; store = g_list_next (store)) + { + McpAccountStorage *plugin = store->data; + + if (mcp_account_storage_get (plugin, ma, account, "manager")) + owner = plugin; + } + + return owner; } -/** +/* * mcd_storage_dup_string: * @storage: An object implementing the #McdStorage interface * @account: unique name of the account * @key: name of the setting to be retrieved * * Returns: a newly allocated gchar * which must be freed with g_free(). - **/ + */ gchar * -mcd_storage_dup_string (McdStorage *storage, +mcd_storage_dup_string (McdStorage *self, const gchar *account, const gchar *key) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); + gchar *value = NULL; - g_assert (iface != NULL); - g_assert (iface->dup_string != NULL); + g_return_val_if_fail (MCD_IS_STORAGE (self), NULL); g_return_val_if_fail (account != NULL, NULL); - return iface->dup_string (storage, account, key); + value = g_key_file_get_string (self->keyfile, account, key, NULL); + + return value; } -/** +/* + * mcd_storage_has_value: + * @storage: An object implementing the #McdStorage interface + * @account: unique name of the account + * @key: name of the setting to be retrieved + * + * Returns: a #gboolean: %TRUE if the setting is present in the store, + * %FALSE otherwise. + */ +gboolean +mcd_storage_has_value (McdStorage *self, + const gchar *account, + const gchar *key) +{ + g_return_val_if_fail (MCD_IS_STORAGE (self), FALSE); + g_return_val_if_fail (account != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + return g_key_file_has_key (self->keyfile, account, key, NULL); +} + +/* * mcd_storage_dup_value: * @storage: An object implementing the #McdStorage interface * @account: unique name of the account @@ -281,118 +521,551 @@ mcd_storage_dup_string (McdStorage *storage, * If @error is set, but a non-%NULL value was returned, this indicates * that no value for the @key was found for @account, and the default * value for @type has been returned. - **/ + */ GValue * -mcd_storage_dup_value (McdStorage *storage, +mcd_storage_dup_value (McdStorage *self, const gchar *account, const gchar *key, GType type, GError **error) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); + GValue *value = NULL; + gchar *v_string = NULL; + gint64 v_int = 0; + guint64 v_uint = 0; + gboolean v_bool = FALSE; + double v_double = 0.0; - g_assert (iface != NULL); - g_assert (iface->dup_value != NULL); + g_return_val_if_fail (MCD_IS_STORAGE (self), NULL); g_return_val_if_fail (account != NULL, NULL); - return iface->dup_value (storage, account, key, type, error); + switch (type) + { + case G_TYPE_STRING: + v_string = g_key_file_get_string (self->keyfile, account, key, error); + value = tp_g_value_slice_new_take_string (v_string); + break; + + case G_TYPE_INT: + v_int = g_key_file_get_integer (self->keyfile, account, key, error); + value = tp_g_value_slice_new_int (v_int); + break; + + case G_TYPE_INT64: + v_int = tp_g_key_file_get_int64 (self->keyfile, account, key, error); + value = tp_g_value_slice_new_int64 (v_int); + break; + + case G_TYPE_UINT: + v_uint = tp_g_key_file_get_uint64 (self->keyfile, account, key, error); + + if (v_uint > 0xFFFFFFFFU) + g_set_error (error, MCD_ACCOUNT_ERROR, + MCD_ACCOUNT_ERROR_GET_PARAMETER, + "Integer is out of range"); + else + value = tp_g_value_slice_new_uint (v_uint); + break; + + case G_TYPE_UCHAR: + v_int = g_key_file_get_integer (self->keyfile, account, key, error); + + if (v_int < 0 || v_int > 0xFF) + { + g_set_error (error, MCD_ACCOUNT_ERROR, + MCD_ACCOUNT_ERROR_GET_PARAMETER, + "Integer is out of range"); + } + else + { + value = tp_g_value_slice_new (G_TYPE_UCHAR); + g_value_set_uchar (value, v_int); + } + break; + + case G_TYPE_UINT64: + v_uint = tp_g_key_file_get_uint64 (self->keyfile, account, key, error); + value = tp_g_value_slice_new_uint64 (v_uint); + break; + + case G_TYPE_BOOLEAN: + v_bool = g_key_file_get_boolean (self->keyfile, account, key, error); + value = tp_g_value_slice_new_boolean (v_bool); + break; + + case G_TYPE_DOUBLE: + v_double = g_key_file_get_double (self->keyfile, account, key, error); + value = tp_g_value_slice_new_double (v_double); + break; + + default: + if (type == G_TYPE_STRV) + { + gchar **v = g_key_file_get_string_list (self->keyfile, account, + key, NULL, error); + + value = tp_g_value_slice_new_take_boxed (G_TYPE_STRV, v); + } + else if (type == DBUS_TYPE_G_OBJECT_PATH) + { + v_string = g_key_file_get_string (self->keyfile, account, key, + NULL); + + if (v_string == NULL) + { + g_set_error (error, MCD_ACCOUNT_ERROR, + MCD_ACCOUNT_ERROR_GET_PARAMETER, + "Invalid object path NULL"); + } + else if (!tp_dbus_check_valid_object_path (v_string, NULL)) + { + g_set_error (error, MCD_ACCOUNT_ERROR, + MCD_ACCOUNT_ERROR_GET_PARAMETER, + "Invalid object path %s", v_string); + g_free (v_string); + } + else + { + value = tp_g_value_slice_new_take_object_path (v_string); + } + } + else if (type == TP_ARRAY_TYPE_OBJECT_PATH_LIST) + { + gchar **v = g_key_file_get_string_list (self->keyfile, account, + key, NULL, error); + gchar **iter; + GPtrArray *arr = g_ptr_array_new (); + + for (iter = v; iter != NULL && *iter != NULL; iter++) + { + if (!g_variant_is_object_path (*iter)) + { + g_set_error (error, MCD_ACCOUNT_ERROR, + MCD_ACCOUNT_ERROR_GET_PARAMETER, + "Invalid object path %s stored in account", *iter); + g_strfreev (v); + v = NULL; + break; + } + } + + for (iter = v; iter != NULL && *iter != NULL; iter++) + { + /* transfer ownership from v to arr */ + g_ptr_array_add (arr, *iter); + } + + /* not g_strfreev - the strings' ownership has been transferred */ + g_free (v); + + value = tp_g_value_slice_new_take_boxed ( + TP_ARRAY_TYPE_OBJECT_PATH_LIST, arr); + } + else + { + gchar *message = + g_strdup_printf ("cannot get property %s on account %s, " + "unknown type %s", + key, account, g_type_name (type)); + + g_warning ("%s: %s", G_STRFUNC, message); + g_set_error (error, MCD_ACCOUNT_ERROR, + MCD_ACCOUNT_ERROR_GET_PARAMETER, + "%s", message); + g_free (message); + } + } + + /* This can return a non-NULL GValue * _and_ a non-NULL GError *, * + * indicating a value was not found and the default for that type * + * (eg 0 for integers) has been returned - this matches the behaviour * + * of the old code that this function replaces. If changing this, make * + * sure all our callers are suitable updated */ + + return value; } -/** +/* * mcd_storage_get_boolean: * @storage: An object implementing the #McdStorage interface * @account: unique name of the account * @key: name of the setting to be retrieved * * Returns: a #gboolean. Unset/unparseable values are returned as %FALSE - **/ + */ gboolean -mcd_storage_get_boolean (McdStorage *storage, +mcd_storage_get_boolean (McdStorage *self, const gchar *account, const gchar *key) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); - - g_assert (iface != NULL); - g_assert (iface->get_boolean != NULL); + g_return_val_if_fail (MCD_IS_STORAGE (self), FALSE); g_return_val_if_fail (account != NULL, FALSE); - return iface->get_boolean (storage, account, key); + return g_key_file_get_boolean (self->keyfile, account, key, NULL); } -/** +/* * mcd_storage_get_integer: * @storage: An object implementing the #McdStorage interface * @account: unique name of the account * @key: name of the setting to be retrieved * * Returns: a #gint. Unset or non-numeric values are returned as 0 - **/ + */ gint -mcd_storage_get_integer (McdStorage *storage, +mcd_storage_get_integer (McdStorage *self, const gchar *account, const gchar *key) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); - - g_assert (iface != NULL); - g_assert (iface->get_integer != NULL); + g_return_val_if_fail (MCD_IS_STORAGE (self), 0); g_return_val_if_fail (account != NULL, 0); - return iface->get_integer (storage, account, key); + return g_key_file_get_integer (self->keyfile, account, key, NULL); } +static void +update_storage (McdStorage *self, + const gchar *account, + const gchar *key) +{ + GList *store; + gboolean done = FALSE; + McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + gchar *val = NULL; -/** - * mcd_storage_has_value: + /* don't unescape the value here, we're flushing it to storage * + * everywhere else should handle escaping on the way in and unescaping * + * on the way out of the keyfile, but not here: */ + val = g_key_file_get_value (self->keyfile, account, key, NULL); + + /* we're deleting, which is unconditional, no need to check if anyone * + * claims this setting for themselves */ + if (val == NULL) + done = TRUE; + + for (store = stores; store != NULL; store = g_list_next (store)) + { + McpAccountStorage *plugin = store->data; + const gchar *pn = mcp_account_storage_name (plugin); + + if (done) + { + DEBUG ("MCP:%s -> delete %s.%s", pn, account, key); + mcp_account_storage_delete (plugin, ma, account, key); + } + else + { + done = mcp_account_storage_set (plugin, ma, account, key, val); + DEBUG ("MCP:%s -> %s %s.%s", + pn, done ? "store" : "ignore", account, key); + } + } + + g_free (val); +} + +/* + * mcd_storage_set_string: * @storage: An object implementing the #McdStorage interface - * @account: unique name of the account - * @key: name of the setting to be retrieved + * @account: the unique name of an account + * @key: the key (name) of the parameter or setting + * @value: the value to be stored (or %NULL to erase it) + * @secret: whether the value is confidential (might get stored in the + * keyring, for example) * - * Returns: a #gboolean: %TRUE if the setting is present in the store, - * %FALSE otherwise. - **/ + * Copies and stores the supplied @value (or removes it if %NULL) to the + * internal cache. + * + * Returns: a #gboolean indicating whether the cache actually required an + * update (so that the caller can decide whether to request a commit to + * long term storage or not). %TRUE indicates the cache was updated and + * may not be in sync with the store any longer, %FALSE indicates we already + * held the value supplied. + */ gboolean -mcd_storage_has_value (McdStorage *storage, +mcd_storage_set_string (McdStorage *self, const gchar *account, - const gchar *key) + const gchar *key, + const gchar *val, + gboolean secret) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); + gboolean updated = FALSE; + gchar *old = g_key_file_get_string (self->keyfile, account, key, NULL); - g_assert (iface != NULL); - g_assert (iface->has_value != NULL); + g_return_val_if_fail (MCD_IS_STORAGE (self), FALSE); g_return_val_if_fail (account != NULL, FALSE); g_return_val_if_fail (key != NULL, FALSE); - return iface->has_value (storage, account, key); + if (val == NULL) + g_key_file_remove_key (self->keyfile, account, key, NULL); + else + g_key_file_set_string (self->keyfile, account, key, val); + + if (tp_strdiff (old, val)) + { + if (secret) + { + McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + + mcp_account_manager_parameter_make_secret (ma, account, key); + } + + update_storage (self, account, key); + updated = TRUE; + } + + g_free (old); + + return updated; } -/** - * mcd_storage_get_plugin: +/* + * mcd_storage_set_value: * @storage: An object implementing the #McdStorage interface - * @account: unique name of the account + * @account: the unique name of an account + * @key: the key (name) of the parameter or setting + * @value: the value to be stored (or %NULL to erase it) + * @secret: whether the value is confidential (might get stored in the + * keyring, for example) * - * Returns: the #McpAccountStorage object which is handling the account, - * if any (if a new account has not yet been flushed to storage this can - * be %NULL). + * Copies and stores the supplied @value (or removes it if %NULL) to the + * internal cache. * - * Plugins are kept in permanent storage and can never be unloaded, so - * the returned pointer need not be reffed or unreffed. (Indeed, it's - * probably safer not to) - **/ -McpAccountStorage * -mcd_storage_get_plugin (McdStorage *storage, const gchar *account) + * Returns: a #gboolean indicating whether the cache actually required an + * update (so that the caller can decide whether to request a commit to + * long term storage or not). %TRUE indicates the cache was updated and + * may not be in sync with the store any longer, %FALSE indicates we already + * held the value supplied. + */ +gboolean +mcd_storage_set_value (McdStorage *self, + const gchar *name, + const gchar *key, + const GValue *value, + gboolean secret) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); + g_return_val_if_fail (MCD_IS_STORAGE (self), FALSE); + g_return_val_if_fail (name != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); - g_assert (iface != NULL); - g_assert (iface->get_storage_plugin != NULL); - g_return_val_if_fail (account != NULL, NULL); + if (value == NULL) + { + return mcd_storage_set_string (self, name, key, NULL, secret); + } + else + { + gboolean updated = FALSE; + gchar *old = g_key_file_get_value (self->keyfile, name, key, NULL); + gchar *new = NULL; + gchar *buf = NULL; + + switch (G_VALUE_TYPE (value)) + { + case G_TYPE_STRING: + g_key_file_set_string (self->keyfile, name, key, + g_value_get_string (value)); + break; + + case G_TYPE_UINT: + buf = g_strdup_printf ("%u", g_value_get_uint (value)); + break; + + case G_TYPE_INT: + g_key_file_set_integer (self->keyfile, name, key, + g_value_get_int (value)); + break; + + case G_TYPE_BOOLEAN: + g_key_file_set_boolean (self->keyfile, name, key, + g_value_get_boolean (value)); + break; + + case G_TYPE_UCHAR: + buf = g_strdup_printf ("%u", g_value_get_uchar (value)); + break; + + case G_TYPE_UINT64: + buf = g_strdup_printf ("%" G_GUINT64_FORMAT, + g_value_get_uint64 (value)); + break; + + case G_TYPE_INT64: + buf = g_strdup_printf ("%" G_GINT64_FORMAT, + g_value_get_int64 (value)); + break; + + case G_TYPE_DOUBLE: + g_key_file_set_double (self->keyfile, name, key, + g_value_get_double (value)); + break; + + default: + if (G_VALUE_HOLDS (value, G_TYPE_STRV)) + { + gchar **strings = g_value_get_boxed (value); + + g_key_file_set_string_list (self->keyfile, name, key, + (const gchar **)strings, + g_strv_length (strings)); + } + else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) + { + g_key_file_set_string (self->keyfile, name, key, + g_value_get_boxed (value)); + } + else if (G_VALUE_HOLDS (value, TP_ARRAY_TYPE_OBJECT_PATH_LIST)) + { + GPtrArray *arr = g_value_get_boxed (value); + + g_key_file_set_string_list (self->keyfile, name, key, + (const gchar * const *) arr->pdata, arr->len); + } + else + { + g_warning ("Unexpected param type %s", + G_VALUE_TYPE_NAME (value)); + return FALSE; + } + } + + if (buf != NULL) + g_key_file_set_string (self->keyfile, name, key, buf); + + new = g_key_file_get_value (self->keyfile, name, key, NULL); - return iface->get_storage_plugin (storage, account); + if (tp_strdiff (old, new)) + { + if (secret) + { + McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + + mcp_account_manager_parameter_make_secret (ma, name, key); + } + + update_storage (self, name, key); + updated = TRUE; + } + + g_free (new); + g_free (buf); + g_free (old); + + return updated; + } } -/** +/* + * mcd_storage_create_account: + * @storage: An object implementing the #McdStorage interface + * @provider: the desired storage provider, or %NULL + * @manager: the name of the manager + * @protocol: the name of the protocol + * @params: A gchar * / GValue * hash table of account parameters + * @error: a #GError to fill when returning %NULL + * + * Create a new account in storage. This should not store any + * information on the long term storage until mcd_storage_commit() is called. + * + * See mcp_account_storage_create(). + * + * Returns: the unique name to use for the new account, or %NULL on error. + */ +gchar * +mcd_storage_create_account (McdStorage *self, + const gchar *provider, + const gchar *manager, + const gchar *protocol, + GHashTable *params, + GError **error) +{ + GList *store; + McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + + g_return_val_if_fail (MCD_IS_STORAGE (self), NULL); + g_return_val_if_fail (!tp_str_empty (manager), NULL); + g_return_val_if_fail (!tp_str_empty (protocol), NULL); + + /* If a storage provider is specified, use only it or fail */ + if (provider != NULL) + { + for (store = stores; store != NULL; store = g_list_next (store)) + { + McpAccountStorage *plugin = store->data; + + if (!tp_strdiff (mcp_account_storage_provider (plugin), provider)) + { + return mcp_account_storage_create (plugin, ma, manager, + protocol, params, error); + } + } + + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + "Storage provider '%s' does not exist", provider); + + return NULL; + } + + /* No provider specified, let's pick the first plugin able to create this + * account in priority order. + * + * FIXME: This is rather subtle, and relies on the fact that accounts + * aren't always strongly tied to a single plugin. + * + * For plugins that only store their accounts set up specifically + * through them (like the libaccounts/SSO pseudo-plugin, + * McdAccountManagerSSO), create() will fail as unimplemented, + * and we'll fall through to the next plugin. Eventually we'll + * reach the default keyfile+gnome-keyring plugin, or another + * plugin that accepts arbitrary accounts. When set() is called, + * the libaccounts/SSO plugin will reject that too, and again, + * we'll fall through to a plugin that accepts arbitrary + * accounts. + * + * Plugins that will accept arbitrary accounts being created + * via D-Bus (like the default keyfile+gnome-keyring plugin, + * and the account-diversion plugin in tests/twisted) + * should, in principle, implement create() to be successful. + * If they do, their create() will succeed, and later, so will + * their set(). + * + * We can't necessarily rely on all such plugins implementing + * create(), because it isn't a mandatory part of the plugin + * API (it was added later). However, as it happens, the + * default plugin returns successfully from create() without + * really doing anything. When we iterate through the accounts again + * to call set(), higher-priority plugins are given a second + * chance to intercept that; so we end up with create() in + * the default plugin being followed by set() from the + * higher-priority plugin. In theory that's bad because it + * splits the account across two plugins, but in practice + * it isn't a problem because the default plugin's create() + * doesn't really do anything anyway. + */ + for (store = stores; store != NULL; store = g_list_next (store)) + { + McpAccountStorage *plugin = store->data; + gchar *ret; + + ret = mcp_account_storage_create (plugin, ma, manager, protocol, params, + error); + + if (ret != NULL) + return ret; + + g_clear_error (error); + } + + /* This should never happen since the default storage is always able to create + * an account */ + g_warn_if_reached (); + g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT, + "None of the storage provider are able to create the account"); + + return NULL; +} + + +/* * mcd_storage_delete_account: * @storage: An object implementing the #McdStorage interface * @account: unique name of the account @@ -403,28 +1076,125 @@ mcd_storage_get_plugin (McdStorage *storage, const gchar *account) * in long term storage once mcd_storage_commit() has been called. */ void -mcd_storage_delete_account (McdStorage *storage, const gchar *account) +mcd_storage_delete_account (McdStorage *self, + const gchar *account) { - McdStorageIface *iface = MCD_STORAGE_GET_IFACE (storage); + GList *store; + McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); - g_assert (iface != NULL); - g_assert (iface->delete_account != NULL); + g_return_if_fail (MCD_IS_STORAGE (self)); g_return_if_fail (account != NULL); - iface->delete_account (storage, account); + g_key_file_remove_group (self->keyfile, account, NULL); + + for (store = stores; store != NULL; store = g_list_next (store)) + { + McpAccountStorage *plugin = store->data; + + mcp_account_storage_delete (plugin, ma, account, NULL); + } } +/* + * mcd_storage_commit: + * @storage: An object implementing the #McdStorage interface + * @account: the unique name of an account + * + * Sync the long term storage (whatever it might be) with the current + * state of our internal cache. + */ void -_mcd_storage_store_connections (McdStorage *storage) +mcd_storage_commit (McdStorage *self, const gchar *account) +{ + GList *store; + McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + + g_return_if_fail (MCD_IS_STORAGE (self)); + + for (store = stores; store != NULL; store = g_list_next (store)) + { + McpAccountStorage *plugin = store->data; + const gchar *pname = mcp_account_storage_name (plugin); + + if (account != NULL) + { + DEBUG ("flushing plugin %s %s to long term storage", pname, account); + mcp_account_storage_commit_one (plugin, ma, account); + } + else + { + DEBUG ("flushing plugin %s to long term storage", pname); + mcp_account_storage_commit (plugin, ma); + } + } +} + +/* + * mcd_storage_set_strv: + * @storage: An object implementing the #McdStorage interface + * @account: the unique name of an account + * @key: the key (name) of the parameter or setting + * @strv: the string vector to be stored (where %NULL is treated as equivalent + * to an empty vector) + * @secret: whether the value is confidential (might get stored in the + * keyring, for example) + * + * Copies and stores the supplied string vector to the internal cache. + * + * Returns: a #gboolean indicating whether the cache actually required an + * update (so that the caller can decide whether to request a commit to + * long term storage or not). %TRUE indicates the cache was updated and + * may not be in sync with the store any longer, %FALSE indicates we already + * held the value supplied. + */ +gboolean +mcd_storage_set_strv (McdStorage *storage, + const gchar *account, + const gchar *key, + const gchar * const *strv, + gboolean secret) { - McdMaster *master = mcd_master_get_default (); - McdAccountManager *account_manager = NULL; + GValue v = G_VALUE_INIT; + static const gchar * const *empty = { NULL }; + gboolean ret; + + g_return_val_if_fail (MCD_IS_STORAGE (storage), FALSE); + g_return_val_if_fail (account != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); - g_object_get (master, "account-manager", &account_manager, NULL); + g_value_init (&v, G_TYPE_STRV); + g_value_set_static_boxed (&v, strv == NULL ? empty : strv); + ret = mcd_storage_set_value (storage, account, key, &v, secret); + g_value_unset (&v); + return ret; +} - if (account_manager != NULL) +void +mcd_storage_ready (McdStorage *self) +{ + GList *store; + McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); + + for (store = stores; store != NULL; store = g_list_next (store)) { - _mcd_account_manager_store_account_connections (account_manager); - g_object_unref (account_manager); + McpAccountStorage *plugin = store->data; + const gchar *plugin_name = mcp_account_storage_name (plugin); + + DEBUG ("Unblocking async account ops by %s", plugin_name); + mcp_account_storage_ready (plugin, ma); } } + +static void +plugin_iface_init (McpAccountManagerIface *iface, + gpointer unused G_GNUC_UNUSED) +{ + DEBUG (); + + iface->get_value = get_value; + iface->set_value = set_value; + iface->is_secret = is_secret; + iface->make_secret = make_secret; + iface->unique_name = unique_name; + iface->list_keys = list_keys; +} diff --git a/src/mcd-storage.h b/src/mcd-storage.h index be26ccf4..c8c031b2 100644 --- a/src/mcd-storage.h +++ b/src/mcd-storage.h @@ -27,74 +27,41 @@ G_BEGIN_DECLS -typedef struct _McdStorage McdStorage; -typedef struct _McdStorageIface McdStorageIface; +typedef struct { + GObject parent; + TpDBusDaemon *dbusd; + GKeyFile *keyfile; + GKeyFile *secrets; +} McdStorage; -struct _McdStorageIface { - GTypeInterface parent; - - void (*load) (McdStorage *storage); - - GStrv (*dup_accounts) (McdStorage *storage, gsize *n); - - GStrv (*dup_settings) (McdStorage *storage, const gchar *account, gsize *n); - - gboolean (*set_string) (McdStorage *storage, - const gchar *account, - const gchar *key, - const gchar *value, - gboolean secret); - - gboolean (*set_value) (McdStorage *storage, - const gchar *account, - const gchar *key, - const GValue *value, - gboolean secret); - - void (*delete_account) (McdStorage *storage, - const gchar *account); - - void (*commit) (McdStorage *storage, const gchar *account); - - gchar * (*dup_string) (McdStorage *storage, - const gchar *account, - const gchar *key); - - GValue * (*dup_value) (McdStorage *storage, - const gchar *account, - const gchar *key, - GType type, - GError **error); - - gboolean (*get_boolean) (McdStorage *storage, - const gchar *account, - const gchar *key); - - gint (*get_integer) (McdStorage *storage, - const gchar *account, - const gchar *key); - - gboolean (*has_value) (McdStorage *storage, - const gchar *account, - const gchar *key); - - McpAccountStorage *(*get_storage_plugin) (McdStorage *storage, - const gchar *account); -}; +typedef struct _McdStorageClass McdStorageClass; +typedef struct _McdStoragePrivate McdStoragePrivate; #define MCD_TYPE_STORAGE (mcd_storage_get_type ()) #define MCD_STORAGE(o) \ (G_TYPE_CHECK_INSTANCE_CAST ((o), MCD_TYPE_STORAGE, McdStorage)) +#define MCD_STORAGE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST ((cls), MCD_TYPE_STORAGE, McdStorageClass)) + #define MCD_IS_STORAGE(o) \ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MCD_TYPE_STORAGE)) -#define MCD_STORAGE_GET_IFACE(o) \ - (G_TYPE_INSTANCE_GET_INTERFACE ((o), MCD_TYPE_STORAGE, McdStorageIface)) +#define MCD_IS_STORAGE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE ((cls), MCD_TYPE_STORAGE)) + +#define MCD_STORAGE_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), MCD_TYPE_STORAGE, McdStorageClass)) GType mcd_storage_get_type (void); +McdStorage *mcd_storage_new (TpDBusDaemon *dbus_daemon); +void mcd_storage_ready (McdStorage *self); +void mcd_storage_connect_signal (const gchar *signal, + GCallback func, + gpointer user_data); + void mcd_storage_load (McdStorage *storage); GStrv mcd_storage_dup_accounts (McdStorage *storage, gsize *n); @@ -121,6 +88,13 @@ gboolean mcd_storage_set_value (McdStorage *storage, const GValue *value, gboolean secret); +gchar *mcd_storage_create_account (McdStorage *storage, + const gchar *provider, + const gchar *manager, + const gchar *protocol, + GHashTable *params, + GError **error); + void mcd_storage_delete_account (McdStorage *storage, const gchar *account); void mcd_storage_commit (McdStorage *storage, const gchar *account); diff --git a/src/mcd-transport.c b/src/mcd-transport.c index 433fce17..9f9bdc79 100644 --- a/src/mcd-transport.c +++ b/src/mcd-transport.c @@ -23,10 +23,10 @@ * */ +#include "config.h" #include <glib.h> #include "mcd-transport.h" -#include "mcd-signals-marshal.h" #include "mcd-enum-types.h" /** @@ -71,8 +71,7 @@ mcd_transport_plugin_base_init (gpointer iface) G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (McdTransportPluginIface, status_changed), - NULL, NULL, - _mcd_marshal_VOID__POINTER_UINT, + NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_POINTER, MCD_TYPE_TRANSPORT_STATUS); initialized = TRUE; @@ -104,22 +103,6 @@ mcd_transport_plugin_get_type (void) } /** - * mcd_transport_plugin_get_name: - * @plugin: the #McdTransportPlugin. - * - * Returns: the name of the plugin. - */ -const gchar * -mcd_transport_plugin_get_name (McdTransportPlugin *plugin) -{ - McdTransportPluginIface *iface; - - iface = MCD_TRANSPORT_PLUGIN_GET_IFACE (plugin); - g_return_val_if_fail (iface->get_name != NULL, NULL); - return iface->get_name (plugin); -} - -/** * mcd_transport_plugin_get_transports: * @plugin: the #McdTransportPlugin. * diff --git a/src/mcd-transport.h b/src/mcd-transport.h index a3d27f54..ec972861 100644 --- a/src/mcd-transport.h +++ b/src/mcd-transport.h @@ -52,7 +52,6 @@ struct _McdTransportPluginIface GTypeInterface g_iface; /* methods */ - const gchar * (*get_name) (McdTransportPlugin *plugin); const GList * (*get_transports) (McdTransportPlugin *plugin); gboolean (*check_conditions) (McdTransportPlugin *plugin, McdTransport *transport, @@ -69,7 +68,6 @@ struct _McdTransportPluginIface GType mcd_transport_plugin_get_type (void) G_GNUC_CONST; -const gchar *mcd_transport_plugin_get_name (McdTransportPlugin *plugin); const GList *mcd_transport_plugin_get_transports (McdTransportPlugin *plugin); gboolean mcd_transport_plugin_check_conditions (McdTransportPlugin *plugin, diff --git a/src/mcd.xml b/src/mcd.xml index eb791c11..27ae8d62 100644 --- a/src/mcd.xml +++ b/src/mcd.xml @@ -6,13 +6,10 @@ <xi:include href="../xml/Connection_Manager_Interface_Account_Storage.xml"/> -<xi:include href="../xml/Account_Interface_Addressing.xml"/> -<xi:include href="../xml/Account_Interface_Compat.xml"/> <xi:include href="../xml/Account_Interface_Conditions.xml"/> <xi:include href="../xml/Account_Interface_External_Password_Storage.xml"/> <xi:include href="../xml/Account_Interface_Hidden.xml"/> -<xi:include href="../xml/Account_Manager_Interface_Query.xml"/> <xi:include href="../xml/Account_Manager_Interface_Hidden.xml"/> <xi:include href="dispatcher.xml"/> diff --git a/src/plugin-account.c b/src/plugin-account.c deleted file mode 100644 index 14b4e443..00000000 --- a/src/plugin-account.c +++ /dev/null @@ -1,911 +0,0 @@ -/* Representation of the account manager as presented to plugins. This is - * deliberately a "smaller" API than McdAccountManager. - * - * Copyright © 2010 Nokia Corporation - * Copyright © 2010-2012 Collabora Ltd. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include "plugin-loader.h" -#include "plugin-account.h" -#include "config.h" - -#include <string.h> - -#include <telepathy-glib/telepathy-glib.h> - -#include "mission-control-plugins/implementation.h" - -/* these pseudo-plugins take care of the actual account storage/retrieval */ -#include "mcd-account-manager-default.h" - -#if ENABLE_LIBACCOUNTS_SSO -#include "mcd-account-manager-sso.h" -# ifdef ACCOUNTS_GLIB_HIDDEN_SERVICE_TYPE -# include "mcd-storage-ag-hidden.h" -# endif -#endif - -static GList *stores = NULL; -static void sort_and_cache_plugins (void); - -enum { - PROP_DBUS_DAEMON = 1, -}; - -struct _McdPluginAccountManagerClass { - GObjectClass parent; -}; - -static void storage_iface_init (McdStorageIface *iface, - gpointer unused G_GNUC_UNUSED); - -static void plugin_iface_init (McpAccountManagerIface *iface, - gpointer unused G_GNUC_UNUSED); - -G_DEFINE_TYPE_WITH_CODE (McdPluginAccountManager, mcd_plugin_account_manager, \ - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (MCD_TYPE_STORAGE, storage_iface_init); - G_IMPLEMENT_INTERFACE (MCP_TYPE_ACCOUNT_MANAGER, plugin_iface_init)) - -static void -mcd_plugin_account_manager_init (McdPluginAccountManager *self) -{ - self->keyfile = g_key_file_new (); - self->secrets = g_key_file_new (); -} - -static void -plugin_account_manager_finalize (GObject *object) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (object); - GObjectFinalizeFunc finalize = - G_OBJECT_CLASS (mcd_plugin_account_manager_parent_class)->finalize; - - g_key_file_free (self->keyfile); - g_key_file_free (self->secrets); - self->keyfile = NULL; - self->secrets = NULL; - - if (finalize != NULL) - finalize (object); -} - -static void -plugin_account_manager_dispose (GObject *object) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (object); - GObjectFinalizeFunc dispose = - G_OBJECT_CLASS (mcd_plugin_account_manager_parent_class)->dispose; - - tp_clear_object (&self->dbusd); - - if (dispose != NULL) - dispose (object); -} - -static void -plugin_account_manager_set_property (GObject *obj, guint prop_id, - const GValue *val, GParamSpec *pspec) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (obj); - - switch (prop_id) - { - case PROP_DBUS_DAEMON: - tp_clear_object (&self->dbusd); - self->dbusd = TP_DBUS_DAEMON (g_value_dup_object (val)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); - break; - } -} - -static void -plugin_account_manager_get_property (GObject *obj, guint prop_id, - GValue *val, GParamSpec *pspec) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (obj); - - switch (prop_id) - { - case PROP_DBUS_DAEMON: - g_value_set_object (val, self->dbusd); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); - break; - } -} - -static void -mcd_plugin_account_manager_class_init (McdPluginAccountManagerClass *cls) -{ - GObjectClass *object_class = (GObjectClass *) cls; - GParamSpec *spec = g_param_spec_object ("dbus-daemon", - "DBus daemon", - "DBus daemon", - TP_TYPE_DBUS_DAEMON, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - object_class->set_property = plugin_account_manager_set_property; - object_class->get_property = plugin_account_manager_get_property; - object_class->dispose = plugin_account_manager_dispose; - object_class->finalize = plugin_account_manager_finalize; - - g_object_class_install_property (object_class, PROP_DBUS_DAEMON, spec); -} - -McdPluginAccountManager * -mcd_plugin_account_manager_new () -{ - return g_object_new (MCD_TYPE_PLUGIN_ACCOUNT_MANAGER, - NULL); -} - -void -_mcd_plugin_account_manager_set_dbus_daemon (McdPluginAccountManager *self, - TpDBusDaemon *dbusd) -{ - GValue value = { 0 }; - - g_value_init (&value, G_TYPE_OBJECT); - g_value_take_object (&value, dbusd); - - g_object_set_property (G_OBJECT (self), "dbus-daemon", &value); -} - -static gchar * -get_value (const McpAccountManager *ma, - const gchar *account, - const gchar *key) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (ma); - return g_key_file_get_value (self->keyfile, account, key, NULL); -} - -static void -set_value (const McpAccountManager *ma, - const gchar *account, - const gchar *key, - const gchar *value) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (ma); - - if (value != NULL) - g_key_file_set_value (self->keyfile, account, key, value); - else - g_key_file_remove_key (self->keyfile, account, key, NULL); -} - -static GStrv -list_keys (const McpAccountManager *ma, - const gchar * account) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (ma); - - return g_key_file_get_keys (self->keyfile, account, NULL, NULL); -} - -static gboolean -is_secret (const McpAccountManager *ma, - const gchar *account, - const gchar *key) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (ma); - - return g_key_file_get_boolean (self->secrets, account, key, NULL); -} - -static void -make_secret (const McpAccountManager *ma, - const gchar *account, - const gchar *key) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (ma); - DEBUG ("flagging %s.%s as secret", account, key); - g_key_file_set_boolean (self->secrets, account, key, TRUE); -} - -static gchar * -unique_name (const McpAccountManager *ma, - const gchar *manager, - const gchar *protocol, - const GHashTable *params) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (ma); - const gchar *base = NULL; - gchar *esc_manager, *esc_protocol, *esc_base; - guint i; - gsize base_len = strlen (TP_ACCOUNT_OBJECT_PATH_BASE); - DBusGConnection *connection = tp_proxy_get_dbus_connection (self->dbusd); - - base = tp_asv_get_string (params, "account"); - - if (base == NULL) - base = "account"; - - esc_manager = tp_escape_as_identifier (manager); - esc_protocol = g_strdelimit (g_strdup (protocol), "-", '_'); - esc_base = tp_escape_as_identifier (base); - - for (i = 0; i < G_MAXUINT; i++) - { - gchar *path = g_strdup_printf ( - TP_ACCOUNT_OBJECT_PATH_BASE "%s/%s/%s%u", - esc_manager, esc_protocol, esc_base, i); - - if (!g_key_file_has_group (self->keyfile, path + base_len) && - dbus_g_connection_lookup_g_object (connection, path) == NULL) - { - gchar *ret = g_strdup (path + base_len); - - g_free (path); - return ret; - } - - g_free (path); - } - - return NULL; -} - -/* sort in descending order of priority (ie higher prio => earlier in list) */ -static gint -account_storage_cmp (gconstpointer a, gconstpointer b) -{ - gint pa = mcp_account_storage_priority (a); - gint pb = mcp_account_storage_priority (b); - - if (pa > pb) return -1; - if (pa < pb) return 1; - - return 0; -} - -static void -add_storage_plugin (McpAccountStorage *plugin) -{ - stores = g_list_insert_sorted (stores, plugin, account_storage_cmp); -} - -static void -add_libaccounts_plugins_if_enabled (void) -{ -#if ENABLE_LIBACCOUNTS_SSO - add_storage_plugin (MCP_ACCOUNT_STORAGE (mcd_account_manager_sso_new ())); -# ifdef ACCOUNTS_GLIB_HIDDEN_SERVICE_TYPE - add_storage_plugin (MCP_ACCOUNT_STORAGE (mcd_storage_ag_hidden_new ())); -# endif -#endif -} - -static void -sort_and_cache_plugins () -{ - const GList *p; - static gboolean plugins_cached = FALSE; - - if (plugins_cached) - return; - - /* not guaranteed to have been called, but idempotent: */ - _mcd_plugin_loader_init (); - - /* Add compiled-in plugins */ - add_storage_plugin (MCP_ACCOUNT_STORAGE (mcd_account_manager_default_new ())); - add_libaccounts_plugins_if_enabled (); - - for (p = mcp_list_objects(); p != NULL; p = g_list_next (p)) - { - if (MCP_IS_ACCOUNT_STORAGE (p->data)) - { - McpAccountStorage *plugin = g_object_ref (p->data); - - add_storage_plugin (plugin); - } - } - - for (p = stores; p != NULL; p = g_list_next (p)) - { - McpAccountStorage *plugin = p->data; - - DEBUG ("found plugin %s [%s; priority %d]\n%s", - mcp_account_storage_name (plugin), - g_type_name (G_TYPE_FROM_INSTANCE (plugin)), - mcp_account_storage_priority (plugin), - mcp_account_storage_description (plugin)); - } - - plugins_cached = TRUE; -} - -void -_mcd_plugin_account_manager_connect_signal (const gchar *signame, - GCallback func, - gpointer user_data) -{ - GList *p; - - for (p = stores; p != NULL; p = g_list_next (p)) - { - McpAccountStorage *plugin = p->data; - - DEBUG ("connecting handler to %s plugin signal %s ", - mcp_account_storage_name (plugin), signame); - g_signal_connect (plugin, signame, func, user_data); - } -} - -/* implement the McdStorage interface */ -static void -_storage_load (McdStorage *self) -{ - McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); - GList *store = NULL; - - sort_and_cache_plugins (); - - store = g_list_last (stores); - - /* fetch accounts stored in plugins, in reverse priority so higher prio * - * plugins can overwrite lower prio ones' account data */ - while (store != NULL) - { - GList *account; - McpAccountStorage *plugin = store->data; - GList *stored = mcp_account_storage_list (plugin, ma); - const gchar *pname = mcp_account_storage_name (plugin); - const gint prio = mcp_account_storage_priority (plugin); - - DEBUG ("listing from plugin %s [prio: %d]", pname, prio); - for (account = stored; account != NULL; account = g_list_next (account)) - { - gchar *name = account->data; - - DEBUG ("fetching %s from plugin %s [prio: %d]", name, pname, prio); - mcp_account_storage_get (plugin, ma, name, NULL); - - g_free (name); - } - - /* already freed the contents, just need to free the list itself */ - g_list_free (stored); - store = g_list_previous (store); - } -} - -static GStrv -_storage_dup_accounts (McdStorage *storage, gsize *n) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage); - - return g_key_file_get_groups (self->keyfile, n); -} - -static GStrv -_storage_dup_settings (McdStorage *storage, const gchar *account, gsize *n) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage); - - return g_key_file_get_keys (self->keyfile, account, n, NULL); -} - -static McpAccountStorage * -_storage_get_plugin (McdStorage *storage, const gchar *account) -{ - GList *store = stores; - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage); - McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); - McpAccountStorage *owner = NULL; - - for (; store != NULL && owner == NULL; store = g_list_next (store)) - { - McpAccountStorage *plugin = store->data; - - if (mcp_account_storage_get (plugin, ma, account, "manager")) - owner = plugin; - } - - return owner; -} - -static gchar * -_storage_dup_string (McdStorage *storage, - const gchar *account, - const gchar *key) -{ - gchar *value = NULL; - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage); - - value = g_key_file_get_string (self->keyfile, account, key, NULL); - - return value; -} - -static gboolean -_storage_has_value (McdStorage *storage, - const gchar *account, - const gchar *key) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage); - - return g_key_file_has_key (self->keyfile, account, key, NULL); -} - -static GValue * -_storage_dup_value (McdStorage *storage, - const gchar *account, - const gchar *key, - GType type, - GError **error) -{ - GValue *value = NULL; - gchar *v_string = NULL; - gint64 v_int = 0; - guint64 v_uint = 0; - gboolean v_bool = FALSE; - double v_double = 0.0; - GKeyFile *keyfile = MCD_PLUGIN_ACCOUNT_MANAGER (storage)->keyfile; - - switch (type) - { - case G_TYPE_STRING: - v_string = g_key_file_get_string (keyfile, account, key, error); - value = tp_g_value_slice_new_take_string (v_string); - break; - - case G_TYPE_INT: - v_int = g_key_file_get_integer (keyfile, account, key, error); - value = tp_g_value_slice_new_int (v_int); - break; - - case G_TYPE_INT64: - v_int = tp_g_key_file_get_int64 (keyfile, account, key, error); - value = tp_g_value_slice_new_int64 (v_int); - break; - - case G_TYPE_UINT: - v_uint = tp_g_key_file_get_uint64 (keyfile, account, key, error); - - if (v_uint > 0xFFFFFFFFU) - g_set_error (error, MCD_ACCOUNT_ERROR, - MCD_ACCOUNT_ERROR_GET_PARAMETER, - "Integer is out of range"); - else - value = tp_g_value_slice_new_uint (v_uint); - break; - - case G_TYPE_UCHAR: - v_int = g_key_file_get_integer (keyfile, account, key, error); - - if (v_int < 0 || v_int > 0xFF) - { - g_set_error (error, MCD_ACCOUNT_ERROR, - MCD_ACCOUNT_ERROR_GET_PARAMETER, - "Integer is out of range"); - } - else - { - value = tp_g_value_slice_new (G_TYPE_UCHAR); - g_value_set_uchar (value, v_int); - } - break; - - case G_TYPE_UINT64: - v_uint = tp_g_key_file_get_uint64 (keyfile, account, key, error); - value = tp_g_value_slice_new_uint64 (v_uint); - break; - - case G_TYPE_BOOLEAN: - v_bool = g_key_file_get_boolean (keyfile, account, key, error); - value = tp_g_value_slice_new_boolean (v_bool); - break; - - case G_TYPE_DOUBLE: - v_double = g_key_file_get_double (keyfile, account, key, error); - value = tp_g_value_slice_new_double (v_double); - break; - - default: - if (type == G_TYPE_STRV) - { - gchar **v = - g_key_file_get_string_list (keyfile, account, key, NULL, error); - - value = tp_g_value_slice_new_take_boxed (G_TYPE_STRV, v); - } - else if (type == DBUS_TYPE_G_OBJECT_PATH) - { - v_string = g_key_file_get_string (keyfile, account, key, NULL); - - if (v_string == NULL) - { - g_set_error (error, MCD_ACCOUNT_ERROR, - MCD_ACCOUNT_ERROR_GET_PARAMETER, - "Invalid object path NULL"); - } - else if (!tp_dbus_check_valid_object_path (v_string, NULL)) - { - g_set_error (error, MCD_ACCOUNT_ERROR, - MCD_ACCOUNT_ERROR_GET_PARAMETER, - "Invalid object path %s", v_string); - g_free (v_string); - } - else - { - value = tp_g_value_slice_new_take_object_path (v_string); - } - } - else if (type == TP_ARRAY_TYPE_OBJECT_PATH_LIST) - { - gchar **v = - g_key_file_get_string_list (keyfile, account, key, NULL, error); - gchar **iter; - GPtrArray *arr = g_ptr_array_new (); - - for (iter = v; iter != NULL && *iter != NULL; iter++) - { - if (!g_variant_is_object_path (*iter)) - { - g_set_error (error, MCD_ACCOUNT_ERROR, - MCD_ACCOUNT_ERROR_GET_PARAMETER, - "Invalid object path %s stored in account", *iter); - g_strfreev (v); - v = NULL; - break; - } - } - - for (iter = v; iter != NULL && *iter != NULL; iter++) - { - /* transfer ownership from v to arr */ - g_ptr_array_add (arr, *iter); - } - - /* not g_strfreev - the strings' ownership has been transferred */ - g_free (v); - - value = tp_g_value_slice_new_take_boxed ( - TP_ARRAY_TYPE_OBJECT_PATH_LIST, arr); - } - else - { - gchar *message = - g_strdup_printf ("cannot get property %s, unknown type %s", - key, g_type_name (type)); - - g_warning ("%s: %s", G_STRFUNC, message); - g_set_error (error, MCD_ACCOUNT_ERROR, - MCD_ACCOUNT_ERROR_GET_PARAMETER, - "%s", message); - g_free (message); - } - } - - /* This can return a non-NULL GValue * _and_ a non-NULL GError *, * - * indicating a value was not found and the default for that type * - * (eg 0 for integers) has been returned - this matches the behaviour * - * of the old code that this function replaces. If changing this, make * - * sure all our callers are suitable updated */ - - return value; -} - -static gboolean -_storage_get_boolean (McdStorage *storage, - const gchar *account, - const gchar *key) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage); - - return g_key_file_get_boolean (self->keyfile, account, key, NULL); -} - -static gint -_storage_get_integer (McdStorage *storage, - const gchar *account, - const gchar *key) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage); - - return g_key_file_get_integer (self->keyfile, account, key, NULL); -} - -static void -update_storage (McdPluginAccountManager *self, - const gchar *account, - const gchar *key) -{ - GList *store; - gboolean done = FALSE; - McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); - gchar *val = NULL; - - /* don't unescape the value here, we're flushing it to storage * - * everywhere else should handle escaping on the way in and unescaping * - * on the way out of the keyfile, but not here: */ - val = g_key_file_get_value (self->keyfile, account, key, NULL); - - /* we're deleting, which is unconditional, no need to check if anyone * - * claims this setting for themselves */ - if (val == NULL) - done = TRUE; - - for (store = stores; store != NULL; store = g_list_next (store)) - { - McpAccountStorage *plugin = store->data; - const gchar *pn = mcp_account_storage_name (plugin); - - if (done) - { - DEBUG ("MCP:%s -> delete %s.%s", pn, account, key); - mcp_account_storage_delete (plugin, ma, account, key); - } - else - { - done = mcp_account_storage_set (plugin, ma, account, key, val); - DEBUG ("MCP:%s -> %s %s.%s", - pn, done ? "store" : "ignore", account, key); - } - } - - g_free (val); -} - -static gboolean -_storage_set_string (McdStorage *storage, - const gchar *account, - const gchar *key, - const gchar *val, - gboolean secret) -{ - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage); - gboolean updated = FALSE; - gchar *old = g_key_file_get_string (self->keyfile, account, key, NULL); - - if (val == NULL) - g_key_file_remove_key (self->keyfile, account, key, NULL); - else - g_key_file_set_string (self->keyfile, account, key, val); - - if (tp_strdiff (old, val)) - { - if (secret) - { - McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); - - mcp_account_manager_parameter_make_secret (ma, account, key); - } - - update_storage (self, account, key); - updated = TRUE; - } - - g_free (old); - - return updated; -} - -static gboolean -_storage_set_value (McdStorage *storage, - const gchar *name, - const gchar *key, - const GValue *value, - gboolean secret) -{ - if (value == NULL) - { - return _storage_set_string (storage, name, key, NULL, secret); - } - else - { - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage); - gboolean updated = FALSE; - gchar *old = g_key_file_get_value (self->keyfile, name, key, NULL); - gchar *new = NULL; - gchar *buf = NULL; - - switch (G_VALUE_TYPE (value)) - { - case G_TYPE_STRING: - g_key_file_set_string (self->keyfile, name, key, - g_value_get_string (value)); - break; - - case G_TYPE_UINT: - buf = g_strdup_printf ("%u", g_value_get_uint (value)); - break; - - case G_TYPE_INT: - g_key_file_set_integer (self->keyfile, name, key, - g_value_get_int (value)); - break; - - case G_TYPE_BOOLEAN: - g_key_file_set_boolean (self->keyfile, name, key, - g_value_get_boolean (value)); - break; - - case G_TYPE_UCHAR: - buf = g_strdup_printf ("%u", g_value_get_uchar (value)); - break; - - case G_TYPE_UINT64: - buf = g_strdup_printf ("%" G_GUINT64_FORMAT, - g_value_get_uint64 (value)); - break; - - case G_TYPE_INT64: - buf = g_strdup_printf ("%" G_GINT64_FORMAT, - g_value_get_int64 (value)); - break; - - case G_TYPE_DOUBLE: - g_key_file_set_double (self->keyfile, name, key, - g_value_get_double (value)); - break; - - default: - if (G_VALUE_HOLDS (value, G_TYPE_STRV)) - { - gchar **strings = g_value_get_boxed (value); - - g_key_file_set_string_list (self->keyfile, name, key, - (const gchar **)strings, - g_strv_length (strings)); - } - else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) - { - g_key_file_set_string (self->keyfile, name, key, - g_value_get_boxed (value)); - } - else if (G_VALUE_HOLDS (value, TP_ARRAY_TYPE_OBJECT_PATH_LIST)) - { - GPtrArray *arr = g_value_get_boxed (value); - - g_key_file_set_string_list (self->keyfile, name, key, - (const gchar * const *) arr->pdata, arr->len); - } - else - { - g_warning ("Unexpected param type %s", - G_VALUE_TYPE_NAME (value)); - return FALSE; - } - } - - if (buf != NULL) - g_key_file_set_string (self->keyfile, name, key, buf); - - new = g_key_file_get_value (self->keyfile, name, key, NULL); - - if (tp_strdiff (old, new)) - { - if (secret) - { - McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); - - mcp_account_manager_parameter_make_secret (ma, name, key); - } - - update_storage (self, name, key); - updated = TRUE; - } - - g_free (new); - g_free (buf); - g_free (old); - - return updated; - } -} - -static void -_storage_delete_account (McdStorage *storage, const gchar *account) -{ - GList *store; - McdPluginAccountManager *self = MCD_PLUGIN_ACCOUNT_MANAGER (storage); - McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); - - g_key_file_remove_group (self->keyfile, account, NULL); - - for (store = stores; store != NULL; store = g_list_next (store)) - { - McpAccountStorage *plugin = store->data; - - mcp_account_storage_delete (plugin, ma, account, NULL); - } -} - -static void -_storage_commit (McdStorage *self, const gchar *account) -{ - GList *store; - McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); - - for (store = stores; store != NULL; store = g_list_next (store)) - { - McpAccountStorage *plugin = store->data; - const gchar *pname = mcp_account_storage_name (plugin); - - if (account != NULL) - { - DEBUG ("flushing plugin %s %s to long term storage", pname, account); - mcp_account_storage_commit_one (plugin, ma, account); - } - else - { - DEBUG ("flushing plugin %s to long term storage", pname); - mcp_account_storage_commit (plugin, ma); - } - } -} - -void -_mcd_plugin_account_manager_ready (McdPluginAccountManager *self) -{ - GList *store; - McpAccountManager *ma = MCP_ACCOUNT_MANAGER (self); - - for (store = stores; store != NULL; store = g_list_next (store)) - { - McpAccountStorage *plugin = store->data; - const gchar *plugin_name = mcp_account_storage_name (plugin); - - DEBUG ("Unblocking async account ops by %s", plugin_name); - mcp_account_storage_ready (plugin, ma); - } -} - -static void -storage_iface_init (McdStorageIface *iface, - gpointer unused G_GNUC_UNUSED) -{ - iface->load = _storage_load; - iface->dup_accounts = _storage_dup_accounts; - iface->dup_settings = _storage_dup_settings; - - iface->delete_account = _storage_delete_account; - iface->set_string = _storage_set_string; - iface->set_value = _storage_set_value; - iface->commit = _storage_commit; - - iface->has_value = _storage_has_value; - iface->get_storage_plugin = _storage_get_plugin; - iface->dup_value = _storage_dup_value; - iface->dup_string = _storage_dup_string; - iface->get_integer = _storage_get_integer; - iface->get_boolean = _storage_get_boolean; -} - -static void -plugin_iface_init (McpAccountManagerIface *iface, - gpointer unused G_GNUC_UNUSED) -{ - DEBUG (); - - iface->get_value = get_value; - iface->set_value = set_value; - iface->is_secret = is_secret; - iface->make_secret = make_secret; - iface->unique_name = unique_name; - iface->list_keys = list_keys; -} diff --git a/src/plugin-account.h b/src/plugin-account.h deleted file mode 100644 index 27fb731e..00000000 --- a/src/plugin-account.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Representation of the account manager as presented to plugins. This is - * deliberately a "smaller" API than McdAccountManager. - * - * Copyright © 2010 Nokia Corporation - * Copyright © 2010 Collabora Ltd. - * - * 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 St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef MCD_PLUGIN_ACCOUNT_MANAGER_H -#define MCD_PLUGIN_ACCOUNT_MANAGER_H - -#include <mission-control-plugins/mission-control-plugins.h> - -#include "mcd-account-manager.h" - -G_BEGIN_DECLS - -typedef struct { - GObject parent; - TpDBusDaemon *dbusd; - GKeyFile *keyfile; - GKeyFile *secrets; -} McdPluginAccountManager; - -typedef struct _McdPluginAccountManagerClass McdPluginAccountManagerClass; -typedef struct _McdPluginAccountManagerPrivate McdPluginAccountManagerPrivate; - -G_GNUC_INTERNAL GType mcd_plugin_account_manager_get_type (void); - -#define MCD_TYPE_PLUGIN_ACCOUNT_MANAGER (mcd_plugin_account_manager_get_type ()) - -#define MCD_PLUGIN_ACCOUNT_MANAGER(o) \ - (G_TYPE_CHECK_INSTANCE_CAST ((o), MCD_TYPE_PLUGIN_ACCOUNT_MANAGER, \ - McdPluginAccountManager)) - -#define MCD_PLUGIN_ACCOUNT_MANAGER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), MCD_TYPE_PLUGIN_ACCOUNT_MANAGER, \ - McdPluginAccountManagerClass)) - -#define MCD_IS_PLUGIN_ACCOUNT_MANAGER(o) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((o), MCD_TYPE_PLUGIN_ACCOUNT_MANAGER)) - -#define MCD_IS_PLUGIN_ACCOUNT_MANAGER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), MCD_TYPE_PLUGIN_ACCOUNT_MANAGER)) - -#define MCD_PLUGIN_ACCOUNT_MANAGER_GET_CLASS(o) \ - (G_TYPE_INSTANCE_GET_CLASS ((o), MCD_TYPE_PLUGIN_ACCOUNT_MANAGER, \ - McdPluginAccountManagerClass)) - -McdPluginAccountManager *mcd_plugin_account_manager_new (void); - -G_GNUC_INTERNAL -void _mcd_plugin_account_manager_set_dbus_daemon (McdPluginAccountManager *self, - TpDBusDaemon *dbusd); - -G_GNUC_INTERNAL -void _mcd_plugin_account_manager_ready (McdPluginAccountManager *self); - -G_GNUC_INTERNAL -void _mcd_plugin_account_manager_connect_signal (const gchar *signal, - GCallback func, - gpointer user_data); - -G_END_DECLS - -#endif diff --git a/src/plugin-dispatch-operation.c b/src/plugin-dispatch-operation.c index 99d532d4..0281dbfc 100644 --- a/src/plugin-dispatch-operation.c +++ b/src/plugin-dispatch-operation.c @@ -21,6 +21,8 @@ * */ +#include "config.h" + #include "plugin-dispatch-operation.h" #include "mission-control-plugins/implementation.h" @@ -176,9 +178,11 @@ plugin_do_get_n_channels (McpDispatchOperation *obj) McdPluginDispatchOperation *self = MCD_PLUGIN_DISPATCH_OPERATION (obj); g_return_val_if_fail (self != NULL, 0); - /* FIXME: O(n) */ - return g_list_length ((GList *) _mcd_dispatch_operation_peek_channels ( - self->real_cdo)); + + if (_mcd_dispatch_operation_peek_channel (self->real_cdo) != NULL) + return 1; + + return 0; } static const gchar * @@ -189,11 +193,10 @@ plugin_do_get_nth_channel_path (McpDispatchOperation *obj, McdChannel *channel; g_return_val_if_fail (self != NULL, NULL); - /* FIXME: O(n) */ - channel = g_list_nth_data ((GList *) _mcd_dispatch_operation_peek_channels ( - self->real_cdo), n); - if (channel == NULL) + channel = _mcd_dispatch_operation_peek_channel (self->real_cdo); + + if (channel == NULL || n != 0) return NULL; return mcd_channel_get_object_path (channel); @@ -208,11 +211,10 @@ plugin_do_ref_nth_channel_properties (McpDispatchOperation *obj, GHashTable *ret; g_return_val_if_fail (self != NULL, NULL); - /* FIXME: O(n) */ - channel = g_list_nth_data ((GList *) _mcd_dispatch_operation_peek_channels ( - self->real_cdo), n); - if (channel == NULL) + channel = _mcd_dispatch_operation_peek_channel (self->real_cdo); + + if (channel == NULL || n != 0) return NULL; ret = _mcd_channel_get_immutable_properties (channel); diff --git a/src/plugin-request.c b/src/plugin-request.c index b0a4b725..a4c3f033 100644 --- a/src/plugin-request.c +++ b/src/plugin-request.c @@ -21,6 +21,8 @@ * */ +#include "config.h" + #include "plugin-request.h" #include <telepathy-glib/telepathy-glib.h> diff --git a/src/request.c b/src/request.c index e2633bb8..8ee8e5a5 100644 --- a/src/request.c +++ b/src/request.c @@ -20,15 +20,13 @@ * */ +#include "config.h" + #include "request.h" #include <dbus/dbus-glib.h> -#include <telepathy-glib/dbus-properties-mixin.h> -#include <telepathy-glib/gtypes.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/svc-channel-request.h> -#include <telepathy-glib/svc-generic.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #include "mcd-account-priv.h" #include "mcd-connection-priv.h" @@ -690,7 +688,7 @@ _mcd_request_proceed (McdRequest *self, if (self->proceeding) { - GError na = { TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + GError na = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Proceed has already been called; stop calling it" }; if (context != NULL) @@ -955,7 +953,7 @@ _mcd_request_cancel (McdRequest *self, } else { - g_set_error (error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, + g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "ChannelRequest is no longer cancellable"); return FALSE; } diff --git a/src/request.h b/src/request.h index 5456b375..f0c0bc41 100644 --- a/src/request.h +++ b/src/request.h @@ -23,7 +23,7 @@ #ifndef MCD_REQUEST_H #define MCD_REQUEST_H -#include <telepathy-glib/client.h> +#include <telepathy-glib/telepathy-glib.h> #include "client-registry.h" #include "mcd-account.h" diff --git a/tests/account-store-default.c b/tests/account-store-default.c index bd33ff3d..944bf2f7 100644 --- a/tests/account-store-default.c +++ b/tests/account-store-default.c @@ -73,6 +73,11 @@ _get_secret_from_keyring (const gchar *account, const gchar *key) GList *i; gchar *secret = NULL; + /* for compatibility with old gnome keyring code we must strip * + * the param- prefix from the name before loading from the keyring */ + if (g_str_has_prefix (key, "param-")) + key += strlen ("param-"); + gnome_keyring_attribute_list_append_string (match, "account", account); ok = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET, @@ -233,16 +238,18 @@ default_set (const gchar *account, GKeyFile *keyfile = NULL; #if ENABLE_GNOME_KEYRING - if (g_str_equal (key, "param-password")) + /* we want to catch, for instance, param-password or param-proxy-password */ + if (g_str_has_prefix (key, "param-") && g_str_has_suffix (key, "-password")) { GnomeKeyringResult result = GNOME_KEYRING_RESULT_CANCELLED; gchar *name = - g_strdup_printf ("account: %s; param: %s", account, "password"); + g_strdup_printf ("account: %s; param: %s", account, + key + strlen ("param-")); result = gnome_keyring_store_password_sync (&keyring_schema, NULL, name, value, "account", account, - "param", "password", + "param", key + strlen ("param-"), NULL); g_free (name); @@ -283,3 +290,30 @@ default_list (void) { return g_key_file_get_groups (default_keyfile (), NULL); } + +guint +default_count_passwords (void) +{ +#if ENABLE_GNOME_KEYRING + GnomeKeyringResult ok = GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON; + GnomeKeyringAttributeList *match = gnome_keyring_attribute_list_new (); + GList *items = NULL; + guint n = 0; + + ok = gnome_keyring_find_items_sync (GNOME_KEYRING_ITEM_GENERIC_SECRET, + match, &items); + + if (ok != GNOME_KEYRING_RESULT_OK) + goto finished; + + n = g_list_length (items); + gnome_keyring_found_list_free (items); + + finished: + gnome_keyring_attribute_list_free (match); + + return n; +#else + return 0; +#endif +} diff --git a/tests/account-store-default.h b/tests/account-store-default.h index 739f95cc..2436e932 100644 --- a/tests/account-store-default.h +++ b/tests/account-store-default.h @@ -38,4 +38,6 @@ gboolean default_exists (const gchar *account); GStrv default_list (void); +guint default_count_passwords (void); + #endif diff --git a/tests/account-store-libaccounts.c b/tests/account-store-libaccounts.c index 11c24006..e2756969 100644 --- a/tests/account-store-libaccounts.c +++ b/tests/account-store-libaccounts.c @@ -19,11 +19,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <string.h> +#include "account-store-libaccounts.h" + #include <libaccounts-glib/ag-manager.h> #include <libaccounts-glib/ag-account.h> -#include <glib.h> -#include "account-store-libaccounts.h" +#include <libaccounts-glib/ag-service.h> + +#include <string.h> #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "account-store-libaccounts" @@ -248,7 +250,7 @@ get_ag_account (const gchar *mc_account) if (account != NULL) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; AgSettingSource source = AG_SETTING_SOURCE_NONE; g_value_init (&value, G_TYPE_STRING); @@ -368,7 +370,7 @@ save_setting (AgAccount *account, if (val != NULL) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; g_value_init (&value, G_TYPE_STRING); g_value_set_string (&value, val); @@ -414,7 +416,7 @@ libaccounts_get (const gchar *mc_account, const gchar *key) } else { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; AgSettingSource source = AG_SETTING_SOURCE_NONE; g_value_init (&value, G_TYPE_STRING); @@ -565,7 +567,7 @@ libaccounts_list (void) for (id = ag_ids; id && i < len; id = g_list_next (id)) { - GValue value = { 0 }; + GValue value = G_VALUE_INIT; AgAccountId uid = GPOINTER_TO_UINT (id->data); AgAccount *ag_account = ag_manager_get_account (ag_manager, uid); AgSettingSource source = AG_SETTING_SOURCE_NONE; @@ -587,9 +589,9 @@ libaccounts_list (void) } else { - GValue cmanager = { 0 }; - GValue protocol = { 0 }; - GValue account = { 0 }; + GValue cmanager = G_VALUE_INIT; + GValue protocol = G_VALUE_INIT; + GValue account = G_VALUE_INIT; const gchar *acct = NULL; const gchar *cman = NULL; const gchar *proto = NULL; diff --git a/tests/account-store-libaccounts.h b/tests/account-store-libaccounts.h index cb2352b1..8e88f696 100644 --- a/tests/account-store-libaccounts.h +++ b/tests/account-store-libaccounts.h @@ -19,9 +19,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include <glib-object.h> + #ifndef _ACCOUNT_STORE_LIBACCOUNTS_H_ #define _ACCOUNT_STORE_LIBACCOUNTS_H_ +G_BEGIN_DECLS + gchar * libaccounts_get (const gchar *mc_account, const gchar *key); @@ -35,4 +39,6 @@ gboolean libaccounts_exists (const gchar *mc_account); GStrv libaccounts_list (void); +G_END_DECLS + #endif diff --git a/tests/account-store.c b/tests/account-store.c index 5483527a..7e609a1c 100644 --- a/tests/account-store.c +++ b/tests/account-store.c @@ -51,6 +51,7 @@ typedef struct { gboolean (*delete) (const gchar *account); gboolean (*exists) (const gchar *account); GStrv (*list) (void); + guint (*count_passwords) (void); } Backend; typedef enum { @@ -60,6 +61,7 @@ typedef enum { OP_DELETE, OP_EXISTS, OP_LIST, + OP_COUNT_PASSWORDS } Operation; const Backend backends[] = { @@ -68,7 +70,8 @@ const Backend backends[] = { default_set, default_delete, default_exists, - default_list, }, + default_list, + default_count_passwords }, #if ENABLE_LIBACCOUNTS_SSO { "libaccounts", @@ -76,7 +79,8 @@ const Backend backends[] = { libaccounts_set, libaccounts_delete, libaccounts_exists, - libaccounts_list, }, + libaccounts_list, + NULL }, #endif { NULL } @@ -164,6 +168,8 @@ int main (int argc, char **argv) op = OP_EXISTS; else if (g_str_equal (op_name, "list")) op = OP_LIST; + else if (g_str_equal (op_name, "count-passwords")) + op = OP_COUNT_PASSWORDS; switch (op) { @@ -202,6 +208,11 @@ int main (int argc, char **argv) usage (argv[0], "op '%s' requires an backend", op_name); break; + case OP_COUNT_PASSWORDS: + if (argc < 3) + usage (argv[0], "op '%s' requires an backend", op_name); + break; + case OP_UNKNOWN: usage (argv[0], "Unknown operation: %s", op_name); } @@ -239,6 +250,19 @@ int main (int argc, char **argv) g_strfreev (list); break; + case OP_COUNT_PASSWORDS: + if (store->count_passwords == NULL) + { + g_printerr ("Password-counting is unimplemented\n"); + } + else + { + guint n = store->count_passwords (); + output = g_strdup_printf ("%u", n); + success = TRUE; + } + break; + default: output = g_strdup ("Unknown operation"); } diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am index 642e9814..8cb78774 100644 --- a/tests/twisted/Makefile.am +++ b/tests/twisted/Makefile.am @@ -23,7 +23,6 @@ TWISTED_BASIC_TESTS = \ account-requests/delete-account-during-request.py \ account/addressing.py \ capabilities/contact-caps.py \ - capabilities/legacy-caps.py \ dispatcher/already-has-channel.py \ dispatcher/already-has-obsolete.py \ dispatcher/approver-fails.py \ @@ -66,20 +65,12 @@ TWISTED_BASIC_TESTS = \ dispatcher/vanishing-client.py \ $(NULL) -if ENABLE_MCD_PLUGINS -TWISTED_BASIC_TESTS += \ - dispatcher/create-delayed-by-plugin.py \ - dispatcher/dispatch-delayed-by-plugin.py \ - dispatcher/dispatch-rejected-by-plugin.py -endif - # Tests that aren't to be run if we're running the real (installed) MC, # because they rely on special behaviour of mc-debug-server. # # For simplicity, these are also separate tests: at least # account-storage/*.py need their own instances. TWISTED_SPECIAL_BUILD_TESTS = \ - account-manager/auto-away.py \ account-manager/connectivity.py \ account-manager/hidden.py \ account-storage/default-keyring-storage.py \ @@ -184,17 +175,11 @@ testplugindir = @mctestsdir@/twisted/plugins testplugin_LTLIBRARIES = \ $(plugins_list) \ $(NULL) -if ENABLE_MCD_PLUGINS -testplugin_LTLIBRARIES += test-plugin.la -endif else # A demo dispatcher plugin (new, minimal API) noinst_LTLIBRARIES = $(plugins_list) -if ENABLE_MCD_PLUGINS -noinst_LTLIBRARIES += test-plugin.la -endif endif @@ -210,18 +195,11 @@ mcp_account_diversion_la_LDFLAGS = $(mcp_plugin_la_LDFLAGS) mcp_dbus_caller_permission_la_SOURCES = mcp-dbus-caller-permission.c mcp_dbus_caller_permission_la_LDFLAGS = $(mcp_plugin_la_LDFLAGS) -if ENABLE_MCD_PLUGINS -# A demo dispatcher plugin (old API, with access to MCD internals) -test_plugin_la_SOURCES = test-plugin.c -test_plugin_la_LDFLAGS = -module -shared -avoid-version -rpath @abs_builddir@ -endif - # A debug version of the normal MC executable, which exits cleanly on # disconnection from D-Bus (so gcov info gets written out) noinst_PROGRAMS = mc-debug-server mc_debug_server_SOURCES = mc-debug-server.c mc_debug_server_LDADD = \ - $(top_builddir)/src/libmissioncontrol-server.la \ $(top_builddir)/src/libmcd-convenience.la INCLUDES = \ @@ -282,16 +260,12 @@ SEPARATE_TESTS_ENVIRONMENT = \ if WANT_TWISTED_TESTS check-local: check-twisted -if HAVE_SERVER - installcheck-local: installcheck-twisted installcheck-twisted: $(MAKE) check-twisted \ TWISTED_SPECIAL_BUILD_TESTS= \ MC_EXECUTABLE=@libexecdir@/mission-control-5 -endif # HAVE_SERVER - endif # WANT_TWISTED_TESTS check-twisted: diff --git a/tests/twisted/account-manager/account-basics.py b/tests/twisted/account-manager/account-basics.py index aceb7aed..ec21a51e 100644 --- a/tests/twisted/account-manager/account-basics.py +++ b/tests/twisted/account-manager/account-basics.py @@ -44,9 +44,6 @@ def test(q, bus, mc): properties.get('InvalidAccounts') interfaces = properties.get('Interfaces') - # assert that current functionality exists - assert cs.AM_IFACE_NOKIA_QUERY in interfaces, interfaces - params = dbus.Dictionary({"account": "someguy@example.com", "password": "secrecy"}, signature='sv') (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) @@ -86,7 +83,6 @@ def test(q, bus, mc): interfaces = properties.get('Interfaces') assert cs.ACCOUNT_IFACE_AVATAR in interfaces, interfaces - assert cs.ACCOUNT_IFACE_NOKIA_COMPAT in interfaces, interfaces assert cs.ACCOUNT_IFACE_NOKIA_CONDITIONS in interfaces, interfaces # sanity check @@ -130,28 +126,6 @@ def test(q, bus, mc): ) assert account_props.Get(cs.ACCOUNT, 'Nickname') == 'Joe Bloggs' - call_async(q, dbus.Interface(account, cs.ACCOUNT_IFACE_NOKIA_COMPAT), - 'SetHasBeenOnline') - q.expect_many( - EventPattern('dbus-signal', - path=account_path, - signal='AccountPropertyChanged', - interface=cs.ACCOUNT, - args=[{'HasBeenOnline': True}]), - EventPattern('dbus-return', method='SetHasBeenOnline'), - ) - assert account_props.Get(cs.ACCOUNT, 'HasBeenOnline') == True - - call_async(q, account_props, 'Set', cs.ACCOUNT_IFACE_NOKIA_COMPAT, - 'SecondaryVCardFields', - ['x-badger', 'x-mushroom']) - # there's no change notification for the Compat properties - q.expect_many( - EventPattern('dbus-return', method='Set'), - ) - assert account_props.Get(cs.ACCOUNT_IFACE_NOKIA_COMPAT, - 'SecondaryVCardFields') == ['x-badger', 'x-mushroom'] - call_async(q, account_props, 'Set', cs.ACCOUNT_IFACE_NOKIA_CONDITIONS, 'Condition', dbus.Dictionary({':foo': 'bar'}, signature='ss')) @@ -206,15 +180,6 @@ def test(q, bus, mc): else: raise AssertionError('Setting %s with wrong type should fail' % p) - for p in ('SecondaryVCardFields'): - try: - account_props.Set(cs.ACCOUNT_IFACE_NOKIA_COMPAT, p, badly_typed) - except dbus.DBusException, e: - assert e.get_dbus_name() == cs.INVALID_ARGUMENT, \ - (p, e.get_dbus_name()) - else: - raise AssertionError('Setting %s with wrong type should fail' % p) - for p in ('Condition',): try: account_props.Set(cs.ACCOUNT_IFACE_NOKIA_CONDITIONS, p, @@ -233,8 +198,6 @@ def test(q, bus, mc): assert properties['Icon'] == 'im-jabber' properties = account_props.GetAll(cs.ACCOUNT_IFACE_AVATAR) assert properties['Avatar'] == ([], '') - properties = account_props.GetAll(cs.ACCOUNT_IFACE_NOKIA_COMPAT) - assert properties['SecondaryVCardFields'] == ['x-badger', 'x-mushroom'] # Delete the account assert account_iface.Remove() is None diff --git a/tests/twisted/account-manager/auto-away.py b/tests/twisted/account-manager/auto-away.py deleted file mode 100644 index 6d2fc81b..00000000 --- a/tests/twisted/account-manager/auto-away.py +++ /dev/null @@ -1,208 +0,0 @@ -# Copyright (C) 2009 Nokia Corporation -# Copyright (C) 2009 Collabora Ltd. -# -# 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 St, Fifth Floor, Boston, MA -# 02110-1301 USA - -import dbus -import dbus.service - -from servicetest import EventPattern, tp_name_prefix, tp_path_prefix -from mctest import exec_test, SimulatedConnection, create_fakecm_account,\ - SimulatedChannel -import constants as cs - -def test(q, bus, mc): - cm_name_ref = dbus.service.BusName( - tp_name_prefix + '.ConnectionManager.fakecm', bus=bus) - - # Create an account - params = dbus.Dictionary({"account": "someguy@example.com", - "password": "secrecy"}, signature='sv') - (cm_name_ref, account) = create_fakecm_account(q, bus, mc, params) - - # The account is initially valid but disabled - assert not account.Get(cs.ACCOUNT, 'Enabled', - dbus_interface=cs.PROPERTIES_IFACE) - assert account.Get(cs.ACCOUNT, 'Valid', - dbus_interface=cs.PROPERTIES_IFACE) - - # Enable the account - account.Set(cs.ACCOUNT, 'Enabled', True, - dbus_interface=cs.PROPERTIES_IFACE) - q.expect('dbus-signal', - path=account.object_path, - signal='AccountPropertyChanged', - interface=cs.ACCOUNT) - - assert account.Get(cs.ACCOUNT, 'Enabled', - dbus_interface=cs.PROPERTIES_IFACE) - assert account.Get(cs.ACCOUNT, 'Valid', - dbus_interface=cs.PROPERTIES_IFACE) - - # Check the requested presence is offline - properties = account.GetAll(cs.ACCOUNT, - dbus_interface=cs.PROPERTIES_IFACE) - assert properties is not None - assert properties.get('RequestedPresence') == \ - dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE), - 'offline', '')), \ - properties.get('RequestedPresence') - - # Go online - requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_AVAILABLE), - dbus.String(u'available'), dbus.String(u'staring at the sea'))) - account.Set(cs.ACCOUNT, - 'RequestedPresence', requested_presence, - dbus_interface=cs.PROPERTIES_IFACE) - - e = q.expect('dbus-method-call', method='RequestConnection', - args=['fakeprotocol', params], - destination=tp_name_prefix + '.ConnectionManager.fakecm', - path=tp_path_prefix + '/ConnectionManager/fakecm', - interface=tp_name_prefix + '.ConnectionManager', - handled=False) - - conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', '_', - 'myself', has_presence=True) - conn.statuses = dbus.Dictionary({ - 'available': (cs.PRESENCE_TYPE_AVAILABLE, True, True), - 'away': (cs.PRESENCE_TYPE_AWAY, True, True), - 'busy': (cs.PRESENCE_TYPE_BUSY, True, True), - 'offline': (cs.PRESENCE_TYPE_OFFLINE, False, False), - }, signature='s(ubb)') - - q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so') - - # MC calls GetStatus (maybe) and then Connect - - q.expect('dbus-method-call', method='Connect', - path=conn.object_path, handled=True) - - # Connect succeeds - conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE) - conn.presence = dbus.Struct((cs.PRESENCE_TYPE_AVAILABLE, 'available', ''), - signature='uss') - - # MC does some setup, including fetching the list of Channels - - get_statuses = q.expect('dbus-method-call', - interface=cs.PROPERTIES_IFACE, method='Get', - args=[cs.CONN_IFACE_SIMPLE_PRESENCE, 'Statuses'], - path=conn.object_path, handled=True) - - call, signal = q.expect_many( - EventPattern('dbus-method-call', - path=conn.object_path, - interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence', - args=['available', 'staring at the sea'], - handled=True), - EventPattern('dbus-signal', - path=account.object_path, - interface=cs.ACCOUNT, signal='AccountPropertyChanged', - predicate = lambda e: 'CurrentPresence' in e.args[0]), - ) - assert signal.args[0]['CurrentPresence'] == (cs.PRESENCE_TYPE_AVAILABLE, - 'available', '') - - e = q.expect('dbus-signal', - path=account.object_path, - interface=cs.ACCOUNT, signal='AccountPropertyChanged', - predicate = lambda e: 'CurrentPresence' in e.args[0]) - assert e.args[0]['CurrentPresence'] == requested_presence - - # Check the requested presence is online - properties = account.GetAll(cs.ACCOUNT, - dbus_interface=cs.PROPERTIES_IFACE) - assert properties is not None - assert properties.get('RequestedPresence') == requested_presence, \ - properties.get('RequestedPresence') - - # This is normally a C API, only exposed to D-Bus here for testing - secret_debug_api = dbus.Interface(bus.get_object(cs.AM, "/"), - 'org.freedesktop.Telepathy.MissionControl5.RegressionTests') - MCD_SYSTEM_IDLE = 32 - - # Set the idle flag - secret_debug_api.ChangeSystemFlags(dbus.UInt32(MCD_SYSTEM_IDLE), - dbus.UInt32(0)) - - e = q.expect('dbus-method-call', - path=conn.object_path, - interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence', - args=['away', ''], - handled=True) - - # Unset the idle flag - secret_debug_api.ChangeSystemFlags(dbus.UInt32(0), - dbus.UInt32(MCD_SYSTEM_IDLE)) - - # MC puts the account back online - - e = q.expect('dbus-method-call', - path=conn.object_path, - interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence', - args=['available', 'staring at the sea'], - handled=True) - - # Go to a non-Available status - requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_BUSY), - dbus.String(u'busy'), dbus.String(u'in the great below'))) - account.Set(cs.ACCOUNT, - 'RequestedPresence', requested_presence, - dbus_interface=cs.PROPERTIES_IFACE) - e = q.expect('dbus-method-call', - path=conn.object_path, - interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence', - args=['busy', 'in the great below'], - handled=True) - - forbidden = [EventPattern('dbus-method-call', - path=conn.object_path, - interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence')] - q.forbid_events(forbidden) - - # Set the idle flag - secret_debug_api.ChangeSystemFlags(dbus.UInt32(MCD_SYSTEM_IDLE), - dbus.UInt32(0)) - - # MC does not put the account away - - # Unset the idle flag - secret_debug_api.ChangeSystemFlags(dbus.UInt32(0), - dbus.UInt32(MCD_SYSTEM_IDLE)) - - # MC does not put the account back online - - q.unforbid_events(forbidden) - - # Put the account offline - requested_presence = (dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE), 'offline', '') - account.Set(cs.ACCOUNT, - 'RequestedPresence', requested_presence, - dbus_interface=cs.PROPERTIES_IFACE) - - # In response, MC tells us to Disconnect, and we do - q.expect('dbus-method-call', method='Disconnect', - path=conn.object_path, handled=True) - - properties = account.GetAll(cs.ACCOUNT, dbus_interface=cs.PROPERTIES_IFACE) - assert properties['Connection'] == '/' - assert properties['ConnectionStatus'] == cs.CONN_STATUS_DISCONNECTED - assert properties['CurrentPresence'] == requested_presence - assert properties['RequestedPresence'] == requested_presence - -if __name__ == '__main__': - exec_test(test, {}) diff --git a/tests/twisted/account-manager/create-with-properties.py b/tests/twisted/account-manager/create-with-properties.py index ca3b50d2..f4a69828 100644 --- a/tests/twisted/account-manager/create-with-properties.py +++ b/tests/twisted/account-manager/create-with-properties.py @@ -39,16 +39,12 @@ def test(q, bus, mc): interfaces = properties.get('Interfaces') supported = properties.get('SupportedAccountProperties') - # assert that current functionality exists - assert cs.AM_IFACE_NOKIA_QUERY in interfaces, interfaces - assert (cs.ACCOUNT + '.AutomaticPresence') in supported assert (cs.ACCOUNT + '.Enabled') in supported assert (cs.ACCOUNT + '.Icon') in supported assert (cs.ACCOUNT + '.Nickname') in supported assert (cs.ACCOUNT + '.ConnectAutomatically') in supported assert (cs.ACCOUNT_IFACE_AVATAR + '.Avatar') in supported - assert (cs.ACCOUNT_IFACE_NOKIA_COMPAT + '.SecondaryVCardFields') in supported assert (cs.ACCOUNT_IFACE_NOKIA_CONDITIONS + '.Condition') in supported assert (cs.ACCOUNT + '.RequestedPresence') in supported @@ -73,8 +69,6 @@ def test(q, bus, mc): cs.ACCOUNT + '.ConnectAutomatically': True, cs.ACCOUNT_IFACE_AVATAR + '.Avatar': (dbus.ByteArray('foo'), 'image/jpeg'), - cs.ACCOUNT_IFACE_NOKIA_COMPAT + '.SecondaryVCardFields': - dbus.Array(['x-ioquake3', 'x-quake3'], signature='s'), cs.ACCOUNT_IFACE_NOKIA_CONDITIONS + '.Condition': dbus.Dictionary({ 'has-quad-damage': ':y' }, signature='ss'), cs.ACCOUNT + '.Supersedes': dbus.Array([ @@ -138,10 +132,6 @@ def test(q, bus, mc): assert properties.get('Avatar') == ([ord('f'), ord('o'), ord('o')], 'image/jpeg') - properties = account_props.GetAll(cs.ACCOUNT_IFACE_NOKIA_COMPAT) - assert sorted(properties.get('SecondaryVCardFields')) == \ - ['x-ioquake3', 'x-quake3'] - properties = account_props.GetAll(cs.ACCOUNT_IFACE_NOKIA_CONDITIONS) assert properties.get('Condition') == { 'has-quad-damage': ':y', diff --git a/tests/twisted/account-storage/default-keyring-storage.py b/tests/twisted/account-storage/default-keyring-storage.py index df478eca..bab0b726 100644 --- a/tests/twisted/account-storage/default-keyring-storage.py +++ b/tests/twisted/account-storage/default-keyring-storage.py @@ -25,7 +25,7 @@ import dbus import dbus.service from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ - call_async + call_async, assertEquals from mctest import ( exec_test, create_fakecm_account, get_fakecm_account, connect_to_mc, keyfile_read, tell_mc_to_die, resuscitate_mc @@ -55,9 +55,11 @@ def remove_keyring(name): os.system('../keyring-command remove ' + name) -def account_store(op, backend, key=None, value=None): - cmd = [ '../account-store', op, backend, - 'fakecm/fakeprotocol/dontdivert_40example_2ecom0' ] +# This doesn't escape its parameters before passing them to the shell, +# so be careful. +def account_store(op, backend, key=None, value=None, + account='fakecm/fakeprotocol/dontdivert_40example_2ecom0'): + cmd = [ '../account-store', op, backend, account ] if key: cmd.append(key) if value: @@ -149,16 +151,12 @@ def test(q, bus, mc): account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) - nokia_compat = dbus.Interface(account, cs.ACCOUNT_IFACE_NOKIA_COMPAT) # Alter some miscellaneous r/w properties account_props.Set(cs.ACCOUNT, 'DisplayName', 'Work account') account_props.Set(cs.ACCOUNT, 'Icon', 'im-jabber') account_props.Set(cs.ACCOUNT, 'Nickname', 'Joe Bloggs') - nokia_compat.SetHasBeenOnline() - account_props.Set(cs.ACCOUNT_IFACE_NOKIA_COMPAT, - 'SecondaryVCardFields', ['x-badger', 'x-mushroom']) tell_mc_to_die(q, bus) @@ -171,15 +169,13 @@ def test(q, bus, mc): assert kf[group]['DisplayName'] == 'Work account', kf assert kf[group]['Icon'] == 'im-jabber', kf assert kf[group]['Nickname'] == 'Joe Bloggs', kf - assert kf[group]['HasBeenOnline'] == 'true', kf - assert kf[group]['SecondaryVCardFields'] == 'x-badger;x-mushroom;', kf # This works wherever the password is stored pwd = account_store('get', 'default', 'param-password') assert pwd == params['password'], pwd # If we're using GNOME keyring, the password should not be in the - # password file + # keyfile if use_keyring: assert 'param-password' not in kf[group] else: @@ -211,6 +207,62 @@ def test(q, bus, mc): kf = keyfile_read(key_file_name) assert group not in kf, kf + if use_keyring: + # the password has been deleted from the keyring too + pwd = account_store('get', 'default', 'param-password') + assertEquals(None, pwd) + + # Tell MC to die, again + tell_mc_to_die(q, bus) + + # Write out account configurations in which the password is in + # both the keyfile and the keyring + + account_store('set', 'default', 'param-password', 'password_in_keyring') + open(ctl_dir + '/accounts.cfg', 'w').write( +r"""# Telepathy accounts +[%s] +manager=fakecm +protocol=fakeprotocol +param-account=dontdivert@example.com +param-password=password_in_keyfile +DisplayName=New and improved account +""" % group) + + account_manager, properties, interfaces = resuscitate_mc(q, bus, mc) + account = get_fakecm_account(bus, mc, account_path) + account_iface = dbus.Interface(account, cs.ACCOUNT) + + pwd = account_store('get', 'default', 'param-password') + if use_keyring: + assertEquals('password_in_keyring', pwd) + else: + # it was overwritten when we edited the keyfile + assertEquals('password_in_keyfile', pwd) + + # Delete the password (only), like Empathy 3.0-3.4 do when migrating + account_iface.UpdateParameters({}, ['password']) + q.expect('dbus-signal', + path=account_path, + signal='AccountPropertyChanged', + interface=cs.ACCOUNT, + predicate=(lambda e: + 'Parameters' in e.args[0]), + ) + + # Tell MC to die yet again + tell_mc_to_die(q, bus) + + # Check the password is correctly deleted + kf = keyfile_read(key_file_name) + assert 'param-password' not in kf[group] + pwd = account_store('get', 'default', 'param-password') + assertEquals(None, pwd) + pwd = account_store('count-passwords', 'default') + assertEquals('0', pwd) + + # Put it back, just so deleting all accounts won't raise errors + account_manager, properties, interfaces = resuscitate_mc(q, bus, mc) if __name__ == '__main__': ctl_dir = os.environ['MC_ACCOUNT_DIR'] diff --git a/tests/twisted/account-storage/diverted-storage.py b/tests/twisted/account-storage/diverted-storage.py index 37208801..d645656e 100644 --- a/tests/twisted/account-storage/diverted-storage.py +++ b/tests/twisted/account-storage/diverted-storage.py @@ -61,13 +61,9 @@ def test(q, bus, mc): account_iface = dbus.Interface(account, cs.ACCOUNT) account_props = dbus.Interface(account, cs.PROPERTIES_IFACE) - nokia_compat = dbus.Interface(account, cs.ACCOUNT_IFACE_NOKIA_COMPAT) # Alter some miscellaneous r/w properties - nokia_compat.SetHasBeenOnline() - account_props.Set(cs.ACCOUNT_IFACE_NOKIA_COMPAT, - 'SecondaryVCardFields', ['x-badger', 'x-mushroom']) account_props.Set(cs.ACCOUNT, 'Icon', 'im-jabber') account_props.Set(cs.ACCOUNT, 'DisplayName', 'Work account') account_props.Set(cs.ACCOUNT, 'Nickname', 'Joe Bloggs') @@ -84,8 +80,6 @@ def test(q, bus, mc): assert kf[group]['DisplayName'] == 'Work account', kf assert kf[group]['Icon'] == 'im-jabber', kf assert kf[group]['Nickname'] == 'Joe Bloggs', kf - assert kf[group]['HasBeenOnline'] == 'true', kf - assert kf[group]['SecondaryVCardFields'] == 'x-badger;x-mushroom;', kf # default keyfile should be empty ekf = keyfile_read(empty_key_file_name) diff --git a/tests/twisted/capabilities/legacy-caps.py b/tests/twisted/capabilities/legacy-caps.py deleted file mode 100644 index 81d99ab6..00000000 --- a/tests/twisted/capabilities/legacy-caps.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (C) 2009 Nokia Corporation -# Copyright (C) 2009 Collabora Ltd. -# -# 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 St, Fifth Floor, Boston, MA -# 02110-1301 USA - -import dbus - -"""Regression test for pushing clients' capabilities into an old CM, with only -the old Capabilities interface. -""" - -import dbus -import dbus.service - -from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ - call_async -from mctest import exec_test, SimulatedConnection, SimulatedClient, \ - create_fakecm_account, enable_fakecm_account, SimulatedChannel, \ - expect_client_setup -import constants as cs - -def test(q, bus, mc): - # Two clients want to handle channels: MediaCall is running, and AbiWord - # is activatable. - - media_fixed_properties = dbus.Dictionary({ - cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_STREAMED_MEDIA, - }, signature='sv') - media_call = SimulatedClient(q, bus, 'MediaCall', - observe=[], approve=[], - handle=[media_fixed_properties], bypass_approval=False) - - # wait for MC to download the properties - expect_client_setup(q, [media_call]) - - def check_legacy_caps(e): - # Because MC has no idea how to map Client capabilities into legacy - # capabilities, it assumes that every client has all the flags in - # the world. In this example we have (only) a StreamedMedia client - # and a stream-tube client, so that's what MC will tell us. - add = e.args[0] - remove = e.args[1] - - assert (cs.CHANNEL_TYPE_STREAMED_MEDIA, 2L**32-1) in add - assert (cs.CHANNEL_TYPE_STREAM_TUBE, 2L**32-1) in add - - # MC puts StreamTube in the list twice - arguably a bug, but - # CMs should cope. So, don't assert about the length of the list - for item in add: - assert item in ( - (cs.CHANNEL_TYPE_STREAMED_MEDIA, 2L**32-1), - (cs.CHANNEL_TYPE_STREAM_TUBE, 2L**32-1), - ) - - assert len(remove) == 0 - - return True - - params = dbus.Dictionary({"account": "someguy@example.com", - "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) - conn = enable_fakecm_account(q, bus, mc, account, params, - extra_interfaces=[cs.CONN_IFACE_CAPS], - expect_after_connect=[ - EventPattern('dbus-method-call', handled=False, - interface=cs.CONN_IFACE_CAPS, - method='AdvertiseCapabilities', - predicate=check_legacy_caps), - ]) - -if __name__ == '__main__': - exec_test(test, {}) diff --git a/tests/twisted/constants.py b/tests/twisted/constants.py index 11587ad2..c3de47cd 100644 --- a/tests/twisted/constants.py +++ b/tests/twisted/constants.py @@ -171,13 +171,11 @@ ACCOUNT = tp_name_prefix + '.Account' ACCOUNT_IFACE_AVATAR = ACCOUNT + '.Interface.Avatar' ACCOUNT_IFACE_ADDRESSING = ACCOUNT + '.Interface.Addressing' ACCOUNT_IFACE_HIDDEN = ACCOUNT + '.Interface.Hidden.DRAFT1' -ACCOUNT_IFACE_NOKIA_COMPAT = 'com.nokia.Account.Interface.Compat' ACCOUNT_IFACE_NOKIA_CONDITIONS = 'com.nokia.Account.Interface.Conditions' ACCOUNT_PATH_PREFIX = tp_path_prefix + '/Account/' AM = tp_name_prefix + '.AccountManager' AM_IFACE_HIDDEN = AM + '.Interface.Hidden.DRAFT1' -AM_IFACE_NOKIA_QUERY = 'com.nokia.AccountManager.Interface.Query' AM_PATH = tp_path_prefix + '/AccountManager' CR = tp_name_prefix + '.ChannelRequest' diff --git a/tests/twisted/dispatcher/create-delayed-by-plugin.py b/tests/twisted/dispatcher/create-delayed-by-plugin.py deleted file mode 100644 index 8a37d228..00000000 --- a/tests/twisted/dispatcher/create-delayed-by-plugin.py +++ /dev/null @@ -1,166 +0,0 @@ -# Copyright (C) 2009 Nokia Corporation -# Copyright (C) 2009 Collabora Ltd. -# -# 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 St, Fifth Floor, Boston, MA -# 02110-1301 USA - -import dbus -"""Regression test for dispatching a requested Text channel, with a plugin that -delays dispatching and asks for permission. -""" - -import dbus -import dbus.service - -from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ - call_async, sync_dbus -from mctest import exec_test, SimulatedConnection, SimulatedClient, \ - create_fakecm_account, enable_fakecm_account, SimulatedChannel, \ - expect_client_setup -import constants as cs - -text_fixed_properties = dbus.Dictionary({ - cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, - cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, - }, signature='sv') - -def request_channel_expect_query(q, bus, account, conn, client): - # This target is special-cased in test-plugin.c - target = 'policy@example.com' - request_properties = dbus.Dictionary(text_fixed_properties, - signature='sv') - request_properties[cs.CHANNEL + '.TargetID'] = target - - cd = bus.get_object(cs.CD, cs.CD_PATH) - - user_action_time = dbus.Int64(1238582606) - - call_async(q, cd, 'CreateChannel', - account.object_path, request_properties, user_action_time, - client.bus_name, dbus_interface=cs.CD) - ret = q.expect('dbus-return', method='CreateChannel') - request_path = ret.value[0] - - cr = bus.get_object(cs.AM, request_path) - cr.Proceed(dbus_interface=cs.CR) - - cm_request_call = q.expect('dbus-method-call', - interface=cs.CONN_IFACE_REQUESTS, method='CreateChannel', - path=conn.object_path, args=[request_properties], handled=False) - - # A channel is returned eventually - - channel_properties = dbus.Dictionary(text_fixed_properties, - signature='sv') - channel_properties[cs.CHANNEL + '.TargetID'] = target - channel_properties[cs.CHANNEL + '.TargetHandle'] = \ - conn.ensure_handle(cs.HT_CONTACT, target) - channel_properties[cs.CHANNEL + '.InitiatorID'] = conn.self_ident - channel_properties[cs.CHANNEL + '.InitiatorHandle'] = conn.self_handle - channel_properties[cs.CHANNEL + '.Requested'] = True - channel_properties[cs.CHANNEL + '.Interfaces'] = \ - dbus.Array([cs.CHANNEL_IFACE_GROUP, - ],signature='s') - - chan = SimulatedChannel(conn, channel_properties, group=True) - q.dbus_return(cm_request_call.message, - chan.object_path, chan.immutable, signature='oa{sv}') - chan.announce() - - # What does the policy service think? - e = q.expect('dbus-method-call', path='/com/example/Policy', - interface='com.example.Policy', method='RequestPermission') - - # Think about it for a bit - sync_dbus(bus, q, account) - - # Let the test code decide how to reply - return e, chan, cr - -def test(q, bus, mc): - params = dbus.Dictionary({"account": "someguy@example.com", - "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) - conn = enable_fakecm_account(q, bus, mc, account, params) - - policy_bus_name_ref = dbus.service.BusName('com.example.Policy', bus) - - # Two clients want to observe, approve and handle channels - empathy = SimulatedClient(q, bus, 'Empathy', - observe=[text_fixed_properties], approve=[text_fixed_properties], - handle=[text_fixed_properties], bypass_approval=False) - kopete = SimulatedClient(q, bus, 'Kopete', - observe=[text_fixed_properties], approve=[text_fixed_properties], - handle=[text_fixed_properties], bypass_approval=False) - - # wait for MC to download the properties - expect_client_setup(q, [empathy, kopete]) - - # subscribe to the OperationList interface (MC assumes that until this - # property has been retrieved once, nobody cares) - - cd = bus.get_object(cs.CD, cs.CD_PATH) - cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) - assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] - - e, chan, cr = request_channel_expect_query(q, bus, account, conn, empathy) - - # No. - q.dbus_raise(e.message, 'com.example.Errors.No', 'Denied!') - - # The plugin responds - e = q.expect('dbus-method-call', - path=chan.object_path, - interface=cs.CHANNEL_IFACE_GROUP, - # this error message is from the plugin - method='RemoveMembersWithReason', args=[[conn.self_handle], - "Computer says no", cs.GROUP_REASON_PERMISSION_DENIED], - handled=False) - q.dbus_return(e.message, signature='') - chan.close() - - # Try again - e, chan, cr = request_channel_expect_query(q, bus, account, conn, kopete) - - # Yes. - q.dbus_return(e.message, signature='') - - e, k = q.expect_many( - EventPattern('dbus-method-call', - path=empathy.object_path, - interface=cs.OBSERVER, method='ObserveChannels', - handled=False), - EventPattern('dbus-method-call', - path=kopete.object_path, - interface=cs.OBSERVER, method='ObserveChannels', - handled=False), - ) - q.dbus_return(k.message, signature='') - q.dbus_return(e.message, signature='') - - for _ in ('Kopete', 'Empathy'): - e = q.expect('dbus-method-call', - interface=cs.HANDLER, method='HandleChannels', handled=False) - q.dbus_raise(e.message, cs.INVALID_ARGUMENT, 'Never mind') - - q.expect_many( - EventPattern('dbus-signal', path=cr.object_path, - interface=cs.CR, signal='Failed'), - EventPattern('dbus-method-call', path=chan.object_path, - interface=cs.CHANNEL, method='Close', handled=True), - ) - -if __name__ == '__main__': - exec_test(test, {}) diff --git a/tests/twisted/dispatcher/dispatch-delayed-by-plugin.py b/tests/twisted/dispatcher/dispatch-delayed-by-plugin.py deleted file mode 100644 index 24a47092..00000000 --- a/tests/twisted/dispatcher/dispatch-delayed-by-plugin.py +++ /dev/null @@ -1,272 +0,0 @@ -# Copyright (C) 2009 Nokia Corporation -# Copyright (C) 2009 Collabora Ltd. -# -# 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 St, Fifth Floor, Boston, MA -# 02110-1301 USA - -import dbus -"""Regression test for dispatching an incoming Text channel. -""" - -import dbus -import dbus.service - -from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ - call_async, sync_dbus -from mctest import exec_test, SimulatedConnection, SimulatedClient, \ - create_fakecm_account, enable_fakecm_account, SimulatedChannel, \ - expect_client_setup -import constants as cs - -text_fixed_properties = dbus.Dictionary({ - cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, - cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, - }, signature='sv') - -def signal_channel_expect_query(q, bus, account, conn): - # This target is special-cased in test-plugin.c - target = 'policy@example.com' - channel_properties = dbus.Dictionary(text_fixed_properties, - signature='sv') - channel_properties[cs.CHANNEL + '.TargetID'] = target - channel_properties[cs.CHANNEL + '.TargetHandle'] = \ - conn.ensure_handle(cs.HT_CONTACT, target) - channel_properties[cs.CHANNEL + '.InitiatorID'] = target - channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ - conn.ensure_handle(cs.HT_CONTACT, target) - channel_properties[cs.CHANNEL + '.Requested'] = False - channel_properties[cs.CHANNEL + '.Interfaces'] = \ - dbus.Array([cs.CHANNEL_IFACE_DESTROYABLE, cs.CHANNEL_IFACE_GROUP, - ],signature='s') - - chan = SimulatedChannel(conn, channel_properties, group=True) - chan.announce() - - e = q.expect('dbus-signal', - path=cs.CD_PATH, - interface=cs.CD_IFACE_OP_LIST, - signal='NewDispatchOperation') - - cdo_path = e.args[0] - cdo_properties = e.args[1] - - assert cdo_properties[cs.CDO + '.Account'] == account.object_path - assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path - assert cs.CDO + '.Interfaces' in cdo_properties - - handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] - handlers.sort() - assert handlers == [cs.tp_name_prefix + '.Client.Empathy', - cs.tp_name_prefix + '.Client.Kopete'], handlers - - # What does the policy service think? - e = q.expect('dbus-method-call', path='/com/example/Policy', - interface='com.example.Policy', method='RequestPermission') - - # Think about it for a bit - sync_dbus(bus, q, account) - - # Let the test code decide how to reply - return e, chan, cdo_path - -def test(q, bus, mc): - params = dbus.Dictionary({"account": "someguy@example.com", - "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) - conn = enable_fakecm_account(q, bus, mc, account, params) - - policy_bus_name_ref = dbus.service.BusName('com.example.Policy', bus) - - # For the beginning of this test, we should never be asked to handle - # a channel. - forbidden = [ - EventPattern('dbus-method-call', method='HandleChannels'), - ] - q.forbid_events(forbidden) - - # Two clients want to observe, approve and handle channels - empathy = SimulatedClient(q, bus, 'Empathy', - observe=[text_fixed_properties], approve=[text_fixed_properties], - handle=[text_fixed_properties], bypass_approval=False) - kopete = SimulatedClient(q, bus, 'Kopete', - observe=[text_fixed_properties], approve=[text_fixed_properties], - handle=[text_fixed_properties], bypass_approval=False) - - # wait for MC to download the properties - expect_client_setup(q, [empathy, kopete]) - - # subscribe to the OperationList interface (MC assumes that until this - # property has been retrieved once, nobody cares) - - cd = bus.get_object(cs.CD, cs.CD_PATH) - cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) - assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] - - e, chan, cdo_path = signal_channel_expect_query(q, bus, account, conn) - - # No. - q.dbus_raise(e.message, 'com.example.Errors.No', 'Denied!') - - # The plugin responds - _, _, e = q.expect_many( - EventPattern('dbus-signal', path=cdo_path, - interface=cs.CDO, signal='Finished'), - EventPattern('dbus-signal', path=cs.CD_PATH, - interface=cs.CD_IFACE_OP_LIST, - signal='DispatchOperationFinished', - args=[cdo_path]), - EventPattern('dbus-method-call', - path=chan.object_path, - interface=cs.CHANNEL_IFACE_GROUP, - # this error message is from the plugin - method='RemoveMembersWithReason', args=[[conn.self_handle], - "Computer says no", cs.GROUP_REASON_PERMISSION_DENIED], - handled=False), - ) - q.dbus_return(e.message, signature='') - chan.close() - - # Try again - e, chan, cdo_path = signal_channel_expect_query(q, bus, account, conn) - - # Yes. - q.dbus_return(e.message, signature='') - - e, k = q.expect_many( - EventPattern('dbus-method-call', - path=empathy.object_path, - interface=cs.OBSERVER, method='ObserveChannels', - handled=False), - EventPattern('dbus-method-call', - path=kopete.object_path, - interface=cs.OBSERVER, method='ObserveChannels', - handled=False), - ) - q.dbus_return(k.message, signature='') - q.dbus_return(e.message, signature='') - - e, k = q.expect_many( - EventPattern('dbus-method-call', - path=empathy.object_path, - interface=cs.APPROVER, method='AddDispatchOperation', - handled=False), - EventPattern('dbus-method-call', - path=kopete.object_path, - interface=cs.APPROVER, method='AddDispatchOperation', - handled=False), - ) - q.dbus_return(e.message, signature='') - q.dbus_return(k.message, signature='') - - kopete_cdo = bus.get_object(cs.CD, cdo_path) - kopete_cdo_iface = dbus.Interface(kopete_cdo, cs.CDO) - call_async(q, kopete_cdo_iface, 'Claim') - - q.expect_many( - EventPattern('dbus-signal', path=cdo_path, signal='Finished'), - EventPattern('dbus-signal', path=cs.CD_PATH, - signal='DispatchOperationFinished', args=[cdo_path]), - EventPattern('dbus-return', method='Claim'), - ) - - sync_dbus(bus, q, mc) - - # From now on we no longer want to forbid HandleChannels, but we do want - # to forbid AddDispatchOperation - q.unforbid_events(forbidden) - forbidden = [ - EventPattern('dbus-method-call', method='AddDispatchOperation'), - ] - q.forbid_events(forbidden) - - # Try yet again - policy_request, chan, cdo_path = signal_channel_expect_query(q, bus, - account, conn) - - # Before the policy service replies, someone requests the same channel - - user_action_time = dbus.Int64(1238582606) - call_async(q, cd, 'EnsureChannel', - account.object_path, chan.immutable, user_action_time, - kopete.bus_name, dbus_interface=cs.CD) - ret, add_request_call = q.expect_many( - EventPattern('dbus-return', method='EnsureChannel'), - EventPattern('dbus-method-call', handled=False, - interface=cs.CLIENT_IFACE_REQUESTS, - method='AddRequest', path=kopete.object_path), - ) - request_path = ret.value[0] - - cr = bus.get_object(cs.CD, request_path) - cr.Proceed(dbus_interface=cs.CR) - - cm_request_call = q.expect('dbus-method-call', - interface=cs.CONN_IFACE_REQUESTS, - method='EnsureChannel', - path=conn.object_path, args=[chan.immutable], handled=False) - - q.dbus_return(add_request_call.message, signature='') - - # Time passes. The CM returns the existing channel, and the policy - # service gets round to replying - - q.dbus_return(cm_request_call.message, False, - chan.object_path, chan.immutable, signature='boa{sv}') - - q.dbus_return(policy_request.message, signature='') - - e, k = q.expect_many( - EventPattern('dbus-method-call', - path=empathy.object_path, - interface=cs.OBSERVER, method='ObserveChannels', - handled=False), - EventPattern('dbus-method-call', - path=kopete.object_path, - interface=cs.OBSERVER, method='ObserveChannels', - handled=False), - ) - - # Both Observers indicate that they are ready to proceed - q.dbus_return(k.message, signature='') - q.dbus_return(e.message, signature='') - - e = q.expect('dbus-method-call', - path=kopete.object_path, - interface=cs.HANDLER, method='HandleChannels', - handled=False) - assert e.args[0] == account.object_path, e.args - assert e.args[1] == conn.object_path, e.args - channels = e.args[2] - assert len(channels) == 1, channels - assert channels[0][0] == chan.object_path, channels - assert channels[0][1] == chan.immutable, channels - assert e.args[3] == [request_path], e.args - assert e.args[4] == user_action_time, (e.args[4], user_action_time) - assert isinstance(e.args[5], dict) - assert len(e.args) == 6 - - # Handler accepts the Channels - q.dbus_return(e.message, signature='') - - q.expect_many( - EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), - EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, - signal='DispatchOperationFinished'), - ) - - sync_dbus(bus, q, mc) - -if __name__ == '__main__': - exec_test(test, {}) diff --git a/tests/twisted/dispatcher/dispatch-rejected-by-plugin.py b/tests/twisted/dispatcher/dispatch-rejected-by-plugin.py deleted file mode 100644 index 272eac37..00000000 --- a/tests/twisted/dispatcher/dispatch-rejected-by-plugin.py +++ /dev/null @@ -1,239 +0,0 @@ -# Copyright (C) 2009 Nokia Corporation -# Copyright (C) 2009 Collabora Ltd. -# -# 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 St, Fifth Floor, Boston, MA -# 02110-1301 USA - -import dbus -"""Regression test for dispatching an incoming Text channel. -""" - -import dbus -import dbus.service - -from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \ - call_async -from mctest import exec_test, SimulatedConnection, SimulatedClient, \ - create_fakecm_account, enable_fakecm_account, SimulatedChannel, \ - expect_client_setup -import constants as cs - -def test(q, bus, mc): - params = dbus.Dictionary({"account": "someguy@example.com", - "password": "secrecy"}, signature='sv') - cm_name_ref, account = create_fakecm_account(q, bus, mc, params) - conn = enable_fakecm_account(q, bus, mc, account, params) - - text_fixed_properties = dbus.Dictionary({ - cs.CHANNEL + '.TargetHandleType': cs.HT_CONTACT, - cs.CHANNEL + '.ChannelType': cs.CHANNEL_TYPE_TEXT, - }, signature='sv') - - # Throughout this entire test, we should never be asked to approve or - # handle a channel. - forbidden = [ - EventPattern('dbus-method-call', method='AddDispatchOperation'), - EventPattern('dbus-method-call', method='HandleChannels'), - # FIXME: currently we're never asked to ObserveChannels either - - # is that right? - # - # EventPattern('dbus-method-call', method='ObserveChannels'), - ] - q.forbid_events(forbidden) - - # Two clients want to observe, approve and handle channels - empathy = SimulatedClient(q, bus, 'Empathy', - observe=[text_fixed_properties], approve=[text_fixed_properties], - handle=[text_fixed_properties], bypass_approval=False) - kopete = SimulatedClient(q, bus, 'Kopete', - observe=[text_fixed_properties], approve=[text_fixed_properties], - handle=[text_fixed_properties], bypass_approval=False) - - # wait for MC to download the properties - expect_client_setup(q, [empathy, kopete]) - - # subscribe to the OperationList interface (MC assumes that until this - # property has been retrieved once, nobody cares) - - cd = bus.get_object(cs.CD, cs.CD_PATH) - cd_props = dbus.Interface(cd, cs.PROPERTIES_IFACE) - assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') == [] - - # This ID is special-cased by the test-plugin plugin, which rejects - # channels to or from it - target = 'rick.astley@example.com' - channel_properties = dbus.Dictionary(text_fixed_properties, - signature='sv') - channel_properties[cs.CHANNEL + '.TargetID'] = target - channel_properties[cs.CHANNEL + '.TargetHandle'] = \ - conn.ensure_handle(cs.HT_CONTACT, target) - channel_properties[cs.CHANNEL + '.InitiatorID'] = target - channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ - conn.ensure_handle(cs.HT_CONTACT, target) - channel_properties[cs.CHANNEL + '.Requested'] = False - channel_properties[cs.CHANNEL + '.Interfaces'] = \ - dbus.Array([cs.CHANNEL_IFACE_DESTROYABLE, cs.CHANNEL_IFACE_GROUP, - ],signature='s') - - chan = SimulatedChannel(conn, channel_properties, group=True) - chan.announce() - - # A channel dispatch operation is created - - e = q.expect('dbus-signal', - path=cs.CD_PATH, - interface=cs.CD_IFACE_OP_LIST, - signal='NewDispatchOperation') - - cdo_path = e.args[0] - cdo_properties = e.args[1] - - assert cdo_properties[cs.CDO + '.Account'] == account.object_path - assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path - assert cs.CDO + '.Interfaces' in cdo_properties - - handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] - handlers.sort() - assert handlers == [cs.tp_name_prefix + '.Client.Empathy', - cs.tp_name_prefix + '.Client.Kopete'], handlers - - # The plugin realises we've been rickrolled, and responds - e = q.expect('dbus-method-call', - path=chan.object_path, - interface=cs.CHANNEL_IFACE_DESTROYABLE, method='Destroy', args=[], - handled=False) - # treat it like Close - chan.Close(e) - - q.expect_many( - EventPattern('dbus-signal', path=cdo_path, - interface=cs.CDO, signal='Finished'), - EventPattern('dbus-signal', path=cs.CD_PATH, - interface=cs.CD_IFACE_OP_LIST, - signal='DispatchOperationFinished', - args=[cdo_path]), - ) - - # This ID is also special-cased - target = 'mc.hammer@example.com' - channel_properties = dbus.Dictionary(text_fixed_properties, - signature='sv') - channel_properties[cs.CHANNEL + '.TargetID'] = target - channel_properties[cs.CHANNEL + '.TargetHandle'] = \ - conn.ensure_handle(cs.HT_CONTACT, target) - channel_properties[cs.CHANNEL + '.InitiatorID'] = target - channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ - conn.ensure_handle(cs.HT_CONTACT, target) - channel_properties[cs.CHANNEL + '.Requested'] = False - channel_properties[cs.CHANNEL + '.Interfaces'] = \ - dbus.Array([cs.CHANNEL_IFACE_DESTROYABLE, cs.CHANNEL_IFACE_GROUP, - ],signature='s') - - chan = SimulatedChannel(conn, channel_properties, group=True) - chan.announce() - - # A channel dispatch operation is created - - e = q.expect('dbus-signal', - path=cs.CD_PATH, - interface=cs.CD_IFACE_OP_LIST, - signal='NewDispatchOperation') - - cdo_path = e.args[0] - cdo_properties = e.args[1] - - assert cdo_properties[cs.CDO + '.Account'] == account.object_path - assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path - assert cs.CDO + '.Interfaces' in cdo_properties - - handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] - handlers.sort() - assert handlers == [cs.tp_name_prefix + '.Client.Empathy', - cs.tp_name_prefix + '.Client.Kopete'], handlers - - # The plugin realises it's MC Hammer, and responds - e = q.expect('dbus-method-call', - path=chan.object_path, - interface=cs.CHANNEL_IFACE_DESTROYABLE, method='Destroy', args=[], - handled=False) - # treat it like Close - chan.Close(e) - - q.expect_many( - EventPattern('dbus-signal', path=cdo_path, - interface=cs.CDO, signal='Finished'), - EventPattern('dbus-signal', path=cs.CD_PATH, - interface=cs.CD_IFACE_OP_LIST, - signal='DispatchOperationFinished', - args=[cdo_path]), - ) - - # This ID is *also* special-cased - target = 'hammertime@example.com' - channel_properties = dbus.Dictionary(text_fixed_properties, - signature='sv') - channel_properties[cs.CHANNEL + '.TargetID'] = target - channel_properties[cs.CHANNEL + '.TargetHandle'] = \ - conn.ensure_handle(cs.HT_CONTACT, target) - channel_properties[cs.CHANNEL + '.InitiatorID'] = target - channel_properties[cs.CHANNEL + '.InitiatorHandle'] = \ - conn.ensure_handle(cs.HT_CONTACT, target) - channel_properties[cs.CHANNEL + '.Requested'] = False - channel_properties[cs.CHANNEL + '.Interfaces'] = \ - dbus.Array([cs.CHANNEL_IFACE_DESTROYABLE, cs.CHANNEL_IFACE_GROUP, - ],signature='s') - - chan = SimulatedChannel(conn, channel_properties, group=True) - chan.announce() - - # A channel dispatch operation is created - - e = q.expect('dbus-signal', - path=cs.CD_PATH, - interface=cs.CD_IFACE_OP_LIST, - signal='NewDispatchOperation') - - cdo_path = e.args[0] - cdo_properties = e.args[1] - - assert cdo_properties[cs.CDO + '.Account'] == account.object_path - assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path - assert cs.CDO + '.Interfaces' in cdo_properties - - handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] - handlers.sort() - assert handlers == [cs.tp_name_prefix + '.Client.Empathy', - cs.tp_name_prefix + '.Client.Kopete'], handlers - - # The plugin realises it's MC Hammer, and responds - _, _, e = q.expect_many( - EventPattern('dbus-signal', path=cdo_path, - interface=cs.CDO, signal='Finished'), - EventPattern('dbus-signal', path=cs.CD_PATH, - interface=cs.CD_IFACE_OP_LIST, - signal='DispatchOperationFinished', - args=[cdo_path]), - EventPattern('dbus-method-call', - path=chan.object_path, - interface=cs.CHANNEL_IFACE_GROUP, - method='RemoveMembersWithReason', args=[[conn.self_handle], - "Can't touch this", cs.GROUP_REASON_PERMISSION_DENIED], - handled=False), - ) - q.dbus_return(e.message, signature='') - chan.close() - -if __name__ == '__main__': - exec_test(test, {}) diff --git a/tests/twisted/dispatcher/exploding-bundles.py b/tests/twisted/dispatcher/exploding-bundles.py index a62a7009..27d3be3a 100644 --- a/tests/twisted/dispatcher/exploding-bundles.py +++ b/tests/twisted/dispatcher/exploding-bundles.py @@ -107,34 +107,30 @@ def test(q, bus, mc): conn.NewChannels([text_chan, media_chan]) - # A channel dispatch operation is created + # A channel dispatch operation is created for the Text channel first. e = q.expect('dbus-signal', path=cs.CD_PATH, interface=cs.CD_IFACE_OP_LIST, signal='NewDispatchOperation') - cdo_path = e.args[0] - cdo_properties = e.args[1] + text_cdo_path = e.args[0] + text_cdo_properties = e.args[1] - assert cdo_properties[cs.CDO + '.Account'] == account.object_path - assert cdo_properties[cs.CDO + '.Connection'] == conn.object_path + assert text_cdo_properties[cs.CDO + '.Account'] == account.object_path + assert text_cdo_properties[cs.CDO + '.Connection'] == conn.object_path - handlers = cdo_properties[cs.CDO + '.PossibleHandlers'][:] - # only Empathy can handle the whole batch - assert handlers == [cs.tp_name_prefix + '.Client.org.gnome.Empathy'], \ - handlers + handlers = text_cdo_properties[cs.CDO + '.PossibleHandlers'][:] + assert (sorted(handlers) == + [cs.tp_name_prefix + '.Client.org.gnome.Empathy', + cs.tp_name_prefix + '.Client.org.kde.Kopete']), handlers - assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') - assert cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations') ==\ - [(cdo_path, cdo_properties)] - - cdo = bus.get_object(cs.CD, cdo_path) - cdo_iface = dbus.Interface(cdo, cs.CDO) + text_cdo = bus.get_object(cs.CD, text_cdo_path) + text_cdo_iface = dbus.Interface(text_cdo, cs.CDO) - # Both Observers are told about the new channels + # Both Observers are told about the new Text channel - e, k = q.expect_many( + e_observe_text, k_observe_text = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.OBSERVER, method='ObserveChannels', @@ -144,62 +140,130 @@ def test(q, bus, mc): interface=cs.OBSERVER, method='ObserveChannels', handled=False), ) - assert e.args[0] == account.object_path, e.args - assert e.args[1] == conn.object_path, e.args - assert e.args[3] == cdo_path, e.args - assert e.args[4] == [], e.args # no requests satisfied - channels = e.args[2] - assert len(channels) == 2, channels + assert e_observe_text.args[0] == account.object_path, e_observe_text.args + assert e_observe_text.args[1] == conn.object_path, e_observe_text.args + assert e_observe_text.args[3] == text_cdo_path, e_observe_text.args + assert e_observe_text.args[4] == [], e_observe_text.args + channels = e_observe_text.args[2] + assert len(channels) == 1, channels assert (text_chan.object_path, text_channel_properties) in channels + + assert k_observe_text.args[0] == e_observe_text.args[0], k_observe_text.args + assert k_observe_text.args[1] == e_observe_text.args[1], k_observe_text.args + assert (k_observe_text.args[2] == + [(text_chan.object_path, text_channel_properties)]) + + # Now a separate CDO is created for the media channel. + + e = q.expect('dbus-signal', + path=cs.CD_PATH, + interface=cs.CD_IFACE_OP_LIST, + signal='NewDispatchOperation') + + media_cdo_path = e.args[0] + media_cdo_properties = e.args[1] + + assert media_cdo_properties[cs.CDO + '.Account'] == account.object_path + assert media_cdo_properties[cs.CDO + '.Connection'] == conn.object_path + + handlers = media_cdo_properties[cs.CDO + '.PossibleHandlers'][:] + # only Empathy can handle it + assert (sorted(handlers) == + [cs.tp_name_prefix + '.Client.org.gnome.Empathy']), handlers + + assert cs.CD_IFACE_OP_LIST in cd_props.Get(cs.CD, 'Interfaces') + assert (sorted(cd_props.Get(cs.CD_IFACE_OP_LIST, 'DispatchOperations')) == + [(text_cdo_path, text_cdo_properties), + (media_cdo_path, media_cdo_properties)]) + + media_cdo = bus.get_object(cs.CD, media_cdo_path) + media_cdo_iface = dbus.Interface(media_cdo, cs.CDO) + + # Only Empathy is told about the new media channel + + e_observe_media = q.expect('dbus-method-call', + path=empathy.object_path, + interface=cs.OBSERVER, method='ObserveChannels', + handled=False) + assert e_observe_media.args[0] == account.object_path, e_observe_media.args + assert e_observe_media.args[1] == conn.object_path, e_observe_media.args + assert e_observe_media.args[3] == media_cdo_path, e_observe_media.args + assert e_observe_media.args[4] == [], e_observe_media.args + channels = e_observe_media.args[2] + assert len(channels) == 1, channels assert (media_chan.object_path, media_channel_properties) in channels - # fd.o #21089: telepathy-spec doesn't say whether Kopete observes the whole - # batch or just the text channel. In current MC, it only observes the text. - assert k.args[0] == e.args[0], k.args - assert k.args[1] == e.args[1], e.args - assert k.args[2] == [(text_chan.object_path, text_channel_properties)] + # All Observers reply. - # Both Observers indicate that they are ready to proceed - q.dbus_return(k.message, signature='') - q.dbus_return(e.message, signature='') + q.dbus_return(e_observe_text.message, signature='') + q.dbus_return(k_observe_text.message, signature='') + q.dbus_return(e_observe_media.message, signature='') # The Approvers are next - # fd.o #21090: telepathy-spec doesn't say whether Kopete is asked to - # approve this CDO. In current MC, it is. - e, k = q.expect_many( + e_approve_text, k_approve_text, e_approve_media = q.expect_many( EventPattern('dbus-method-call', path=empathy.object_path, interface=cs.APPROVER, method='AddDispatchOperation', + predicate=lambda e: e.args[1] == text_cdo_path, handled=False), EventPattern('dbus-method-call', path=kopete.object_path, interface=cs.APPROVER, method='AddDispatchOperation', handled=False), + EventPattern('dbus-method-call', + path=empathy.object_path, + interface=cs.APPROVER, method='AddDispatchOperation', + predicate=lambda e: e.args[1] == media_cdo_path, + handled=False) ) - assert len(e.args[0]) == 2 - assert (text_chan.object_path, text_channel_properties) in e.args[0] - assert (media_chan.object_path, media_channel_properties) in e.args[0] - assert e.args[1:] == [cdo_path, cdo_properties] - assert k.args == e.args + assert len(e_approve_text.args[0]) == 1 + assert ((text_chan.object_path, text_channel_properties) in + e_approve_text.args[0]) + assert e_approve_text.args[1:] == [text_cdo_path, text_cdo_properties] + assert k_approve_text.args == e_approve_text.args - q.dbus_return(e.message, signature='') - q.dbus_return(k.message, signature='') + assert len(e_approve_media.args[0]) == 1 + assert ((media_chan.object_path, media_channel_properties) in + e_approve_media.args[0]) + assert e_approve_media.args[1:] == [media_cdo_path, media_cdo_properties] + + q.dbus_return(e_approve_text.message, signature='') + q.dbus_return(k_approve_text.message, signature='') + q.dbus_return(e_approve_media.message, signature='') # Both Approvers now have a flashing icon or something, trying to get the - # user's attention + # user's attention. The user clicks on Empathy + call_async(q, text_cdo_iface, 'HandleWith', + cs.tp_name_prefix + '.Client.org.gnome.Empathy') + + # Empathy is asked to handle the channel + e = q.expect('dbus-method-call', + path=empathy.object_path, + interface=cs.HANDLER, method='HandleChannels', + handled=False) + + # Empathy accepts the channel + q.dbus_return(e.message, signature='') + + q.expect_many( + EventPattern('dbus-return', method='HandleWith'), + EventPattern('dbus-signal', interface=cs.CDO, signal='Finished'), + EventPattern('dbus-signal', interface=cs.CD_IFACE_OP_LIST, + signal='DispatchOperationFinished'), + ) - # The user doesn't care which one will handle the channels - because + # The user doesn't care which client will handle the channel - because # Empathy is the only possibility, it will be chosen (this is also a # regression test for the ability to leave the handler unspecified). - call_async(q, cdo_iface, 'HandleWith', '') + call_async(q, media_cdo_iface, 'HandleWith', '') - # Empathy is asked to handle the channels + # Empathy is asked to handle the channel e = q.expect('dbus-method-call', path=empathy.object_path, interface=cs.HANDLER, method='HandleChannels', handled=False) - # Empathy accepts the channels + # Empathy accepts the channel q.dbus_return(e.message, signature='') q.expect_many( diff --git a/tests/twisted/mc-debug-server.c b/tests/twisted/mc-debug-server.c index c1a485fe..f1cfa8ff 100644 --- a/tests/twisted/mc-debug-server.c +++ b/tests/twisted/mc-debug-server.c @@ -33,8 +33,7 @@ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/debug.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> #if ENABLE_GNOME_KEYRING #include <gnome-keyring.h> @@ -120,58 +119,6 @@ dbus_filter_function (DBusConnection *connection, } else if (dbus_message_is_method_call (message, "org.freedesktop.Telepathy.MissionControl5.RegressionTests", - "ChangeSystemFlags")) - { - DBusMessage *reply; - DBusError e; - dbus_uint32_t set, unset; - - dbus_error_init (&e); - - if (!dbus_message_get_args (message, &e, - 'u', &set, - 'u', &unset, - DBUS_TYPE_INVALID)) - { - reply = dbus_message_new_error (message, e.name, e.message); - dbus_error_free (&e); - } - else - { - McdMaster *master = mcd_master_get_default (); - - if (set & MCD_SYSTEM_IDLE) - { - mcd_master_set_idle (master, TRUE); - } - - if (set & MCD_SYSTEM_MEMORY_CONSERVED) - { - mcd_master_set_low_memory (master, TRUE); - } - - if (unset & MCD_SYSTEM_IDLE) - { - mcd_master_set_idle (master, FALSE); - } - - if (unset & MCD_SYSTEM_MEMORY_CONSERVED) - { - mcd_master_set_low_memory (master, FALSE); - } - - reply = dbus_message_new_method_return (message); - } - - if (reply == NULL || !dbus_connection_send (connection, reply, NULL)) - g_error ("Out of memory"); - - dbus_message_unref (reply); - - return DBUS_HANDLER_RESULT_HANDLED; - } - else if (dbus_message_is_method_call (message, - "org.freedesktop.Telepathy.MissionControl5.RegressionTests", "BillyIdle")) { /* Used to drive a souped-up version of sync_dbus(), where we need to diff --git a/tests/twisted/mcp-plugin.c b/tests/twisted/mcp-plugin.c index 67e3a8fb..f103dac0 100644 --- a/tests/twisted/mcp-plugin.c +++ b/tests/twisted/mcp-plugin.c @@ -24,9 +24,8 @@ #include <dbus/dbus.h> #include <dbus/dbus-glib-lowlevel.h> -#include <telepathy-glib/dbus.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/util.h> +#include <telepathy-glib/telepathy-glib.h> +#include <telepathy-glib/telepathy-glib-dbus.h> #define DEBUG g_debug @@ -128,7 +127,7 @@ permission_cb (DBusPendingCall *pc, if (ctx->result != NULL) { - g_simple_async_result_set_error (ctx->result, TP_ERRORS, + g_simple_async_result_set_error (ctx->result, TP_ERROR, TP_ERROR_PERMISSION_DENIED, "No, sorry"); } else @@ -355,7 +354,7 @@ request_permission_cb (DBusPendingCall *pc, { DEBUG ("Permission denied"); mcp_request_deny (ctx->request, - TP_ERRORS, TP_CHANNEL_GROUP_CHANGE_REASON_PERMISSION_DENIED, + TP_ERROR, TP_CHANNEL_GROUP_CHANGE_REASON_PERMISSION_DENIED, "Computer says no"); } else @@ -536,7 +535,7 @@ test_rejection_plugin_check_request (McpRequestPolicy *policy, "com.example.ForbiddenChannel")) { DEBUG ("Forbidden channel detected, denying request"); - mcp_request_deny (request, TP_ERRORS, TP_ERROR_PERMISSION_DENIED, + mcp_request_deny (request, TP_ERROR, TP_ERROR_PERMISSION_DENIED, "No, you don't"); } @@ -545,7 +544,7 @@ test_rejection_plugin_check_request (McpRequestPolicy *policy, NULL, NULL)) { DEBUG ("Forbidden channel detected, denying request"); - mcp_request_deny (request, TP_ERRORS, TP_ERROR_PERMISSION_DENIED, + mcp_request_deny (request, TP_ERROR, TP_ERROR_PERMISSION_DENIED, "No, you don't"); } diff --git a/tests/twisted/mctest.py b/tests/twisted/mctest.py index 48d98c0e..be187d6b 100644 --- a/tests/twisted/mctest.py +++ b/tests/twisted/mctest.py @@ -1078,7 +1078,7 @@ class Account(servicetest.ProxyWrapper): def __init__(self, bus, account_path): servicetest.ProxyWrapper.__init__(self, bus.get_object(cs.AM, account_path), - cs.ACCOUNT, {'Compat': cs.ACCOUNT_IFACE_NOKIA_COMPAT}) + cs.ACCOUNT, {}) class ChannelDispatcher(servicetest.ProxyWrapper): def __init__(self, bus): @@ -1110,9 +1110,6 @@ def connect_to_mc(q, bus, mc): assert properties is not None interfaces = properties.get('Interfaces') - # assert that current functionality exists - assert cs.AM_IFACE_NOKIA_QUERY in interfaces, interfaces - return account_manager, properties, interfaces def tell_mc_to_die(q, bus): diff --git a/tests/twisted/servicetest.py b/tests/twisted/servicetest.py index c0c63ed3..60418312 100644 --- a/tests/twisted/servicetest.py +++ b/tests/twisted/servicetest.py @@ -316,12 +316,12 @@ class IteratingEventQueue(BaseEventQueue): try: # for dbus > 1.5 - bus.add_match_string("eavesdrop=true") + bus.add_match_string("eavesdrop=true,type='signal'") except dbus.DBusException: - pass - - # for dbus 1.4 - bus.add_match_string("") + bus.add_match_string("type='signal'") + bus.add_match_string("type='method_call'") + else: + bus.add_match_string("eavesdrop=true,type='method_call'") bus.add_message_filter(self._dbus_filter_bound_method) diff --git a/tests/twisted/test-plugin.c b/tests/twisted/test-plugin.c deleted file mode 100644 index 89171a32..00000000 --- a/tests/twisted/test-plugin.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * A demonstration plugin that acts as a channel filter. - * - * Copyright (C) 2008-2009 Nokia Corporation - * Copyright (C) 2009 Collabora Ltd. - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mcd-dispatcher-context.h" -#include "mcd-plugin.h" -#include "mcd-debug.h" - -#include <dbus/dbus.h> -#include <dbus/dbus-glib-lowlevel.h> - -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/util.h> - -/* forward declaration to keep the compiler happy */ -void mcd_plugin_init (McdPlugin *); - -static void -reject_rickrolling (McdDispatcherContext *ctx, - gpointer user_data) -{ - McdChannel *channel = mcd_dispatcher_context_get_channel (ctx); - const gchar *inviter = mcd_channel_get_inviter (channel); - GQuark channel_type = mcd_channel_get_channel_type_quark (channel); - const gchar *object_path = mcd_channel_get_object_path (channel); - - DEBUG ("called"); - - /* we don't actually use the user_data here, so just assert that it's - * passed to the callback correctly */ - g_assert (!tp_strdiff (user_data, "Never gonna give you up")); - - /* the McdChannel had better have a TpChannel, otherwise something is badly - * wrong */ - g_assert (channel_type != 0); - g_assert (object_path != NULL); - - if (!tp_strdiff (inviter, "rick.astley@example.com") - && (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA || - channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT)) - { - DEBUG ("rickrolling detected, closing channel %s", object_path); - mcd_dispatcher_context_destroy_all (ctx); - } - - mcd_dispatcher_context_proceed (ctx); -} - -static void -reject_with_reason (McdDispatcherContext *ctx, - gpointer user_data) -{ - McdChannel *channel = mcd_dispatcher_context_get_channel (ctx); - const gchar *inviter = mcd_channel_get_inviter (channel); - GQuark channel_type = mcd_channel_get_channel_type_quark (channel); - const gchar *object_path = mcd_channel_get_object_path (channel); - - DEBUG ("called"); - - /* we don't actually use the user_data here, so just assert that it's - * passed to the callback correctly */ - g_assert (!tp_strdiff (user_data, "Can't touch this")); - - /* the McdChannel had better have a TpChannel, otherwise something is badly - * wrong */ - g_assert (channel_type != 0); - g_assert (object_path != NULL); - - if (!tp_strdiff (inviter, "hammertime@example.com") - && (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA || - channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT)) - { - DEBUG ("MC Hammer detected, closing channel %s", object_path); - mcd_dispatcher_context_close_all (ctx, - TP_CHANNEL_GROUP_CHANGE_REASON_PERMISSION_DENIED, - "Can't touch this"); - } - - mcd_dispatcher_context_proceed (ctx); -} - -/* An older API for terminating unwanted channels */ -static void -reject_mc_hammer (McdDispatcherContext *ctx, - gpointer user_data) -{ - McdChannel *channel = mcd_dispatcher_context_get_channel (ctx); - const gchar *inviter = mcd_channel_get_inviter (channel); - GQuark channel_type = mcd_channel_get_channel_type_quark (channel); - const gchar *object_path = mcd_channel_get_object_path (channel); - - DEBUG ("called"); - - /* we don't actually use the user_data here, so just assert that it's - * passed to the callback correctly */ - g_assert (!tp_strdiff (user_data, "Stop! Hammer time")); - - /* the McdChannel had better have a TpChannel, otherwise something is badly - * wrong */ - g_assert (channel_type != 0); - g_assert (object_path != NULL); - - if (!tp_strdiff (inviter, "mc.hammer@example.com") - && (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA || - channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT)) - { - DEBUG ("MC Hammer detected, closing channel %s", object_path); - mcd_dispatcher_context_process (ctx, FALSE); - return; - } - - mcd_dispatcher_context_process (ctx, TRUE); -} - -static void -permission_cb (DBusPendingCall *pc, - gpointer data) -{ - McdDispatcherContext *ctx = data; - DBusMessage *message = dbus_pending_call_steal_reply (pc); - - if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR) - { - DEBUG ("Permission denied for %p", ctx); - mcd_dispatcher_context_close_all (ctx, - TP_CHANNEL_GROUP_CHANGE_REASON_PERMISSION_DENIED, - "Computer says no"); - } - else - { - DEBUG ("Permission granted for %p", ctx); - } - - dbus_message_unref (message); - dbus_pending_call_unref (pc); -} - -static void -ask_for_permission (McdDispatcherContext *ctx, gpointer user_data) -{ - McdChannel *channel = mcd_dispatcher_context_get_channel (ctx); - - DEBUG ("%p", ctx); - - if (!tp_strdiff (mcd_channel_get_name (channel), "policy@example.com")) - { - TpDBusDaemon *dbus_daemon = tp_dbus_daemon_dup (NULL); - DBusGConnection *gconn = tp_proxy_get_dbus_connection (dbus_daemon); - DBusConnection *libdbus = dbus_g_connection_get_connection (gconn); - DBusPendingCall *pc = NULL; - DBusMessage *message; - - /* in a real policy-mechanism you'd give some details, like the - * channel's properties or object path */ - message = dbus_message_new_method_call ("com.example.Policy", - "/com/example/Policy", "com.example.Policy", "RequestPermission"); - - if (!dbus_connection_send_with_reply (libdbus, message, - &pc, -1)) - g_error ("out of memory"); - - dbus_message_unref (message); - - if (pc == NULL) - { - DEBUG ("got disconnected from D-Bus..."); - goto proceed; - } - - /* pc is unreffed by permission_cb */ - - DEBUG ("Waiting for permission for %p", ctx); - - if (dbus_pending_call_get_completed (pc)) - { - permission_cb (pc, ctx); - goto proceed; - } - - if (!dbus_pending_call_set_notify (pc, permission_cb, ctx, - (DBusFreeFunction) mcd_dispatcher_context_proceed)) - g_error ("Out of memory"); - - return; - } - -proceed: - mcd_dispatcher_context_proceed (ctx); -} - -static const McdFilter my_filters[] = { - { reject_rickrolling, MCD_FILTER_PRIORITY_CRITICAL, - "Never gonna give you up" }, - { reject_with_reason, MCD_FILTER_PRIORITY_CRITICAL, - "Can't touch this" }, - { reject_mc_hammer, MCD_FILTER_PRIORITY_CRITICAL, - "Stop! Hammer time" }, - { ask_for_permission, MCD_FILTER_PRIORITY_SYSTEM, "May I?" }, - { NULL } -}; - -void -mcd_plugin_init (McdPlugin *plugin) -{ - McdDispatcher *dispatcher = mcd_plugin_get_dispatcher (plugin); - - DEBUG ("Initializing test-plugin"); - - mcd_dispatcher_add_filters (dispatcher, my_filters); -} diff --git a/tests/twisted/tools/exec-with-log.sh.in b/tests/twisted/tools/exec-with-log.sh.in index a7abbf91..9ff5a899 100644 --- a/tests/twisted/tools/exec-with-log.sh.in +++ b/tests/twisted/tools/exec-with-log.sh.in @@ -20,6 +20,8 @@ cd "@abs_top_builddir@/tests/twisted/tools" +G_MESSAGES_DEBUG=all +export G_MESSAGES_DEBUG ulimit -c unlimited exec > missioncontrol-$$.log 2>&1 ln -f missioncontrol-$$.log missioncontrol.log diff --git a/tests/value-is-same.c b/tests/value-is-same.c index f0b5c36d..1f7854ba 100644 --- a/tests/value-is-same.c +++ b/tests/value-is-same.c @@ -57,7 +57,9 @@ assert_and_reset (GValue *value, GValue *same, GValue *different) static void test_numeric (void) { - GValue value = { 0 }, same = { 0 }, different = { 0 }; + GValue value = G_VALUE_INIT; + GValue same = G_VALUE_INIT; + GValue different = G_VALUE_INIT; g_value_set_int (g_value_init (&value, G_TYPE_INT), -42); g_value_set_int (g_value_init (&same, G_TYPE_INT), -42); @@ -103,7 +105,9 @@ test_numeric (void) static void test_string (void) { - GValue value = { 0 }, same = { 0 }, different = { 0 }; + GValue value = G_VALUE_INIT; + GValue same = G_VALUE_INIT; + GValue different = G_VALUE_INIT; g_value_init (&value, G_TYPE_STRING); g_value_init (&same, G_TYPE_STRING); @@ -132,7 +136,9 @@ test_string (void) static void test_object_path (void) { - GValue value = { 0 }, same = { 0 }, different = { 0 }; + GValue value = G_VALUE_INIT; + GValue same = G_VALUE_INIT; + GValue different = G_VALUE_INIT; g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH); g_value_init (&same, DBUS_TYPE_G_OBJECT_PATH); @@ -154,7 +160,9 @@ test_strv (void) const gchar * const empty[] = { NULL }; const gchar * const small[] = { "foo", "bar", NULL }; const gchar * const large[] = { "foo", "bar", "baz", NULL }; - GValue value = { 0 }, same = { 0 }, different = { 0 }; + GValue value = G_VALUE_INIT; + GValue same = G_VALUE_INIT; + GValue different = G_VALUE_INIT; g_value_init (&value, G_TYPE_STRV); g_value_init (&same, G_TYPE_STRV); diff --git a/util/Makefile.am b/util/Makefile.am index 69832a53..f506dd22 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -3,15 +3,15 @@ AM_CPPFLAGS = \ $(DBUS_CFLAGS) \ $(LIBFFI_CFLAGS) \ $(GLIB_CFLAGS) \ - $(GIO_CFLAGS) \ - $(TELEPATHY_CFLAGS) + $(TELEPATHY_CFLAGS) \ + $(NULL) LDADD = \ $(LIBFFI_LIBS) \ $(GLIB_LIBS) \ $(DBUS_LIBS) \ $(TELEPATHY_LIBS) \ - $(GIO_LIBS) + $(NULL) AM_CFLAGS = $(ERROR_CFLAGS) diff --git a/util/mc-tool.c b/util/mc-tool.c index 1a114881..3e5445fd 100644 --- a/util/mc-tool.c +++ b/util/mc-tool.c @@ -22,6 +22,8 @@ * */ +#include "config.h" + #include <stdlib.h> #include <string.h> #include <stdio.h> @@ -43,6 +45,7 @@ show_help (gchar * err) printf ("Usage:\n" " %1$s list\n" " %1$s summary\n" + " %1$s dump\n" " %1$s add <manager>/<protocol> <display name> [<param> ...]\n" " %1$s update <account name> [<param>|clear:key] ...\n" " %1$s display <account name> <display name>\n" @@ -320,10 +323,7 @@ show_uri_schemes (const gchar * const *schemes) int result; gchar *tmp; - if (schemes == NULL || schemes[0] == NULL) - tmp = g_strdup (""); - else - tmp = g_strjoinv (", ", (gchar **) schemes); + tmp = g_strjoinv (", ", (gchar **) schemes); result = printf ("%12s: %s\n", "URIScheme", tmp); @@ -682,6 +682,36 @@ command_remove (TpAccount *account) return TRUE; } +static gchar * +dup_storage_restrictions (TpAccount *account) +{ + TpStorageRestrictionFlags flags; + GPtrArray *tmp; + gchar *result; + + flags = tp_account_get_storage_restrictions (account); + if (flags == 0) + return g_strdup ("(none)"); + + tmp = g_ptr_array_new (); + + if (flags & TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PARAMETERS) + g_ptr_array_add (tmp, "Cannot_Set_Parameters"); + if (flags & TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_ENABLED) + g_ptr_array_add (tmp, "Cannot_Set_Enabled"); + if (flags & TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PRESENCE) + g_ptr_array_add (tmp, "Cannot_Set_Presence"); + if (flags & TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_SERVICE) + g_ptr_array_add (tmp, "Cannot_Set_Service"); + + g_ptr_array_add (tmp, NULL); + + result = g_strjoinv (", ", (gchar **) tmp->pdata); + + g_ptr_array_unref (tmp); + return result; +} + static gboolean command_show (TpAccount *account) { @@ -690,6 +720,8 @@ command_show (TpAccount *account) gpointer keyp, valuep; struct presence automatic, current, requested; const gchar * const *schemes; + const gchar *storage_provider; + const gchar * const *supersedes; show ("Account", tp_account_get_path_suffix (account)); show ("Display Name", tp_account_get_display_name (account)); @@ -726,10 +758,50 @@ command_show (TpAccount *account) show ("Changing", tp_account_get_changing_presence (account) ? "yes" : "no"); - puts (""); - puts ("Addressing:"); schemes = tp_account_get_uri_schemes (account); - show_uri_schemes (schemes); + if (schemes != NULL && schemes[0] != NULL) + { + puts (""); + puts ("Addressing:"); + + show_uri_schemes (schemes); + } + + storage_provider = tp_account_get_storage_provider (account); + if (!tp_str_empty (storage_provider)) + { + GVariant *storage_identifier; + gchar *storage_restrictions; + + puts (""); + puts ("Storage:"); + show ("Provider", storage_provider); + + storage_identifier = tp_account_dup_storage_identifier_variant ( + account); + if (storage_identifier != NULL) + { + gchar *tmp = g_variant_print (storage_identifier, TRUE); + + show ("Identifier", tmp); + + g_free (tmp); + g_variant_unref (storage_identifier); + } + + storage_restrictions = dup_storage_restrictions (account); + show ("Restrictions", storage_restrictions); + g_free (storage_restrictions); + } + + supersedes = tp_account_get_supersedes (account); + if (supersedes != NULL && supersedes[0] != NULL) + { + puts (""); + puts ("Supersedes:"); + for (; *supersedes != NULL; supersedes++) + printf (" %s\n", *supersedes + strlen (TP_ACCOUNT_OBJECT_PATH_BASE)); + } puts (""); parameters = tp_account_get_parameters (account); @@ -745,6 +817,30 @@ command_show (TpAccount *account) } static gboolean +command_dump (TpAccountManager *manager) +{ + GList *accounts, *l; + + accounts = tp_account_manager_get_valid_accounts (manager); + if (accounts == NULL) { + return FALSE; + } + command.common.ret = 0; + + for (l = accounts; l != NULL; l = l->next) { + TpAccount *account = TP_ACCOUNT (l->data); + + command_show (account); + + if (l->next != NULL) + printf ("\n------------------------------------------------------------\n\n"); + } + + g_list_free (accounts); + return FALSE; /* stop mainloop */ +} + +static gboolean command_connection (TpAccount *account) { TpConnection *conn; @@ -1028,6 +1124,14 @@ parse (int argc, char **argv) command.ready.manager = command_summary; } + else if (strcmp (argv[1], "dump") == 0) + { + /* Dump all accounts */ + if (argc != 2) + show_help ("Invalid dump command."); + + command.ready.manager = command_dump; + } else if (strcmp (argv[1], "remove") == 0 || strcmp (argv[1], "delete") == 0) { @@ -1306,6 +1410,8 @@ main (int argc, char **argv) TpAccount *a = NULL; TpDBusDaemon *dbus = NULL; GError *error = NULL; + const GQuark features[] = { TP_ACCOUNT_FEATURE_CORE, + TP_ACCOUNT_FEATURE_ADDRESSING, TP_ACCOUNT_FEATURE_STORAGE, 0 }; g_type_init (); @@ -1323,11 +1429,16 @@ main (int argc, char **argv) } if (command.common.account == NULL) { + TpSimpleClientFactory *factory; + am = tp_account_manager_new (dbus); + factory = tp_proxy_get_factory (am); + + tp_simple_client_factory_add_account_features (factory, features); + tp_proxy_prepare_async (am, NULL, manager_ready, NULL); } else { - const GQuark features[] = { TP_ACCOUNT_FEATURE_CORE, TP_ACCOUNT_FEATURE_ADDRESSING, 0 }; command.common.account = ensure_prefix (command.common.account); a = tp_account_new (dbus, command.common.account, &error); diff --git a/xml/Account_Interface_Addressing.xml b/xml/Account_Interface_Addressing.xml deleted file mode 100644 index 2241fb83..00000000 --- a/xml/Account_Interface_Addressing.xml +++ /dev/null @@ -1,76 +0,0 @@ -<?xml version="1.0" ?> -<node name="/Account_Interface_Addressing" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> - <tp:copyright>Copyright © 2010 Collabora Ltd</tp:copyright> - <tp:license xmlns="http://www.w3.org/1999/xhtml"> - <p>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.</p> - -<p>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.</p> - -<p>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.</p> - </tp:license> - <interface name="org.freedesktop.Telepathy.Account.Interface.Addressing"> - <tp:requires interface="org.freedesktop.Telepathy.Account"/> - <tp:added version="0.21.UNRELEASED">(as stable api)</tp:added> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>Some accounts can be used for multiple protocols; for instance, SIP - and Skype accounts can often be used to contact the PSTN, MSN and - Yahoo accounts can contact each other, and XMPP accounts can - potentially contact many protocols via a transport.</p> - <p>However, if the user does not intend to make use of this functionality, - user interfaces can improve clarity by not displaying it: for instance, - if a user prefers to call phone numbers via a particular SIP account, - when an address book displays a contact with a phone number, it is - desirable to display a "call with SIP" button for that account, but - avoid displaying similar buttons for any other configured SIP or - Skype accounts.</p> - <p>The purpose of this interface is to allow this "for use with" information - to be recorded and retrieved.</p> - </tp:docstring> - - <property name="URISchemes" type="as" access="read" - tp:name-for-bindings="URI_Schemes"> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>A list of fields indicating the type of URI addressing scheme - the the account should be used for (eg 'tel') indicating the - account is intended for use by applications offering a telephony - UI, or 'sip' or 'xmpp' for those protocols</p> - <p>Note that these fields signify intent, not ability: It is - entirely possible that an account which can be used for a - given URI scheme is not wanted for it by the user, and - therefore not flagged as such in this field.</p> - </tp:docstring> - </property> - - <method name="SetURISchemeAssociation" - tp:name-for-bindings="Set_URI_Scheme_Association"> - <tp:docstring> - <p>Associate (or disassociate) an account with a particular - URI addressing scheme, (such as 'tel' for telephony)</p> - </tp:docstring> - - <arg name="URI_Scheme" direction="in" type="s"> - <tp:docstring> - <p>URI scheme to associate/disassociate the account with/from</p> - </tp:docstring> - </arg> - - <arg name="Association" direction="in" type="b"> - <tp:docstring> - <p>True to associate this account with a given addressing scheme</p> - <p>False if the account should not be associated with said scheme</p> - </tp:docstring> - </arg> - - </method> - - </interface> -</node> -<!-- vim:set sw=2 sts=2 et ft=xml: --> diff --git a/xml/Account_Interface_Compat.xml b/xml/Account_Interface_Compat.xml deleted file mode 100644 index a71650c1..00000000 --- a/xml/Account_Interface_Compat.xml +++ /dev/null @@ -1,65 +0,0 @@ -<?xml version="1.0" ?> -<node name="/Account_Interface_Compat" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> - <tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright> - <tp:license xmlns="http://www.w3.org/1999/xhtml"> - <p>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.</p> - -<p>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.</p> - -<p>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.</p> - </tp:license> - <interface name="com.nokia.Account.Interface.Compat"> - <tp:requires interface="org.freedesktop.Telepathy.Account"/> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>The Compat interface holds properties necessary for maintaining the - libmissioncontrol compatible layer.</p> - </tp:docstring> - - <property name="AvatarFile" type="s" access="read"> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>The location of the avatar.</p> - </tp:docstring> - </property> - - <property name="SecondaryVCardFields" type="as" access="readwrite"> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>List of secondary VCard fields.</p> - </tp:docstring> - </property> - - <method name="SetHasBeenOnline" - tp:name-for-bindings="Set_Has_Been_Online"> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>Force MC to believe that this account has been put online - successfully at some point in the past.</p> - </tp:docstring> - </method> - - <signal name="CompatPropertyChanged" - tp:name-for-bindings="Compat_Property_Changed"> - <tp:docstring> - The values of one or more properties on this interface may have - changed. - </tp:docstring> - - <arg name="Properties" type="a{sv}"> - <tp:docstring> - A map from property names in this namespace (e.g. - <tp:member-ref>SecondaryVCardFields</tp:member-ref>) to - values. Properties whose values have not changed SHOULD be - omitted, but this need not be done. - </tp:docstring> - </arg> - </signal> - - </interface> -</node> -<!-- vim:set sw=2 sts=2 et ft=xml: --> diff --git a/xml/Account_Manager_Interface_Query.xml b/xml/Account_Manager_Interface_Query.xml deleted file mode 100644 index e66e127b..00000000 --- a/xml/Account_Manager_Interface_Query.xml +++ /dev/null @@ -1,75 +0,0 @@ -<?xml version="1.0" ?> -<node name="/Account_Manager_Interface_Query" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> - <tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright> - <tp:license xmlns="http://www.w3.org/1999/xhtml"> - <p>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.</p> - -<p>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.</p> - -<p>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.</p> - </tp:license> - <interface name="com.nokia.AccountManager.Interface.Query"> - <tp:requires interface="org.freedesktop.Telepathy.AccountManager"/> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>The Query interface provides a convienient way for clients to retrieve - a subset of the accounts satisfying certain conditions.</p> - - <tp:rationale> - <p>This is basically the same API proposed by Zdra</p> - </tp:rationale> - </tp:docstring> - - <method name="FindAccounts" - tp:name-for-bindings="Find_Accounts"> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>Find all accounts which match the search query.</p> - <p>An empty parameter should return all accounts</p> - </tp:docstring> - - <arg direction="in" name="params" type="a{sv}" tp:type="String_Variant_Map"> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - <p>The search query data. The keys can be any Connection Manager - parameter (in which case they must be prepended with the string - "param-"), any readable Account property (in the form - <code>Interface.PropertyName</code>) or any of these special - keys:</p> - <ul> - <li>s: Manager</li> - <li>s: Protocol</li> - <li>u: RequestedPresence</li> - <li>s: RequestedStatus</li> - <li>u: CurrentPresence</li> - <li>s: CurrentStatus</li> - </ul> - </tp:docstring> - </arg> - <arg direction="out" name="accounts" type="ao"> - <tp:docstring xmlns="http://www.w3.org/1999/xhtml"> - The array of account objects. - </tp:docstring> - </arg> - </method> - - <property name="Keywords" type="as" access="read"> - <tp:docstring> - A list of the special keywords recognized by the FindAccounts method. - <tp:rationale> - <p>It's likely that some new keywords will be added later, or that - different implementation of this interface will support a different - set of keywords; in such a scenario it seems proper to inform the - client about supported keywords.</p> - <p>But I'm not sure this is really needed.</p> - </tp:rationale> - </tp:docstring> - </property> - </interface> -</node> -<!-- vim:set sw=2 sts=2 et ft=xml: --> diff --git a/xml/Makefile.am b/xml/Makefile.am index 9bd31773..50ef1d51 100644 --- a/xml/Makefile.am +++ b/xml/Makefile.am @@ -6,9 +6,6 @@ DROP_TPTYPE = sed -e 's@tp:type="[^"]*"@@g' SPECS = \ Account_Manager_Interface_Hidden.xml \ - Account_Manager_Interface_Query.xml \ - Account_Interface_Addressing.xml \ - Account_Interface_Compat.xml \ Account_Interface_Conditions.xml \ Account_Interface_External_Password_Storage.xml \ Account_Interface_Hidden.xml \ diff --git a/xml/nmc5.xml b/xml/nmc5.xml index 212559f7..130fd3f3 100644 --- a/xml/nmc5.xml +++ b/xml/nmc5.xml @@ -4,13 +4,10 @@ <tp:copyright>Copyright (C) 2008 Nokia Corporation</tp:copyright> -<xi:include href="Account_Interface_Addressing.xml"/> -<xi:include href="Account_Interface_Compat.xml"/> <xi:include href="Account_Interface_Conditions.xml"/> <xi:include href="Account_Interface_External_Password_Storage.xml"/> <xi:include href="Account_Interface_Hidden.xml"/> <xi:include href="Account_Manager_Interface_Hidden.xml"/> -<xi:include href="Account_Manager_Interface_Query.xml"/> <xi:include href="Connection_Manager_Interface_Account_Storage.xml"/> |