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)
#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,
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 */
};
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
#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"
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);
input_handler->exit(NULL);
input_handler = NULL;
+
+ input_devman_exit();
}
static const struct device_ops input_device_ops = {