1 /* vi:set et ai sw=2 sts=2 ts=2: */
3 * Copyright (c) 2012 GENIVI.
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/.
14 #include <glib-object.h>
16 #include <glib-unix.h>
18 #include <systemd/sd-daemon.h>
22 #include <common/watchdog-client.h>
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>
33 DLT_IMPORT_CONTEXT (boot_manager_context);
37 /* property identifiers */
43 PROP_BOOT_MANAGER_SERVICE,
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,
56 static void boot_manager_application_set_property (GObject *object,
60 static void boot_manager_application_startup (GApplication *application);
61 static gboolean boot_manager_application_sigint_handler (GApplication *application);
65 struct _BootManagerApplicationClass
67 GApplicationClass __parent__;
70 struct _BootManagerApplication
72 GApplication __parent__;
74 /* the connection to D-Bus */
75 GDBusConnection *connection;
77 /* systemd watchdog client that repeatedly asks systemd to update
78 * the watchdog timestamp */
79 WatchdogClient *watchdog_client;
81 /* internal handler of Start() and Stop() jobs */
82 JobManager *job_manager;
84 /* boot manager service */
85 BootManagerService *boot_manager_service;
87 /* LUC starter to restore the LUC */
88 LUCStarter *luc_starter;
90 /* signal handler IDs */
93 /* Legacy App Handler to register apps with the Node State Manager */
94 LAHandlerService *la_handler;
96 /* Identifier for the registered bus name */
102 G_DEFINE_TYPE (BootManagerApplication, boot_manager_application, G_TYPE_APPLICATION);
107 boot_manager_application_class_init (BootManagerApplicationClass *klass)
109 GApplicationClass *gapplication_class;
110 GObjectClass *gobject_class;
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;
118 gapplication_class = G_APPLICATION_CLASS (klass);
119 gapplication_class->startup = boot_manager_application_startup;
121 g_object_class_install_property (gobject_class,
123 g_param_spec_object ("connection",
125 "The connection to D-Bus",
126 G_TYPE_DBUS_CONNECTION,
128 G_PARAM_CONSTRUCT_ONLY |
129 G_PARAM_STATIC_STRINGS));
131 g_object_class_install_property (gobject_class,
133 g_param_spec_object ("job-manager",
135 "The internal handler of Start()"
139 G_PARAM_CONSTRUCT_ONLY |
140 G_PARAM_STATIC_STRINGS));
142 g_object_class_install_property (gobject_class,
144 g_param_spec_object ("la-handler",
146 "Legacy Application Handler",
147 LA_HANDLER_TYPE_SERVICE,
149 G_PARAM_CONSTRUCT_ONLY |
150 G_PARAM_STATIC_STRINGS));
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,
159 G_PARAM_CONSTRUCT_ONLY |
160 G_PARAM_STATIC_STRINGS));
162 g_object_class_install_property (gobject_class,
164 g_param_spec_object ("luc-starter",
169 G_PARAM_STATIC_STRINGS));
175 boot_manager_application_init (BootManagerApplication *application)
177 /* update systemd's watchdog timestamp every 120 seconds */
178 application->watchdog_client = watchdog_client_new (120);
180 /* install the signal handler */
181 application->sigint_id =
182 g_unix_signal_add (SIGINT, (GSourceFunc) boot_manager_application_sigint_handler,
189 boot_manager_application_finalize (GObject *object)
191 BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
193 /* release the bus name */
194 g_bus_unown_name (application->bus_name_id);
196 /* release the D-Bus connection object */
197 if (application->connection != NULL)
198 g_object_unref (application->connection);
200 /* release the signal handler */
201 g_source_remove (application->sigint_id);
203 /* release the watchdog client */
204 g_object_unref (application->watchdog_client);
206 /* release the boot manager */
207 g_object_unref (application->boot_manager_service);
209 /* release the LUC starter */
210 g_object_unref (application->luc_starter);
212 /* release the legacy app handler */
213 g_object_unref (application->la_handler);
215 /* release the job manager */
216 g_object_unref (application->job_manager);
218 (*G_OBJECT_CLASS (boot_manager_application_parent_class)->finalize) (object);
224 boot_manager_application_constructed (GObject *object)
226 BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
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);
233 /* instantiate the LUC starter */
234 application->luc_starter = luc_starter_new (application->job_manager,
235 application->boot_manager_service);
241 boot_manager_application_get_property (GObject *object,
246 BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
250 case PROP_CONNECTION:
251 g_value_set_object (value, application->connection);
253 case PROP_JOB_MANAGER:
254 g_value_set_object (value, application->job_manager);
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);
261 case PROP_LUC_STARTER:
262 g_value_set_object (value, application->luc_starter);
265 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
273 boot_manager_application_set_property (GObject *object,
278 BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
282 case PROP_CONNECTION:
283 application->connection = g_value_dup_object (value);
285 case PROP_JOB_MANAGER:
286 application->job_manager = g_value_dup_object (value);
288 case PROP_BOOT_MANAGER_SERVICE:
289 application->boot_manager_service = g_value_dup_object (value);
291 case PROP_LA_HANDLER:
292 application->la_handler = g_value_dup_object (value);
295 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
303 boot_manager_application_startup (GApplication *app)
305 BootManagerApplication *application = BOOT_MANAGER_APPLICATION (app);
306 GError *error = NULL;
309 /* chain up to the parent class */
310 (*G_APPLICATION_CLASS (boot_manager_application_parent_class)->startup) (app);
312 /* start the boot manager service */
313 boot_manager_service_start_up (application->boot_manager_service, &error);
317 log_text = g_strdup_printf ("Error starting boot manager service: %s",
319 DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text));
323 /* restore the LUC if desired */
324 luc_starter_start_groups (application->luc_starter);
326 /* start the legacy app handler */
327 la_handler_service_start (application->la_handler, &error);
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));
338 /* inform systemd that this process has started */
339 sd_notify (0, "READY=1");
341 /* hold the application so that it persists */
342 g_application_hold (app);
348 boot_manager_application_sigint_handler (GApplication *app)
350 BootManagerApplication *application = BOOT_MANAGER_APPLICATION (app);
352 luc_starter_cancel (application->luc_starter);
359 BootManagerApplication *
360 boot_manager_application_new (GDBusConnection *connection,
361 JobManager *job_manager,
362 LAHandlerService *la_handler,
363 BootManagerService *boot_manager_service)
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);
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,