24
24
#include "config.h"
27
#include "libempathy/empathy-account-manager.h"
27
#include <telepathy-glib/account-manager.h>
29
29
#include "status-provider.h"
30
30
#include "status-provider-mc5.h"
31
31
#include "status-provider-mc5-marshal.h"
33
33
#include <dbus/dbus-glib.h>
34
#include <dbus/dbus-glib-bindings.h>
35
36
static gchar * sp_to_mc_map[STATUS_PROVIDER_STATUS_LAST] = {
36
37
/* STATUS_PROVIDER_STATUS_ONLINE, */ "available",
65
66
typedef struct _StatusProviderMC5Private StatusProviderMC5Private;
66
67
struct _StatusProviderMC5Private {
67
EmpathyAccountManager * manager;
68
TpAccountManager * manager;
68
69
StatusProviderStatus status;
70
DBusGProxy * dbus_proxy;
71
73
#define STATUS_PROVIDER_MC5_GET_PRIVATE(o) \
72
74
(G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5Private))
75
#define MC5_WELL_KNOWN_NAME "org.freedesktop.Telepathy.MissionControl5"
75
78
/* GObject stuff */
80
83
/* Internal Funcs */
81
84
static void set_status (StatusProvider * sp, StatusProviderStatus status);
82
85
static StatusProviderStatus get_status (StatusProvider * sp);
83
static void presence_changed (EmpathyAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp);
86
static void presence_changed (TpAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp);
87
static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderMC5 * self);
88
static void mc5_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata);
85
90
G_DEFINE_TYPE (StatusProviderMC5, status_provider_mc5, STATUS_PROVIDER_TYPE);
112
/* Build our telepathy account manager instance if we don't
115
build_eam (StatusProviderMC5 * self)
117
StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self);
118
static TpDBusDaemon *daemon = NULL;
119
GError *error = NULL;
121
if (priv->manager != NULL) {
124
/* the daemon is used to communicate via DBus */
125
daemon = tp_dbus_daemon_dup(&error);
129
g_debug("Cannot create DBus daemon: %s\n", error->message);
134
priv->manager = TP_ACCOUNT_MANAGER (g_object_new (TP_TYPE_ACCOUNT_MANAGER,
135
"dbus-daemon", daemon,
136
"dbus-connection", ((TpProxy *) daemon)->dbus_connection,
137
"bus-name", "org.freedesktop.Telepathy.MissionControl5",
138
"object-path", "/org/freedesktop/Telepathy/AccountManager",
140
g_signal_connect(G_OBJECT(priv->manager), "most-available-presence-changed", G_CALLBACK(presence_changed), self);
107
145
/* Creating an instance of the status provider. We set the variables
108
and create an EmpathyAccountManager object. It does all the hard
146
and create an TpAccountManager object. It does all the hard
109
147
work in this module of tracking MissionControl and enumerating the
110
148
accounts and all that jazz. */
116
154
priv->status = STATUS_PROVIDER_STATUS_DISCONNECTED;
117
155
priv->manager = NULL;
119
g_signal_connect(G_OBJECT(priv->manager), "global-presence-changed", G_CALLBACK(presence_changed), self);
157
DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
158
g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this,
159
all non-DBus stuff should be done */
161
GError * error = NULL;
163
/* Set up the dbus Proxy */
164
priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus,
170
g_warning("Unable to connect to DBus events: %s", error->message);
175
/* Configure the name owner changing */
176
dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged",
177
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
179
dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged",
180
G_CALLBACK(dbus_namechange),
183
org_freedesktop_DBus_name_has_owner_async(priv->dbus_proxy, MC5_WELL_KNOWN_NAME, mc5_exists_cb, self);
218
/* Watch for MC5 Coming on and off the bus. */
220
dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderMC5 * self)
222
/* g_debug("DBUS NAMECHANGE: %s %s %s", name, prev, new); */
224
if (prev[0] == '\0' && g_strcmp0(name, MC5_WELL_KNOWN_NAME) == 0) {
225
g_debug("MC5 Coming online");
228
if (new[0] == '\0' && g_strcmp0(name, MC5_WELL_KNOWN_NAME) == 0) {
229
g_debug("MC5 going offline");
230
StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self);
231
if (priv->manager != NULL) {
232
g_object_unref(priv->manager);
233
priv->manager = NULL;
236
priv->status = STATUS_PROVIDER_STATUS_DISCONNECTED;
237
g_signal_emit(G_OBJECT(self), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, priv->status, TRUE);
243
/* Callback for the Dbus command to do HasOwner on
244
the MC5 service. If it exists, we want to have an
247
mc5_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata)
250
g_warning("Unable to check if MC5 is running: %s", error->message);
255
build_eam(STATUS_PROVIDER_MC5(userdata));
150
262
status_provider_mc5_new:
168
280
set_status (StatusProvider * sp, StatusProviderStatus status)
170
282
StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp);
171
if (priv->manager == NULL) {
172
priv->manager = EMPATHY_ACCOUNT_MANAGER(g_object_new(EMPATHY_TYPE_ACCOUNT_MANAGER, NULL));
175
empathy_account_manager_request_global_presence(priv->manager, sp_to_tp_map[status], sp_to_mc_map[status], "");
284
build_eam(STATUS_PROVIDER_MC5(sp));
285
tp_account_manager_set_all_requested_presences(priv->manager, sp_to_tp_map[status], sp_to_mc_map[status], "");
192
302
return priv->status;
195
/* A signal handler for when the EmpatyAccountManager believes
305
/* A signal handler for when the TpAccountManager believes
196
306
that the global status has changed. It roughly calculates this
197
307
by finding the most available of all accounts that are active. */
199
presence_changed (EmpathyAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp)
309
presence_changed (TpAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp)
201
311
StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp);