display: Add set attribute for current state 28/297228/1
authorYoungjae Cho <y0.cho@samsung.com>
Mon, 14 Aug 2023 07:55:14 +0000 (16:55 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Mon, 14 Aug 2023 07:55:14 +0000 (16:55 +0900)
New attribute:
 - id: DEVICED_DISPLAY_ATTR_TUPLE2_SET_CURRENT_STATE
 - type: SYSCOMMON_RESMAN_DATA_TYPE_UIN64_UINT64
 - setter: O
 - getter: X

It sets display current state. It receives two parameters,
 - enum deviced_display_state
  : next state to be changed
 - enum deviced_event
  : reason why the state changed

Change-Id: I9e3bca655b85f0639fa50ea6d21cee62e2dc909d
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
src/display/display-panel.c
src/display/display-state-transition.c
src/display/display-state-transition.h
src/display/resource-display.c

index a4e1cef..d79b6e9 100644 (file)
@@ -359,7 +359,7 @@ void display_panel_lcd_on_direct(enum device_flags flags)
 /* FIXME: timer_refresh_cb seems legacy code, it can be removed after discussion */
 static gboolean timer_refresh_cb(gpointer data)
 {
-       display_state_set_current(DEVICED_DISPLAY_STATE_ON);
+       display_state_set_current(DEVICED_DISPLAY_STATE_ON, DEVICED_EVENT_INPUT);
        return 0;
 }
 
@@ -378,7 +378,7 @@ int display_panel_custom_lcd_on(int timeout)
        if (set_custom_lcdon_timeout(timeout))
                display_state_transition_update_display_state_timeout_by_priority();
 
-       display_state_set_current(DEVICED_DISPLAY_STATE_ON);
+       display_state_set_current(DEVICED_DISPLAY_STATE_ON, DEVICED_EVENT_INPUT);
 
        g_idle_add(timer_refresh_cb, NULL);
 
@@ -413,7 +413,7 @@ int display_panel_custom_lcd_off(enum device_flags flag)
        if (set_custom_lcdon_timeout(0) == true)
                display_state_transition_update_display_state_timeout_by_priority();
 
-       display_state_set_current(DEVICED_DISPLAY_STATE_OFF);
+       display_state_set_current(DEVICED_DISPLAY_STATE_OFF, DEVICED_EVENT_INPUT);
 
        return 0;
 }
@@ -455,7 +455,7 @@ int display_panel_display_turn_on_by_reason(const char *reason, int timeout)
        if (set_custom_lcdon_timeout(timeout) == true)
                display_state_transition_update_display_state_timeout_by_priority();
 
-       display_state_set_current(DEVICED_DISPLAY_STATE_ON);
+       display_state_set_current(DEVICED_DISPLAY_STATE_ON, DEVICED_EVENT_INPUT);
 
        return 0;
 }
@@ -493,7 +493,7 @@ int display_panel_display_turn_off_by_reason(const char *reason)
        if (display_panel_get_dpms_cached_state() == DPMS_ON)
                display_panel_lcd_off_procedure(flag);
 
-       display_state_set_current(DEVICED_DISPLAY_STATE_OFF);
+       display_state_set_current(DEVICED_DISPLAY_STATE_OFF, DEVICED_EVENT_INPUT);
 
        return 0;
 }
index cb8106e..ca65769 100644 (file)
@@ -21,6 +21,7 @@
  * @brief      This file has functions related to display state transition
  */
 
+#include <assert.h>
 #include <libsyscommon/common.h>
 #include <libsyscommon/resource-manager.h>
 #include <system/syscommon-plugin-deviced-display.h>
@@ -45,6 +46,7 @@ static enum deviced_display_state current = DEVICED_DISPLAY_STATE_START;
 static enum deviced_display_state previous = DEVICED_DISPLAY_STATE_START;
 
 static guint state_transition_timer_id;
+static guint state_timer;
 static unsigned int custom_normal_timeout = 0;
 static unsigned int custom_dim_timeout = 0;
 static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
@@ -107,22 +109,178 @@ inline void set_pm_old_state(int state)
        previous = state;
 }
 
-int display_state_set_current(enum deviced_display_state state)
+/**
+ * Default policy for display state timeout.
+ */
+static int get_default_timeout(enum deviced_display_state state, int *timeout)
 {
-       int timeout = 0;
+       double display_on_ratio = 1.0;
+       double display_dim_ratio = 0.0;
+       int lockscreen = 0;
+       int screen_timeout = 0;
+       int dimming = 0;
+       int ret = 0;
 
-       if (!is_display_state_valid(state))
+       assert(timeout);
+
+       /* Fixed timeout for state DEVICED_DISPLAY_STATE_OFF, 300ms */
+       if (state == DEVICED_DISPLAY_STATE_OFF) {
+               *timeout = 300;
+               return 0;
+       }
+
+       /* Get screen timeout from setting app */
+       ret = vconf_get_int(VCONFKEY_SETAPPL_LCD_TIMEOUT_NORMAL, &screen_timeout);
+       if (ret < 0)
+               return ret;
+
+       /* If lockscreen is being displayed, use lockscreen timeout instead. */
+       ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lockscreen);
+       if (ret == 0 && lockscreen == VCONFKEY_IDLE_LOCK)
+               screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
+
+       /* If dimming enabled, devide screen timeout into
+        * DEVICED_DISPLAY_STATE_ON and DEVICED_DISPLAY_STATE_DIM by 7:3. */
+       ret = display_plugin_config_get_dimming(&dimming);
+       if (ret == 0 && dimming) {
+               display_on_ratio = 0.7;
+               display_dim_ratio = 0.3;
+       }
+
+       if (state == DEVICED_DISPLAY_STATE_ON)
+               screen_timeout *= display_on_ratio;
+       else if (state == DEVICED_DISPLAY_STATE_DIM)
+               screen_timeout *= display_dim_ratio;
+       else
+               return -EINVAL;
+
+       *timeout = screen_timeout;
+
+       return 0;
+}
+
+static gboolean timeout_default_cb(void *data)
+{
+       enum deviced_display_state state = GPOINTER_TO_INT(data);
+       enum deviced_display_state next;
+
+       assert(state == current);
+
+       switch (state) {
+       case DEVICED_DISPLAY_STATE_ON:
+               next = DEVICED_DISPLAY_STATE_DIM;
+               break;
+       case DEVICED_DISPLAY_STATE_DIM:
+               next = DEVICED_DISPLAY_STATE_OFF;
+               break;
+       case DEVICED_DISPLAY_STATE_OFF:
+               /**
+                * TODO: Add power suspend at this point.
+                *
+                *  power_request_change_state(DEVICED_POWER_STATE_SLEEP, ...);
+                *
+                *  state_timer = 0;
+                *  return G_SOURCE_REMOVE;
+                */
+       default:
+               state_timer = 0;
+               return G_SOURCE_REMOVE;
+       }
+
+       state_timer = 0;
+
+       display_state_set_current(next, DEVICED_EVENT_DISPLAY_SCREEN_TIMEOUT);
+
+       return G_SOURCE_REMOVE;
+}
+
+/**
+ * next: set the current to the next
+ * event: reason for the transition
+ */
+static int set_current(enum deviced_display_state next, enum deviced_event event)
+{
+       if (!is_display_state_valid(next))
                return -EINVAL;
 
+       /**
+        * The 'locked' state cannot transition to the next state
+        * by an event DEVICED_EVENT_DISPLAY_SCREEN_TIMEOUT.
+        */
+       if (event == DEVICED_EVENT_DISPLAY_SCREEN_TIMEOUT && display_lock_is_state_locked(current))
+               return -EAGAIN;
+
+       /**
+        * TODO: Acquire power wakelock at this point.
+        *  power_request_change_state(DEVICED_POWER_STATE_NORMAL, ...);
+        */
+
        previous = current;
-       current = state;
+       current = next;
+
+       return 0;
+}
 
-       display_plugin_state_get_timeout(current, &timeout);
-       display_state_transition_do_state_action(timeout);
+/**
+ * timeout: set the timeout for the current state in milisecond
+ *          -1, use internally defined policy
+ *          0, immediately expires the current state
+ *          DEVICED_DISPLAY_SCREEN_TIMEOUT_INFINITE, do not set timeout for the state
+ * timeout_cb: callback for the given timeout expiration
+ */
+static int set_current_timeout(int timeout, GSourceFunc timeout_cb)
+{
+       int ret;
+
+       /* Have not received specfic timeout. Use default one. */
+       if (timeout < 0) {
+               ret = get_default_timeout(current, &timeout);
+               if (ret < 0)
+                       return ret;
+       }
+
+       assert(timeout >= 0);
+
+       if (state_timer) {
+               g_source_remove(state_timer);
+               state_timer = 0;
+       }
+
+       if (timeout == DEVICED_DISPLAY_SCREEN_TIMEOUT_INFINITE)
+               return 0;
+
+       /* Timeout 0 means transition to the next immediately */
+       if (timeout == 0)
+               state_timer = g_idle_add(timeout_cb ? : timeout_default_cb, GINT_TO_POINTER(current));
+       else
+               state_timer = g_timeout_add(timeout, timeout_cb ? : timeout_default_cb, GINT_TO_POINTER(current));
 
        return 0;
 }
 
+int display_state_set_current(enum deviced_display_state state, enum deviced_event event)
+{
+       int ret;
+
+       ret = set_current(state, event);
+       if (ret < 0)
+               return ret;
+
+       return set_current_timeout(-1, NULL);
+}
+
+int display_state_set_current_full(enum deviced_display_state state,
+       enum deviced_event event, int timeout, GSourceFunc timeout_cb)
+{
+       int ret;
+
+       ret = set_current(state, event);
+       if (ret < 0)
+               return ret;
+
+       return set_current_timeout(timeout, timeout_cb);
+}
+
 int display_state_get_current(enum deviced_display_state *state)
 {
        if (!state)
@@ -681,7 +839,11 @@ void display_state_transition_do_proc_change_state_action(enum deviced_display_s
 
 }
 
-/* FIXME: this function is temporary, it will be refactored */
+
+/**
+ * !! DO NOT USE THIS FUNCTION ANYMOER. It is legacy for old plugins.
+ * Use display_state_set_current() instead.
+ */
 int display_state_transition_do_proc_change_state(unsigned int cond, pid_t pid)
 {
        enum deviced_display_state next;
index 08edfe6..df5cfd6 100644 (file)
@@ -31,7 +31,7 @@
 
 #define LOCK_SCREEN_INPUT_TIMEOUT      10000
 
-int display_state_set_current(enum deviced_display_state state);
+int display_state_set_current(enum deviced_display_state state, enum deviced_event event);
 int display_state_get_current(enum deviced_display_state *state);
 int display_state_get_previous(enum deviced_display_state *state);
 
index c5c3265..3fd2d3d 100644 (file)
@@ -38,6 +38,28 @@ typedef union {
        bool b;
 } resource_attr_data_t;
 
+static int set_tuple2_display_attr_data(int resource_id,
+       const struct syscommon_resman_resource_attribute *attr,
+       const void *data1, const void *data2, int count1, int count2)
+{
+       if (!data1 || !data2)
+               return -EINVAL;
+
+       switch (attr->id) {
+       case DEVICED_DISPLAY_ATTR_TUPLE2_SET_CURRENT_STATE:
+               {
+                       enum deviced_display_state state = *(enum deviced_display_state *) data1;
+                       enum deviced_event event = *(enum deviced_event *) data2;
+
+                       return display_state_set_current(state, event);
+               }
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static int get_display_attr_data(int resource_id,
        const struct syscommon_resman_resource_attribute *attr, void *data)
 {
@@ -110,7 +132,16 @@ static const struct syscommon_resman_resource_attribute display_attrs[] = {
                        .get = get_display_attr_data,
                        .is_supported = syscommon_resman_resource_attr_supported_always,
                },
-       },
+       }, {
+               .name = "DEVICED_DISPLAY_ATTR_TUPLE2_SET_CURRENT_STATE",
+               .id = DEVICED_DISPLAY_ATTR_TUPLE2_SET_CURRENT_STATE,
+               .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64_UINT64,
+               .flag = SYSCOMMON_RESMAN_RESOURCE_FLAG_PUBLIC,
+               .ops = {
+                       .set_2_tuple = set_tuple2_display_attr_data,
+                       .is_supported = syscommon_resman_resource_attr_supported_always,
+               },
+       }
 };
 
 static const struct syscommon_resman_resource_driver deviced_display_driver = {