power: add timeout not to permit permanent power lock 00/57700/6
authorTaeyoung Kim <ty317.kim@samsung.com>
Fri, 22 Jan 2016 00:28:10 +0000 (09:28 +0900)
committerTaeyoung Kim <ty317.kim@samsung.com>
Sat, 30 Jul 2016 03:24:03 +0000 (20:24 -0700)
- If an app requests permanent power lock and does not
  release the powr lock, power comsumption will be increased
  dramatically. This is not good for the platform.

- Now, a timeout is added not to permit permanent power lock.
  Even if an app requests permanent power lock, the api
  adds timeout with maximum lock time (currently 10 minutes)
  internally. If the timeout is expired, the permanent power
  lock is released.

- Only the way to keep the power lock is to use the platform
  apis which use power lock internally. For example, if an
  app plays music using MM apis, the power lock will be kept
  sinc the MM apis request power lock internally.

Change-Id: I3f11df904f61f720081e5ab63e4e4da130dc85dc
Signed-off-by: Taeyoung Kim <ty317.kim@samsung.com>
CMakeLists.txt
packaging/capi-system-device.spec
src/power.c

index ce868b8edfe8a9cdcc3a7e7eb3beacc4552e5d3a..9b56a58565e5bbf6c2777cd91dfa4dca89fb0663 100755 (executable)
@@ -11,7 +11,14 @@ SET(INC_DIR include)
 INCLUDE_DIRECTORIES(${INC_DIR})
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(${fw_name} REQUIRED dlog vconf capi-base-common capi-system-info gio-2.0)
+pkg_check_modules(${fw_name} REQUIRED
+               dlog
+               vconf
+               capi-base-common
+               capi-system-info
+               gio-2.0
+               tracker
+)
 FOREACH(flag ${${fw_name}_CFLAGS})
     SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
index f063ff2d05564b0e83399ceb6eb90f9aeaf23e72..ca2d14d8a1ad8e4f9436a7fedea134d7f572c1b8 100644 (file)
@@ -12,6 +12,7 @@ BuildRequires:  pkgconfig(capi-system-info)
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(vconf)
 BuildRequires:  pkgconfig(gio-2.0)
+BuildRequires:  pkgconfig(tracker)
 
 %description
 A Device library in TIZEN C API package.
index 38b771f2dc005d83d71475012b7a05473e25da4f..a25e98bbdaa22776200857f7cd9be59202b9c031 100644 (file)
@@ -19,6 +19,7 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <errno.h>
+#include <tracker.h>
 
 #include "power.h"
 #include "display.h"
 #define STR_LCD_DIM   "lcddim"
 #define STR_LCD_ON    "lcdon"
 
+#define LOCK_CPU_TIMEOUT_MAX       600000 /* milliseconds */
+
+static guint off_lock_timeout;
+
 static char *get_state_str(display_state_e state)
 {
        switch (state) {
@@ -75,6 +80,51 @@ static char *get_state_str(display_state_e state)
        return NULL;
 }
 
+static void remove_off_lock_timeout(void)
+{
+       _I("Power lock timeout handler removed");
+       if (off_lock_timeout) {
+               g_source_remove(off_lock_timeout);
+               off_lock_timeout = 0;
+       }
+}
+
+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");
+               goto out;
+       }
+
+       _I("reference count of power lock is (%d)", ref);
+       if (ref > 0)
+               return G_SOURCE_CONTINUE;
+
+out:
+       ret = device_power_release_lock(POWER_LOCK_CPU);
+       if (ret != DEVICE_ERROR_NONE)
+               _E("Failed to lock power(CPU) again(%d)", ret);
+
+       return G_SOURCE_REMOVE;
+}
+
+static void add_off_lock_timeout(void)
+{
+       guint id;
+
+       remove_off_lock_timeout();
+
+       id = g_timeout_add(LOCK_CPU_TIMEOUT_MAX,
+                       off_lock_timeout_expired, NULL);
+       if (id)
+               off_lock_timeout = id;
+}
+
 static void lock_cb(void *data, GVariant *result, GError *err)
 {
        int ret;
@@ -86,6 +136,9 @@ static void lock_cb(void *data, GVariant *result, GError *err)
 
        g_variant_get(result, "(i)", &ret);
        _D("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_LOCK_STATE, ret);
+
+       if (ret < 0)
+               remove_off_lock_timeout();
 }
 
 static int lock_state(display_state_e state, unsigned int flag, int timeout_ms)
@@ -177,9 +230,12 @@ int device_power_request_lock(power_lock_e type, int timeout_ms)
        if (timeout_ms < 0)
                return DEVICE_ERROR_INVALID_PARAMETER;
 
-       if (type == POWER_LOCK_CPU)
+       if (type == POWER_LOCK_CPU) {
                ret = lock_state(DISPLAY_STATE_SCREEN_OFF, STAY_CUR_STATE, timeout_ms);
-       else if (type == POWER_LOCK_DISPLAY)
+               if (ret == 0 &&
+                       (timeout_ms == 0 || timeout_ms > LOCK_CPU_TIMEOUT_MAX))
+                       add_off_lock_timeout();
+       } else if (type == POWER_LOCK_DISPLAY)
                ret = lock_state(DISPLAY_STATE_NORMAL, STAY_CUR_STATE, timeout_ms);
        else if (type == POWER_LOCK_DISPLAY_DIM)
                ret = lock_state(DISPLAY_STATE_SCREEN_DIM, STAY_CUR_STATE, timeout_ms);
@@ -193,9 +249,11 @@ int device_power_release_lock(power_lock_e type)
 {
        int ret;
 
-       if (type == POWER_LOCK_CPU)
+       if (type == POWER_LOCK_CPU) {
                ret = unlock_state(DISPLAY_STATE_SCREEN_OFF, PM_SLEEP_MARGIN);
-       else if (type == POWER_LOCK_DISPLAY)
+               if (ret == 0 && off_lock_timeout > 0)
+                       remove_off_lock_timeout();
+       } else if (type == POWER_LOCK_DISPLAY)
                ret = unlock_state(DISPLAY_STATE_NORMAL, PM_KEEP_TIMER);
        else if (type == POWER_LOCK_DISPLAY_DIM)
                ret = unlock_state(DISPLAY_STATE_SCREEN_DIM, PM_KEEP_TIMER);