From ec1d4bd71eb275b6184c5d5851d7dd7b06e7eeda Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Fri, 27 Feb 2015 18:56:33 +0900 Subject: [PATCH 01/16] deviced: remove out unsupported device from device list Unsupported device remove out from device list. It does not invoke any function of unsuppoted device include exit() function. Change-Id: Ia09a9a0b3676b0fc8cca8cbf3875c72961d51d1b Signed-off-by: Jiyoung Yun --- src/core/devices.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/devices.c b/src/core/devices.c index 307d3a0..942b7e0 100644 --- a/src/core/devices.c +++ b/src/core/devices.c @@ -64,12 +64,13 @@ int check_default(const struct device_ops *dev) void devices_init(void *data) { - dd_list *elem; + dd_list *elem, *elem_n; const struct device_ops *dev; - DD_LIST_FOREACH(dev_head, elem, dev) { + DD_LIST_FOREACH_SAFE(dev_head, elem, elem_n, dev) { if (dev->probe && dev->probe(data) != 0) { _E("[%s] probe fail", dev->name); + DD_LIST_REMOVE(dev_head, dev); continue; } -- 2.7.4 From 088d78b463cd5c44b2a2fe3dc40efe538e0e271f Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Wed, 25 Feb 2015 21:30:05 +0900 Subject: [PATCH 02/16] deviced: Add inline function to make dbus reply automatically Apply new function in extcon module Change-Id: Ia9a77fd88be8151288e9f51bc1ddd3e9ece74f8b Signed-off-by: Jiyoung Yun --- src/core/edbus-handler.h | 10 ++++++++++ src/extcon/extcon.c | 7 +------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/core/edbus-handler.h b/src/core/edbus-handler.h index cd2d266..6aee7d5 100644 --- a/src/core/edbus-handler.h +++ b/src/core/edbus-handler.h @@ -43,6 +43,16 @@ struct watch { int (*func)(char *name, enum watch_id id); }; +static inline DBusMessage *make_reply_message(DBusMessage *msg, int ret) +{ + DBusMessageIter iter; + DBusMessage *reply; + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret); + return reply; +} + int register_edbus_interface_and_method(const char *path, const char *interface, const struct edbus_method *edbus_methods, int size); diff --git a/src/extcon/extcon.c b/src/extcon/extcon.c index 37635f5..030dcae 100755 --- a/src/extcon/extcon.c +++ b/src/extcon/extcon.c @@ -202,8 +202,6 @@ static DBusMessage *dbus_get_extcon_status(E_DBus_Object *obj, DBusMessage *msg) { DBusError err; - DBusMessageIter iter; - DBusMessage *reply; struct extcon_ops *dev; char *str; int ret; @@ -230,10 +228,7 @@ static DBusMessage *dbus_get_extcon_status(E_DBus_Object *obj, _D("Extcon device : %s, status : %d", dev->name, dev->status); error: - reply = dbus_message_new_method_return(msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret); - return reply; + return make_reply_message(msg, ret); } static int extcon_probe(void *data) -- 2.7.4 From 0eedb2a0954e4e7153758b925b1564782a2c0ce9 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Fri, 6 Mar 2015 18:04:05 +0900 Subject: [PATCH 03/16] deviced: Apply display HAL structure Deviced will control display power using display HAL. It also supports to control display brightness. Change-Id: Ie15c0abe434610dfe60bbda7949ba6e5f71d174f Signed-off-by: Jiyoung Yun --- CMakeLists.txt | 3 - src/display/auto-brightness.c | 13 ++-- src/display/core.c | 14 ++++ src/display/device-interface.c | 148 +++++++++++++++++++++++++++++++++-------- src/display/device-interface.h | 14 ++-- src/display/display-dbus.c | 46 +++++-------- 6 files changed, 166 insertions(+), 72 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 304e348..d613d2f 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,9 +159,6 @@ ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"") ADD_DEFINITIONS("-DLIBPATH=\"${LIB_INSTALL_DIR}\"") ADD_DEFINITIONS("-DENABLE_KEY_FILTER") -IF(X11_SUPPORT) -ADD_DEFINITIONS("-DENABLE_X_LCD_ONOFF") -ENDIF(X11_SUPPORT) ADD_DEFINITIONS("-DENABLE_DEVICED_DLOG") ADD_DEFINITIONS("-DENABLE_LIBDEVICED_DLOG") ADD_DEFINITIONS("-DENABLE_PM_LOG") diff --git a/src/display/auto-brightness.c b/src/display/auto-brightness.c index 63b245e..6611d06 100644 --- a/src/display/auto-brightness.c +++ b/src/display/auto-brightness.c @@ -118,11 +118,10 @@ static bool update_working_position(void) static int get_siop_brightness(int value) { - int cmd, ret, brt; + int brt; - cmd = DISP_CMD(PROP_DISPLAY_MAX_BRIGHTNESS, DEFAULT_DISPLAY); - ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &brt); - if (ret >= 0 && value > brt) + brt = DEFAULT_DISPLAY_MAX_BRIGHTNESS; + if (value > brt) return brt; return value; @@ -131,10 +130,10 @@ static int get_siop_brightness(int value) static void alc_set_brightness(int setting, int value, int lux) { static int old; - int position, cmd, tmp_value = 0; + int position, tmp_value = 0, ret; - cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY); - if (device_get_property(DEVICE_TYPE_DISPLAY, cmd, &tmp_value) < 0) { + ret = backlight_ops.get_brightness(&tmp_value); + if (ret < 0) { _E("Fail to get display brightness!"); return; } diff --git a/src/display/core.c b/src/display/core.c index 19557d2..c7cdd94 100644 --- a/src/display/core.c +++ b/src/display/core.c @@ -2319,6 +2319,16 @@ static int display_load_config(struct parse_result *result, void *user_data) * Power manager Main * */ +static int display_probe(void *data) +{ + /** + * load display service + * if there is no display shared library, + * deviced does not provide any method and function of display. + */ + return display_service_load(); +} + static void display_init(void *data) { int ret, i; @@ -2448,6 +2458,9 @@ static void display_exit(void *data) exit_lcd_operation(); free_lock_info_list(); + /* free display service */ + display_service_free(); + _I("Stop power manager"); } @@ -2504,6 +2517,7 @@ static int display_status(void) static const struct device_ops display_device_ops = { .priority = DEVICE_PRIORITY_HIGH, .name = "display", + .probe = display_probe, .init = display_init, .exit = display_exit, .start = display_start, diff --git a/src/display/device-interface.c b/src/display/device-interface.c index 7c9575d..17bd707 100644 --- a/src/display/device-interface.c +++ b/src/display/device-interface.c @@ -1,7 +1,7 @@ /* * deviced * - * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. + * Copyright (c) 2012 - 2015 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. @@ -27,6 +27,9 @@ #include #include #include +#include +#include +#include #include "core/log.h" #include "core/devices.h" @@ -79,20 +82,30 @@ static bool custom_status = false; static int custom_brightness = 0; static int force_brightness = 0; +static struct display_device *display_dev; + static int _bl_onoff(PMSys *p, int on) { - int cmd; + if (!display_dev || !display_dev->set_state) { + _E("there is no display device"); + return -ENOENT; + } - cmd = DISP_CMD(PROP_DISPLAY_ONOFF, DEFAULT_DISPLAY); - return device_set_property(DEVICE_TYPE_DISPLAY, cmd, on); + return display_dev->set_state(on); } static int _bl_brt(PMSys *p, int brightness, int delay) { int ret = -1; - int cmd; int prev; + if (!display_dev || + !display_dev->get_brightness || + !display_dev->set_brightness) { + _E("there is no display device"); + return -ENOENT; + } + if (delay > 0) usleep(delay); @@ -102,8 +115,7 @@ static int _bl_brt(PMSys *p, int brightness, int delay) brightness = force_brightness; } - cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY); - ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &prev); + ret = display_dev->get_brightness(&prev); /* Update new brightness to vconf */ if (!ret && (brightness != prev)) { @@ -111,7 +123,7 @@ static int _bl_brt(PMSys *p, int brightness, int delay) } /* Update device brightness */ - ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, brightness); + ret = display_dev->set_brightness(brightness); _I("set brightness %d, %d", brightness, ret); @@ -148,17 +160,19 @@ static int _sys_get_power_lock_support(PMSys *p) static int _sys_get_lcd_power(PMSys *p) { - int value = -1; - int ret = -1; - int cmd; + enum display_state state; + int ret; - cmd = DISP_CMD(PROP_DISPLAY_ONOFF, DEFAULT_DISPLAY); - ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &value); + if (!display_dev || !display_dev->get_state) { + _E("there is no display device"); + return -ENOENT; + } - if (ret < 0 || value < 0) - return -1; + ret = display_dev->get_state(&state); + if (ret < 0) + return ret; - return value; + return state; } static void _init_bldev(PMSys *p, unsigned int flags) @@ -291,15 +305,23 @@ void change_brightness(int start, int end, int step) { int diff, val; int ret = -1; - int cmd; int prev; + if (!display_dev || + !display_dev->get_brightness) { + _E("there is no display device"); + return; + } + if ((pm_status_flag & PWRSV_FLAG) && !(pm_status_flag & BRTCH_FLAG)) return; - cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY); - ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &prev); + ret = display_dev->get_brightness(&prev); + if (ret < 0) { + _E("fail to get brightness : %d", ret); + return; + } if (prev == end) return; @@ -336,8 +358,8 @@ static int backlight_on(enum device_flags flags) return -1; for (i = 0; i < PM_LCD_RETRY_CNT; i++) { - ret = pmsys->bl_onoff(pmsys, STATUS_ON); - if (get_lcd_power() == PM_LCD_POWER_ON) { + ret = pmsys->bl_onoff(pmsys, DISPLAY_ON); + if (get_lcd_power() == DISPLAY_ON) { #ifdef ENABLE_PM_LOG pm_history_save(PM_LOG_LCD_ON, pm_cur_state); #endif @@ -381,8 +403,8 @@ static int backlight_off(enum device_flags flags) if (x_dpms_enable == false) #endif usleep(30000); - ret = pmsys->bl_onoff(pmsys, STATUS_OFF); - if (get_lcd_power() == PM_LCD_POWER_OFF) { + ret = pmsys->bl_onoff(pmsys, DISPLAY_OFF); + if (get_lcd_power() == DISPLAY_OFF) { #ifdef ENABLE_PM_LOG pm_history_save(PM_LOG_LCD_OFF, pm_cur_state); #endif @@ -430,10 +452,15 @@ static bool get_custom_status(void) static int save_custom_brightness(void) { - int cmd, ret, brightness; + int ret, brightness; + + if (!display_dev || + !display_dev->get_brightness) { + _E("there is no display device"); + return -ENOENT; + } - cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY); - ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &brightness); + ret = display_dev->get_brightness(&brightness); custom_brightness = brightness; @@ -490,9 +517,9 @@ static int backlight_standby(int force) if (!pmsys || !pmsys->bl_onoff) return -1; - if ((get_lcd_power() == PM_LCD_POWER_ON) || force) { + if ((get_lcd_power() == DISPLAY_ON) || force) { _I("LCD standby"); - ret = pmsys->bl_onoff(pmsys, STATUS_STANDBY); + ret = pmsys->bl_onoff(pmsys, DISPLAY_STANDBY); } return ret; @@ -518,6 +545,26 @@ static int check_wakeup_src(void) return EVENT_DEVICE; } +static int set_brightness(int val) +{ + if (!display_dev || !display_dev->set_brightness) { + _E("there is no display device"); + return -ENOENT; + } + + return display_dev->set_brightness(val); +} + +static int get_brightness(int *val) +{ + if (!display_dev || !display_dev->get_brightness) { + _E("there is no display device"); + return -ENOENT; + } + + return display_dev->get_brightness(val); +} + void _init_ops(void) { backlight_ops.off = backlight_off; @@ -532,6 +579,8 @@ void _init_ops(void) backlight_ops.save_custom_brightness = save_custom_brightness; backlight_ops.custom_update = custom_backlight_update; backlight_ops.set_force_brightness = set_force_brightness; + backlight_ops.set_brightness = set_brightness; + backlight_ops.get_brightness = get_brightness; power_ops.suspend = system_suspend; power_ops.pre_suspend = system_pre_suspend; @@ -542,6 +591,49 @@ void _init_ops(void) power_ops.check_wakeup_src = check_wakeup_src; } +int display_service_load(void) +{ + struct hw_info *info; + int r; + + r = hw_get_info(DISPLAY_HARDWARE_DEVICE_ID, + (const struct hw_info **)&info); + if (r < 0) { + _E("fail to load display shared library : %d", r); + return -ENOENT; + } + + if (!info->open) { + _E("fail to open display device : open(NULL)"); + return -EPERM; + } + + r = info->open(info, NULL, (struct hw_common **)&display_dev); + if (r < 0) { + _E("fail to get display device structure : %d", r); + return -EPERM; + } + + _D("display device structure load success"); + return 0; +} + +int display_service_free(void) +{ + struct hw_info *info; + + if (!display_dev) + return -ENOENT; + + info = display_dev->common.info; + + assert(info); + + info->close((struct hw_common *)display_dev); + + return 0; +} + int init_sysfs(unsigned int flags) { int ret; diff --git a/src/display/device-interface.h b/src/display/device-interface.h index 59191c3..01f44ef 100644 --- a/src/display/device-interface.h +++ b/src/display/device-interface.h @@ -36,14 +36,16 @@ #define PM_DEFAULT_BRIGHTNESS 60 #define PM_LCD_POWER_ON 0 -#define PM_LCD_POWER_OFF 4 +#define PM_LCD_POWER_OFF 3 #define PM_LCD_RETRY_CNT 3 -#define STATUS_STANDBY (STATUS_ON + 1) #define DISP_INDEX_SHIFT 16 #define DISP_CMD(prop, index) ((index << DISP_INDEX_SHIFT) | prop) +#define DEFAULT_DISPLAY_COUNT 1 +#define DEFAULT_DISPLAY_MAX_BRIGHTNESS 100 + /* * Event type enumeration */ @@ -54,8 +56,10 @@ enum { EVENT_END, }; -extern int init_sysfs(unsigned int); -extern int exit_sysfs(void); +int init_sysfs(unsigned int); +int exit_sysfs(void); +int display_service_load(void); +int display_service_free(void); struct _backlight_ops { int (*off)(enum device_flags); @@ -70,6 +74,8 @@ struct _backlight_ops { int (*save_custom_brightness)(void); int (*custom_update)(void); int (*set_force_brightness)(int level); + int (*set_brightness)(int val); + int (*get_brightness)(int *val); }; struct _power_ops { diff --git a/src/display/display-dbus.c b/src/display/display-dbus.c index 2068e67..fedddda 100644 --- a/src/display/display-dbus.c +++ b/src/display/display-dbus.c @@ -330,12 +330,9 @@ static DBusMessage *edbus_getdisplaycount(E_DBus_Object *obj, DBusMessage *msg) { DBusMessageIter iter; DBusMessage *reply; - int cmd, cnt, ret; + int ret; - cmd = DISP_CMD(PROP_DISPLAY_DISPLAY_COUNT, DEFAULT_DISPLAY); - ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &cnt); - if (ret >= 0) - ret = cnt; + ret = DEFAULT_DISPLAY_COUNT; reply = dbus_message_new_method_return(msg); dbus_message_iter_init_append(reply, &iter); @@ -347,12 +344,9 @@ static DBusMessage *edbus_getmaxbrightness(E_DBus_Object *obj, DBusMessage *msg) { DBusMessageIter iter; DBusMessage *reply; - int cmd, brt, ret; + int ret; - cmd = DISP_CMD(PROP_DISPLAY_MAX_BRIGHTNESS, DEFAULT_DISPLAY); - ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &brt); - if (ret >= 0) - ret = brt; + ret = DEFAULT_DISPLAY_MAX_BRIGHTNESS; reply = dbus_message_new_method_return(msg); dbus_message_iter_init_append(reply, &iter); @@ -364,13 +358,9 @@ static DBusMessage *edbus_setmaxbrightness(E_DBus_Object *obj, DBusMessage *msg) { DBusMessageIter iter; DBusMessage *reply; - int cmd, brt, ret; - - dbus_message_iter_init(msg, &iter); - dbus_message_iter_get_basic(&iter, &brt); + int ret; - cmd = DISP_CMD(PROP_DISPLAY_MAX_BRIGHTNESS, DEFAULT_DISPLAY); - ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, brt); + ret = -ENOTSUP; reply = dbus_message_new_method_return(msg); dbus_message_iter_init_append(reply, &iter); @@ -382,10 +372,9 @@ static DBusMessage *edbus_getbrightness(E_DBus_Object *obj, DBusMessage *msg) { DBusMessageIter iter; DBusMessage *reply; - int cmd, brt, ret; + int brt, ret; - cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY); - ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &brt); + ret = backlight_ops.get_brightness(&brt); if (ret >= 0) ret = brt; @@ -401,7 +390,7 @@ static DBusMessage *edbus_setbrightness(E_DBus_Object *obj, DBusMessage *msg) { DBusMessageIter iter; DBusMessage *reply; - int cmd, brt, autobrt, ret, caps; + int brt, autobrt, ret, caps; caps = display_get_caps(DISPLAY_ACTOR_API); @@ -431,8 +420,7 @@ static DBusMessage *edbus_setbrightness(E_DBus_Object *obj, DBusMessage *msg) goto error; } - cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY); - ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, brt); + ret = backlight_ops.set_brightness(brt); if (ret < 0) goto error; if (vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt) != 0) @@ -454,7 +442,7 @@ static DBusMessage *edbus_holdbrightness(E_DBus_Object *obj, DBusMessage *msg) { DBusMessageIter iter; DBusMessage *reply; - int cmd, brt, autobrt, ret, caps; + int brt, autobrt, ret, caps; caps = display_get_caps(DISPLAY_ACTOR_API); @@ -480,8 +468,7 @@ static DBusMessage *edbus_holdbrightness(E_DBus_Object *obj, DBusMessage *msg) vconf_set_int(VCONFKEY_PM_CUSTOM_BRIGHTNESS_STATUS, VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON); - cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY); - ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, brt); + ret = backlight_ops.set_brightness(brt); if (ret < 0) goto error; @@ -507,7 +494,7 @@ static DBusMessage *edbus_releasebrightness(E_DBus_Object *obj, DBusMessage *msg { DBusMessageIter iter; DBusMessage *reply; - int cmd, bat, charger, changed, setting, brt, autobrt, ret = 0; + int bat, charger, changed, setting, brt, autobrt, ret = 0; if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat) != 0) { _E("Failed to get VCONFKEY_SYSMAN_BATTERY_STATUS_LOW value"); @@ -541,8 +528,7 @@ static DBusMessage *edbus_releasebrightness(E_DBus_Object *obj, DBusMessage *msg vconf_set_int(VCONFKEY_PM_CUSTOM_BRIGHTNESS_STATUS, VCONFKEY_PM_CUSTOM_BRIGHTNESS_OFF); - cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY); - ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &brt); + ret = backlight_ops.get_brightness(&brt); if (ret < 0) brt = ret; @@ -551,14 +537,14 @@ static DBusMessage *edbus_releasebrightness(E_DBus_Object *obj, DBusMessage *msg charger == VCONFKEY_SYSMAN_CHARGER_DISCONNECTED && !changed) { _D("batt warning low : brightness is not changed!"); if (brt != 0) { - device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_BRIGHTNESS, 0); + backlight_ops.set_brightness(0); } goto error; } if (autobrt == SETTING_BRIGHTNESS_AUTOMATIC_OFF) { if (brt != setting) { - device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_BRIGHTNESS, setting); + backlight_ops.set_brightness(setting); if (vconf_set_int(VCONFKEY_PM_CURRENT_BRIGHTNESS, setting) != 0) { _E("Failed to set VCONFKEY_PM_CURRENT_BRIGHTNESS value"); } -- 2.7.4 From 82adf8aab74588db77a8dbc22525ca19b495db6f Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Wed, 11 Mar 2015 15:33:48 +0900 Subject: [PATCH 04/16] deviced: Update usb vconf key whenever usb is connected or not Currently, runtime-info uses VCONFKEY_SYSMAN_USB_STATUS vconf key to judge if usb is connected or not. Deviced will update the vconf key whenever usb is changed. Change-Id: I97ab2e9a7a8228fe33b14297b4c002398fd9532c Signed-off-by: Jiyoung Yun --- src/usb/usb.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/usb/usb.c b/src/usb/usb.c index 6de4bd3..44d5d2d 100644 --- a/src/usb/usb.c +++ b/src/usb/usb.c @@ -18,6 +18,7 @@ #include +#include #include "core/log.h" #include "core/list.h" @@ -137,7 +138,8 @@ static int usb_config_disable(void) static int usb_state_changed(int status) { - static int old = USB_DISCONNECTED; + static int old = -1; /* to update at the first time */ + int vconf_state; int ret; _I("USB state is changed from (%d) to (%d)", old, status); @@ -149,10 +151,15 @@ static int usb_state_changed(int status) case USB_CONNECTED: _I("USB cable is connected"); ret = usb_config_enable(); + if (ret == 0) + vconf_state = VCONFKEY_SYSMAN_USB_AVAILABLE; + else + vconf_state = VCONFKEY_SYSMAN_USB_CONNECTED; break; case USB_DISCONNECTED: _I("USB cable is disconnected"); ret = usb_config_disable(); + vconf_state = VCONFKEY_SYSMAN_USB_DISCONNECTED; break; default: _E("Invalid USB state(%d)", status); @@ -163,6 +170,7 @@ static int usb_state_changed(int status) else old = status; + vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS, vconf_state); return ret; } @@ -180,7 +188,7 @@ static void usb_init(void *data) if (ret < 0) _E("Failed to initialize usb configuation"); - ret = usb_state_changed(&(extcon_usb_ops.status)); + ret = usb_state_changed(extcon_usb_ops.status); if (ret < 0) _E("Failed to update usb status(%d)", ret); } -- 2.7.4 From 8ef2d179c83065f76601343a849b8276e539481c Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Wed, 25 Mar 2015 20:57:39 +0900 Subject: [PATCH 05/16] extcon: Changed the function name easily identifiable get_extcon_uevent_state is changed to get_extcon_state_node. This function is for getting state node string. And remove the duplicated logic regarding extcon_changed() and extcon_update(). Signed-off-by: Jiyoung Yun Change-Id: Ifdd5f5f3d1a1b710d9ead02bce64d7cb7e388fdc --- src/extcon/extcon.c | 96 ++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 49 deletions(-) diff --git a/src/extcon/extcon.c b/src/extcon/extcon.c index 030dcae..8d5479f 100755 --- a/src/extcon/extcon.c +++ b/src/extcon/extcon.c @@ -46,23 +46,6 @@ void remove_extcon(struct extcon_ops *dev) DD_LIST_REMOVE(extcon_list, dev); } -static int extcon_changed(struct extcon_ops *dev, int status) -{ - if (!dev) - return -EINVAL; - - if (dev->status == status) - return 0; - - _I("Changed %s device : %d -> %d", dev->name, dev->status, status); - - dev->status = status; - if (dev->update) - dev->update(status); - - return 0; -} - static struct extcon_ops *find_extcon(const char *name) { dd_list *l; @@ -93,7 +76,31 @@ int extcon_get_status(const char *name) return dev->status; } -static int extcon_update(const char *value) +static int extcon_update(const char *name, const char *value) +{ + struct extcon_ops *dev; + int status; + + if (!name || !value) + return -EINVAL; + + dev = find_extcon(name); + if (!dev) { + _E("fail to find matched extcon device : name(%s)", name); + return -EINVAL; + } + + status = atoi(value); + _I("Changed %s device : %d -> %d", name, dev->status, status); + + dev->status = status; + if (dev->update) + dev->update(status); + + return 0; +} + +static int extcon_parsing_value(const char *value) { char *s, *p; char name[NAME_MAX]; @@ -109,9 +116,8 @@ static int extcon_update(const char *value) break; memset(name, 0, sizeof(name)); memcpy(name, s, p-s); - dev = find_extcon(name); - if (dev) - extcon_changed(dev, atoi(p+1)); + /* name is env_name and p+1 is env_value */ + extcon_update(name, p+1); s = strchr(p, '\n'); if (!s) break; @@ -121,26 +127,34 @@ static int extcon_update(const char *value) return 0; } -static int extcon_load_uevent(struct parse_result *result, void *user_data) +static void uevent_extcon_handler(struct udev_device *dev) { - struct extcon_ops *dev; - int val; + const char *env_value; + int ret; + env_value = udev_device_get_property_value(dev, STATE_NAME); + if (!env_value) + return; + + ret = extcon_parsing_value(env_value); + if (ret < 0) + _E("fail to parse extcon value : %d", ret); +} + +static int extcon_load_uevent(struct parse_result *result, void *user_data) +{ if (!result) return 0; if (!result->name || !result->value) return 0; - val = atoi(result->value); - dev = find_extcon(result->name); - if (dev) - extcon_changed(dev, val); + extcon_update(result->name, result->value); return 0; } -static int get_extcon_uevent_state(char *state, unsigned int len) +static int get_extcon_state_node(char *state, unsigned int len) { DIR *dir; struct dirent *entry; @@ -182,22 +196,6 @@ static int get_extcon_uevent_state(char *state, unsigned int len) return ret; } -static void uevent_extcon_handler(struct udev_device *dev) -{ - const char *env_value; - int ret; - - env_value = udev_device_get_property_value(dev, STATE_NAME); - if (!env_value) - return; - - ret = extcon_update(env_value); - if (ret < 0) - _E("fail to update extcon status : %d", ret); - - return; -} - static DBusMessage *dbus_get_extcon_status(E_DBus_Object *obj, DBusMessage *msg) { @@ -276,12 +274,12 @@ static void extcon_init(void *data) if (ret < 0) _E("fail to register extcon uevent : %d", ret); - /* load extcon uevent */ - ret = get_extcon_uevent_state(state, sizeof(state)); + /* set initialize extcon device state */ + ret = get_extcon_state_node(state, sizeof(state)); if (ret == 0) { ret = config_parse(state, extcon_load_uevent, NULL); if (ret < 0) - _E("Failed to load %s file : %d", EXTCON_PATH, ret); + _E("Failed to load %s file : %d", state, ret); } else { _E("Failed to get extcon uevent state node"); } @@ -311,7 +309,7 @@ static void extcon_exit(void *data) } } -const struct device_ops extcon_device_ops = { +static const struct device_ops extcon_device_ops = { .name = "extcon", .probe = extcon_probe, .init = extcon_init, -- 2.7.4 From 9c65213513c7bde56d04cd8cfc94794d6cdea293 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Fri, 27 Mar 2015 20:02:17 +0900 Subject: [PATCH 06/16] mmc: Enable filesystem routine MMC directory is interlaced with filesystem and mmc logic. Filesystem logic should be enable regardless of the supported devices. So I enable MMC routine first and will be separated two logics. And MMC routine works when sdcard is connected. So it does not make any overhead at present. Change-Id: I7c02968aa989df842fc8c43d92af94e92a588be1 Signed-off-by: Jiyoung Yun --- CMakeLists.txt | 14 ++++---------- packaging/deviced.spec | 6 ------ src/core/edbus-handler.c | 1 - src/mmc/mmc-handler.c | 6 ++++-- 4 files changed, 8 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d613d2f..362ff82 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,6 @@ SET(SRCS ${SRCS} src/gpio/hall.c) ENDIF(TIZEN_HALL) -IF(TIZEN_SDCARD) SET(SRCS ${SRCS} src/mmc/config.c src/mmc/mmc-handler.c @@ -83,7 +82,6 @@ SET(SRCS ${SRCS} src/mmc/ext4.c ) ENDIF(USE_EMULATOR) -ENDIF(TIZEN_SDCARD) IF(TIZEN_SIM) SET(SRCS ${SRCS} @@ -186,10 +184,8 @@ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/deviced.conf DESTINATION /etc/ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/movi_format.sh DESTINATION bin) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/usb/usb-setting.conf DESTINATION /etc/deviced) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/usb/usb-operation.conf DESTINATION /etc/deviced) -IF(TIZEN_SDCARD) - INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mmc-smack-label DESTINATION bin) - INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/fsck-msdos/LICENSE DESTINATION share/license RENAME fsck_msdosfs) -ENDIF(TIZEN_SDCARD) +INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mmc-smack-label DESTINATION bin) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/fsck-msdos/LICENSE DESTINATION share/license RENAME fsck_msdosfs) INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system FILES_MATCHING @@ -198,10 +194,8 @@ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/s ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(src/libdeviced) -IF(TIZEN_SDCARD) - ADD_SUBDIRECTORY(src/fsck-msdos) - ADD_SUBDIRECTORY(src/newfs-msdos) -ENDIF(TIZEN_SDCARD) +ADD_SUBDIRECTORY(src/fsck-msdos) +ADD_SUBDIRECTORY(src/newfs-msdos) ADD_SUBDIRECTORY(src/devicectl) ADD_SUBDIRECTORY(src/libsysman) ADD_SUBDIRECTORY(src/libslp-pm) diff --git a/packaging/deviced.spec b/packaging/deviced.spec index 5cfb87b..77e0202 100755 --- a/packaging/deviced.spec +++ b/packaging/deviced.spec @@ -7,7 +7,6 @@ %bcond_with buzzer %bcond_with extcon %bcond_with hall -%bcond_with sdcard %bcond_with sim %bcond_with usb @@ -198,9 +197,6 @@ export CFLAGS+=" -DX11_SUPPORT" %if %{with hall} -DTIZEN_HALL:BOOL=ON \ %endif -%if %{with sdcard} - -DTIZEN_SDCARD:BOOL=ON \ -%endif %if %{with sim} -DTIZEN_SIM:BOOL=ON \ %endif @@ -312,13 +308,11 @@ systemctl daemon-reload %{_bindir}/movi_format.sh %{_sysconfdir}/deviced/usb-setting.conf %{_sysconfdir}/deviced/usb-operation.conf -%if %{with sdcard} %{_bindir}/mmc-smack-label %{_bindir}/fsck_msdosfs %{_bindir}/newfs_msdos %{_datadir}/license/fsck_msdosfs %{_datadir}/license/newfs_msdos -%endif %{_unitdir}/multi-user.target.wants/deviced.service %{_unitdir}/sockets.target.wants/deviced.socket %{_unitdir}/graphical.target.wants/zbooting-done.service diff --git a/src/core/edbus-handler.c b/src/core/edbus-handler.c index 78038f1..a06dc5a 100644 --- a/src/core/edbus-handler.c +++ b/src/core/edbus-handler.c @@ -50,7 +50,6 @@ static struct edbus_object { { DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY, NULL, NULL }, { DEVICED_PATH_POWER , DEVICED_INTERFACE_POWER , NULL, NULL }, { DEVICED_PATH_STORAGE, DEVICED_INTERFACE_STORAGE, NULL, NULL }, - { DEVICED_PATH_MMC , DEVICED_INTERFACE_MMC , NULL, NULL }, { DEVICED_PATH_PROCESS, DEVICED_INTERFACE_PROCESS, NULL, NULL }, { DEVICED_PATH_KEY , DEVICED_INTERFACE_KEY , NULL, NULL }, { DEVICED_PATH_CPU , DEVICED_INTERFACE_CPU , NULL, NULL }, diff --git a/src/mmc/mmc-handler.c b/src/mmc/mmc-handler.c index 7827e55..cd32ee8 100644 --- a/src/mmc/mmc-handler.c +++ b/src/mmc/mmc-handler.c @@ -927,9 +927,11 @@ static void mmc_init(void *data) int ret; mmc_load_config(); - ret = register_edbus_method(DEVICED_PATH_MMC, edbus_methods, ARRAY_SIZE(edbus_methods)); + ret = register_edbus_interface_and_method(DEVICED_PATH_MMC, + DEVICED_INTERFACE_MMC, + edbus_methods, ARRAY_SIZE(edbus_methods)); if (ret < 0) - _E("fail to init edbus method(%d)", ret); + _E("fail to init edbus interface and method(%d)", ret); /* register mmc uevent control routine */ ret = mmc_uevent_start(); -- 2.7.4 From 26bcb8ac2895ef02a8c7c1fea93e3b7c4ec2bc42 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Thu, 26 Mar 2015 21:29:15 +0900 Subject: [PATCH 07/16] usb-host: Add usb host logic When usb host device is added or removed, deviced receives the usb uevent and control internal usb host list. Usb host device must have at least one interface. And an interface is matched with a specific usb class. Change-Id: Ib0164daa4b7649820146092f2f04e814f5cef4ca Signed-off-by: Jiyoung Yun --- CMakeLists.txt | 1 + src/core/udev.h | 4 + src/usb/usb-host.c | 253 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+) create mode 100644 src/usb/usb-host.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 362ff82..08d5d7d 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ SET(SRCS SET(SRCS ${SRCS} src/usb/usb.c src/usb/usb-default.c + src/usb/usb-host.c ) IF(TIZEN_BUZZER) diff --git a/src/core/udev.h b/src/core/udev.h index ab231b4..f867026 100644 --- a/src/core/udev.h +++ b/src/core/udev.h @@ -64,6 +64,10 @@ /* host device */ #define HOST_SUBSYSTEM "host_notify" +/* usb */ +#define USB_SUBSYSTEM "usb" +#define USB_INTERFACE_DEVTYPE "usb_interface" + /* power supply status */ enum { POWER_SUPPLY_STATUS_UNKNOWN = 0, diff --git a/src/usb/usb-host.c b/src/usb/usb-host.c new file mode 100644 index 0000000..8831b60 --- /dev/null +++ b/src/usb/usb-host.c @@ -0,0 +1,253 @@ +/* + * deviced + * + * Copyright (c) 2015 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 +#include + +#include "core/log.h" +#include "core/devices.h" +#include "core/udev.h" +#include "core/list.h" + +#define USB_INTERFACE_CLASS "bInterfaceClass" +#define USB_INTERFACE_SUBCLASS "bInterfaceSubClass" +#define USB_INTERFACE_PROTOCOL "bInterfaceProtocol" +#define USB_VENDOR_ID "idVendor" +#define USB_PRODUCT_ID "idProduct" +#define USB_MANUFACTURER "manufacturer" +#define USB_PRODUCT "product" +#define USB_SERIAL "serial" + +struct usbhost_device { + char devpath[PATH_MAX]; /* unique info. */ + int baseclass; + int subclass; + int protocol; + int vendorid; + int productid; + char *manufacturer; + char *product; + char *serial; +}; + +static dd_list *usbhost_list; + +static void print_usbhost(struct usbhost_device *usbhost) +{ + if (!usbhost) + return; + + _I("devpath : %s", usbhost->devpath); + _I("interface baseclass : %xh", usbhost->baseclass); + _I("interface subclass : %xh", usbhost->subclass); + _I("interface protocol : %xh", usbhost->protocol); + _I("vendor id : %xh", usbhost->vendorid); + _I("product id : %xh", usbhost->productid); + _I("manufacturer : %s", usbhost->manufacturer); + _I("product : %s", usbhost->product); + _I("serial : %s", usbhost->serial); +} + +static int add_usbhost_list(struct udev_device *dev, const char *devpath) +{ + struct usbhost_device *usbhost; + const char *str; + struct udev_device *parent; + + /* allocate new usbhost device */ + usbhost = calloc(1, sizeof(struct usbhost_device)); + if (!usbhost) { + _E("fail to allocate usbhost memory : %s", strerror(errno)); + return -errno; + } + + /* save the devnode */ + snprintf(usbhost->devpath, sizeof(usbhost->devpath), + "%s", devpath); + + /* get usb interface informations */ + str = udev_device_get_sysattr_value(dev, USB_INTERFACE_CLASS); + if (str) + usbhost->baseclass = (int)strtol(str, NULL, 16); + str = udev_device_get_sysattr_value(dev, USB_INTERFACE_SUBCLASS); + if (str) + usbhost->subclass = (int)strtol(str, NULL, 16); + str = udev_device_get_sysattr_value(dev, USB_INTERFACE_PROTOCOL); + if (str) + usbhost->protocol = (int)strtol(str, NULL, 16); + + /* parent has a lot of information about usb_interface */ + parent = udev_device_get_parent(dev); + if (!parent) { + _E("fail to get parent"); + free(usbhost); + return -EPERM; + } + + /* get usb device informations */ + str = udev_device_get_sysattr_value(parent, USB_VENDOR_ID); + if (str) + usbhost->vendorid = (int)strtol(str, NULL, 16); + str = udev_device_get_sysattr_value(parent, USB_PRODUCT_ID); + if (str) + usbhost->productid = (int)strtol(str, NULL, 16); + str = udev_device_get_sysattr_value(parent, USB_MANUFACTURER); + if (str) + usbhost->manufacturer = strdup(str); + str = udev_device_get_sysattr_value(parent, USB_PRODUCT); + if (str) + usbhost->product = strdup(str); + str = udev_device_get_sysattr_value(parent, USB_SERIAL); + if (str) + usbhost->serial = strdup(str); + + DD_LIST_APPEND(usbhost_list, usbhost); + + /* for debugging */ + _I("USB HOST Added"); + print_usbhost(usbhost); + + return 0; +} + +static int remove_usbhost_list(const char *devpath) +{ + struct usbhost_device *usbhost; + dd_list *n, *next; + + /* find the matched item */ + DD_LIST_FOREACH_SAFE(usbhost_list, n, next, usbhost) { + if (!strncmp(usbhost->devpath, + devpath, sizeof(usbhost->devpath))) + break; + } + + if (!usbhost) { + _E("fail to find the matched usbhost device"); + return -ENODEV; + } + + /* for debugging */ + _I("USB HOST Removed"); + _I("devpath : %s", usbhost->devpath); + + DD_LIST_REMOVE(usbhost_list, usbhost); + free(usbhost->manufacturer); + free(usbhost->product); + free(usbhost->serial); + free(usbhost); + + return 0; +} + +static void remove_all_usbhost_list(void) +{ + struct usbhost_device *usbhost; + dd_list *n, *next; + + DD_LIST_FOREACH_SAFE(usbhost_list, n, next, usbhost) { + + /* for debugging */ + _I("USB HOST Removed"); + _I("devpath : %s", usbhost->devpath); + + DD_LIST_REMOVE(usbhost_list, usbhost); + free(usbhost->manufacturer); + free(usbhost->product); + free(usbhost->serial); + free(usbhost); + } +} + +static void uevent_usbhost_handler(struct udev_device *dev) +{ + const char *subsystem; + const char *devtype; + const char *devpath; + const char *action; + + /** + * Usb host device must have at least one interface. + * An interface is matched with a specific usb class. + */ + subsystem = udev_device_get_subsystem(dev); + devtype = udev_device_get_devtype(dev); + if (!subsystem || !devtype) { + _E("fail to get subsystem or devtype"); + return; + } + + /* devpath is an unique information among usb host devices */ + devpath = udev_device_get_devpath(dev); + if (!devpath) { + _E("fail to get devpath from udev_device"); + return; + } + + /** + * if devtype is not matched with usb subsystem + * and usb_interface devtype, skip. + */ + _I("subsystem : %s, devtype : %s", subsystem, devtype); + if (strncmp(subsystem, USB_SUBSYSTEM, sizeof(USB_SUBSYSTEM)) || + strncmp(devtype, USB_INTERFACE_DEVTYPE, sizeof(USB_INTERFACE_DEVTYPE))) + return; + + action = udev_device_get_action(dev); + if (!strncmp(action, UDEV_ADD, sizeof(UDEV_ADD))) + add_usbhost_list(dev, devpath); + else if (!strncmp(action, UDEV_REMOVE, sizeof(UDEV_REMOVE))) + remove_usbhost_list(devpath); +} + +static struct uevent_handler uh = { + .subsystem = USB_SUBSYSTEM, + .uevent_func = uevent_usbhost_handler, +}; + +static void usbhost_init(void *data) +{ + int ret; + + /* register usbhost uevent */ + ret = register_kernel_uevent_control(&uh); + if (ret < 0) + _E("fail to register usb uevent : %d", ret); +} + +static void usbhost_exit(void *data) +{ + int ret; + + /* unreigset usbhost uevent */ + ret = unregister_kernel_uevent_control(&uh); + if (ret < 0) + _E("fail to unregister usb uevent : %d", ret); + + /* remove all usbhost list */ + remove_all_usbhost_list(); +} + +static const struct device_ops usbhost_device_ops = { + .name = "usbhost", + .init = usbhost_init, + .exit = usbhost_exit, +}; + +DEVICE_OPS_REGISTER(&usbhost_device_ops) -- 2.7.4 From 2346b181629e9d8c4dd0c574030c02d594634714 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Fri, 27 Mar 2015 17:36:53 +0900 Subject: [PATCH 08/16] usb-host: Add dbus method to provide the current device list and count Added dbus method: GetDeviceList("i") - "i" : baseclass - Return whole device information about the matching baseclass. GetDeviceListCount("i") - "i" : baseclass - Return device count about the matching baseclass. PrintDeviceList - Print out whole device information for debugging Change-Id: Iebf51ec81d30b431e384cd2e57a0c1fc3ca2b1cb Signed-off-by: Jiyoung Yun --- src/core/edbus-handler.c | 1 - src/usb/usb-host.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 1 deletion(-) diff --git a/src/core/edbus-handler.c b/src/core/edbus-handler.c index a06dc5a..f873b96 100644 --- a/src/core/edbus-handler.c +++ b/src/core/edbus-handler.c @@ -55,7 +55,6 @@ static struct edbus_object { { DEVICED_PATH_CPU , DEVICED_INTERFACE_CPU , NULL, NULL }, { DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI, NULL, NULL }, { DEVICED_PATH_USB , DEVICED_INTERFACE_USB , NULL, NULL }, - { DEVICED_PATH_USBHOST, DEVICED_INTERFACE_USBHOST, NULL, NULL }, { DEVICED_PATH_GPIO, DEVICED_INTERFACE_GPIO, NULL, NULL}, { DEVICED_PATH_HDMICEC, DEVICED_INTERFACE_HDMICEC, NULL, NULL}, /* Add new object & interface here*/ diff --git a/src/usb/usb-host.c b/src/usb/usb-host.c index 8831b60..2e88398 100644 --- a/src/usb/usb-host.c +++ b/src/usb/usb-host.c @@ -22,6 +22,7 @@ #include "core/log.h" #include "core/devices.h" +#include "core/edbus-handler.h" #include "core/udev.h" #include "core/list.h" @@ -34,6 +35,29 @@ #define USB_PRODUCT "product" #define USB_SERIAL "serial" +/** + * Below usb host class is defined by www.usb.org. + * Please refer to below site. + * http://www.usb.org/developers/defined_class + * You can find the detail class codes in linux/usb/ch9.h. + * Deviced uses kernel defines. + */ +#include +#define USB_CLASS_ALL 0xffffffff + +/** + * HID Standard protocol information. + * Please refer to below site. + * http://www.usb.org/developers/hidpage/HID1_11.pdf + * Below protocol only has meaning + * if the subclass is a boot interface subclass, + * otherwise it is 0. + */ +enum usbhost_hid_protocol { + USB_HOST_HID_KEYBOARD = 1, + USB_HOST_HID_MOUSE = 2, +}; + struct usbhost_device { char devpath[PATH_MAX]; /* unique info. */ int baseclass; @@ -216,11 +240,109 @@ static void uevent_usbhost_handler(struct udev_device *dev) remove_usbhost_list(devpath); } +static DBusMessage *print_device_list(E_DBus_Object *obj, DBusMessage *msg) +{ + dd_list *elem; + struct usbhost_device *usbhost; + int cnt = 0; + + DD_LIST_FOREACH(usbhost_list, elem, usbhost) { + _I("== [%2d USB HOST DEVICE] ===============", cnt++); + print_usbhost(usbhost); + } + + return dbus_message_new_method_return(msg); +} + +static DBusMessage *get_device_list(E_DBus_Object *obj, DBusMessage *msg) +{ + DBusMessageIter iter; + DBusMessageIter arr; + DBusMessageIter s; + DBusMessage *reply; + dd_list *elem; + struct usbhost_device *usbhost; + const char *str; + int baseclass; + + reply = dbus_message_new_method_return(msg); + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &baseclass, DBUS_TYPE_INVALID)) { + _E("there is no message"); + goto out; + } + + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_open_container(&iter, + DBUS_TYPE_ARRAY, "(siiiiisss)", &arr); + + DD_LIST_FOREACH(usbhost_list, elem, usbhost) { + if (baseclass != USB_CLASS_ALL && usbhost->baseclass != baseclass) + continue; + dbus_message_iter_open_container(&arr, DBUS_TYPE_STRUCT, NULL, &s); + str = usbhost->devpath; + dbus_message_iter_append_basic(&s, DBUS_TYPE_STRING, &str); + dbus_message_iter_append_basic(&s, + DBUS_TYPE_INT32, &usbhost->baseclass); + dbus_message_iter_append_basic(&s, + DBUS_TYPE_INT32, &usbhost->subclass); + dbus_message_iter_append_basic(&s, + DBUS_TYPE_INT32, &usbhost->protocol); + dbus_message_iter_append_basic(&s, + DBUS_TYPE_INT32, &usbhost->vendorid); + dbus_message_iter_append_basic(&s, + DBUS_TYPE_INT32, &usbhost->productid); + dbus_message_iter_append_basic(&s, + DBUS_TYPE_STRING, &usbhost->manufacturer); + dbus_message_iter_append_basic(&s, + DBUS_TYPE_STRING, &usbhost->product); + dbus_message_iter_append_basic(&s, + DBUS_TYPE_STRING, &usbhost->serial); + dbus_message_iter_close_container(&arr, &s); + } + + dbus_message_iter_close_container(&iter, &arr); + +out: + return reply; +} + +static DBusMessage *get_device_list_count(E_DBus_Object *obj, DBusMessage *msg) +{ + dd_list *elem; + struct usbhost_device *usbhost; + int baseclass; + int ret = 0; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &baseclass, DBUS_TYPE_INVALID)) { + _E("there is no message"); + ret = -EINVAL; + goto out; + } + + DD_LIST_FOREACH(usbhost_list, elem, usbhost) { + if (baseclass != USB_CLASS_ALL && usbhost->baseclass != baseclass) + continue; + ret++; + } + +out: + return make_reply_message(msg, ret); +} + static struct uevent_handler uh = { .subsystem = USB_SUBSYSTEM, .uevent_func = uevent_usbhost_handler, }; +static const struct edbus_method edbus_methods[] = { + { "PrintDeviceList", NULL, NULL, print_device_list }, /* for debugging */ + { "GetDeviceList", "i", "a(siiiiisss)", get_device_list }, + { "GetDeviceListCount", "i", "i", get_device_list_count }, +}; + static void usbhost_init(void *data) { int ret; @@ -229,6 +351,13 @@ static void usbhost_init(void *data) ret = register_kernel_uevent_control(&uh); if (ret < 0) _E("fail to register usb uevent : %d", ret); + + /* register usbhost interface and method */ + ret = register_edbus_interface_and_method(DEVICED_PATH_USBHOST, + DEVICED_INTERFACE_USBHOST, + edbus_methods, ARRAY_SIZE(edbus_methods)); + if (ret < 0) + _E("fail to register edbus interface and method! %d", ret); } static void usbhost_exit(void *data) -- 2.7.4 From 6402c5d62c03445f683ffb71b670fbc0f54f8176 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Fri, 27 Mar 2015 19:47:49 +0900 Subject: [PATCH 09/16] usb-host: Add ChangedDevice signal Whenever usb host devices are connected and disconnected, ChangedDevice signal will broacast with whole information about the device. Added signal: ChangedDevice("isiiiiisss") - int32 : Usbhost state(0:remove, 1:add) - The order of other signatures are the same with that of dbus method. (devpath, baseclass, subclass, protocol, vendorid, productid, manufacturer, product, serial) Change-Id: I23002f1a0766584b49bc9dd4c4c42ea5bde5a002 Signed-off-by: Jiyoung Yun --- src/usb/usb-host.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/usb/usb-host.c b/src/usb/usb-host.c index 2e88398..51e6bd5 100644 --- a/src/usb/usb-host.c +++ b/src/usb/usb-host.c @@ -35,6 +35,8 @@ #define USB_PRODUCT "product" #define USB_SERIAL "serial" +#define SIGNAL_USB_HOST_CHANGED "ChangedDevice" + /** * Below usb host class is defined by www.usb.org. * Please refer to below site. @@ -58,6 +60,11 @@ enum usbhost_hid_protocol { USB_HOST_HID_MOUSE = 2, }; +enum usbhost_state { + USB_HOST_REMOVED, + USB_HOST_ADDED, +}; + struct usbhost_device { char devpath[PATH_MAX]; /* unique info. */ int baseclass; @@ -88,6 +95,49 @@ static void print_usbhost(struct usbhost_device *usbhost) _I("serial : %s", usbhost->serial); } +static void broadcast_usbhost_signal(enum usbhost_state state, + struct usbhost_device *usbhost) +{ + char *arr[10]; + char str_state[32]; + char str_baseclass[32]; + char str_subclass[32]; + char str_protocol[32]; + char str_vendorid[32]; + char str_productid[32]; + + if (!usbhost) + return; + + snprintf(str_state, sizeof(str_state), "%d", state); + arr[0] = str_state; + /* devpath is always valid */ + arr[1] = usbhost->devpath; + snprintf(str_baseclass, sizeof(str_baseclass), + "%d", usbhost->baseclass); + arr[2] = str_baseclass; + snprintf(str_subclass, sizeof(str_subclass), + "%d", usbhost->subclass); + arr[3] = str_subclass; + snprintf(str_protocol, sizeof(str_protocol), + "%d", usbhost->protocol); + arr[4] = str_protocol; + snprintf(str_vendorid, sizeof(str_vendorid), + "%d", usbhost->vendorid); + arr[5] = str_vendorid; + snprintf(str_productid, sizeof(str_productid), + "%d", usbhost->productid); + arr[6] = str_productid; + arr[7] = (!usbhost->manufacturer ? "" : usbhost->manufacturer); + arr[8] = (!usbhost->product ? "" : usbhost->product); + arr[9] = (!usbhost->serial ? "" : usbhost->serial); + + broadcast_edbus_signal(DEVICED_PATH_USBHOST, + DEVICED_INTERFACE_USBHOST, + SIGNAL_USB_HOST_CHANGED, + "isiiiiisss", arr); +} + static int add_usbhost_list(struct udev_device *dev, const char *devpath) { struct usbhost_device *usbhost; @@ -143,6 +193,8 @@ static int add_usbhost_list(struct udev_device *dev, const char *devpath) DD_LIST_APPEND(usbhost_list, usbhost); + broadcast_usbhost_signal(USB_HOST_ADDED, usbhost); + /* for debugging */ _I("USB HOST Added"); print_usbhost(usbhost); @@ -167,6 +219,8 @@ static int remove_usbhost_list(const char *devpath) return -ENODEV; } + broadcast_usbhost_signal(USB_HOST_REMOVED, usbhost); + /* for debugging */ _I("USB HOST Removed"); _I("devpath : %s", usbhost->devpath); -- 2.7.4 From a14df282ac6497762dac298d9a272a9d38b35fc5 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Mon, 30 Mar 2015 17:23:05 +0900 Subject: [PATCH 10/16] usb-host: Add the attached usb host device on booting time When usb host devices are connected before boot, it will add usb host list automatically by udev enumerate. Change-Id: I9d0c56405d3c31a8921f0cd724722381110169cf Signed-off-by: Jiyoung Yun --- src/core/udev.h | 1 + src/usb/usb-host.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/src/core/udev.h b/src/core/udev.h index f867026..45680a5 100644 --- a/src/core/udev.h +++ b/src/core/udev.h @@ -31,6 +31,7 @@ #define UDEV_REMOVE "remove" #define UDEV_DEVPATH "DEVPATH" +#define UDEV_DEVTYPE "DEVTYPE" #define UDEV_MONITOR_SIZE (10*1024) #define UDEV_MONITOR_SIZE_LARGE (128*1024*1024) diff --git a/src/usb/usb-host.c b/src/usb/usb-host.c index 51e6bd5..54a5ea0 100644 --- a/src/usb/usb-host.c +++ b/src/usb/usb-host.c @@ -23,6 +23,7 @@ #include "core/log.h" #include "core/devices.h" #include "core/edbus-handler.h" +#include "core/device-notifier.h" #include "core/udev.h" #include "core/list.h" @@ -294,6 +295,63 @@ static void uevent_usbhost_handler(struct udev_device *dev) remove_usbhost_list(devpath); } +static int usbhost_init_from_udev_enumerate(void) +{ + struct udev *udev; + struct udev_enumerate *enumerate; + struct udev_list_entry *list_entry; + struct udev_device *dev; + const char *syspath; + const char *devpath; + int ret; + + udev = udev_new(); + if (!udev) { + _E("fail to create udev library context"); + return -EPERM; + } + + /* create a list of the devices in the 'usb' subsystem */ + enumerate = udev_enumerate_new(udev); + if (!enumerate) { + _E("fail to create an enumeration context"); + return -EPERM; + } + + udev_enumerate_add_match_subsystem(enumerate, USB_SUBSYSTEM); + udev_enumerate_add_match_property(enumerate, + UDEV_DEVTYPE, USB_INTERFACE_DEVTYPE); + udev_enumerate_scan_devices(enumerate); + + udev_list_entry_foreach(list_entry, + udev_enumerate_get_list_entry(enumerate)) { + syspath = udev_list_entry_get_name(list_entry); + if (!syspath) + continue; + + dev = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate), + syspath); + if (!dev) + continue; + + /* devpath is an unique information among usb host devices */ + devpath = udev_device_get_devpath(dev); + if (!devpath) { + _E("fail to get devpath from %s device", syspath); + continue; + } + + /* add usbhost list */ + add_usbhost_list(dev, devpath); + + udev_device_unref(dev); + } + + udev_enumerate_unref(enumerate); + udev_unref(udev); + return 0; +} + static DBusMessage *print_device_list(E_DBus_Object *obj, DBusMessage *msg) { dd_list *elem; @@ -397,6 +455,21 @@ static const struct edbus_method edbus_methods[] = { { "GetDeviceListCount", "i", "i", get_device_list_count }, }; +static int booting_done(void *data) +{ + /** + * To search the attched usb host device is not an argent task. + * So deviced does not load while booting time. + * After booting task is done, it tries to find the attached devices. + */ + usbhost_init_from_udev_enumerate(); + + /* unregister booting done notifier */ + unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done); + + return 0; +} + static void usbhost_init(void *data) { int ret; @@ -412,6 +485,9 @@ static void usbhost_init(void *data) edbus_methods, ARRAY_SIZE(edbus_methods)); if (ret < 0) _E("fail to register edbus interface and method! %d", ret); + + /* register notifier */ + register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done); } static void usbhost_exit(void *data) -- 2.7.4 From c309ff9f6198e5df78b0a536eff4dc6f94dbf404 Mon Sep 17 00:00:00 2001 From: Maciej Wereski Date: Mon, 30 Mar 2015 16:45:49 +0200 Subject: [PATCH 11/16] Get rid of unnecesary dbus-glib dependency None of dbus-glib functions were used in libdeviced. Besides dbus-glib is deprecated. Change-Id: I6ea986bc3548b36390493050078edacb26a7cb7f Signed-off-by: Maciej Wereski --- packaging/deviced.spec | 2 +- src/libdeviced/CMakeLists.txt | 1 - src/libdeviced/dbus.c | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packaging/deviced.spec b/packaging/deviced.spec index 77e0202..17aa10e 100755 --- a/packaging/deviced.spec +++ b/packaging/deviced.spec @@ -42,7 +42,7 @@ BuildRequires: pkgconfig(sensor) BuildRequires: gettext BuildRequires: pkgconfig(libsystemd-daemon) BuildRequires: pkgconfig(capi-base-common) -BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(dbus-1) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(notification) BuildRequires: pkgconfig(hwcommon) diff --git a/src/libdeviced/CMakeLists.txt b/src/libdeviced/CMakeLists.txt index 17de698..71e13b0 100755 --- a/src/libdeviced/CMakeLists.txt +++ b/src/libdeviced/CMakeLists.txt @@ -23,7 +23,6 @@ pkg_check_modules(libpkgs REQUIRED vconf dlog dbus-1 - dbus-glib-1 edbus) FOREACH(flag ${libpkgs_CFLAGS}) diff --git a/src/libdeviced/dbus.c b/src/libdeviced/dbus.c index b204635..d62e8fc 100644 --- a/src/libdeviced/dbus.c +++ b/src/libdeviced/dbus.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include "common.h" #include "log.h" -- 2.7.4 From a679c3df3d0f979c9dc56c3b46909145b21ccef8 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Mon, 30 Mar 2015 21:50:25 +0900 Subject: [PATCH 12/16] usb-host: Fix dbus segfault issue on GetDeviceList method call dbus_message_iter_append_basic() makes segfault when string is NULL. So the null is changed to "" string. Change-Id: I1afe2971d2c3ca7221c40c1e67959531de60e86b Signed-off-by: Jiyoung Yun --- src/usb/usb-host.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/usb/usb-host.c b/src/usb/usb-host.c index 54a5ea0..201db1f 100644 --- a/src/usb/usb-host.c +++ b/src/usb/usb-host.c @@ -405,12 +405,12 @@ static DBusMessage *get_device_list(E_DBus_Object *obj, DBusMessage *msg) DBUS_TYPE_INT32, &usbhost->vendorid); dbus_message_iter_append_basic(&s, DBUS_TYPE_INT32, &usbhost->productid); - dbus_message_iter_append_basic(&s, - DBUS_TYPE_STRING, &usbhost->manufacturer); - dbus_message_iter_append_basic(&s, - DBUS_TYPE_STRING, &usbhost->product); - dbus_message_iter_append_basic(&s, - DBUS_TYPE_STRING, &usbhost->serial); + str = (!usbhost->manufacturer ? "" : usbhost->manufacturer); + dbus_message_iter_append_basic(&s, DBUS_TYPE_STRING, &str); + str = (!usbhost->product ? "" : usbhost->product); + dbus_message_iter_append_basic(&s, DBUS_TYPE_STRING, &str); + str = (!usbhost->serial ? "" : usbhost->serial); + dbus_message_iter_append_basic(&s, DBUS_TYPE_STRING, &str); dbus_message_iter_close_container(&arr, &s); } -- 2.7.4 From ea151b68d5920d95f2fb95903e125f20cb4bcdf8 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Wed, 25 Mar 2015 21:03:04 +0900 Subject: [PATCH 13/16] extcon: Add extcon test module on devicectl To test extcon devices, devicectl supports to enable/disable device manually. commands: devicectl extcon enable [MODULE NAME] devicectl extcon disable [MODULE NAME] Change-Id: I7f032aee5eb5415380a3dc040e4b13bd9a85af74 Signed-off-by: Jiyoung Yun --- src/devicectl/devicectl.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/extcon/extcon.c | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/src/devicectl/devicectl.c b/src/devicectl/devicectl.c index 18f195f..72dda40 100644 --- a/src/devicectl/devicectl.c +++ b/src/devicectl/devicectl.c @@ -37,6 +37,7 @@ enum device_type { DEVICE_LED, DEVICE_PASS, DEVICE_USB, + DEVICE_EXTCON, DEVICE_MAX, DEVICE_ALL, }; @@ -53,6 +54,7 @@ static const struct device { { DEVICE_LED, "led", DEVICED_PATH_LED, DEVICED_INTERFACE_LED }, { DEVICE_PASS, "pass", DEVICED_PATH_PASS, DEVICED_INTERFACE_PASS }, { DEVICE_USB, "usb", DEVICED_PATH_USB, DEVICED_INTERFACE_USB }, + { DEVICE_EXTCON, "extcon", DEVICED_PATH_EXTCON, DEVICED_INTERFACE_EXTCON }, }; static int start_device(char **args) @@ -157,6 +159,48 @@ static int unset_usb_mode(char **args) return unload_usb_mode(args[3]); } +static int enable_device(char **args) +{ + DBusMessage *msg; + char *arr[1]; + + if (!args[3]) + return -EINVAL; + + printf("enable %s device!\n", args[3]); + + arr[0] = args[3]; + + msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME, + devices[arg_id].path, devices[arg_id].iface, + "enable", "s", arr); + if (!msg) + return -EBADMSG; + + dbus_message_unref(msg); +} + +static int disable_device(char **args) +{ + DBusMessage *msg; + char *arr[1]; + + if (!args[3]) + return -EINVAL; + + printf("disable %s device!\n", args[3]); + + arr[0] = args[3]; + + msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME, + devices[arg_id].path, devices[arg_id].iface, + "disable", "s", arr); + if (!msg) + return -EBADMSG; + + dbus_message_unref(msg); +} + static const struct action { const enum device_type id; const char *action; @@ -171,6 +215,8 @@ static const struct action { { DEVICE_DISPLAY, "savelog", 3, save_log, "" }, { DEVICE_USB, "set", 4, set_usb_mode, "[sdb|ssh]" }, { DEVICE_USB, "unset", 4, unset_usb_mode, "[sdb|ssh]" }, + { DEVICE_EXTCON, "enable", 4, enable_device, "[USB|HEADPHONE|HDMI|DOCK]" }, + { DEVICE_EXTCON, "disable", 4, disable_device, "[USB|HEADPHONE|HDMI|DOCK]" }, }; static inline void usage() diff --git a/src/extcon/extcon.c b/src/extcon/extcon.c index 8d5479f..c31db41 100755 --- a/src/extcon/extcon.c +++ b/src/extcon/extcon.c @@ -229,6 +229,42 @@ error: return make_reply_message(msg, ret); } +static DBusMessage *dbus_enable_device(E_DBus_Object *obj, DBusMessage *msg) +{ + char *device; + int ret; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &device, DBUS_TYPE_INVALID)) { + _E("there is no message"); + ret = -EINVAL; + goto out; + } + + ret = extcon_update(device, "1"); + +out: + return make_reply_message(msg, ret); +} + +static DBusMessage *dbus_disable_device(E_DBus_Object *obj, DBusMessage *msg) +{ + char *device; + int ret; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &device, DBUS_TYPE_INVALID)) { + _E("there is no message"); + ret = -EINVAL; + goto out; + } + + ret = extcon_update(device, "0"); + +out: + return make_reply_message(msg, ret); +} + static int extcon_probe(void *data) { /** @@ -250,7 +286,9 @@ static struct uevent_handler uh = { }; static const struct edbus_method edbus_methods[] = { - { "GetStatus", "s", "i", dbus_get_extcon_status }, + { "GetStatus", "s", "i", dbus_get_extcon_status }, + { "enable", "s", NULL, dbus_enable_device }, /* for devicectl */ + { "disable", "s", NULL, dbus_disable_device }, /* for devicectl */ }; static void extcon_init(void *data) -- 2.7.4 From d6ae77d2139a494b89531d73e3e06af7dc2c272e Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Tue, 31 Mar 2015 17:11:53 +0900 Subject: [PATCH 14/16] deviced: Remove unnecessary service files devicectl-start@/stop@ service files are just helper modules. It does not need to register by systemd. You can execute the devicectl binary directly. Change-Id: I24516c642d558e30e2288b36ee0b81fec0cef244 Signed-off-by: Jiyoung Yun --- packaging/deviced.spec | 4 ---- systemd/devicectl-start@.service | 7 ------- systemd/devicectl-stop@.service | 7 ------- 3 files changed, 18 deletions(-) delete mode 100644 systemd/devicectl-start@.service delete mode 100644 systemd/devicectl-stop@.service diff --git a/packaging/deviced.spec b/packaging/deviced.spec index 17aa10e..a0c5bb9 100755 --- a/packaging/deviced.spec +++ b/packaging/deviced.spec @@ -221,7 +221,6 @@ rm -rf %{buildroot} %install_service multi-user.target.wants deviced.service %install_service sockets.target.wants deviced.socket %install_service graphical.target.wants zbooting-done.service -%install_service graphical.target.wants devicectl-stop@.service %post #memory type vconf key init @@ -316,13 +315,10 @@ systemctl daemon-reload %{_unitdir}/multi-user.target.wants/deviced.service %{_unitdir}/sockets.target.wants/deviced.socket %{_unitdir}/graphical.target.wants/zbooting-done.service -%{_unitdir}/graphical.target.wants/devicectl-stop@.service %{_unitdir}/deviced.service %{_unitdir}/deviced.socket %{_unitdir}/deviced-pre.service %{_unitdir}/zbooting-done.service -%{_unitdir}/devicectl-start@.service -%{_unitdir}/devicectl-stop@.service %files -n libdeviced %defattr(-,root,root,-) diff --git a/systemd/devicectl-start@.service b/systemd/devicectl-start@.service deleted file mode 100644 index 3322274..0000000 --- a/systemd/devicectl-start@.service +++ /dev/null @@ -1,7 +0,0 @@ -[Unit] -Description=Device Control Start %I -DefaultDependencies=no - -[Service] -Type=oneshot -ExecStart=/usr/bin/devicectl %I start diff --git a/systemd/devicectl-stop@.service b/systemd/devicectl-stop@.service deleted file mode 100644 index c242e72..0000000 --- a/systemd/devicectl-stop@.service +++ /dev/null @@ -1,7 +0,0 @@ -[Unit] -Description=Device Control Stop %I -DefaultDependencies=no - -[Service] -Type=oneshot -ExecStart=/usr/bin/devicectl %I stop -- 2.7.4 From 82773ce3186a9eb8aec2993d9107c286920e5a58 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Mon, 30 Mar 2015 19:04:02 +0900 Subject: [PATCH 15/16] deviced: Move direct_set_debug script from usb-server Usb-server is no longer used. Instead to control usb devices will be replaced by deviced. direct_set_debug script is for controlling sdb or ssh tools manually. It is a very helpful when deviced does not work normally. Change-Id: Ib0b3369677d1a1819fb5d57c5072c477e2b389f5 Signed-off-by: Jiyoung Yun --- CMakeLists.txt | 3 + packaging/deviced.spec | 1 + scripts/direct_set_debug.sh | 147 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100755 scripts/direct_set_debug.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 08d5d7d..49a76c6 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,6 +188,9 @@ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/usb/usb-operation.conf DESTINATION INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mmc-smack-label DESTINATION bin) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/fsck-msdos/LICENSE DESTINATION share/license RENAME fsck_msdosfs) +# USB (Manual setting) +INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/direct_set_debug.sh DESTINATION bin) + INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/systemd/ DESTINATION lib/systemd/system FILES_MATCHING PATTERN "*.service" diff --git a/packaging/deviced.spec b/packaging/deviced.spec index a0c5bb9..79f179f 100755 --- a/packaging/deviced.spec +++ b/packaging/deviced.spec @@ -305,6 +305,7 @@ systemctl daemon-reload %{_bindir}/deviced %{_bindir}/devicectl %{_bindir}/movi_format.sh +%{_bindir}/direct_set_debug.sh %{_sysconfdir}/deviced/usb-setting.conf %{_sysconfdir}/deviced/usb-operation.conf %{_bindir}/mmc-smack-label diff --git a/scripts/direct_set_debug.sh b/scripts/direct_set_debug.sh new file mode 100755 index 0000000..f99469d --- /dev/null +++ b/scripts/direct_set_debug.sh @@ -0,0 +1,147 @@ +#!/bin/sh + +VERSION= + +check_driver_version() { + if [ -f /sys/class/usb_mode/version ] + then + VERSION=`cat /sys/class/usb_mode/version` + else + VERSION="0.0" + fi +} + +load_usb_gadget_0_0() { + echo 4 > /sys/devices/platform/usb_mode/UsbMenuSel +} + +load_usb_gadget_1_0() { + echo 0 > /sys/class/usb_mode/usb0/enable + echo 04e8 > /sys/class/usb_mode/usb0/idVendor + echo $1 > /sys/class/usb_mode/usb0/idProduct + echo $2 > /sys/class/usb_mode/usb0/functions + echo 239 > /sys/class/usb_mode/usb0/bDeviceClass + echo 2 > /sys/class/usb_mode/usb0/bDeviceSubClass + echo 1 > /sys/class/usb_mode/usb0/bDeviceProtocol + echo 1 > /sys/class/usb_mode/usb0/enable +} + +load_usb_gadget_1_1() { + echo 0 > /sys/class/usb_mode/usb0/enable + echo 04e8 > /sys/class/usb_mode/usb0/idVendor + echo $1 > /sys/class/usb_mode/usb0/idProduct + echo " " > /sys/class/usb_mode/usb0/functions + echo $2 > /sys/class/usb_mode/usb0/funcs_fconf + echo $3 > /sys/class/usb_mode/usb0/funcs_sconf + echo 239 > /sys/class/usb_mode/usb0/bDeviceClass + echo 2 > /sys/class/usb_mode/usb0/bDeviceSubClass + echo 1 > /sys/class/usb_mode/usb0/bDeviceProtocol + echo 1 > /sys/class/usb_mode/usb0/enable +} + +unload_usb_gadget_1() { + echo 0 > /sys/class/usb_mode/usb0/enable +} + +sdb_set() { + case "$VERSION" in + "1.0") + load_usb_gadget_1_0 "6860" "mtp,acm,sdb" + ;; + "1.1") + load_usb_gadget_1_1 "6860" "mtp" "mtp,acm,sdb" + ;; + *) + echo "USB driver version $VERSION is not supported" + return + ;; + esac + + /usr/bin/systemctl start sdbd.service + echo "SDB enabled" +} + +ssh_set() { + case "$VERSION" in + "0.0") + load_usb_gadget_0_0 + ;; + "1.0") + load_usb_gadget_1_0 "6864" "rndis" + ;; + "1.1") + load_usb_gadget_1_1 "6864" "rndis" " " + ;; + *) + echo "USB driver version $VERSION is not supported" + return + ;; + esac + + /sbin/ifconfig usb0 192.168.129.3 up + /sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0 + /usr/bin/systemctl start sshd.service + echo "SSH enabled" +} + +usb_unset() { + case "$VERSION" in + "1.0" | "1.1") + unload_usb_gadget_1 + ;; + *) + echo "USB driver version $VERSION is not supported" + return + ;; + esac +} + +sdb_unset() { + usb_unset + /usr/bin/systemctl stop sdbd.service + echo "SDB disabled" +} + +ssh_unset() { + usb_unset + /sbin/ifconfig usb0 down + /usr/bin/systemctl stop sshd.service + echo "SSH disabled" +} + +show_options() { + echo "direct_set_debug.sh: usage:" + echo " --help This message" + echo " --sdb-set Load sdb without usb-manager" + echo " --sdb-unset Unload sdb without usb-manager" + echo " --ssh-set Load ssh without usb-manager" + echo " --ssh-unset Unload ssh without usb-manager" +} + +check_driver_version + +case "$1" in +"--sdb-set") + sdb_set + ;; + +"--ssh-set") + ssh_set + ;; + +"--sdb-unset") + sdb_unset + ;; + +"--ssh-unset") + ssh_unset + ;; + +"--help") + show_options + ;; + +*) + echo "Wrong parameters. Please use option --help to check options " + ;; +esac -- 2.7.4 From dc32715ebc426f7874b737b80ad301c205235324 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Tue, 31 Mar 2015 22:57:37 +0900 Subject: [PATCH 16/16] display: Use libinput to get input events Remove the exisiting input code and use libinput for getting input events It's for common use with wayland input system. Change-Id: I2de534b73250e8d1fdfccd3b02f64eb13efcb45a Signed-off-by: Seunghun Pi --- CMakeLists.txt | 3 +- packaging/deviced.spec | 1 + scripts/device-daemon.in | 53 ------- scripts/deviced-pre.sh | 3 - src/core/common.h | 3 + src/core/device-change-handler.c | 25 ---- src/core/device-notifier.h | 2 - src/core/udev.h | 4 - src/display/core.c | 89 +----------- src/display/core.h | 2 +- src/display/input.c | 213 ++++++++++++++++++++++++++++ src/display/key-filter.c | 123 ++++++++-------- src/display/poll.c | 298 ++------------------------------------- src/display/poll.h | 20 +-- 14 files changed, 293 insertions(+), 546 deletions(-) delete mode 100644 scripts/device-daemon.in create mode 100644 src/display/input.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 49a76c6..9e72a84 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,7 @@ SET(SRCS ${SRCS} src/display/lock-detector.c src/display/poll.c src/display/setting.c + src/display/input.c ) ENDIF(TIZEN_DISPLAY) @@ -134,6 +135,7 @@ SET(PKG_MODULES libtzplatform-config notification hwcommon + libinput ) IF(X11_SUPPORT) @@ -157,7 +159,6 @@ MESSAGE("FLAGS: ${CMAKE_C_FLAGS}") ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"") ADD_DEFINITIONS("-DLIBPATH=\"${LIB_INSTALL_DIR}\"") -ADD_DEFINITIONS("-DENABLE_KEY_FILTER") ADD_DEFINITIONS("-DENABLE_DEVICED_DLOG") ADD_DEFINITIONS("-DENABLE_LIBDEVICED_DLOG") ADD_DEFINITIONS("-DENABLE_PM_LOG") diff --git a/packaging/deviced.spec b/packaging/deviced.spec index 79f179f..5d851ec 100755 --- a/packaging/deviced.spec +++ b/packaging/deviced.spec @@ -46,6 +46,7 @@ BuildRequires: pkgconfig(dbus-1) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(notification) BuildRequires: pkgconfig(hwcommon) +BuildRequires: pkgconfig(libinput) %{?systemd_requires} Requires(preun): /usr/bin/systemctl diff --git a/scripts/device-daemon.in b/scripts/device-daemon.in deleted file mode 100644 index 7260d7e..0000000 --- a/scripts/device-daemon.in +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh - -KERNVER=`uname -r` - -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib -export PATH=$PATH:/usr/bin -export ELM_FONT_PATH=@PREFIX@/share/SLP/fonts:@PREFIX@/share/SLP/licensed_fonts:@PREFIX@/share/fonts/truetype/ttf-bitstream-vera -export PM_EXEC_PRG=@PREFIX@/bin/@IDLE_LOCK@ - -export PM_TO_NORMAL=600 # normal state timeout seconds -export PM_TO_LCDDIM=5 # dim state timeout seconds -export PM_TO_LCDOFF=1 # off state timeout seconds -#export PM_TO_LCDOFF=0 # prevent suspend mode - -export PM_SYS_DIMBRT=0 - -DEV_INPUT= -ABS_POSITION_X=0x15 -ABS_POSITION_Y=0x16 -for file in /sys/class/input/event*; do - if [ -e $file ]; then - dev_keytype=`cat ${file}/device/capabilities/key` - if [ "$dev_keytype" != 0 ]; then - DEV_INPUT=$DEV_INPUT:/dev/input/${file#/sys/class/input/} - continue - fi - abs_num=`cat ${file}/device/capabilities/abs | wc -w | cut -d ' ' -f 1` - if [ $abs_num != 2 ]; then - continue - fi - abs_val=`cat ${file}/device/capabilities/abs | cut -d ' ' -f 1` - if [ $(((0x$abs_val >> $ABS_POSITION_X) & 0x1)) != 1 ]; then - continue - fi - if [ $(((0x$abs_val >> $ABS_POSITION_Y) & 0x1)) != 1 ]; then - continue - fi - DEV_INPUT=$DEV_INPUT:/dev/input/${file#/sys/class/input/} - fi -done - -export PM_INPUT=$DEV_INPUT - -PMD=@PREFIX@/bin/@EXEC@ - -echo "Input Event: $PM_INPUT" -OPT_X_DPMS="-x" -echo "LCD Power: X-DPMS enabled" - -/usr/bin/system_server & - -exit 0 - diff --git a/scripts/deviced-pre.sh b/scripts/deviced-pre.sh index f714a95..0238c05 100755 --- a/scripts/deviced-pre.sh +++ b/scripts/deviced-pre.sh @@ -6,7 +6,6 @@ DEVICED_ENV_F=/run/deviced/deviced_env echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib" >> $DEVICED_ENV_F -DEV_INPUT= TOUCHSCREEN=400 TOUCHKEY=200 @@ -14,7 +13,6 @@ for file in /sys/class/input/event*; do if [ -e $file ]; then dev_keytype=`/bin/cat ${file}/device/capabilities/key` if [ "$dev_keytype" != 0 ]; then - DEV_INPUT=$DEV_INPUT:/dev/input/${file#/sys/class/input/} var=${dev_keytype%%' '*} if [ $var == $TOUCHSCREEN ]; then DEV_TOUCHSCREEN=/sys/class/input/${file#/sys/class/input/}/device/enabled @@ -31,7 +29,6 @@ for file in /sys/class/input/event*; do fi done -echo "PM_INPUT=$DEV_INPUT" >> $DEVICED_ENV_F echo "PM_TOUCHSCREEN=$DEV_TOUCHSCREEN" >> $DEVICED_ENV_F echo "PM_TOUCHKEY=$DEV_TOUCHKEY" >> $DEVICED_ENV_F echo "PM_TO_NORMAL=30000" >> $DEVICED_ENV_F diff --git a/src/core/common.h b/src/core/common.h index 9eb56be..eabb0b3 100644 --- a/src/core/common.h +++ b/src/core/common.h @@ -87,6 +87,9 @@ #ifndef SEC_TO_MSEC #define SEC_TO_MSEC(x) ((x)*1000) #endif +#ifndef MSEC_TO_USEC +#define MSEC_TO_USEC(x) ((unsigned int)(x)*1000) +#endif #ifndef NSEC_TO_MSEC #define NSEC_TO_MSEC(x) ((double)x/1000000) #endif diff --git a/src/core/device-change-handler.c b/src/core/device-change-handler.c index 794a9f9..9881dcb 100644 --- a/src/core/device-change-handler.c +++ b/src/core/device-change-handler.c @@ -54,7 +54,6 @@ #define MOVINAND_MOUNT_POINT "/opt/media" #define BUFF_MAX 255 -#define SYS_CLASS_INPUT "/sys/class/input" #define USB_STATE_PLATFORM_PATH "/sys/devices/platform/jack/usb_online" #define USB_STATE_SWITCH_PATH "/sys/devices/virtual/switch/usb_cable/state" @@ -65,13 +64,6 @@ static E_DBus_Connection *conn; #endif /* ENABLE_EDBUS_USE */ -struct input_event { - long dummy[2]; - unsigned short type; - unsigned short code; - int value; -}; - enum snd_jack_types { SND_JACK_HEADPHONE = 0x0001, SND_JACK_MICROPHONE = 0x0002, @@ -140,8 +132,6 @@ struct siop_data { static int ss_flags = 0; -static int input_device_number; - /* Uevent */ static struct udev *udev = NULL; /* Kernel Uevent */ @@ -151,7 +141,6 @@ static int ufd = -1; static int hdmi_status = 0; enum udev_subsystem_type { - UDEV_INPUT, UDEV_PLATFORM, UDEV_SWITCH, }; @@ -161,7 +150,6 @@ static const struct udev_subsystem { const char *str; const char *devtype; } udev_subsystems[] = { - { UDEV_INPUT, INPUT_SUBSYSTEM, NULL }, { UDEV_PLATFORM, PLATFORM_SUBSYSTEM, NULL }, { UDEV_SWITCH, SWITCH_SUBSYSTEM, NULL }, }; @@ -725,7 +713,6 @@ static int booting_done(void *data) _I("booting done"); /* set initial state for devices */ - input_device_number = 0; cradle_chgdet_cb(NULL); keyboard_chgdet_cb(NULL); hdmi_chgdet_cb(NULL); @@ -764,18 +751,6 @@ static Eina_Bool uevent_kernel_control_cb(void *data, Ecore_Fd_Handler *fd_handl devpath = udev_device_get_devpath(dev); switch (udev_subsystems[i].type) { - case UDEV_INPUT: - /* check new input device */ - if (!fnmatch(INPUT_PATH, devpath, 0)) { - action = udev_device_get_action(dev); - devnode = udev_device_get_devnode(dev); - if (!strcmp(action, UDEV_ADD)) - device_notify(DEVICE_NOTIFIER_INPUT_ADD, (void *)devnode); - else if (!strcmp(action, UDEV_REMOVE)) - device_notify(DEVICE_NOTIFIER_INPUT_REMOVE, (void *)devnode); - goto out; - } - break; case UDEV_SWITCH: env_name = udev_device_get_property_value(dev, "SWITCH_NAME"); env_value = udev_device_get_property_value(dev, "SWITCH_STATE"); diff --git a/src/core/device-notifier.h b/src/core/device-notifier.h index 597217a..5a4d6d4 100644 --- a/src/core/device-notifier.h +++ b/src/core/device-notifier.h @@ -28,8 +28,6 @@ enum device_notifier_type { DEVICE_NOTIFIER_TA, DEVICE_NOTIFIER_LOWBAT, DEVICE_NOTIFIER_TOUCH_HARDKEY, - DEVICE_NOTIFIER_INPUT_ADD, - DEVICE_NOTIFIER_INPUT_REMOVE, DEVICE_NOTIFIER_PROCESS_TERMINATED, DEVICE_NOTIFIER_POWER_SUPPLY, DEVICE_NOTIFIER_POWEROFF, diff --git a/src/core/udev.h b/src/core/udev.h index 45680a5..c8c846c 100644 --- a/src/core/udev.h +++ b/src/core/udev.h @@ -52,10 +52,6 @@ #define CHARGE_STATUS "POWER_SUPPLY_STATUS" #define CHARGE_ONLINE "POWER_SUPPLY_ONLINE" -/* input device */ -#define INPUT_SUBSYSTEM "input" -#define INPUT_PATH "*/input[0-9]*/event[0-9]*" - /* switch device */ #define SWITCH_SUBSYSTEM "switch" diff --git a/src/display/core.c b/src/display/core.c index c7cdd94..a4a68af 100644 --- a/src/display/core.c +++ b/src/display/core.c @@ -1313,29 +1313,6 @@ void pm_history_print(int fd, int count) } #endif -/* logging indev_list for debug */ -void print_dev_list(int fd) -{ - int i; - unsigned int total = 0; - indev *tmp; - - total = eina_list_count(indev_list); - _I("***** total list : %d *****", total); - for (i = 0; i < total; i++) { - tmp = (indev*)eina_list_nth(indev_list, i); - _I("* %d | path:%s, fd:%d, dev_fd:%d", - i, tmp->dev_path, tmp->fd, tmp->dev_fd); - if (fd >= 0) { - char buf[255]; - snprintf(buf, sizeof(buf), " %2d| path:%s, fd:%d, dev_fd:%d\n", - i, tmp->dev_path, tmp->fd, tmp->dev_fd); - write(fd, buf, strlen(buf)); - } - } - _I("***************************\n"); -} - void print_info(int fd) { int s_index = 0; @@ -1386,8 +1363,6 @@ void print_info(int fd) } } - print_dev_list(fd); - if (standby_mode) { snprintf(buf, sizeof(buf), "\n\nstandby mode is on\n"); write(fd, buf, strlen(buf)); @@ -2092,32 +2067,6 @@ static const char *errMSG[INIT_END] = { [INIT_DBUS] = "d-bus init error", }; -static int input_action(char* input_act, char* input_path) -{ - int ret = 0; - Eina_List *l = NULL; - Eina_List *l_next = NULL; - indev *data = NULL; - - if (!strcmp("add", input_act)) { - _I("add input path : %s", input_path); - ret = init_pm_poll_input(poll_callback, input_path); - } else if (!strcmp("remove", input_act)) { - EINA_LIST_FOREACH_SAFE(indev_list, l, l_next, data) - if (!strcmp(input_path, data->dev_path)) { - _I("remove %s", input_path); - ecore_main_fd_handler_del(data->dev_fd); - close(data->fd); - free(data->dev_path); - free(data); - indev_list = eina_list_remove_list(indev_list, l); - } - } else { - ret = -EINVAL; - } - return ret; -} - int set_lcd_timeout(int on, int dim, int holdkey_block, char *name) { if (on == 0 && dim == 0) { @@ -2220,30 +2169,6 @@ static int hall_ic_open(void *data) return 0; } -static int input_device_add(void *data) -{ - char *path = (char *)data; - - if (!path) - return -EINVAL; - - input_action(UDEV_ADD, path); - - return 0; -} - -static int input_device_remove(void *data) -{ - char *path = (char *)data; - - if (!path) - return -EINVAL; - - input_action(UDEV_REMOVE, path); - - return 0; -} - static int booting_done(void *data) { static bool done = false; @@ -2340,8 +2265,6 @@ static void display_init(void *data) signal(SIGHUP, sig_hup); power_saving_func = default_saving_mode; - /* noti init for new input device like bt mouse */ - indev_list = NULL; /* load configutation */ ret = config_parse(DISPLAY_CONF_FILE, display_load_config, &display_conf); @@ -2349,8 +2272,6 @@ static void display_init(void *data) _W("Failed to load %s, %d Use default value!", DISPLAY_CONF_FILE, ret); - register_notifier(DEVICE_NOTIFIER_INPUT_ADD, input_device_add); - register_notifier(DEVICE_NOTIFIER_INPUT_REMOVE, input_device_remove); register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done); register_notifier(DEVICE_NOTIFIER_HDMI, hdmi_changed); @@ -2364,8 +2285,8 @@ static void display_init(void *data) ret = init_sysfs(flags); break; case INIT_POLL: - _I("poll init"); - ret = init_pm_poll(poll_callback); + _I("input init"); + ret = init_input(poll_callback); break; case INIT_DBUS: _I("dbus init"); @@ -2442,15 +2363,11 @@ static void display_exit(void *data) exit_sysfs(); break; case INIT_POLL: - unregister_notifier(DEVICE_NOTIFIER_INPUT_ADD, - input_device_add); - unregister_notifier(DEVICE_NOTIFIER_INPUT_REMOVE, - input_device_remove); unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done); unregister_notifier(DEVICE_NOTIFIER_HDMI, hdmi_changed); - exit_pm_poll(); + exit_input(); break; } } diff --git a/src/display/core.h b/src/display/core.h index 32d99ea..2629d6e 100644 --- a/src/display/core.h +++ b/src/display/core.h @@ -145,7 +145,7 @@ extern struct display_function_info display_info; struct display_keyfilter_ops { void (*init)(void); void (*exit)(void); - int (*check)(int, char[], int); + int (*check)(void *, int); void (*set_powerkey_ignore)(int); int (*powerkey_lcdoff)(void); void (*backlight_enable)(bool); diff --git a/src/display/input.c b/src/display/input.c new file mode 100644 index 0000000..28f4de3 --- /dev/null +++ b/src/display/input.c @@ -0,0 +1,213 @@ +/* + * deviced + * + * Copyright (c) 2015 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 +#include +#include +#include +#include "util.h" +#include "core.h" +#include "poll.h" + +#define SEAT_NAME "seat0" + +static struct udev *udev; +static struct libinput *li; +static Ecore_Fd_Handler *efd; + +int (*pm_callback) (int, PMMsg *); + +static inline void process_event(struct libinput_event *ev) +{ + static const struct device_ops *display_device_ops; + struct input_event input; + struct libinput *li; + struct libinput_event_keyboard *k; + unsigned int time; + int fd; + + if (!pm_callback) + return; + + if (!display_device_ops) { + display_device_ops = find_device("display"); + if (!display_device_ops) + return; + } + + /* do not operate when display stops */ + if (device_get_status(display_device_ops) + != DEVICE_OPS_STATUS_START) { + _E("display status is stop"); + return; + } + + switch (libinput_event_get_type(ev)) { + case LIBINPUT_EVENT_KEYBOARD_KEY: + k = libinput_event_get_keyboard_event(ev); + time = libinput_event_keyboard_get_time(k); + li = libinput_event_get_context(ev); + + input.time.tv_sec = MSEC_TO_SEC(time); + input.time.tv_usec = MSEC_TO_USEC(time % 1000); + input.type = EV_KEY; + input.code = libinput_event_keyboard_get_key(k); + input.value = libinput_event_keyboard_get_key_state(k); + + fd = libinput_get_fd(li); + _D("time %d.%d type %d code %d value %d fd %d", + input.time.tv_sec, input.time.tv_usec, input.type, + input.code, input.value, fd); + + if (CHECK_OPS(keyfilter_ops, check) && + keyfilter_ops->check(&input, fd) != 0) + return; + break; + case LIBINPUT_EVENT_POINTER_MOTION: + case LIBINPUT_EVENT_POINTER_BUTTON: + case LIBINPUT_EVENT_POINTER_AXIS: + input.type = EV_REL; + if (CHECK_OPS(keyfilter_ops, check) && + keyfilter_ops->check(&input, fd) != 0) + return; + break; + case LIBINPUT_EVENT_TOUCH_DOWN: + case LIBINPUT_EVENT_TOUCH_UP: + case LIBINPUT_EVENT_TOUCH_MOTION: + case LIBINPUT_EVENT_TOUCH_FRAME: + break; + default: + break; + } + + /* lcd on or update lcd timeout */ + (*pm_callback) (INPUT_POLL_EVENT, NULL); +} + +static Eina_Bool input_handler(void *data, Ecore_Fd_Handler *fd_handler) +{ + struct libinput_event *ev; + struct libinput *li = (struct libinput *)data; + + if (!li) + return ECORE_CALLBACK_RENEW; + + libinput_dispatch(li); + + while ((ev = libinput_get_event(li))) { + process_event(ev); + + libinput_event_destroy(ev); + libinput_dispatch(li); + } + + return ECORE_CALLBACK_RENEW; +} + +static int open_restricted(const char *path, int flags, void *user_data) +{ + int fd; + unsigned int clockid = CLOCK_MONOTONIC; + + if (!path) + return -EINVAL; + + fd = open(path, flags); + if (fd >= 0) { + /* TODO Why does fd change the clock? */ + if (ioctl(fd, EVIOCSCLOCKID, &clockid) < 0) + _E("fail to change clock %s", path); + } + + return fd < 0 ? -errno : fd; +} + +static void close_restricted(int fd, void *user_data) +{ + close(fd); +} + +static const struct libinput_interface interface = { + .open_restricted = open_restricted, + .close_restricted = close_restricted, +}; + +int init_input(int (*callback)(int , PMMsg * )) +{ + int ret; + int fd; + + if (!callback) { + _E("invalid parameter : callback(NULL)"); + return -EINVAL; + } + + pm_callback = callback; + + udev = udev_new(); + if (!udev) { + _E("fail to create udev library context"); + return -EPERM; + } + + li = libinput_udev_create_context(&interface, NULL, udev); + if (!li) { + _E("fail to create a new libinput context from udev"); + return -EPERM; + } + + ret = libinput_udev_assign_seat(li, SEAT_NAME); + if (ret < 0) { + _E("fail to assign a seat"); + return -EPERM; + } + + fd = libinput_get_fd(li); + if (fd < 0) { + _E("fail to get file descriptor from libinput context"); + return -EPERM; + } + + /* add to poll handler */ + efd = ecore_main_fd_handler_add(fd, ECORE_FD_READ|ECORE_FD_ERROR, + input_handler, + (void *)((intptr_t)li), NULL, NULL); + if (!efd) { + _E("fail to add fd handler"); + /* TODO Does it really need close()? */ + close(fd); + return -EPERM; + } + + return 0; +} + +int exit_input(void) +{ + if (efd) + ecore_main_fd_handler_del(efd); + + if (li) + libinput_unref(li); + + if (udev) + udev_unref(udev); + + return 0; +} diff --git a/src/display/key-filter.c b/src/display/key-filter.c index ab3f48d..23573a1 100644 --- a/src/display/key-filter.c +++ b/src/display/key-filter.c @@ -21,10 +21,9 @@ #include #include #include - +#include #include #include - #include "util.h" #include "core.h" #include "poll.h" @@ -134,8 +133,8 @@ static void longkey_pressed() /* change state - LCD on */ recv_data.pid = getpid(); recv_data.cond = 0x100; - (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data); - (*g_pm_callback)(INPUT_POLL_EVENT, NULL); + (*pm_callback)(PM_CONTROL_EVENT, &recv_data); + (*pm_callback)(INPUT_POLL_EVENT, NULL); } if (!display_has_caps(caps, DISPLAY_CAPA_LCDOFF)) { @@ -344,7 +343,7 @@ static int lcdoff_powerkey(void) update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_POWERKEY); recv_data.pid = getpid(); recv_data.cond = 0x400; - (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data); + (*pm_callback)(PM_CONTROL_EVENT, &recv_data); } } else { ignore = false; @@ -469,7 +468,7 @@ static int process_screenlock_key(struct input_event *pinput) /* LCD off forcly */ recv_data.pid = -1; recv_data.cond = 0x400; - (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data); + (*pm_callback)(PM_CONTROL_EVENT, &recv_data); } return true; @@ -599,8 +598,6 @@ static int check_key(struct input_event *pinput, int fd) if (current_state_in_on()) { process_hardkey_backlight(pinput); ignore = false; - } else if (!check_pre_install(fd)) { - ignore = false; } break; case KEY_VOLUMEUP: @@ -641,72 +638,70 @@ static int check_key(struct input_event *pinput, int fd) return ignore; } -static int check_key_filter(int length, char buf[], int fd) +static int check_key_filter(void *data, int fd) { - struct input_event *pinput; + struct input_event *pinput = data; int ignore = true; - int idx = 0; static int old_fd, code, value; - do { - pinput = (struct input_event *)&buf[idx]; - switch (pinput->type) { - case EV_KEY: - if (pinput->code == BTN_TOUCH && - pinput->value == KEY_RELEASED) - touch_pressed = false; - /* - * Normally, touch press/release events don't occur - * in lcd off state. But touch release events can occur - * in the state abnormally. Then touch events are ignored - * when lcd is off state. - */ - if (pinput->code == BTN_TOUCH && !current_state_in_on()) - break; - if (get_standby_state() && pinput->code != KEY_POWER) { - _D("standby mode,key ignored except powerkey"); - break; - } - if (pinput->code == code && pinput->value == value) { - _E("Same key(%d, %d) is polled [%d,%d]", - code, value, old_fd, fd); - } - old_fd = fd; - code = pinput->code; - value = pinput->value; + assert(pinput); + + switch (pinput->type) { + case EV_KEY: + if (pinput->code == BTN_TOUCH && + pinput->value == KEY_RELEASED) + touch_pressed = false; + /* + * Normally, touch press/release events don't occur + * in lcd off state. But touch release events can occur + * in the state abnormally. Then touch events are ignored + * when lcd is off state. + */ + if (pinput->code == BTN_TOUCH && !current_state_in_on()) + break; + if (get_standby_state() && pinput->code != KEY_POWER) { + _D("standby mode,key ignored except powerkey"); + break; + } + if (pinput->code == code && pinput->value == value) { + _E("Same key(%d, %d) is polled [%d,%d]", + code, value, old_fd, fd); + } + old_fd = fd; + code = pinput->code; + value = pinput->value; - ignore = check_key(pinput, fd); - restore_custom_brightness(); + ignore = check_key(pinput, fd); + restore_custom_brightness(); + break; + case EV_REL: + if (get_standby_state()) break; - case EV_REL: - if (get_standby_state()) - break; - ignore = false; - break; - case EV_ABS: - if (get_standby_state()) - break; - if (current_state_in_on()) - ignore = false; - restore_custom_brightness(); - - touch_pressed = - (pinput->value == TOUCH_RELEASE ? false : true); + ignore = false; + break; + case EV_ABS: + if (get_standby_state()) break; - case EV_SW: - if (!get_glove_state || !switch_glove_key) - break; - if (pinput->code == SW_GLOVE && - get_glove_state() == GLOVE_MODE) { - switch_glove_key(pinput->value); - } + if (current_state_in_on()) + ignore = false; + restore_custom_brightness(); + + touch_pressed = + (pinput->value == TOUCH_RELEASE ? false : true); + break; + case EV_SW: + if (!get_glove_state || !switch_glove_key) break; + if (pinput->code == SW_GLOVE && + get_glove_state() == GLOVE_MODE) { + switch_glove_key(pinput->value); } - idx += sizeof(struct input_event); - if (ignore == true && length <= idx) - return 1; - } while (length > idx); + break; + } + + if (ignore) + return 1; return 0; } diff --git a/src/display/poll.c b/src/display/poll.c index 2ea191b..9052d3c 100644 --- a/src/display/poll.c +++ b/src/display/poll.c @@ -19,27 +19,12 @@ /** * @file poll.c - * @brief Power Manager poll implementation (input devices & a domain socket file) + * @brief Power Manager poll implementation * - * This file includes the input device poll implementation. - * Default input devices are /dev/event0 and /dev/event1 - * User can use "PM_INPUT" for setting another input device poll in an environment file (/etc/profile). - * (ex: PM_INPUT=/dev/event0:/dev/event1:/dev/event5 ) */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "core/device-handler.h" #include "util.h" #include "core.h" #include "poll.h" @@ -54,273 +39,6 @@ #define HOLDKEY_BLOCK_BIT (__HOLDKEY_BLOCK_BIT << LOCK_FLAG_SHIFT) #define STANDBY_MODE_BIT (__STANDBY_MODE_BIT << LOCK_FLAG_SHIFT) -#define DEV_PATH_DLM ":" - -PMMsg recv_data; -int (*g_pm_callback) (int, PMMsg *); - -#ifdef ENABLE_KEY_FILTER -extern int check_key_filter(int length, char buf[], int fd); -# define CHECK_KEY_FILTER(a, b, c) \ - do { \ - if (CHECK_OPS(keyfilter_ops, check) && \ - keyfilter_ops->check(a, b, c) != 0) \ - return EINA_TRUE;\ - } while (0); -#else -# define CHECK_KEY_FILTER(a, b, c) -#endif - -#define DEFAULT_DEV_PATH "/dev/event1:/dev/event0" - -static Eina_Bool pm_handler(void *data, Ecore_Fd_Handler *fd_handler) -{ - char buf[1024]; - struct sockaddr_un clientaddr; - int fd; - int ret; - static const struct device_ops *display_device_ops = NULL; - - if (!data) - return EINA_FALSE; - - FIND_DEVICE_INT(display_device_ops, "display"); - - if (device_get_status(display_device_ops) != DEVICE_OPS_STATUS_START) { - _E("display is not started!"); - return EINA_FALSE; - } - - if (g_pm_callback == NULL) { - return EINA_FALSE; - } - - /* A passed data is a fd type data, not a 64bit data. */ - fd = (int)((intptr_t)data); - ret = read(fd, buf, sizeof(buf)); - CHECK_KEY_FILTER(ret, buf, fd); - (*g_pm_callback) (INPUT_POLL_EVENT, NULL); - - return EINA_TRUE; -} - -int init_pm_poll(int (*pm_callback) (int, PMMsg *)) -{ - char *dev_paths, *path_tok, *pm_input_env, *save_ptr; - int dev_paths_size; - - Ecore_Fd_Handler *fd_handler; - int fd = -1; - indev *new_dev = NULL; - - g_pm_callback = pm_callback; - - _I("initialize pm poll - input devices(deviced)"); - - pm_input_env = getenv("PM_INPUT"); - if ((pm_input_env != NULL) && (strlen(pm_input_env) < 1024)) { - _I("Getting input device path from environment: %s", - pm_input_env); - /* Add 2 bytes for following strncat() */ - dev_paths_size = strlen(pm_input_env) + 2; - dev_paths = (char *)malloc(dev_paths_size); - if (!dev_paths) { - _E("Fail to malloc for dev path"); - return -ENOMEM; - } - snprintf(dev_paths, dev_paths_size, "%s", pm_input_env); - } else { - /* Add 2 bytes for following strncat() */ - dev_paths_size = strlen(DEFAULT_DEV_PATH) + 2; - dev_paths = (char *)malloc(dev_paths_size); - if (!dev_paths) { - _E("Fail to malloc for dev path"); - return -ENOMEM; - } - snprintf(dev_paths, dev_paths_size, "%s", DEFAULT_DEV_PATH); - } - - /* add the UNIX domain socket file path */ - strncat(dev_paths, DEV_PATH_DLM, strlen(DEV_PATH_DLM)); - - path_tok = strtok_r(dev_paths, DEV_PATH_DLM, &save_ptr); - if (path_tok == NULL) { - _E("Device Path Tokeninzing Failed"); - free(dev_paths); - return -1; - } - - do { - char *path, *new_path; - int len; - - fd = open(path_tok, O_RDONLY); - path = path_tok; - _I("pm_poll input device file: %s, fd: %d", path_tok, fd); - - if (fd == -1) { - _E("Cannot open the file: %s", path_tok); - goto out1; - } - - /* - * To pass a fd data through the fd hander infrastructure - * without memory allocation, a fd data becomes typecast - * to intptr_t and void *(64bit) type. - */ - fd_handler = ecore_main_fd_handler_add(fd, - ECORE_FD_READ|ECORE_FD_ERROR, - pm_handler, (void *)((intptr_t)fd), NULL, NULL); - if (fd_handler == NULL) { - _E("Failed ecore_main_handler_add() in init_pm_poll()"); - goto out2; - } - - new_dev = (indev *)malloc(sizeof(indev)); - - if (!new_dev) { - _E("Fail to malloc for new_dev %s", path); - goto out3; - } - - memset(new_dev, 0, sizeof(indev)); - - len = strlen(path) + 1; - new_path = (char*) malloc(len); - if (!new_path) { - _E("Fail to malloc for dev_path %s", path); - goto out4; - } - - strncpy(new_path, path, len); - new_dev->dev_path = new_path; - new_dev->fd = fd; - new_dev->dev_fd = fd_handler; - new_dev->pre_install = true; - indev_list = eina_list_append(indev_list, new_dev); - - } while ((path_tok = strtok_r(NULL, DEV_PATH_DLM, &save_ptr))); - - free(dev_paths); - return 0; - -out4: - free(new_dev); -out3: - ecore_main_fd_handler_del(fd_handler); -out2: - close(fd); -out1: - free(dev_paths); - - return -ENOMEM; -} - -int exit_pm_poll(void) -{ - Eina_List *l = NULL; - Eina_List *l_next = NULL; - indev *data = NULL; - - EINA_LIST_FOREACH_SAFE(indev_list, l, l_next, data) { - ecore_main_fd_handler_del(data->dev_fd); - close(data->fd); - free(data->dev_path); - free(data); - indev_list = eina_list_remove_list(indev_list, l); - } - - _I("pm_poll is finished"); - return 0; -} - -int init_pm_poll_input(int (*pm_callback)(int , PMMsg * ), const char *path) -{ - indev *new_dev = NULL; - indev *data = NULL; - Ecore_Fd_Handler *fd_handler = NULL; - Eina_List *l = NULL; - Eina_List *l_next = NULL; - int fd = -1; - char *dev_path = NULL; - - if (!pm_callback || !path) { - _E("argument is NULL! (%x,%x)", pm_callback, path); - return -1; - } - - EINA_LIST_FOREACH_SAFE(indev_list, l, l_next, data) - if(!strcmp(path, data->dev_path)) { - _E("%s is already polled!", path); - return -1; - } - - _I("initialize pm poll for bt %s", path); - - g_pm_callback = pm_callback; - - fd = open(path, O_RDONLY); - if (fd == -1) { - _E("Cannot open the file for BT: %s", path); - return -1; - } - - dev_path = (char*)malloc(strlen(path) + 1); - if (!dev_path) { - _E("Fail to malloc for dev_path"); - close(fd); - return -1; - } - strncpy(dev_path, path, strlen(path) +1); - - /* - * To pass a fd data through the fd hander infrastructure - * without memory allocation, a fd data becomes typecast - * to intptr_t and void *(64bit) type. - */ - fd_handler = ecore_main_fd_handler_add(fd, - ECORE_FD_READ|ECORE_FD_ERROR, - pm_handler, (void *)((intptr_t)fd), NULL, NULL); - if (!fd_handler) { - _E("Fail to ecore fd handler add! %s", path); - close(fd); - free(dev_path); - return -1; - } - - new_dev = (indev *)malloc(sizeof(indev)); - if (!new_dev) { - _E("Fail to malloc for new_dev %s", path); - ecore_main_fd_handler_del(fd_handler); - close(fd); - free(dev_path); - return -1; - } - new_dev->dev_path = dev_path; - new_dev->fd = fd; - new_dev->dev_fd = fd_handler; - new_dev->pre_install = false; - - _I("pm_poll for BT input device file(path: %s, fd: %d", - new_dev->dev_path, new_dev->fd); - indev_list = eina_list_append(indev_list, new_dev); - - return 0; -} - -int check_pre_install(int fd) -{ - indev *data = NULL; - Eina_List *l = NULL; - Eina_List *l_next = NULL; - - EINA_LIST_FOREACH_SAFE(indev_list, l, l_next, data) - if(fd == data->fd) { - return data->pre_install; - } - - return -ENODEV; -} int check_dimstay(int next_state, int flag) { @@ -338,7 +56,7 @@ int check_dimstay(int next_state, int flag) int pm_lock_internal(pid_t pid, int s_bits, int flag, int timeout) { - if (!g_pm_callback) + if (!pm_callback) return -1; switch (s_bits) { @@ -363,14 +81,14 @@ int pm_lock_internal(pid_t pid, int s_bits, int flag, int timeout) recv_data.cond = s_bits; recv_data.timeout = timeout; - (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data); + (*pm_callback)(PM_CONTROL_EVENT, &recv_data); return 0; } int pm_unlock_internal(pid_t pid, int s_bits, int flag) { - if (!g_pm_callback) + if (!pm_callback) return -1; switch (s_bits) { @@ -388,14 +106,14 @@ int pm_unlock_internal(pid_t pid, int s_bits, int flag) recv_data.pid = pid; recv_data.cond = s_bits; - (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data); + (*pm_callback)(PM_CONTROL_EVENT, &recv_data); return 0; } int pm_change_internal(pid_t pid, int s_bits) { - if (!g_pm_callback) + if (!pm_callback) return -1; switch (s_bits) { @@ -411,7 +129,7 @@ int pm_change_internal(pid_t pid, int s_bits) recv_data.pid = pid; recv_data.cond = s_bits << SHIFT_CHANGE_STATE; - (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data); + (*pm_callback)(PM_CONTROL_EVENT, &recv_data); return 0; } diff --git a/src/display/poll.h b/src/display/poll.h index 48b7a46..de5aebf 100644 --- a/src/display/poll.h +++ b/src/display/poll.h @@ -21,10 +21,6 @@ * @file poll.h * @brief Power Manager input device poll implementation * - * This file includes the input device poll implementation. - * Default input devices are /dev/event0 and /dev/event1 - * User can use "PM_INPUT_DEV" for setting another input device poll in an environment file (/etc/profile). - * (ex: PM_INPUT_DEV=/dev/event0:/dev/event1:/dev/event5 ) */ #ifndef __PM_POLL_H__ @@ -103,21 +99,11 @@ typedef struct { unsigned int timeout2; } PMMsg; -typedef struct { - char *dev_path; - int fd; - Ecore_Fd_Handler *dev_fd; - int pre_install; -} indev; - -Eina_List *indev_list; - PMMsg recv_data; -int (*g_pm_callback) (int, PMMsg *); +int (*pm_callback) (int, PMMsg *); -extern int init_pm_poll(int (*pm_callback) (int, PMMsg *)); -extern int exit_pm_poll(); -extern int init_pm_poll_input(int (*pm_callback)(int , PMMsg * ), const char *path); +int init_input(int (*pm_callback) (int, PMMsg *)); +int exit_input(void); extern int pm_lock_internal(pid_t pid, int s_bits, int flag, int timeout); extern int pm_unlock_internal(pid_t pid, int s_bits, int flag); -- 2.7.4