input: add ConditionVconf property for conditional action 56/269256/3
authorYoungjae Cho <y0.cho@samsung.com>
Wed, 12 Jan 2022 05:55:31 +0000 (21:55 -0800)
committerYoungjae Cho <y0.cho@samsung.com>
Fri, 14 Jan 2022 08:05:45 +0000 (17:05 +0900)
[EVENT_ACTION] of input.conf can now have property ConditionVconf
 - ConditionVconf=key,type,value
which set the condition for an event, so that it will trigger action
only when the given vconf meet.

Change-Id: I3dbd4484718cc3ba3b9b241ec670b28963d45f3d
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
conf/iot-headless-input.conf
plugins/iot-headless/input/input-config.c
plugins/iot-headless/input/input-config.h
plugins/iot-headless/input/input-handler.c

index 404bb55..3d4a658 100644 (file)
@@ -54,4 +54,5 @@ Enum=1004
 Keycode=power
 Duration=7000,-1
 TriggerType=edge
+ConditionVconf=memory/sysman/charger_status,int,0
 Action=normal,poweroff
index 7e193ff..69bd8ac 100644 (file)
@@ -70,6 +70,40 @@ static void parse_trigger_type(struct input_event_unit *ieu, const char *type)
 
 }
 
+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 trans_info *ti = NULL;
@@ -126,6 +160,8 @@ static void parse_event_action_property(gpointer data, gpointer user_data)
                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, "Action")) {
                parse_action(ieu, prop->value);
        }
@@ -163,6 +199,73 @@ static int parse_event_action(const struct parse_result *result, void *data)
        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)
 {
        libsys_config_parse_by_section(INPUT_CONF_PATH, parse_event_action, NULL);
index 1fe1e75..7638298 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __INPUT_CONFIG_H__
 #define __INPUT_CONFIG_H__
 
+#include <vconf.h>
 #include "shared/device-notifier.h"
 
 enum trigger_type {
@@ -8,6 +9,17 @@ enum trigger_type {
        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;
@@ -17,6 +29,9 @@ struct input_event_unit {
        enum trigger_type type;
        unsigned long interval[2];
 
+       /* condition for triggering action */
+       struct condition_vconf cv;
+
        /* which action to do on receiving an event */
        enum device_notifier_type notifier;
        void *user_data;
@@ -34,5 +49,6 @@ struct input_config {
 
 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__
index 4b69c04..dd989ad 100644 (file)
@@ -38,9 +38,11 @@ static gboolean level_triggered(gpointer data)
 
        ieu->timer = 0;
 
-       if (ieu->notifier > 0) {
+       if (check_input_event_condition(ieu)) {
                _D("Trigger(level) event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier);
                device_notify(ieu->notifier, ieu->user_data);
+       } else {
+               _D("Skip(level) event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname);
        }
 
        return G_SOURCE_REMOVE;
@@ -48,8 +50,12 @@ static gboolean level_triggered(gpointer data)
 
 static void edge_triggered(struct input_event_unit *ieu)
 {
-       _D("Trigger(edge) event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier);
-       device_notify(ieu->notifier, ieu->user_data);
+       if (check_input_event_condition(ieu)) {
+               _D("Trigger(edge) event=%s(%d), action=%d", ieu->name, ieu->id, ieu->notifier);
+               device_notify(ieu->notifier, ieu->user_data);
+       } else {
+               _D("Skip(edge) event=%s(%d), condition=%s isn't meet", ieu->name, ieu->id, ieu->cv.keyname);
+       }
 }
 
 static void start_event_timer(struct input_config *ic)