input: add the dbus interface and input config parser 84/286884/1 accepted/tizen/7.0/unified/20230117.141746
authorYunhee Seo <yuni.seo@samsung.com>
Mon, 9 Jan 2023 14:18:46 +0000 (23:18 +0900)
committeryunhee seo <yuni.seo@samsung.com>
Mon, 16 Jan 2023 07:58:19 +0000 (07:58 +0000)
Add input device information dbus methods
Input event on/off option can be handled by device id number.
With config file, user can set the customed input devices
and input-parser will mananging input devices from it.

[InputDeivce] format which is in input.conf
InputDeviceType -> hal_deivce_input_type
InputDeviceId -> id number which exist under the /sys/class/input/inputXX path
InputDeviceName -> device name
InputDeviceDefault -> yes/no

Input dbus methods
1. Get input devices
    path: /Org/Tizen/System/DeviceD/Input
    interface: org.tizen.system.deviced.input
    member: InputGetDevices
    parameter: "(i)", input device type to get device id list
    return: "(ai)", get int device id list on success, empty list on error.

2. Get default device
    path: /Org/Tizen/System/DeviceD/Input
    interface: org.tizen.system.deviced.input
    member: InputGetDefaultDevice
    parameter: "(i)", input device type to get default devicd id
    return: "(i)", get device id value on success, negative on error.

3. Get device name
    path: /Org/Tizen/System/DeviceD/Input
    interface: org.tizen.system.deviced.input
    member: InputGetDeviceName
    parameter: "(i)", input device id to get device name
    return: "(is)", (ret_val, ret_dev_name)
        negative ret_val means error, otherwise success.

Change-Id: I0977c29f538f432cb5ab82e610130698ce7ad5b9
Signed-off-by: Yunhee Seo <yuni.seo@samsung.com>
(cherry picked from commit c67debace2c0a2f2bfb53b9d71cb18d3a6f947fc)

src/input/input-dbus.c
src/input/input-device-manager.c [new file with mode: 0644]
src/input/input-device-manager.h [new file with mode: 0644]
src/input/input-parser.c [new file with mode: 0644]
src/input/input-parser.h [new file with mode: 0644]
src/input/input.c

index ba00174..df7ccd7 100644 (file)
@@ -34,6 +34,7 @@
 #include "input.h"
 #include "input-dbus.h"
 #include "input-interface.h"
+#include "input-device-manager.h"
 
 /* FIXME: input.keyboard feature check should be added and return DEVICE_ERROR_NOT_SUPPORTED */
 static GVariant *dbus_inputseteventstate(GDBusConnection *conn,
@@ -94,10 +95,76 @@ static GVariant *dbus_emulate_key(GDBusConnection *conn,
        return gdbus_new_g_variant_tuple();
 }
 
+static GVariant *dbus_inputgetdevices(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int input_type;
+       pid_t pid;
+       GVariant* input_device_list;
+
+       g_variant_get(param, "(i)", &input_type);
+       input_device_list = input_devman_find_device_list(input_type);
+
+       pid = gdbus_connection_get_sender_pid(conn, sender);
+       _D("Input get devices pid=%d input device type=%d", pid, input_type);
+
+       return input_device_list;
+}
+
+static GVariant *dbus_inputgetdefaultdevice(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int input_type, input_default_device_id = 0, ret = 0;
+       pid_t pid;
+
+       g_variant_get(param, "(i)", &input_type);
+
+       ret = input_devman_find_default_device(input_type, &input_default_device_id);
+       if (ret < 0)
+               _E("Failed to get input default device id");
+       else
+               ret = input_default_device_id;
+
+       pid = gdbus_connection_get_sender_pid(conn, sender);
+       _D("Input get default device pid=%d input device type=%d", pid, input_type);
+
+       return g_variant_new("(i)", ret);
+}
+
+static GVariant *dbus_inputgetdevicename(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       GVariant *dbus_ret;
+       int input_id, ret = 0;
+       char *input_device_name;
+       pid_t pid;
+
+       g_variant_get(param, "(i)", &input_id);
+
+       ret = input_devman_find_device_name(input_id, &input_device_name);
+       if (ret < 0)
+               _E("Failed to get input device name");
+
+       pid = gdbus_connection_get_sender_pid(conn, sender);
+       _D("Input get device name pid=%d input device id=%d input device name=%s",
+               pid, input_id, input_device_name);
+
+       dbus_ret = g_variant_new("(is)", ret, input_device_name);
+       free(input_device_name);
+
+       return dbus_ret;
+}
+
 static const dbus_method_s dbus_methods[] = {
        {"InputSetEventState", "ii", "i", dbus_inputseteventstate},
        {"InputGetEventState", "i", "i", dbus_inputgeteventstate},
        {"EmulateKey", "ii", NULL, dbus_emulate_key},
+       {"InputGetDevices", "i", "ai", dbus_inputgetdevices},
+       {"InputGetDefaultDevice","i", "i", dbus_inputgetdefaultdevice},
+       {"InputGetDeviceName","i", "is", dbus_inputgetdevicename},
        /* Add methods here */
 };
 
diff --git a/src/input/input-device-manager.c b/src/input/input-device-manager.c
new file mode 100644 (file)
index 0000000..3bd966a
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+#include <glib.h>
+
+#include <libsyscommon/list.h>
+
+#include "shared/log.h"
+#include "input-device-manager.h"
+
+static struct input_device_element {
+       int id;
+       int device_default;
+       char *name;
+};
+
+static GHashTable *g_input_device_list;
+
+static void destroy_input_device_hashtable_value(gpointer data)
+{
+       g_list_free((GList*)data);
+}
+
+int input_devman_init(void)
+{
+       g_input_device_list = g_hash_table_new_full(g_int_hash, g_int_equal,
+               g_free, destroy_input_device_hashtable_value);
+       if (g_input_device_list)
+               return 0;
+       return -EPERM;
+}
+
+void input_devman_exit(void)
+{
+       if (g_input_device_list)
+               g_hash_table_destroy(g_steal_pointer(&g_input_device_list));
+}
+
+static struct input_device_element* find_input_device_info_element_by_device_id(int input_device_id)
+{
+       GList *all_input_device_list = g_hash_table_get_values(g_input_device_list);
+       GList *temp_glist1, *temp_glist2, *temp_input_device_list;
+       struct input_device_element *input_device_elem;
+
+       SYS_G_LIST_FOREACH(all_input_device_list, temp_glist1, temp_input_device_list) {
+               SYS_G_LIST_FOREACH(temp_input_device_list, temp_glist2, input_device_elem) {
+                       if (input_device_id == input_device_elem->id)
+                               return input_device_elem;
+               }
+       }
+       return NULL;
+}
+
+static GList* find_input_device_list_by_device_type(int input_device_type)
+{
+       gint *hash_key = g_new(gint, 1);
+       *hash_key = input_device_type;
+       GList *find_list = g_hash_table_lookup(g_input_device_list, hash_key);
+       g_free(hash_key);
+       return find_list;
+}
+
+int input_devman_find_default_device(int input_device_type, int *input_device_id)
+{
+       GList *find_input_device_list = find_input_device_list_by_device_type(input_device_type);
+       GList *temp_glist1;
+       struct input_device_element *input_device_elem;
+
+       if (find_input_device_list == NULL)
+               return -ENXIO;
+
+       SYS_G_LIST_FOREACH(find_input_device_list, temp_glist1, input_device_elem) {
+               if (input_device_elem->device_default == 1) {
+                       *input_device_id = input_device_elem->id;
+                       return 0;
+               }
+       }
+       return -ENXIO;
+}
+
+GVariant *input_devman_find_device_list(int input_device_type)
+{
+       GList *find_input_device_list = find_input_device_list_by_device_type(input_device_type);
+       GList *temp_glist1;
+       GVariantBuilder *input_device_list_builder = g_variant_builder_new(G_VARIANT_TYPE("ai"));
+       GVariant *id_list;
+       struct input_device_element *input_device_elem;
+       int num_input_ids = g_list_length(find_input_device_list);
+
+       if (num_input_ids <= 0) {
+               id_list = g_variant_new("(ai)", input_device_list_builder);
+               goto out;
+       }
+
+       SYS_G_LIST_FOREACH(find_input_device_list, temp_glist1, input_device_elem) {
+               g_variant_builder_add(input_device_list_builder, "i", input_device_elem->id);
+       }
+       id_list = g_variant_new("(ai)", input_device_list_builder);
+out:
+       g_variant_builder_unref(input_device_list_builder);
+       return id_list;
+}
+
+int input_devman_find_device_name(int input_device_id, char** input_device_name)
+{
+       struct input_device_element *input_device_elem = find_input_device_info_element_by_device_id(input_device_id);
+
+       if (input_device_elem == NULL)
+               return -ENXIO;
+
+       *input_device_name = strndup(input_device_elem->name, 32);
+       return 0;
+}
+
+int input_devman_add_device(int input_device_type, int input_device_id,
+       int input_device_default, char *input_device_name)
+{
+       struct input_device_element *input_device_elem = NULL;
+       GList* hash_value_list = NULL;
+       gint *hash_key = g_new(gint, 1);
+
+       input_device_elem = malloc(sizeof(struct input_device_element));
+       if (!input_device_elem) {
+               _E("Failed to malloc input device element");
+               return -ENOMEM;
+       }
+       input_device_elem->id = input_device_id;
+       input_device_elem->device_default = input_device_default;
+       input_device_elem->name = strndup(input_device_name, 32);
+       *hash_key = input_device_type;
+       hash_value_list = g_hash_table_lookup(g_input_device_list, hash_key);
+
+       if (hash_value_list != NULL) {
+               hash_value_list = g_list_append(hash_value_list, input_device_elem);
+               g_free(hash_key);
+       } else {
+               hash_value_list = g_list_append(hash_value_list, input_device_elem);
+               g_hash_table_insert(g_input_device_list, hash_key, hash_value_list);
+       }
+       return 0;
+}
\ No newline at end of file
diff --git a/src/input/input-device-manager.h b/src/input/input-device-manager.h
new file mode 100644 (file)
index 0000000..782345f
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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_DEVICE_MANAGER_H__
+#define __INPUT_DEVICE_MANAGER_H__
+
+int input_devman_init(void);
+void input_devman_exit(void);
+int input_devman_find_default_device(int input_device_type, int *input_device_id);
+GVariant *input_devman_find_device_list(int input_device_type);
+int input_devman_find_device_name(int input_device_id, char** input_device_name);
+int input_devman_add_device(int input_device_type, int input_device_id,
+       int input_device_default, char *input_device_name);
+
+#endif /* __INPUT_DEVICE_MANAGER_H__ */
\ No newline at end of file
diff --git a/src/input/input-parser.c b/src/input/input-parser.c
new file mode 100644 (file)
index 0000000..ea45fdb
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include <libsyscommon/ini-parser.h>
+#include <libsyscommon/list.h>
+#include <hal/device/hal-device-input.h>
+
+#include "shared/log.h"
+#include "input-parser.h"
+#include "input-device-manager.h"
+
+#define INPUT_CONF_PATH    "/hal/etc/deviced/input.conf"
+
+static struct input_device_info {
+       int input_device_type;
+       int input_device_id;
+       char *input_device_name;
+       int input_device_default;
+};
+
+static GHashTable *g_hash_table_to_check_default_duplicated;
+
+static bool is_default_input_device_duplicated(int input_device_type)
+{
+       gint *hash_key = g_new(gint, 1);
+       *hash_key = input_device_type;
+       if (g_hash_table_contains(g_hash_table_to_check_default_duplicated, hash_key)) {
+               g_free(hash_key);
+               return true;
+       } else {
+               g_hash_table_insert(g_hash_table_to_check_default_duplicated, hash_key, NULL);
+       }
+       return false;
+}
+
+static void parse_input_device_property(gpointer data, gpointer user_data)
+{
+       struct section_property *prop = (struct section_property *) data;
+       struct input_device_info *input_dev_info = *(struct input_device_info **)user_data;
+
+       if (!prop || !input_dev_info)
+               return;
+
+       if (MATCH(prop->key, "InputDeviceType")) {
+               if (MATCH(prop->value, "unknown"))
+                       input_dev_info->input_device_type = (int)HAL_DEVICE_INPUT_TYPE_UNKNOWN;
+               else if (MATCH(prop->value, "mouse"))
+                       input_dev_info->input_device_type = (int)HAL_DEVICE_INPUT_TYPE_MOUSE;
+               else if (MATCH(prop->value, "keyboard"))
+                       input_dev_info->input_device_type = (int)HAL_DEVICE_INPUT_TYPE_KEYBOARD;
+               else if (MATCH(prop->value, "custom_knob"))
+                       input_dev_info->input_device_type = (int)HAL_DEVICE_INPUT_TYPE_CUSTOM_KNOB;
+       } else if (MATCH(prop->key, "InputDeviceId")) {
+               sscanf(prop->value, "%d", (&input_dev_info->input_device_id));
+       } else if (MATCH(prop->key, "InputDeviceName")) {
+               input_dev_info->input_device_name = calloc(sizeof(prop->value), sizeof(char));
+               strcpy(input_dev_info->input_device_name, prop->value);
+       } else if (MATCH(prop->key, "InputDeviceDefault")) {
+               if (MATCH(prop->value, "yes"))
+                       input_dev_info->input_device_default = 1;
+               else if (MATCH(prop->value, "no"))
+                       input_dev_info->input_device_default = 0;
+       }
+}
+
+static int parse_input_device_section(const struct parse_result *result, void *data)
+{
+       struct input_device_info *input_dev_info;
+       int ret;
+
+       if (!result || !result->props)
+               return 0;
+
+       if (!MATCH(result->section, "InputDevice"))
+               return 0;
+
+       input_dev_info = calloc(1, sizeof(struct input_device_info));
+       if (!input_dev_info)
+               return -ENOMEM;
+
+       g_list_foreach(result->props, parse_input_device_property, &input_dev_info);
+       if (input_dev_info->input_device_default == 1) {
+               if (is_default_input_device_duplicated(input_dev_info->input_device_type))
+                       return -EPERM;
+       }
+       ret = input_devman_add_device(input_dev_info->input_device_type,
+               input_dev_info->input_device_id,
+               input_dev_info->input_device_default,
+               input_dev_info->input_device_name);
+       free(input_dev_info);
+
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int input_parser_init(void)
+{
+       int ret;
+
+       g_hash_table_to_check_default_duplicated = g_hash_table_new_full(g_int_hash, g_int_equal,
+               g_free, g_free);
+
+       ret = libsys_config_parse_by_section(INPUT_CONF_PATH, parse_input_device_section, NULL);
+
+       if (g_hash_table_to_check_default_duplicated) {
+               g_hash_table_destroy(g_steal_pointer(&g_hash_table_to_check_default_duplicated));
+       }
+
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
\ No newline at end of file
diff --git a/src/input/input-parser.h b/src/input/input-parser.h
new file mode 100644 (file)
index 0000000..f041c11
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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_PARSER_H__
+#define __INPUT_PARSER_H__
+
+#include <glib.h>
+
+int input_parser_init(void);
+
+#endif //__INPUT_PARSER_H__
\ No newline at end of file
index 20b4faf..e30357f 100644 (file)
@@ -34,7 +34,9 @@
 #include "shared/log.h"
 #include "input.h"
 #include "input-dbus.h"
+#include "input-parser.h"
 #include "input-interface.h"
+#include "input-device-manager.h"
 
 #define SEAT_NAME   "seat0"
 
@@ -119,6 +121,16 @@ static void input_init(void *data)
        if (input_plugin_ops == NULL)
                _E("Failed to init input_ops");
 
+       ret = input_devman_init();
+       if (ret < 0)
+               _E("Failed to initialize input device manager(%d)", ret);
+
+       ret = input_parser_init();
+       if (ret < 0) {
+               _E("Failed to parsing input config file(%d)", ret);
+               input_devman_exit();
+       }
+
        ret = input_dbus_init();
        if (ret < 0)
                _E("Failed to init input device dbus interface(%d)", ret);
@@ -176,6 +188,8 @@ static void input_exit(void *data)
                input_handler->exit(NULL);
 
        input_handler = NULL;
+
+       input_devman_exit();
 }
 
 static const struct device_ops input_device_ops = {