5124dfca0d9242eb5368631b5b5a727da704bdc1
[profile/ivi/node-startup-controller.git] / boot-manager / boot-manager-application.c
1 /* vi:set et ai sw=2 sts=2 ts=2: */
2 /* -
3  * Copyright (c) 2012 GENIVI.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #include <glib-object.h>
15 #include <gio/gio.h>
16 #include <glib-unix.h>
17
18 #include <systemd/sd-daemon.h>
19
20 #include <dlt/dlt.h>
21
22 #include <common/watchdog-client.h>
23
24 #include <boot-manager/boot-manager-application.h>
25 #include <boot-manager/boot-manager-service.h>
26 #include <boot-manager/job-manager.h>
27 #include <boot-manager/la-handler-service.h>
28 #include <boot-manager/luc-starter.h>
29
30
31
32
33 DLT_IMPORT_CONTEXT (boot_manager_context);
34
35
36
37 /* property identifiers */
38 enum
39 {
40   PROP_0,
41   PROP_CONNECTION,
42   PROP_JOB_MANAGER,
43   PROP_BOOT_MANAGER_SERVICE,
44   PROP_LUC_STARTER,
45   PROP_LA_HANDLER,
46 };
47
48
49
50 static void     boot_manager_application_finalize       (GObject      *object);
51 static void     boot_manager_application_constructed    (GObject      *object);
52 static void     boot_manager_application_get_property   (GObject      *object,
53                                                          guint         prop_id,
54                                                          GValue       *value,
55                                                          GParamSpec   *pspec);
56 static void     boot_manager_application_set_property   (GObject      *object,
57                                                          guint         prop_id,
58                                                          const GValue *value,
59                                                          GParamSpec   *pspec);
60 static void     boot_manager_application_startup        (GApplication *application);
61 static gboolean boot_manager_application_sigint_handler (GApplication *application);
62
63
64
65 struct _BootManagerApplicationClass
66 {
67   GApplicationClass __parent__;
68 };
69
70 struct _BootManagerApplication
71 {
72   GApplication        __parent__;
73
74   /* the connection to D-Bus */
75   GDBusConnection    *connection;
76
77   /* systemd watchdog client that repeatedly asks systemd to update
78    * the watchdog timestamp */
79   WatchdogClient     *watchdog_client;
80
81   /* internal handler of Start() and Stop() jobs */
82   JobManager         *job_manager;
83
84   /* boot manager service */
85   BootManagerService *boot_manager_service;
86
87   /* LUC starter to restore the LUC */
88   LUCStarter         *luc_starter;
89
90   /* signal handler IDs */
91   guint               sigint_id;
92
93   /* Legacy App Handler to register apps with the Node State Manager */
94   LAHandlerService   *la_handler;
95
96   /* Identifier for the registered bus name */
97   guint               bus_name_id;
98 };
99
100
101
102 G_DEFINE_TYPE (BootManagerApplication, boot_manager_application, G_TYPE_APPLICATION);
103
104
105
106 static void
107 boot_manager_application_class_init (BootManagerApplicationClass *klass)
108 {
109   GApplicationClass *gapplication_class;
110   GObjectClass *gobject_class;
111
112   gobject_class = G_OBJECT_CLASS (klass);
113   gobject_class->finalize = boot_manager_application_finalize;
114   gobject_class->constructed = boot_manager_application_constructed;
115   gobject_class->get_property = boot_manager_application_get_property;
116   gobject_class->set_property = boot_manager_application_set_property;
117
118   gapplication_class = G_APPLICATION_CLASS (klass);
119   gapplication_class->startup = boot_manager_application_startup;
120
121   g_object_class_install_property (gobject_class,
122                                    PROP_CONNECTION,
123                                    g_param_spec_object ("connection",
124                                                         "D-Bus Connection",
125                                                         "The connection to D-Bus",
126                                                         G_TYPE_DBUS_CONNECTION,
127                                                         G_PARAM_READWRITE |
128                                                         G_PARAM_CONSTRUCT_ONLY |
129                                                         G_PARAM_STATIC_STRINGS));
130
131   g_object_class_install_property (gobject_class,
132                                    PROP_JOB_MANAGER,
133                                    g_param_spec_object ("job-manager",
134                                                         "Job Manager",
135                                                         "The internal handler of Start()"
136                                                         " and Stop() jobs",
137                                                         TYPE_JOB_MANAGER,
138                                                         G_PARAM_READWRITE |
139                                                         G_PARAM_CONSTRUCT_ONLY |
140                                                         G_PARAM_STATIC_STRINGS));
141
142   g_object_class_install_property (gobject_class,
143                                    PROP_LA_HANDLER,
144                                    g_param_spec_object ("la-handler",
145                                                         "LA Handler",
146                                                         "Legacy Application Handler",
147                                                         LA_HANDLER_TYPE_SERVICE,
148                                                         G_PARAM_READWRITE |
149                                                         G_PARAM_CONSTRUCT_ONLY |
150                                                         G_PARAM_STATIC_STRINGS));
151
152   g_object_class_install_property (gobject_class,
153                                    PROP_BOOT_MANAGER_SERVICE,
154                                    g_param_spec_object ("boot-manager-service",
155                                                         "boot-manager-service",
156                                                         "boot-manager-service",
157                                                         BOOT_MANAGER_TYPE_SERVICE,
158                                                         G_PARAM_READWRITE |
159                                                         G_PARAM_CONSTRUCT_ONLY |
160                                                         G_PARAM_STATIC_STRINGS));
161
162   g_object_class_install_property (gobject_class,
163                                    PROP_LUC_STARTER,
164                                    g_param_spec_object ("luc-starter",
165                                                         "luc-starter",
166                                                         "luc-starter",
167                                                         TYPE_LUC_STARTER,
168                                                         G_PARAM_READABLE |
169                                                         G_PARAM_STATIC_STRINGS));
170 }
171
172
173
174 static void
175 boot_manager_application_init (BootManagerApplication *application)
176 {
177   /* update systemd's watchdog timestamp every 120 seconds */
178   application->watchdog_client = watchdog_client_new (120);
179
180   /* install the signal handler */
181   application->sigint_id =
182     g_unix_signal_add (SIGINT, (GSourceFunc) boot_manager_application_sigint_handler,
183                        application);
184 }
185
186
187
188 static void
189 boot_manager_application_finalize (GObject *object)
190 {
191   BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
192
193   /* release the bus name */
194   g_bus_unown_name (application->bus_name_id);
195
196   /* release the D-Bus connection object */
197   if (application->connection != NULL)
198     g_object_unref (application->connection);
199
200   /* release the signal handler */
201   g_source_remove (application->sigint_id);
202
203   /* release the watchdog client */
204   g_object_unref (application->watchdog_client);
205
206   /* release the boot manager */
207   g_object_unref (application->boot_manager_service);
208
209   /* release the LUC starter */
210   g_object_unref (application->luc_starter);
211
212   /* release the legacy app handler */
213   g_object_unref (application->la_handler);
214
215   /* release the job manager */
216   g_object_unref (application->job_manager);
217
218   (*G_OBJECT_CLASS (boot_manager_application_parent_class)->finalize) (object);
219 }
220
221
222
223 static void
224 boot_manager_application_constructed (GObject *object)
225 {
226   BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
227
228   /* get a bus name on the given connection */
229   application->bus_name_id =
230     g_bus_own_name_on_connection (application->connection, "org.genivi.BootManager1",
231                                   G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL);
232
233   /* instantiate the LUC starter */
234   application->luc_starter = luc_starter_new (application->job_manager,
235                                               application->boot_manager_service);
236 }
237
238
239
240 static void
241 boot_manager_application_get_property (GObject    *object,
242                                        guint       prop_id,
243                                        GValue     *value,
244                                        GParamSpec *pspec)
245 {
246   BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
247
248   switch (prop_id)
249     {
250     case PROP_CONNECTION:
251       g_value_set_object (value, application->connection);
252       break;
253     case PROP_JOB_MANAGER:
254       g_value_set_object (value, application->job_manager);
255       break;
256     case PROP_BOOT_MANAGER_SERVICE:
257       g_value_set_object (value, application->boot_manager_service);
258     case PROP_LA_HANDLER:
259       g_value_set_object (value, application->la_handler);
260       break;
261     case PROP_LUC_STARTER:
262       g_value_set_object (value, application->luc_starter);
263       break;
264     default:
265       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
266       break;
267     }
268 }
269
270
271
272 static void
273 boot_manager_application_set_property (GObject      *object,
274                                        guint         prop_id,
275                                        const GValue *value,
276                                        GParamSpec   *pspec)
277 {
278   BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
279
280   switch (prop_id)
281     {
282     case PROP_CONNECTION:
283       application->connection = g_value_dup_object (value);
284       break;
285     case PROP_JOB_MANAGER:
286       application->job_manager = g_value_dup_object (value);
287       break;
288     case PROP_BOOT_MANAGER_SERVICE:
289       application->boot_manager_service = g_value_dup_object (value);
290       break;
291     case PROP_LA_HANDLER:
292       application->la_handler = g_value_dup_object (value);
293       break;
294     default:
295       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
296       break;
297     }
298 }
299
300
301
302 static void
303 boot_manager_application_startup (GApplication *app)
304 {
305   BootManagerApplication *application = BOOT_MANAGER_APPLICATION (app);
306   GError                 *error = NULL;
307   gchar                  *log_text;
308
309   /* chain up to the parent class */
310   (*G_APPLICATION_CLASS (boot_manager_application_parent_class)->startup) (app);
311
312   /* start the boot manager service */
313   boot_manager_service_start_up (application->boot_manager_service, &error);
314
315   if (error != NULL)
316     {
317       log_text = g_strdup_printf ("Error starting boot manager service: %s",
318                                   error->message);
319       DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text));
320       g_free (log_text);
321     }
322
323   /* restore the LUC if desired */
324   luc_starter_start_groups (application->luc_starter);
325
326   /* start the legacy app handler */
327   la_handler_service_start (application->la_handler, &error);
328
329   if (error != NULL)
330     {
331       log_text =
332         g_strdup_printf ("Boot Manager Application failed to start the legacy app "
333                          "handler: %s", error->message);
334       DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text));
335       g_free (log_text);
336     }
337
338   /* inform systemd that this process has started */
339   sd_notify (0, "READY=1");
340
341   /* hold the application so that it persists */
342   g_application_hold (app);
343 }
344
345
346
347 static gboolean
348 boot_manager_application_sigint_handler (GApplication *app)
349 {
350   BootManagerApplication *application = BOOT_MANAGER_APPLICATION (app);
351
352   luc_starter_cancel (application->luc_starter);
353
354   return TRUE;
355 }
356
357
358
359 BootManagerApplication *
360 boot_manager_application_new (GDBusConnection    *connection,
361                               JobManager         *job_manager,
362                               LAHandlerService   *la_handler,
363                               BootManagerService *boot_manager_service)
364 {
365   g_return_val_if_fail (IS_JOB_MANAGER (job_manager), NULL);
366   g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (boot_manager_service), NULL);
367
368   return g_object_new (BOOT_MANAGER_TYPE_APPLICATION,
369                        "application-id", "org.genivi.BootManager1",
370                        "flags", G_APPLICATION_IS_SERVICE,
371                        "connection", connection,
372                        "job-manager", job_manager,
373                        "boot-manager-service", boot_manager_service,
374                        "la-handler", la_handler,
375                        NULL);
376 }