INSTALL_CONF(conf power-profile-wearable)
INSTALL_CONF(conf power-profile-tv)
INSTALL_CONF(conf power-profile-iot-headed)
- INSTALL_CONF(conf power-profile-iot-headless)
ENDIF()
# USB connection
ADD_SUBDIRECTORY(plugins/wearable/display)
ADD_SUBDIRECTORY(plugins/tv/display)
ADD_SUBDIRECTORY(plugins/iot-headed/display)
-ADD_SUBDIRECTORY(plugins/iot-headless/input)
IF(BATTERY_MODULE STREQUAL on)
ADD_SUBDIRECTORY(plugins/mobile/battery)
ADD_SUBDIRECTORY(plugins/wearable/battery)
INSTALL_CONF(conf display-profile-wearable)
INSTALL_CONF(conf display-profile-tv)
INSTALL_CONF(conf display-profile-iot-headed)
-INSTALL_CONF(conf input-profile-iot-headless)
# Tests
ADD_SUBDIRECTORY(tests/deviced-common-private-test)
%description plugin-profile-iot-headed
Plugin libraries for IoT devices
-%package plugin-profile-iot-headless
-Summary: Plugin libraries for IoT headless devices
-Group: System/Management
-Requires: %{name} = %{version}-%{release}
-
-%description plugin-profile-iot-headless
-Plugin libraries for IoT headless devices
-
%isu_package
%prep
mkdir -p %{_libdir}/deviced
mv %{_libdir}/iot-headed-display.so %{_libdir}/deviced/display.so
-%post plugin-profile-iot-headless
-mv %{_sysconfdir}/deviced/input-profile-iot-headless.conf %{_sysconfdir}/deviced/input.conf
-mv %{_sysconfdir}/deviced/power-profile-iot-headless.conf %{_sysconfdir}/deviced/power.conf
-mkdir -p %{_libdir}/deviced
-mv %{_libdir}/iot-headless-input-handler.so %{_libdir}/deviced/input-handler.so
-
%files
%manifest %{name}.manifest
%license LICENSE.Apache-2.0
%{_libdir}/iot-headed-display.so
%{_unitdir}/rndis.service
%{_bindir}/rndis.sh
-
-%files plugin-profile-iot-headless
-%manifest deviced.manifest
-%license LICENSE.Apache-2.0
-%defattr(-,root,root,-)
-%config %{_sysconfdir}/deviced/input-profile-iot-headless.conf
-%config %{_sysconfdir}/deviced/power-profile-iot-headless.conf
-%{_libdir}/iot-headless-input-handler.so
-%{_unitdir}/rndis.service
-%{_bindir}/rndis.sh
+++ /dev/null
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-
-PROJECT(iot-headless-input-handler C)
-
-INCLUDE(FindPkgConfig)
-PKG_CHECK_MODULES(REQUIRED_PKGS REQUIRED
- glib-2.0
- dlog
- libinput)
-
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../power)
-
-ADD_DEFINITIONS("-DENABLE_DLOG")
-
-FILE(GLOB SRCS "*.c")
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "")
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES OUTPUT_NAME iot-headless-input-handler)
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+++ /dev/null
-/*
- * deviced
- *
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <glib.h>
-#include <libsyscommon/ini-parser.h>
-#include <libsyscommon/list.h>
-#include <libsyscommon/log.h>
-#include <system/syscommon-plugin-deviced-common-interface.h>
-#include <system/syscommon-plugin-deviced-power-interface.h>
-
-#include <linux/input.h>
-
-#include "input-config.h"
-
-#define INPUT_CONF_PATH "/etc/deviced/input.conf"
-
-/* input config list */
-static GList *input_config_list;
-
-struct input_config *find_input_config(int keycode)
-{
- GList *elem;
- struct input_config *ic;
-
- SYS_G_LIST_FOREACH(input_config_list, elem, ic)
- if (ic->keycode == keycode)
- return ic;
-
- return NULL;
-}
-
-static void parse_keycode(struct input_event_unit *ieu, const char *keycode)
-{
- if (MATCH(keycode, "power"))
- ieu->keycode = KEY_POWER;
- else if (MATCH(keycode, "bluetooth"))
- ieu->keycode = KEY_BLUETOOTH;
- /* add keycode list here */
-}
-
-static void parse_duration(struct input_event_unit *ieu, const char *duration)
-{
- long start, end;
- int retval;
-
- retval = sscanf(duration, "%ld,%ld", &start, &end);
- if (retval != 2) {
- _E("Invalid duration format=%s", duration);
- ieu->interval[0] = 0;
- ieu->interval[1] = 0;
- return;
- }
-
- if (end < 0)
- end = ~0UL;
-
- ieu->interval[0] = (unsigned long) start;
- ieu->interval[1] = (unsigned long) end;
-}
-
-static void parse_trigger_type(struct input_event_unit *ieu, const char *type)
-{
- if (MATCH(type, "edge")) {
- ieu->type = TRIGGER_TYPE_EDGE;
- } else if (MATCH(type, "level")) {
- ieu->type = TRIGGER_TYPE_LEVEL;
- } else {
- _E("Invalid type=%s", type);
- ieu->type = TRIGGER_TYPE_EDGE;
- }
-
-}
-
-static void parse_condition_vconf(struct input_event_unit *ieu, const char *str)
-{
- int retval;
-
- char vconfkey[128] = { 0, };
- char vconftype[16] = { 0, };
- char vconfvalue[64] = { 0, };
-
- retval = sscanf(str, "%127[^,],%15[^,],%63s", vconfkey, vconftype, vconfvalue);
- if (retval != 3)
- return;
-
- _D("Condition vconf: key=%s, type=%s, value=%s", vconfkey, vconftype, vconfvalue);
-
- if (!strncasecmp(vconftype, "bool", sizeof("bool"))) {
- ieu->cv.type = VCONF_TYPE_BOOL;
- sscanf(vconfvalue, "%d", &ieu->cv.b);
- } else if (!strncasecmp(vconftype, "int", sizeof("int"))) {
- ieu->cv.type = VCONF_TYPE_INT;
- sscanf(vconfvalue, "%d", &ieu->cv.i);
- } else if (!strncasecmp(vconftype, "double", sizeof("double"))) {
- ieu->cv.type = VCONF_TYPE_DOUBLE;
- sscanf(vconfvalue, "%lf", &ieu->cv.d);
- } else if (!strncasecmp(vconftype, "string", sizeof("string"))) {
- ieu->cv.type = VCONF_TYPE_STRING;
- ieu->cv.s = strndup(vconfvalue, 128);
- } else {
- _E("Invalid condition vconf type");
- return;
- }
-
- ieu->cv.keyname = strndup(vconfkey, 128);
-}
-
-static void add_action_transition_info(struct input_event_unit *ieu, char *curr, char *next)
-{
- struct syscommon_plugin_deviced_power_trans_info *ti = NULL;
- GList **action_list = (GList **) &(ieu->user_data);
-
- ti = calloc(1, sizeof(struct syscommon_plugin_deviced_power_trans_info));
- if (!ti)
- return;
-
- /* In configuration file, Enum= must be followed by Action=.
- * Otherwise, ieu->id won't be defined at this point.*/
- ti->reason = ieu->id;
-
- ti->curr = syscommon_plugin_deviced_power_convert_to_power_state(curr);
- ti->next = syscommon_plugin_deviced_power_convert_to_power_state(next);
-
- SYS_G_LIST_APPEND(*action_list, ti);
-}
-
-static void parse_change_state(struct input_event_unit *ieu, const char *action)
-{
- char curr[16] = { 0, };
- char next[16] = { 0, };
-
- if (sscanf(action, "%15[^,],%15s", curr, next) == 2) {
- ieu->notifier = DEVICED_NOTIFIER_REQUEST_TRANSITION_STATE;
- /* append transition info to ieu->user_data */
- add_action_transition_info(ieu, curr, next);
- } else {
- _E("Invalid action=%s", action);
- }
-}
-
-static void parse_event_action_property(gpointer data, gpointer user_data)
-{
- struct section_property *prop = (struct section_property *) data;
- struct input_event_unit *ieu = (struct input_event_unit *) user_data;
-
- if (!prop || !ieu)
- return;
-
- _D("Key=%s, Value=%s", prop->key, prop->value);
-
- if (MATCH(prop->key, "Name")) {
- ieu->name = strndup(prop->value, 32);
- } else if (MATCH(prop->key, "Enum")) {
- sscanf(prop->value, "%d", &ieu->id);
- } else if (MATCH(prop->key, "Keycode")) {
- parse_keycode(ieu, prop->value);
- } else if (MATCH(prop->key, "DetectionRangeMsec")) {
- parse_duration(ieu, prop->value);
- } else if (MATCH(prop->key, "TriggerType")) {
- parse_trigger_type(ieu, prop->value);
- } else if (MATCH(prop->key, "ConditionVconf")) {
- parse_condition_vconf(ieu, prop->value);
- } else if (MATCH(prop->key, "ActionChangeState")) {
- parse_change_state(ieu, prop->value);
- } else if (MATCH(prop->key, "ActionBroadcast")) {
- ieu->broadcast = MATCH(prop->value, "yes");
- } else if (MATCH(prop->key, "WakeLockDurationSec")) {
- sscanf(prop->value, "%d", &ieu->wakelock_duration);
- }
-}
-
-static int parse_event_action(const struct parse_result *result, void *data)
-{
- struct input_config *ic;
- struct input_event_unit *ieu;
-
- if (!result || !result->props)
- return 0;
-
- if (!MATCH(result->section, "EventAction"))
- return 0;
-
- _D("Input section=%s", result->section);
-
- ieu = calloc(1, sizeof(struct input_event_unit));
- if (!ieu)
- return 0;
-
- g_list_foreach(result->props, parse_event_action_property, ieu);
-
- ic = find_input_config(ieu->keycode);
- if (!ic) {
- ic = calloc(1, sizeof(struct input_config));
- if (!ic)
- return -ENOMEM;
- ic->keycode = ieu->keycode;
- SYS_G_LIST_APPEND(input_config_list, ic);
- }
- SYS_G_LIST_APPEND(ic->event_list, ieu);
-
- return 0;
-}
-
-/* return 1 if the condition met, otherwise return 0 */
-int check_input_event_condition(const struct input_event_unit *ieu)
-{
- char *keyname;
- int retval, ret;
- char buffer[256] = { 0, };
-
- int b;
- int i;
- double d;
- char *s;
-
- if (!ieu)
- return 0;
-
- if (!ieu->cv.keyname)
- return 1;
-
- keyname = ieu->cv.keyname;
-
- switch (ieu->cv.type) {
- case VCONF_TYPE_BOOL:
- retval = vconf_get_bool(keyname, &b);
- if (retval < 0) {
- _E("Failed to get vconf=%s", keyname);
- return 0;
- }
- snprintf(buffer, sizeof(buffer), "expected=%d, current=%d", ieu->cv.b, b);
- ret = (b == ieu->cv.b);
- break;
- case VCONF_TYPE_INT:
- retval = vconf_get_int(keyname, &i);
- if (retval < 0) {
- _E("Failed to get vconf=%s", keyname);
- return 0;
- }
- snprintf(buffer, sizeof(buffer), "expected=%d, current=%d", ieu->cv.i, i);
- ret = (i == ieu->cv.i);
- break;
- case VCONF_TYPE_DOUBLE:
- retval = vconf_get_dbl(keyname, &d);
- if (retval < 0) {
- _E("Failed to get vconf=%s", keyname);
- return 0;
- }
- snprintf(buffer, sizeof(buffer), "expected=%lf, current=%lf", ieu->cv.d, d);
- ret = (d == ieu->cv.d);
- break;
- case VCONF_TYPE_STRING:
- s = vconf_get_str(keyname);
- if (!s) {
- _E("Failed to get vconf=%s", keyname);
- return 0;
- }
- snprintf(buffer, sizeof(buffer), "expected=%s, current=%s", ieu->cv.s, s);
- ret = (strncmp(s, ieu->cv.s, 128) == 0);
- free(s);
- break;
- default:
- return 0;
- }
-
- _D("Check condition vconf=%s(%s)", keyname, buffer);
-
- return ret;
-}
-
-void init_input_config(void)
-{
- syscommon_config_parse_by_section(INPUT_CONF_PATH, parse_event_action, NULL);
-}
+++ /dev/null
-/*
- * deviced
- *
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __INPUT_CONFIG_H__
-#define __INPUT_CONFIG_H__
-
-#include <vconf.h>
-#include <system/syscommon-plugin-deviced-common-interface.h>
-
-enum trigger_type {
- TRIGGER_TYPE_LEVEL, /* trigger event if a key is pressed for a duration */
- TRIGGER_TYPE_EDGE, /* trigger event if a key is released within a specific time interval */
-};
-
-struct condition_vconf {
- char *keyname;
- enum vconf_t type;
- union {
- int b;
- int i;
- double d;
- char *s;
- };
-};
-
-struct input_event_unit {
- char *name;
- int id;
-
- /* which event to filter */
- int keycode;
- enum trigger_type type;
- unsigned long interval[2];
-
- /* level-trigger timer */
- int timer;
-
- /* condition for triggering action */
- struct condition_vconf cv;
-
- /* broadcast upon occuring the event */
- int broadcast;
-
- /* which action to do on receiving an event */
- enum deviced_notifier notifier;
- void *user_data;
-
- /* hold wakelock for a duration on detecting the event */
- int wakelock_duration;
-};
-
-struct input_config {
- int keycode;
- GList *event_list; /* list of struct input_event_unit */
-
- unsigned long start; /* input incoming time in milisecond */
-};
-
-void init_input_config(void);
-struct input_config *find_input_config(int keycode);
-int check_input_event_condition(const struct input_event_unit *ieu);
-
-#endif //__INPUT_CONFIG_H__
+++ /dev/null
-/*
- * deviced
- *
- * Copyright (c) 2022 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 <time.h>
-#include <stdint.h>
-#include <libinput.h>
-#include <linux/input.h>
-#include <glib.h>
-#include <libsyscommon/libgdbus.h>
-#include <libsyscommon/list.h>
-#include <libsyscommon/log.h>
-#include <libsyscommon/resource-manager.h>
-#include <libsyscommon/notifier.h>
-#include <system/syscommon-plugin-deviced-common-interface.h>
-#include <system/syscommon-plugin-deviced-power-interface.h>
-
-#include "input-config.h"
-#include "input/input.h"
-#include "input/input-plugin-interface.h"
-
-static int input_event_handler_id;
-
-static gboolean level_event_detected(gpointer data)
-{
- struct input_event_unit *ieu = (struct input_event_unit *) data;
-
- ieu->timer = 0;
-
- _D("Detected level event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier);
-
- if (check_input_event_condition(ieu) == 0) {
- _D("Skip triggering event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname);
- return G_SOURCE_REMOVE;
- }
-
- if (ieu->broadcast)
- gdbus_signal_emit(NULL, DEVICED_PATH_EVENT, DEVICED_INTERFACE_EVENT,
- DEVICED_SIGNAL_EVENT_ID, g_variant_new("(i)", ieu->id));
-
- if (ieu->wakelock_duration > 0)
- syscommon_resman_set_resource_attr_uint64_2(
- SYSCOMMON_RESOURCE_ID(DEVICED_RESOURCE_TYPE_POWER),
- DEVICED_POWER_ATTR_TUPLE2_SET_WAKELOCK,
- ieu->id, ieu->wakelock_duration);
-
- if (ieu->notifier)
- syscommon_notifier_emit_notify(ieu->notifier, ieu->user_data);
-
- return G_SOURCE_REMOVE;
-}
-
-static void edge_event_detected(struct input_event_unit *ieu)
-{
- _D("Detected edge event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier);
-
- if (check_input_event_condition(ieu) == 0) {
- _D("Skip triggering event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname);
- return;
- }
-
- if (ieu->broadcast)
- gdbus_signal_emit(NULL, DEVICED_PATH_EVENT, DEVICED_INTERFACE_EVENT,
- DEVICED_SIGNAL_EVENT_ID, g_variant_new("(i)", ieu->id));
-
- if (ieu->wakelock_duration > 0)
- syscommon_resman_set_resource_attr_uint64_2(
- SYSCOMMON_RESOURCE_ID(DEVICED_RESOURCE_TYPE_POWER),
- DEVICED_POWER_ATTR_TUPLE2_SET_WAKELOCK,
- ieu->id, ieu->wakelock_duration);
-
- if (ieu->notifier)
- syscommon_notifier_emit_notify(ieu->notifier, ieu->user_data);
-}
-
-static void start_event_timer(struct input_config *ic)
-{
- struct timespec ts;
- struct input_event_unit *ieu;
- GList *elem;
-
- clock_gettime(CLOCK_MONOTONIC, &ts);
- ic->start = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
-
- /* set timer for level-trigger event */
- SYS_G_LIST_FOREACH(ic->event_list, elem, ieu) {
- if (ieu->type == TRIGGER_TYPE_LEVEL) {
- if (ieu->timer)
- g_source_remove(ieu->timer);
- ieu->timer = g_timeout_add(ieu->interval[0], level_event_detected, (gpointer) ieu);
- }
- }
-}
-
-static void stop_event_timer(struct input_config *ic)
-{
- struct timespec ts;
- struct input_event_unit *ieu;
- GList *elem;
- unsigned long current;
- unsigned long lapse;
-
- if (ic->start == 0)
- return;
-
- clock_gettime(CLOCK_MONOTONIC, &ts);
- current = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
- lapse = current - ic->start;
- ic->start = 0;
-
- SYS_G_LIST_FOREACH(ic->event_list, elem, ieu) {
- /* remove all level-trigger timer */
- if (ieu->timer) {
- g_source_remove(ieu->timer);
- ieu->timer = 0;
- }
-
- /* detected edge-trigger event */
- if (lapse >= ieu->interval[0] && lapse < ieu->interval[1] && ieu->type == TRIGGER_TYPE_EDGE)
- edge_event_detected(ieu);
- }
-}
-
-static void input_handler_process_key(struct timeval time, unsigned short type, unsigned short keycode, unsigned int keyvalue)
-{
- struct input_config *ic;
-
- if (type != EV_KEY)
- return;
-
- _D("Key input: code=%d, value=%d", keycode, keyvalue);
-
- /* acquire tmplock on pressing key */
- if (keyvalue == KEY_PRESSED)
- syscommon_notifier_emit_notify(DEVICED_NOTIFIER_KEY_PRESS, (void *)(intptr_t) keycode);
-
- /* process all registered event to the keycode */
- ic = find_input_config(keycode);
- if (ic && keyvalue == KEY_PRESSED)
- start_event_timer(ic);
- else if (ic && keyvalue == KEY_RELEASED)
- stop_event_timer(ic);
-
- /* release tmplock on releasing key */
- if (keyvalue == KEY_RELEASED)
- syscommon_notifier_emit_notify(DEVICED_NOTIFIER_KEY_RELEASE, (void *)(intptr_t) keycode);
-}
-
-static int input_handler_init(void *data)
-{
- init_input_config();
- input_register_event_callback(input_handler_process_key, NULL, NULL, &input_event_handler_id);
-
- return 0;
-}
-
-static void input_handler_exit(void *data)
-{
- input_unregister_event_callback(input_event_handler_id);
-}
-
-const struct input_plugin_interface INPUT_PLUGIN_INTERFACE_SYMBOL = {
- .init = input_handler_init,
- .exit = input_handler_exit,
-};