7352b80179439c9fe3b047afbcd4b886e3e14b40
[profile/ivi/node-startup-controller.git] / legacy-app-handler / la-handler-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 #ifdef HAVE_STDLIB_H
15 #include <stdlib.h>
16 #endif
17
18 #include <glib-object.h>
19 #include <gio/gio.h>
20
21 #include <dlt/dlt.h>
22
23 #include <common/watchdog-client.h>
24
25 #include <legacy-app-handler/la-handler-dbus.h>
26 #include <legacy-app-handler/la-handler-application.h>
27 #include <legacy-app-handler/la-handler-service.h>
28
29
30
31 DLT_IMPORT_CONTEXT (la_handler_context);
32
33
34
35 /* property identifiers */
36 enum
37 {
38   PROP_0,
39   PROP_LA_HANDLER_SERVICE,
40 };
41
42
43
44 static void la_handler_application_finalize     (GObject                 *object);
45 static void la_handler_application_get_property (GObject                 *object,
46                                                  guint                    prop_id,
47                                                  GValue                  *value,
48                                                  GParamSpec              *pspec);
49 static void la_handler_application_set_property (GObject                 *object,
50                                                  guint                    prop_id,
51                                                  const GValue            *value,
52                                                  GParamSpec              *pspec);
53 static void la_handler_application_startup      (GApplication            *application);
54 static int  la_handler_application_command_line (GApplication            *application,
55                                                  GApplicationCommandLine *cmdline);
56
57
58
59 struct _LAHandlerApplicationClass
60 {
61   GApplicationClass __parent__;
62 };
63
64 struct _LAHandlerApplication
65 {
66   GApplication       __parent__;
67
68   /* systemd watchdog client that repeatedly asks systemd to update
69    * the watchdog timestamp */
70   WatchdogClient    *watchdog_client;
71
72   /* service object that implements the Legacy App Handler D-Bus interface */
73   LAHandlerService *service;
74 };
75
76
77
78 G_DEFINE_TYPE (LAHandlerApplication, la_handler_application, G_TYPE_APPLICATION);
79
80
81
82 static void
83 la_handler_application_class_init (LAHandlerApplicationClass *klass)
84 {
85   GApplicationClass *gapplication_class;
86   GObjectClass *gobject_class;
87
88   gobject_class = G_OBJECT_CLASS (klass);
89   gobject_class->finalize = la_handler_application_finalize;
90   gobject_class->get_property = la_handler_application_get_property;
91   gobject_class->set_property = la_handler_application_set_property;
92
93   gapplication_class = G_APPLICATION_CLASS (klass);
94   gapplication_class->startup = la_handler_application_startup;
95   gapplication_class->command_line = la_handler_application_command_line;
96
97   g_object_class_install_property (gobject_class,
98                                    PROP_LA_HANDLER_SERVICE,
99                                    g_param_spec_object ("la-handler-service",
100                                                         "la-handler-service",
101                                                         "la-handler-service",
102                                                         LA_HANDLER_TYPE_SERVICE,
103                                                         G_PARAM_READWRITE |
104                                                         G_PARAM_CONSTRUCT_ONLY |
105                                                         G_PARAM_STATIC_STRINGS));
106 }
107
108
109
110 static void
111 la_handler_application_init (LAHandlerApplication *application)
112 {
113 }
114
115
116
117 static void
118 la_handler_application_finalize (GObject *object)
119 {
120   LAHandlerApplication *application = LA_HANDLER_APPLICATION (object);
121
122   /* release the watchdog client */
123   if (application->watchdog_client != NULL)
124     g_object_unref (application->watchdog_client);
125
126   /* release the Legacy App Handler service implementation */
127   if (application->service != NULL)
128     g_object_unref (application->service);
129
130   (*G_OBJECT_CLASS (la_handler_application_parent_class)->finalize) (object);
131 }
132
133
134
135 static void
136 la_handler_application_get_property (GObject    *object,
137                                      guint       prop_id,
138                                      GValue     *value,
139                                      GParamSpec *pspec)
140 {
141   LAHandlerApplication *application = LA_HANDLER_APPLICATION (object);
142
143   switch (prop_id)
144     {
145     case PROP_LA_HANDLER_SERVICE:
146       g_value_set_object (value, application->service);
147       break;
148     default:
149       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
150       break;
151     }
152 }
153
154
155
156 static void
157 la_handler_application_set_property (GObject      *object,
158                                      guint         prop_id,
159                                      const GValue *value,
160                                      GParamSpec   *pspec)
161 {
162   LAHandlerApplication *application = LA_HANDLER_APPLICATION (object);
163
164   switch (prop_id)
165     {
166     case PROP_LA_HANDLER_SERVICE:
167       application->service = g_value_dup_object (value);
168       break;
169     default:
170       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
171       break;
172     }
173 }
174
175
176
177 static void
178 la_handler_application_startup (GApplication *app)
179 {
180   LAHandlerApplication *application = LA_HANDLER_APPLICATION (app);
181
182   /* chain up to the parent class */
183   (*G_APPLICATION_CLASS (la_handler_application_parent_class)->startup) (app);
184
185   /* update systemd's watchdog timestamp every 120 seconds */
186   application->watchdog_client = watchdog_client_new (120);
187
188   /* the Legacy Application Handler should keep running until it is shut down by the Node
189    * State Manager. */
190   g_application_hold (app);
191 }
192
193
194
195 static int
196 la_handler_application_command_line (GApplication            *application,
197                                      GApplicationCommandLine *cmdline)
198 {
199   GOptionContext *context;
200   gboolean        do_register;
201   GError         *error = NULL;
202   gchar         **args;
203   gchar         **argv;
204   gchar          *mode = NULL;
205   gchar          *unit = NULL;
206   gint            argc;
207   gint            timeout = 0;
208   gint            i;
209
210   GOptionEntry entries[] = {
211     {"register",      0, 0, G_OPTION_ARG_NONE,   &do_register, NULL, NULL},
212     {"unit",          0, 0, G_OPTION_ARG_STRING, &unit,     NULL, NULL},
213     {"timeout",       0, 0, G_OPTION_ARG_INT,    &timeout,  NULL, NULL},
214     {"shutdown-mode", 0, 0, G_OPTION_ARG_STRING, &mode,     NULL, NULL},
215     {NULL},
216   };
217
218   /* keep the application running until we have finished */
219   g_application_hold (application);
220
221   /* retrieve the command-line arguments */
222   args = g_application_command_line_get_arguments (cmdline, &argc);
223
224   /* copy the args array, because g_option_context_parse() removes elements without
225    * freeing them */
226   argv = g_new (gchar *, argc + 1);
227   for (i = 0; i <= argc; i++)
228     argv[i] = args[i];
229
230   /* set up the option context */
231   context = g_option_context_new (NULL);
232   g_option_context_set_help_enabled (context, FALSE);
233   g_option_context_add_main_entries (context, entries, NULL);
234
235   /* parse the arguments into the argument data */
236   if (!g_option_context_parse (context, &argc, &argv, &error) || error != NULL)
237     {
238       /* an error occurred */
239       g_application_command_line_printerr (cmdline, "%s\n", error->message);
240       g_error_free (error);
241       g_application_command_line_set_exit_status (cmdline, EXIT_FAILURE);
242     }
243   else if (do_register)
244     {
245       if (unit != NULL && *unit != '\0' && timeout >= 0)
246         {
247           /* register was called correctly */
248           la_handler_service_register (LA_HANDLER_APPLICATION (application)->service,
249                                        unit, mode ? mode : "normal", (guint) timeout);
250         }
251       else
252         {
253           /* register was called incorrectly */
254           g_application_command_line_printerr (cmdline,
255                                                "Invalid arguments. A unit must be "
256                                                "specified and the timeout must be "
257                                                "positive.\n");
258         }
259     }
260
261   /* clean up */
262   g_free (argv);
263   g_strfreev (args);
264   g_option_context_free (context);
265
266   g_free (mode);
267   g_free (unit);
268
269   /* allow the application to stop */
270   g_application_release (application);
271
272   return EXIT_SUCCESS;
273 }
274
275
276
277 LAHandlerApplication *
278 la_handler_application_new (LAHandlerService *service,
279                             GApplicationFlags flags)
280 {
281   return g_object_new (LA_HANDLER_TYPE_APPLICATION,
282                        "application-id", "org.genivi.LegacyAppHandler1",
283                        "flags", flags,
284                        "la-handler-service", service,
285                        NULL);
286 }