Do default action in RUI mode 60/154060/4
authorPaweł Szewczyk <p.szewczyk@samsung.com>
Thu, 5 Oct 2017 15:20:02 +0000 (17:20 +0200)
committerKarol Lewandowski <k.lewandowsk@samsung.com>
Fri, 13 Oct 2017 12:43:52 +0000 (14:43 +0200)
Change-Id: I4ffd0b5b9a415498c1de1a0e15af205ada268a5d
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
src/librui/input-events.c
src/librui/input-events.h
src/system-recovery/recovery-headless.c
src/system-recovery/recovery-main.c
src/system-recovery/recovery-rui.c
src/system-recovery/system-recovery.h

index c841ed4..325391c 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <sys/poll.h>
 #include <sys/signalfd.h>
+#include <sys/timerfd.h>
 
 #include <linux/input.h>
 
@@ -50,8 +51,10 @@ static struct pollfd ev_fds[MAX_INPUTS];
 static unsigned ev_count = 0;
 
 static unsigned signalfd_idx = -1;
+static unsigned timerfd_idx = -1;
 
 #define IS_SIGNAL_EVENT(x) (x == signalfd_idx)
+#define IS_TIMER_EVENT(x) (x == timerfd_idx)
 
 static bool ev_signal_init(void)
 {
@@ -78,6 +81,31 @@ static bool ev_signal_init(void)
        return true;
 }
 
+static bool ev_timer_init(void)
+{
+       int fd;
+       struct itimerspec timer_spec = {
+               .it_interval = {TIMER_INTERVAL, 0},
+               .it_value = {0, 1},
+       };
+
+       if (ev_count >= MAX_INPUTS)
+               return false;
+
+       fd = timerfd_create(CLOCK_REALTIME, 0);
+       if (fd < 0) {
+               perror("timerfd_create");
+               return false;
+       }
+
+       timerfd_settime(fd, 0, &timer_spec, NULL);
+       ev_fds[ev_count].fd = fd;
+       ev_fds[ev_count].events = POLLIN;
+       timerfd_idx = ev_count++;
+
+       return true;
+}
+
 static bool ev_input_init(void)
 {
        DIR *dir;
@@ -134,7 +162,7 @@ static bool ev_input_init(void)
 
 bool ev_init(void)
 {
-       return ev_input_init() && ev_signal_init();
+       return ev_input_init() && ev_signal_init() && ev_timer_init();
 }
 
 void ev_exit(void)
@@ -256,6 +284,19 @@ bool ev_dispatch(input_callback callback)
                                continue;
                        }
 
+                       if (IS_TIMER_EVENT(n)) {
+                               uint64_t exp;
+
+                               r = read(ev_fds[n].fd, &exp, sizeof(exp));
+                               if (r != sizeof(exp)) {
+                                       perror("read");
+                                       return false;
+                               }
+
+                               callback(ACTION_TIMEOUT, ACTION_TYPE_TIMER);
+                               continue;
+                       }
+
                        r = read(ev_fds[n].fd, &ev, sizeof(ev));
                        if (r != sizeof(ev))
                                continue;
index 3d1e6b5..b07f996 100644 (file)
@@ -26,6 +26,7 @@ extern "C" {
 
 #define DISPATCH_TIMEOUT        (1 * 1000) /* One second */
 #define LONGPRESS_TIME          3 /* Seconds */
+#define TIMER_INTERVAL          1 /* Seconds */
 
 typedef enum {
        ACTION_NONE,
@@ -34,14 +35,16 @@ typedef enum {
        ACTION_CONFIRM,
        ACTION_HOME,
        ACTION_MENU,
-       ACTION_BACK
+       ACTION_BACK,
+       ACTION_TIMEOUT,
 } user_action;
 
 typedef enum {
        ACTION_TYPE_IDLE,
        ACTION_TYPE_BEGIN,
        ACTION_TYPE_END,
-       ACTION_TYPE_LONGPRESS
+       ACTION_TYPE_LONGPRESS,
+       ACTION_TYPE_TIMER,
 } user_action_type;
 
 typedef void (*input_callback)(user_action action,
index aa113f9..3f45dc8 100644 (file)
 #include "log.h"
 #include "system-recovery.h"
 
-#include <asm-generic/setup.h> // for COMMAND_LINE_SIZE
-
-#define KERNEL_CMDLINE_KEY "tizen.recovery"
-
 static char *get_action_from_config(config_t *cfg)
 {
        config_setting_t *node;
@@ -45,34 +41,6 @@ static char *get_action_from_config(config_t *cfg)
        return strdup(action);
 }
 
-// looks for tizen.recovery= key in kernel command line
-static char *get_action_from_cmdline(void)
-{
-       FILE *fp;
-       char cmdline[COMMAND_LINE_SIZE];
-       int len;
-
-       fp = fopen("/proc/cmdline", "r");
-       if (!fp)
-               return NULL;
-
-       char *p = fgets(cmdline, sizeof cmdline, fp);
-       fclose(fp);
-       if (!p)
-               return NULL;
-
-       const char *prefix = KERNEL_CMDLINE_KEY "=";
-       p = strstr(cmdline, prefix);
-       if (!p)
-               return NULL;
-       p += strlen(prefix);
-
-       for (len = 0; *(p + len) != 0 && !isspace(*(p + len)); ++len)
-               ; /* skip */
-
-       return strndup(p, len);
-}
-
 int recovery_headless(config_t *cfg)
 {
        config_setting_t *node;
index f3bf4e0..693c92f 100644 (file)
@@ -34,6 +34,7 @@
 #include <sys/reboot.h>
 
 #include <vconf/vconf-keys.h>
+#include <asm-generic/setup.h> // for COMMAND_LINE_SIZE
 
 #include "system-recovery.h"
 
@@ -42,6 +43,37 @@ void sys_power_reboot(void)
        reboot(RB_AUTOBOOT);
 }
 
+#define KERNEL_CMDLINE_KEY "tizen.recovery"
+
+// looks for tizen.recovery= key in kernel command line
+char *get_action_from_cmdline(void)
+{
+       FILE *fp;
+       char cmdline[COMMAND_LINE_SIZE];
+       int len;
+
+       fp = fopen("/proc/cmdline", "r");
+       if (!fp)
+               return NULL;
+
+       char *p = fgets(cmdline, sizeof cmdline, fp);
+       fclose(fp);
+       if (!p)
+               return NULL;
+
+       const char *prefix = KERNEL_CMDLINE_KEY "=";
+       p = strstr(cmdline, prefix);
+       if (!p)
+               return NULL;
+       p += strlen(prefix);
+
+       for (len = 0; *(p + len) != 0 && !isspace(*(p + len)); ++len)
+               ; /* skip */
+
+       return strndup(p, len);
+}
+
+
 int main(void)
 {
        config_t cfg;
index 50521b8..4fc5fd5 100644 (file)
 #include "recovery-rui-skin.h"
 #include "process-util.h"
 
+/* if user does not do anything, default action will be taken after this timeout*/
+#define DEFAULT_ACTION_TIMEOUT 4
+
+#define BUFFER_SIZE 512
+
 bool volatile running = true;
+static const char *original_description = NULL;
+static char description_buffer[BUFFER_SIZE];
+static char *rui_default_action = NULL;
+static const char *rui_default_handler = NULL;
+
+static int timer_count = 0;
+static bool user_idle = true;
+
+static void timeout_handler(rui_screen *cs)
+{
+       int ret;
+
+       if (rui_default_action && user_idle) {
+               if (!original_description) {
+                       original_description = cs->description->text;
+                       cs->description->text = description_buffer;
+               }
+
+               snprintf(description_buffer, BUFFER_SIZE,
+                               "%s\nDefault action (%s) will be taken after %d seconds",
+                               original_description, rui_default_action,
+                               DEFAULT_ACTION_TIMEOUT - timer_count/TIMER_INTERVAL);
+
+               if (timer_count/TIMER_INTERVAL == DEFAULT_ACTION_TIMEOUT) {
+                       ret = system(rui_default_handler);
+                       if (ret < 0)
+                               LOGD("Could not run action: %s\n", rui_default_handler);
+               }
+       }
+
+       if (!user_idle) {
+               cs->description->text = original_description;
+       }
+
+       timer_count++;
+}
 
 void recovery_rui_input_callback(user_action action, user_action_type action_type)
 {
@@ -47,10 +88,18 @@ void recovery_rui_input_callback(user_action action, user_action_type action_typ
        /* We interested only in button downs, long presses and idle events */
        if (action_type != ACTION_TYPE_BEGIN &&
            action_type != ACTION_TYPE_LONGPRESS &&
-           action_type != ACTION_TYPE_IDLE)
+           action_type != ACTION_TYPE_IDLE &&
+           action_type != ACTION_TYPE_TIMER)
                return;
 
        cs = get_current_screen();
+       if (action_type != ACTION_TYPE_TIMER &&
+                       action_type != ACTION_TYPE_IDLE &&
+                       user_idle) {
+               user_idle = false;
+               timeout_handler(cs);
+       }
+
        if (action == ACTION_DOWN && cs->menu)
                rui_menu_cursor_down(cs->menu);
        else if (action == ACTION_UP && cs->menu)
@@ -64,6 +113,8 @@ void recovery_rui_input_callback(user_action action, user_action_type action_typ
                rui_menu_action_run(cs->menu);
        else if (action == ACTION_BACK)
                rui_screen_switch(RUI_SCREEN_BACK);
+       else if (action == ACTION_TIMEOUT)
+               timeout_handler(cs);
        else if (action != ACTION_NONE || action_type != ACTION_TYPE_IDLE ||
                 !cs->animations)
                need_repaint = 0;
@@ -729,6 +780,8 @@ void recovery_rui_exit(void)
        free(rui_config_labels.rui_colors);
        free(rui_config_labels.rui_rulers);
        free(rui_config_labels.rui_descriptions);
+
+       free(rui_default_action);
 }
 
 
@@ -753,6 +806,17 @@ int recovery_gui(config_t *cfg)
                return 1;
        }
 
+       rui_default_action = get_action_from_cmdline();
+       if (rui_default_action) {
+               int idx = find_string(rui_config_labels.rui_action_handlers, rui_default_action);
+               if (idx < 0) {
+                       LOGD("Invalid action: %s\n", rui_default_action);
+                       free(rui_default_action);
+                       rui_default_action = NULL;
+               } else
+                       rui_default_handler = rui_action_handlers[idx];
+       }
+
        if (!ev_init()) {
                LOGD("Can't initialize input subsystem.\n");
                recovery_rui_exit();
index 5364c19..f309251 100644 (file)
@@ -38,6 +38,7 @@ void sys_power_reboot(void);
 
 int recovery_gui(config_t *cfg);
 int recovery_headless(config_t *cfg);
+char *get_action_from_cmdline(void);
 
 #ifdef __cplusplus
 }