From: Taeyoung Kim Date: Mon, 15 Feb 2016 04:29:07 +0000 (+0900) Subject: power: add padding timer to power lock X-Git-Tag: submit/tizen/20160803.081834^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4ef5c21187f14817f10b5da5249ae867efd0fe44;p=platform%2Fcore%2Fapi%2Fdevice.git power: add padding timer to power lock - If Power Lock timeout (10 minutes) is expired during apps do something with reference count 0 for very short time, Power Lock will be released. Thus Suspend mode can be entered. (Problem example) ============================================================== Time | Music player | device-power | libtracker ============================================================== 00:00 power lock power lock add timer play start ref count:1 -------------------------------------------------------------- 09:50 play stop ref count:0 search music -------------------------------------------------------------- 10:00 timer expired check ref count (== 0) -> power unlock -------------------------------------------------------------- 10:10 search done play start ref count:1 -------------------------------------------------------------- After few < Power Suspend Mode > minutes ============================================================== - To fix the issue, power lock api uses the padding timeout whose callback is called after 20 seconds of power lock timeout. Apps can do something without increasing reference count. If the ref count is still 0 after 20 seconds, the Power Lock will be released. - If the ref count is changed during 20 seconds but the value is still 0, Power Lock should not be released. Thus libtracker supports the total reference count which means the accumulated ref count. Thus The accumulated ref count is checked if the ref count is still 0. Change-Id: I307fbda4313d14fec2a4a31640096020c3c21485 Signed-off-by: Taeyoung Kim Signed-off-by: taeyoung --- diff --git a/src/power.c b/src/power.c index a25e98b..647c9a2 100644 --- a/src/power.c +++ b/src/power.c @@ -61,9 +61,12 @@ #define STR_LCD_DIM "lcddim" #define STR_LCD_ON "lcdon" -#define LOCK_CPU_TIMEOUT_MAX 600000 /* milliseconds */ +#define LOCK_CPU_TIMEOUT_MAX (60*60*1000) /* milliseconds */ +#define LOCK_CPU_PADDING_TIMEOUT (20*1000) /* milliseconds */ static guint off_lock_timeout; +static guint padding_timeout; +static int prev_count; static char *get_state_str(display_state_e state) { @@ -82,18 +85,30 @@ static char *get_state_str(display_state_e state) static void remove_off_lock_timeout(void) { - _I("Power lock timeout handler removed"); if (off_lock_timeout) { + _I("Power lock timeout handler removed"); g_source_remove(off_lock_timeout); off_lock_timeout = 0; } } -static gboolean off_lock_timeout_expired(gpointer data) +static void remove_padding_timeout(void) +{ + if (padding_timeout) { + _I("Padding timeout handler removed"); + g_source_remove(padding_timeout); + padding_timeout = 0; + } +} + +static gboolean padding_timeout_expired(gpointer data) { int ret, ref; + int count; - _I("Power lock timeout expired"); + _I("Padding timeout expired"); + + remove_padding_timeout(); ret = tracker_get_power_lock_ref(&ref); if (ret != TRACKER_ERROR_NONE) { @@ -102,10 +117,25 @@ static gboolean off_lock_timeout_expired(gpointer data) } _I("reference count of power lock is (%d)", ref); - if (ref > 0) - return G_SOURCE_CONTINUE; + if (ref > 0) { + _I("Power Lock continue (Reference count > 0 !!)"); + return G_SOURCE_REMOVE; + } + + ret = tracker_get_power_lock_total(&count); + if (ret != TRACKER_ERROR_NONE) { + _E("Failed to get total count of power lock(%d)", ret); + goto out; + } + + if (count != prev_count) { + _I("Power Lock continue (Total reference count increased !!)"); + return G_SOURCE_REMOVE; + } out: + remove_off_lock_timeout(); + ret = device_power_release_lock(POWER_LOCK_CPU); if (ret != DEVICE_ERROR_NONE) _E("Failed to lock power(CPU) again(%d)", ret); @@ -113,16 +143,64 @@ out: return G_SOURCE_REMOVE; } +static void add_padding_timeout(void) +{ + guint id; + + remove_padding_timeout(); + + _I("Padding timeout handler added"); + + id = g_timeout_add(LOCK_CPU_PADDING_TIMEOUT, + padding_timeout_expired, NULL); + if (id) + padding_timeout = id; + else + _E("Failed to add timeout for padding time"); +} + +static gboolean off_lock_timeout_expired(gpointer data) +{ + int ret, ref; + + _I("Power lock timeout expired"); + + ret = tracker_get_power_lock_ref(&ref); + if (ret != TRACKER_ERROR_NONE) { + _E("Failed to get reference count of power lock(%d)", ret); + remove_off_lock_timeout(); + return G_SOURCE_REMOVE; + } + + _I("reference count of power lock is (%d)", ref); + if (ref > 0) + goto out; + + add_padding_timeout(); + + ret = tracker_get_power_lock_total(&prev_count); + if (ret != TRACKER_ERROR_NONE) + _E("Failed to get total count of power lock(%d)", ret); + +out: + return G_SOURCE_CONTINUE; +} + static void add_off_lock_timeout(void) { guint id; remove_off_lock_timeout(); + remove_padding_timeout(); + + _I("Power lock timeout handler added"); id = g_timeout_add(LOCK_CPU_TIMEOUT_MAX, off_lock_timeout_expired, NULL); if (id) off_lock_timeout = id; + else + _E("Failed to add Power Lock timeout handler"); } static void lock_cb(void *data, GVariant *result, GError *err) @@ -251,8 +329,10 @@ int device_power_release_lock(power_lock_e type) if (type == POWER_LOCK_CPU) { ret = unlock_state(DISPLAY_STATE_SCREEN_OFF, PM_SLEEP_MARGIN); - if (ret == 0 && off_lock_timeout > 0) + if (ret == 0 && off_lock_timeout > 0) { remove_off_lock_timeout(); + remove_padding_timeout(); + } } else if (type == POWER_LOCK_DISPLAY) ret = unlock_state(DISPLAY_STATE_NORMAL, PM_KEEP_TIMER); else if (type == POWER_LOCK_DISPLAY_DIM)