# vi:set ts=8 sw=8 noet ai nocindent:
SUBDIRS = \
- common \
- luc-handler \
boot-manager \
- legacy-app-handler \
tests
.PHONY: ChangeLog
# vi:set ts=8 sw=8 noet ai nocindent:
+SUBDIRS = \
+ busconf \
+ dbus \
+ systemd
+
+luc_dir = \
+ $(datadir)/org.genivi.BootManager$(BOOT_MANAGER_VERSION_API)
+
+luc_path = \
+ $(luc_dir)/last-user-context
+
boot_managerdir = \
$(libdir)/boot-manager-$(BOOT_MANAGER_VERSION_API)
boot-manager
boot_manager_built_headers = \
+ boot-manager-dbus.h \
+ la-handler-dbus.h \
+ shutdown-consumer-dbus.h \
systemd-manager-dbus.h
boot_manager_built_sources = \
+ boot-manager-dbus.c \
+ la-handler-dbus.c \
+ shutdown-consumer-dbus.c \
systemd-manager-dbus.c \
$(boot_manager_built_headers)
boot_manager_SOURCES = \
- $(top_srcdir)/luc-handler/luc-handler-dbus.c \
- $(top_srcdir)/luc-handler/luc-handler-dbus.h \
boot-manager-application.c \
boot-manager-application.h \
+ boot-manager-command-line.c \
+ boot-manager-command-line.h \
boot-manager-service.c \
boot-manager-service.h \
+ glib-extensions.c \
+ glib-extensions.h \
+ job-manager.c \
+ job-manager.h \
+ la-handler-service.c \
+ la-handler-service.h \
luc-starter.c \
luc-starter.h \
+ shutdown-consumer-service.c \
+ shutdown-consumer-service.h \
target-startup-monitor.c \
target-startup-monitor.h \
+ watchdog-client.c \
+ watchdog-client.h \
main.c \
$(boot_manager_built_sources)
boot_manager_CFLAGS = \
+ -DLUCDIR=\"$(luc_dir)\" \
+ -DLUCPATH=\"$(luc_path)\" \
-DG_LOG_DOMAIN=\"boot-manager\" \
-I$(top_srcdir) \
$(DLT_CFLAGS) \
-no-undefined \
$(PLATFORM_LDFLAGS)
-boot_manager_DEPENDENCIES = \
- $(top_builddir)/common/libcommon.la
-
boot_manager_LDADD = \
$(DLT_LIBS) \
$(GIO_LIBS) \
$(GIO_UNIX_LIBS) \
$(GLIB_LIBS) \
- $(SYSTEMD_DAEMON_LIBS) \
- $(top_builddir)/common/libcommon.la
-
-servicedir = $(datadir)/dbus-1/services
-service_in_files = \
- org.genivi.BootManager1.service.in
-
-service_DATA = $(service_in_files:.service.in=.service)
-
-%.service: %.service.in
- sed -e "s,\@libdir\@,$(libdir),g" \
- -e "s,\@BOOT_MANAGER_VERSION_API\@,$(BOOT_MANAGER_VERSION_API),g" < $< > $@
-
-CLEANFILES = \
- $(service_DATA)
+ $(SYSTEMD_DAEMON_LIBS)
EXTRA_DIST = \
- $(service_in_files) \
+ boot-manager-dbus.xml \
+ la-handler-dbus.xml \
+ shutdown-consumer-dbus.xml \
systemd-manager-dbus.xml
DISTCLEANFILES = \
BUILT_SOURCES = \
$(boot_manager_built_headers)
+boot-manager-dbus.h: boot-manager-dbus.xml Makefile
+ $(AM_V_GEN) $(GDBUS_CODEGEN) \
+ --interface-prefix org.genivi \
+ --c-namespace "" \
+ --generate-c-code boot-manager-dbus \
+ --annotate org.genivi.BootManager1.BootManager org.gtk.GDBus.C.Name \
+ Boot_Manager $<
+
+la-handler-dbus.h: la-handler-dbus.xml Makefile
+ $(AM_V_GEN) $(GDBUS_CODEGEN) \
+ --interface-prefix org.genivi \
+ --c-namespace "" \
+ --generate-c-code la-handler-dbus \
+ --annotate org.genivi.BootManager1.LegacyAppHandler org.gtk.GDBus.C.Name \
+ LA_Handler $<
+
+shutdown-consumer-dbus.h: shutdown-consumer-dbus.xml Makefile
+ $(AM_V_GEN) $(GDBUS_CODEGEN) \
+ --interface-prefix org.genivi \
+ --c-namespace "" \
+ --generate-c-code shutdown-consumer-dbus \
+ --annotate org.genivi.BootManager1.ShutdownConsumer org.gtk.GDBus.C.Name \
+ Shutdown_Consumer $<
+
systemd-manager-dbus.h: systemd-manager-dbus.xml Makefile
$(AM_V_GEN) $(GDBUS_CODEGEN) \
--interface-prefix org.freedesktop.systemd1 \
#include <gio/gio.h>
#include <glib-unix.h>
-#include <common/boot-manager-dbus.h>
-#include <common/watchdog-client.h>
-#include <luc-handler/luc-handler-dbus.h>
+#include <systemd/sd-daemon.h>
+
+#include <dlt/dlt.h>
#include <boot-manager/boot-manager-application.h>
#include <boot-manager/boot-manager-service.h>
+#include <boot-manager/job-manager.h>
+#include <boot-manager/la-handler-service.h>
#include <boot-manager/luc-starter.h>
+#include <boot-manager/watchdog-client.h>
+
+
+
+DLT_IMPORT_CONTEXT (boot_manager_context);
enum
{
PROP_0,
- PROP_BOOT_MANAGER,
- PROP_LUC_HANDLER,
+ PROP_CONNECTION,
+ PROP_JOB_MANAGER,
+ PROP_BOOT_MANAGER_SERVICE,
PROP_LUC_STARTER,
+ PROP_LA_HANDLER,
};
struct _BootManagerApplication
{
- GApplication __parent__;
+ GApplication __parent__;
+
+ /* the connection to D-Bus */
+ GDBusConnection *connection;
/* systemd watchdog client that repeatedly asks systemd to update
* the watchdog timestamp */
- WatchdogClient *watchdog_client;
+ WatchdogClient *watchdog_client;
- /* implementation of the boot manager D-Bus interface */
- BootManagerService *boot_manager;
+ /* internal handler of Start() and Stop() jobs */
+ JobManager *job_manager;
+
+ /* boot manager service */
+ BootManagerService *boot_manager_service;
/* LUC starter to restore the LUC */
- LUCHandler *luc_handler;
LUCStarter *luc_starter;
/* signal handler IDs */
guint sigint_id;
+
+ /* Legacy App Handler to register apps with the Node State Manager */
+ LAHandlerService *la_handler;
+
+ /* Identifier for the registered bus name */
+ guint bus_name_id;
};
gapplication_class->startup = boot_manager_application_startup;
g_object_class_install_property (gobject_class,
- PROP_BOOT_MANAGER,
- g_param_spec_object ("boot-manager",
- "boot-manager",
- "boot-manager",
- BOOT_MANAGER_TYPE_SERVICE,
+ PROP_CONNECTION,
+ g_param_spec_object ("connection",
+ "D-Bus Connection",
+ "The connection to D-Bus",
+ G_TYPE_DBUS_CONNECTION,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class,
+ PROP_JOB_MANAGER,
+ g_param_spec_object ("job-manager",
+ "Job Manager",
+ "The internal handler of Start()"
+ " and Stop() jobs",
+ TYPE_JOB_MANAGER,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
- PROP_LUC_HANDLER,
- g_param_spec_object ("luc-handler",
- "luc-handler",
- "luc-handler",
- TYPE_LUC_HANDLER,
+ PROP_LA_HANDLER,
+ g_param_spec_object ("la-handler",
+ "LA Handler",
+ "Legacy Application Handler",
+ LA_HANDLER_TYPE_SERVICE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class,
+ PROP_BOOT_MANAGER_SERVICE,
+ g_param_spec_object ("boot-manager-service",
+ "boot-manager-service",
+ "boot-manager-service",
+ BOOT_MANAGER_TYPE_SERVICE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
{
BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
+ /* release the bus name */
+ g_bus_unown_name (application->bus_name_id);
+
+ /* release the D-Bus connection object */
+ if (application->connection != NULL)
+ g_object_unref (application->connection);
+
/* release the signal handler */
g_source_remove (application->sigint_id);
/* release the watchdog client */
g_object_unref (application->watchdog_client);
- /* release the LUC handler/starter */
- g_object_unref (application->luc_handler);
+ /* release the boot manager */
+ g_object_unref (application->boot_manager_service);
+
+ /* release the LUC starter */
g_object_unref (application->luc_starter);
- /* release the boot manager implementation */
- if (application->boot_manager != NULL)
- g_object_unref (application->boot_manager);
+ /* release the legacy app handler */
+ g_object_unref (application->la_handler);
+
+ /* release the job manager */
+ g_object_unref (application->job_manager);
(*G_OBJECT_CLASS (boot_manager_application_parent_class)->finalize) (object);
}
{
BootManagerApplication *application = BOOT_MANAGER_APPLICATION (object);
+ /* get a bus name on the given connection */
+ application->bus_name_id =
+ g_bus_own_name_on_connection (application->connection, "org.genivi.BootManager1",
+ G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL);
+
/* instantiate the LUC starter */
- application->luc_starter = luc_starter_new (application->boot_manager,
- application->luc_handler);
+ application->luc_starter = luc_starter_new (application->job_manager,
+ application->boot_manager_service);
}
switch (prop_id)
{
- case PROP_BOOT_MANAGER:
- g_value_set_object (value, application->boot_manager);
+ case PROP_CONNECTION:
+ g_value_set_object (value, application->connection);
break;
- case PROP_LUC_HANDLER:
- g_value_set_object (value, application->luc_handler);
+ case PROP_JOB_MANAGER:
+ g_value_set_object (value, application->job_manager);
+ break;
+ case PROP_BOOT_MANAGER_SERVICE:
+ g_value_set_object (value, application->boot_manager_service);
+ case PROP_LA_HANDLER:
+ g_value_set_object (value, application->la_handler);
break;
case PROP_LUC_STARTER:
g_value_set_object (value, application->luc_starter);
switch (prop_id)
{
- case PROP_BOOT_MANAGER:
- application->boot_manager = g_value_dup_object (value);
+ case PROP_CONNECTION:
+ application->connection = g_value_dup_object (value);
+ break;
+ case PROP_JOB_MANAGER:
+ application->job_manager = g_value_dup_object (value);
+ break;
+ case PROP_BOOT_MANAGER_SERVICE:
+ application->boot_manager_service = g_value_dup_object (value);
break;
- case PROP_LUC_HANDLER:
- application->luc_handler = g_value_dup_object (value);
+ case PROP_LA_HANDLER:
+ application->la_handler = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
boot_manager_application_startup (GApplication *app)
{
BootManagerApplication *application = BOOT_MANAGER_APPLICATION (app);
+ GError *error = NULL;
+ gchar *log_text;
/* chain up to the parent class */
(*G_APPLICATION_CLASS (boot_manager_application_parent_class)->startup) (app);
+ /* start the boot manager service */
+ boot_manager_service_start_up (application->boot_manager_service, &error);
+
+ if (error != NULL)
+ {
+ log_text = g_strdup_printf ("Error starting boot manager service: %s",
+ error->message);
+ DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text));
+ g_free (log_text);
+ }
+
/* restore the LUC if desired */
luc_starter_start_groups (application->luc_starter);
-}
+ /* start the legacy app handler */
+ la_handler_service_start (application->la_handler, &error);
+
+ if (error != NULL)
+ {
+ log_text =
+ g_strdup_printf ("Boot Manager Application failed to start the legacy app "
+ "handler: %s", error->message);
+ DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text));
+ g_free (log_text);
+ }
+
+ /* inform systemd that this process has started */
+ sd_notify (0, "READY=1");
+
+ /* hold the application so that it persists */
+ g_application_hold (app);
+}
static gboolean
BootManagerApplication *application = BOOT_MANAGER_APPLICATION (app);
luc_starter_cancel (application->luc_starter);
- boot_manager_service_cancel (application->boot_manager);
return TRUE;
}
BootManagerApplication *
-boot_manager_application_new (BootManagerService *boot_manager,
- LUCHandler *luc_handler)
+boot_manager_application_new (GDBusConnection *connection,
+ JobManager *job_manager,
+ LAHandlerService *la_handler,
+ BootManagerService *boot_manager_service)
{
- g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (boot_manager), NULL);
- g_return_val_if_fail (IS_LUC_HANDLER (luc_handler), NULL);
+ g_return_val_if_fail (IS_JOB_MANAGER (job_manager), NULL);
+ g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (boot_manager_service), NULL);
return g_object_new (BOOT_MANAGER_TYPE_APPLICATION,
"application-id", "org.genivi.BootManager1",
"flags", G_APPLICATION_IS_SERVICE,
- "boot-manager", boot_manager,
- "luc-handler", luc_handler,
+ "connection", connection,
+ "job-manager", job_manager,
+ "boot-manager-service", boot_manager_service,
+ "la-handler", la_handler,
NULL);
}
#ifndef __BOOT_MANAGER_APPLICATION_H__
#define __BOOT_MANAGER_APPLICATION_H__
-#include <luc-handler/luc-handler-dbus.h>
+#include <gio/gio.h>
+
#include <boot-manager/boot-manager-service.h>
+#include <boot-manager/job-manager.h>
+#include <boot-manager/la-handler-service.h>
G_BEGIN_DECLS
GType boot_manager_application_get_type (void) G_GNUC_CONST;
-BootManagerApplication *boot_manager_application_new (BootManagerService *service,
- LUCHandler *luc_handler) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+BootManagerApplication *boot_manager_application_new (GDBusConnection *connection,
+ JobManager *job_manager,
+ LAHandlerService *la_handler,
+ BootManagerService *boot_manager_service) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
G_END_DECLS
--- /dev/null
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/* -
+ * Copyright (c) 2012 GENIVI.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <dlt/dlt.h>
+
+#include <boot-manager/boot-manager-command-line.h>
+#include <boot-manager/la-handler-dbus.h>
+
+
+DLT_IMPORT_CONTEXT (la_handler_context);
+
+
+
+gint
+boot_manager_handle_command_line (int argc,
+ char **argv,
+ GDBusConnection *connection)
+{
+ GOptionContext *context = g_option_context_new (NULL);
+ LAHandler *legacy_app_handler = NULL;
+ gboolean do_register = FALSE;
+ gboolean do_deregister = FALSE;
+ GError *error = NULL;
+ gchar *unit = NULL;
+ gchar *log_message = NULL;
+ gchar *mode = NULL;
+ gint timeout = 0;
+ int exit_status;
+
+ GOptionEntry entries[] = {
+ {"deregister", 0, 0, G_OPTION_ARG_NONE, &do_deregister, NULL, NULL},
+ {"register", 0, 0, G_OPTION_ARG_NONE, &do_register, NULL, NULL},
+ {"unit", 0, 0, G_OPTION_ARG_STRING, &unit, NULL, NULL},
+ {"timeout", 0, 0, G_OPTION_ARG_INT, &timeout, NULL, NULL},
+ {"shutdown-mode", 0, 0, G_OPTION_ARG_STRING, &mode, NULL, NULL},
+ {NULL},
+ };
+
+ /* set up the option context */
+ g_option_context_set_help_enabled (context, FALSE);
+ g_option_context_add_main_entries (context, entries, NULL);
+
+ /* parse the arguments into argument data */
+ if (!g_option_context_parse (context, &argc, &argv, &error) || error != NULL)
+ {
+ /* an error occurred */
+ log_message =
+ g_strdup_printf ("Error occurred parsing arguments: %s\n", error->message);
+ DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
+
+ exit_status = EXIT_FAILURE;
+ goto finish;
+ }
+
+ /* validate the argument data */
+ if (unit == NULL || *unit == '\0')
+ {
+ DLT_LOG (la_handler_context, DLT_LOG_ERROR,
+ DLT_STRING ("Invalid arguments: unit must be defined"));
+ exit_status = EXIT_FAILURE;
+ goto finish;
+ }
+
+ if (!(do_register ^ do_deregister))
+ {
+ DLT_LOG (la_handler_context, DLT_LOG_ERROR,
+ DLT_STRING ("Invalid arguments: Please select either --register or "
+ "--deregister"));
+ exit_status = EXIT_FAILURE;
+ goto finish;
+ }
+
+ if (do_register && timeout < 0)
+ {
+ DLT_LOG (la_handler_context, DLT_LOG_ERROR,
+ DLT_STRING ("Invalid arguments: Timeout must be non-negative"));
+ exit_status = EXIT_FAILURE;
+ goto finish;
+ }
+
+ /* get a legacy app handler interface */
+ legacy_app_handler =
+ la_handler_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE,
+ "org.genivi.BootManager1",
+ "/org/genivi/BootManager1/LegacyAppHandler", NULL,
+ &error);
+ if (error != NULL)
+ {
+ /* failed to connect to the legacy app handler */
+ log_message =
+ g_strdup_printf ("Error occurred connecting to legacy app handler "
+ "interface: %s", error->message);
+ DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
+
+ g_free (log_message);
+ g_error_free (error);
+
+ exit_status = EXIT_FAILURE;
+ goto finish;
+ }
+
+ if (do_register)
+ {
+ /* call the legacy app handler's Register() method */
+ la_handler_call_register_sync (legacy_app_handler, unit, mode ? mode : "normal",
+ (guint) timeout, NULL, &error);
+
+ if (error != NULL)
+ {
+ /* failed to register the legacy app */
+ log_message = g_strdup_printf ("Error occurred registering legacy app: %s",
+ error->message);
+ DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
+
+ exit_status = EXIT_FAILURE;
+ }
+ else
+ {
+ exit_status = EXIT_SUCCESS;
+ }
+ goto finish;
+ }
+ else if (do_deregister)
+ {
+ /* call the legacy app handler's Deregister() method */
+ la_handler_call_deregister_sync (legacy_app_handler, unit, NULL, &error);
+ if (error != NULL)
+ {
+ /* failed to deregister the legacy app */
+ log_message = g_strdup_printf ("Error occurred deregistering legacy app: %s",
+ error->message);
+ DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
+
+ exit_status = EXIT_FAILURE;
+ }
+ else
+ {
+ exit_status = EXIT_SUCCESS;
+ }
+ goto finish;
+ }
+ else
+ {
+ DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING ("unexpected input"));
+ exit_status = EXIT_FAILURE;
+ goto finish;
+ }
+
+ finish:
+ g_option_context_free (context);
+ if (legacy_app_handler != NULL)
+ g_object_unref (legacy_app_handler);
+ if (error != NULL)
+ g_error_free (error);
+ g_free (unit);
+ g_free (log_message);
+ g_free (mode);
+ return exit_status;
+}
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-#ifndef __GLIB_EXTENSIONS_H__
-#define __GLIB_EXTENSIONS_H__
-
#include <glib.h>
+#include <gio/gio.h>
-G_BEGIN_DECLS
-
-gboolean g_variant_string_array_has_string (GVariant *array,
- const gchar *str);
-
-G_END_DECLS
-
-#endif /* !__GLIB_EXTENSION_H__ */
+gint boot_manager_handle_command_line (int argc,
+ char **argv,
+ GDBusConnection *connection);
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<node name="/org/genivi/BootManager1/BootManager">
+ <!--
+ org.genivi.BootManager1.BootManager:
+ @short_description: Interface for managing the GENIVI LUC (Last User Context)
+
+ The GENIVI Boot Manager remembers applications that were used in the last
+ session of a user. It is used in order to restore these applications on
+ the next start-up.
+
+ The Boot Manager is a passive component in the sense that it does not
+ remember applications on its own; instead, applications need to register
+ and deregister themselves proactively.
+
+ Applications can be registered for different LUC types, the standard ones
+ being "foreground", "background" and "audible".
+ -->
+ <interface name="org.genivi.BootManager1.BootManager">
+ <!--
+ BeginLUCRegistration:
+
+ Initialises the LUC registration sequence at shutdown in order to register
+ the applications which are running in the LUC in this moment.
+ -->
+ <method name="BeginLUCRegistration">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+ </method>
+
+ <!--
+ RegisterWithLUC:
+ @apps: A dictionary that maps LUC types to arrays of application unit names.
+
+ Registers one or more applications for certain LUC types. Applications may
+ be listed multiple times. For LUC types where only a single application may
+ be registered at a time, the last application in the corresponding list wins.
+
+ An example for the apps parameter would be:
+
+ {
+ 0 : [ "app1.unit" ],
+ 1 : [ "app2.unit", "app3.unit" ],
+ 2 : [ "app3.unit" ]
+ }
+
+ where 0 = "foreground", 1 = background , 2 = "audible"
+ -->
+ <method name="RegisterWithLUC">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+ <arg name="apps" type="a{ias}" direction="in"/>
+ </method>
+
+ <!--
+ FinishLUCRegistration:
+
+ Finishes the LUC registration sequence and atomically replaces the previous LUC.
+ -->
+ <method name="FinishLUCRegistration">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+ </method>
+ </interface>
+</node>
#include <config.h>
#endif
+#include <glib.h>
#include <glib-object.h>
#include <gio/gio.h>
-#include <common/boot-manager-dbus.h>
+#include <dlt/dlt.h>
+#include <boot-manager/glib-extensions.h>
+#include <boot-manager/boot-manager-dbus.h>
#include <boot-manager/boot-manager-service.h>
-typedef struct _BootManagerServiceJob BootManagerServiceJob;
+DLT_IMPORT_CONTEXT (boot_manager_context);
{
PROP_0,
PROP_CONNECTION,
- PROP_SYSTEMD_MANAGER,
};
-static void boot_manager_service_finalize (GObject *object);
-static void boot_manager_service_constructed (GObject *object);
-static void boot_manager_service_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void boot_manager_service_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static gboolean boot_manager_service_handle_start (BootManager *interface,
- GDBusMethodInvocation *invocation,
- const gchar *unit,
- BootManagerService *service);
-static void boot_manager_service_handle_start_finish (BootManagerService *service,
- const gchar *unit,
- const gchar *result,
- GError *error,
- gpointer user_data);
-static void boot_manager_service_start_unit_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data);
-static gboolean boot_manager_service_handle_stop (BootManager *interface,
- GDBusMethodInvocation *invocation,
- const gchar *unit,
- BootManagerService *service);
-static void boot_manager_service_handle_stop_finish (BootManagerService *service,
- const gchar *unit,
- const gchar *result,
- GError *error,
- gpointer user_data);
-static void boot_manager_service_stop_unit_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data);
-static gboolean boot_manager_service_handle_kill (BootManager *interface,
- GDBusMethodInvocation *invocation,
- const gchar *unit,
- BootManagerService *service);
-static void boot_manager_service_handle_kill_finish (BootManagerService *service,
- const gchar *unit,
- const gchar *result,
- GError *error,
- gpointer user_data);
-static void boot_manager_service_kill_unit_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data);
-static gboolean boot_manager_service_handle_restart (BootManager *interface,
- GDBusMethodInvocation *invocation,
- const gchar *unit,
- BootManagerService *service);
-static void boot_manager_service_handle_restart_finish (BootManagerService *service,
- const gchar *unit,
- const gchar *result,
- GError *error,
- gpointer user_data);
-static void boot_manager_service_restart_unit_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data);
-static gboolean boot_manager_service_handle_isolate (BootManager *interface,
- GDBusMethodInvocation *invocation,
- const gchar *unit,
- BootManagerService *service);
-static void boot_manager_service_handle_isolate_finish (BootManagerService *service,
- const gchar *unit,
- const gchar *result,
- GError *error,
- gpointer user_data);
-static void boot_manager_service_isolate_unit_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data);
-static gboolean boot_manager_service_handle_list (BootManager *interface,
- GDBusMethodInvocation *invocation,
- BootManagerService *service);
-static void boot_manager_service_handle_list_finish (BootManagerService *service,
- const gchar *const *result,
- GError *error,
- gpointer user_data);
-static void boot_manager_service_list_units_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data);
-static void boot_manager_service_job_removed (SystemdManager *manager,
- guint id,
- const gchar *job_name,
- const gchar *result,
- BootManagerService *service);
-static BootManagerServiceJob *boot_manager_service_job_new (BootManagerService *service,
- const gchar *unit,
- GCancellable *cancellable,
- BootManagerServiceCallback callback,
- BootManagerServiceListCallback list_callback,
- gpointer user_data);
-static void boot_manager_service_job_unref (BootManagerServiceJob *job);
-static void boot_manager_service_remember_job (BootManagerService *service,
- const gchar *job_name,
- BootManagerServiceJob *job);
-static void boot_manager_service_forget_job (BootManagerService *service,
- const gchar *job_name);
-static void boot_manager_service_cancel_task (gpointer key,
- GCancellable *cancellable,
- gpointer user_data);
+static void boot_manager_service_finalize (GObject *object);
+static void boot_manager_service_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void boot_manager_service_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static gboolean boot_manager_service_handle_begin_luc_registration (BootManager *object,
+ GDBusMethodInvocation *invocation,
+ BootManagerService *service);
+static gboolean boot_manager_service_handle_finish_luc_registration (BootManager *object,
+ GDBusMethodInvocation *invocation,
+ BootManagerService *service);
+static gboolean boot_manager_service_handle_register_with_luc (BootManager *object,
+ GDBusMethodInvocation *invocation,
+ GVariant *apps,
+ BootManagerService *service);
GDBusConnection *connection;
BootManager *interface;
- SystemdManager *systemd_manager;
- GHashTable *jobs;
- GHashTable *cancellables;
-};
-
-struct _BootManagerServiceJob
-{
- BootManagerService *service;
- gchar *unit;
- GCancellable *cancellable;
- BootManagerServiceCallback callback;
- BootManagerServiceListCallback list_callback;
- gpointer user_data;
- gchar *name;
+ GVariant *current_user_context;
+ gboolean started_registration;
};
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = boot_manager_service_finalize;
- gobject_class->constructed = boot_manager_service_constructed;
gobject_class->get_property = boot_manager_service_get_property;
gobject_class->set_property = boot_manager_service_set_property;
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (gobject_class,
- PROP_SYSTEMD_MANAGER,
- g_param_spec_object ("systemd-manager",
- "systemd-manager",
- "systemd-manager",
- TYPE_SYSTEMD_MANAGER,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
}
static void
boot_manager_service_init (BootManagerService *service)
{
- /* create a mapping of systemd job names to job objects; we will use this
- * to remember jobs that we started */
- service->jobs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
- (GDestroyNotify) boot_manager_service_job_unref);
-
service->interface = boot_manager_skeleton_new ();
- /* implement the Start() method handler */
- g_signal_connect (service->interface, "handle-start",
- G_CALLBACK (boot_manager_service_handle_start), service);
-
- /* implement the Stop() method handler */
- g_signal_connect (service->interface, "handle-stop",
- G_CALLBACK (boot_manager_service_handle_stop), service);
-
- /* implement the Kill() method handler */
- g_signal_connect (service->interface, "handle-kill",
- G_CALLBACK (boot_manager_service_handle_kill), service);
- /* implement the Restart() method handler */
- g_signal_connect (service->interface, "handle-restart",
- G_CALLBACK (boot_manager_service_handle_restart), service);
- /* implement the Isolate() method handler */
- g_signal_connect (service->interface, "handle-isolate",
- G_CALLBACK (boot_manager_service_handle_isolate), service);
- /* implement the List() method handler */
- g_signal_connect (service->interface, "handle-list",
- G_CALLBACK (boot_manager_service_handle_list), service);
-
- /* create a mapping of method calls to units and cancellables; we will use this to
- * cancel jobs that are in the middle of being started */
- service->cancellables =
- g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) g_object_unref,
- (GDestroyNotify) g_object_unref);
+ /* initialise started_registration */
+ service->started_registration = FALSE;
+
+ /* prepare current_user_contex */
+ service->current_user_context = NULL;
+ /* implement the RegisterWithLUC() handler */
+ g_signal_connect (service->interface, "handle-register-with-luc",
+ G_CALLBACK (boot_manager_service_handle_register_with_luc),
+ service);
+
+ /* implement the BeginLUCRegistration() handler */
+ g_signal_connect (service->interface, "handle-begin-lucregistration",
+ G_CALLBACK (boot_manager_service_handle_begin_luc_registration),
+ service);
+
+ /* implement the FinishLUCRegistration() handler */
+ g_signal_connect (service->interface, "handle-finish-lucregistration",
+ G_CALLBACK (boot_manager_service_handle_finish_luc_registration),
+ service);
}
{
BootManagerService *service = BOOT_MANAGER_SERVICE (object);
- /* release all the jobs we have remembered */
- g_hash_table_unref (service->jobs);
-
/* release the D-Bus connection object */
g_object_unref (service->connection);
- /* release the systemd manager */
- g_signal_handlers_disconnect_matched (service->systemd_manager,
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, service);
- g_object_unref (service->systemd_manager);
-
/* release the interface skeleton */
g_signal_handlers_disconnect_matched (service->interface,
G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL, service);
g_object_unref (service->interface);
- /* release the cancellables hash table */
- g_hash_table_unref (service->cancellables);
+ /* release the current user context */
+ g_variant_unref (service->current_user_context);
(*G_OBJECT_CLASS (boot_manager_service_parent_class)->finalize) (object);
}
static void
-boot_manager_service_constructed (GObject *object)
-{
- BootManagerService *service = BOOT_MANAGER_SERVICE (object);
-
- /* connect to systemd's "JobRemoved" signal so that we are notified
- * whenever a job is finished */
- g_signal_connect (service->systemd_manager, "job-removed",
- G_CALLBACK (boot_manager_service_job_removed), service);
-}
-
-
-
-static void
boot_manager_service_get_property (GObject *object,
guint prop_id,
GValue *value,
case PROP_CONNECTION:
g_value_set_object (value, service->connection);
break;
- case PROP_SYSTEMD_MANAGER:
- g_value_set_object (value, service->systemd_manager);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_CONNECTION:
service->connection = g_value_dup_object (value);
break;
- case PROP_SYSTEMD_MANAGER:
- service->systemd_manager = g_value_dup_object (value);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
static gboolean
-boot_manager_service_handle_start (BootManager *interface,
- GDBusMethodInvocation *invocation,
- const gchar *unit,
- BootManagerService *service)
+boot_manager_service_handle_begin_luc_registration (BootManager *object,
+ GDBusMethodInvocation *invocation,
+ BootManagerService *service)
{
- GCancellable *cancellable;
+ GVariantBuilder *luc_builder;
- g_return_val_if_fail (IS_BOOT_MANAGER (interface), FALSE);
+ g_return_val_if_fail (IS_BOOT_MANAGER (object), FALSE);
g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);
- g_return_val_if_fail (unit != NULL, FALSE);
g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (service), FALSE);
- /* create a new cancellable so that we can cancel this start call */
- cancellable = g_cancellable_new ();
-
- /* store the cancellable in the cancellables GHashTable */
- g_hash_table_insert (service->cancellables, g_object_ref (invocation), cancellable);
+ /* last user context registration started */
+ service->started_registration = TRUE;
- /* ask systemd to start the unit for us, send a D-Bus reply in the finish callback */
- boot_manager_service_start (service, unit, cancellable,
- boot_manager_service_handle_start_finish, invocation);
+ /* initialize the current user context */
+ luc_builder = g_variant_builder_new (G_VARIANT_TYPE("a{ias}"));
+ service->current_user_context = g_variant_new ("a{ias}", luc_builder);
+ g_variant_builder_unref (luc_builder);
+ /* notify the caller that we have handled the register request */
+ g_dbus_method_invocation_return_value (invocation, NULL);
return TRUE;
}
-static void
-boot_manager_service_handle_start_finish (BootManagerService *service,
- const gchar *unit,
- const gchar *result,
- GError *error,
- gpointer user_data)
-{
- GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (user_data);
-
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (unit != NULL);
- g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
-
- /* log any potential errors */
- if (error != NULL)
- g_warning ("there was an error: %s", error->message);
-
- /* remove the cancellable associated with this invocation now the job is finished */
- g_hash_table_remove (service->cancellables, invocation);
- g_object_unref (invocation);
-
- /* report the result back to the boot manager client */
- boot_manager_complete_start (service->interface, invocation, result);
-}
-
-
-
-static void
-boot_manager_service_start_unit_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- BootManagerServiceJob *job = user_data;
- GError *error = NULL;
- gchar *job_name = NULL;
-
- g_return_if_fail (IS_SYSTEMD_MANAGER (object));
- g_return_if_fail (G_IS_ASYNC_RESULT (result));
- g_return_if_fail (user_data != NULL);
-
- /* finish the start unit call */
- if (!systemd_manager_call_start_unit_finish (job->service->systemd_manager,
- &job_name, result, &error))
- {
- /* there was an error; let the caller know */
- job->callback (job->service, job->unit, "failed", error, job->user_data);
- g_error_free (error);
- g_free (job_name);
-
- /* finish the job immediately */
- boot_manager_service_job_unref (job);
- }
- else
- {
- /* remember the job so that we can finish it in the "job-removed" signal
- * handler. the service takes ownership of the job so we don't need to
- * unref it here */
- boot_manager_service_remember_job (job->service, job_name, job);
- }
-}
-
-
-
static gboolean
-boot_manager_service_handle_stop (BootManager *interface,
- GDBusMethodInvocation *invocation,
- const gchar *unit,
- BootManagerService *service)
+boot_manager_service_handle_finish_luc_registration (BootManager *object,
+ GDBusMethodInvocation *invocation,
+ BootManagerService *service)
{
- GCancellable *cancellable;
+ GError *error = NULL;
+ gchar *log_text;
- g_return_val_if_fail (IS_BOOT_MANAGER (interface), FALSE);
+ g_return_val_if_fail (IS_BOOT_MANAGER (object), FALSE);
g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);
- g_return_val_if_fail (unit != NULL, FALSE);
g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (service), FALSE);
- /* create a new cancellable so that we can cancel this stop call */
- cancellable = g_cancellable_new ();
-
- /* store the cancellable in the cancellables GHashTable */
- g_hash_table_insert (service->cancellables, g_object_ref (invocation), cancellable);
-
- /* ask systemd to stop the unit for us, send a D-Bus reply in the finish callback */
- boot_manager_service_stop (service, unit, cancellable,
- boot_manager_service_handle_stop_finish, invocation);
-
- return TRUE;
-}
-
-
-
-static void
-boot_manager_service_handle_stop_finish (BootManagerService *service,
- const gchar *unit,
- const gchar *result,
- GError *error,
- gpointer user_data)
-{
- GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (user_data);
-
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (unit != NULL);
- g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
-
- /* log any potential errors */
- if (error != NULL)
- g_warning ("there was an error: %s", error->message);
-
- /* remove the cancellable associated with this invocation now the job is finished */
- g_hash_table_remove (service->cancellables, invocation);
- g_object_unref (invocation);
-
- /* report the result back to the boot manager client */
- boot_manager_complete_stop (service->interface, invocation, result);
-}
-
-
-
-static void
-boot_manager_service_stop_unit_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- BootManagerServiceJob *job = user_data;
- GError *error = NULL;
- gchar *job_name = NULL;
-
- g_return_if_fail (IS_SYSTEMD_MANAGER (object));
- g_return_if_fail (G_IS_ASYNC_RESULT (result));
- g_return_if_fail (user_data != NULL);
-
- /* finish the stop unit call */
- if (!systemd_manager_call_stop_unit_finish (job->service->systemd_manager,
- &job_name, result, &error))
- {
- /* there was an error; let the caller know */
- job->callback (job->service, job->unit, "failed", error, job->user_data);
- g_error_free (error);
- g_free (job_name);
-
- /* finish the job immediately */
- boot_manager_service_job_unref (job);
- }
- else
+ /* check if last user context registration started */
+ if (!service->started_registration)
{
- /* remember the job so that we can finish it in the "job-removed" signal
- * handler. the service takes ownership of the job so we don't need to
- * unref it here */
- boot_manager_service_remember_job (job->service, job_name, job);
+ log_text = g_strdup_printf ("Failed to finish LUC registration. Begin registration"
+ " did not start");
+ DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text));
+ g_free (log_text);
+
+ /* notify the caller that we have handled the register request */
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ return TRUE;
}
-}
-
-
-
-static gboolean
-boot_manager_service_handle_kill (BootManager *interface,
- GDBusMethodInvocation *invocation,
- const gchar *unit,
- BootManagerService *service)
-{
- GCancellable *cancellable;
-
- g_return_val_if_fail (IS_BOOT_MANAGER (interface), FALSE);
- g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);
- g_return_val_if_fail (unit != NULL, FALSE);
- g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (service), FALSE);
-
- /* create a new cancellable so that we can cancel this kill call */
- cancellable = g_cancellable_new ();
-
- /* store the cancellable in the cancellables GHashTable */
- g_hash_table_insert (service->cancellables, g_object_ref (invocation), cancellable);
-
- /* ask systemd to kill the unit, send a D-Bus reply in the finish callback */
- boot_manager_service_kill (service, unit, cancellable,
- boot_manager_service_handle_kill_finish, invocation);
-
- return TRUE;
-}
-
-
-
-static void
-boot_manager_service_handle_kill_finish (BootManagerService *service,
- const gchar *unit,
- const gchar *result,
- GError *error,
- gpointer user_data)
-{
- GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (user_data);
-
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (unit!= NULL);
- g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
-
- /* log any potential errors */
- if (error != NULL)
- g_warning ("there was an error: %s", error->message);
-
- /* remove the cancellable associated with this invocation now the job is finished */
- g_hash_table_remove (service->cancellables, invocation);
- g_object_unref (invocation);
-
- /* report the result back to the boot manager client */
- boot_manager_complete_kill (service->interface, invocation, result);
-}
-
-
-static void
-boot_manager_service_kill_unit_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- BootManagerServiceJob *job = user_data;
- GError *error = NULL;
-
- g_return_if_fail (IS_SYSTEMD_MANAGER (object));
- g_return_if_fail (G_IS_ASYNC_RESULT (result));
- g_return_if_fail (user_data != NULL);
-
- /* finish the kill unit call */
- systemd_manager_call_kill_unit_finish (job->service->systemd_manager,
- result, &error);
-
- /* got a reply from systemd; let the caller know we're done */
- job->callback (job->service, job->unit, (error == NULL) ? "done" : "failed", error,
- job->user_data);
+ /* write the last user context in a file */
+ boot_manager_service_write_luc (service, &error);
if (error != NULL)
- g_error_free (error);
-
- /* finish the job */
- boot_manager_service_job_unref (job);
+ {
+ log_text = g_strdup_printf ("Failed to finish LUC registration: %s",
+ error->message);
+ DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text));
+ g_free (log_text);
+ g_error_free (error);
+ }
+
+ /* last user context registration finished */
+ service->started_registration = FALSE;
+
+ /* notify the caller that we have handled the register request */
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ return TRUE;
}
static gboolean
-boot_manager_service_handle_restart (BootManager *interface,
- GDBusMethodInvocation *invocation,
- const gchar *unit,
- BootManagerService *service)
-{
- GCancellable *cancellable;
-
- g_return_val_if_fail (IS_BOOT_MANAGER (interface), FALSE);
+boot_manager_service_handle_register_with_luc (BootManager *object,
+ GDBusMethodInvocation *invocation,
+ GVariant *apps,
+ BootManagerService *service)
+{
+ GVariantBuilder dict_builder;
+ GHashTableIter hiter;
+ GVariantIter viter;
+ GHashTable *table;
+ GPtrArray *apps_array;
+ GVariant *current_context;
+ GVariant *current_apps;
+ GVariant *new_apps;
+ GList *lp;
+ GList *luc_types;
+ gchar *app;
+ gchar *debug_text = NULL;
+ gchar *log_text = NULL;
+ guint n;
+ gint *dup_luc_type;
+ gint luc_type;
+ gint builder_luc_type;
+
+ g_return_val_if_fail (IS_BOOT_MANAGER (object), FALSE);
g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);
- g_return_val_if_fail (unit != NULL, FALSE);
g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (service), FALSE);
- /* create a new cancellable so that we can cancel this restart call */
- cancellable = g_cancellable_new ();
-
- /* store the cancellable in the cancellables GHashTable */
- g_hash_table_insert (service->cancellables, g_object_ref (invocation), cancellable);
-
- /* ask systemd to restart the unit for us, send a D-Bus reply in the finish callback */
- boot_manager_service_restart (service, unit, cancellable,
- boot_manager_service_handle_restart_finish, invocation);
-
- return TRUE;
-}
-
-
-
-static void
-boot_manager_service_handle_restart_finish (BootManagerService *service,
- const gchar *unit,
- const gchar *result,
- GError *error,
- gpointer user_data)
-{
- GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (user_data);
-
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (unit != NULL);
- g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
-
- /* log any potential errors */
- if (error != NULL)
- g_warning ("there was an error: %s", error->message);
-
- /* remove the cancellable associated with this invocation now the job is finished */
- g_hash_table_remove (service->cancellables, invocation);
- g_object_unref (invocation);
-
- /* report the result back to the boot manager client */
- boot_manager_complete_restart (service->interface, invocation, result);
-}
-
-
-
-static void
-boot_manager_service_restart_unit_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- BootManagerServiceJob *job = user_data;
- GError *error = NULL;
- gchar *job_name = NULL;
-
- g_return_if_fail (IS_SYSTEMD_MANAGER (object));
- g_return_if_fail (G_IS_ASYNC_RESULT (result));
- g_return_if_fail (user_data != NULL);
-
- /* finish the restart unit call */
- if (!systemd_manager_call_restart_unit_finish (job->service->systemd_manager,
- &job_name, result, &error))
- {
- /* there was an error; let the caller know */
- job->callback (job->service, job->unit, "failed", error, job->user_data);
- g_error_free (error);
- g_free (job_name);
-
- /* finish the job immediately */
- boot_manager_service_job_unref (job);
- }
- else
+ /* check if last user context registration started */
+ if (!service->started_registration)
{
- /* remember the job so that we can finish it in the "job-removed" signal
- * handler. the service takes ownership of the job so we don't need to
- * unref it here */
- boot_manager_service_remember_job (job->service, job_name, job);
+ log_text = g_strdup_printf ("Failed to register apps. Begin registration "
+ "did not start");
+ DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text));
+ g_free (log_text);
+
+ /* notify the caller that we have handled the register request */
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ return TRUE;
}
-}
-
-
-
-static gboolean
-boot_manager_service_handle_isolate (BootManager *interface,
- GDBusMethodInvocation *invocation,
- const gchar *unit,
- BootManagerService *service)
-{
- GCancellable *cancellable;
-
- g_return_val_if_fail (IS_BOOT_MANAGER (interface), FALSE);
- g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);
- g_return_val_if_fail (unit != NULL, FALSE);
- g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (service), FALSE);
-
- /* create a new cancellable so that we can cancel this isolate call */
- cancellable = g_cancellable_new ();
-
- /* store the cancellable in the cancellables GHashTable */
- g_hash_table_insert (service->cancellables, g_object_ref (invocation), cancellable);
-
- /* ask systemd to isolate the unit for us, send a D-Bus reply in the finish callback */
- boot_manager_service_isolate (service, unit, cancellable,
- boot_manager_service_handle_isolate_finish, invocation);
-
- return TRUE;
-}
-
-
-
-static void
-boot_manager_service_handle_isolate_finish (BootManagerService *service,
- const gchar *unit,
- const gchar *result,
- GError *error,
- gpointer user_data)
-{
- GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (user_data);
-
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (unit != NULL);
- g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
-
- /* log any potential errors */
- if (error != NULL)
- g_warning ("there was an error: %s", error->message);
-
- /* remove the cancellable associated with this invocation now the job is finished */
- g_hash_table_remove (service->cancellables, invocation);
- g_object_unref (invocation);
-
- /* report the result back to the boot manager client */
- boot_manager_complete_isolate (service->interface, invocation, result);
-}
-
+ /* create a hash table to merge the current context and the newly registered apps */
+ table = g_hash_table_new_full (g_int_hash, g_int_equal,
+ g_free, (GDestroyNotify) g_ptr_array_unref);
-static void
-boot_manager_service_isolate_unit_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- BootManagerServiceJob *job = user_data;
- GError *error = NULL;
- gchar *job_name = NULL;
-
- g_return_if_fail (IS_SYSTEMD_MANAGER (object));
- g_return_if_fail (G_IS_ASYNC_RESULT (result));
- g_return_if_fail (user_data != NULL);
+ /* obtain the current content of the last user context */
+ current_context = g_variant_ref (service->current_user_context);
- /* finish the isolate unit call */
- if (!systemd_manager_call_start_unit_finish (job->service->systemd_manager,
- &job_name, result, &error))
+ /* prepare app lists for all LUC types present in the current context */
+ g_variant_iter_init (&viter, current_context);
+ while (g_variant_iter_loop (&viter, "{ias}", &luc_type, NULL))
{
- /* there was an error; let the caller know */
- job->callback (job->service, job->unit, "failed", error, job->user_data);
- g_error_free (error);
- g_free (job_name);
+ dup_luc_type = g_new0(gint, 1);
+ *dup_luc_type = luc_type;
- /* finish the job immediately */
- boot_manager_service_job_unref (job);
- }
- else
- {
- /* remember the job so that we can finish it in the "job-removed" signal
- * handler. the service takes ownership of the job so we don't need to
- * unref it here */
- boot_manager_service_remember_job (job->service, job_name, job);
+ g_hash_table_insert (table, dup_luc_type,
+ g_ptr_array_new_with_free_func (g_free));
}
-}
-
-
-
-static gboolean
-boot_manager_service_handle_list (BootManager *interface,
- GDBusMethodInvocation *invocation,
- BootManagerService *service)
-{
- GCancellable *cancellable;
-
- g_return_val_if_fail (IS_BOOT_MANAGER (interface), FALSE);
- g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);
- g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (service), FALSE);
-
- /* create a new cancellable so that we can cancel this list call */
- cancellable = g_cancellable_new ();
-
- /* store the cancellable in the cancellables GHashTable */
- g_hash_table_insert (service->cancellables, g_object_ref (invocation), cancellable);
-
- /* ask systemd to list all its units, send a D-Bus reply in the finish callback */
- boot_manager_service_list (service, cancellable, boot_manager_service_handle_list_finish,
- invocation);
-
- return TRUE;
-}
-
-
-
-static void
-boot_manager_service_handle_list_finish (BootManagerService *service,
- const gchar *const *result,
- GError *error,
- gpointer user_data)
-{
- GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (user_data);
-
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (result != NULL);
- g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
-
- /* log any potential errors */
- if (error != NULL)
- g_warning ("there was an error: %s", error->message);
-
- /* remove this cancellable now the job has finished */
- g_hash_table_remove (service->cancellables, invocation);
-
- /* report the result back to the boot manager client */
- boot_manager_complete_list (service->interface, invocation, result);
-}
-
-
-static void
-boot_manager_service_list_units_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- BootManagerServiceJob *job = user_data;
- GVariantIter iter;
- GVariant *units = NULL;
- GError *error = NULL;
- gchar **output = NULL;
- guint n;
- guint i;
-
- g_return_if_fail (IS_SYSTEMD_MANAGER (object));
- g_return_if_fail (G_IS_ASYNC_RESULT (result));
- g_return_if_fail (user_data != NULL);
-
- /* finish the list units call */
- if (!systemd_manager_call_list_units_finish (job->service->systemd_manager, &units,
- result, &error))
- {
- /* there was an error; build the result as failure response */
- output = g_malloc (sizeof (gchar *));
- output[0] = NULL;
- }
- else
+ /* add app lists for LUC types that are needed for the newly registered apps */
+ g_variant_iter_init (&viter, apps);
+ while (g_variant_iter_loop (&viter, "{ias}", &luc_type, NULL))
{
- /* it was successful; build the result from the GVariant units */
- n = g_variant_n_children (units);
- i = 0;
+ dup_luc_type = g_new0(gint, 1);
+ *dup_luc_type = luc_type;
- /* output is a null-terminated strv */
- output = g_malloc (sizeof (gchar *) * (n + 1));
+ g_hash_table_insert (table, dup_luc_type,
+ g_ptr_array_new_with_free_func (g_free));
+ }
- g_variant_iter_init (&iter, units);
+ /* we now have a hash table that has all LUC types involved in the
+ * current context and in the newly registered apps */
- /* fill output with the first element of every list entry */
- while (g_variant_iter_next (&iter, "(ssssssouso)", &output[i], NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL))
+ /* fill the app lists for each LUC type involved, make sure that newly registered
+ * apps are added at the end so that they are "prioritized" */
+ g_hash_table_iter_init (&hiter, table);
+ while (g_hash_table_iter_next (&hiter, (gpointer) &dup_luc_type, (gpointer) &apps_array))
+ {
+ /* get apps currently registered for the LUC type */
+ current_apps = g_variant_lookup_value_with_int_key (current_context,
+ *dup_luc_type,
+ G_VARIANT_TYPE_STRING_ARRAY);
+
+ /* get apps to be registered for the LUC type now */
+ new_apps = g_variant_lookup_value_with_int_key (apps,
+ *dup_luc_type,
+ G_VARIANT_TYPE_STRING_ARRAY);
+
+ /* add all currently registered apps unless they are to be registered now.
+ * this is because we want apps to be registered now to be moved to the end
+ * of the lists */
+ for (n = 0; current_apps != NULL && n < g_variant_n_children (current_apps); n++)
{
- i++;
+ g_variant_get_child (current_apps, n, "&s", &app);
+ if (!g_variant_string_array_has_string (new_apps, app))
+ g_ptr_array_add (apps_array, g_strdup (app));
}
- /* null-terminate output */
- output[i] = NULL;
- }
-
- /* let the caller know the result */
- job->list_callback (job->service, (const gchar *const *)output, error, job->user_data);
-
- /* clean up */
- if (error != NULL)
- g_error_free (error);
-
- g_strfreev (output);
- boot_manager_service_job_unref (job);
-}
-
-
-
-static void
-boot_manager_service_job_removed (SystemdManager *manager,
- guint id,
- const gchar *job_name,
- const gchar *result,
- BootManagerService *service)
-{
- BootManagerServiceJob *job;
-
- g_return_if_fail (IS_SYSTEMD_MANAGER (manager));
- g_return_if_fail (job_name != NULL && *job_name != '\0');
- g_return_if_fail (result != NULL && *result != '\0');
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
-
- /* lookup the rememebred job for this job name */
- job = g_hash_table_lookup (service->jobs, job_name);
-
- /* if there is no such job, just ignore this job-removed signal */
- if (job == NULL)
- return;
-
- /* finish the job by notifying the caller */
- job->callback (service, job->unit, result, NULL, job->user_data);
-
- /* forget about this job; this will unref the job */
- boot_manager_service_forget_job (service, job_name);
-}
-
-
-
-static BootManagerServiceJob *
-boot_manager_service_job_new (BootManagerService *service,
- const gchar *unit,
- GCancellable *cancellable,
- BootManagerServiceCallback callback,
- BootManagerServiceListCallback list_callback,
- gpointer user_data)
-{
- BootManagerServiceJob *job;
-
- g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (service), NULL);
- g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
-
- /* allocate a new job struct */
- job = g_slice_new0 (BootManagerServiceJob);
- job->service = g_object_ref (service);
- job->unit = g_strdup (unit);
- if (cancellable != NULL)
- job->cancellable = g_object_ref (cancellable);
- job->callback = callback;
- job->list_callback = list_callback;
- job->user_data = user_data;
-
- return job;
-}
-
+ /* add all newly registered apps at the end now */
+ for (n = 0; new_apps != NULL && n < g_variant_n_children (new_apps); n++)
+ {
+ g_variant_get_child (new_apps, n, "&s", &app);
+ g_ptr_array_add (apps_array, g_strdup (app));
+ }
-static void
-boot_manager_service_job_unref (BootManagerServiceJob *job)
-{
- if (job == NULL)
- return;
-
- /* release all memory and references held by the job */
- if (job->cancellable != NULL)
- g_object_unref (job->cancellable);
- g_free (job->unit);
- g_object_unref (job->service);
- g_slice_free (BootManagerServiceJob, job);
-}
-
+ /* release app lists for this LUC type */
+ if (current_apps != NULL)
+ g_variant_unref (current_apps);
+ if (new_apps != NULL)
+ g_variant_unref (new_apps);
+ }
+ /* construct a new dictionary variant for the new LUC */
+ g_variant_builder_init (&dict_builder, G_VARIANT_TYPE ("a{ias}"));
-static void
-boot_manager_service_remember_job (BootManagerService *service,
- const gchar *job_name,
- BootManagerServiceJob *job)
-{
- BootManagerServiceJob *existing_job;
+ /* copy LUC types and corresponding apps over to the new context.
+ * make sure the order in which we add LUC types to the context
+ * dict is always the same. this is helpful for testing */
+ luc_types = g_hash_table_get_keys (table);
+ luc_types = g_list_sort (luc_types, (GCompareFunc) g_int_compare);
+ for (lp = luc_types; lp != NULL; lp = lp->next)
+ {
+ builder_luc_type = *(gint*) lp->data;
+ /* get the apps list registered for this LUC type */
+ apps_array = g_hash_table_lookup (table, lp->data);
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (job_name != NULL && *job_name != '\0');
- g_return_if_fail (job != NULL);
+ /* NULL-terminate the pointer so that we can treat it as a gchar ** */
+ g_ptr_array_add (apps_array, NULL);
- /* if the job is already being remembered, then there is a programming
- * mistake and we should make people aware of it */
- existing_job = g_hash_table_lookup (service->jobs, job_name);
- if (existing_job != NULL)
- {
- g_critical ("trying to remember the same job twice");
- return;
+ /* add the LUC type and its apps to the new context */
+ g_variant_builder_add (&dict_builder, "{i^as}", builder_luc_type, apps_array->pdata);
}
- /* associate the job name with the job */
- g_hash_table_insert (service->jobs, g_strdup (job_name), job);
-}
-
+ /* free the LUC types and our LUC type to apps mapping */
+ g_list_free (luc_types);
+ g_hash_table_unref (table);
+ /* free the last user context */
+ g_variant_unref (service->current_user_context);
-static void
-boot_manager_service_forget_job (BootManagerService *service,
- const gchar *job_name)
-{
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (job_name != NULL && *job_name != '\0');
+ /* apply the new last user context */
+ service->current_user_context = g_variant_builder_end (&dict_builder);
- g_hash_table_remove (service->jobs, job_name);
-}
+ /* log the new last user context */
+ debug_text = g_variant_print (service->current_user_context, TRUE);
+ log_text = g_strdup_printf ("The new context is: %s", debug_text);
+ DLT_LOG (boot_manager_context, DLT_LOG_DEBUG, DLT_STRING (log_text));
+ g_free (debug_text);
+ g_free (log_text);
+ /* release the current context */
+ g_variant_unref (current_context);
+ /* notify the caller that we have handled the register request */
+ g_dbus_method_invocation_return_value (invocation, NULL);
-static void
-boot_manager_service_cancel_task (gpointer key,
- GCancellable *cancellable,
- gpointer user_data)
-{
- g_cancellable_cancel (cancellable);
+ return TRUE;
}
BootManagerService *
-boot_manager_service_new (GDBusConnection *connection,
- SystemdManager *systemd_manager)
+boot_manager_service_new (GDBusConnection *connection)
{
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
- g_return_val_if_fail (IS_SYSTEMD_MANAGER (systemd_manager), NULL);
return g_object_new (BOOT_MANAGER_TYPE_SERVICE,
"connection", connection,
- "systemd-manager", systemd_manager,
NULL);
}
g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (service), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- /* announce the org.genivi.BootManager1 service on the bus */
+ /* announce the org.genivi.BootManager1.BootManager service on the bus */
return g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (service->interface),
service->connection,
- "/org/genivi/BootManager1",
+ "/org/genivi/BootManager1/BootManager",
error);
}
-void
-boot_manager_service_start (BootManagerService *service,
- const gchar *unit,
- GCancellable *cancellable,
- BootManagerServiceCallback callback,
- gpointer user_data)
-{
- BootManagerServiceJob *job;
-
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (unit != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- g_return_if_fail (callback != NULL);
-
- /* create a new job object */
- job = boot_manager_service_job_new (service, unit, cancellable, callback, NULL,
- user_data);
-
- /* ask systemd to start the unit asynchronously */
- systemd_manager_call_start_unit (service->systemd_manager, unit, "fail", cancellable,
- boot_manager_service_start_unit_reply, job);
-}
-
-
-
-void
-boot_manager_service_stop (BootManagerService *service,
- const gchar *unit,
- GCancellable *cancellable,
- BootManagerServiceCallback callback,
- gpointer user_data)
-{
- BootManagerServiceJob *job;
-
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (unit != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- g_return_if_fail (callback != NULL);
-
- /* create a new job object */
- job = boot_manager_service_job_new (service, unit, cancellable, callback, NULL,
- user_data);
-
- /* ask systemd to stop the unit asynchronously */
- systemd_manager_call_stop_unit (service->systemd_manager, unit, "fail", cancellable,
- boot_manager_service_stop_unit_reply, job);
-}
-
-
-
-void
-boot_manager_service_kill (BootManagerService *service,
- const gchar *unit,
- GCancellable *cancellable,
- BootManagerServiceCallback callback,
- gpointer user_data)
+GVariant *
+boot_manager_service_read_luc (BootManagerService *service,
+ GError **error)
{
- BootManagerServiceJob *job;
-
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (unit != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- g_return_if_fail (callback != NULL);
-
- /* create a new job object */
- job = boot_manager_service_job_new (service, unit, cancellable, callback, NULL,
- user_data);
-
- /* ask systemd to stop the unit asynchronously */
- systemd_manager_call_kill_unit (service->systemd_manager, unit, "all", "control-group",
- SIGKILL, cancellable,
- boot_manager_service_kill_unit_reply, job);
-}
+ GVariant *context;
+ GFile *luc_file;
+ char *data;
+ gsize data_len;
+ g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (service), NULL);
+ g_return_val_if_fail ((error == NULL || *error == NULL), NULL);
+ /* initialize the GFile */
+ luc_file = g_file_new_for_path (LUCPATH);
-void
-boot_manager_service_restart (BootManagerService *service,
- const gchar *unit,
- GCancellable *cancellable,
- BootManagerServiceCallback callback,
- gpointer user_data)
-{
- BootManagerServiceJob *job;
+ /* read the contents of the file */
+ if (!g_file_load_contents (luc_file, NULL, &data, &data_len, NULL, error))
+ {
+ g_object_unref (luc_file);
+ return NULL;
+ }
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (unit != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- g_return_if_fail (callback != NULL);
+ /* store the contents of the file in a GVariant */
+ context = g_variant_new_from_data (G_VARIANT_TYPE ("a{ias}"), data, data_len,
+ TRUE, g_free, data);
- /* create a new job object */
- job = boot_manager_service_job_new (service, unit, cancellable, callback, NULL,
- user_data);
+ g_object_unref (luc_file);
- /* ask systemd to restart the unit asynchronously */
- systemd_manager_call_restart_unit (service->systemd_manager, unit, "fail", cancellable,
- boot_manager_service_restart_unit_reply, job);
+ return context;
}
void
-boot_manager_service_isolate (BootManagerService *service,
- const gchar *unit,
- GCancellable *cancellable,
- BootManagerServiceCallback callback,
- gpointer user_data)
+boot_manager_service_write_luc (BootManagerService *service,
+ GError **error)
{
- BootManagerServiceJob *job;
+ GFileOutputStream *stream = NULL;
+ GError *error_file = NULL;
+ GFile *luc_file;
+ GFile *luc_dir;
g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (unit != NULL);
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- g_return_if_fail (callback != NULL);
-
- /* create a new job object */
- job = boot_manager_service_job_new (service, unit, cancellable, callback, NULL,
- user_data);
-
- /* ask systemd to isolate the unit asynchronously */
- systemd_manager_call_start_unit (service->systemd_manager, unit, "isolate",
- cancellable, boot_manager_service_isolate_unit_reply,
- job);
-}
-
-
+ g_return_if_fail (error == NULL || *error == NULL);
-void
-boot_manager_service_list (BootManagerService *service,
- GCancellable *cancellable,
- BootManagerServiceListCallback list_callback,
- gpointer user_data)
-{
- BootManagerServiceJob *job;
+ /* initialize the GFiles */
+ luc_file = g_file_new_for_path (LUCPATH);
+ luc_dir = g_file_new_for_path (LUCDIR);
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
- g_return_if_fail (list_callback != NULL);
+ /* make sure the last user context's directory exists */
+ g_file_make_directory_with_parents (luc_dir, NULL, &error_file);
+ if (error_file != NULL)
+ {
+ if (error_file->code != G_IO_ERROR_EXISTS)
+ {
+ *error = g_error_copy (error_file);
+ g_error_free (error_file);
+ g_object_unref (luc_file);
+ g_object_unref (luc_dir);
+ return;
+ }
+ else
+ {
+ g_error_free (error_file);
+ error_file = NULL;
+ }
+ }
- /* create a new job object */
- job = boot_manager_service_job_new (service, NULL, cancellable, NULL, list_callback,
- user_data);
+ /* try to create the file. It is fine if this already exists */
+ stream = g_file_create (luc_file, G_FILE_CREATE_NONE, NULL, &error_file);
+ if (error_file != NULL)
+ {
+ if (error_file->code != G_IO_ERROR_EXISTS)
+ {
+ *error = g_error_copy (error_file);
+ g_error_free (error_file);
+ g_object_unref (luc_file);
+ g_object_unref (luc_dir);
+ return;
+ }
+ else
+ {
+ g_error_free (error_file);
+ error_file = NULL;
+ }
+ }
+ else
+ {
+ g_object_unref (stream);
+ }
- /* ask systemd to list units asynchronously */
- systemd_manager_call_list_units (service->systemd_manager, cancellable,
- boot_manager_service_list_units_reply, job);
-}
+ /* replace the contents with that of the new file. g_file_replace_contents guarantees
+ * atomic overwriting and can make backups */
+ g_file_replace_contents (luc_file, g_variant_get_data (service->current_user_context),
+ g_variant_get_size (service->current_user_context), NULL,
+ TRUE, G_FILE_CREATE_NONE, NULL, NULL, error);
-void
-boot_manager_service_cancel (BootManagerService *service)
-{
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
+ /* release the GFiles */
+ g_object_unref (luc_file);
+ g_object_unref (luc_dir);
- /* cancel all listed cancellables */
- g_hash_table_foreach (service->cancellables,
- (GHFunc) boot_manager_service_cancel_task, NULL);
+ /* clear the current user context */
+ g_variant_unref (service->current_user_context);
+ service->current_user_context = NULL;
}
#ifndef __BOOT_MANAGER_SERVICE_H__
#define __BOOT_MANAGER_SERVICE_H__
+#include <gio/gio.h>
+
#include <boot-manager/systemd-manager-dbus.h>
G_BEGIN_DECLS
typedef struct _BootManagerServiceClass BootManagerServiceClass;
typedef struct _BootManagerService BootManagerService;
-typedef void (*BootManagerServiceCallback) (BootManagerService *service,
- const gchar *unit,
- const gchar *result,
- GError *error,
- gpointer user_data);
-typedef void (*BootManagerServiceListCallback) (BootManagerService *service,
- const gchar *const *result,
- GError *error,
- gpointer user_data);
-GType boot_manager_service_get_type (void) G_GNUC_CONST;
+GType boot_manager_service_get_type (void) G_GNUC_CONST;
+
+BootManagerService *boot_manager_service_new (GDBusConnection *connection) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+gboolean boot_manager_service_start_up (BootManagerService *service,
+ GError **error);
+GVariant *boot_manager_service_read_luc (BootManagerService *service,
+ GError **error);
+void boot_manager_service_write_luc (BootManagerService *service,
+ GError **error);
-BootManagerService *boot_manager_service_new (GDBusConnection *connection,
- SystemdManager *systemd_manager) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-gboolean boot_manager_service_start_up (BootManagerService *service,
- GError **error);
-void boot_manager_service_start (BootManagerService *service,
- const gchar *unit,
- GCancellable *cancellable,
- BootManagerServiceCallback callback,
- gpointer user_data);
-void boot_manager_service_stop (BootManagerService *service,
- const gchar *unit,
- GCancellable *cancellable,
- BootManagerServiceCallback callback,
- gpointer user_data);
-void boot_manager_service_kill (BootManagerService *service,
- const gchar *unit,
- GCancellable *cancellable,
- BootManagerServiceCallback callback,
- gpointer user_data);
-void boot_manager_service_restart (BootManagerService *service,
- const gchar *unit,
- GCancellable *cancellable,
- BootManagerServiceCallback callback,
- gpointer user_data);
-void boot_manager_service_isolate (BootManagerService *service,
- const gchar *unit,
- GCancellable *cancellable,
- BootManagerServiceCallback callback,
- gpointer user_data);
-void boot_manager_service_list (BootManagerService *service,
- GCancellable *cancellable,
- BootManagerServiceListCallback list_callback,
- gpointer user_data);
-void boot_manager_service_cancel (BootManagerService *service);
G_END_DECLS
--- /dev/null
+# vi:set ts=8 sw=8 noet ai nocindent:
+
+boot_manager_confdir = /etc/dbus-1/system.d
+
+boot_manager_conf_DATA = \
+ org.genivi.BootManager1.conf
+
+
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="root">
- <allow own="org.genivi.LegacyAppHandler1"/>
- <allow send_destination="org.genivi.LegacyAppHandler1" />
- <allow receive_sender="org.genivi.LegacyAppHandler1" />
+ <allow own="org.genivi.BootManager1"/>
+ <allow send_destination="org.genivi.BootManager1" />
+ <allow receive_sender="org.genivi.BootManager1" />
</policy>
</busconfig>
bus_servicedir = $(datadir)/dbus-1/system-services
bus_service_in_files = \
- org.genivi.LegacyAppHandler1.service.in
+ org.genivi.BootManager1.service.in
bus_service_DATA = $(bus_service_in_files:.service.in=.service)
[D-BUS Service]
Name=org.genivi.BootManager1
+SystemdService = org.genivi.BootManager1.service
Exec=@libdir@/boot-manager-@BOOT_MANAGER_VERSION_API@/boot-manager
--- /dev/null
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/* -
+ * Copyright (c) 2012 GENIVI.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+
+#include <boot-manager/glib-extensions.h>
+
+
+
+GVariant *
+g_variant_lookup_value_with_int_key (GVariant *dictionary,
+ const gint key,
+ const GVariantType *expected_type)
+{
+ GVariantIter iter;
+ GVariant *entry;
+ GVariant *entry_key;
+ GVariant *tmp;
+ GVariant *value;
+ gboolean matches;
+
+ g_return_val_if_fail (g_variant_is_of_type (dictionary, G_VARIANT_TYPE ("a{i*}")),
+ NULL);
+
+ g_variant_iter_init (&iter, dictionary);
+
+ while ((entry = g_variant_iter_next_value (&iter)))
+ {
+ entry_key = g_variant_get_child_value (entry, 0);
+ matches = (g_variant_get_int32(entry_key) == key);
+ g_variant_unref (entry_key);
+
+ if (matches)
+ break;
+
+ g_variant_unref (entry);
+ }
+
+ if (entry == NULL)
+ return NULL;
+
+ value = g_variant_get_child_value (entry, 1);
+ g_variant_unref (entry);
+
+ if (g_variant_is_of_type (value, G_VARIANT_TYPE_VARIANT))
+ {
+ tmp = g_variant_get_variant (value);
+ g_variant_unref (value);
+
+ if (expected_type && !g_variant_is_of_type (tmp, expected_type))
+ {
+ g_variant_unref (tmp);
+ tmp = NULL;
+ }
+
+ value = tmp;
+ }
+
+ g_return_val_if_fail (expected_type == NULL || value == NULL ||
+ g_variant_is_of_type (value, expected_type), NULL);
+
+ return value;
+}
+
+
+
+gboolean
+g_variant_string_array_has_string (GVariant *array,
+ const gchar *str)
+{
+ gboolean found = FALSE;
+ gchar *current_str;
+ guint n;
+
+ for (n = 0; array != NULL && !found && n < g_variant_n_children (array); n++)
+ {
+ g_variant_get_child (array, n, "&s", ¤t_str);
+ if (g_strcmp0 (str, current_str) == 0)
+ found = TRUE;
+ }
+
+ return found;
+}
+
+
+gint
+g_int_compare (gconstpointer a, gconstpointer b)
+{
+ const gint *a1 = a;
+ const gint *b1 = b;
+
+ return (*a1 - *b1);
+}
--- /dev/null
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/* -
+ * Copyright (c) 2012 GENIVI.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef __GLIB_EXTENSIONS_H__
+#define __GLIB_EXTENSIONS_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+gint g_int_compare (gconstpointer a,
+ gconstpointer b);
+GVariant *g_variant_lookup_value_with_int_key (GVariant *dictionary,
+ const gint key,
+ const GVariantType *expected_type);
+gboolean g_variant_string_array_has_string (GVariant *array,
+ const gchar *str);
+
+G_END_DECLS
+
+#endif /* !__GLIB_EXTENSION_H__ */
--- /dev/null
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/* -
+ * Copyright (c) 2012 GENIVI.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include <boot-manager/job-manager.h>
+#include <boot-manager/systemd-manager-dbus.h>
+
+
+
+typedef struct _JobManagerJob JobManagerJob;
+
+
+
+/* property identifiers */
+enum
+{
+ PROP_0,
+ PROP_CONNECTION,
+ PROP_SYSTEMD_MANAGER,
+};
+
+
+
+static void job_manager_constructed (GObject *object);
+static void job_manager_finalize (GObject *object);
+static void job_manager_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void job_manager_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void job_manager_start_unit_reply (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data);
+static void job_manager_stop_unit_reply (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data);
+static void job_manager_job_removed (SystemdManager *systemd_manager,
+ guint id,
+ const gchar *job_name,
+ const gchar *result,
+ JobManager *job_manager);
+static JobManagerJob *job_manager_job_new (JobManager *manager,
+ const gchar *unit,
+ GCancellable *cancellable,
+ JobManagerCallback callback,
+ gpointer user_data);
+static void job_manager_job_unref (JobManagerJob *job);
+static void job_manager_remember_job (JobManager *manager,
+ const gchar *job_name,
+ JobManagerJob *job);
+static void job_manager_forget_job (JobManager *manager,
+ const gchar *job_name);
+
+struct _JobManagerClass
+{
+ GObjectClass __parent__;
+};
+
+struct _JobManager
+{
+ GObject __parent__;
+
+ GDBusConnection *connection;
+ SystemdManager *systemd_manager;
+
+ GHashTable *jobs;
+};
+
+struct _JobManagerJob
+{
+ JobManager *manager;
+ gchar *unit;
+ GCancellable *cancellable;
+ JobManagerCallback callback;
+ gpointer user_data;
+};
+
+
+
+G_DEFINE_TYPE (JobManager, job_manager, G_TYPE_OBJECT);
+
+
+
+static void
+job_manager_class_init (JobManagerClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = job_manager_finalize;
+ gobject_class->constructed = job_manager_constructed;
+ gobject_class->get_property = job_manager_get_property;
+ gobject_class->set_property = job_manager_set_property;
+
+ g_object_class_install_property (gobject_class,
+ PROP_CONNECTION,
+ g_param_spec_object ("connection",
+ "connection",
+ "connection",
+ G_TYPE_DBUS_CONNECTION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SYSTEMD_MANAGER,
+ g_param_spec_object ("systemd-manager",
+ "systemd-manager",
+ "systemd-manager",
+ TYPE_SYSTEMD_MANAGER,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+}
+
+
+
+static void
+job_manager_init (JobManager *manager)
+{
+ /* create a mapping of systemd job names to job objects; we will use this
+ * to remember jobs that we started */
+ manager->jobs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+ (GDestroyNotify) job_manager_job_unref);
+
+}
+
+
+
+static void
+job_manager_finalize (GObject *object)
+{
+ JobManager *manager = JOB_MANAGER (object);
+
+ /* release all the jobs we have remembered */
+ g_hash_table_unref (manager->jobs);
+
+ /* release the D-Bus connection */
+ g_object_unref (manager->connection);
+
+ /* release the systemd manager */
+ g_signal_handlers_disconnect_matched (manager->systemd_manager,
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, manager);
+ g_object_unref (manager->systemd_manager);
+
+ /* chain up to finalize parent class */
+ (*G_OBJECT_CLASS (job_manager_parent_class)->finalize) (object);
+}
+
+
+
+static void
+job_manager_constructed (GObject *object)
+{
+ JobManager *manager = JOB_MANAGER (object);
+
+ /* connect to systemd's "JobRemoved" signal so that we are notified whenever a job is
+ * finished */
+ g_signal_connect (manager->systemd_manager, "job-removed",
+ G_CALLBACK (job_manager_job_removed), manager);
+}
+
+
+
+static void
+job_manager_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ JobManager *manager = JOB_MANAGER (object);
+
+ switch (prop_id)
+ {
+ case PROP_CONNECTION:
+ g_value_set_object (value, manager->connection);
+ break;
+ case PROP_SYSTEMD_MANAGER:
+ g_value_set_object (value, manager->systemd_manager);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+
+static void
+job_manager_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ JobManager *manager = JOB_MANAGER (object);
+
+ switch (prop_id)
+ {
+ case PROP_CONNECTION:
+ manager->connection = g_value_dup_object (value);
+ break;
+ case PROP_SYSTEMD_MANAGER:
+ manager->systemd_manager = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+
+static void
+job_manager_start_unit_reply (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ JobManagerJob *job = user_data;
+ GError *error = NULL;
+ gchar *job_name = NULL;
+
+ g_return_if_fail (IS_SYSTEMD_MANAGER (object));
+ g_return_if_fail (G_IS_ASYNC_RESULT (result));
+ g_return_if_fail (user_data != NULL);
+
+ /* finish the start unit call */
+ if (!systemd_manager_call_start_unit_finish (job->manager->systemd_manager,
+ &job_name, result, &error))
+ {
+ /* there was an error. notify the caller */
+ job->callback (job->manager, job->unit, "failed", error, job->user_data);
+ g_error_free (error);
+ g_free (job_name);
+
+ /* finish the job immediately */
+ job_manager_job_unref (job);
+ }
+ else
+ {
+ /* remember the job so that we can finish it in the "job-removed" signal handler.
+ * the service takes ownership of the job so we don't need to unref it here */
+ job_manager_remember_job (job->manager, job_name, job);
+ }
+}
+
+
+
+static void
+job_manager_stop_unit_reply (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ JobManagerJob *job = user_data;
+ GError *error = NULL;
+ gchar *job_name = NULL;
+
+ g_return_if_fail (IS_SYSTEMD_MANAGER (object));
+ g_return_if_fail (G_IS_ASYNC_RESULT (result));
+ g_return_if_fail (user_data != NULL);
+
+ /* finish the stop unit call */
+ if (!systemd_manager_call_stop_unit_finish (job->manager->systemd_manager,
+ &job_name, result, &error))
+ {
+ /* there was an error. notify the caller */
+ job->callback (job->manager, job->unit, "failed", error, job->user_data);
+ g_error_free (error);
+ g_free (job_name);
+
+ /* finish the job immediately */
+ job_manager_job_unref (job);
+ }
+ else
+ {
+ /* remember the job so that we can finish it in the "job-removed" signal handler.
+ * the service takes ownership of the job so we don't need to unref it here */
+ job_manager_remember_job (job->manager, job_name, job);
+ }
+}
+
+
+
+static void
+job_manager_job_removed (SystemdManager *systemd_manager,
+ guint id,
+ const gchar *job_name,
+ const gchar *result,
+ JobManager *job_manager)
+{
+ JobManagerJob *job;
+
+ g_return_if_fail (IS_SYSTEMD_MANAGER (systemd_manager));
+ g_return_if_fail (job_name != NULL && *job_name != '\0');
+ g_return_if_fail (result != NULL && *result != '\0');
+ g_return_if_fail (IS_JOB_MANAGER (job_manager));
+
+ /* look up the remembered job for this job name */
+ job = g_hash_table_lookup (job_manager->jobs, job_name);
+
+ /* if no job is found, ignore this job-removed signal */
+ if (job == NULL)
+ return;
+
+ /* finish the job by notifying the caller */
+ job->callback (job_manager, job->unit, result, NULL, job->user_data);
+
+ /* forget about this job */
+ job_manager_forget_job (job_manager, job_name);
+}
+
+
+
+static JobManagerJob *
+job_manager_job_new (JobManager *manager,
+ const gchar *unit,
+ GCancellable *cancellable,
+ JobManagerCallback callback,
+ gpointer user_data)
+{
+ JobManagerJob *job;
+
+ g_return_val_if_fail (IS_JOB_MANAGER (manager), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+
+ /* allocate a new job struct */
+ job = g_slice_new0 (JobManagerJob);
+ job->manager = g_object_ref (manager);
+ job->unit = g_strdup(unit);
+ if (cancellable != NULL)
+ job->cancellable = g_object_ref (cancellable);
+ job->callback = callback;
+ job->user_data = user_data;
+
+ return job;
+}
+
+
+static void
+job_manager_job_unref (JobManagerJob *job)
+{
+ if (job == NULL)
+ return;
+
+ /* release all memory and references held by job */
+ if (job->cancellable != NULL)
+ g_object_unref (job->cancellable);
+ g_free (job->unit);
+ g_object_unref (job->manager);
+ g_slice_free (JobManagerJob, job);
+}
+
+
+
+static void
+job_manager_remember_job (JobManager *manager,
+ const char *job_name,
+ JobManagerJob *job)
+{
+ JobManagerJob *existing_job;
+
+ g_return_if_fail (IS_JOB_MANAGER (manager));
+ g_return_if_fail (job_name != NULL && *job_name != '\0');
+ g_return_if_fail (job != NULL);
+
+ /* if the job is already being remembered, there is a programming error that should be
+ * notified */
+ existing_job = g_hash_table_lookup (manager->jobs, job_name);
+ if (existing_job != NULL)
+ {
+ g_critical ("Trying to remember the same job twice.");
+ return;
+ }
+ /* associate the job name with the job */
+ g_hash_table_insert (manager->jobs, g_strdup (job_name), job);
+}
+
+
+
+static void
+job_manager_forget_job (JobManager *manager,
+ const gchar *job_name)
+{
+ g_return_if_fail (IS_JOB_MANAGER (manager));
+ g_return_if_fail (job_name != NULL && *job_name != '\0');
+
+ g_hash_table_remove (manager->jobs, job_name);
+}
+
+
+
+JobManager *
+job_manager_new (GDBusConnection *connection,
+ SystemdManager *systemd_manager)
+{
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
+ g_return_val_if_fail (IS_SYSTEMD_MANAGER (systemd_manager), NULL);
+
+ return g_object_new (TYPE_JOB_MANAGER,
+ "connection", connection,
+ "systemd-manager", systemd_manager,
+ NULL);
+}
+
+
+
+void
+job_manager_start (JobManager *manager,
+ const gchar *unit,
+ GCancellable *cancellable,
+ JobManagerCallback callback,
+ gpointer user_data)
+{
+ JobManagerJob *job;
+
+ g_return_if_fail (IS_JOB_MANAGER (manager));
+ g_return_if_fail (unit != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (callback != NULL);
+
+ /* create a new job object */
+ job = job_manager_job_new (manager, unit, cancellable, callback, user_data);
+
+ /* ask systemd to start the unit asynchronously */
+ systemd_manager_call_start_unit (manager->systemd_manager, unit, "fail", cancellable,
+ job_manager_start_unit_reply, job);
+}
+
+
+
+void
+job_manager_stop (JobManager *manager,
+ const gchar *unit,
+ GCancellable *cancellable,
+ JobManagerCallback callback,
+ gpointer user_data)
+{
+ JobManagerJob *job;
+
+ g_return_if_fail (IS_JOB_MANAGER (manager));
+ g_return_if_fail (unit != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (callback != NULL);
+
+ /* create a new job object */
+ job = job_manager_job_new (manager, unit, cancellable, callback, user_data);
+
+ /* ask systemd to stop the unit asynchronously */
+ systemd_manager_call_stop_unit (manager->systemd_manager, unit, "fail", cancellable,
+ job_manager_stop_unit_reply, job);
+}
--- /dev/null
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/* -
+ * Copyright (c) 2012 GENIVI.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef __JOB_MANAGER_H__
+#define __JOB_MANAGER_H__
+
+#include <boot-manager/systemd-manager-dbus.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_JOB_MANAGER (job_manager_get_type())
+#define JOB_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_JOB_MANAGER, JobManager))
+#define JOB_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_JOB_MANAGER, JobManagerClass))
+#define IS_JOB_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_JOB_MANAGER))
+#define IS_JOB_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass, TYPE_JOB_MANAGER))
+#define JOB_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj, TYPE_JOB_MANAGER, JobManagerClass))
+
+typedef struct _JobManagerClass JobManagerClass;
+typedef struct _JobManager JobManager;
+
+typedef void (*JobManagerCallback) (JobManager *manager,
+ const gchar *unit,
+ const gchar *result,
+ GError *error,
+ gpointer user_data);
+
+GType job_manager_get_type (void) G_GNUC_CONST;
+JobManager *job_manager_new (GDBusConnection *connection,
+ SystemdManager *systemd_manager) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+void job_manager_start (JobManager *manager,
+ const gchar *unit,
+ GCancellable *cancellable,
+ JobManagerCallback callback,
+ gpointer user_data);
+void job_manager_stop (JobManager *manager,
+ const gchar *unit,
+ GCancellable *cancellable,
+ JobManagerCallback callback,
+ gpointer user_data);
+
+G_END_DECLS
+
+#endif /* !__JOB_MANAGER_H__ */
<?xml version="1.0" encoding="UTF-8"?>
-<node name="/org/genivi/LegacyAppHandler1">
+<node name="/org/genivi/BootManager1/LegacyAppHandler">
<!--
org.genivi.LegacyAppHandler1:
@short_description: Interface for registering legacy apps with the NSM
performs a shutdown it can shut down the application in reverse
order of their creation.
-->
- <interface name="org.genivi.LegacyAppHandler1">
+ <interface name="org.genivi.BootManager1.LegacyAppHandler">
<!--
Register:
@unit: An application unit filename.
#include <dlt/dlt.h>
-#include <common/boot-manager-dbus.h>
-#include <common/glib-extensions.h>
-#include <common/shutdown-consumer-service.h>
-
-#include <legacy-app-handler/la-handler-dbus.h>
-#include <legacy-app-handler/la-handler-service.h>
+#include <boot-manager/job-manager.h>
+#include <boot-manager/la-handler-dbus.h>
+#include <boot-manager/la-handler-service.h>
+#include <boot-manager/shutdown-consumer-service.h>
{
PROP_0,
PROP_CONNECTION,
+ PROP_JOB_MANAGER,
};
LAHandlerService *service);
static void la_handler_service_handle_consumer_shutdown (ShutdownConsumerService *interface,
LAHandlerService *service);
-static void la_handler_service_handle_consumer_shutdown_finish (GObject *object,
- GAsyncResult *res,
+static void la_handler_service_handle_consumer_shutdown_finish (JobManager *manager,
+ const gchar *unit,
+ const gchar *result,
+ GError *error,
gpointer user_data);
static LAHandlerServiceConsumerBundle *la_handler_service_consumer_bundle_new (LAHandlerService *la_handler,
ShutdownConsumerService *consumer);
GDBusConnection *connection;
LAHandler *interface;
- BootManager *boot_manager;
+ JobManager *job_manager;
/* list of shutdown consumers */
GList *shutdown_consumers;
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class,
+ PROP_JOB_MANAGER,
+ g_param_spec_object ("job-manager",
+ "Job Manager",
+ "The internal handler of Start()"
+ " and Stop() jobs",
+ TYPE_JOB_MANAGER,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
}
GError *error = NULL;
gchar *log_text;
- /* connect to the boot manager */
- service->boot_manager = boot_manager_proxy_new_sync (service->connection,
- G_DBUS_PROXY_FLAGS_NONE,
- "org.genivi.BootManager1",
- "/org/genivi/BootManager1",
- NULL,
- &error);
if (error != NULL)
{
log_text = g_strdup_printf ("Failed to connect to the boot manager service: %s",
service->index = 1;
/* the string that precedes the index in the shutdown consumer's object path */
- service->prefix = "/org/genivi/lifecycle/LegacyAppHandler1";
+ service->prefix = "/org/genivi/BootManager1/ShutdownConsumer";
/* initialize the list of shutdown consumers */
service->shutdown_consumers = NULL;
0, 0, NULL, NULL, service);
g_object_unref (service->interface);
- /* release the boot manager skeleton */
- g_object_unref (service->boot_manager);
+ /* release the job manager skeleton */
+ g_object_unref (service->job_manager);
/* release the shutdown consumers */
g_list_free_full (service->shutdown_consumers,
case PROP_CONNECTION:
g_value_set_object (value, service->connection);
break;
+ case PROP_JOB_MANAGER:
+ g_value_set_object (value, service->job_manager);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_CONNECTION:
service->connection = g_value_dup_object (value);
break;
+ case PROP_JOB_MANAGER:
+ service->job_manager = g_value_dup_object (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
object_path = shutdown_consumer_service_get_object_path (consumer);
if (g_str_has_prefix (object_path, service->prefix))
{
- /* tell boot manager to stop the unit */
+ /* tell job manager to stop the unit */
unit_name = shutdown_consumer_service_get_unit_name (consumer);
-
bundle = la_handler_service_consumer_bundle_new (service, consumer);
- boot_manager_call_stop (service->boot_manager, unit_name, NULL,
- la_handler_service_handle_consumer_shutdown_finish,
- bundle);
+ job_manager_stop (service->job_manager, unit_name, NULL,
+ la_handler_service_handle_consumer_shutdown_finish, bundle);
}
}
static void
-la_handler_service_handle_consumer_shutdown_finish (GObject *object,
- GAsyncResult *res,
+la_handler_service_handle_consumer_shutdown_finish (JobManager *manager,
+ const gchar *unit,
+ const gchar *result,
+ GError *error,
gpointer user_data)
{
LAHandlerServiceConsumerBundle *bundle = user_data;
- BootManager *proxy = BOOT_MANAGER (object);
- GError *error = NULL;
- gchar *result;
gchar *log_text;
- const gchar *unit_name;
- g_return_if_fail (IS_BOOT_MANAGER (object));
- g_return_if_fail (G_IS_ASYNC_RESULT (res));
+ g_return_if_fail (IS_JOB_MANAGER (manager));
g_return_if_fail (user_data != NULL);
- boot_manager_call_stop_finish (proxy, &result, res, &error);
-
- unit_name = shutdown_consumer_service_get_unit_name (bundle->consumer);
-
/* log any potential errors */
if (error != NULL)
{
log_text =
- g_strdup_printf ("Failed to stop unit \"%s\": %s", unit_name, error->message);
+ g_strdup_printf ("Failed to stop unit \"%s\": %s", unit, error->message);
DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_text));
g_free (log_text);
}
else if (g_strcmp0 (result, "failed") == 0)
{
- log_text = g_strdup_printf ("Failed to stop unit \"%s\"", unit_name);
+ log_text = g_strdup_printf ("Failed to stop unit \"%s\"", unit);
DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_text));
g_free (log_text);
}
}
-
static void
la_handler_service_release_shutdown_consumer (ShutdownConsumerService *service)
{
LAHandlerService *
-la_handler_service_new (GDBusConnection *connection)
+la_handler_service_new (GDBusConnection *connection,
+ JobManager *job_manager)
{
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
- return g_object_new (LA_HANDLER_TYPE_SERVICE, "connection", connection, NULL);
+ g_return_val_if_fail (IS_JOB_MANAGER (job_manager), NULL);
+
+ return g_object_new (LA_HANDLER_TYPE_SERVICE,
+ "connection", connection,
+ "job-manager", job_manager,
+ NULL);
}
g_return_val_if_fail (LA_HANDLER_IS_SERVICE (service), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- /* announce the org.genivi.LegacyAppHandler1 service on the bus */
+ /* announce the org.genivi.BootManager1.LegacyAppHandler service on the bus */
return g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (service->interface),
service->connection,
- "/org/genivi/LegacyAppHandler1",
+ "/org/genivi/BootManager1/LegacyAppHandler",
error);
}
#include <gio/gio.h>
+#include <boot-manager/job-manager.h>
+
G_BEGIN_DECLS
#define LA_HANDLER_TYPE_SERVICE (la_handler_service_get_type ())
GType la_handler_service_get_type (void) G_GNUC_CONST;
-LAHandlerService *la_handler_service_new (GDBusConnection *connection) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+LAHandlerService *la_handler_service_new (GDBusConnection *connection,
+ JobManager *job_manager) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
gboolean la_handler_service_start (LAHandlerService *service,
GError **error);
void la_handler_service_register (LAHandlerService *service,
#include <dlt/dlt.h>
#include <boot-manager/boot-manager-service.h>
+#include <boot-manager/job-manager.h>
#include <boot-manager/luc-starter.h>
-#include <luc-handler/luc-handler-dbus.h>
enum
{
PROP_0,
- PROP_BOOT_MANAGER,
- PROP_LUC_HANDLER,
+ PROP_JOB_MANAGER,
+ PROP_BOOT_MANAGER_SERVICE,
};
static void luc_starter_start_next_group (LUCStarter *starter);
static void luc_starter_start_app (const gchar *app,
LUCStarter *starter);
-static void luc_starter_start_app_finish (BootManagerService *service,
+static void luc_starter_start_app_finish (JobManager *manager,
const gchar *unit,
const gchar *result,
GError *error,
{
GObject __parent__;
- BootManagerService *boot_manager;
- LUCHandler *luc_handler;
+ JobManager *job_manager;
+ BootManagerService *boot_manager_service;
gchar **prioritised_types;
gobject_class->set_property = luc_starter_set_property;
g_object_class_install_property (gobject_class,
- PROP_BOOT_MANAGER,
- g_param_spec_object ("boot-manager",
- "boot-manager",
- "boot-manager",
- BOOT_MANAGER_TYPE_SERVICE,
+ PROP_JOB_MANAGER,
+ g_param_spec_object ("job-manager",
+ "Job Manager",
+ "The internal handler of Start()"
+ " and Stop() jobs",
+ TYPE_JOB_MANAGER,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
- PROP_LUC_HANDLER,
- g_param_spec_object ("luc-handler",
- "luc-handler",
- "luc-handler",
- TYPE_LUC_HANDLER,
+ PROP_BOOT_MANAGER_SERVICE,
+ g_param_spec_object ("boot-manager-service",
+ "boot-manager-service",
+ "boot-manager-service",
+ BOOT_MANAGER_TYPE_SERVICE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/* free the prioritised types array */
g_strfreev (starter->prioritised_types);
- /* release the boot manager */
- g_object_unref (starter->boot_manager);
+ /* release the job manager */
+ g_object_unref (starter->job_manager);
- /* release the LUC handler */
- g_object_unref (starter->luc_handler);
+ /* release the boot manager service */
+ g_object_unref (starter->boot_manager_service);
(*G_OBJECT_CLASS (luc_starter_parent_class)->finalize) (object);
}
switch (prop_id)
{
- case PROP_BOOT_MANAGER:
- g_value_set_object (value, starter->boot_manager);
+ case PROP_JOB_MANAGER:
+ g_value_set_object (value, starter->job_manager);
break;
- case PROP_LUC_HANDLER:
- g_value_set_object (value, starter->luc_handler);
+ case PROP_BOOT_MANAGER_SERVICE:
+ g_value_set_object (value, starter->boot_manager_service);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
switch (prop_id)
{
- case PROP_BOOT_MANAGER:
- starter->boot_manager = g_value_dup_object (value);
+ case PROP_JOB_MANAGER:
+ starter->job_manager = g_value_dup_object (value);
break;
- case PROP_LUC_HANDLER:
- starter->luc_handler = g_value_dup_object (value);
+ case PROP_BOOT_MANAGER_SERVICE:
+ starter->boot_manager_service = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
g_hash_table_insert (starter->cancellables, g_strdup (app), cancellable);
/* start the service, passing the cancellable */
- boot_manager_service_start (starter->boot_manager, app, cancellable,
- luc_starter_start_app_finish,
- g_object_ref (starter));
+ job_manager_start (starter->job_manager, app, cancellable,
+ luc_starter_start_app_finish,
+ g_object_ref (starter));
}
static void
-luc_starter_start_app_finish (BootManagerService *service,
- const gchar *unit,
- const gchar *result,
- GError *error,
- gpointer user_data)
+luc_starter_start_app_finish (JobManager *manager,
+ const gchar *unit,
+ const gchar *result,
+ GError *error,
+ gpointer user_data)
{
const gchar *group_name;
LUCStarter *starter = LUC_STARTER (user_data);
gchar *message;
guint n;
- g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
+ g_return_if_fail (IS_JOB_MANAGER (manager));
g_return_if_fail (unit != NULL && *unit != '\0');
g_return_if_fail (IS_LUC_STARTER (user_data));
g_return_if_fail (starter->start_order != NULL);
LUCStarter *
-luc_starter_new (BootManagerService *boot_manager,
- LUCHandler *luc_handler)
+luc_starter_new (JobManager *job_manager,
+ BootManagerService *boot_manager_service)
{
- g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (boot_manager), NULL);
- g_return_val_if_fail (IS_LUC_HANDLER (luc_handler), NULL);
+ g_return_val_if_fail (IS_JOB_MANAGER (job_manager), NULL);
+ g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (boot_manager_service), NULL);
return g_object_new (TYPE_LUC_STARTER,
- "boot-manager", boot_manager,
- "luc-handler", luc_handler,
+ "job-manager", job_manager,
+ "boot-manager-service", boot_manager_service,
NULL);
}
GVariantIter iter;
GPtrArray *group;
GVariant *context;
+ GError *error = NULL;
GList *lp;
gchar **apps;
- gchar *type;
+ gchar *log_text;
guint n;
+ gint type;
+ gint *dup_type;
g_debug ("prioritised types:");
for (n = 0; starter->prioritised_types[n] != NULL; n++)
}
/* get the current last user context */
- context = luc_handler_get_last_user_context (starter->luc_handler);
- type = g_variant_print (context, TRUE);
- g_debug ("context: %s", type);
+ context = boot_manager_service_read_luc (starter->boot_manager_service, &error);
+ if (error != NULL)
+ {
+ if (error->code == G_IO_ERROR_NOT_FOUND)
+ {
+ DLT_LOG (boot_manager_context, DLT_LOG_INFO,
+ DLT_STRING ("Boot manager could not find the last user context"));
+ }
+ else
+ {
+ log_text =
+ g_strdup_printf ("Error reading last user context: %s", error->message);
+ DLT_LOG (boot_manager_context, DLT_LOG_ERROR, DLT_STRING (log_text));
+ g_free (log_text);
+ }
+ g_error_free (error);
+ return;
+ }
/* create groups for all types in the LUC */
g_variant_iter_init (&iter, context);
- while (g_variant_iter_loop (&iter, "{s^as}", &type, &apps))
+ while (g_variant_iter_loop (&iter, "{i^as}", &type, &apps))
{
+ dup_type = g_new0 (gint, 1);
+ *dup_type = type;
group = g_ptr_array_new_with_free_func (g_free);
for (n = 0; apps != NULL && apps[n] != NULL; n++)
{
- g_debug (" group %s app %s", type, apps[n]);
+ g_debug (" group %d app %s", type, apps[n]);
g_ptr_array_add (group, g_strdup (apps[n]));
}
- g_hash_table_insert (starter->start_groups, g_strdup (type), group);
+ g_hash_table_insert (starter->start_groups, dup_type, group);
}
/* generate the start order by sorting the LUC types according to
if (starter->start_order != NULL)
luc_starter_start_next_group (starter);
+
+ g_variant_unref (context);
}
void
#define __LUC_STARTER_H__
#include <boot-manager/boot-manager-service.h>
-#include <luc-handler/luc-handler-dbus.h>
+#include <boot-manager/job-manager.h>
+
+
G_BEGIN_DECLS
GType luc_starter_get_type (void) G_GNUC_CONST;
-LUCStarter *luc_starter_new (BootManagerService *boot_manager,
- LUCHandler *luc_handler) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+LUCStarter *luc_starter_new (JobManager *job_manager,
+ BootManagerService *boot_manager_service) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
void luc_starter_start_groups (LUCStarter *starter);
void luc_starter_cancel (LUCStarter *starter);
#include <dlt/dlt.h>
#include <boot-manager/boot-manager-application.h>
+#include <boot-manager/boot-manager-command-line.h>
+#include <boot-manager/boot-manager-dbus.h>
#include <boot-manager/boot-manager-service.h>
+#include <boot-manager/la-handler-service.h>
#include <boot-manager/systemd-manager-dbus.h>
#include <boot-manager/target-startup-monitor.h>
DLT_DECLARE_CONTEXT (boot_manager_context);
+DLT_DECLARE_CONTEXT (la_handler_context);
+
+
+
+static void
+unregister_dlt (void)
+{
+ DLT_UNREGISTER_CONTEXT (boot_manager_context);
+ DLT_UNREGISTER_CONTEXT (la_handler_context);
+ DLT_UNREGISTER_APP ();
+}
{
BootManagerApplication *application;
TargetStartupMonitor *target_startup_monitor;
- BootManagerService *service;
+ BootManagerService *boot_manager_service;
+ LAHandlerService *la_handler_service;
GDBusConnection *connection;
SystemdManager *systemd_manager;
- LUCHandler *luc_handler;
+ JobManager *job_manager;
GError *error = NULL;
- gint exit_status = EXIT_SUCCESS;
+ gint exit_status;
/* register the application and context in DLT */
DLT_REGISTER_APP ("BMGR", "GENIVI Boot Manager");
DLT_REGISTER_CONTEXT (boot_manager_context, "MGR",
"Context of the boot manager itself");
+ DLT_REGISTER_CONTEXT (la_handler_context, "LAH",
+ "Context of the legacy application handler that hooks legacy "
+ "applications up with the shutdown concept of the Node State "
+ "Manager");
+
+ /* have DLT unregistered at exit */
+ atexit (unregister_dlt);
/* initialize the GType type system */
g_type_init ();
/* attempt to connect to D-Bus */
- connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+ connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (connection == NULL)
{
g_warning ("Failed to connect to D-Bus: %s", error->message);
return EXIT_FAILURE;
}
+ /* Parse and react to the command-line arguments instead of starting the application
+ * if any arguments are given */
+ if (argc > 1)
+ {
+ exit_status = boot_manager_handle_command_line (argc, argv, connection);
+
+ g_object_unref (connection);
+
+ return exit_status;
+ }
+
/* attempt to connect to the systemd manager */
systemd_manager =
systemd_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
return EXIT_FAILURE;
}
- /* attempt to connect to the LUC handler */
- luc_handler =
- luc_handler_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_NONE,
- "org.genivi.LUCHandler1",
- "/org/genivi/LUCHandler1",
- NULL, &error);
- if (luc_handler == NULL)
- {
- g_warning ("Failed to connect to the LUC handler: %s", error->message);
-
- /* clean up */
- g_error_free (error);
- g_object_unref (systemd_manager);
- g_object_unref (connection);
-
- return EXIT_FAILURE;
- }
-
/* instantiate the boot manager service implementation */
- service = boot_manager_service_new (connection, systemd_manager);
- if (!boot_manager_service_start_up (service, &error))
- {
- g_warning ("Failed to start the BootManager service: %s", error->message);
+ boot_manager_service = boot_manager_service_new (connection);
- /* clean up */
- g_error_free (error);
- g_object_unref (systemd_manager);
- g_object_unref (service);
- g_object_unref (connection);
-
- return EXIT_FAILURE;
- }
+ /* instantiate the job manager */
+ job_manager = job_manager_new (connection, systemd_manager);
/* start up the target startup monitor */
target_startup_monitor = target_startup_monitor_new (systemd_manager);
+ /* instantiate the legacy app handler */
+ la_handler_service = la_handler_service_new (connection, job_manager);
+
/* create and run the main application */
- application = boot_manager_application_new (service, luc_handler);
+ application = boot_manager_application_new (connection, job_manager,
+ la_handler_service, boot_manager_service);
exit_status = g_application_run (G_APPLICATION (application), 0, NULL);
g_object_unref (application);
/* release allocated objects */
g_object_unref (target_startup_monitor);
g_object_unref (systemd_manager);
- g_object_unref (service);
+ g_object_unref (job_manager);
+ g_object_unref (boot_manager_service);
g_object_unref (connection);
- /* unregister the application and context with DLT */
- DLT_UNREGISTER_CONTEXT (boot_manager_context);
- DLT_UNREGISTER_APP ();
-
return exit_status;
}
with the Node State Manager (NSM) instead of the apps and shut down those
apps when Shutdown() is called on the Shutdown Consumer.
-->
- <interface name="org.genivi.lifecycle.ShutdownConsumer1">
+ <interface name="org.genivi.BootManager1.ShutdownConsumer">
<!--
Shutdown:
#include <glib-object.h>
#include <gio/gio.h>
-#include <common/shutdown-consumer-dbus.h>
-#include <common/shutdown-consumer-service.h>
+#include <boot-manager/shutdown-consumer-dbus.h>
+#include <boot-manager/shutdown-consumer-service.h>
# vi:set ts=8 sw=8 noet ai nocindent:
-systemd_servicedir = $(libdir)/systemd/system
+systemd_servicedir = /lib/systemd/system
systemd_service_in_files = \
- org.genivi.LegacyAppHandler1.service.in
+ org.genivi.BootManager1.service.in
-systemd_service_DATA = $(systmd_service_in_files:.service.in=.service)
+systemd_service_DATA = $(systemd_service_in_files:.service.in=.service)
%.service: %.service.in
sed -e "s,\@libdir\@,$(libdir),g" \
--- /dev/null
+[Service]
+Type = notify
+BusName = org.genivi.BootManager1.service
+ExecStart = @libdir@/boot-manager-@BOOT_MANAGER_VERSION_API@/boot-manager
#include <glib-object.h>
#include <gio/gio.h>
-#include <common/boot-manager-dbus.h>
-
+#include <boot-manager/boot-manager-dbus.h>
#include <boot-manager/target-startup-monitor.h>
#include <glib-object.h>
#include <gio/gio.h>
-#include <common/watchdog-client.h>
+#include <boot-manager/watchdog-client.h>
+++ /dev/null
-# vi:set ts=8 sw=8 noet ai nocindent:
-
-noinst_LTLIBRARIES = libcommon.la
-
-libcommon_la_built_headers = \
- boot-manager-dbus.h \
- shutdown-consumer-dbus.h
-
-libcommon_la_built_sources = \
- boot-manager-dbus.c \
- shutdown-consumer-dbus.c \
- $(libcommon_la_built_headers)
-
-libcommon_la_SOURCES = \
- glib-extensions.c \
- glib-extensions.h \
- shutdown-consumer-service.c \
- shutdown-consumer-service.h \
- watchdog-client.c \
- watchdog-client.h \
- $(libcommon_la_built_sources)
-
-libcommon_la_CFLAGS = \
- -DG_LOG_DOMAIN=\"common\" \
- -I$(top_srcdir) \
- $(GIO_CFLAGS) \
- $(GIO_UNIX_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(PLATFORM_CFLAGS) \
- $(PLATFORM_CPPFLAGS) \
- $(SYSTEMD_DAEMON_CFLAGS)
-
-libcommon_la_LDFLAGS = \
- -no-undefined \
- $(PLATFORM_LDFLAGS)
-
-libcommon_la_LIBADD = \
- $(GIO_LIBS) \
- $(GIO_UNIX_LIBS) \
- $(GLIB_LIBS) \
- $(SYSTEMD_DAEMON_LIBS)
-
-EXTRA_DIST = \
- boot-manager-dbus.xml
- shutdown-consumer-dbus.xml
-
-DISTCLEANFILES = \
- $(libcommon_la_built_sources)
-
-BUILT_SOURCES = \
- $(libcommon_la_built_headers)
-
-boot-manager-dbus.h: boot-manager-dbus.xml Makefile
- $(AM_V_GEN) $(GDBUS_CODEGEN) \
- --interface-prefix org.genivi \
- --c-namespace "" \
- --generate-c-code boot-manager-dbus \
- --annotate org.genivi.BootManager1 org.gtk.GDBus.C.Name \
- BootManager $<
-
-shutdown-consumer-dbus.h: shutdown-consumer-dbus.xml Makefile
- $(AM_V_GEN) $(GDBUS_CODEGEN) \
- --interface-prefix org.genivi \
- --c-namespace "" \
- --generate-c-code shutdown-consumer-dbus \
- --annotate org.genivi.lifecycle.ShutdownConsumer1 org.gtk.GDBus.C.Name \
- Shutdown_Consumer $<
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<node name="/org/genivi/BootManager1">
- <!--
- org.genivi.BootManager1:
- @short_description: Interface for simplified control over systemd units.
-
- The GENIVI Boot Manager service allows other components in the system to
- control the lifetime of systemd units, e.g. by starting and stopping them
- during system runtime.
-
- It's goal is to safe-guard the access to systemd and provide a simplified
- interface to controling units based on asynchronous D-Bus methods.
- -->
- <interface name="org.genivi.BootManager1">
- <!--
- Start:
- @unit: A unit filename (e.g. "app1.unit").
- @result: The result of the unit start request.
-
- Attempts to start a unit through systemd. Possible values for the
- result are:
-
- done - the unit was started successfully.
- failed - the unit startup failed.
- timeout - the unit startup job timed out.
- canceled - the unit startup was canceled by someone else.
- dependency - a dependency or non-dependency could not be started or stopped.
- skipped - the unit startup was skipped.
-
- These values are identical to the possible job results systemd implements.
-
- -->
- <method name="Start">
- <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
- <arg name="unit" type="s" direction="in"/>
- <arg name="result" type="s" direction="out"/>
- </method>
-
- <!--
- Stop:
- @unit: A unit filename (e.g. "app1.unit").
- @result: The result of the unit stop request.
-
- Attempts to stop a running unit through systemd. The possible result
- values are the same as for the Start() method.
- -->
- <method name="Stop">
- <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
- <arg name="unit" type="s" direction="in"/>
- <arg name="result" type="s" direction="out"/>
- </method>
-
- <!--
- Kill:
- @unit: A unit filename (e.g. "app1.unit").
- @result: The result of the unit kill request.
-
- Attempts to kill a running unit through systemd. The possible result
- values are the same as for the Start() method.
- -->
- <method name="Kill">
- <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
- <arg name="unit" type="s" direction="in"/>
- <arg name="result" type="s" direction="out"/>
- </method>
-
- <!--
- Restart:
- @unit: A unit filename (e.g. "app1.unit").
- @result: The result of the unit stop request.
-
- Attempts to restart a running unit through systemd. The possible result
- values are the same as for the Start() method.
- -->
- <method name="Restart">
- <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
- <arg name="unit" type="s" direction="in"/>
- <arg name="result" type="s" direction="out"/>
- </method>
-
- <!--
- Isolate:
- @unit: A unit filename (e.g. "transport-mode.target").
- @result: The result of the unit isolate request.
-
- Attempts to isolate a running unit through systemd. The possible result
- values are the same as for the Start() method.
-
- Isolating a unit (usually a target) is similar to switching to a
- certain runlevel in traditional Linux systems. In IVI systems it can be
- used to switch between system modes such as user mode, transport mode,
- loading mode etc.
- -->
- <method name="Isolate">
- <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
- <arg name="unit" type="s" direction="in"/>
- <arg name="result" type="s" direction="out"/>
- </method>
-
- <!--
- List:
- @apps: Return parameter that is an array of all available unit filenames.
-
- Lists all unit filenames currently known to systemd.
- -->
- <method name="List">
- <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
- <arg name="apps" type="as" direction="out"/>
- </method>
- </interface>
-</node>
+++ /dev/null
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/* -
- * Copyright (c) 2012 GENIVI.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-
-#include <common/glib-extensions.h>
-
-
-
-gboolean
-g_variant_string_array_has_string (GVariant *array,
- const gchar *str)
-{
- gboolean found = FALSE;
- gchar *current_str;
- guint n;
-
- for (n = 0; array != NULL && !found && n < g_variant_n_children (array); n++)
- {
- g_variant_get_child (array, n, "&s", ¤t_str);
- if (g_strcmp0 (str, current_str) == 0)
- found = TRUE;
- }
-
- return found;
-}
AC_OUTPUT([
Makefile
-common/Makefile
+boot-manager/busconf/Makefile
+boot-manager/dbus/Makefile
+boot-manager/systemd/Makefile
boot-manager/Makefile
-legacy-app-handler/dbus/Makefile
-legacy-app-handler/Makefile
-legacy-app-handler/systemd/Makefile
-luc-handler/Makefile
-luc-handler/org.genivi.LUCHandler1.gschema.xml
tests/Makefile
-tests/luc-handler/Makefile
+tests/boot-manager/Makefile
tests/legacy-app-handler/Makefile
])
+++ /dev/null
-# vi:set ts=8 sw=8 noet ai nocindent:
-
-SUBDIRS = \
- dbus \
- systemd
-
-legacy_app_handler_confdir = /etc/dbus-1/system.d
-
-legacy_app_handler_conf_DATA = \
- org.genivi.LegacyAppHandler1.conf
-
-legacy_app_handlerdir = \
- $(libdir)/legacy-app-handler-$(BOOT_MANAGER_VERSION_API)
-
-legacy_app_handler_PROGRAMS = \
- legacy-app-handler
-
-legacy_app_handler_built_headers = \
- la-handler-dbus.h
-
-legacy_app_handler_built_sources = \
- la-handler-dbus.c \
- $(legacy_app_handler_built_headers)
-
-legacy_app_handler_SOURCES = \
- la-handler-application.c \
- la-handler-application.h \
- la-handler-service.c \
- la-handler-service.h \
- main.c \
- $(legacy_app_handler_built_sources)
-
-legacy_app_handler_CFLAGS = \
- -DG_LOG_DOMAIN=\"legacy-app-handler\" \
- -I$(top_srcdir) \
- $(DLT_CFLAGS) \
- $(GIO_CFLAGS) \
- $(GIO_UNIX_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(PLATFORM_CFLAGS) \
- $(PLATFORM_CPPFLAGS) \
- $(SYSTEMD_DAEMON_CFLAGS)
-
-legacy_app_handler_LDFLAGS = \
- -no-undefined \
- $(PLATFORM_LDFLAGS)
-
-legacy_app_handler_DEPENDENCIES = \
- $(top_builddir)/common/libcommon.la
-
-legacy_app_handler_LDADD = \
- $(DLT_LIBS) \
- $(GIO_LIBS) \
- $(GIO_UNIX_LIBS) \
- $(GLIB_LIBS) \
- $(SYSTEMD_DAEMON_LIBS) \
- $(top_builddir)/common/libcommon.la
-
-EXTRA_DIST = \
- $(gsettingsschema_in_files) \
- la-handler-dbus.xml
-
-DISTCLEANFILES = \
- $(legacy_app_handler_built_sources) \
- $(gsettings_SCHEMAS)
-
-BUILT_SOURCES = \
- $(legacy_app_handler_built_headers)
-
-la-handler-dbus.h: la-handler-dbus.xml Makefile
- $(AM_V_GEN) $(GDBUS_CODEGEN) \
- --interface-prefix org.genivi \
- --c-namespace "" \
- --generate-c-code la-handler-dbus \
- --annotate org.genivi.LegacyAppHandler1 org.gtk.GDBus.C.Name \
- LA_Handler $<
+++ /dev/null
-[D-BUS Service]
-Name=org.genivi.LegacyAppHandler1
-SystemdService = org.genivi.LegacyAppHandler1.service
-Exec=@libdir@/legacy-app-handler-@BOOT_MANAGER_VERSION_API@/legacy-app-handler
+++ /dev/null
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/* -
- * Copyright (c) 2012 GENIVI.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-#include <dlt/dlt.h>
-
-#include <common/watchdog-client.h>
-
-#include <legacy-app-handler/la-handler-dbus.h>
-#include <legacy-app-handler/la-handler-application.h>
-#include <legacy-app-handler/la-handler-service.h>
-
-
-
-DLT_IMPORT_CONTEXT (la_handler_context);
-
-
-
-/* property identifiers */
-enum
-{
- PROP_0,
- PROP_LA_HANDLER_SERVICE,
-};
-
-
-
-static void la_handler_application_finalize (GObject *object);
-static void la_handler_application_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void la_handler_application_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void la_handler_application_startup (GApplication *application);
-
-
-
-struct _LAHandlerApplicationClass
-{
- GApplicationClass __parent__;
-};
-
-struct _LAHandlerApplication
-{
- GApplication __parent__;
-
- /* systemd watchdog client that repeatedly asks systemd to update
- * the watchdog timestamp */
- WatchdogClient *watchdog_client;
-
- /* service object that implements the Legacy App Handler D-Bus interface */
- LAHandlerService *service;
-};
-
-
-
-G_DEFINE_TYPE (LAHandlerApplication, la_handler_application, G_TYPE_APPLICATION);
-
-
-
-static void
-la_handler_application_class_init (LAHandlerApplicationClass *klass)
-{
- GApplicationClass *gapplication_class;
- GObjectClass *gobject_class;
-
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = la_handler_application_finalize;
- gobject_class->get_property = la_handler_application_get_property;
- gobject_class->set_property = la_handler_application_set_property;
-
- gapplication_class = G_APPLICATION_CLASS (klass);
- gapplication_class->startup = la_handler_application_startup;
-
- g_object_class_install_property (gobject_class,
- PROP_LA_HANDLER_SERVICE,
- g_param_spec_object ("la-handler-service",
- "la-handler-service",
- "la-handler-service",
- LA_HANDLER_TYPE_SERVICE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-}
-
-
-
-static void
-la_handler_application_init (LAHandlerApplication *application)
-{
-}
-
-
-
-static void
-la_handler_application_finalize (GObject *object)
-{
- LAHandlerApplication *application = LA_HANDLER_APPLICATION (object);
-
- /* release the watchdog client */
- if (application->watchdog_client != NULL)
- g_object_unref (application->watchdog_client);
-
- /* release the Legacy App Handler service implementation */
- if (application->service != NULL)
- g_object_unref (application->service);
-
- (*G_OBJECT_CLASS (la_handler_application_parent_class)->finalize) (object);
-}
-
-
-
-static void
-la_handler_application_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- LAHandlerApplication *application = LA_HANDLER_APPLICATION (object);
-
- switch (prop_id)
- {
- case PROP_LA_HANDLER_SERVICE:
- g_value_set_object (value, application->service);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-
-static void
-la_handler_application_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- LAHandlerApplication *application = LA_HANDLER_APPLICATION (object);
-
- switch (prop_id)
- {
- case PROP_LA_HANDLER_SERVICE:
- application->service = g_value_dup_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-
-static void
-la_handler_application_startup (GApplication *app)
-{
- LAHandlerApplication *application = LA_HANDLER_APPLICATION (app);
-
- /* chain up to the parent class */
- (*G_APPLICATION_CLASS (la_handler_application_parent_class)->startup) (app);
-
- /* update systemd's watchdog timestamp every 120 seconds */
- application->watchdog_client = watchdog_client_new (120);
-
- /* the Legacy Application Handler should keep running until it is shut down by the Node
- * State Manager. */
- g_application_hold (app);
-}
-
-
-
-LAHandlerApplication *
-la_handler_application_new (LAHandlerService *service,
- GApplicationFlags flags)
-{
- return g_object_new (LA_HANDLER_TYPE_APPLICATION,
- "application-id", "org.genivi.LegacyAppHandler1",
- "flags", flags,
- "la-handler-service", service,
- NULL);
-}
+++ /dev/null
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/* -
- * Copyright (c) 2012 GENIVI.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#ifndef __LA_HANDLER_APPLICATION_H__
-#define __LA_HANDLER_APPLICATION_H__
-
-#include <legacy-app-handler/la-handler-service.h>
-
-G_BEGIN_DECLS
-
-#define LA_HANDLER_TYPE_APPLICATION (la_handler_application_get_type ())
-#define LA_HANDLER_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LA_HANDLER_TYPE_APPLICATION, LAHandlerApplication))
-#define LA_HANDLER_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LA_HANDLER_TYPE_APPLICATION, LAHandlerApplicationClass))
-#define LA_HANDLER_IS_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LA_HANDLER_TYPE_APPLICATION))
-#define LA_HANDLER_IS_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LA_HANDLER_TYPE_APPLICATION)
-#define LA_HANDLER_APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LA_HANDLER_TYPE_APPLICATION, LAHandlerApplicationClass))
-
-typedef struct _LAHandlerApplicationClass LAHandlerApplicationClass;
-typedef struct _LAHandlerApplication LAHandlerApplication;
-
-GType la_handler_application_get_type (void) G_GNUC_CONST;
-
-LAHandlerApplication *la_handler_application_new (LAHandlerService *service,
- GApplicationFlags flags) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-
-G_END_DECLS
-
-#endif /* !__LA_HANDLER_APPLICATION_H__ */
-
+++ /dev/null
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/* -
- * Copyright (c) 2012 GENIVI.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include <glib.h>
-#include <gio/gio.h>
-
-#include <dlt/dlt.h>
-
-#include <legacy-app-handler/la-handler-application.h>
-#include <legacy-app-handler/la-handler-dbus.h>
-#include <legacy-app-handler/la-handler-service.h>
-
-
-
-DLT_DECLARE_CONTEXT (la_handler_context);
-
-
-
-static void
-dlt_cleanup (void)
-{
- DLT_UNREGISTER_CONTEXT (la_handler_context);
- DLT_UNREGISTER_APP ();
-}
-
-
-
-static gboolean
-handle_command_line (int argc,
- char **argv,
- GDBusConnection *connection)
-{
- GOptionContext *context = g_option_context_new (NULL);
- LAHandler *legacy_app_handler;
- gboolean do_register = FALSE;
- gboolean do_deregister = FALSE;
- GError *error = NULL;
- gchar *unit = NULL;
- gchar *log_message = NULL;
- gchar *mode = NULL;
- gint timeout = 0;
-
- GOptionEntry entries[] = {
- {"deregister", 0, 0, G_OPTION_ARG_NONE, &do_deregister, NULL, NULL},
- {"register", 0, 0, G_OPTION_ARG_NONE, &do_register, NULL, NULL},
- {"unit", 0, 0, G_OPTION_ARG_STRING, &unit, NULL, NULL},
- {"timeout", 0, 0, G_OPTION_ARG_INT, &timeout, NULL, NULL},
- {"shutdown-mode", 0, 0, G_OPTION_ARG_STRING, &mode, NULL, NULL},
- {NULL},
- };
-
- /* set up the option context */
- g_option_context_set_help_enabled (context, FALSE);
- g_option_context_add_main_entries (context, entries, NULL);
-
- /* parse the arguments into argument data */
- if (!g_option_context_parse (context, &argc, &argv, &error) || error != NULL)
- {
- /* an error occurred */
- log_message =
- g_strdup_printf ("Error occurred parsing arguments: %s\n", error->message);
- DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
-
- g_error_free (error);
- g_free (log_message);
-
- return FALSE;
- }
- else if (do_register && !do_deregister)
- {
- if (unit == NULL || *unit == '\0' || timeout < 0)
- {
- /* register was called incorrectly */
- log_message =
- g_strdup_printf ("Invalid arguments for --register. A unit must be specified"
- " and the timeout must be positive.");
- DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
-
- g_free (log_message);
-
- return FALSE;
- }
-
- /* get a legacy app handler interface */
- legacy_app_handler =
- la_handler_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE,
- "org.genivi.LegacyAppHandler1",
- "/org/genivi/LegacyAppHandler1", NULL, &error);
- if (error != NULL)
- {
- /* failed to connect to the legacy app handler */
- log_message =
- g_strdup_printf ("Error occurred connecting to legacy app handler "
- "interface: %s", error->message);
- DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
-
- g_free (log_message);
- g_error_free (error);
-
- return FALSE;
- }
-
- /* call the legacy app handler's Register() method */
- la_handler_call_register_sync (legacy_app_handler, unit,
- mode ? mode : "normal", (guint) timeout, NULL,
- &error);
- if (error != NULL)
- {
- /* failed to register the legacy app */
- log_message = g_strdup_printf ("Error occurred registering legacy app: %s",
- error->message);
- DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
-
- g_object_unref (legacy_app_handler);
- g_free (log_message);
- g_error_free (error);
-
- return FALSE;
- }
-
- g_object_unref (legacy_app_handler);
-
- return TRUE;
-
- }
- else if (do_deregister && !do_register)
- {
- if (unit == NULL || *unit == '\0')
- {
- /* deregister was called incorrectly */
- log_message =
- g_strdup_printf ("Invalid arguments for --deregister. A unit must be "
- "specified.");
- DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
-
- g_free (log_message);
-
- return FALSE;
- }
-
- /* get a legacy app handler interface */
- legacy_app_handler =
- la_handler_proxy_new_sync (connection, G_DBUS_PROXY_FLAGS_NONE,
- "org.genivi.LegacyAppHandler1",
- "/org/genivi/LegacyAppHandler1", NULL, &error);
- if (error != NULL)
- {
- log_message =
- g_strdup_printf ("Error occurred connecting to legacy app handler "
- "interface: %s", error->message);
- DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
-
- g_free (log_message);
- g_error_free (error);
-
- return FALSE;
- }
-
- /* call the legacy app handler's Deregister() method */
- la_handler_call_deregister_sync (legacy_app_handler, unit, NULL, &error);
- if (error != NULL)
- {
- log_message = g_strdup_printf ("Error occurred deregistering legacy "
- "app: %s", error->message);
- DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
-
- g_object_unref (legacy_app_handler);
- g_free (log_message);
- g_error_free (error);
-
- return FALSE;
- }
-
- g_object_unref (legacy_app_handler);
-
- return TRUE;
- }
- else if (do_register && do_deregister)
- {
- log_message =
- g_strdup_printf ("Invalid arguments. Please choose either --register or "
- "--deregister.");
- DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_message));
-
- g_free (log_message);
-
- return FALSE;
- }
- else
- {
- DLT_LOG (la_handler_context, DLT_LOG_ERROR,
- DLT_STRING ("No arguments recognised"));
- return FALSE;
- }
-}
-
-
-
-int
-main (int argc,
- char **argv)
-{
- LAHandlerApplication *application;
- LAHandlerService *service;
- GDBusConnection *connection;
- gboolean is_remote;
- GError *error = NULL;
- gchar *log_text;
- int exit_status;
-
- /* check if this program execution is meant as a remote application.
- * if it is a remote application, then it will be called with command-line arguments. */
- is_remote = (argc > 1) ? TRUE : FALSE;
-
- /* register the application and context in DLT */
- if (!is_remote)
- {
- DLT_REGISTER_APP ("BMGR", "GENIVI Boot Manager");
- DLT_REGISTER_CONTEXT (la_handler_context, "LAH",
- "Context of the legacy application handler that hooks legacy "
- "applications up with the shutdown concept of the Node State "
- "Manager");
- atexit (dlt_cleanup);
- }
-
- /* initialize the GType type system */
- g_type_init ();
-
- /* attempt to connect to D-Bus */
- connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
- if (connection == NULL || error != NULL || !G_IS_DBUS_CONNECTION (connection))
- {
- log_text = g_strdup_printf ("Failed to connect to D-Bus: %s", error->message);
- DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_text));
-
- /* clean up */
- g_free (log_text);
- g_error_free (error);
-
- return EXIT_FAILURE;
- }
-
- if (is_remote)
- {
- if (!handle_command_line (argc, argv, connection))
- exit_status = EXIT_FAILURE;
- else
- exit_status = EXIT_SUCCESS;
- }
- else
- {
- /* instantiate the LegacyAppHandler service implementation */
- service = la_handler_service_new (connection);
- if (!la_handler_service_start (service, &error))
- {
- log_text = g_strdup_printf ("Failed to start the legacy app handler service: %s",
- error->message);
- DLT_LOG (la_handler_context, DLT_LOG_ERROR, DLT_STRING (log_text));
-
- /* clean up */
- g_free (log_text);
- g_error_free (error);
- g_object_unref (service);
- g_object_unref (connection);
-
- return EXIT_FAILURE;
- }
-
- /* create and run the main application */
- application =
- la_handler_application_new (service, G_APPLICATION_IS_SERVICE);
-
- exit_status = g_application_run (G_APPLICATION (application), argc, argv);
- g_object_unref (application);
-
- /* release allocated objects */
- g_object_unref (service);
- }
-
- g_object_unref (connection);
-
- return exit_status;
-}
+++ /dev/null
-[Service]
-BusName = org.genivi.LegacyAppHandler1.service
-ExecStart = @libdir@/legacy-app-handler-@BOOT_MANAGER_VERSION_API@/legacy-app-handler
+++ /dev/null
-# vi:set ts=8 sw=8 noet ai nocindent:
-
-luc_handlerdir = \
- $(libdir)/luc-handler-$(BOOT_MANAGER_VERSION_API)
-
-luc_handler_PROGRAMS = \
- luc-handler
-
-luc_handler_built_headers = \
- luc-handler-dbus.h
-
-luc_handler_built_sources = \
- luc-handler-dbus.c \
- $(luc_handler_built_headers)
-
-luc_handler_SOURCES = \
- luc-handler-application.c \
- luc-handler-application.h \
- luc-handler-service.c \
- luc-handler-service.h \
- main.c \
- $(luc_handler_built_sources)
-
-luc_handler_CFLAGS = \
- -DG_LOG_DOMAIN=\"luc-handler\" \
- -I$(top_srcdir) \
- $(DLT_CFLAGS) \
- $(GIO_CFLAGS) \
- $(GIO_UNIX_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(PLATFORM_CFLAGS) \
- $(PLATFORM_CPPFLAGS) \
- $(SYSTEMD_DAEMON_CFLAGS)
-
-luc_handler_LDFLAGS = \
- -no-undefined \
- $(PLATFORM_LDFLAGS)
-
-luc_handler_DEPENDENCIES = \
- $(top_builddir)/common/libcommon.la
-
-luc_handler_LDADD = \
- $(DLT_LIBS) \
- $(GIO_LIBS) \
- $(GIO_UNIX_LIBS) \
- $(GLIB_LIBS) \
- $(SYSTEMD_DAEMON_LIBS) \
- $(top_builddir)/common/libcommon.la
-
-servicedir = $(datadir)/dbus-1/services
-service_in_files = \
- org.genivi.LUCHandler1.service.in
-
-service_DATA = $(service_in_files:.service.in=.service)
-
-%.service: %.service.in
- sed -e "s,\@libdir\@,$(libdir),g" \
- -e "s,\@BOOT_MANAGER_VERSION_API\@,$(BOOT_MANAGER_VERSION_API),g" < $< > $@
-
-gsettingsschema_in_files = \
- org.genivi.LUCHandler1.gschema.xml.in
-
-gsettings_SCHEMAS = \
- $(gsettingsschema_in_files:.xml.in=.xml)
-
-.PRECIOUS: $(gsettings_SCHEMAS)
-
-@GSETTINGS_RULES@
-
-CLEANFILES = \
- $(service_DATA)
-
-EXTRA_DIST = \
- $(service_in_files) \
- $(gsettingsschema_in_files) \
- luc-handler-dbus.xml
-
-DISTCLEANFILES = \
- $(luc_handler_built_sources) \
- $(gsettings_SCHEMAS)
-
-BUILT_SOURCES = \
- $(luc_handler_built_headers)
-
-luc-handler-dbus.h: luc-handler-dbus.xml Makefile
- $(AM_V_GEN) $(GDBUS_CODEGEN) \
- --interface-prefix org.genivi \
- --c-namespace "" \
- --generate-c-code luc-handler-dbus \
- --annotate org.genivi.LUCHandler1 org.gtk.GDBus.C.Name \
- LUC_Handler $<
+++ /dev/null
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/* -
- * Copyright (c) 2012 GENIVI.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-#include <common/watchdog-client.h>
-
-#include <luc-handler/luc-handler-dbus.h>
-#include <luc-handler/luc-handler-application.h>
-#include <luc-handler/luc-handler-service.h>
-
-
-
-/* property identifiers */
-enum
-{
- PROP_0,
- PROP_LUC_HANDLER_SERVICE,
-};
-
-
-
-static void luc_handler_application_finalize (GObject *object);
-static void luc_handler_application_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void luc_handler_application_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void luc_handler_application_startup (GApplication *application);
-
-
-
-struct _LUCHandlerApplicationClass
-{
- GApplicationClass __parent__;
-};
-
-struct _LUCHandlerApplication
-{
- GApplication __parent__;
-
- /* systemd watchdog client that repeatedly asks systemd to update
- * the watchdog timestamp */
- WatchdogClient *watchdog_client;
-
- /* service object that implements the LUC Handler D-Bus interface */
- LUCHandlerService *service;
-};
-
-
-
-G_DEFINE_TYPE (LUCHandlerApplication, luc_handler_application, G_TYPE_APPLICATION);
-
-
-
-static void
-luc_handler_application_class_init (LUCHandlerApplicationClass *klass)
-{
- GApplicationClass *gapplication_class;
- GObjectClass *gobject_class;
-
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = luc_handler_application_finalize;
- gobject_class->get_property = luc_handler_application_get_property;
- gobject_class->set_property = luc_handler_application_set_property;
-
- gapplication_class = G_APPLICATION_CLASS (klass);
- gapplication_class->startup = luc_handler_application_startup;
-
- g_object_class_install_property (gobject_class,
- PROP_LUC_HANDLER_SERVICE,
- g_param_spec_object ("luc-handler-service",
- "luc-handler-service",
- "luc-handler-service",
- LUC_HANDLER_TYPE_SERVICE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-}
-
-
-
-static void
-luc_handler_application_init (LUCHandlerApplication *application)
-{
-}
-
-
-
-static void
-luc_handler_application_finalize (GObject *object)
-{
- LUCHandlerApplication *application = LUC_HANDLER_APPLICATION (object);
-
- /* release the watchdog client */
- g_object_unref (application->watchdog_client);
-
- /* release the LUC Handler service implementation */
- if (application->service != NULL)
- g_object_unref (application->service);
-
- (*G_OBJECT_CLASS (luc_handler_application_parent_class)->finalize) (object);
-}
-
-
-
-static void
-luc_handler_application_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- LUCHandlerApplication *application = LUC_HANDLER_APPLICATION (object);
-
- switch (prop_id)
- {
- case PROP_LUC_HANDLER_SERVICE:
- g_value_set_object (value, application->service);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-
-static void
-luc_handler_application_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- LUCHandlerApplication *application = LUC_HANDLER_APPLICATION (object);
-
- switch (prop_id)
- {
- case PROP_LUC_HANDLER_SERVICE:
- application->service = g_value_dup_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-
-static void
-luc_handler_application_startup (GApplication *app)
-{
- LUCHandlerApplication *application = LUC_HANDLER_APPLICATION (app);
-
- /* update systemd's watchdog timestamp every 120 seconds */
- application->watchdog_client = watchdog_client_new (120);
-}
-
-
-
-LUCHandlerApplication *
-luc_handler_application_new (LUCHandlerService *service)
-{
- return g_object_new (LUC_HANDLER_TYPE_APPLICATION,
- "application-id", "org.genivi.LUCHandler1",
- "flags", G_APPLICATION_IS_SERVICE,
- "luc-handler-service", service,
- NULL);
-}
+++ /dev/null
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/* -
- * Copyright (c) 2012 GENIVI.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#ifndef __LUC_HANDLER_APPLICATION_H__
-#define __LUC_HANDLER_APPLICATION_H__
-
-#include <luc-handler/luc-handler-service.h>
-
-G_BEGIN_DECLS
-
-#define LUC_HANDLER_TYPE_APPLICATION (luc_handler_application_get_type ())
-#define LUC_HANDLER_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LUC_HANDLER_TYPE_APPLICATION, LUCHandlerApplication))
-#define LUC_HANDLER_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LUC_HANDLER_TYPE_APPLICATION, LUCHandlerApplicationClass))
-#define LUC_HANDLER_IS_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LUC_HANDLER_TYPE_APPLICATION))
-#define LUC_HANDLER_IS_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LUC_HANDLER_TYPE_APPLICATION)
-#define LUC_HANDLER_APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LUC_HANDLER_TYPE_APPLICATION, LUCHandlerApplicationClass))
-
-typedef struct _LUCHandlerApplicationClass LUCHandlerApplicationClass;
-typedef struct _LUCHandlerApplication LUCHandlerApplication;
-
-GType luc_handler_application_get_type (void) G_GNUC_CONST;
-
-LUCHandlerApplication *luc_handler_application_new (LUCHandlerService *service) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-
-G_END_DECLS
-
-#endif /* !__LUC_HANDLER_APPLICATION_H__ */
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<node name="/org/genivi/LUCHandler1">
- <!--
- org.genivi.LUCHandler1:
- @short_description: Interface for managing the GENIVI LUC (Last User Context)
-
- The GENIVI LUC Handler remembers applications that were used in the last
- session of a user. It is used by other components such as the boot manager
- in order to restore these applications on the next start-up.
-
- The LUC Handler is a passive component in the sense that it does not
- remember applications on its own; instead, applications need to register
- and deregister themselves proactively.
-
- Applications can be registered for different LUC types, the standard ones
- being "foreground", "background" and "audible".
- -->
- <interface name="org.genivi.LUCHandler1">
- <!--
- Register:
- @apps: A dictionary that maps LUC types to arrays of application unit names.
-
- Registers one or more applications for certain LUC types. Applications may
- be listed multiple times. For LUC types where only a single application may
- be registered at a time, the last application in the corresponding list wins.
-
- An example for the apps parameter would be:
-
- {
- "foreground": [ "app1.unit" ],
- "background": [ "app2.unit", "app3.unit" ],
- "audible": [ "app3.unit" ]
- }
-
- -->
- <method name="Register">
- <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
- <arg name="apps" type="a{sas}" direction="in"/>
- </method>
-
- <!--
- Deregister:
- @apps: A dictionary that maps LUC types to arrays of application unit names.
-
- Removes one or multiple applications from the LUC. It is the exact opposite
- of the Register() method.
- -->
- <method name="Deregister">
- <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
- <arg name="apps" type="a{sas}" direction="in"/>
- </method>
-
- <!--
- LastUserContext:
-
- The current Last User Context, that is, a dictionary that maps LUC types
- to arrays of one or more applications registered for each of them.
-
- This property is read-only as it is supposed to be modified only through
- Register() and Deregister() method calls.
- -->
- <property name="LastUserContext" type="a{sas}" access="read"/>
- </interface>
-</node>
+++ /dev/null
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/* -
- * Copyright (c) 2012 GENIVI.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib-object.h>
-#include <gio/gio.h>
-
-#include <common/glib-extensions.h>
-
-#include <luc-handler/luc-handler-dbus.h>
-#include <luc-handler/luc-handler-service.h>
-
-
-
-/* property identifiers */
-enum
-{
- PROP_0,
- PROP_CONNECTION,
-};
-
-
-
-static void luc_handler_service_finalize (GObject *object);
-static void luc_handler_service_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void luc_handler_service_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static gboolean luc_handler_service_handle_register (LUCHandler *interface,
- GDBusMethodInvocation *invocation,
- GVariant *apps,
- LUCHandlerService *service);
-static gboolean luc_handler_service_handle_deregister (LUCHandler *interface,
- GDBusMethodInvocation *invocation,
- GVariant *apps,
- LUCHandlerService *service);
-static gboolean luc_handler_service_get_last_user_context (GValue *value,
- GVariant *variant,
- gpointer user_data);
-static GVariant *luc_handler_service_set_last_user_context (const GValue *value,
- const GVariantType *expected_type,
- gpointer user_data);
-
-
-
-struct _LUCHandlerServiceClass
-{
- GObjectClass __parent__;
-};
-
-struct _LUCHandlerService
-{
- GObject __parent__;
-
- GDBusConnection *connection;
- LUCHandler *interface;
- GSettings *settings;
-};
-
-
-
-G_DEFINE_TYPE (LUCHandlerService, luc_handler_service, G_TYPE_OBJECT);
-
-
-
-static void
-luc_handler_service_class_init (LUCHandlerServiceClass *klass)
-{
- GObjectClass *gobject_class;
-
- gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->finalize = luc_handler_service_finalize;
- gobject_class->get_property = luc_handler_service_get_property;
- gobject_class->set_property = luc_handler_service_set_property;
-
- g_object_class_install_property (gobject_class,
- PROP_CONNECTION,
- g_param_spec_object ("connection",
- "connection",
- "connection",
- G_TYPE_DBUS_CONNECTION,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-}
-
-
-
-static void
-luc_handler_service_init (LUCHandlerService *service)
-{
- service->interface = luc_handler_skeleton_new ();
-
- /* create GSettings object for the LUC Handler schema */
- service->settings = g_settings_new ("org.genivi.LUCHandler1");
-
- /* bind the settings key to the D-Bus property so changes are
- * automatically synchronised; we need to use a custom binding
- * here because g_settings_bind() alone does not work with dicts */
- g_settings_bind_with_mapping (service->settings, "last-user-context",
- service->interface, "last-user-context",
- G_SETTINGS_BIND_DEFAULT,
- luc_handler_service_get_last_user_context,
- luc_handler_service_set_last_user_context,
- g_object_ref (service),
- (GDestroyNotify) g_object_unref);
-
- /* implement the Register() handler */
- g_signal_connect (service->interface, "handle-register",
- G_CALLBACK (luc_handler_service_handle_register),
- service);
-
- /* implement the Deregister() handler */
- g_signal_connect (service->interface, "handle-deregister",
- G_CALLBACK (luc_handler_service_handle_deregister),
- service);
-}
-
-
-
-static void
-luc_handler_service_finalize (GObject *object)
-{
- LUCHandlerService *service = LUC_HANDLER_SERVICE (object);
-
- /* release the D-Bus connection object */
- if (service->connection != NULL)
- g_object_unref (service->connection);
-
- /* release the interface skeleton */
- g_signal_handlers_disconnect_matched (service->interface,
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, service);
- g_object_unref (service->interface);
-
- /* release the settings object */
- g_object_unref (service->settings);
-
- (*G_OBJECT_CLASS (luc_handler_service_parent_class)->finalize) (object);
-}
-
-
-
-static void
-luc_handler_service_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- LUCHandlerService *service = LUC_HANDLER_SERVICE (object);
-
- switch (prop_id)
- {
- case PROP_CONNECTION:
- g_value_set_object (value, service->connection);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-
-static void
-luc_handler_service_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- LUCHandlerService *service = LUC_HANDLER_SERVICE (object);
-
- switch (prop_id)
- {
- case PROP_CONNECTION:
- service->connection = g_value_dup_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-
-
-static gboolean
-luc_handler_service_handle_register (LUCHandler *object,
- GDBusMethodInvocation *invocation,
- GVariant *apps,
- LUCHandlerService *service)
-{
- GVariantBuilder dict_builder;
- GHashTableIter hiter;
- GVariantIter viter;
- GHashTable *table;
- GPtrArray *apps_array;
- GVariant *current_context;
- GVariant *current_apps;
- GVariant *new_context;
- GVariant *new_apps;
- GList *lp;
- GList *luc_types;
- gchar *app;
- gchar *luc_type;
- guint n;
-
- g_return_val_if_fail (IS_LUC_HANDLER (object), FALSE);
- g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);
- g_return_val_if_fail (LUC_HANDLER_IS_SERVICE (service), FALSE);
-
- /* create a hash table to merge the current context and the newly registered apps */
- table = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, (GDestroyNotify) g_ptr_array_unref);
-
- /* obtain the current content of the last user context */
- current_context = luc_handler_get_last_user_context (service->interface);
-
- /* prepare app lists for all LUC types present in the current context */
- g_variant_iter_init (&viter, current_context);
- while (g_variant_iter_loop (&viter, "{sas}", &luc_type, NULL))
- {
- g_hash_table_insert (table, g_strdup (luc_type),
- g_ptr_array_new_with_free_func (g_free));
- }
-
- /* add app lists for LUC types that are needed for the newly registered apps */
- g_variant_iter_init (&viter, apps);
- while (g_variant_iter_loop (&viter, "{sas}", &luc_type, NULL))
- {
- g_hash_table_insert (table, g_strdup (luc_type),
- g_ptr_array_new_with_free_func (g_free));
- }
-
- /* we now have a hash table that has all LUC types involved in the
- * current context and in the newly registered apps */
-
- /* fill the app lists for each LUC type involved, make sure that newly registered
- * apps are added at the end so that they are "prioritized" */
- g_hash_table_iter_init (&hiter, table);
- while (g_hash_table_iter_next (&hiter, (gpointer) &luc_type, (gpointer) &apps_array))
- {
- /* get apps currently registered for the LUC type */
- current_apps = g_variant_lookup_value (current_context, luc_type,
- G_VARIANT_TYPE_STRING_ARRAY);
-
- /* get apps to be registered for the LUC type now */
- new_apps = g_variant_lookup_value (apps, luc_type, G_VARIANT_TYPE_STRING_ARRAY);
-
- /* add all currently registered apps unless they are to be registered now.
- * this is because we want apps to be registered now to be moved to the end
- * of the lists */
- for (n = 0; current_apps != NULL && n < g_variant_n_children (current_apps); n++)
- {
- g_variant_get_child (current_apps, n, "&s", &app);
- if (!g_variant_string_array_has_string (new_apps, app))
- g_ptr_array_add (apps_array, g_strdup (app));
- }
-
- /* add all newly registered apps at the end now */
- for (n = 0; new_apps != NULL && n < g_variant_n_children (new_apps); n++)
- {
- g_variant_get_child (new_apps, n, "&s", &app);
- g_ptr_array_add (apps_array, g_strdup (app));
- }
-
- /* release app lists for this LUC type */
- if (current_apps != NULL)
- g_variant_unref (current_apps);
- if (new_apps != NULL)
- g_variant_unref (new_apps);
- }
-
- /* construct a new dictionary variant for the new LUC */
- g_variant_builder_init (&dict_builder, G_VARIANT_TYPE ("a{sas}"));
-
- /* copy LUC types and corresponding apps over to the new context. make
- * sure the order (alphabetic) in which we add LUC types to the context
- * dict is always the same. this is helpful for testing */
- luc_types = g_hash_table_get_keys (table);
- luc_types = g_list_sort (luc_types, (GCompareFunc) g_strcmp0);
- for (lp = luc_types; lp != NULL; lp = lp->next)
- {
- /* get the apps list registered for this LUC type */
- apps_array = g_hash_table_lookup (table, lp->data);
-
- /* NULL-terminate the pointer so that we can treat it as a gchar ** */
- g_ptr_array_add (apps_array, NULL);
-
- /* add the LUC type and its apps to the new context */
- g_variant_builder_add (&dict_builder, "{s^as}", lp->data, apps_array->pdata);
- }
-
- /* free the LUC types and our LUC type to apps mapping */
- g_list_free (luc_types);
- g_hash_table_unref (table);
-
- /* apply the new last user context */
- new_context = g_variant_builder_end (&dict_builder);
- luc_handler_set_last_user_context (service->interface, new_context);
-
- /* notify the caller that we have handled the register request */
- g_dbus_method_invocation_return_value (invocation, NULL);
- return TRUE;
-}
-
-
-
-static gboolean
-luc_handler_service_handle_deregister (LUCHandler *object,
- GDBusMethodInvocation *invocation,
- GVariant *apps,
- LUCHandlerService *service)
-{
- GVariantBuilder apps_builder;
- GVariantBuilder builder;
- GVariantIter viter;
- GVariant *current_context;
- GVariant *new_context;
- GVariant *current_apps;
- GVariant *apps_to_remove;
- gchar *app;
- gchar *luc_type;
- guint num_apps;
- guint n;
-
- g_return_val_if_fail (IS_LUC_HANDLER (object), FALSE);
- g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);
- g_return_val_if_fail (LUC_HANDLER_IS_SERVICE (service), FALSE);
-
- /* obtain the current content of the last user context */
- current_context = luc_handler_get_last_user_context (service->interface);
-
- /* initialise the builder for the new context */
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sas}"));
-
- /* copy the current context into the new context, drop all apps that
- * are supposed to be registered */
- g_variant_iter_init (&viter, current_context);
- while (g_variant_iter_loop (&viter, "{s@as}", &luc_type, ¤t_apps))
- {
- /* get a list of apps to be removed from this LUC type */
- apps_to_remove = g_variant_lookup_value (apps, luc_type,
- G_VARIANT_TYPE_STRING_ARRAY);
-
- if (apps_to_remove == NULL)
- {
- /* there are no apps to be removed from this LUC type, just copy
- * all currently registered apps over */
- g_variant_builder_add (&builder, "{s@as}", luc_type, current_apps);
- }
- else
- {
- /* we need to remove some apps from the current LUC type, so let's
- * build a new string array */
- g_variant_builder_init (&apps_builder, G_VARIANT_TYPE ("as"));
-
- /* add all apps currently registered for this LUC type to the string
- * array unless they are to be removed */
- for (n = 0, num_apps = 0;
- current_apps != NULL && n < g_variant_n_children (current_apps);
- n++)
- {
- g_variant_get_child (current_apps, n, "&s", &app);
- if (!g_variant_string_array_has_string (apps_to_remove, app))
- {
- g_variant_builder_add (&apps_builder, "s", app);
- num_apps++;
- }
- }
-
- /* add the LUC type and its apps to the new context unless there are none */
- if (num_apps > 0)
- g_variant_builder_add (&builder, "{sas}", luc_type, &apps_builder);
-
- /* free resources used for building the string array */
- g_variant_builder_clear (&apps_builder);
- }
-
- /* release the apps to be removed for this LUC type */
- if (apps_to_remove != NULL)
- g_variant_unref (apps_to_remove);
- }
-
- /* apply the new last user context */
- new_context = g_variant_builder_end (&builder);
- luc_handler_set_last_user_context (service->interface, new_context);
-
- /* notify the caller that we have handled the deregistration request */
- g_dbus_method_invocation_return_value (invocation, NULL);
- return TRUE;
-}
-
-
-
-static gboolean
-luc_handler_service_get_last_user_context (GValue *value,
- GVariant *variant,
- gpointer user_data)
-{
- g_return_val_if_fail (G_IS_VALUE (value), FALSE);
- g_return_val_if_fail (variant != NULL, FALSE);
-
- g_value_set_variant (value, variant);
- return TRUE;
-}
-
-
-
-static GVariant *
-luc_handler_service_set_last_user_context (const GValue *value,
- const GVariantType *expected_type,
- gpointer user_data)
-{
- g_return_val_if_fail (G_IS_VALUE (value), FALSE);
- g_return_val_if_fail (expected_type != G_VARIANT_TYPE_DICTIONARY, FALSE);
-
- return g_value_dup_variant (value);
-}
-
-
-
-LUCHandlerService *
-luc_handler_service_new (GDBusConnection *connection)
-{
- g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
- return g_object_new (LUC_HANDLER_TYPE_SERVICE, "connection", connection, NULL);
-}
-
-
-
-gboolean
-luc_handler_service_start (LUCHandlerService *service,
- GError **error)
-{
- g_return_val_if_fail (LUC_HANDLER_IS_SERVICE (service), FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- /* announce the org.genivi.LUCHandler1 service on the bus */
- return g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (service->interface),
- service->connection,
- "/org/genivi/LUCHandler1",
- error);
-}
+++ /dev/null
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/* -
- * Copyright (c) 2012 GENIVI.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#ifndef __LUC_HANDLER_SERVICE_H__
-#define __LUC_HANDLER_SERVICE_H__
-
-#include <gio/gio.h>
-
-G_BEGIN_DECLS
-
-#define LUC_HANDLER_TYPE_SERVICE (luc_handler_service_get_type ())
-#define LUC_HANDLER_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LUC_HANDLER_TYPE_SERVICE, LUCHandlerService))
-#define LUC_HANDLER_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LUC_HANDLER_TYPE_SERVICE, LUCHandlerServiceClass))
-#define LUC_HANDLER_IS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LUC_HANDLER_TYPE_SERVICE))
-#define LUC_HANDLER_IS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LUC_HANDLER_TYPE_SERVICE)
-#define LUC_HANDLER_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LUC_HANDLER_TYPE_SERVICE, LUCHandlerServiceClass))
-
-typedef struct _LUCHandlerServiceClass LUCHandlerServiceClass;
-typedef struct _LUCHandlerService LUCHandlerService;
-
-GType luc_handler_service_get_type (void) G_GNUC_CONST;
-
-LUCHandlerService *luc_handler_service_new (GDBusConnection *connection) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-gboolean luc_handler_service_start (LUCHandlerService *service,
- GError **error);
-
-G_END_DECLS
-
-#endif /* !__LUC_HANDLER_SERVICE_H__ */
-
+++ /dev/null
-/* vi:set et ai sw=2 sts=2 ts=2: */
-/* -
- * Copyright (c) 2012 GENIVI.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include <glib.h>
-#include <gio/gio.h>
-
-#include <luc-handler/luc-handler-application.h>
-#include <luc-handler/luc-handler-service.h>
-
-
-
-int
-main (int argc,
- char **argv)
-{
- LUCHandlerApplication *application;
- LUCHandlerService *service;
- GDBusConnection *connection;
- GError *error = NULL;
- gint exit_status = EXIT_SUCCESS;
-
- /* initialize the GType type system */
- g_type_init ();
-
- /* attempt to connect to D-Bus */
- connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
- if (connection == NULL)
- {
- g_warning ("Failed to connect to D-Bus: %s", error->message);
-
- /* clean up */
- g_error_free (error);
-
- return EXIT_FAILURE;
- }
-
- /* instantiate the LUCHandler service implementation */
- service = luc_handler_service_new (connection);
- if (!luc_handler_service_start (service, &error))
- {
- g_warning ("Failed to start the LUCHandler service: %s", error->message);
-
- /* clean up */
- g_error_free (error);
- g_object_unref (service);
- g_object_unref (connection);
-
- return EXIT_FAILURE;
- }
-
- /* create and run the main application */
- application = luc_handler_application_new (service);
- exit_status = g_application_run (G_APPLICATION (application), 0, NULL);
- g_object_unref (application);
-
- /* release allocated objects */
- g_object_unref (service);
- g_object_unref (connection);
-
- return exit_status;
-}
+++ /dev/null
-<schemalist>
- <schema id="org.genivi.LUCHandler@BOOT_MANAGER_VERSION_API@" path="/org/genivi/LUCHandler@BOOT_MANAGER_VERSION_API@/">
- <key name="last-user-context" type="a{sas}">
- <summary>A dictionary of the apps that are considered part of the Last User Context</summary>
- <description>
- The current Last User Context, that is, a dictionary that maps LUC types
- to arrays of one or more applications registered for each of them.
- </description>
- <default>{}</default>
- </key>
- </schema>
-</schemalist>
+++ /dev/null
-[D-BUS Service]
-Name=org.genivi.LUCHandler1
-Exec=@libdir@/luc-handler-@BOOT_MANAGER_VERSION_API@/luc-handler
# vi:set ts=8 sw=8 noet ai nocindent:
SUBDIRS = \
- luc-handler \
+ boot-manager \
legacy-app-handler
--- /dev/null
+# vi:set ts=8 sw=8 noet ai nocindent:
+
+TESTS = \
+ test-luc-handler
+
+EXTRA_DIST = \
+ test-luc-handler
+
+luc_dir = \
+ $(datadir)/org.genivi.BootManager$(BOOT_MANAGER_VERSION_API)
+
+export luc_path = \
+ $(luc_dir)/last-user-context
+
+noinst_PROGRAMS = \
+ gvariant-writer
+
+gvariant_writer_SOURCES = \
+ gvariant_writer.c
+
+gvariant_writer_CFLAGS = \
+ -DG_LOG_DOMAIN=\"gvariant-writer\" \
+ -I$(top_srcdir) \
+ $(GIO_CFLAGS) \
+ $(GIO_UNIX_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(PLATFORM_CFLAGS) \
+ $(PLATFORM_CPPFLAGS)
+
+gvariant_writer_LDFLAGS = \
+ -no-undefined \
+ $(PLATFORM_LDFLAGS)
+
+gvariant_writer_LDADD = \
+ $(GIO_LIBS) \
+ $(GIO_UNIX_LIBS) \
+ $(GLIB_LIBS)
--- /dev/null
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/* -
+ * Copyright (c) 2012 GENIVI.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <glib.h>
+#include <gio/gio.h>
+
+static void
+print_usage (const char *process_name)
+{
+ g_print ("Usage: \"%s <variant string> <file>\"\n"
+ "i.e. %s \"{0: ['foo.service']}\" \"temporary_file\"\n",
+ process_name, process_name);
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GFileOutputStream *stream;
+ const gchar *format = "a{ias}";
+ GVariant *variant;
+ GError *error = NULL;
+ GFile *outfile;
+
+ g_type_init();
+
+ if (argc != 3)
+ {
+ print_usage (argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ outfile = g_file_new_for_path (argv[2]);
+
+ /* First argument is the string to parse, second is the filename to put it in */
+
+ variant = g_variant_parse (G_VARIANT_TYPE (format), argv[1], NULL, NULL, &error);
+ if (error != NULL)
+ g_error ("Error occurred parsing variant: %s", error->message);
+
+ stream = g_file_create (outfile, G_FILE_CREATE_NONE, NULL, &error);
+ if (error != NULL)
+ {
+ if (error->code != G_IO_ERROR_EXISTS)
+ {
+ g_error ("Error occurred creating file: %s", error->message);
+ }
+ g_error_free (error);
+ error = NULL;
+ }
+ else
+ {
+ g_object_unref (stream);
+ }
+
+ g_file_replace_contents (outfile, g_variant_get_data (variant),
+ g_variant_get_size (variant), NULL, FALSE, G_FILE_CREATE_NONE,
+ NULL, NULL, &error);
+ if (error != NULL)
+ g_error ("Error occurred writing variant: %s", error->message);
+
+ g_variant_unref (variant);
+ g_object_unref (outfile);
+
+ return EXIT_SUCCESS;
+}
--- /dev/null
+#!/bin/bash
+
+#set -e
+
+#function to compare the LastUserContext
+# $1 is the context
+# $2 is the path to the file to compare the context to
+compare_luc()
+{
+ ./gvariant-writer "$1" "$2"
+ diff -q "$luc_path" "$2"
+}
+
+# function to begin registration
+begin()
+{
+ gdbus call --system \
+ -d org.genivi.BootManager1 \
+ -o /org/genivi/BootManager1/BootManager \
+ -m org.genivi.BootManager1.BootManager.BeginLUCRegistration \
+ &> /dev/null
+}
+
+# function to make a registration call
+register()
+{
+ gdbus call --system \
+ -d org.genivi.BootManager1 \
+ -o /org/genivi/BootManager1/BootManager \
+ -m org.genivi.BootManager1.BootManager.RegisterWithLUC \
+ "$1" &> /dev/null
+}
+
+# function to begin registration
+end()
+{
+ gdbus call --system \
+ -d org.genivi.BootManager1 \
+ -o /org/genivi/BootManager1/BootManager \
+ -m org.genivi.BootManager1.BootManager.FinishLUCRegistration \
+ &> /dev/null
+}
+
+
+# function to fail with a reason
+fail()
+{
+ echo "ERROR: $1"
+ exit 1
+}
+
+rm -f temp
+rm -f "$luc_path"
+
+
+#Test a simple dictionary
+begin
+register "{0: ['app1.unit']}"
+end
+[ -z "$(compare_luc "{0: ['app1.unit']}" "temp")" ] \
+ || fail "Registration was not identical"
+
+#Test whether RegisterWithLUC() writes by itself
+register "{1: ['app2.service']}"
+[ "$(compare_luc "{1: ['app2.service']}" "temp" )" ] \
+ || fail "Registration happened with only RegisterWithLUC() called"
+
+#Test whether calling FinishLUCRegistration() by itself changes the file
+end
+[ -z "$(compare_luc "{0: ['app1.unit']}" "temp")" ] \
+ || fail "FinishLUCRegistration() without BeginLUCRegistration() changed the file"
+
+#Test whether a complex dictionary works
+dict="{0: ['app1.unit'], 1: ['app1.unit', 'app3.unit'], 2: ['app2.unit']}"
+begin
+register "$dict"
+end
+[ -z "$(compare_luc "$dict" "temp")" ] \
+ || fail "Failed to register a complex dictionary type"
+
+#Test with multiple RegisterWithLUC() calls
+dict="{0: ['app1.unit'], 1: ['app3.unit']}"
+begin
+register "{0: ['app1.unit']}"
+register "{1: ['app3.unit']}"
+end
+[ -z "$(compare_luc "$dict" "temp")" ] \
+ || fail "Failed to register correctly when multiple calls are used"
+
+#Test that using multiply RegisterWithLUC() calls changes the order of the apps
+dict="{1: ['app2.unit', 'app1.unit']}"
+begin
+register "{1: ['app1.unit', 'app2.unit']}"
+register "{1: ['app1.unit']}"
+end
+[ -z "$(compare_luc "$dict" "temp")" ] \
+ || fail "Failed to change the order of the apps on multiple RegisterWithLUC() calls"
+
+++ /dev/null
-# vi:set ts=8 sw=8 noet ai nocindent:
-
-TESTS = \
- test-luc-handler
-
-EXTRA_DIST = \
- test-luc-handler
+++ /dev/null
-
-#!/bin/bash
-
-set -e
-
-# function to read the LastUserContext property
-get_luc()
-{
- gdbus call -e \
- -d org.genivi.LUCHandler1 \
- -o /org/genivi/LUCHandler1 \
- -m org.freedesktop.DBus.Properties.Get \
- "org.genivi.LUCHandler1" \
- "LastUserContext"
-}
-
-# function to make a registration call
-register()
-{
- gdbus call -e \
- -d org.genivi.LUCHandler1 \
- -o /org/genivi/LUCHandler1 \
- -m org.genivi.LUCHandler1.Register \
- "$1" &> /dev/null
-}
-
-# function to make a registration call
-deregister()
-{
- gdbus call -e \
- -d org.genivi.LUCHandler1 \
- -o /org/genivi/LUCHandler1 \
- -m org.genivi.LUCHandler1.Deregister \
- "$1" &> /dev/null
-}
-
-# function to fail with a reason
-fail()
-{
- echo "ERROR: $1"
- exit 1
-}
-
-# reset the LUC
-gsettings set org.genivi.LUCHandler1 last-user-context '{}'
-
-# assert that the LastUserContext property is empty now
-[[ "$(get_luc)" = "(<@a{sas} {}>,)" ]] \
- || fail "LastUserContext out of sync with GSettings key after resetting"
-
-### REGISTRATION OF SINGLE APPS
-
-## Registration of the first app
-register '{ "background": [ "app1" ] }'
-[[ "$(get_luc)" = "(<{'background': ['app1']}>,)" ]] \
- || fail "Registration of a single background app was not applied"
-
-## Registration of another, different app
-register '{ "background" : [ "app2" ] }'
-[[ "$(get_luc)" = "(<{'background': ['app1', 'app2']}>,)" ]] \
- || fail "Registration of a second background app was missing or out of order"
-
-## Registration of a pre-existing app moves it to the end
-register '{ "background" : [ "app1"] }'
-[[ "$(get_luc)" = "(<{'background': ['app2', 'app1']}>,)" ]] \
- || fail "Registration of a pre-existing app failed to change its ordering"
-
-## Registration of another app in a different category
-register '{ "foreground" : [ "app3" ] }'
-[[ "$(get_luc)" = "(<{'background': ['app2', 'app1'], 'foreground': ['app3']}>,)" ]] \
- || fail "Registration of an app in a different category was missing or out of order"
-
-### DEREGISTRATION OF SINGLE APPS
-## deregister an app from a list (not leaving it empty)
-deregister '{ "background" : [ "app2" ] }'
-[[ "$(get_luc)" = "(<{'background': ['app1'], 'foreground': ['app3']}>,)" ]] \
- || fail "Deregistration of an app was not applied"
-
-## deregister an app from a list, leaving it empty
-deregister '{ "background" : [ "app1" ] }'
-[[ "$(get_luc)" = "(<{'foreground': ['app3']}>,)" ]] \
- || fail "Deregistration of an app did not remove category"
-
-### REGISTRATION OF MULTIPLE APPS
-## register two apps into a new category
-register '{ "background" : [ "app1", "app2"] }'
-[[ "$(get_luc)" = "(<{'background': ['app1', 'app2'], 'foreground': ['app3']}>,)" ]] \
- || fail "Registration of multiple apps was not applied"
-
-## register two apps into an existing category
-register '{ "background" : [ "app3", "app4"] }'
-[[ "$(get_luc)" = \
- "(<{'background': ['app1', 'app2', 'app3', 'app4'], 'foreground': ['app3']}>,)" ]] \
- || fail "Registration of multiple apps in existing category was not applied"
-
-## register two apps, reordering
-register '{ "background" : [ "app3", "app1"] }'
-[[ "$(get_luc)" = \
- "(<{'background': ['app2', 'app4', 'app3', 'app1'], 'foreground': ['app3']}>,)" ]] \
- || fail "Registration of multiple apps did not reorder"
-
-## register multiple apps, one in a new category
-register '{ "background" : [ "app5" ], "audible" : [ "app5" ] }'
-[[ "$(get_luc)" = \
- "(<{'audible': ['app5'], 'background': ['app2', 'app4', 'app3', 'app1', 'app5'], 'foreground': ['app3']}>,)" ]] \
- || fail "Registration of multiple apps did not create new category"
-
-### DEREGISTRATION OF MULTIPLE APPS
-## Deregister all the contents of one category
-deregister '{ "background" : [ "app1", "app2", "app3", "app4", "app5" ] }'
-[[ "$(get_luc)" = "(<{'audible': ['app5'], 'foreground': ['app3']}>,)" ]] \
- || fail "Deregistration of apps did not remove category"
-
-## Deregister multiple categories at once
-deregister '{ "foreground" : [ "app3" ], "audible" : [ "app5" ] }'
-[[ "$(get_luc)" = "(<@a{sas} {}>,)" ]] \
- || fail "Deregistration of apps did not remove multiple categories"
-