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 ce868b8..9b56a58 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 f063ff2..ca2d14d 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 38b771f..a25e98b 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);