input: Define plugin interface for input 63/294063/5
authorYoungjae Cho <y0.cho@samsung.com>
Mon, 12 Jun 2023 09:08:09 +0000 (18:08 +0900)
committeryoungjae cho <y0.cho@samsung.com>
Tue, 13 Jun 2023 08:13:22 +0000 (08:13 +0000)
Input plugin must implement interface provided by input-plugin-interface.h
with symbol name INPUT_PLUGIN_INTERFACE_SYMBOL. The input core dlopen()
and dlsym() with that symbol, initializing or exiting input plugin within
the deviced core execution.

Change-Id: Id279db971cb0351b609a022de02a51672242c0b6
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
plugins/iot-headless/input/input-handler.c
plugins/iot-headless/input/input-handler.h
src/input/input-plugin-interface.h [new file with mode: 0644]
src/input/input-plugin.c [new file with mode: 0644]
src/input/input-plugin.h [new file with mode: 0644]
src/input/input.c

index c332d32..f5d5a21 100644 (file)
 #include <linux/input.h>
 #include <glib.h>
 #include <libsyscommon/libgdbus.h>
+#include <libsyscommon/list.h>
 
 #include "shared/common.h"
-#include "shared/devices.h"
 #include "shared/device-notifier.h"
 #include "shared/log.h"
 #include "shared/event.h"
 
 #include "input-config.h"
 #include "input/input.h"
+#include "input/input-plugin-interface.h"
 
 static int input_event_handler_id;
 
@@ -151,10 +152,12 @@ static void input_handler_process_key(struct timeval time, unsigned short type,
                device_notify(DEVICE_NOTIFIER_KEY_RELEASE, (void *)(intptr_t) keycode);
 }
 
-static void input_handler_init(void *data)
+static int input_handler_init(void *data)
 {
        init_input_config();
        input_register_event_callback(input_handler_process_key, NULL, NULL, &input_event_handler_id);
+
+       return 0;
 }
 
 static void input_handler_exit(void *data)
@@ -162,10 +165,7 @@ static void input_handler_exit(void *data)
        input_unregister_event_callback(input_event_handler_id);
 }
 
-static const struct device_ops input_handler_device_ops = {
-       DECLARE_NAME_LEN("input-handler"),
+const struct input_plugin_interface INPUT_PLUGIN_INTERFACE_SYMBOL = {
        .init              = input_handler_init,
        .exit              = input_handler_exit,
 };
-
-DEVICE_OPS_REGISTER(&input_handler_device_ops)
index e66730d..e69de29 100644 (file)
@@ -1,6 +0,0 @@
-#ifndef __INPUT_HANDLER_H__
-#define __INPUT_HANDLER_H__
-
-void input_handler_process_key(int keycode, int keyvalue);
-
-#endif //__INPUT_HANDLER_H__
\ No newline at end of file
diff --git a/src/input/input-plugin-interface.h b/src/input/input-plugin-interface.h
new file mode 100644 (file)
index 0000000..26736a4
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __INPUT_PLUGIN_INTERFACE_H__
+#define __INPUT_PLUGIN_INTERFACE_H__
+
+struct input_plugin_interface {
+       int (*init) (void *);
+       void (*exit) (void *);
+};
+
+#define INPUT_PLUGIN_INTERFACE_SYMBOL   input_plugin_interface_sym
+
+#endif// __INPUT_PLUGIN_INTERFACE_H__
diff --git a/src/input/input-plugin.c b/src/input/input-plugin.c
new file mode 100644 (file)
index 0000000..ff894ca
--- /dev/null
@@ -0,0 +1,83 @@
+#include <unistd.h>
+#include <dlfcn.h>
+#include <shared/log.h>
+
+#include "input-plugin-interface.h"
+
+#define INPUT_PLUGIN_PATH      LIBPATH"/deviced/input-handler.so"
+
+#define __stringify(s)  #s
+#define stringify(s)   __stringify(s)
+
+static void *g_input_plugin_handle;
+static struct input_plugin_interface *g_input_plugin;
+
+static int load_input_plugin(void)
+{
+       void *g_input_plugin_handle;
+
+       if (g_input_plugin)
+               return 0;
+
+       if (access(INPUT_PLUGIN_PATH, F_OK) != 0)
+               return -ENOENT;
+
+       g_input_plugin_handle = dlopen(INPUT_PLUGIN_PATH, RTLD_NOW | RTLD_GLOBAL);
+       if (!g_input_plugin_handle) {
+               _E("Failed to load input plugin shared object, %s", dlerror());
+               return -1;
+       }
+
+       g_input_plugin = dlsym(g_input_plugin_handle, stringify(INPUT_PLUGIN_INTERFACE_SYMBOL));
+       if (!g_input_plugin) {
+               _E("Failed to load input plugin symbol, %s", dlerror());
+               return -1;
+       }
+
+       return 0;
+}
+
+static void unload_input_plugin(void)
+{
+       int ret;
+
+       if (!g_input_plugin_handle)
+               return;
+
+       g_input_plugin = NULL;
+
+       ret = dlclose(g_input_plugin_handle);
+       if (ret != 0) {
+               _E("Failed to unload input plugin shared object, %s", dlerror());
+               return;
+       }
+
+       g_input_plugin_handle = NULL;
+}
+
+int input_plugin_init(void *data)
+{
+       int ret;
+
+       if (!g_input_plugin) {
+               ret = load_input_plugin();
+               if (ret != 0)
+                       return ret;
+       }
+
+       if (!g_input_plugin->init)
+               return -EOPNOTSUPP;
+
+       return g_input_plugin->init(data);
+}
+
+void input_plugin_exit(void *data)
+{
+       if (!g_input_plugin)
+               return;
+
+       if (g_input_plugin->exit)
+               g_input_plugin->exit(data);
+
+       unload_input_plugin();
+}
diff --git a/src/input/input-plugin.h b/src/input/input-plugin.h
new file mode 100644 (file)
index 0000000..cb17a3d
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __INPUT_PLUGIN_H__
+#define __INPUT_PLUGIN_H__
+
+int input_plugin_init(void *data);
+void input_plugin_exit(void *data);
+
+#endif //__INPUT_PLUGIN_H__
index f596414..3b3f067 100644 (file)
@@ -35,6 +35,7 @@
 #include "shared/log.h"
 #include "input.h"
 #include "input-dbus.h"
+#include "input-plugin.h"
 #include "input-parser.h"
 #include "input-device-manager.h"
 
@@ -42,7 +43,6 @@
 
 static struct udev *udev;
 static struct libinput *li;
-static struct input_ops *input_plugin_ops;
 static guint efd;
 
 struct input_event_handler {
@@ -249,8 +249,9 @@ static void input_init(void *data)
        int ret;
        int fd;
 
-       if (input_plugin_ops == NULL)
-               _E("Failed to init input_ops");
+       ret = input_plugin_init(data);
+       if (ret < 0)
+               _E("Failed to initialize input plugin(%d)", ret);
 
        ret = input_devman_init();
        if (ret < 0) {
@@ -318,6 +319,7 @@ static void input_exit(void *data)
                udev_unref(udev);
 
        input_devman_exit();
+       input_plugin_exit(data);
 }
 
 static const struct device_ops input_device_ops = {