summaryrefslogtreecommitdiffstats
path: root/input_hal/src
diff options
context:
space:
mode:
Diffstat (limited to 'input_hal/src')
-rw-r--r--input_hal/src/input_drm.cpp128
-rw-r--r--input_hal/src/input_hal.cpp267
-rw-r--r--input_hal/src/input_touch_ilitek.cpp226
-rw-r--r--input_hal/src/input_udev_monitor.cpp566
-rw-r--r--input_hal/src/input_util.cpp77
5 files changed, 1264 insertions, 0 deletions
diff --git a/input_hal/src/input_drm.cpp b/input_hal/src/input_drm.cpp
new file mode 100644
index 00000000..20adf799
--- /dev/null
+++ b/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 <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#if defined(_USE_DRM)
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#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/input_hal/src/input_hal.cpp b/input_hal/src/input_hal.cpp
new file mode 100644
index 00000000..b5f49160
--- /dev/null
+++ b/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 <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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<pthread_t>(-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/input_hal/src/input_touch_ilitek.cpp b/input_hal/src/input_touch_ilitek.cpp
new file mode 100644
index 00000000..9d1822a7
--- /dev/null
+++ b/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 <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#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/input_hal/src/input_udev_monitor.cpp b/input_hal/src/input_udev_monitor.cpp
new file mode 100644
index 00000000..5d8cc6b7
--- /dev/null
+++ b/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 <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <libudev.h>
+#include <native_service/ns_message_center_if.h>
+
+#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/input_hal/src/input_util.cpp b/input_hal/src/input_util.cpp
new file mode 100644
index 00000000..bb349ebd
--- /dev/null
+++ b/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 <native_service/ns_message_center_if.h>
+#include <stdio.h>
+
+#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;
+}