#include <sys/poll.h>
#include <sys/signalfd.h>
+#include <sys/timerfd.h>
#include <linux/input.h>
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)
{
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;
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)
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;
#define DISPATCH_TIMEOUT (1 * 1000) /* One second */
#define LONGPRESS_TIME 3 /* Seconds */
+#define TIMER_INTERVAL 1 /* Seconds */
typedef enum {
ACTION_NONE,
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,
#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;
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;
#include <sys/reboot.h>
#include <vconf/vconf-keys.h>
+#include <asm-generic/setup.h> // for COMMAND_LINE_SIZE
#include "system-recovery.h"
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;
#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)
{
/* 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)
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;
free(rui_config_labels.rui_colors);
free(rui_config_labels.rui_rulers);
free(rui_config_labels.rui_descriptions);
+
+ free(rui_default_action);
}
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();
int recovery_gui(config_t *cfg);
int recovery_headless(config_t *cfg);
+char *get_action_from_cmdline(void);
#ifdef __cplusplus
}