Update dLeyna to v0.2.1
[profile/ivi/dLeyna.git] / dleyna-core / libdleyna / core / main-loop.c
1 /*
2  * dLeyna
3  *
4  * Copyright (C) 2013 Intel Corporation. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU Lesser General Public License,
8  * version 2.1, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
13  * for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Regis Merlino <regis.merlino@intel.com>
20  *
21  */
22
23 #include <glib.h>
24 #include <string.h>
25
26 #include "connector-mgr.h"
27 #include "control-point.h"
28 #include "error.h"
29 #include "log.h"
30 #include "main-loop.h"
31 #include "settings.h"
32 #include "task-processor.h"
33
34 typedef struct dleyna_daemon_context_t_ dleyna_daemon_context_t;
35 struct dleyna_daemon_context_t_ {
36         gboolean error;
37         GMainLoop *main_loop;
38         dleyna_connector_id_t connection;
39         dleyna_task_processor_t *processor;
40         dleyna_settings_t *settings;
41         const dleyna_connector_t *connector;
42         const dleyna_control_point_t *control_point;
43 };
44
45 static dleyna_daemon_context_t g_context;
46
47 static gboolean prv_context_mainloop_quit_cb(gpointer user_data)
48 {
49         DLEYNA_LOG_DEBUG("Main loop quit");
50
51         g_main_loop_quit(g_context.main_loop);
52
53         return FALSE;
54 }
55
56 static gboolean prv_context_quit_cb(gpointer user_data)
57 {
58         DLEYNA_LOG_DEBUG("Quitting");
59
60         g_context.connector->disconnect();
61         g_context.control_point->stop_service();
62
63         g_timeout_add_seconds(1, prv_context_mainloop_quit_cb, NULL);
64
65         return FALSE;
66 }
67
68 static gboolean prv_context_init(const gchar *server,
69                                  const dleyna_control_point_t *control_point)
70 {
71         gboolean retval = TRUE;
72         const gchar *connector;
73
74         memset(&g_context, 0, sizeof(g_context));
75
76         g_context.processor = dleyna_task_processor_new(prv_context_quit_cb);
77         g_context.control_point = control_point;
78
79         dleyna_settings_new(server, &g_context.settings);
80
81         connector = dleyna_settings_connector_name(g_context.settings);
82         g_context.connector = dleyna_connector_mgr_load(connector);
83
84         if (!g_context.connector)
85                 retval = FALSE;
86
87         return retval;
88 }
89
90 static void prv_connector_acquired(dleyna_connector_id_t connection)
91 {
92         g_context.connection = connection;
93
94         if (!g_context.control_point->start_service(connection)) {
95                 g_context.error = TRUE;
96                 g_main_loop_quit(g_context.main_loop);
97         }
98 }
99
100 static void prv_name_lost(dleyna_connector_id_t connection)
101 {
102         g_context.connection = NULL;
103         dleyna_task_processor_set_quitting(g_context.processor);
104 }
105
106 static void prv_context_free(void)
107 {
108         dleyna_task_processor_free(g_context.processor);
109
110         if (g_context.connector) {
111                 g_context.connector->shutdown();
112                 dleyna_connector_mgr_release(g_context.connector);
113         }
114
115         if (g_context.main_loop)
116                 g_main_loop_unref(g_context.main_loop);
117
118         if (g_context.settings)
119                 dleyna_settings_delete(g_context.settings);
120 }
121
122 int dleyna_main_loop_start(char *server,
123                            const dleyna_control_point_t *control_point,
124                            gpointer user_data)
125 {
126         int retval = 1;
127
128 #if !GLIB_CHECK_VERSION(2, 35, 0)
129         g_type_init();
130 #endif
131
132         dleyna_log_init(server);
133
134         if (!prv_context_init(server, control_point))
135                 goto out;
136
137         if (!g_context.connector->initialize(
138                                 g_context.control_point->server_introspection(),
139                                 g_context.control_point->root_introspection(),
140                                 dleyna_error_quark(),
141                                 user_data))
142                 goto out;
143
144         g_context.main_loop = g_main_loop_new(NULL, FALSE);
145
146         g_context.connector->connect(g_context.control_point->server_name(),
147                                      prv_connector_acquired,
148                                      prv_name_lost);
149
150
151         g_context.control_point->initialize(g_context.connector,
152                                             g_context.processor,
153                                             g_context.settings);
154
155         g_main_loop_run(g_context.main_loop);
156         if (g_context.error)
157                 goto on_error;
158
159         retval = 0;
160
161 on_error:
162
163         g_context.control_point->free();
164
165 out:
166
167         prv_context_free();
168
169         dleyna_log_finalize();
170
171         return retval;
172 }
173
174 static gboolean prv_set_quitting(gpointer user_data)
175 {
176         dleyna_task_processor_set_quitting(g_context.processor);
177
178         return FALSE;
179 }
180
181 void dleyna_main_loop_quit(void)
182 {
183         g_idle_add_full(G_PRIORITY_HIGH_IDLE, prv_set_quitting, NULL, NULL);
184 }