Add skeleton for the org.genivi.LUCHandler1 service implementation
authorJannis Pohlmann <jannis.pohlmann@codethink.co.uk>
Mon, 11 Jun 2012 16:27:13 +0000 (17:27 +0100)
committerJannis Pohlmann <jannis.pohlmann@codethink.co.uk>
Mon, 11 Jun 2012 16:27:13 +0000 (17:27 +0100)
This skeleton has stubs for the implementation of the Register() and
Deregister() methods. It currently uses the session bus to make it
easier to test as a regular user.

The implementation does not use the DLT yet, neither does it register
with systemd's watchdog mechanism. It also does not register with the
NSM as a shutdown consumer yet.

GDBus appears to need a little help to add parameters to the generated
C functions, so we'll probably have to extend the XML interface
definition with a few annotations.

configure.ac
luc-handler/Makefile.am
luc-handler/luc-handler-dbus.xml
luc-handler/luc-handler-service.c [new file with mode: 0644]
luc-handler/luc-handler-service.h [new file with mode: 0644]
luc-handler/main.c

index bdd0bab..74f76df 100644 (file)
@@ -57,7 +57,7 @@ dnl ***************************************
 dnl *** Check for standard header files ***
 dnl ***************************************
 AC_HEADER_STDC()
-AC_CHECK_HEADERS([])
+AC_CHECK_HEADERS([stdlib.h])
 
 dnl ************************************
 dnl *** Check for standard functions ***
index cef22d7..f1424b6 100644 (file)
@@ -14,6 +14,8 @@ luc_handler_built_sources =                                           \
        $(luc_handler_built_headers)
 
 luc_handler_SOURCES =                                                  \
+       luc-handler-service.c                                           \
+       luc-handler-service.h                                           \
        main.c                                                          \
        $(luc_handler_built_sources)
 
@@ -62,8 +64,8 @@ BUILT_SOURCES =                                                               \
 
 luc-handler-dbus.h: luc-handler-dbus.xml Makefile
        $(AM_V_GEN) $(GDBUS_CODEGEN)                                    \
-           --interface-prefix org.genivi.LUCHandler1                   \
+           --interface-prefix org.genivi                               \
            --c-namespace ""                                            \
            --generate-c-code luc-handler-dbus                          \
            --annotate org.genivi.LUCHandler1 org.gtk.GDBus.C.Name      \
-             "LUCHandler" $<
+             LUC_Handler $<
index 792d406..db05691 100644 (file)
@@ -1,21 +1,18 @@
 <?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)
+  -->
   <interface name="org.genivi.LUCHandler1">
     <method name="Register">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
       <param name="apps" type="a{sas}" direction="in"/>
     </method>
-    
     <method name="Deregister">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
       <param name="apps" type="a{sas}" direction="in"/>
     </method>
-    
-    <method name="GetLUCContent">
-      <param name="apps" type="a{sas}" direction="out"/>
-    </method>
-    
-    <signal name="LUCChanged">
-      <param name="apps" type="a{sas}"/>
-    </signal>
-    
+    <property name="Content" type="a{sas}" access="read"/>
   </interface>
 </node>
diff --git a/luc-handler/luc-handler-service.c b/luc-handler/luc-handler-service.c
new file mode 100644 (file)
index 0000000..0a82027
--- /dev/null
@@ -0,0 +1,229 @@
+/* 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 <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,
+                                                       LUCHandlerService     *service);
+static gboolean luc_handler_service_handle_deregister (LUCHandler            *interface,
+                                                       GDBusMethodInvocation *invocation,
+                                                       LUCHandlerService     *service);
+
+
+
+struct _LUCHandlerServiceClass
+{
+  GObjectClass __parent__;
+};
+
+struct _LUCHandlerService
+{
+  GObject          __parent__;
+
+  GDBusConnection *connection;
+  LUCHandler      *interface;
+};
+
+
+
+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));
+}
+
+
+
+static void
+luc_handler_service_init (LUCHandlerService *service)
+{
+  service->interface = luc_handler_skeleton_new ();
+
+  /* TODO read LUC content from disk and set the "content" property of the 
+   * skeleton instance */
+
+  g_signal_connect (service->interface, "handle-register",
+                    G_CALLBACK (luc_handler_service_handle_register),
+                    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);
+
+  (*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,
+                                     LUCHandlerService     *service)
+{
+  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);
+
+  g_debug ("Deregister called");
+
+  /* TODO read the apps parameter and update the "content" property of
+   * the skeleton */
+
+  g_dbus_method_invocation_return_value (invocation, NULL);
+
+  return TRUE;
+}
+
+
+
+static gboolean
+luc_handler_service_handle_deregister (LUCHandler            *object,
+                                       GDBusMethodInvocation *invocation,
+                                       LUCHandlerService     *service)
+{
+  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);
+
+  g_debug ("Register called");
+
+  /* TODO read the apps parameter and update the "content" property of
+   * the skeleton */
+
+  g_dbus_method_invocation_return_value (invocation, NULL);
+
+  return TRUE;
+}
+
+
+
+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
new file mode 100644 (file)
index 0000000..3b56833
--- /dev/null
@@ -0,0 +1,36 @@
+/* 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__ */
+
index ab7e7c1..9c65b33 100644 (file)
@@ -7,7 +7,18 @@
  * 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-service.h>
 
 
 
@@ -15,6 +26,48 @@ int
 main (int    argc,
       char **argv)
 {
-  g_debug ("Hello");
-  return 0;
+  LUCHandlerService     *service;
+  GDBusConnection       *connection;
+  GMainLoop             *main_loop;
+  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 application's main loop */
+  main_loop = g_main_loop_new (NULL, FALSE);
+  g_main_loop_run (main_loop);
+
+  /* release allocated objects */
+  g_object_unref (service);
+  g_object_unref (connection);
+
+  return EXIT_SUCCESS;
 }