From 17cf21bcf8a2e29d2cbcf0a313474d2a4ee44f5d Mon Sep 17 00:00:00 2001 From: Tadao Tanikawa Date: Fri, 20 Nov 2020 23:36:23 +0900 Subject: Re-organized sub-directory by category Since all the sub-directories were placed in the first level, created sub-directories, "hal", "module", and "service" for classification and relocated each component. Signed-off-by: Tadao Tanikawa Change-Id: Ifdf743ac0d1893bd8e445455cf0d2c199a011d5c --- hal/input_hal/src/input_drm.cpp | 128 +++++++ hal/input_hal/src/input_hal.cpp | 267 +++++++++++++++ hal/input_hal/src/input_touch_ilitek.cpp | 226 ++++++++++++ hal/input_hal/src/input_udev_monitor.cpp | 566 +++++++++++++++++++++++++++++++ hal/input_hal/src/input_util.cpp | 77 +++++ 5 files changed, 1264 insertions(+) create mode 100755 hal/input_hal/src/input_drm.cpp create mode 100755 hal/input_hal/src/input_hal.cpp create mode 100755 hal/input_hal/src/input_touch_ilitek.cpp create mode 100755 hal/input_hal/src/input_udev_monitor.cpp create mode 100755 hal/input_hal/src/input_util.cpp (limited to 'hal/input_hal/src') diff --git a/hal/input_hal/src/input_drm.cpp b/hal/input_hal/src/input_drm.cpp new file mode 100755 index 0000000..20adf79 --- /dev/null +++ b/hal/input_hal/src/input_drm.cpp @@ -0,0 +1,128 @@ +/* + * @copyright Copyright (c) 2018-2020 TOYOTA MOTOR CORPORATION. + * + * 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 "input_drm.h" + +#include +#include +#include +#include + +#if defined(_USE_DRM) +#include +#include +#endif + +#include "input_hal.h" +#include "input_hal_debug.h" + +#define DIR_PATH "/dev/dri/card0" +#define DEFAULT_RESOLUTION_HORIZONTAL 1280 /* Horizontal resolution default value */ +#define DEFAULT_RESOLUTION_VERTICAL 800 /* Vertical resolution default value */ +/** + * Panel resolution acquisition / GetPanelSpecResolutionInput + */ +int GetPanelSpecResolutionInput(int *reso_h, int *reso_v) { + if ((NULL == reso_h) || (NULL == reso_v)) { + return HAL_INPUT_RET_ERROR; + } + +#if defined(_USE_DRM) + int fd; + drmModeRes *resources = NULL; + drmModeConnector *connector = NULL; + drmModeEncoder *encoder = NULL; + drmModeCrtc *crtc = NULL; + + fd = open(DIR_PATH, O_RDWR); + if (fd < 0) { + INPUT_ERROR_LOG("DRI Open Error=%s\n", DIR_PATH); + goto err_rtn; + } + + resources = drmModeGetResources(fd); + if (!resources) { + INPUT_ERROR_LOG("No resources\n"); + goto err_rtn; + } + if (2 > resources->count_connectors) { + INPUT_ERROR_LOG("DRI Connect Num Error connectors=%d\n", + resources->count_connectors); + goto err_rtn; + } + + connector = drmModeGetConnector(fd, resources->connectors[1]); + if (!connector) { + INPUT_ERROR_LOG("No Connector\n"); + goto err_rtn; + } + + if ((DRM_MODE_CONNECTED == connector->connection) &&(connector->count_modes > 0)) { + } else { + INPUT_ERROR_LOG("Not found connected connector\n"); + goto err_rtn; + } + + encoder = drmModeGetEncoder(fd, connector->encoder_id); + if (!encoder) { + INPUT_ERROR_LOG("drmModeGetEncoder null\n"); + goto err_rtn; + } + + crtc = drmModeGetCrtc(fd, encoder->crtc_id); + if (!crtc) { + INPUT_ERROR_LOG("drmModeGetCrtc null\n"); + goto err_rtn; + } + + *reso_h = crtc->mode.hdisplay; + *reso_v = crtc->mode.vdisplay; + + drmModeFreeCrtc(crtc); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + + INPUT_LOG_TRACE("width=%d height=%d\n", *reso_h, *reso_v); + return HAL_INPUT_RET_NORMAL; + +err_rtn: + + if (encoder) { + drmModeFreeEncoder(encoder); + } + if (connector) { + drmModeFreeConnector(connector); + } + if (resources) { + drmModeFreeResources(resources); + } + if (fd >= 0) { + close(fd); + } + + INPUT_ERROR_LOG("Use Default Resolution\n"); + *reso_h = DEFAULT_RESOLUTION_HORIZONTAL; + *reso_v = DEFAULT_RESOLUTION_VERTICAL; + + return HAL_INPUT_RET_ERROR; +#else + *reso_h = DEFAULT_RESOLUTION_HORIZONTAL; + *reso_v = DEFAULT_RESOLUTION_VERTICAL; + + return HAL_INPUT_RET_NORMAL; +#endif +} diff --git a/hal/input_hal/src/input_hal.cpp b/hal/input_hal/src/input_hal.cpp new file mode 100755 index 0000000..b5f4916 --- /dev/null +++ b/hal/input_hal/src/input_hal.cpp @@ -0,0 +1,267 @@ +/* + * @copyright Copyright (c) 2017-2020 TOYOTA MOTOR CORPORATION. + * + * 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 "input_hal.h" + +#include +#include +#include +#include + +#include "input_hal_debug.h" +#include "input_hal_internal.h" +#include "input_touch_ilitek.h" +#include "input_udev_monitor.h" + +// Touch panel operation function info +static struct TouchHal g_input_touch_info = { 0 }; + +char* g_app_name = NULL; +static bool g_touch_inited = false; +static bool g_input_inited = false; + +extern bool g_break_from_watch; +extern pthread_t g_udev_monitor_thread; + +// Environment key name +#define HAL_INPUT_TARGET_BOARD "TARGET_BOARD" +// Reference board environment value of HAL_INPUT_TARGET_BOARD +#define HAL_INPUT_REF_BOARD_NAME "agl_reference" +// Invalid status of report touch panel's touch event +#define HAL_INPUT_TOUCH_REPORT_INVALID (-1) + +/* + * Input device init. + */ +int InitInput(const char* app_name) { + if (NULL == app_name) { + INPUT_ERROR_LOG("param is error"); + return HAL_INPUT_RET_ERROR; + } + + if (!g_touch_inited) { + INPUT_ERROR_LOG("call InitTouch first."); + return HAL_INPUT_RET_ERROR; + } + + if (g_input_inited) { + INPUT_ERROR_LOG("input inited."); + return HAL_INPUT_RET_ERROR; + } + + g_break_from_watch = false; + if (NULL != g_app_name) { + delete[] g_app_name; + } + + g_app_name = new char[strlen(app_name) + 1]; + snprintf(g_app_name, strlen(app_name) + 1, "%s", app_name); + if (HAL_INPUT_RET_ERROR == InputUdevMonitorThreadCreate()) { + delete[] g_app_name; + g_app_name = NULL; + return HAL_INPUT_RET_ERROR; + } + + g_input_inited = true; + return HAL_INPUT_RET_NORMAL; +} + +/* + * Deinit input device + */ +int DeInitInput() { + g_break_from_watch = true; + void* ret_val = NULL; + if (NULL != g_app_name) { + delete[] g_app_name; + g_app_name = NULL; + } + if (g_udev_monitor_thread != static_cast(-1)) { + pthread_join(g_udev_monitor_thread, &ret_val); + } + g_input_inited = false; + return HAL_INPUT_RET_NORMAL; +} + +/* + * Init those operating function of touch panel driver + */ +int InitTouch() { + int ret = InputTouchIlitekInit(&g_input_touch_info); + g_touch_inited = true; + return ret; +} + +/* + * Make touch panel start work + */ +int StartTouch() { + int ret = HAL_INPUT_RET_ERROR; + + if (NULL != g_input_touch_info.start) { + ret = g_input_touch_info.start(); + } + + return ret; +} + +/* + * Config touch panel + */ +int ConfigTouch(const char *path , int reso_h, int reso_v) { + int ret = HAL_INPUT_RET_ERROR; + + if (NULL != g_input_touch_info.config) { + ret = g_input_touch_info.config(path, reso_h, reso_v); + } + + return ret; +} + +/* + * Get touch panel device name + */ +int GetPanelNameTouch(char* name, size_t buf_length) { + int ret = HAL_INPUT_RET_ERROR; + + if (NULL != g_input_touch_info.get_touch_devicename) { + ret = g_input_touch_info.get_touch_devicename(name, buf_length); + } + + return ret; +} + +/* + * Get touch panel key device name + */ +int GetKeyNameTouch(char* name, size_t buf_length) { + int ret = HAL_INPUT_RET_ERROR; + + if (NULL != g_input_touch_info.get_key_devicename) { + ret = g_input_touch_info.get_key_devicename(name, buf_length); + } + + return ret; +} + +/* + * Execute touch panel self test + */ +int SelfTestTouch(int id, void *result) { + int ret = HAL_INPUT_RET_ERROR; + + if (NULL != g_input_touch_info.selftest) { + ret = g_input_touch_info.selftest(id, result); + } + + return ret; +} + +/* + * Get touch panel config status + */ +int GetConfigStatusTouch(int *status) { + int ret = HAL_INPUT_RET_ERROR; + + if (NULL != g_input_touch_info.get_config_status) { + ret = g_input_touch_info.get_config_status(status); + } + + return ret; +} + +/* + * Set whether the driver sends touch panel data or not + */ +int LockTouch(int status) { + static int input_touch_lock_status = HAL_INPUT_TOUCH_REPORT_INVALID; + + if (input_touch_lock_status == status) { + return HAL_INPUT_RET_NORMAL; + } + + int ret = HAL_INPUT_RET_ERROR; + if (NULL != g_input_touch_info.set_touch_lock) { + ret = g_input_touch_info.set_touch_lock(status); + if (HAL_INPUT_RET_NORMAL == ret) { + input_touch_lock_status = status; + } + } + + return ret; +} + +/* + * Suspend touch panel + */ +int SuspendTouch() { + int ret = HAL_INPUT_RET_ERROR; + + if (NULL != g_input_touch_info.set_touch_suspend) { + ret = g_input_touch_info.set_touch_suspend(); + } + + return ret; +} + +/* + * Set touch panel sensitivity level + */ +int SetSensitivityLevelTouch(int level) { + int cur = HAL_INPUT_TOUCH_SENSITIVITY_LEVEL_NONE; + + int ret = GetSensitivityLevelTouch(&cur); + if (HAL_INPUT_RET_NORMAL == ret) { + if (cur == level) { + // Don't need to update sensitivity level + INPUT_LOG_TRACE("already set level=%d", level); + } else { + if (NULL != g_input_touch_info.set_sensitivity_level) { + ret = g_input_touch_info.set_sensitivity_level(level); + } else { + ret = HAL_INPUT_RET_ERROR; + } + } + } + + return ret; +} + +/* + * Get touch panel sensitivity level + */ +int GetSensitivityLevelTouch(int *level) { + int ret = HAL_INPUT_RET_ERROR; + + if (NULL != g_input_touch_info.get_sensitivity_level) { + ret = g_input_touch_info.get_sensitivity_level(level); + } + + return ret; +} + +/* + * Notify radio scan frequency + */ +int NotifyRadioScanFreqTouch(struct RadioInfoTouch *info) { + int ret = HAL_INPUT_RET_ERROR; + + if (NULL != g_input_touch_info.notify_radio_scan_frequency) { + ret = g_input_touch_info.notify_radio_scan_frequency(info); + } + + return ret; +} diff --git a/hal/input_hal/src/input_touch_ilitek.cpp b/hal/input_hal/src/input_touch_ilitek.cpp new file mode 100755 index 0000000..9d1822a --- /dev/null +++ b/hal/input_hal/src/input_touch_ilitek.cpp @@ -0,0 +1,226 @@ +/* + * @copyright Copyright (c) 2017-2020 TOYOTA MOTOR CORPORATION. + * + * 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 "input_touch_ilitek.h" + +#include +#include +#include + +#include "input_hal.h" + +// Touch panel device name +#define HAL_INPUT_ILITEK_TOUCH_DEVICE_NAME "ILITEK ILITEK Multi-Touch" +// Touch panel key device name +#define HAL_INPUT_ILITEK_KEY_DEVICE_NAME "" + +// Touch panel horizontal resolution value +#define HAL_INPUT_TOUCH_RESOLUTION_HORIZONTAL 4816 + +// Touch panel vertical resolution value +#define HAL_INPUT_TOUCH_RESOLUTION_VERTICAL 2992 + +/* + * Make touch panel start work + */ +static int InputTouchStart() { + return HAL_INPUT_RET_NORMAL; +} + +/* + * Config touch panel + */ +static int InputTouchConfig(const char *path, + int resolution_h, int resolution_v) { + if (NULL == path) { + return HAL_INPUT_RET_ERROR; + } + + if (-1 == ::access(path, F_OK)) { + return HAL_INPUT_RET_ERROR; + } + return HAL_INPUT_RET_NORMAL; +} + +/* + * Get touch panel device name + */ +static int InputTouchGetDeviceName(char* name, size_t buf_length) { + if (NULL == name) { + return HAL_INPUT_RET_ERROR; + } + + if (buf_length < (strlen(HAL_INPUT_ILITEK_TOUCH_DEVICE_NAME) + 1)) { + return HAL_INPUT_RET_ERROR; + } + + snprintf(name, buf_length, "%s", HAL_INPUT_ILITEK_TOUCH_DEVICE_NAME); + return HAL_INPUT_RET_NORMAL; +} + +/* + * Get touch panel key device name + */ +static int InputTouchGetKeyName(char* name, size_t buf_length) { + if (NULL == name) { + return HAL_INPUT_RET_ERROR; + } + + if (buf_length < (strlen(HAL_INPUT_ILITEK_KEY_DEVICE_NAME) + 1)) { + return HAL_INPUT_RET_ERROR; + } + + snprintf(name, buf_length, "%s", HAL_INPUT_ILITEK_KEY_DEVICE_NAME); + return HAL_INPUT_RET_NORMAL; +} + +/* + * Get touch panel device horizontal resolution + */ +static int InputTouchGetDeviceHResolution(int *resolution) { + if (NULL == resolution) { + return HAL_INPUT_RET_ERROR; + } + *resolution = HAL_INPUT_TOUCH_RESOLUTION_HORIZONTAL; + return HAL_INPUT_RET_NORMAL; +} + +/* + * Get touch panel device vertical resolution + */ +static int InputTouchGetDeviceVResolution(int *resolution) { + if (NULL == resolution) { + return HAL_INPUT_RET_ERROR; + } + *resolution = HAL_INPUT_TOUCH_RESOLUTION_VERTICAL; + return HAL_INPUT_RET_NORMAL; +} + +/* + * Get whether X axis is inversion + */ +static int InputTouchGetXAxisReverse(bool* is_reverse) { + if (NULL == is_reverse) { + return HAL_INPUT_RET_ERROR; + } + *is_reverse = false; + return HAL_INPUT_RET_NORMAL; +} + +/* + * Get whether Y axis is inversion + */ +static int InputTouchGetYAxisReverse(bool* is_reverse) { + if (NULL == is_reverse) { + return HAL_INPUT_RET_ERROR; + } + *is_reverse = false; + return HAL_INPUT_RET_NORMAL; +} + +/* + * Execute touch panel self test + */ +static int InputTouchSelftest(int id, void *result) { + if (NULL == result) { + return HAL_INPUT_RET_ERROR; + } + return HAL_INPUT_RET_NOT_SUPPORT; +} + +/* + * Get touch panel config status + */ +static int InputTouchGetConfigStatus(int *status) { + if (NULL == status) { + return HAL_INPUT_RET_ERROR; + } + *status = HAL_INPUT_TOUCH_CONFIG_OFF; + return HAL_INPUT_RET_NORMAL; +} + +/* + * Set whether the driver sends touch panel data or not + */ +static int InputTouchSetTouchLock(int lock) { + if ((HAL_INPUT_TOUCH_UNREPORT == lock) || + (HAL_INPUT_TOUCH_REPORT == lock)) { + return HAL_INPUT_RET_NOT_SUPPORT; + } + return HAL_INPUT_RET_ERROR; +} + +/* + * Suspend touch panel + */ +static int InputTouchSetTouchSuspend() { + return HAL_INPUT_RET_NOT_SUPPORT; +} + +/* + * Set touch panel sensitivity level + */ +static int InputTouchSetSensitivityLevel(int level) { + if ((HAL_INPUT_TOUCH_SENSITIVITY_LEVEL_LOW == level) || + (HAL_INPUT_TOUCH_SENSITIVITY_LEVEL_MIDDLE == level) || + (HAL_INPUT_TOUCH_SENSITIVITY_LEVEL_HIGH == level) || + (HAL_INPUT_TOUCH_SENSITIVITY_LEVEL_NONE == level) ) { + return HAL_INPUT_RET_NOT_SUPPORT; + } + return HAL_INPUT_RET_ERROR; +} + +/* + * Get touch panel sensitivity level + */ +static int InputTouchGetSensitivityLevel(int *level) { + if (NULL == level) { + return HAL_INPUT_RET_ERROR; + } + + return HAL_INPUT_RET_NOT_SUPPORT; +} + +/* + * Notify radio scan frequency + */ +static int InputTouchNotifyRadioScanFrequency(struct RadioInfoTouch *info) { + if (NULL == info) { + return HAL_INPUT_RET_ERROR; + } + return HAL_INPUT_RET_NOT_SUPPORT; +} + +/* + * Init touch panel operation function + */ +int InputTouchIlitekInit(struct TouchHal *touch) { + touch->start = InputTouchStart; + touch->config = InputTouchConfig; + touch->get_touch_devicename = InputTouchGetDeviceName; + touch->get_key_devicename = InputTouchGetKeyName; + touch->get_reso_h = InputTouchGetDeviceHResolution; + touch->get_reso_v = InputTouchGetDeviceVResolution; + touch->get_reverse_axis_x = InputTouchGetXAxisReverse; + touch->get_reverse_axis_y = InputTouchGetYAxisReverse; + touch->selftest = InputTouchSelftest; + touch->get_config_status = InputTouchGetConfigStatus; + touch->set_touch_lock = InputTouchSetTouchLock; + touch->set_touch_suspend = InputTouchSetTouchSuspend; + touch->set_sensitivity_level = InputTouchSetSensitivityLevel; + touch->get_sensitivity_level = InputTouchGetSensitivityLevel; + touch->notify_radio_scan_frequency = InputTouchNotifyRadioScanFrequency; + return HAL_INPUT_RET_NORMAL; +} diff --git a/hal/input_hal/src/input_udev_monitor.cpp b/hal/input_hal/src/input_udev_monitor.cpp new file mode 100755 index 0000000..5d8cc6b --- /dev/null +++ b/hal/input_hal/src/input_udev_monitor.cpp @@ -0,0 +1,566 @@ +/* + * @copyright Copyright (c) 2017-2020 TOYOTA MOTOR CORPORATION. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "input_hal.h" +#include "input_hal_debug.h" +#include "input_hal_internal.h" +#include "input_drm.h" +#include "input_udev_monitor.h" + +#define HAL_INPUT_UDEVMONITOR_THREADNAME "input_hal_udevm" +#define max_value(x, y) ((x) > (y) ? (x) : (y)) + +#define INPUT_VIRTUAL_INPUTDEVICE_NAME "/devices/virtual" /* Virtual device name created by SwitchManager */ + +// Enough name length to contain node name +#define INPUT_NODE_NAME_LENGTH 256 + +#define TRACKING_ID_NONE -1 + +static struct InputUdevMonitorInfo g_input_udevmonitor_info; +static HANDLE g_sender_handle; +static bool g_input_touch_init_notify = false; +extern char* g_app_name; /* app name */ +bool g_break_from_watch = false; /* watch thread loop break flag */ +pthread_t g_udev_monitor_thread = -1; /* udev monitor thread */ + +static void InputUdevMonitorTouchInitFinEventSend(int result) { + struct TouchInitFinishInput msg; + + if (g_input_touch_init_notify) { + return; + } + + if (NULL == g_sender_handle) { + g_sender_handle = McOpenSender(g_app_name); + } + msg.result = result; + + InputUtilMCSend( + g_sender_handle, HAL_INPUT_SOURCE_NAME, + HAL_INPUT_NOTIFY_TOUCH_INIT_FINISH, sizeof(msg), &msg); + g_input_touch_init_notify = true; +} + +static void InputUdevMonitorInputEventHandle(int fd, int device_type, int notify_id) { + ssize_t read_size; + struct EventsPackageInput events = {0}; + + read_size = read(fd, events.event, sizeof(events.event)); + if (read_size > 0) { + events.count = read_size / sizeof(struct input_event); + events.device_type = device_type; + + if (NULL == g_sender_handle) { + g_sender_handle = McOpenSender(g_app_name); + } + + InputUtilMCSend( + g_sender_handle, HAL_INPUT_SOURCE_NAME, + notify_id, sizeof(events), &events); + } +} + +static void InputUdevMonitorTouchEventHandle(int fd, int notify_id) { + ssize_t read_size; + struct input_event event[HAL_INPUT_EVENT_COUNT] = {0}; + int touch_status; + + read_size = read(fd, event, sizeof(event)); + + if (read_size > 0) { + if (NULL == g_sender_handle) { + g_sender_handle = McOpenSender(g_app_name); + } + + int event_num = read_size / sizeof(struct input_event); + + for (int index = 0; index < event_num; ++index) { + if (EV_ABS == event[index].type) { + if (event[index].code == ABS_MT_TRACKING_ID) { + if (TRACKING_ID_NONE == event[index].value) { + touch_status = HAL_INPUT_TOUCH_RELEASE; + } else { + touch_status = HAL_INPUT_TOUCH_PRESS; + } + InputUtilMCSend( + g_sender_handle, HAL_INPUT_SOURCE_NAME, + notify_id, sizeof(touch_status), &touch_status); + } + } + } + } +} + +static int InputUdevMonitorDeviceAssort(struct udev_device *dev) { + const char *property; + + char touch_key_device_name[INPUT_NODE_NAME_LENGTH] = { 0 }; + GetKeyNameTouch(touch_key_device_name, sizeof(touch_key_device_name)); + const char *sysattr_name = udev_device_get_sysattr_value(dev, "name"); + if ((sysattr_name) && + (0 == strcmp(touch_key_device_name, sysattr_name))) { + INPUT_LOG_TRACE("DeviceAssort : ESC_SW\n"); + return HAL_INPUT_DEVICE_TOUCH_ESCKEY; + } + + char touch_device_name[INPUT_NODE_NAME_LENGTH] = { 0 }; + GetPanelNameTouch(touch_device_name, sizeof(touch_device_name)); + sysattr_name = udev_device_get_sysattr_value(dev, "name"); + if ((sysattr_name) && + (0 == strcmp(touch_device_name, sysattr_name))) { + INPUT_LOG_TRACE("DeviceAssort : Touch\n"); + return HAL_INPUT_DEVICE_TOUCH; + } + + property = udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD"); + if ((property) && (strcmp("1", property) == 0)) { + INPUT_LOG_TRACE("DeviceAssort : KeyBoard\n"); + return HAL_INPUT_DEVICE_KEYBOARD; + } + + property = udev_device_get_property_value(dev, "ID_INPUT_TABLET"); + if ((property) && (strcmp("1", property) == 0)) { + INPUT_LOG_TRACE("DeviceAssort : Tablet\n"); + return HAL_INPUT_DEVICE_INVALID; + } + + property = udev_device_get_property_value(dev, "ID_INPUT_TOUCHPAD"); + if ((property) && (strcmp("1", property) == 0)) { + INPUT_LOG_TRACE("DeviceAssort : Touch pad\n"); + return HAL_INPUT_DEVICE_TABLET_FINGER; + } + + return HAL_INPUT_DEVICE_INVALID; +} + +static void InputUdevMonitorDeviceListOutput(void) { + struct InputUtilList *p; + + INPUT_LOG_TRACE("OutputList >> start ======================\n"); + input_list_for_each(p, &g_input_udevmonitor_info.dev_list.list) { + struct InputInputDeviceList *entry = input_list_entry(p, struct InputInputDeviceList, list); + if (NULL != entry) { + INPUT_LOG_TRACE("FD: %d Device=%s Assort=%d\n", + entry->fd, entry->device_node, entry->device_assort); + } + } + INPUT_LOG_TRACE("OutputList << end ======================\n"); +} + +static void InputUdevMonitorDeviceListDelete(const char *node) { + struct InputUtilList *p; + + input_list_for_each(p, &g_input_udevmonitor_info.dev_list.list) { + struct InputInputDeviceList *entry = input_list_entry(p, struct InputInputDeviceList, list); + if (strcmp(node, entry->device_node) == 0) { + close(entry->fd); + InputUtilListDelete(p); + free(entry); + break; + } + } + InputUdevMonitorDeviceListOutput(); +} + +static int InputUdevMonitorDeviceListAdd(int fd, int device_assort, const char *node) { + int ret = HAL_INPUT_RET_NORMAL; + struct InputInputDeviceList *p; + + p = (struct InputInputDeviceList *) malloc(sizeof(struct InputInputDeviceList)); + if (p) { + p->fd = fd; + p->device_assort = device_assort; + + if (strlen(node) < INPUT_DEVICE_NODE_LENGTH_MAX) { + strncpy(p->device_node, node, sizeof(p->device_node) - 1); + InputUdevMonitorDeviceListDelete(node); + InputUtilListAdd(&p->list, &g_input_udevmonitor_info.dev_list.list); + } else { + ret = HAL_INPUT_RET_ERROR; + } + } else { + ret = HAL_INPUT_RET_ERROR; + } + + InputUdevMonitorDeviceListOutput(); + + return ret; +} + +static int InputUdevMonitorInputEventGrab(const char *node, struct udev_device *dev) { + int fd, rtn; + + InputUdevMonitorDeviceListDelete(node); + + fd = open(node, O_RDONLY); + + if (fd < 0) { + INPUT_ERROR_LOG("ERR: open %s errno=%d \n", node, errno); + goto err_rtn; + } + + rtn = ioctl(fd, EVIOCGRAB, 1); + if (rtn) { + INPUT_ERROR_LOG("ERR: ioctl grab %s \n", node); + goto err_rtn_close; + } + INPUT_LOG_TRACE("%s Grab \n", node); + + /* Backup FD */ + rtn = InputUdevMonitorDeviceListAdd(fd, InputUdevMonitorDeviceAssort(dev), node); + if (rtn) { + goto err_rtn_close; + } + + return HAL_INPUT_RET_NORMAL; + +err_rtn_close: + close(fd); +err_rtn: + INPUT_LOG_TRACE("%s Grab impossible \n", node); + return HAL_INPUT_RET_ERROR; +} + +static void InputUdevMonitorFDSet(int *nfds, fd_set *fds) { + struct InputUtilList *p; + + input_list_for_each(p, &g_input_udevmonitor_info.dev_list.list) { + struct InputInputDeviceList *entry = input_list_entry(p, struct InputInputDeviceList, list); + + switch (entry->device_assort) { + case HAL_INPUT_DEVICE_TOUCH_ESCKEY: + case HAL_INPUT_DEVICE_TOUCH: + case HAL_INPUT_DEVICE_KEYBOARD: + case HAL_INPUT_DEVICE_TABLET_FINGER: + FD_SET(entry->fd, fds); + *nfds = max_value(*nfds, entry->fd); + break; + default: + break; + } + } +} + +static void InputUdevMonitorFDHandle(fd_set *fds) { + struct InputUtilList *p; + + input_list_for_each(p, &g_input_udevmonitor_info.dev_list.list) { + struct InputInputDeviceList *entry = input_list_entry(p, struct InputInputDeviceList, list); + if (FD_ISSET(entry->fd, fds)) { + int notify_id = 0; + switch (entry->device_assort) { + case HAL_INPUT_DEVICE_TOUCH_ESCKEY: + notify_id = HAL_INPUT_NOTIFY_ESC_KEY; + break; + case HAL_INPUT_DEVICE_TOUCH: + notify_id = HAL_INPUT_NOTIFY_TOUCH; + break; + case HAL_INPUT_DEVICE_KEYBOARD: + notify_id = HAL_INPUT_NOTIFY_KEY_BOARD; + break; + case HAL_INPUT_DEVICE_TABLET_FINGER: + notify_id = HAL_INPUT_NOTIFY_TABLET_FINGER; + break; + default: + return; + } + if (notify_id == HAL_INPUT_NOTIFY_TOUCH) { + InputUdevMonitorTouchEventHandle(entry->fd, notify_id); + } else { + InputUdevMonitorInputEventHandle(entry->fd, entry->device_assort, notify_id); + } + } + } +} + +static int InputUdevMonitorInit(void) { + g_input_udevmonitor_info.udev = udev_new(); + if (NULL == g_input_udevmonitor_info.udev) { + INPUT_ERROR_LOG("ERR: udev_new ret=%d \n", errno); + return HAL_INPUT_RET_ERROR; + } + + // create the udev monitor + g_input_udevmonitor_info.monitor = udev_monitor_new_from_netlink(g_input_udevmonitor_info.udev, "udev"); + udev_monitor_filter_add_match_subsystem_devtype(g_input_udevmonitor_info.monitor, "input", NULL); + + // start receiving hotplug events + udev_monitor_enable_receiving(g_input_udevmonitor_info.monitor); + + INPUT_INIT_LIST_HEAD(&g_input_udevmonitor_info.dev_list.list) + + return HAL_INPUT_RET_NORMAL; +} + +static void InputUdevMonitorDeinit(void) { + // destroy the udev monitor + udev_monitor_unref(g_input_udevmonitor_info.monitor); + // destroy the udev object + udev_unref(g_input_udevmonitor_info.udev); + + if (g_sender_handle != NULL) { + McClose(g_sender_handle); + g_sender_handle = NULL; + } + + g_input_touch_init_notify = false; +} + +static int InputUdevMonitorDevicesGet(void) { + int ret; + struct udev_enumerate *enumerate; + struct udev_list_entry *devices, *dev_list_entry; + char touch_device_name[INPUT_NODE_NAME_LENGTH] = { 0}; + const char* sysattr_name; + bool input_touch_device_found = false; + + // Create a list of the devices in the 'usb_device' subsystem. + enumerate = udev_enumerate_new(g_input_udevmonitor_info.udev); + udev_enumerate_add_match_subsystem(enumerate, "input"); + udev_enumerate_scan_devices(enumerate); + devices = udev_enumerate_get_list_entry(enumerate); + GetPanelNameTouch(touch_device_name, sizeof(touch_device_name)); + + // Enumerate device list + udev_list_entry_foreach(dev_list_entry, devices) { + const char *path, *node; + + // Get the filename of the /sys entry for the device and create a udev_device object (dev) representing it + path = udev_list_entry_get_name(dev_list_entry); + struct udev_device* dev = udev_device_new_from_syspath(g_input_udevmonitor_info.udev, path); + if (NULL == dev) continue; + + // usb_device_get_devnode() returns the path to the device node itself in /dev. + node = udev_device_get_devnode(dev); + if (!node) { + udev_device_unref(dev); + continue; + } + + // Filter device name is eventX + if (strncmp("event", udev_device_get_sysname(dev), sizeof("event") -1) != 0) { + udev_device_unref(dev); + continue; + } + + // virtual device + if (strncmp(INPUT_VIRTUAL_INPUTDEVICE_NAME, udev_device_get_devpath(dev), + sizeof(INPUT_VIRTUAL_INPUTDEVICE_NAME) - 1) == 0) { + INPUT_LOG_TRACE("Found Virtual Device : %s \n", node); + udev_device_unref(dev); + continue; + } + + // check parent is input + struct udev_device* input_dev = udev_device_get_parent_with_subsystem_devtype(dev, "input", NULL); + if (NULL == input_dev) { + udev_device_unref(dev); + continue; + } + + sysattr_name = udev_device_get_sysattr_value(input_dev, "name"); + if (NULL == sysattr_name) { + INPUT_ERROR_LOG("ERR: Unable to find sysattr \n"); + udev_device_unref(dev); + continue; + } + + // touchpanel device + if (0 == strcmp(touch_device_name, sysattr_name)) { + INPUT_LOG_TRACE("Found %s : %s \n", touch_device_name, path); + int spec_reso_h; + int spec_reso_v; + GetPanelSpecResolutionInput(&spec_reso_h, &spec_reso_v); + ret = ConfigTouch(udev_device_get_syspath(input_dev), + spec_reso_h, spec_reso_v); + + if (HAL_INPUT_RET_NORMAL == ret) { + int status; + ret = GetConfigStatusTouch(&status); + if (HAL_INPUT_RET_NORMAL == ret) { + if (HAL_INPUT_TOUCH_CONFIG_OFF == status) { + InputUdevMonitorTouchInitFinEventSend(HAL_INPUT_RET_NORMAL); + } + } else { + INPUT_ERROR_LOG("GetConfigStatusTouch fail\n"); + InputUdevMonitorTouchInitFinEventSend(HAL_INPUT_RET_ERROR); + } + } else { + INPUT_ERROR_LOG("ConfigTouch fail\n"); + InputUdevMonitorTouchInitFinEventSend(HAL_INPUT_RET_ERROR); + } + + input_touch_device_found = true; + } + + INPUT_LOG_TRACE("Found Device : %s \n", node); + + /* Modified not to notify input events to other processes */ + InputUdevMonitorInputEventGrab(node, input_dev); + + udev_device_unref(dev); + } // end foreach + + if (!input_touch_device_found) { + INPUT_ERROR_LOG("ERR: Dummy Device Create"); + InputUdevMonitorTouchInitFinEventSend(HAL_INPUT_RET_NORMAL); + } + + // Free the enumerator object + udev_enumerate_unref(enumerate); + + return HAL_INPUT_RET_NORMAL; +} + +static void InputUdevMonitorDeviceStatusChange(int fd, fd_set *fds) { + if (FD_ISSET(fd, fds)) { + // receive the relevant device + struct udev_device* dev = udev_monitor_receive_device(g_input_udevmonitor_info.monitor); + if (NULL == dev) return; + + // input_udev_DevicesGet(udm); + const char* action = udev_device_get_action(dev); + const char* node = udev_device_get_devnode(dev); + if ((!action) || (!node)) { + udev_device_unref(dev); + return; + } + + if (strncmp("event", udev_device_get_sysname(dev), sizeof("event") -1) != 0) { + INPUT_LOG_TRACE("not event device %s \n", udev_device_get_sysname(dev)); + udev_device_unref(dev); + return; + } + + if (strncmp(INPUT_VIRTUAL_INPUTDEVICE_NAME, udev_device_get_devpath(dev), + sizeof(INPUT_VIRTUAL_INPUTDEVICE_NAME) - 1) == 0) { + udev_device_unref(dev); + return; + } + + if (strcmp(action, "remove") == 0) { + InputUdevMonitorDeviceListDelete(node); + } + + struct udev_device* input_dev = udev_device_get_parent_with_subsystem_devtype(dev, "input", NULL); + if (NULL == input_dev) { + udev_device_unref(dev); + return; + } + char touch_device_name[INPUT_NODE_NAME_LENGTH] = { 0}; + GetPanelNameTouch(touch_device_name, sizeof(touch_device_name)); + const char *sysattr_name = udev_device_get_sysattr_value(input_dev, "name"); + if (NULL == sysattr_name) { + INPUT_ERROR_LOG("ERR: Unable to find sysattr \n"); + udev_device_unref(dev); + return; + } + + if (0 == strcmp(touch_device_name, sysattr_name)) { + if (strcmp(action, "remove") == 0) { + } else { + INPUT_LOG_TRACE("Found %s \n", touch_device_name); + InputUdevMonitorTouchInitFinEventSend(HAL_INPUT_RET_NORMAL); + } + } + + INPUT_LOG_TRACE("%s : %s \n", node, action); + if (strcmp(action, "remove") == 0) { + } else { + /* Modified not to notify input events to other processes */ + InputUdevMonitorInputEventGrab(node, input_dev); + } + udev_device_unref(dev); + } +} + +static void InputUdevMonitorWatch(void) { + fd_set fds; + int fd = udev_monitor_get_fd(g_input_udevmonitor_info.monitor); + + if (fd != -1) { + while (!g_break_from_watch) { + FD_ZERO(&fds); + FD_SET(fd, &fds); + int nfds = max_value(0, fd); + + InputUdevMonitorFDSet(&nfds, &fds); + + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 100 * 1000; + int ret = select(nfds + 1, &fds, NULL, NULL, &timeout); + if (ret > 0) { + InputUdevMonitorDeviceStatusChange(fd, &fds); + + InputUdevMonitorFDHandle(&fds); + } + } + } else { + INPUT_ERROR_LOG("ERR: udev_monitor_get_fd"); + } +} + +static void *InputUdevMonitorMain(void * arg) { + int rtn; + prctl(PR_SET_NAME, HAL_INPUT_UDEVMONITOR_THREADNAME); + + rtn = InputUdevMonitorInit(); + if (rtn != HAL_INPUT_RET_NORMAL) { + goto err_rtn; + } + + /* Get input device */ + InputUdevMonitorDevicesGet(); + + /* Input device monitoring (basically never get out from here) */ + InputUdevMonitorWatch(); + + InputUdevMonitorDeinit(); + + return NULL; + +err_rtn: + INPUT_LOG_TRACE("pthread_detach\n"); + return NULL; +} + +int32_t InputUdevMonitorThreadCreate(void) { + int ret; + + ret = pthread_create(&g_udev_monitor_thread, NULL, InputUdevMonitorMain, NULL); + if (ret != 0) { + INPUT_ERROR_LOG("ERR: pthread_create =%d\n", errno); + return HAL_INPUT_RET_ERROR; + } + + return HAL_INPUT_RET_NORMAL; +} diff --git a/hal/input_hal/src/input_util.cpp b/hal/input_hal/src/input_util.cpp new file mode 100755 index 0000000..bb349eb --- /dev/null +++ b/hal/input_hal/src/input_util.cpp @@ -0,0 +1,77 @@ +/* + * @copyright Copyright (c) 2018-2020 TOYOTA MOTOR CORPORATION. + * + * 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 "input_util.h" + +#include +#include + +#include "input_hal.h" +#include "input_hal_debug.h" + +#define INPUT_UTIL_MESSAGE_SEND_RETRY 3 +#define INPUT_UTIL_MESSAGE_SEND_WAIT 10000 /* RetryWait:10ms */ +/* + * InputUtilListAdd + */ +void InputUtilListAdd(struct InputUtilList *node_new, struct InputUtilList *node_head) { + node_new->prev = node_head; + node_new->next = node_head->next; + node_head->next = node_new; + node_new->next->prev = node_new; +} + +/* + * InputUtilListDelete + */ +void InputUtilListDelete(struct InputUtilList *node) { + node->prev->next = node->next; + node->next->prev = node->prev; +} + +/* + * InputUtilMCSend + */ +int InputUtilMCSend(HANDLE h_message, PCSTR source, UI_32 cmd, UI_32 length, PCVOID data) { + int i = 0; + EFrameworkunifiedStatus e_status; /* return value */ + + do { + e_status = McSend(h_message, source, cmd, length, data); + if (eFrameworkunifiedStatusOK == e_status) { + break; + } + InputUtilSleep(INPUT_UTIL_MESSAGE_SEND_WAIT); + } while (i++ < INPUT_UTIL_MESSAGE_SEND_RETRY); + + if (e_status != eFrameworkunifiedStatusOK) { + INPUT_ERROR_LOG("ERR: MessageSend=%d \n", e_status); + } + + return e_status; +} + +/* + * InputUtilSleep + */ +int InputUtilSleep(int usec) { + struct timespec req; + + req.tv_sec = 0; + req.tv_nsec = usec * 1000; + nanosleep(&req, NULL); + + return HAL_INPUT_RET_NORMAL; +} -- cgit 1.2.3-korg