Merge into one process, change D-Bus interfaces and write LUC to file
authorJonathan Maw <jonathan.maw@codethink.co.uk>
Mon, 9 Jul 2012 11:53:25 +0000 (12:53 +0100)
committerJonathan Maw <jonathan.maw@codethink.co.uk>
Tue, 17 Jul 2012 14:26:01 +0000 (15:26 +0100)
The following changes were made:
- Restructure the D-Bus interfaces:
--  The old boot manager interface is removed, we are no longer
    interested in being a remote controller of systemd.
--  The LUC Handler has been rewritten and renamed to
    org.genivi.BootManager1.BootManager. It has the following
    methods:
---   BeginLUCRegistration() initializes the LUC registration
      sequence at shutdown.
---   RegisterWithLUC(a{ias}) registers one or more apps with
      different LUC types.
---   FinishLUCRegistration() finishes the LUC registration
      sequence and atomically replaces the previous LUC.
--  The legacy application handler has been renamed to
    org.genivi.BootManager1.LegacyAppHandler. This interface
    is not for external use. It is meant only for the command-
    line interface to communicate with the boot manager.
--  The LastUserContext property has been removed.
- The last user context is now stored in a file rather than with
  GSettings. This was requested after the Gothenburg F2F, but is
  included because it is easier to make the change now than modify
  GSettings only to remove it later.
- All services run as part of the same process (i.e. boot-manager).
- All services run on the system bus. Because of this, the boot
  manager's command-line interface is handled differently, as the
  previous implementation, using GApplication, does not work on the
  system bus. The command-line interface now works by making a D-Bus
  call to the boot manager service, instead of using GApplication's
  remote command-line functionality.
- The LUC Handler tests have been renamed to the boot manager
  tests, and are changed in line with the new interface methods.

Note: The legacy app handler tests have not yet been modified to work
      with these changes.

56 files changed:
Makefile.am
boot-manager/Makefile.am
boot-manager/boot-manager-application.c
boot-manager/boot-manager-application.h
boot-manager/boot-manager-command-line.c [new file with mode: 0644]
boot-manager/boot-manager-command-line.h [moved from common/glib-extensions.h with 55% similarity]
boot-manager/boot-manager-dbus.xml [new file with mode: 0644]
boot-manager/boot-manager-service.c
boot-manager/boot-manager-service.h
boot-manager/busconf/Makefile.am [new file with mode: 0644]
boot-manager/busconf/org.genivi.BootManager1.conf [moved from legacy-app-handler/org.genivi.LegacyAppHandler1.conf with 54% similarity]
boot-manager/dbus/Makefile.am [moved from legacy-app-handler/dbus/Makefile.am with 91% similarity]
boot-manager/dbus/org.genivi.BootManager1.service.in [moved from boot-manager/org.genivi.BootManager1.service.in with 69% similarity]
boot-manager/glib-extensions.c [new file with mode: 0644]
boot-manager/glib-extensions.h [new file with mode: 0644]
boot-manager/job-manager.c [new file with mode: 0644]
boot-manager/job-manager.h [new file with mode: 0644]
boot-manager/la-handler-dbus.xml [moved from legacy-app-handler/la-handler-dbus.xml with 92% similarity]
boot-manager/la-handler-service.c [moved from legacy-app-handler/la-handler-service.c with 84% similarity]
boot-manager/la-handler-service.h [moved from legacy-app-handler/la-handler-service.h with 91% similarity]
boot-manager/luc-starter.c
boot-manager/luc-starter.h
boot-manager/main.c
boot-manager/shutdown-consumer-dbus.xml [moved from common/shutdown-consumer-dbus.xml with 92% similarity]
boot-manager/shutdown-consumer-service.c [moved from common/shutdown-consumer-service.c with 98% similarity]
boot-manager/shutdown-consumer-service.h [moved from common/shutdown-consumer-service.h with 100% similarity]
boot-manager/systemd/Makefile.am [moved from legacy-app-handler/systemd/Makefile.am with 67% similarity]
boot-manager/systemd/org.genivi.BootManager1.service.in [new file with mode: 0644]
boot-manager/target-startup-monitor.c
boot-manager/watchdog-client.c [moved from common/watchdog-client.c with 99% similarity]
boot-manager/watchdog-client.h [moved from common/watchdog-client.h with 100% similarity]
common/Makefile.am [deleted file]
common/boot-manager-dbus.xml [deleted file]
common/glib-extensions.c [deleted file]
configure.ac
legacy-app-handler/Makefile.am [deleted file]
legacy-app-handler/dbus/org.genivi.LegacyAppHandler1.service.in [deleted file]
legacy-app-handler/la-handler-application.c [deleted file]
legacy-app-handler/la-handler-application.h [deleted file]
legacy-app-handler/main.c [deleted file]
legacy-app-handler/systemd/org.genivi.LegacyAppHandler1.service.in [deleted file]
luc-handler/Makefile.am [deleted file]
luc-handler/luc-handler-application.c [deleted file]
luc-handler/luc-handler-application.h [deleted file]
luc-handler/luc-handler-dbus.xml [deleted file]
luc-handler/luc-handler-service.c [deleted file]
luc-handler/luc-handler-service.h [deleted file]
luc-handler/main.c [deleted file]
luc-handler/org.genivi.LUCHandler1.gschema.xml.in [deleted file]
luc-handler/org.genivi.LUCHandler1.service.in [deleted file]
tests/Makefile.am
tests/boot-manager/Makefile.am [new file with mode: 0644]
tests/boot-manager/gvariant_writer.c [new file with mode: 0644]
tests/boot-manager/test-luc-handler [new file with mode: 0755]
tests/luc-handler/Makefile.am [deleted file]
tests/luc-handler/test-luc-handler [deleted file]

index bf8f9dc..0af9335 100644 (file)
@@ -1,10 +1,7 @@
 # vi:set ts=8 sw=8 noet ai nocindent:
 
 SUBDIRS =                                                              \
-       common                                                          \
-       luc-handler                                                     \
        boot-manager                                                    \
-       legacy-app-handler                                              \
        tests
 
 .PHONY: ChangeLog
index b075aca..abd3284 100644 (file)
@@ -1,5 +1,16 @@
 # 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)
 
@@ -7,27 +18,45 @@ boot_manager_PROGRAMS =                                                      \
        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)                                                   \
@@ -42,32 +71,17 @@ boot_manager_LDFLAGS =                                                      \
        -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 =                                                       \
@@ -76,6 +90,30 @@ 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                 \
index 2b7345b..20565d2 100644 (file)
 #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,
 };
 
 
@@ -58,21 +67,32 @@ struct _BootManagerApplicationClass
 
 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;
 };
 
 
@@ -97,22 +117,42 @@ boot_manager_application_class_init (BootManagerApplicationClass *klass)
   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));
@@ -148,19 +188,30 @@ boot_manager_application_finalize (GObject *object)
 {
   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);
 }
@@ -172,9 +223,14 @@ boot_manager_application_constructed (GObject *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);
 }
 
 
@@ -189,11 +245,16 @@ boot_manager_application_get_property (GObject    *object,
 
   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);
@@ -216,11 +277,17 @@ boot_manager_application_set_property (GObject      *object,
 
   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);
@@ -234,14 +301,44 @@ static void
 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
@@ -250,7 +347,6 @@ boot_manager_application_int_handler (GApplication *app)
   BootManagerApplication *application = BOOT_MANAGER_APPLICATION (app);
 
   luc_starter_cancel (application->luc_starter);
-  boot_manager_service_cancel (application->boot_manager);
 
   return TRUE;
 }
@@ -258,16 +354,20 @@ boot_manager_application_int_handler (GApplication *app)
 
 
 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);
 }
index c5fcbf4..1733a4f 100644 (file)
 #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
 
@@ -27,8 +30,10 @@ typedef struct _BootManagerApplication      BootManagerApplication;
 
 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
 
diff --git a/boot-manager/boot-manager-command-line.c b/boot-manager/boot-manager-command-line.c
new file mode 100644 (file)
index 0000000..e83f5ff
--- /dev/null
@@ -0,0 +1,176 @@
+/* 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;
+}
similarity index 55%
rename from common/glib-extensions.h
rename to boot-manager/boot-manager-command-line.h
index b60497d..45e0611 100644 (file)
@@ -7,16 +7,9 @@
  * 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);
diff --git a/boot-manager/boot-manager-dbus.xml b/boot-manager/boot-manager-dbus.xml
new file mode 100644 (file)
index 0000000..c1e92a0
--- /dev/null
@@ -0,0 +1,61 @@
+<?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>
index 0b8761b..d8e0b84 100644 (file)
 #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);
 
 
 
@@ -29,111 +32,29 @@ enum
 {
   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);
 
 
 
@@ -148,21 +69,9 @@ struct _BootManagerService
 
   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;
 };
 
 
@@ -178,7 +87,6 @@ boot_manager_service_class_init (BootManagerServiceClass *klass)
 
   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;
 
@@ -191,16 +99,6 @@ boot_manager_service_class_init (BootManagerServiceClass *klass)
                                                         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));
 }
 
 
@@ -208,40 +106,28 @@ boot_manager_service_class_init (BootManagerServiceClass *klass)
 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);
 }
 
 
@@ -251,26 +137,17 @@ boot_manager_service_finalize (GObject *object)
 {
   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);
 }
@@ -278,19 +155,6 @@ boot_manager_service_finalize (GObject *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,
@@ -303,9 +167,6 @@ boot_manager_service_get_property (GObject    *object,
     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;
@@ -327,9 +188,6 @@ boot_manager_service_set_property (GObject      *object,
     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;
@@ -339,694 +197,245 @@ boot_manager_service_set_property (GObject      *object,
 
 
 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);
 }
 
@@ -1039,169 +448,117 @@ boot_manager_service_start_up (BootManagerService *service,
   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;
 }
index 6e86b36..c1575c0 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef __BOOT_MANAGER_SERVICE_H__
 #define __BOOT_MANAGER_SERVICE_H__
 
+#include <gio/gio.h>
+
 #include <boot-manager/systemd-manager-dbus.h>
 
 G_BEGIN_DECLS
@@ -24,53 +26,18 @@ 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
 
diff --git a/boot-manager/busconf/Makefile.am b/boot-manager/busconf/Makefile.am
new file mode 100644 (file)
index 0000000..cf373b7
--- /dev/null
@@ -0,0 +1,8 @@
+# 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
+
+
@@ -2,8 +2,8 @@
  "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>
similarity index 91%
rename from legacy-app-handler/dbus/Makefile.am
rename to boot-manager/dbus/Makefile.am
index 1ba7717..6e7b058 100644 (file)
@@ -3,7 +3,7 @@
 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)
 
@@ -1,3 +1,4 @@
 [D-BUS Service]
 Name=org.genivi.BootManager1
+SystemdService = org.genivi.BootManager1.service
 Exec=@libdir@/boot-manager-@BOOT_MANAGER_VERSION_API@/boot-manager
diff --git a/boot-manager/glib-extensions.c b/boot-manager/glib-extensions.c
new file mode 100644 (file)
index 0000000..b2c21ea
--- /dev/null
@@ -0,0 +1,103 @@
+/* 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", &current_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);
+}
diff --git a/boot-manager/glib-extensions.h b/boot-manager/glib-extensions.h
new file mode 100644 (file)
index 0000000..caaf2ae
--- /dev/null
@@ -0,0 +1,27 @@
+/* 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__ */
diff --git a/boot-manager/job-manager.c b/boot-manager/job-manager.c
new file mode 100644 (file)
index 0000000..01e8df8
--- /dev/null
@@ -0,0 +1,466 @@
+/* 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);
+}
diff --git a/boot-manager/job-manager.h b/boot-manager/job-manager.h
new file mode 100644 (file)
index 0000000..d20c7ba
--- /dev/null
@@ -0,0 +1,49 @@
+/* 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__ */
similarity index 92%
rename from legacy-app-handler/la-handler-dbus.xml
rename to boot-manager/la-handler-dbus.xml
index c7cf713..6a4cd1a 100644 (file)
@@ -1,5 +1,5 @@
 <?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
@@ -12,7 +12,7 @@
     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.
similarity index 84%
rename from legacy-app-handler/la-handler-service.c
rename to boot-manager/la-handler-service.c
index d042bf8..a0d7adb 100644 (file)
 
 #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>
 
 
 
@@ -34,6 +32,7 @@ enum
 {
   PROP_0,
   PROP_CONNECTION,
+  PROP_JOB_MANAGER,
 };
 
 
@@ -64,8 +63,10 @@ static gboolean                        la_handler_service_handle_deregister
                                                                                            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);
@@ -85,7 +86,7 @@ struct _LAHandlerService
 
   GDBusConnection *connection;
   LAHandler       *interface;
-  BootManager     *boot_manager;
+  JobManager      *job_manager;
 
   /* list of shutdown consumers */
   GList           *shutdown_consumers;
@@ -127,6 +128,16 @@ la_handler_service_class_init (LAHandlerServiceClass *klass)
                                                         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));
 }
 
 
@@ -138,13 +149,6 @@ la_handler_service_constructed (GObject *object)
   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",
@@ -172,7 +176,7 @@ la_handler_service_init (LAHandlerService *service)
   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;
@@ -209,8 +213,8 @@ la_handler_service_finalize (GObject *object)
                                         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,
@@ -234,6 +238,9 @@ la_handler_service_get_property (GObject    *object,
     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;
@@ -255,6 +262,9 @@ la_handler_service_set_property (GObject      *object,
     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;
@@ -308,50 +318,41 @@ la_handler_service_handle_consumer_shutdown (ShutdownConsumerService *consumer,
   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);
     }
@@ -368,7 +369,6 @@ la_handler_service_handle_consumer_shutdown_finish (GObject      *object,
 }
 
 
-
 static void
 la_handler_service_release_shutdown_consumer (ShutdownConsumerService *service)
 {
@@ -417,10 +417,16 @@ la_handler_service_consumer_bundle_unref (LAHandlerServiceConsumerBundle *bundle
 
 
 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);
 }
 
 
@@ -432,10 +438,10 @@ la_handler_service_start (LAHandlerService *service,
   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);
 }
 
similarity index 91%
rename from legacy-app-handler/la-handler-service.h
rename to boot-manager/la-handler-service.h
index 6aac1e9..cf877b0 100644 (file)
@@ -12,6 +12,8 @@
 
 #include <gio/gio.h>
 
+#include <boot-manager/job-manager.h>
+
 G_BEGIN_DECLS
 
 #define LA_HANDLER_TYPE_SERVICE            (la_handler_service_get_type ())
@@ -26,7 +28,8 @@ typedef struct _LAHandlerService      LAHandlerService;
 
 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,
index 80614ae..19fcca6 100644 (file)
@@ -17,8 +17,8 @@
 #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>
 
 
 
@@ -30,8 +30,8 @@ DLT_IMPORT_CONTEXT (boot_manager_context);
 enum
 {
   PROP_0,
-  PROP_BOOT_MANAGER,
-  PROP_LUC_HANDLER,
+  PROP_JOB_MANAGER,
+  PROP_BOOT_MANAGER_SERVICE,
 };
 
 
@@ -52,7 +52,7 @@ static gint luc_starter_compare_luc_types (gconstpointer       a,
 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,
@@ -72,8 +72,8 @@ struct _LUCStarter
 {
   GObject             __parent__;
 
-  BootManagerService *boot_manager;
-  LUCHandler         *luc_handler;
+  JobManager         *job_manager;
+  BootManagerService *boot_manager_service;
 
   gchar             **prioritised_types;
 
@@ -101,21 +101,22 @@ luc_starter_class_init (LUCStarterClass *klass)
   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));
@@ -160,11 +161,11 @@ luc_starter_finalize (GObject *object)
   /* 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);
 }
@@ -181,11 +182,11 @@ luc_starter_get_property (GObject    *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);
@@ -205,11 +206,11 @@ luc_starter_set_property (GObject      *object,
 
   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);
@@ -295,19 +296,19 @@ luc_starter_start_app (const gchar *app,
   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);
@@ -316,7 +317,7 @@ luc_starter_start_app_finish (BootManagerService *service,
   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);
@@ -387,15 +388,15 @@ luc_starter_cancel_start (const gchar  *app,
 
 
 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);
 }
 
@@ -407,10 +408,13 @@ luc_starter_start_groups (LUCStarter *starter)
   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++)
@@ -448,23 +452,40 @@ luc_starter_start_groups (LUCStarter *starter)
     }
 
   /* 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
@@ -480,6 +501,8 @@ luc_starter_start_groups (LUCStarter *starter)
 
   if (starter->start_order != NULL)
     luc_starter_start_next_group (starter);
+
+  g_variant_unref (context);
 }
 
 void
index 2f6db6e..f62601a 100644 (file)
@@ -11,7 +11,9 @@
 #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
 
@@ -27,8 +29,8 @@ typedef struct _LUCStarter      LUCStarter;
 
 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);
 
index 3291664..b37b79e 100644 (file)
 #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 ();
+}
 
 
 
@@ -37,23 +51,31 @@ main (int    argc,
 {
   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);
@@ -64,6 +86,17 @@ main (int    argc,
       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,
@@ -94,57 +127,30 @@ main (int    argc,
       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;
 }
similarity index 92%
rename from common/shutdown-consumer-dbus.xml
rename to boot-manager/shutdown-consumer-dbus.xml
index b793002..fb3fd01 100644 (file)
@@ -9,7 +9,7 @@
     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:
 
similarity index 98%
rename from common/shutdown-consumer-service.c
rename to boot-manager/shutdown-consumer-service.c
index 91b92eb..0e9f917 100644 (file)
@@ -14,8 +14,8 @@
 #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>
 
 
 
similarity index 67%
rename from legacy-app-handler/systemd/Makefile.am
rename to boot-manager/systemd/Makefile.am
index 874d9e6..ddc0dea 100644 (file)
@@ -1,11 +1,11 @@
 # 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"                               \
diff --git a/boot-manager/systemd/org.genivi.BootManager1.service.in b/boot-manager/systemd/org.genivi.BootManager1.service.in
new file mode 100644 (file)
index 0000000..09fb441
--- /dev/null
@@ -0,0 +1,4 @@
+[Service]
+Type = notify
+BusName = org.genivi.BootManager1.service
+ExecStart = @libdir@/boot-manager-@BOOT_MANAGER_VERSION_API@/boot-manager
index a6f15ae..e188152 100644 (file)
@@ -14,8 +14,7 @@
 #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>
 
 
similarity index 99%
rename from common/watchdog-client.c
rename to boot-manager/watchdog-client.c
index a2c1090..0a349f5 100644 (file)
@@ -16,7 +16,7 @@
 #include <glib-object.h>
 #include <gio/gio.h>
 
-#include <common/watchdog-client.h>
+#include <boot-manager/watchdog-client.h>
 
 
 
diff --git a/common/Makefile.am b/common/Makefile.am
deleted file mode 100644 (file)
index 30b40eb..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-# 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 $<
diff --git a/common/boot-manager-dbus.xml b/common/boot-manager-dbus.xml
deleted file mode 100644 (file)
index 9419ad6..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-<?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>
diff --git a/common/glib-extensions.c b/common/glib-extensions.c
deleted file mode 100644 (file)
index b28ef26..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* 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", &current_str);
-      if (g_strcmp0 (str, current_str) == 0)
-        found = TRUE;
-    }
-
-  return found;
-}
index 7f25c54..5c4e24c 100644 (file)
@@ -135,14 +135,11 @@ AC_DEFINE_UNQUOTED([PRIORITISED_LUC_TYPES],
 
 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
 ])
diff --git a/legacy-app-handler/Makefile.am b/legacy-app-handler/Makefile.am
deleted file mode 100644 (file)
index 0e037bc..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-# 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 $<
diff --git a/legacy-app-handler/dbus/org.genivi.LegacyAppHandler1.service.in b/legacy-app-handler/dbus/org.genivi.LegacyAppHandler1.service.in
deleted file mode 100644 (file)
index 3d84a65..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-[D-BUS Service]
-Name=org.genivi.LegacyAppHandler1
-SystemdService = org.genivi.LegacyAppHandler1.service
-Exec=@libdir@/legacy-app-handler-@BOOT_MANAGER_VERSION_API@/legacy-app-handler
diff --git a/legacy-app-handler/la-handler-application.c b/legacy-app-handler/la-handler-application.c
deleted file mode 100644 (file)
index 05b9167..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/* 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);
-}
diff --git a/legacy-app-handler/la-handler-application.h b/legacy-app-handler/la-handler-application.h
deleted file mode 100644 (file)
index 57160e2..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* 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__ */
-
diff --git a/legacy-app-handler/main.c b/legacy-app-handler/main.c
deleted file mode 100644 (file)
index 398ac04..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-/* 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;
-}
diff --git a/legacy-app-handler/systemd/org.genivi.LegacyAppHandler1.service.in b/legacy-app-handler/systemd/org.genivi.LegacyAppHandler1.service.in
deleted file mode 100644 (file)
index bc1f4b4..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-[Service]
-BusName = org.genivi.LegacyAppHandler1.service
-ExecStart = @libdir@/legacy-app-handler-@BOOT_MANAGER_VERSION_API@/legacy-app-handler
diff --git a/luc-handler/Makefile.am b/luc-handler/Makefile.am
deleted file mode 100644 (file)
index e86f4b1..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-# 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 $<
diff --git a/luc-handler/luc-handler-application.c b/luc-handler/luc-handler-application.c
deleted file mode 100644 (file)
index cd008ac..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/* 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);
-}
diff --git a/luc-handler/luc-handler-application.h b/luc-handler/luc-handler-application.h
deleted file mode 100644 (file)
index 6dd0c18..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* 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__ */
-
diff --git a/luc-handler/luc-handler-dbus.xml b/luc-handler/luc-handler-dbus.xml
deleted file mode 100644 (file)
index dd44e37..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-<?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>
diff --git a/luc-handler/luc-handler-service.c b/luc-handler/luc-handler-service.c
deleted file mode 100644 (file)
index fe6c2df..0000000
+++ /dev/null
@@ -1,456 +0,0 @@
-/* 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, &current_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);
-}
diff --git a/luc-handler/luc-handler-service.h b/luc-handler/luc-handler-service.h
deleted file mode 100644 (file)
index 3b56833..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* 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__ */
-
diff --git a/luc-handler/main.c b/luc-handler/main.c
deleted file mode 100644 (file)
index 90277be..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/* 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;
-}
diff --git a/luc-handler/org.genivi.LUCHandler1.gschema.xml.in b/luc-handler/org.genivi.LUCHandler1.gschema.xml.in
deleted file mode 100644 (file)
index 80c3775..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<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>
diff --git a/luc-handler/org.genivi.LUCHandler1.service.in b/luc-handler/org.genivi.LUCHandler1.service.in
deleted file mode 100644 (file)
index f45668f..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=org.genivi.LUCHandler1
-Exec=@libdir@/luc-handler-@BOOT_MANAGER_VERSION_API@/luc-handler
index 4bc7685..0e58ad8 100644 (file)
@@ -1,5 +1,5 @@
 # vi:set ts=8 sw=8 noet ai nocindent:
 
 SUBDIRS =                                                              \
-       luc-handler                                                     \
+       boot-manager                                                    \
        legacy-app-handler
diff --git a/tests/boot-manager/Makefile.am b/tests/boot-manager/Makefile.am
new file mode 100644 (file)
index 0000000..10fd944
--- /dev/null
@@ -0,0 +1,37 @@
+# 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)
diff --git a/tests/boot-manager/gvariant_writer.c b/tests/boot-manager/gvariant_writer.c
new file mode 100644 (file)
index 0000000..ffaf051
--- /dev/null
@@ -0,0 +1,80 @@
+/* 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;
+}
diff --git a/tests/boot-manager/test-luc-handler b/tests/boot-manager/test-luc-handler
new file mode 100755 (executable)
index 0000000..4d6f680
--- /dev/null
@@ -0,0 +1,98 @@
+#!/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"
+
diff --git a/tests/luc-handler/Makefile.am b/tests/luc-handler/Makefile.am
deleted file mode 100644 (file)
index 8883c85..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# vi:set ts=8 sw=8 noet ai nocindent:
-
-TESTS =                                                                        \
-       test-luc-handler
-
-EXTRA_DIST =                                                           \
-       test-luc-handler
diff --git a/tests/luc-handler/test-luc-handler b/tests/luc-handler/test-luc-handler
deleted file mode 100755 (executable)
index 45d2846..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-
-#!/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"
-