4
* Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
6
* Copyright 2010 Canonical Ltd.
8
* This program is free software: you can redistribute it and/or modify it
9
* under the terms of the GNU General Public License version 3, as published
10
* by the Free Software Foundation.
12
* This program is distributed in the hope that it will be useful, but
13
* WITHOUT ANY WARRANTY; without even the implied warranties of
14
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15
* PURPOSE. See the GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License along
18
* with this program. If not, see <http://www.gnu.org/licenses/>.
27
#include <dbus/dbus-glib.h>
29
#include "syncdaemon-daemon.h"
30
#include "syncdaemon-config-interface.h"
31
#include "syncdaemon-events-interface.h"
32
#include "syncdaemon-filesystem-interface.h"
33
#include "syncdaemon-folders-interface.h"
34
#include "syncdaemon-publicfiles-interface.h"
35
#include "syncdaemon-shares-interface.h"
36
#include "syncdaemon-status-interface.h"
37
#include "syncdaemon-marshal.h"
39
G_DEFINE_TYPE(SyncdaemonDaemon, syncdaemon_daemon, G_TYPE_OBJECT)
41
struct _SyncdaemonDaemonPrivate {
50
GObject *daemon_interface;
51
GHashTable *subinterfaces;
65
FOLDER_CREATED_SIGNAL,
66
FOLDER_DELETED_SIGNAL,
67
FOLDER_SUBSCRIBED_SIGNAL,
68
FOLDER_UNSUBSCRIBED_SIGNAL,
71
DOWNLOAD_STARTED_SIGNAL,
72
DOWNLOAD_FINISHED_SIGNAL,
73
UPLOAD_STARTED_SIGNAL,
74
UPLOAD_FINISHED_SIGNAL,
78
static guint daemon_signals[LAST_SIGNAL] = { 0, };
81
syncdaemon_daemon_finalize (GObject *object)
83
SyncdaemonDaemon *daemon = SYNCDAEMON_DAEMON (object);
85
if (daemon->priv != NULL) {
86
g_hash_table_destroy (daemon->priv->subinterfaces);
88
if (daemon->priv->dbus_proxy != NULL)
89
g_object_unref (daemon->priv->dbus_proxy);
91
if (daemon->priv->bus != NULL) {
93
g_object_unref (G_OBJECT (daemon->priv->bus));
95
dbus_g_connection_unref (daemon->priv->bus);
99
if (daemon->priv->root_dir != NULL)
100
g_free (daemon->priv->root_dir);
102
g_free (daemon->priv);
105
G_OBJECT_CLASS (syncdaemon_daemon_parent_class)->finalize (object);
109
syncdaemon_daemon_class_init (SyncdaemonDaemonClass *klass)
111
GObjectClass *object_class = G_OBJECT_CLASS (klass);
113
object_class->finalize = syncdaemon_daemon_finalize;
115
/* Register signals */
116
daemon_signals[CONNECTED_SIGNAL] = g_signal_new ("connected",
117
G_TYPE_FROM_CLASS (klass),
118
(GSignalFlags) G_SIGNAL_RUN_LAST,
119
G_STRUCT_OFFSET (SyncdaemonDaemonClass, connected),
121
g_cclosure_marshal_VOID__VOID,
123
daemon_signals[DISCONNECTED_SIGNAL] = g_signal_new ("disconnected",
124
G_TYPE_FROM_CLASS (klass),
125
(GSignalFlags) G_SIGNAL_RUN_LAST,
126
G_STRUCT_OFFSET (SyncdaemonDaemonClass, disconnected),
128
g_cclosure_marshal_VOID__VOID,
130
daemon_signals[EVENT_SIGNAL] = g_signal_new ("event",
131
G_TYPE_FROM_CLASS (klass),
132
(GSignalFlags) G_SIGNAL_RUN_LAST,
133
G_STRUCT_OFFSET (SyncdaemonDaemonClass, event),
135
g_cclosure_marshal_VOID__POINTER,
138
daemon_signals[ERROR_SIGNAL] = g_signal_new ("error",
139
G_TYPE_FROM_CLASS (klass),
140
(GSignalFlags) G_SIGNAL_RUN_LAST,
141
G_STRUCT_OFFSET (SyncdaemonDaemonClass, error),
143
_syncdaemon_marshal_VOID__STRING_POINTER,
145
G_TYPE_STRING, G_TYPE_POINTER);
146
daemon_signals[GOT_METADATA_SIGNAL] = g_signal_new ("got_metadata",
147
G_TYPE_FROM_CLASS (klass),
148
(GSignalFlags) G_SIGNAL_RUN_LAST,
149
G_STRUCT_OFFSET (SyncdaemonDaemonClass, got_metadata),
151
_syncdaemon_marshal_VOID__STRING_POINTER,
153
G_TYPE_STRING, G_TYPE_POINTER);
154
daemon_signals[FOLDER_CREATED_SIGNAL] = g_signal_new ("folder_created",
155
G_TYPE_FROM_CLASS (klass),
156
(GSignalFlags) G_SIGNAL_RUN_LAST,
157
G_STRUCT_OFFSET (SyncdaemonDaemonClass, folder_created),
159
g_cclosure_marshal_VOID__POINTER,
162
daemon_signals[FOLDER_DELETED_SIGNAL] = g_signal_new ("folder_deleted",
163
G_TYPE_FROM_CLASS (klass),
164
(GSignalFlags) G_SIGNAL_RUN_LAST,
165
G_STRUCT_OFFSET (SyncdaemonDaemonClass, folder_deleted),
167
g_cclosure_marshal_VOID__POINTER,
170
daemon_signals[FOLDER_SUBSCRIBED_SIGNAL] = g_signal_new ("folder_subscribed",
171
G_TYPE_FROM_CLASS (klass),
172
(GSignalFlags) G_SIGNAL_RUN_LAST,
173
G_STRUCT_OFFSET (SyncdaemonDaemonClass, folder_subscribed),
175
g_cclosure_marshal_VOID__POINTER,
178
daemon_signals[FOLDER_UNSUBSCRIBED_SIGNAL] = g_signal_new ("folder_unsubscribed",
179
G_TYPE_FROM_CLASS (klass),
180
(GSignalFlags) G_SIGNAL_RUN_LAST,
181
G_STRUCT_OFFSET (SyncdaemonDaemonClass, folder_unsubscribed),
183
g_cclosure_marshal_VOID__POINTER,
186
daemon_signals[SHARE_CREATED_SIGNAL] = g_signal_new ("share_created",
187
G_TYPE_FROM_CLASS (klass),
188
(GSignalFlags) G_SIGNAL_RUN_LAST,
189
G_STRUCT_OFFSET (SyncdaemonDaemonClass, share_created),
191
g_cclosure_marshal_VOID__POINTER,
194
daemon_signals[SHARE_DELETED_SIGNAL] = g_signal_new ("share_deleted",
195
G_TYPE_FROM_CLASS (klass),
196
(GSignalFlags) G_SIGNAL_RUN_LAST,
197
G_STRUCT_OFFSET (SyncdaemonDaemonClass, share_deleted),
199
g_cclosure_marshal_VOID__POINTER,
202
daemon_signals[DOWNLOAD_STARTED_SIGNAL] = g_signal_new ("download_started",
203
G_TYPE_FROM_CLASS (klass),
204
(GSignalFlags) G_SIGNAL_RUN_LAST,
205
G_STRUCT_OFFSET (SyncdaemonDaemonClass, download_started),
207
g_cclosure_marshal_VOID__STRING,
210
daemon_signals[DOWNLOAD_FINISHED_SIGNAL] = g_signal_new ("download_finished",
211
G_TYPE_FROM_CLASS (klass),
212
(GSignalFlags) G_SIGNAL_RUN_LAST,
213
G_STRUCT_OFFSET (SyncdaemonDaemonClass, download_finished),
215
_syncdaemon_marshal_VOID__STRING_POINTER,
217
G_TYPE_STRING, G_TYPE_POINTER);
218
daemon_signals[UPLOAD_STARTED_SIGNAL] = g_signal_new ("upload_started",
219
G_TYPE_FROM_CLASS (klass),
220
(GSignalFlags) G_SIGNAL_RUN_LAST,
221
G_STRUCT_OFFSET (SyncdaemonDaemonClass, upload_started),
223
g_cclosure_marshal_VOID__STRING,
226
daemon_signals[UPLOAD_FINISHED_SIGNAL] = g_signal_new ("upload_finished",
227
G_TYPE_FROM_CLASS (klass),
228
(GSignalFlags) G_SIGNAL_RUN_LAST,
229
G_STRUCT_OFFSET (SyncdaemonDaemonClass, upload_finished),
231
_syncdaemon_marshal_VOID__STRING_POINTER,
233
G_TYPE_STRING, G_TYPE_POINTER);
237
setup_daemon_interface (SyncdaemonDaemon *daemon)
239
daemon->priv->daemon_interface = g_object_new (SYNCDAEMON_TYPE_INTERFACE,
242
syncdaemon_interface_setup_proxy (SYNCDAEMON_INTERFACE (daemon->priv->daemon_interface),
243
"com.ubuntuone.Syncdaemon", "/",
244
"com.ubuntuone.Syncdaemon.SyncDaemon");
248
name_owner_changed_cb (DBusGProxy *proxy,
250
const char *old_owner,
251
const char *new_owner,
254
SyncdaemonDaemon *daemon = SYNCDAEMON_DAEMON (user_data);
256
if (g_strcmp0 (name, "com.ubuntuone.Syncdaemon") == 0) {
257
if (new_owner != NULL && strlen (new_owner) > 0) {
258
setup_daemon_interface (daemon);
260
g_debug ("Syncdaemon service died");
261
if (daemon->priv->daemon_interface != NULL) {
262
g_object_unref (daemon->priv->daemon_interface);
263
daemon->priv->daemon_interface = NULL;
266
g_hash_table_remove_all (daemon->priv->subinterfaces);
267
daemon->priv->connected = FALSE;
273
syncdaemon_daemon_init (SyncdaemonDaemon *daemon)
275
GError *error = NULL;
277
daemon->priv = g_new0 (SyncdaemonDaemonPrivate, 1);
279
daemon->priv->connected = FALSE;
280
daemon->priv->subinterfaces = g_hash_table_new_full (g_str_hash, g_str_equal,
281
g_free, g_object_unref);
283
/* Initialize DBus */
285
daemon->priv->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
287
daemon->priv->bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
290
g_warning ("Couldn't get session bus: %s", error->message);
291
g_error_free (error);
295
/* Listen to DBus for syncdaemon restarts */
296
daemon->priv->dbus_proxy = (GObject *) dbus_g_proxy_new_for_name (daemon->priv->bus,
297
"org.freedesktop.DBus",
298
"/org/freedesktop/DBus",
299
"org.freedesktop.DBus");
300
dbus_g_proxy_add_signal (DBUS_G_PROXY (daemon->priv->dbus_proxy), "NameOwnerChanged",
301
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
303
dbus_g_proxy_connect_signal (DBUS_G_PROXY (daemon->priv->dbus_proxy),
305
G_CALLBACK (name_owner_changed_cb),
308
/* Get the main interface */
309
setup_daemon_interface (daemon);
313
* syncdaemon_daemon_new:
315
* Create a new #SyncdaemonDaemon object, which provides access to the
318
* Return value: A new #SyncdaemonDaemon object.
321
syncdaemon_daemon_new (void)
323
return g_object_new (SYNCDAEMON_TYPE_DAEMON, NULL);
327
connect_response_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
329
GError *error = NULL;
330
SyncdaemonDaemon *daemon = (SyncdaemonDaemon *) user_data;
332
if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
333
daemon->priv->connected = TRUE;
334
g_signal_emit (daemon, daemon_signals[CONNECTED_SIGNAL], 0);
336
g_warning ("Syncdaemon cannot connect: %s", error->message);
337
g_error_free (error);
342
* syncdaemon_daemon_connect:
345
syncdaemon_daemon_connect (SyncdaemonDaemon *daemon)
349
g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), FALSE);
351
proxy = syncdaemon_interface_get_proxy_object (SYNCDAEMON_INTERFACE (daemon->priv->daemon_interface));
355
if (!dbus_g_proxy_begin_call (DBUS_G_PROXY (proxy), "connect",
356
connect_response_cb, daemon, NULL,
358
g_warning ("Call to 'connect' method failed");
369
disconnect_response_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
371
GError *error = NULL;
372
SyncdaemonDaemon *daemon = (SyncdaemonDaemon *) user_data;
374
if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
375
daemon->priv->connected = FALSE;
376
g_signal_emit (daemon, daemon_signals[DISCONNECTED_SIGNAL], 0);
378
g_warning ("Syncdaemon cannot disconnect: %s", error->message);
379
g_error_free (error);
384
* syncdaemon_daemon_interface_disconnect:
387
syncdaemon_daemon_disconnect (SyncdaemonDaemon *daemon)
391
g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), FALSE);
393
proxy = syncdaemon_interface_get_proxy_object (SYNCDAEMON_INTERFACE (daemon->priv->daemon_interface));
397
if (!dbus_g_proxy_begin_call (DBUS_G_PROXY (proxy), "disconnect",
398
disconnect_response_cb, daemon, NULL,
400
g_warning ("Call to 'disconnect' method failed");
411
* syncdaemon_daemon_interface_quit:
414
syncdaemon_daemon_quit (SyncdaemonDaemon *daemon)
418
g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), FALSE);
420
proxy = syncdaemon_interface_get_proxy_object (SYNCDAEMON_INTERFACE (daemon->priv->daemon_interface));
422
GError *error = NULL;
426
if (!dbus_g_proxy_call (DBUS_G_PROXY (proxy), "quit", &error,
429
g_warning ("Could not quit syncdaemon: %s", error->message);
430
g_error_free (error);
441
* syncdaemon_daemon_get_root_dir:
444
syncdaemon_daemon_get_root_dir (SyncdaemonDaemon *daemon)
448
g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL);
450
if (daemon->priv->root_dir != NULL)
451
return (const gchar *) daemon->priv->root_dir;
453
proxy = syncdaemon_interface_get_proxy_object (SYNCDAEMON_INTERFACE (daemon->priv->daemon_interface));
456
GError *error = NULL;
460
if (!dbus_g_proxy_call (DBUS_G_PROXY (proxy), "get_root_dir", &error,
462
G_TYPE_STRING, &new_root_dir,
464
g_warning ("Could not get syncdaemon's root dir: %s", error->message);
465
g_error_free (error);
471
daemon->priv->root_dir = new_root_dir;
477
static SyncdaemonInterface *
478
get_interface (SyncdaemonDaemon *daemon, const gchar *path, SyncdaemonInterface * (* new_func) (SyncdaemonDaemon *daemon))
480
SyncdaemonInterface *interface;
482
interface = g_hash_table_lookup (daemon->priv->subinterfaces, path);
483
if (interface == NULL) {
484
interface = new_func (daemon);
485
if (SYNCDAEMON_IS_INTERFACE (interface))
486
g_hash_table_insert (daemon->priv->subinterfaces, g_strdup (path), interface);
493
* syncdaemon_daemon_get_config_interface:
495
SyncdaemonInterface *
496
syncdaemon_daemon_get_config_interface (SyncdaemonDaemon *daemon)
498
g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL);
500
return get_interface (daemon, "/config", syncdaemon_config_interface_new);
504
* syncdaemon_daemon_get_events_interface:
506
SyncdaemonInterface *
507
syncdaemon_daemon_get_events_interface (SyncdaemonDaemon *daemon)
509
g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL);
511
return get_interface (daemon, "/events", syncdaemon_events_interface_new);
515
* syncdaemon_daemon_get_filesystem_interface:
517
SyncdaemonInterface *
518
syncdaemon_daemon_get_filesystem_interface (SyncdaemonDaemon *daemon)
520
g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL);
522
return get_interface (daemon, "/filesystem", syncdaemon_filesystem_interface_new);
526
* syncdaemon_daemon_get_folders_interface:
528
SyncdaemonInterface *
529
syncdaemon_daemon_get_folders_interface (SyncdaemonDaemon *daemon)
531
g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL);
533
return get_interface (daemon, "/folders", syncdaemon_folders_interface_new);
537
* syncdaemon_daemon_get_publicfiles_interface:
539
SyncdaemonInterface *
540
syncdaemon_daemon_get_publicfiles_interface (SyncdaemonDaemon *daemon)
542
g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL);
544
return get_interface (daemon, "/publicfiles", syncdaemon_publicfiles_interface_new);
548
* syncdaemon_daemon_get_shares_interface:
550
SyncdaemonInterface *
551
syncdaemon_daemon_get_shares_interface (SyncdaemonDaemon *daemon)
553
g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL);
555
return get_interface (daemon, "/shares", syncdaemon_shares_interface_new);
559
* syncdaemon_daemon_get_status_interface:
561
SyncdaemonInterface *
562
syncdaemon_daemon_get_status_interface (SyncdaemonDaemon *daemon)
564
g_return_val_if_fail (SYNCDAEMON_IS_DAEMON (daemon), NULL);
566
return get_interface (daemon, "/status", syncdaemon_status_interface_new);