Plugin architecture - IoT profile 81/192181/1
authorHyotaek Shim <hyotaek.shim@samsung.com>
Wed, 31 Oct 2018 08:27:09 +0000 (17:27 +0900)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Wed, 31 Oct 2018 08:27:09 +0000 (17:27 +0900)
Change-Id: I524ab65b1ec77f472249d86c2c6611cdb30412f1
Signed-off-by: Hyotaek Shim <hyotaek.shim@samsung.com>
16 files changed:
CMakeLists.txt
packaging/deviced.spec
plugins/iot/display/CMakeLists.txt [new file with mode: 0644]
plugins/iot/display/ambient-mode.c [new file with mode: 0644]
plugins/iot/display/auto-brightness.c [new file with mode: 0644]
plugins/iot/display/core.c [new file with mode: 0755]
plugins/iot/display/device-interface.c [new file with mode: 0755]
plugins/iot/display/display-actor.c [new file with mode: 0644]
plugins/iot/display/display-dbus.c [new file with mode: 0755]
plugins/iot/display/display-ops.c [new file with mode: 0644]
plugins/iot/display/dpms-wayland-none.c [new file with mode: 0644]
plugins/iot/display/input.c [new file with mode: 0644]
plugins/iot/display/key-filter.c [new file with mode: 0644]
plugins/iot/display/lock-detector.c [new file with mode: 0644]
plugins/iot/display/poll.c [new file with mode: 0644]
plugins/iot/display/setting.c [new file with mode: 0644]

index e988990..f08ee01 100755 (executable)
@@ -281,3 +281,4 @@ ADD_SUBDIRECTORY(src/auto-test)
 ADD_SUBDIRECTORY(plugins/mobile/display)
 ADD_SUBDIRECTORY(plugins/wearable/display)
 ADD_SUBDIRECTORY(plugins/tv/display)
+ADD_SUBDIRECTORY(plugins/iot/display)
index 35e926c..c0c3365 100755 (executable)
@@ -114,6 +114,14 @@ Requires:   %{name} = %{version}-%{release}
 %description plugin-profile-tv
 Plugin libraries for TV devices
 
+%package plugin-profile-iot
+Summary:    Plugin libraries for IoT devices
+Group:      System/Management
+Requires:   %{name} = %{version}-%{release}
+
+%description plugin-profile-iot
+Plugin libraries for IoT devices
+
 %prep
 %setup -q
 
@@ -213,6 +221,10 @@ mv %{_libdir}/wearable-display.so %{_libdir}/deviced/display.so
 mkdir -p %{_libdir}/deviced
 mv %{_libdir}/tv-display.so %{_libdir}/deviced/display.so
 
+%post plugin-profile-iot
+mkdir -p %{_libdir}/deviced
+mv %{_libdir}/iot-display.so %{_libdir}/deviced/display.so
+
 %files
 %manifest %{name}.manifest
 %license LICENSE.Apache-2.0
@@ -286,3 +298,9 @@ mv %{_libdir}/tv-display.so %{_libdir}/deviced/display.so
 %license LICENSE.Apache-2.0
 %defattr(-,root,root,-)
 %{_libdir}/tv-display.so
+
+%files plugin-profile-iot
+%manifest deviced.manifest
+%license LICENSE.Apache-2.0
+%defattr(-,root,root,-)
+%{_libdir}/iot-display.so
diff --git a/plugins/iot/display/CMakeLists.txt b/plugins/iot/display/CMakeLists.txt
new file mode 100644 (file)
index 0000000..95ccb0d
--- /dev/null
@@ -0,0 +1,27 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(iot-display C)
+
+FILE(GLOB ALL_SRCS "*.c")
+SET(SRCS ${ALL_SRCS})
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/core ${CMAKE_SOURCE_DIR}/src/display)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(libpkgs REQUIRED
+       dlog
+       glib-2.0
+       gio-2.0
+       gio-unix-2.0
+       libinput
+       capi-system-sensor)
+
+FOREACH(flag ${libpkgs_CFLAGS})
+       SET(EXTRA_LIB_CFLAGS "${EXTRA_LIB_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_LIB_CFLAGS}")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${libpkgs_LDFLAGS})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "")
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES OUTPUT_NAME iot-display)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
diff --git a/plugins/iot/display/ambient-mode.c b/plugins/iot/display/ambient-mode.c
new file mode 100644 (file)
index 0000000..7b0e399
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdbool.h>
+#include <fcntl.h>
+#include <libgdbus/dbus-system.h>
+
+#include "util.h"
+#include "core.h"
+#include "display-ops.h"
+#include "core/device-notifier.h"
+#include "core/devices.h"
+
+#define ON             "on"
+#define OFF            "off"
+
+#define SIGNAL_AMBIENT_MODE                    "AmbientMode"
+#define CLOCK_START                    "clockstart"
+#define CLOCK_END                      "clockend"
+#define TIMEOUT_NONE                   (-1)
+#define AMBIENT_CLOCK_WAITING_TIME     5000 /* ms */
+
+extern struct display_plugin disp_plgn;
+static int ambient_state;
+static pid_t ambient_pid;  /* Ambient Clock pid */
+static int ambient_condition;
+static unsigned int update_count;
+
+void broadcast_ambient_state(int state)
+{
+       dbus_handle_broadcast_dbus_signal_var(DEVICED_PATH_DISPLAY,
+                                               DEVICED_INTERFACE_DISPLAY,
+                                               SIGNAL_AMBIENT_MODE,
+                                               g_variant_new("(i)", (state == 0 ? 0 : 1)));
+}
+
+int ambient_get_condition(void)
+{
+       return ambient_condition;
+}
+
+int ambient_get_state(void)
+{
+       return ambient_state;
+}
+
+static void ambient_set_condition(keynode_t *key_nodes, void *data)
+{
+       int state;
+
+       if (key_nodes == NULL) {
+               _E("wrong parameter, key_nodes is null");
+               return;
+       }
+
+       ambient_condition = vconf_keynode_get_bool(key_nodes);
+       _I("ambient mode condition is %d", ambient_condition);
+
+       state = (ambient_condition == 0 ? 0 : 1);
+       device_notify(DEVICE_NOTIFIER_DISPLAY_AMBIENT_CONDITION, (void *)&state);
+
+       set_dim_state(state);
+}
+
+int ambient_set_state(int on)
+{
+       if (!ambient_condition)
+               return 0;
+
+       broadcast_ambient_state(on);
+
+       update_count = 0;
+
+       if (!on)
+               ambient_pid = 0;
+
+       _D("AMBIENT is %s", (on ? ON : OFF));
+
+       ambient_state = on;
+
+       device_notify(DEVICE_NOTIFIER_DISPLAY_AMBIENT_STATE, (void *)&ambient_state);
+
+       return 0;
+}
+
+void ambient_check_invalid_state(pid_t pid)
+{
+       if (pid != INTERNAL_LOCK_AMBIENT)
+               return;
+
+       if (backlight_ops.get_lcd_power() == DPMS_OFF)
+               return;
+
+       if (is_emulator()) {
+               /* In emulator, deviced does not turn off the display. */
+               if (backlight_ops.get_lcd_power() == DPMS_ON)
+                       return;
+       }
+
+       if (ambient_get_state() == false)
+               return;
+
+       _E("Invalid state! Ambient state is change to off!");
+
+       /* If lcd_power is on and ambient state is true
+        * when pm state is changed to sleep,
+        * deviced doesn't get the clock signal.
+        * deviced just turns off lcd in this case. */
+
+       ambient_set_state(false);
+       backlight_ops.off(NORMAL_MODE);
+}
+
+static void start_clock(void)
+{
+       if (pm_cur_state == S_NORMAL ||
+           pm_cur_state == S_LCDDIM ||
+           ambient_state == false)
+               return;
+
+       if (disp_plgn.pm_lock_internal)
+               disp_plgn.pm_lock_internal(INTERNAL_LOCK_AMBIENT, LCD_OFF, STAY_CUR_STATE, 
+                       AMBIENT_CLOCK_WAITING_TIME);
+}
+
+static void end_clock(pid_t pid)
+{
+       if (pm_cur_state == S_NORMAL ||
+           pm_cur_state == S_LCDDIM ||
+           ambient_state == false)
+               return;
+
+       if (update_count == 0)
+               broadcast_lcd_off_late(LCD_OFF_LATE_MODE);
+
+       if (disp_plgn.pm_unlock_internal)
+               disp_plgn.pm_unlock_internal(INTERNAL_LOCK_AMBIENT, LCD_OFF, PM_SLEEP_MARGIN);
+
+       update_count++;
+       if (update_count == UINT_MAX)
+               update_count = 1;
+       ambient_pid = pid;
+
+       _I("enter real ambient state by %d",
+           ambient_pid);
+}
+
+int ambient_set_screen(char *screen, pid_t pid)
+{
+       if (!screen)
+               return -EINVAL;
+
+       if (!strncmp(screen, CLOCK_START, strlen(CLOCK_START)))
+               start_clock();
+       else if (!strncmp(screen, CLOCK_END, strlen(CLOCK_END)))
+               end_clock(pid);
+
+       return 0;
+}
+
+static void ambient_init(void *data)
+{
+       int ret;
+
+       ret = vconf_get_bool(VCONFKEY_SETAPPL_AMBIENT_MODE_BOOL,
+           &ambient_condition);
+       if (ret < 0) {
+               _E("Failed to get ambient mode condition ! (%d)", ret);
+               ambient_condition = false;
+       }
+       _I("ambient mode condition is %d", ambient_condition);
+
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_AMBIENT_MODE_BOOL,
+           ambient_set_condition, NULL);
+}
+
+static void ambient_exit(void *data)
+{
+       ambient_set_state(false);
+       vconf_ignore_key_changed(VCONFKEY_SETAPPL_AMBIENT_MODE_BOOL,
+                       ambient_set_condition);
+}
+
+static const struct display_ops ambient_ops = {
+       .name     = "ambient",
+       .init     = ambient_init,
+       .exit     = ambient_exit,
+};
+
+DISPLAY_OPS_REGISTER(&ambient_ops)
+
diff --git a/plugins/iot/display/auto-brightness.c b/plugins/iot/display/auto-brightness.c
new file mode 100644 (file)
index 0000000..0a36de1
--- /dev/null
@@ -0,0 +1,667 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <math.h>
+#include <limits.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <vconf.h>
+#include <sensor.h>
+
+
+#include "util.h"
+#include "core.h"
+#include "display-ops.h"
+#include "device-node.h"
+#include "setting.h"
+#include "core/device-notifier.h"
+#include "core/config-parser.h"
+
+#define METHOD_CHECK_SUPPORTED "CheckSupported"
+
+#define DISP_FORCE_SHIFT       12
+#define DISP_FORCE_CMD(prop, force)    (((force) << DISP_FORCE_SHIFT) | prop)
+
+#define SAMPLING_INTERVAL      1       /* 1 sec */
+#define MAX_SAMPLING_COUNT     3
+#define MAX_FAULT              5
+#define DEFAULT_AUTOMATIC_BRT  5
+#define AUTOMATIC_DEVIDE_VAL   10
+#define AUTOMATIC_DELAY_TIME   0.5     /* 0.5 sec */
+
+#define RADIAN_VALUE           (57.2957)
+#define ROTATION_90            90
+#define WORKING_ANGLE_MIN      0
+#define WORKING_ANGLE_MAX      20
+
+#define BOARD_CONF_FILE "/etc/deviced/display.conf"
+
+#define ON_LUX         -1
+#define OFF_LUX                -1
+#define ON_COUNT       1
+#define OFF_COUNT      1
+
+static int (*_default_action) (int);
+static guint alc_timeout_id = 0;
+static guint update_timeout;
+static sensor_listener_h light_listener;
+static sensor_listener_h accel_listener;
+static int fault_count;
+static int automatic_brt = DEFAULT_AUTOMATIC_BRT;
+static int min_brightness = PM_MIN_BRIGHTNESS;
+static char *min_brightness_name = 0;
+
+/* light sensor */
+static float lmax, lmin;
+
+static bool update_working_position(void)
+{
+       sensor_event_s data;
+       int ret;
+       float x, y, z, pitch, realg;
+
+       if (!display_conf.accel_sensor_on)
+               return false;
+
+       ret = sensor_listener_read_data(accel_listener, &data);
+       if (ret != SENSOR_ERROR_NONE) {
+               _E("Fail to get accelerometer data! %d", ret);
+               return true;
+       }
+
+       x = data.values[0];
+       y = data.values[1];
+       z = data.values[2];
+
+       realg = (float)sqrt((x * x) + (y * y) + (z * z));
+       pitch = ROTATION_90 - abs((int) (asin(z / realg) * RADIAN_VALUE));
+
+       _D("accel data [%f, %f, %f] - %f", x, y, z, pitch);
+
+       if (pitch >= WORKING_ANGLE_MIN && pitch <= WORKING_ANGLE_MAX)
+               return true;
+       return false;
+}
+
+static void alc_set_brightness(int setting, int value, float light)
+{
+       static float old;
+       int position, tmp_value = 0, ret;
+
+       ret = backlight_ops.get_brightness(&tmp_value);
+       if (ret < 0) {
+               _E("Fail to get display brightness!");
+               return;
+       }
+
+       if (value < min_brightness)
+               value = min_brightness;
+
+       if (tmp_value != value) {
+               if (!setting && min_brightness == PM_MIN_BRIGHTNESS &&
+                   display_conf.accel_sensor_on == true) {
+                       position = update_working_position();
+                       if (!position && (old > light)) {
+                               _D("It's not working position, "
+                                   "LCD isn't getting dark!");
+                               return;
+                       }
+               }
+               int diff, step;
+
+               diff = value - tmp_value;
+               if (abs(diff) < display_conf.brightness_change_step)
+                       step = (diff > 0 ? 1 : -1);
+               else
+                       step = (int)ceil(diff /
+                           (float)display_conf.brightness_change_step);
+
+               _D("%d", step);
+               while (tmp_value != value) {
+                       if (step == 0) break;
+
+                       tmp_value += step;
+                       if ((step > 0 && tmp_value > value) ||
+                           (step < 0 && tmp_value < value))
+                               tmp_value = value;
+
+                       backlight_ops.set_default_brt(tmp_value);
+                       backlight_ops.update();
+               }
+               _I("load light data:%f ,auto brt %d,min brightness %d,"
+                   "brightness %d", light, automatic_brt, min_brightness, value);
+               old = light;
+       }
+}
+
+static bool check_brightness_changed(int value)
+{
+       int i;
+       static int values[MAX_SAMPLING_COUNT], count = 0;
+
+       if (count >= MAX_SAMPLING_COUNT || count < 0)
+               count = 0;
+
+       values[count++] = value;
+
+       for (i = 0; i < MAX_SAMPLING_COUNT - 1; i++)
+               if (values[i] != values[i+1])
+                       return false;
+       return true;
+}
+
+static bool alc_update_brt(bool setting)
+{
+       int value = 0;
+       int ret = -1;
+       sensor_event_s light_data;
+       int index;
+       float light;
+
+       ret = sensor_listener_read_data(light_listener, &light_data);
+       if (ret != SENSOR_ERROR_NONE) {
+               _E("Failed to read light sensor data(%d)", ret);
+               goto out;
+       }
+
+       index = light_data.value_count - 1;
+       if (index < 0 || light_data.values[index] < 0) {
+               _E("Invalid light sensor data");
+               goto out;
+       }
+
+       light = light_data.values[index];
+       ret = backlight_ops.get_brightness_by_light_sensor(
+                       lmax, lmin, light, &value);
+       if (ret == -ENOTSUP) {
+               _E("Not supported to handle the light data");
+               goto out;
+       }
+
+       if (ret < 0 || value < PM_MIN_BRIGHTNESS || value > PM_MAX_BRIGHTNESS) {
+               _E("fail to load light data : light(%f), value(%d), ret(%d)", light, value, ret);
+               goto out;
+       }
+
+       fault_count = 0;
+
+       if (display_conf.continuous_sampling &&
+               !check_brightness_changed(value) &&
+               !setting)
+               return true;
+
+       alc_set_brightness(setting, value, light);
+
+       return true;
+
+out:
+       fault_count++;
+
+       if ((fault_count > MAX_FAULT) && !(pm_status_flag & PWROFF_FLAG)) {
+               if (alc_timeout_id) {
+                       g_source_remove(alc_timeout_id);
+                       alc_timeout_id = 0;
+               }
+               vconf_set_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT,
+                   SETTING_BRIGHTNESS_AUTOMATIC_OFF);
+               _E("Fault counts is over %d, disable automatic brightness", MAX_FAULT);
+               return false;
+       }
+       return true;
+}
+
+static gboolean alc_handler(void *data)
+{
+       if (pm_cur_state != S_NORMAL) {
+               if (alc_timeout_id > 0)
+                       g_source_remove(alc_timeout_id);
+               alc_timeout_id = 0;
+               return G_SOURCE_REMOVE;
+       }
+
+       if (!alc_update_brt(false))
+               return G_SOURCE_REMOVE;
+
+       if (alc_timeout_id != 0)
+               return G_SOURCE_CONTINUE;
+
+       return G_SOURCE_REMOVE;
+}
+
+static int alc_action(int timeout)
+{
+       /* sampling timer add */
+       if (alc_timeout_id == 0 && !(pm_status_flag & PWRSV_FLAG)) {
+               display_info.update_auto_brightness(true);
+
+               alc_timeout_id =
+                   g_timeout_add_seconds(display_conf.lightsensor_interval,
+                           alc_handler, NULL);
+       }
+
+       if (_default_action != NULL)
+               return _default_action(timeout);
+
+       /* unreachable code */
+       return -1;
+}
+
+static int connect_sensor(void)
+{
+       int ret;
+       sensor_h sensor;
+       sensor_h *list = NULL;
+       int cnt = 0;
+
+       _I("connect with sensor fw");
+       /* light sensor */
+       ret = sensor_get_sensor_list(SENSOR_LIGHT, &list, &cnt);
+       if (ret != SENSOR_ERROR_NONE) {
+               _E("Failed to get light sensor list(%d)", ret);
+               goto error;
+       }
+
+       /* TODO
+        * Sensor apis will be fixed
+        * to provide which sensor is effective among sensors */
+       if (cnt == 3) /* three light sensors exist */
+               sensor = list[2];
+       else
+               sensor = list[0];
+
+       free(list);
+
+       ret = sensor_get_min_range(sensor, &lmin);
+       if (ret != SENSOR_ERROR_NONE) {
+               _E("Failed to get light sensor min range (%d)", ret);
+               goto error;
+       }
+       ret = sensor_get_max_range(sensor, &lmax);
+       if (ret != SENSOR_ERROR_NONE) {
+               _E("Failed to get light sensor max range (%d)", ret);
+               goto error;
+       }
+       _I("Light sensor min(%f), max(%f)", lmin, lmax);
+
+       ret = sensor_create_listener(sensor, &light_listener);
+       if (ret != SENSOR_ERROR_NONE) {
+               _E("Failed to create listener(light)!");
+               goto error;
+       }
+       sensor_listener_set_option(light_listener, SENSOR_OPTION_ALWAYS_ON);
+       ret = sensor_listener_start(light_listener);
+       if (ret != SENSOR_ERROR_NONE) {
+               _E("Failed to start light sensor!");
+               sensor_destroy_listener(light_listener);
+               light_listener = 0;
+               goto error;
+       }
+
+       if (!display_conf.accel_sensor_on)
+               goto success;
+
+       /* accelerometer sensor */
+       ret = sensor_get_default_sensor(SENSOR_ACCELEROMETER, &sensor);
+       if (ret != SENSOR_ERROR_NONE) {
+               _E("Failed to get default accel sensor!");
+               goto error;
+       }
+       ret = sensor_create_listener(&sensor, &accel_listener);
+       if (ret != SENSOR_ERROR_NONE) {
+               _E("Failed to create listener(accel)!");
+               goto error;
+       }
+       sensor_listener_set_option(accel_listener, SENSOR_OPTION_ALWAYS_ON);
+       ret = sensor_listener_start(accel_listener);
+       if (ret != SENSOR_ERROR_NONE) {
+               _E("Failed to start accel sensor!");
+               sensor_destroy_listener(accel_listener);
+               accel_listener = 0;
+               goto error;
+       }
+
+success:
+       fault_count = 0;
+       return 0;
+
+error:
+       if (light_listener > 0) {
+               sensor_listener_stop(light_listener);
+               sensor_destroy_listener(light_listener);
+               light_listener = 0;
+       }
+       if (display_conf.accel_sensor_on && accel_listener > 0) {
+               sensor_listener_stop(accel_listener);
+               sensor_destroy_listener(accel_listener);
+               accel_listener = 0;
+       }
+       return -EIO;
+}
+
+static int disconnect_sensor(void)
+{
+       _I("disconnect with sensor fw");
+       /* light sensor*/
+       if (light_listener > 0) {
+               sensor_listener_stop(light_listener);
+               sensor_destroy_listener(light_listener);
+               light_listener = 0;
+       }
+
+       /* accelerometer sensor*/
+       if (display_conf.accel_sensor_on && accel_listener > 0) {
+               sensor_listener_stop(accel_listener);
+               sensor_destroy_listener(accel_listener);
+               accel_listener = 0;
+       }
+
+       if (_default_action != NULL) {
+               states[S_NORMAL].action = _default_action;
+               _default_action = NULL;
+       }
+       if (alc_timeout_id > 0) {
+               g_source_remove(alc_timeout_id);
+               alc_timeout_id = 0;
+       }
+
+       return 0;
+}
+
+void set_brightness_changed_state(void)
+{
+       if (pm_status_flag & PWRSV_FLAG) {
+               pm_status_flag |= BRTCH_FLAG;
+               _D("brightness changed in low battery,"
+                   "escape dim state (light)");
+       }
+}
+
+static int set_autobrightness_state(int status)
+{
+       int ret = -1;
+       int brt = -1;
+       int default_brt = -1;
+
+       if (status == SETTING_BRIGHTNESS_AUTOMATIC_ON) {
+               if (connect_sensor() < 0)
+                       return -1;
+
+               /* escape dim state if it's in low battery.*/
+               set_brightness_changed_state();
+
+               /* change alc action func */
+               if (_default_action == NULL)
+                       _default_action = states[S_NORMAL].action;
+               states[S_NORMAL].action = alc_action;
+
+               display_info.update_auto_brightness(true);
+
+               alc_timeout_id =
+                   g_timeout_add_seconds(display_conf.lightsensor_interval,
+                           alc_handler, NULL);
+       } else if (status == SETTING_BRIGHTNESS_AUTOMATIC_PAUSE) {
+               _I("auto brightness paused!");
+               disconnect_sensor();
+       } else {
+               disconnect_sensor();
+               /* escape dim state if it's in low battery.*/
+               set_brightness_changed_state();
+
+               ret = get_setting_brightness(&default_brt);
+               if (ret != 0 || (default_brt < PM_MIN_BRIGHTNESS || default_brt > PM_MAX_BRIGHTNESS)) {
+                       _I("fail to read vconf value for brightness");
+                       brt = PM_DEFAULT_BRIGHTNESS;
+                       if (default_brt < PM_MIN_BRIGHTNESS || default_brt > PM_MAX_BRIGHTNESS)
+                               vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
+                       default_brt = brt;
+               }
+
+               backlight_ops.set_default_brt(default_brt);
+               backlight_ops.update();
+       }
+
+       return 0;
+}
+
+static void set_alc_function(keynode_t *key_nodes, void *data)
+{
+       int status, ret;
+
+       if (key_nodes == NULL) {
+               _E("wrong parameter, key_nodes is null");
+               return;
+       }
+
+       status = vconf_keynode_get_int(key_nodes);
+
+       switch (status) {
+       case SETTING_BRIGHTNESS_AUTOMATIC_OFF:
+       case SETTING_BRIGHTNESS_AUTOMATIC_ON:
+       case SETTING_BRIGHTNESS_AUTOMATIC_PAUSE:
+               ret = set_autobrightness_state(status);
+               _D("set auto brightness : %d", ret);
+               break;
+       default:
+               _E("invalid value! %d", status);
+       }
+}
+
+static void set_alc_automatic_brt(keynode_t *key_nodes, void *data)
+{
+       if (key_nodes == NULL) {
+               _E("wrong parameter, key_nodes is null");
+               return;
+       }
+       automatic_brt = vconf_keynode_get_int(key_nodes) / AUTOMATIC_DEVIDE_VAL;
+       _D("automatic brt : %d", automatic_brt);
+
+       alc_update_brt(true);
+}
+
+static gboolean update_handler(void *data)
+{
+       int ret, on;
+
+       update_timeout = 0;
+
+       if (pm_cur_state != S_NORMAL)
+               return G_SOURCE_REMOVE;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &on);
+       if (ret < 0 || on != SETTING_BRIGHTNESS_AUTOMATIC_ON)
+               return G_SOURCE_REMOVE;
+
+       _D("auto brightness is working!");
+       alc_update_brt(true);
+
+       return G_SOURCE_REMOVE;
+}
+
+static void update_auto_brightness(bool update)
+{
+       if (update_timeout) {
+               g_source_remove(update_timeout);
+               update_timeout = 0;
+       }
+
+       if (update) {
+               update_timeout = g_timeout_add_seconds(AUTOMATIC_DELAY_TIME,
+                   update_handler, NULL);
+       }
+}
+
+static int prepare_lsensor(void *data)
+{
+       int status, ret;
+       int brt = -1;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &status);
+
+       if (ret == 0 && status == SETTING_BRIGHTNESS_AUTOMATIC_ON)
+               set_autobrightness_state(status);
+
+       /* add auto_brt_setting change handler */
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT,
+                                set_alc_function, NULL);
+
+       vconf_get_int(VCONFKEY_SETAPPL_LCD_AUTOMATIC_BRIGHTNESS, &brt);
+       if (brt < PM_MIN_BRIGHTNESS || brt > PM_MAX_BRIGHTNESS) {
+               _E("Failed to get automatic brightness!");
+       } else {
+               automatic_brt = brt / AUTOMATIC_DEVIDE_VAL;
+               _I("automatic brt init success %d", automatic_brt);
+       }
+
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_LCD_AUTOMATIC_BRIGHTNESS,
+                               set_alc_automatic_brt, NULL);
+
+       return 0;
+}
+
+static void update_brightness_direct(void)
+{
+       int ret, status;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &status);
+       if (ret == 0 && status == SETTING_BRIGHTNESS_AUTOMATIC_ON)
+               alc_update_brt(true);
+}
+
+static int set_autobrightness_min(int val, char *name)
+{
+       if (!name)
+               return -EINVAL;
+
+       if (val < PM_MIN_BRIGHTNESS || val > PM_MAX_BRIGHTNESS)
+               return -EINVAL;
+
+       min_brightness = val;
+
+       if (min_brightness_name) {
+               free(min_brightness_name);
+               min_brightness_name = 0;
+       }
+       min_brightness_name = strndup(name, strlen(name));
+
+       update_brightness_direct();
+
+       _I("auto brightness min value changed! (%d, %s)",
+           min_brightness, min_brightness_name);
+
+       return 0;
+}
+
+static void reset_autobrightness_min(GDBusConnection *conn,
+       const gchar     *sender,
+       const gchar     *unique_name,
+       gpointer         data)
+{
+       if (!sender)
+               return;
+
+       if (!min_brightness_name)
+               return;
+
+       if (strcmp(sender, min_brightness_name))
+               return;
+
+       _I("change to default %d -> %d, %s", min_brightness,
+           PM_MIN_BRIGHTNESS, min_brightness_name);
+       min_brightness = PM_MIN_BRIGHTNESS;
+       if (min_brightness_name) {
+               free(min_brightness_name);
+               min_brightness_name = 0;
+       }
+
+       update_brightness_direct();
+}
+
+static int lcd_changed_cb(void *data)
+{
+       int lcd_state;
+
+       if (!data)
+               return 0;
+       lcd_state = *(int *)data;
+       if (lcd_state == S_LCDOFF && alc_timeout_id > 0) {
+               g_source_remove(alc_timeout_id);
+               alc_timeout_id = 0;
+       }
+
+       return 0;
+}
+
+static int booting_done_cb(void *data)
+{
+       int state;
+
+       if (!data)
+               return 0;
+
+       state = *(int *)data;
+       if (state != true)
+               return 0;
+
+       /* get light data from sensor fw */
+       prepare_lsensor(NULL);
+
+       return 0;
+}
+
+static void exit_lsensor(void)
+{
+       vconf_ignore_key_changed(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT,
+           set_alc_function);
+
+       vconf_ignore_key_changed(VCONFKEY_SETAPPL_LCD_AUTOMATIC_BRIGHTNESS,
+           set_alc_automatic_brt);
+
+       set_autobrightness_state(SETTING_BRIGHTNESS_AUTOMATIC_OFF);
+}
+
+static void auto_brightness_init(void *data)
+{
+       display_info.update_auto_brightness = update_auto_brightness;
+       display_info.set_autobrightness_min = set_autobrightness_min;
+       display_info.reset_autobrightness_min = reset_autobrightness_min;
+
+       register_notifier(DEVICE_NOTIFIER_LCD, lcd_changed_cb);
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done_cb);
+}
+
+static void auto_brightness_exit(void *data)
+{
+       exit_lsensor();
+
+       unregister_notifier(DEVICE_NOTIFIER_LCD, lcd_changed_cb);
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done_cb);
+}
+
+static const struct display_ops display_autobrightness_ops = {
+       .name     = "auto-brightness",
+       .init     = auto_brightness_init,
+       .exit     = auto_brightness_exit,
+};
+
+DISPLAY_OPS_REGISTER(&display_autobrightness_ops)
+
diff --git a/plugins/iot/display/core.c b/plugins/iot/display/core.c
new file mode 100755 (executable)
index 0000000..670a6bc
--- /dev/null
@@ -0,0 +1,2432 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * @file       core.c
+ * @brief      Power manager main loop.
+ *
+ * This file includes Main loop, the FSM, signal processing.
+ */
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <vconf-keys.h>
+#include <sys/time.h>
+#include <tzplatform_config.h>
+#include <libgdbus/dbus-system.h>
+
+#include "ambient-mode.h"
+#include "util.h"
+#include "core.h"
+#include "device-node.h"
+#include "lock-detector.h"
+#include "display-ops.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+#include "core/udev.h"
+#include "core/list.h"
+#include "core/common.h"
+#include "battery/battery.h"
+#include "shared/plugin.h"
+#include "core/config-parser.h"
+#include "core/launch.h"
+#include "extcon/extcon.h"
+#include "power/power-handler.h"
+#include "dd-display.h"
+
+#define PM_STATE_LOG_FILE    tzplatform_mkpath(TZ_SYS_ALLLOGS, "pm_state.log")
+#define DISPLAY_CONF_FILE    "/etc/deviced/display.conf"
+
+/**
+ * @addtogroup POWER_MANAGER
+ * @{
+ */
+
+#define SET_BRIGHTNESS_IN_BOOTLOADER   "/usr/bin/save_blenv SLP_LCD_BRIGHT"
+#define LOCK_SCREEN_INPUT_TIMEOUT      10000
+#define LOCK_SCREEN_CONTROL_TIMEOUT    5000
+#define DD_LCDOFF_INPUT_TIMEOUT                3000
+#define ALWAYS_ON_TIMEOUT                      3600000  //3600000 = 1 hour
+
+#define GESTURE_STR            "gesture"
+#define POWER_KEY_STR          "powerkey"
+#define TOUCH_STR              "touch"
+#define EVENT_STR              "event"
+#define TIMEOUT_STR            "timeout"
+#define UNKNOWN_STR            "unknown"
+
+extern void init_pm_internal();
+extern struct display_plugin disp_plgn;
+unsigned int pm_status_flag;
+static int trans_condition;
+
+static void (*power_saving_func) (int onoff);
+static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
+
+int pm_cur_state;
+int pm_old_state;
+guint timeout_src_id;
+static unsigned int custom_normal_timeout = 0;
+static unsigned int custom_dim_timeout = 0;
+static int custom_holdkey_block = false;
+static int custom_change_pid = -1;
+static char *custom_change_name;
+static bool hallic_open = true;
+static guint lock_timeout_id;
+static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
+static struct timeval lcdon_tv;
+static int lcd_paneloff_mode = false;
+static int stay_touchscreen_off = false;
+static dd_list *lcdon_ops;
+static bool lcdon_broadcast = true;
+static bool touch_blocked = false;
+
+/* default transition, action fuctions */
+static int default_trans(int evt);
+static int default_action(int timeout);
+static int default_check(int curr, int next);
+
+static gboolean del_normal_cond(void *data);
+static gboolean del_dim_cond(void *data);
+static gboolean del_off_cond(void *data);
+
+static int default_proc_change_state(unsigned int cond, pid_t pid);
+static int (*proc_change_state)(unsigned int cond, pid_t pid) = default_proc_change_state;
+
+struct state states[S_END] = {
+       { S_START,    "S_START",    NULL,          NULL,           NULL,          NULL            },
+       { S_NORMAL,   "S_NORMAL",   default_trans, default_action, default_check, del_normal_cond },
+       { S_LCDDIM,   "S_LCDDIM",   default_trans, default_action, default_check, del_dim_cond    },
+       { S_LCDOFF,   "S_LCDOFF",   default_trans, default_action, default_check, del_off_cond    },
+       { S_STANDBY,  "S_STANDBY",  NULL,          NULL,           NULL,          NULL            },
+       { S_SLEEP,    "S_SLEEP",    default_trans, default_action, default_check, NULL            },
+       { S_POWEROFF, "S_POWEROFF", NULL,          NULL,           NULL,          NULL            },
+};
+
+static int trans_table[S_END][EVENT_END] = {
+       /* Timeout,   Input */
+       { S_START,    S_START    }, /* S_START */
+       { S_LCDDIM,   S_NORMAL   }, /* S_NORMAL */
+       { S_LCDOFF,   S_NORMAL   }, /* S_LCDDIM */
+       { S_SLEEP,    S_NORMAL   }, /* S_LCDOFF */
+       { S_SLEEP,    S_STANDBY  }, /* S_STANDBY */
+       { S_LCDOFF,   S_NORMAL   }, /* S_SLEEP */
+       { S_POWEROFF, S_POWEROFF }, /* S_POWEROFF */
+};
+
+enum signal_type {
+       SIGNAL_INVALID = 0,
+       SIGNAL_PRE,
+       SIGNAL_POST,
+       SIGNAL_MAX,
+};
+
+static const char *lcdon_sig_lookup[SIGNAL_MAX] = {
+       [SIGNAL_PRE]  = "LCDOn",
+       [SIGNAL_POST] = "LCDOnCompleted",
+};
+static const char *lcdoff_sig_lookup[SIGNAL_MAX] = {
+       [SIGNAL_PRE]  = "LCDOff",
+       [SIGNAL_POST] = "LCDOffCompleted",
+};
+
+#define SHIFT_UNLOCK           4
+#define SHIFT_CHANGE_STATE     7
+#define CHANGE_STATE_BIT       0xF00   /* 1111 0000 0000 */
+#define SHIFT_LOCK_FLAG        16
+#define SHIFT_CHANGE_TIMEOUT   20
+#define CUSTOM_TIMEOUT_BIT     0x1
+#define CUSTOM_HOLDKEY_BIT     0x2
+#define HOLD_KEY_BLOCK_BIT     0x1
+#define TIMEOUT_NONE           (-1)
+
+#define S_COVER_TIMEOUT                        8000
+#define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
+#define BOOTING_DONE_WATING_TIME       60000   /* 1 minute */
+#define LOCK_TIME_WARNING              60      /* 60 seconds */
+
+#define ACTIVE_ACT "active"
+#define INACTIVE_ACT "inactive"
+
+#define LOCK_SCREEN_WATING_TIME                0.3     /* 0.3 second */
+#define LONG_PRESS_INTERVAL             2       /* 2 seconds */
+#define SAMPLING_INTERVAL              1       /* 1 sec */
+#define BRIGHTNESS_CHANGE_STEP         10
+#define LCD_ALWAYS_ON                  1
+#define ACCEL_SENSOR_ON                        1
+#define CONTINUOUS_SAMPLING            1
+#define LCDOFF_TIMEOUT                 500     /* milli second */
+
+#define DIFF_TIMEVAL_MS(a, b) \
+       (((a.tv_sec * 1000000 + a.tv_usec) - \
+       (b.tv_sec * 1000000 + b.tv_usec)) \
+       / 1000)
+
+struct display_config display_conf = {
+       .lock_wait_time         = LOCK_SCREEN_WATING_TIME,
+       .longpress_interval     = LONG_PRESS_INTERVAL,
+       .lightsensor_interval   = SAMPLING_INTERVAL,
+       .lcdoff_timeout         = LCDOFF_TIMEOUT,
+       .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
+       .lcd_always_on          = LCD_ALWAYS_ON,
+       .framerate_app          = {1, 0, 0, 0},
+       .control_display        = 1,
+       .powerkey_doublepress   = 0,
+       .accel_sensor_on        = ACCEL_SENSOR_ON,
+       .continuous_sampling    = CONTINUOUS_SAMPLING,
+       .timeout_enable         = false,
+       .input_support          = true,
+};
+
+struct display_function_info display_info = {
+       .update_auto_brightness         = NULL,
+       .set_autobrightness_min         = NULL,
+       .reset_autobrightness_min       = NULL,
+       .face_detection                 = NULL,
+};
+
+typedef struct _pm_lock_node {
+       pid_t pid;
+       guint timeout_id;
+       time_t time;
+       bool holdkey_block;
+       bool background;
+} PmLockNode;
+
+static dd_list *cond_head[S_END];
+
+static void set_process_active(bool flag, pid_t pid)
+{
+       int ret;
+
+       if (pid >= INTERNAL_LOCK_BASE)
+               return;
+
+       /* Send dbug to resourced */
+       ret = dbus_handle_broadcast_dbus_signal_var(RESOURCED_PATH_PROCESS,
+                                                   RESOURCED_INTERFACE_PROCESS,
+                                                   RESOURCED_METHOD_ACTIVE,
+                                                   g_variant_new("(si)", (flag ? ACTIVE_ACT : INACTIVE_ACT), pid));
+       if (ret < 0)
+               _E("Fail to send dbus signal to resourced!!");
+}
+
+bool check_lock_state(int state)
+{
+       dd_list *elem;
+       PmLockNode *t;
+
+       DD_LIST_FOREACH(cond_head[state], elem, t) {
+               if (t->background == false)
+                       return true;
+       }
+
+       return false;
+}
+
+void change_state_action(enum state_t state, int (*func)(int timeout))
+{
+       _I("[%s] action is changed", states[state].name);
+       states[state].action = func;
+}
+
+void change_state_trans(enum state_t state, int (*func)(int evt))
+{
+       _I("[%s] trans is changed", states[state].name);
+       states[state].trans = func;
+}
+
+void change_state_check(enum state_t state, int (*func)(int curr, int next))
+{
+       _I("[%s] check is changed", states[state].name);
+       states[state].check = func;
+}
+
+void change_state_name(enum state_t state, char *name)
+{
+       _I("[%s] name is changed", states[state].name);
+       states[state].name = name;
+}
+
+void change_trans_table(enum state_t state, enum state_t next)
+{
+       _I("[%s] timeout trans table is changed", states[state].name);
+       trans_table[state][EVENT_TIMEOUT] = next;
+}
+
+void change_proc_change_state(int (*func)(unsigned int cond, pid_t pid))
+{
+       _I("proc change state is changed");
+       proc_change_state = func;
+}
+
+static void broadcast_lcd_on(enum signal_type type, enum device_flags flags)
+{
+       const char *str;
+       const char *signal;
+
+       if (type <= SIGNAL_INVALID || type >= SIGNAL_MAX) {
+               _E("invalid signal type %d", type);
+               return;
+       }
+
+       if (flags & LCD_ON_BY_GESTURE)
+               str = GESTURE_STR;
+       else if (flags & LCD_ON_BY_POWER_KEY)
+               str = POWER_KEY_STR;
+       else if (flags & LCD_ON_BY_EVENT)
+               str = EVENT_STR;
+       else if (flags & LCD_ON_BY_TOUCH)
+               str = TOUCH_STR;
+       else
+               str = UNKNOWN_STR;
+
+       signal = lcdon_sig_lookup[type];
+       _I("lcdstep : broadcast %s %s", signal, str);
+       dbus_handle_broadcast_dbus_signal_var(DEVICED_PATH_DISPLAY,
+                                               DEVICED_INTERFACE_DISPLAY,
+                                               signal,
+                                               g_variant_new("(s)", str));
+}
+
+static void broadcast_lcd_off(enum signal_type type, enum device_flags flags)
+{
+       const char *str;
+       const char *signal;
+
+       if (type <= SIGNAL_INVALID || type >= SIGNAL_MAX) {
+               _E("invalid signal type %d", type);
+               return;
+       }
+
+       signal = lcdoff_sig_lookup[type];
+
+       if (flags & LCD_OFF_BY_POWER_KEY)
+               str = POWER_KEY_STR;
+       else if (flags & LCD_OFF_BY_TIMEOUT)
+               str = TIMEOUT_STR;
+       else if (flags & LCD_OFF_BY_EVENT)
+               str = EVENT_STR;
+       else
+               str = UNKNOWN_STR;
+
+       _I("lcdstep : broadcast %s", signal);
+       dbus_handle_broadcast_dbus_signal_var(DEVICED_PATH_DISPLAY,
+                                               DEVICED_INTERFACE_DISPLAY,
+                                               signal,
+                                               g_variant_new("(s)", str));
+}
+
+void broadcast_lcd_off_late(enum device_flags flags)
+{
+       static enum device_flags late_flags;
+
+       if (flags & LCD_OFF_LATE_MODE)
+               broadcast_lcd_off(SIGNAL_POST, late_flags);
+       else
+               late_flags = flags;
+}
+
+static unsigned long get_lcd_on_flags(void)
+{
+       unsigned long flags = NORMAL_MODE;
+
+       if (lcd_paneloff_mode)
+               flags |= LCD_PANEL_OFF_MODE;
+
+       if (stay_touchscreen_off)
+               flags |= TOUCH_SCREEN_OFF_MODE;
+
+       if (ambient_get_condition() == true) {
+               flags |= AMBIENT_MODE;
+               flags |= LCD_PHASED_TRANSIT_MODE;
+       }
+
+       return flags;
+}
+
+bool touch_event_blocked(void)
+{
+       return touch_blocked;
+}
+
+void lcd_on_procedure(int state, enum device_flags flag)
+{
+       dd_list *l = NULL;
+       const struct device_ops *ops = NULL;
+       unsigned long flags = get_lcd_on_flags();
+       flags |= flag;
+
+       /* send LCDOn dbus signal */
+       if (!lcdon_broadcast) {
+               broadcast_lcd_on(SIGNAL_PRE, flags);
+               lcdon_broadcast = true;
+       }
+
+       if (flags & AMBIENT_MODE) {
+               if (ambient_get_state() == false &&
+                       backlight_ops.get_lcd_power() == DPMS_ON)
+                       return;
+               ambient_set_state(false);
+       }
+
+       if (!(flags & LCD_PHASED_TRANSIT_MODE)) {
+               /* Update brightness level */
+               if (state == LCD_DIM)
+                       backlight_ops.dim();
+               else if (state == LCD_NORMAL)
+                       backlight_ops.update();
+       }
+
+       if (state == LCD_NORMAL)
+               set_setting_pmstate(S_NORMAL);
+       else if (state == LCD_DIM)
+               set_setting_pmstate(S_LCDDIM);
+
+       DD_LIST_FOREACH(lcdon_ops, l, ops)
+               ops->start(flags);
+
+       broadcast_lcd_on(SIGNAL_POST, flags);
+
+       if (CHECK_OPS(keyfilter_ops, backlight_enable))
+               keyfilter_ops->backlight_enable(true);
+
+       touch_blocked = false;
+}
+
+static inline unsigned long get_lcd_off_flags(void)
+{
+       unsigned long flags = NORMAL_MODE;
+
+       if (ambient_get_condition() == true) {
+               flags |= AMBIENT_MODE;
+               flags |= LCD_PHASED_TRANSIT_MODE;
+       }
+
+       return flags;
+}
+
+
+inline void lcd_off_procedure(enum device_flags flag)
+{
+       dd_list *l = NULL;
+       const struct device_ops *ops = NULL;
+       unsigned long flags = get_lcd_off_flags();
+       flags |= flag;
+
+       touch_blocked = true;
+
+       if (flags & AMBIENT_MODE) {
+               if (ambient_get_state() == true)
+                       return;
+               ambient_set_state(true);
+       }
+
+       if (lcdon_broadcast) {
+               broadcast_lcd_off(SIGNAL_PRE, flags);
+               lcdon_broadcast = false;
+       }
+       if (CHECK_OPS(keyfilter_ops, backlight_enable))
+               keyfilter_ops->backlight_enable(false);
+
+       set_setting_pmstate(S_LCDOFF);
+
+       DD_LIST_FOREACH(lcdon_ops, l, ops)
+               ops->stop(flags);
+
+       if (flags & AMBIENT_MODE)
+               /* Do not broadcast the post signal here.
+                * The signal will be broadcasted
+                * after showing Ambient clock */
+               broadcast_lcd_off_late(flags);
+       else
+               broadcast_lcd_off(SIGNAL_POST, flags);
+}
+
+void set_stay_touchscreen_off(int val)
+{
+       _D("stay touch screen off : %d", val);
+       stay_touchscreen_off = val;
+
+       lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
+       set_setting_pmstate(LCD_NORMAL);
+}
+
+void set_lcd_paneloff_mode(int val)
+{
+       _D("lcd paneloff mode : %d", val);
+       lcd_paneloff_mode = val;
+
+       lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
+       set_setting_pmstate(LCD_NORMAL);
+}
+
+int low_battery_state(int val)
+{
+       switch (val) {
+       case VCONFKEY_SYSMAN_BAT_POWER_OFF:
+       case VCONFKEY_SYSMAN_BAT_CRITICAL_LOW:
+       case VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF:
+               return true;
+       }
+       return false;
+}
+
+int get_hallic_open(void)
+{
+       return hallic_open;
+}
+
+static int refresh_app_cond()
+{
+       trans_condition = 0;
+
+       if (check_lock_state(S_NORMAL))
+               trans_condition = trans_condition | MASK_NORMAL;
+       if (check_lock_state(S_LCDDIM))
+               trans_condition = trans_condition | MASK_DIM;
+       if (check_lock_state(S_LCDOFF))
+               trans_condition = trans_condition | MASK_OFF;
+
+       return 0;
+}
+
+static void makeup_trans_condition(void)
+{
+       check_processes(S_NORMAL);
+       check_processes(S_LCDDIM);
+       check_processes(S_LCDOFF);
+       refresh_app_cond();
+}
+
+static PmLockNode *find_node(enum state_t s_index, pid_t pid)
+{
+       dd_list *elem;
+       PmLockNode *t;
+
+       DD_LIST_FOREACH(cond_head[s_index], elem, t) {
+               if (t->pid == pid)
+                       return t;
+       }
+
+       return NULL;
+}
+
+static PmLockNode *add_node(enum state_t s_index, pid_t pid, guint timeout_id,
+               bool holdkey_block)
+{
+       PmLockNode *n;
+       time_t now;
+
+       n = (PmLockNode *) malloc(sizeof(PmLockNode));
+       if (n == NULL) {
+               _E("Not enough memory, add cond. fail");
+               return NULL;
+       }
+
+       time(&now);
+       n->pid = pid;
+       n->timeout_id = timeout_id;
+       n->time = now;
+       n->holdkey_block = holdkey_block;
+       n->background = false;
+       DD_LIST_APPEND(cond_head[s_index], n);
+
+       refresh_app_cond();
+       return n;
+}
+
+static int del_node(enum state_t s_index, PmLockNode *n)
+{
+       if (n == NULL)
+               return 0;
+
+       DD_LIST_REMOVE(cond_head[s_index], n);
+
+       /* delete timer */
+       if (n->timeout_id) {
+               g_source_remove(n->timeout_id);
+               n->timeout_id = 0;
+       }
+       free(n);
+       refresh_app_cond();
+       return 0;
+}
+
+static void print_node(int next)
+{
+       dd_list *elem;
+       PmLockNode *n;
+       char buf[30];
+       time_t now;
+       double diff;
+
+       if (next <= S_START || next >= S_END)
+               return;
+
+       time(&now);
+       DD_LIST_FOREACH(cond_head[next], elem, n) {
+               diff = difftime(now, n->time);
+               ctime_r(&n->time, buf);
+
+               if (diff > LOCK_TIME_WARNING)
+                       _W("over %.0f s, pid: %5d, lock time: %s", diff, n->pid, buf);
+               else
+                       _I("pid: %5d, lock time: %s", n->pid, buf);
+       }
+}
+
+void get_pname(pid_t pid, char *pname)
+{
+       char buf[PATH_MAX];
+       int cmdline, r;
+
+       if (pid >= INTERNAL_LOCK_BASE)
+               snprintf(buf, PATH_MAX, "/proc/%d/cmdline", getpid());
+       else
+               snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
+
+       cmdline = open(buf, O_RDONLY);
+       if (cmdline < 0) {
+               pname[0] = '\0';
+               _E("%d does not exist now(may be dead without unlock)", pid);
+               return;
+       }
+
+       r = read(cmdline, pname, PATH_MAX);
+       if ((r >= 0) && (r < PATH_MAX))
+               pname[r] = '\0';
+       else
+               pname[0] = '\0';
+
+       close(cmdline);
+}
+
+static void del_state_cond(void *data, enum state_t state)
+{
+       PmLockNode *tmp = NULL;
+       char pname[PATH_MAX];
+       pid_t pid;
+
+       if (!data)
+               return;
+
+       /* A passed data is a pid_t type data, not a 64bit data. */
+       pid = (pid_t)((intptr_t)data);
+       _I("delete prohibit dim condition by timeout (%d)", pid);
+
+       tmp = find_node(state, pid);
+       del_node(state, tmp);
+       get_pname(pid, pname);
+       set_unlock_time(pname, state);
+
+       if (!timeout_src_id)
+               states[pm_cur_state].trans(EVENT_TIMEOUT);
+
+       if (state == S_LCDOFF)
+               set_process_active(FALSE, pid);
+}
+
+static gboolean del_normal_cond(void *data)
+{
+       del_state_cond(data, S_NORMAL);
+       return G_SOURCE_REMOVE;
+}
+
+static gboolean del_dim_cond(void *data)
+{
+       del_state_cond(data, S_LCDDIM);
+       return G_SOURCE_REMOVE;
+}
+
+static gboolean del_off_cond(void *data)
+{
+       del_state_cond(data, S_LCDOFF);
+       return G_SOURCE_REMOVE;
+}
+
+/* timeout handler  */
+gboolean timeout_handler(void *data)
+{
+       int run_timeout;
+
+       _I("Time out state %s\n", states[pm_cur_state].name);
+       /* default setting */
+       get_run_timeout(&run_timeout);
+
+       /* for sdk
+        * if the run_timeout is zero, it regards AlwaysOn state
+        */
+       if (pm_cur_state == S_NORMAL && (run_timeout == 0 || display_conf.lcd_always_on)) {
+               _D("run_timeout is always on");
+               return G_SOURCE_CONTINUE;
+       }
+
+       if (timeout_src_id) {
+               g_source_remove(timeout_src_id);
+               timeout_src_id = 0;
+       }
+
+       states[pm_cur_state].trans(EVENT_TIMEOUT);
+       return G_SOURCE_REMOVE;
+}
+
+void reset_timeout(int timeout)
+{
+       if (!display_conf.timeout_enable)
+               return;
+
+       _I("Reset Timeout (%d)ms", timeout);
+       if (timeout_src_id != 0) {
+               g_source_remove(timeout_src_id);
+               timeout_src_id = 0;
+       }
+
+       if (trans_table[pm_cur_state][EVENT_TIMEOUT] == pm_cur_state)
+               return;
+
+       if (timeout > 0)
+               timeout_src_id = g_timeout_add_seconds(MSEC_TO_SEC((double)timeout),
+                   timeout_handler, NULL);
+       else if (timeout == 0)
+               states[pm_cur_state].trans(EVENT_TIMEOUT);
+}
+
+/* get configurations from setting */
+static int get_lcd_timeout_from_settings(void)
+{
+       int i;
+       int val = 0;
+
+       for (i = 0; i < S_END; i++) {
+               switch (states[i].state) {
+               case S_NORMAL:
+                       get_run_timeout(&val);
+                       break;
+               case S_LCDDIM:
+                       get_dim_timeout(&val);
+                       break;
+               case S_LCDOFF:
+                       val = display_conf.lcdoff_timeout;
+                       break;
+               default:
+                       /* This state doesn't need to set time out. */
+                       val = 0;
+                       break;
+               }
+               if (val > 0)
+                       states[i].timeout = val;
+
+               _I("%s state : %d ms timeout", states[i].name,
+                       states[i].timeout);
+       }
+
+       return 0;
+}
+
+static void update_display_time(void)
+{
+       int run_timeout, val;
+
+       /* first priority : s cover */
+       if (!hallic_open) {
+               states[S_NORMAL].timeout = S_COVER_TIMEOUT;
+               _I("S cover closed : timeout is set by normal(%d ms)",
+                   S_COVER_TIMEOUT);
+               return;
+       }
+
+       /* second priority : custom timeout */
+       if (custom_normal_timeout > 0) {
+               states[S_NORMAL].timeout = custom_normal_timeout;
+               states[S_LCDDIM].timeout = custom_dim_timeout;
+               _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
+                   custom_normal_timeout, custom_dim_timeout);
+               return;
+       }
+
+       /* third priority : lock state */
+       if ((__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
+           !get_lock_screen_bg_state()) {
+               /* timeout is different according to key or event. */
+               states[S_NORMAL].timeout = lock_screen_timeout;
+               _I("LOCK : timeout is set by normal(%d ms)",
+                   lock_screen_timeout);
+               return;
+       }
+
+       /* default setting */
+       get_run_timeout(&run_timeout);
+
+       /* for sdk
+        * if the run_timeout is zero, it regards AlwaysOn state
+        */
+       if (run_timeout == 0 || display_conf.lcd_always_on) {
+               run_timeout = ALWAYS_ON_TIMEOUT;
+               _I("LCD Always On");
+       }
+
+       states[S_NORMAL].timeout = run_timeout;
+
+       get_dim_timeout(&val);
+       states[S_LCDDIM].timeout = val;
+
+       _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
+       _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
+}
+
+static void update_display_locktime(int time)
+{
+       lock_screen_timeout = time;
+       update_display_time();
+}
+
+
+void set_dim_state(bool on)
+{
+       _I("dim state is %d", on);
+       update_display_time();
+       states[pm_cur_state].trans(EVENT_INPUT);
+}
+
+
+void lcd_on_direct(enum device_flags flags)
+{
+       int ret, call_state;
+
+       if (power_ops.get_power_lock_support()
+           && pm_cur_state == S_SLEEP)
+               power_ops.power_lock();
+
+#ifdef MICRO_DD
+       _D("lcd is on directly");
+       gettimeofday(&lcdon_tv, NULL);
+       lcd_on_procedure(LCD_NORMAL, flags);
+       reset_timeout(DD_LCDOFF_INPUT_TIMEOUT);
+#else
+       ret = vconf_get_int(VCONFKEY_CALL_STATE, &call_state);
+       if ((ret >= 0 && call_state != VCONFKEY_CALL_OFF) ||
+           (__get_lock_screen_state() == VCONFKEY_IDLE_LOCK)) {
+               _D("LOCK state, lcd is on directly");
+               lcd_on_procedure(LCD_NORMAL, flags);
+       }
+       reset_timeout(display_conf.lcdoff_timeout);
+#endif
+       update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
+}
+
+static inline bool check_lcd_is_on(void)
+{
+       if (backlight_ops.get_lcd_power() != DPMS_ON)
+               return false;
+
+       return true;
+}
+
+int custom_lcdon(int timeout)
+{
+       struct state *st;
+
+       if (timeout <= 0)
+               return -EINVAL;
+
+       if (check_lcd_is_on() == false)
+               lcd_on_direct(LCD_ON_BY_GESTURE);
+
+       _I("custom lcd on %d ms", timeout);
+       if (set_custom_lcdon_timeout(timeout) == true)
+               update_display_time();
+
+       /* state transition */
+       pm_old_state = pm_cur_state;
+       pm_cur_state = S_NORMAL;
+       st = &states[pm_cur_state];
+
+       /* enter action */
+       if (st->action)
+               st->action(st->timeout);
+
+       return 0;
+}
+
+static void default_proc_change_state_action(enum state_t next, int timeout)
+{
+       struct state *st;
+
+       pm_old_state = pm_cur_state;
+       pm_cur_state = next;
+
+       st = &states[pm_cur_state];
+
+       if (st && st->action) {
+               if (timeout < 0)
+                       st->action(st->timeout);
+               else
+                       st->action(timeout);
+       }
+}
+
+static int default_proc_change_state(unsigned int cond, pid_t pid)
+{
+       enum state_t next;
+
+       next = GET_COND_STATE(cond);
+       _I("Change State to %s (%d)", states[next].name, pid);
+
+       switch (next) {
+       case S_NORMAL:
+               if (check_lcd_is_on() == false)
+                       lcd_on_direct(LCD_ON_BY_EVENT);
+               update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
+               default_proc_change_state_action(next, -1);
+               break;
+       case S_LCDDIM:
+               default_proc_change_state_action(next, -1);
+               break;
+       case S_LCDOFF:
+               if (backlight_ops.get_lcd_power() != DPMS_OFF)
+                       lcd_off_procedure(LCD_OFF_BY_EVENT);
+               if (set_custom_lcdon_timeout(0))
+                       update_display_time();
+               default_proc_change_state_action(next, -1);
+               break;
+       case S_SLEEP:
+               _I("Dangerous requests.");
+               /* at first LCD_OFF and then goto sleep */
+               /* state transition */
+               default_proc_change_state_action(S_LCDOFF, TIMEOUT_NONE);
+               delete_condition(S_LCDOFF);
+               default_proc_change_state_action(S_SLEEP, TIMEOUT_NONE);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/* update transition condition for application requrements */
+static void update_lock_timer(PMMsg *data,
+               PmLockNode *node, guint timeout_id)
+{
+       time_t now;
+
+       if (data->timeout > 0) {
+               time(&now);
+               node->time = now;
+       }
+
+       if (node->timeout_id)
+               g_source_remove(node->timeout_id);
+       node->timeout_id = timeout_id;
+}
+
+static void proc_condition_lock(PMMsg *data)
+{
+       PmLockNode *tmp;
+       guint cond_timeout_id = 0;
+       char pname[PATH_MAX];
+       pid_t pid = data->pid;
+       enum state_t state;
+       int holdkey_block;
+
+       state = GET_COND_STATE(data->cond);
+       if (!state)
+               return;
+
+       get_pname(pid, pname);
+
+       if (state == S_LCDOFF &&
+               pm_cur_state == S_SLEEP)
+               proc_change_state(data->cond, INTERNAL_LOCK_PM);
+
+       if (data->timeout > 0) {
+               /* To pass a pid_t data through the timer infrastructure
+                * without memory allocation, a pid_t data becomes typecast
+                * to intptr_t and void *(64bit) type. */
+               cond_timeout_id = g_timeout_add_seconds(
+                               MSEC_TO_SEC((double)data->timeout),
+                               states[state].timeout_cb,
+                               (void*)((intptr_t)pid));
+               if (!cond_timeout_id)
+                       _E("Failed to register display timer");
+       }
+
+       holdkey_block = GET_COND_FLAG(data->cond) & PM_FLAG_BLOCK_HOLDKEY;
+
+       tmp = find_node(state, pid);
+       if (!tmp)
+               add_node(state, pid, cond_timeout_id, holdkey_block);
+       else {
+               update_lock_timer(data, tmp, cond_timeout_id);
+               tmp->holdkey_block = holdkey_block;
+       }
+
+       if (state == S_LCDOFF)
+               set_process_active(TRUE, pid);
+
+       /* for debug */
+       _SD("[%s] locked by pid %d - process %s holdkeyblock %d\n",
+                       states[state].name, pid, pname, holdkey_block);
+       set_lock_time(pname, state);
+
+       device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)true);
+}
+
+static void proc_condition_unlock(PMMsg *data)
+{
+       pid_t pid = data->pid;
+       enum state_t state;
+       PmLockNode *tmp;
+       char pname[PATH_MAX];
+
+       state = GET_COND_STATE(data->cond);
+       if (!state)
+               return;
+
+       get_pname(pid, pname);
+
+       tmp = find_node(state, pid);
+       del_node(state, tmp);
+
+       if (state == S_LCDOFF)
+               set_process_active(FALSE, pid);
+
+       if (ambient_get_state())
+               ambient_check_invalid_state(pid);
+
+       _SD("[%s] unlocked by pid %d - process %s\n",
+                       states[state].name, pid, pname);
+       set_unlock_time(pname, state);
+
+       device_notify(DEVICE_NOTIFIER_DISPLAY_LOCK, (void *)false);
+}
+
+static int proc_condition(PMMsg *data)
+{
+       unsigned int flags;
+
+       if (IS_COND_REQUEST_LOCK(data->cond))
+               proc_condition_lock(data);
+
+       if (IS_COND_REQUEST_UNLOCK(data->cond))
+               proc_condition_unlock(data);
+
+       if (!display_conf.timeout_enable)
+               return 0;
+
+       flags = GET_COND_FLAG(data->cond);
+       if (flags == 0) {
+               /* guard time for suspend */
+               if (pm_cur_state == S_LCDOFF) {
+                       reset_timeout(states[S_LCDOFF].timeout);
+                       _I("Margin timeout (%d ms)", states[S_LCDOFF].timeout);
+               }
+       } else {
+               if (flags & PM_FLAG_RESET_TIMER) {
+                       reset_timeout(states[pm_cur_state].timeout);
+                       _I("Reset timeout (%d ms)", states[pm_cur_state].timeout);
+               }
+       }
+
+       if (!timeout_src_id)
+               states[pm_cur_state].trans(EVENT_TIMEOUT);
+
+       return 0;
+}
+
+/* If some changed, return 1 */
+int check_processes(enum state_t prohibit_state)
+{
+       dd_list *elem, *next;
+       PmLockNode *t;
+       int ret = 0;
+
+       DD_LIST_FOREACH_SAFE(cond_head[prohibit_state], elem, next, t) {
+               if (t->pid < INTERNAL_LOCK_BASE && kill(t->pid, 0) == -1) {
+                       _E("%d process does not exist, delete the REQ"
+                               " - prohibit state %d ",
+                               t->pid, prohibit_state);
+                       if (t->pid == custom_change_pid) {
+                               get_lcd_timeout_from_settings();
+                               custom_normal_timeout = custom_dim_timeout = 0;
+                               custom_change_pid = -1;
+                       }
+                       ret = 1;
+                       del_node(prohibit_state, t);
+               }
+       }
+
+       return ret;
+}
+
+int check_holdkey_block(enum state_t state)
+{
+       dd_list *elem;
+       PmLockNode *t;
+       int ret = 0;
+
+       _I("check holdkey block : state of %s", states[state].name);
+
+       if (custom_holdkey_block == true) {
+               _I("custom hold key blocked by pid(%d)",
+                       custom_change_pid);
+               return 1;
+       }
+
+       DD_LIST_FOREACH(cond_head[state], elem, t) {
+               if (t->holdkey_block == true) {
+                       ret = 1;
+                       _I("Hold key blocked by pid(%d)!", t->pid);
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+int delete_condition(enum state_t state)
+{
+       dd_list *elem, *next;
+       PmLockNode *t;
+       pid_t pid;
+       char pname[PATH_MAX];
+
+       _I("delete condition : state of %s", states[state].name);
+
+       if (!cond_head[state])
+               return 0;
+
+       DD_LIST_FOREACH_SAFE(cond_head[state], elem, next, t) {
+               if (t->timeout_id > 0) {
+                       g_source_remove(t->timeout_id);
+                       t->timeout_id = 0;
+               }
+               pid = t->pid;
+               if (state == S_LCDOFF)
+                       set_process_active(FALSE, pid);
+               _I("delete node of pid(%d)", pid);
+               del_node(state, t);
+               get_pname(pid, pname);
+               set_unlock_time(pname, state-1);
+       }
+
+       DD_LIST_FREE_LIST(cond_head[state]);
+       cond_head[state] = NULL;
+
+       return 0;
+}
+
+void update_lcdoff_source(int source)
+{
+       switch (source) {
+       case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
+               _I("LCD OFF by timeout");
+               break;
+       case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
+               _I("LCD OFF by powerkey");
+               break;
+       default:
+               _E("Invalid value(%d)", source);
+               return;
+       }
+       vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
+}
+
+#ifdef ENABLE_PM_LOG
+
+typedef struct _pm_history {
+       time_t time;
+       enum pm_log_type log_type;
+       int keycode;
+} pm_history;
+
+static int max_history_count = MAX_LOG_COUNT;
+static pm_history pm_history_log[MAX_LOG_COUNT] = {{0, }, };
+static int history_count = 0;
+
+static const char history_string[PM_LOG_MAX][15] = {
+       "PRESS", "LONG PRESS", "RELEASE", "LCD ON", "LCD ON FAIL",
+       "LCD DIM", "LCD DIM FAIL", "LCD OFF", "LCD OFF FAIL", "SLEEP"};
+
+void pm_history_init()
+{
+       memset(pm_history_log, 0x0, sizeof(pm_history_log));
+       history_count = 0;
+       max_history_count = MAX_LOG_COUNT;
+}
+
+void pm_history_save(enum pm_log_type log_type, int code)
+{
+       time_t now;
+
+       time(&now);
+       pm_history_log[history_count].time = now;
+       pm_history_log[history_count].log_type = log_type;
+       pm_history_log[history_count].keycode = code;
+       history_count++;
+
+       if (history_count >= max_history_count)
+               history_count = 0;
+}
+
+void pm_history_print(int fd, int count)
+{
+       int start_index, index, i;
+       int ret;
+       char buf[255];
+       char time_buf[30];
+
+       if (count <= 0 || count > max_history_count)
+               return;
+
+       start_index = (history_count - count + max_history_count)
+                   % max_history_count;
+
+       for (i = 0; i < count; i++) {
+               index = (start_index + i) % max_history_count;
+
+               if (pm_history_log[index].time == 0)
+                       continue;
+
+               if (pm_history_log[index].log_type < PM_LOG_MIN ||
+                   pm_history_log[index].log_type >= PM_LOG_MAX)
+                       continue;
+               ctime_r(&pm_history_log[index].time, time_buf);
+               snprintf(buf, sizeof(buf), "[%3d] %15s %3d %s",
+                       index,
+                       history_string[pm_history_log[index].log_type],
+                       pm_history_log[index].keycode,
+                       time_buf);
+               ret = write(fd, buf, strlen(buf));
+               if (ret < 0)
+                       _E("write() failed (%d)", errno);
+       }
+}
+#endif
+
+void print_info(int fd)
+{
+       int s_index = 0;
+       char buf[255];
+       int i = 1;
+       int ret;
+       char pname[PATH_MAX];
+       PmLockNode *t;
+       dd_list *elem;
+       char time_buf[30];
+
+       if (fd < 0)
+               return;
+
+       snprintf(buf, sizeof(buf),
+               "\n==========================================="
+               "===========================\n");
+       ret = write(fd, buf, strlen(buf));
+       if (ret < 0)
+               _E("write() failed (%d)", errno);
+       snprintf(buf, sizeof(buf), "Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
+                states[S_NORMAL].timeout,
+                states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
+       ret = write(fd, buf, strlen(buf));
+       if (ret < 0)
+               _E("write() failed (%d)", errno);
+
+       snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
+                (trans_condition & MASK_NORMAL) ? states[S_NORMAL].name : "-",
+                (trans_condition & MASK_DIM) ? states[S_LCDDIM].name : "-",
+                (trans_condition & MASK_OFF) ? states[S_LCDOFF].name : "-");
+       ret = write(fd, buf, strlen(buf));
+       if (ret < 0)
+               _E("write() failed (%d)", errno);
+
+       snprintf(buf, sizeof(buf), "Current State: %s\n",
+               states[pm_cur_state].name);
+       ret = write(fd, buf, strlen(buf));
+       if (ret < 0)
+               _E("write() failed (%d)", errno);
+
+       snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
+       ret = write(fd, buf, strlen(buf));
+       if (ret < 0)
+               _E("write() failed (%d)", errno);
+
+       for (s_index = S_NORMAL; s_index < S_END; s_index++) {
+               DD_LIST_FOREACH(cond_head[s_index], elem, t) {
+                       get_pname((pid_t)t->pid, pname);
+                       ctime_r(&t->time, time_buf);
+                       snprintf(buf, sizeof(buf),
+                                " %d: [%s] locked by pid %d %s %s",
+                                i++, states[s_index].name, t->pid, pname, time_buf);
+                       ret = write(fd, buf, strlen(buf));
+                       if (ret < 0)
+                               _E("write() failed (%d)", errno);
+               }
+       }
+
+       print_lock_info_list(fd);
+
+#ifdef ENABLE_PM_LOG
+       pm_history_print(fd, 250);
+#endif
+}
+
+void save_display_log(void)
+{
+       int fd, ret;
+       char buf[255];
+       time_t now_time;
+       char time_buf[30];
+
+       _D("internal state is saved!");
+
+       time(&now_time);
+       ctime_r(&now_time, time_buf);
+
+       fd = open(PM_STATE_LOG_FILE, O_CREAT | O_TRUNC | O_WRONLY, 0644);
+       if (fd != -1) {
+               snprintf(buf, sizeof(buf),
+                       "\npm_state_log now-time : %d(s) %s\n\n",
+                       (int)now_time, time_buf);
+               ret = write(fd, buf, strlen(buf));
+               if (ret < 0)
+                       _E("write() failed (%d)", errno);
+
+               snprintf(buf, sizeof(buf), "pm_status_flag: %x\n", pm_status_flag);
+               ret = write(fd, buf, strlen(buf));
+               if (ret < 0)
+                       _E("write() failed (%d)", errno);
+
+               snprintf(buf, sizeof(buf), "screen lock status : %d\n",
+                       __get_lock_screen_state());
+               ret = write(fd, buf, strlen(buf));
+               if (ret < 0)
+                       _E("write() failed (%d)", errno);
+               print_info(fd);
+               close(fd);
+       }
+
+       fd = open("/dev/console", O_WRONLY);
+       if (fd != -1) {
+               print_info(fd);
+               close(fd);
+       }
+}
+
+/* SIGHUP signal handler
+ * For debug... print info to syslog
+ */
+static void sig_hup(int signo)
+{
+       save_display_log();
+}
+
+int check_lcdoff_direct(void)
+{
+       int ret, lock, cradle;
+       int hdmi_state;
+
+       if (pm_old_state != S_NORMAL)
+               return false;
+
+       if (pm_cur_state != S_LCDDIM)
+               return false;
+
+       lock = __get_lock_screen_state();
+       if (lock != VCONFKEY_IDLE_LOCK && hallic_open)
+               return false;
+
+       hdmi_state = extcon_get_status(EXTCON_CABLE_HDMI);
+       if (hdmi_state)
+               return false;
+
+       ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
+       if (ret >= 0 && cradle == DOCK_SOUND)
+               return false;
+
+       _D("Goto LCDOFF direct(%d,%d,%d)", lock, hdmi_state, cradle);
+
+       return true;
+}
+
+static int __check_lcdoff_lock_state(void)
+{
+       if (cond_head[S_LCDOFF] != NULL)
+               return true;
+
+       return false;
+}
+
+/*
+ * default transition function
+ *   1. call check
+ *   2. transition
+ *   3. call enter action function
+ */
+static int default_trans(int evt)
+{
+       struct state *st = &states[pm_cur_state];
+       int next_state;
+
+       next_state = (enum state_t)trans_table[pm_cur_state][evt];
+
+       /* check conditions */
+       while (st->check && !st->check(pm_cur_state, next_state)) {
+               /* There is a condition. */
+               _I("(%s) locked. Trans to (%s) failed", states[pm_cur_state].name,
+                      states[next_state].name);
+               if (!check_processes(pm_cur_state)) {
+                       /* This is valid condition
+                        * The application that sent the condition is running now. */
+                       return -1;
+               }
+       }
+
+       /* state transition */
+       pm_old_state = pm_cur_state;
+       pm_cur_state = next_state;
+       st = &states[pm_cur_state];
+
+       /* enter action */
+       if (st->action) {
+               if (pm_cur_state == S_LCDOFF)
+                       update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
+
+               if (pm_cur_state == S_NORMAL || pm_cur_state == S_LCDOFF)
+                       if (set_custom_lcdon_timeout(0) == true)
+                               update_display_time();
+
+               if (check_lcdoff_direct() == true) {
+                       /* enter next state directly */
+                       states[pm_cur_state].trans(EVENT_TIMEOUT);
+               } else {
+                       st->action(st->timeout);
+               }
+       }
+
+       return 0;
+}
+
+static gboolean lcd_on_expired(void *data)
+{
+       int lock_state, ret;
+
+       if (lock_timeout_id)
+               lock_timeout_id = 0;
+
+       /* check state of lock */
+       ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
+
+       if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
+               return G_SOURCE_REMOVE;
+
+       /* lock screen is not launched yet, but lcd is on */
+       if (check_lcd_is_on() == false)
+               lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
+
+       return G_SOURCE_REMOVE;
+}
+
+static inline void stop_lock_timer(void)
+{
+       if (lock_timeout_id) {
+               g_source_remove(lock_timeout_id);
+               lock_timeout_id = 0;
+       }
+}
+
+static void check_lock_screen(void)
+{
+       int lock_setting, lock_state, app_state, ret;
+
+       stop_lock_timer();
+
+       ret = vconf_get_int(VCONFKEY_CALL_STATE, &app_state);
+       if (ret >= 0 && app_state != VCONFKEY_CALL_OFF)
+               goto lcd_on;
+
+       /* check setting of lock screen is enabled. */
+       ret = vconf_get_int(VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT,
+           &lock_setting);
+
+       /* check state of lock */
+       ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
+
+       if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
+               goto lcd_on;
+
+       /* Use time to check lock is done. */
+       lock_timeout_id = g_timeout_add_seconds(display_conf.lock_wait_time,
+           lcd_on_expired, NULL);
+
+       return;
+
+lcd_on:
+       if (check_lcd_is_on() == false)
+               lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
+}
+
+/* default enter action function */
+static int default_action(int timeout)
+{
+       int wakeup_count = -1;
+       time_t now;
+       double diff;
+       static time_t last_update_time = 0;
+       static int last_timeout = 0;
+       struct timeval now_tv;
+
+       if (status != DEVICE_OPS_STATUS_START) {
+               _E("display is not started!");
+               return -EINVAL;
+       }
+
+       if (pm_cur_state != S_SLEEP) {
+               if (pm_cur_state == S_NORMAL &&
+                   lcdon_tv.tv_sec != 0) {
+                       gettimeofday(&now_tv, NULL);
+                       timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
+                       lcdon_tv.tv_sec = 0;
+               }
+               /* set timer with current state timeout */
+               reset_timeout(timeout);
+
+               if (pm_cur_state == S_NORMAL) {
+                       time(&last_update_time);
+                       last_timeout = timeout;
+               } else {
+                       _I("timout set: %s state %d ms",
+                           states[pm_cur_state].name, timeout);
+               }
+       }
+
+       if (pm_cur_state != pm_old_state && pm_cur_state != S_SLEEP) {
+               if (power_ops.get_power_lock_support())
+                       power_ops.power_lock();
+               set_setting_pmstate(pm_cur_state);
+               device_notify(DEVICE_NOTIFIER_LCD, &pm_cur_state);
+       }
+
+       if (pm_old_state == S_NORMAL && pm_cur_state != S_NORMAL) {
+               time(&now);
+               diff = difftime(now, last_update_time);
+               _I("S_NORMAL is changed to %s [%d ms, %.0f s]",
+                   states[pm_cur_state].name, last_timeout, diff);
+       }
+
+       switch (pm_cur_state) {
+       case S_NORMAL:
+               /*
+                * normal state : backlight on and restore
+                * the previous brightness
+                */
+               if (pm_old_state == S_LCDOFF || pm_old_state == S_SLEEP)
+                       check_lock_screen();
+               else if (pm_old_state == S_LCDDIM)
+                       backlight_ops.update();
+
+               if (check_lcd_is_on() == false)
+                       lcd_on_procedure(LCD_NORMAL, NORMAL_MODE);
+               break;
+
+       case S_LCDDIM:
+               if (pm_old_state == S_NORMAL &&
+                   backlight_ops.get_custom_status())
+                       backlight_ops.save_custom_brightness();
+               /* lcd dim state : dim the brightness */
+               backlight_ops.dim();
+
+               if (pm_old_state == S_LCDOFF || pm_old_state == S_SLEEP)
+                       lcd_on_procedure(LCD_DIM, NORMAL_MODE);
+               break;
+
+       case S_LCDOFF:
+               if (pm_old_state != S_SLEEP && pm_old_state != S_LCDOFF) {
+                       stop_lock_timer();
+                       /* lcd off state : turn off the backlight */
+                       if (backlight_ops.get_lcd_power() != DPMS_OFF)
+                               lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
+               }
+
+               if (backlight_ops.get_lcd_power() != DPMS_OFF
+                   || lcd_paneloff_mode)
+                       lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
+               break;
+
+       case S_SLEEP:
+               if (pm_old_state != S_SLEEP && pm_old_state != S_LCDOFF)
+                       stop_lock_timer();
+
+               if (backlight_ops.get_lcd_power() != DPMS_OFF)
+                       lcd_off_procedure(LCD_OFF_BY_TIMEOUT);
+
+               if (!power_ops.get_power_lock_support()) {
+                       /* sleep state : set system mode to SUSPEND */
+                       if (power_ops.get_wakeup_count(&wakeup_count) < 0)
+                               _E("wakeup count read error");
+
+                       if (wakeup_count < 0) {
+                               _I("Wakup Event! Can not enter suspend mode.");
+                               goto go_lcd_off;
+                       }
+
+                       if (power_ops.set_wakeup_count(wakeup_count) < 0) {
+                               _E("wakeup count write error");
+                               goto go_lcd_off;
+                       }
+               }
+               goto go_suspend;
+       }
+
+       return 0;
+
+go_suspend:
+#ifdef ENABLE_PM_LOG
+       pm_history_save(PM_LOG_SLEEP, pm_cur_state);
+#endif
+       if (power_ops.get_power_lock_support()) {
+               if (power_ops.enable_autosleep)
+                       power_ops.enable_autosleep();
+
+               if (power_ops.power_unlock() < 0)
+                       _E("power unlock state error!");
+       } else {
+               dd_list *elem, *elem_n;
+               const struct device_ops *dev;
+               /* Devices Suspend */
+               DD_LIST_FOREACH_SAFE(dev_head, elem, elem_n, dev) {
+                       if (dev->suspend)
+                               dev->suspend();
+               }
+
+               power_ops.suspend();
+
+               /* Devices Resume */
+               DD_LIST_FOREACH_SAFE(dev_head, elem, elem_n, dev) {
+                       if (dev->resume)
+                               dev->resume();
+               }
+
+               _I("system wakeup!!");
+               disp_plgn.system_wakeup_flag = true;
+               /* Resume !! */
+               if (power_ops.check_wakeup_src() == EVENT_DEVICE)
+                       /* system waked up by devices */
+                       states[pm_cur_state].trans(EVENT_DEVICE);
+               else
+                       /* system waked up by user input */
+                       states[pm_cur_state].trans(EVENT_INPUT);
+       }
+       return 0;
+
+go_lcd_off:
+       if (!power_ops.get_power_lock_support()) {
+               /* Resume !! */
+               states[pm_cur_state].trans(EVENT_DEVICE);
+       }
+       return 0;
+}
+
+/*
+ * default check function
+ *   return
+ *    0 : can't transit, others : transitable
+ */
+static int default_check(int curr, int next)
+{
+       int trans_cond;
+
+       makeup_trans_condition();
+
+       trans_cond = trans_condition & MASK_BIT;
+
+       if (next == S_NORMAL) /* S_NORMAL is exceptional */
+               return 1;
+
+       switch (curr) {
+       case S_NORMAL:
+               trans_cond = trans_cond & MASK_NORMAL;
+               break;
+       case S_LCDDIM:
+               trans_cond = trans_cond & MASK_DIM;
+               break;
+       case S_LCDOFF:
+               trans_cond = trans_cond & MASK_OFF;
+               break;
+       default:
+               trans_cond = 0;
+               break;
+       }
+
+       if (trans_cond != 0) {
+               print_node(curr);
+               return 0;
+       }
+
+       return 1;               /* transitable */
+}
+
+static void default_saving_mode(int onoff)
+{
+       if (onoff)
+               pm_status_flag |= PWRSV_FLAG;
+       else
+               pm_status_flag &= ~PWRSV_FLAG;
+
+       if (pm_cur_state == S_NORMAL)
+               backlight_ops.update();
+}
+
+static int poll_callback(int condition, PMMsg *data)
+{
+       static time_t last_t;
+       time_t now;
+
+       if (status != DEVICE_OPS_STATUS_START) {
+               _E("display logic is not started!");
+               return -ECANCELED;
+       }
+
+       if (condition == INPUT_POLL_EVENT) {
+               if (pm_cur_state == S_LCDOFF || pm_cur_state == S_SLEEP)
+                       _I("Power key input");
+               time(&now);
+               if (last_t != now ||
+                   pm_cur_state == S_LCDOFF ||
+                   pm_cur_state == S_SLEEP) {
+                       states[pm_cur_state].trans(EVENT_INPUT);
+                       last_t = now;
+               }
+       }
+
+       if (condition == PM_CONTROL_EVENT) {
+               proc_condition(data);
+
+               if (IS_COND_REQUEST_CHANGE(data->cond))
+                       proc_change_state(data->cond, data->pid);
+       }
+
+       return 0;
+}
+
+static int update_setting(int key_idx, int val)
+{
+       char buf[PATH_MAX];
+
+       switch (key_idx) {
+       case SETTING_TO_NORMAL:
+               update_display_time();
+               states[pm_cur_state].trans(EVENT_INPUT);
+               break;
+       case SETTING_HALLIC_OPEN:
+               hallic_open = val;
+               update_display_time();
+               if (pm_cur_state == S_NORMAL || pm_cur_state == S_LCDDIM)
+                       states[pm_cur_state].trans(EVENT_INPUT);
+               else if (pm_cur_state == S_SLEEP && hallic_open)
+                       proc_change_state(S_LCDOFF, INTERNAL_LOCK_HALLIC);
+               break;
+       case SETTING_LOW_BATT:
+               if (low_battery_state(val)) {
+                       if (!(pm_status_flag & CHRGR_FLAG))
+                               power_saving_func(true);
+                       pm_status_flag |= LOWBT_FLAG;
+               } else {
+                       if (pm_status_flag & PWRSV_FLAG)
+                               power_saving_func(false);
+                       pm_status_flag &= ~LOWBT_FLAG;
+                       pm_status_flag &= ~BRTCH_FLAG;
+                       vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM,
+                           false);
+               }
+               break;
+       case SETTING_CHARGING:
+               if (val) {
+                       if (pm_status_flag & LOWBT_FLAG) {
+                               power_saving_func(false);
+                               pm_status_flag &= ~LOWBT_FLAG;
+                       }
+                       pm_status_flag |= CHRGR_FLAG;
+               } else {
+                       int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
+                       vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
+                               &bat_state);
+                       if (low_battery_state(bat_state)) {
+                               power_saving_func(true);
+                               pm_status_flag |= LOWBT_FLAG;
+                       }
+                       pm_status_flag &= ~CHRGR_FLAG;
+               }
+               break;
+       case SETTING_BRT_LEVEL:
+               if (pm_status_flag & PWRSV_FLAG) {
+                       pm_status_flag |= BRTCH_FLAG;
+                       vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM,
+                           true);
+                       _I("brightness changed in low battery,"
+                               "escape dim state");
+               }
+               backlight_ops.set_default_brt(val);
+               snprintf(buf, sizeof(buf), "%d", val);
+               _D("Brightness set in bl : %d", val);
+               launch_evenif_exist(SET_BRIGHTNESS_IN_BOOTLOADER, buf);
+               break;
+       case SETTING_LOCK_SCREEN:
+               set_lock_screen_state(val);
+               if (val == VCONFKEY_IDLE_UNLOCK) {
+                       if (CHECK_OPS(keyfilter_ops, backlight_enable))
+                               keyfilter_ops->backlight_enable(false);
+               }
+
+               /* LCD on if lock screen show before waiting time */
+               if (pm_cur_state == S_NORMAL &&
+                   val == VCONFKEY_IDLE_LOCK &&
+                   backlight_ops.get_lcd_power() != DPMS_ON)
+                       lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
+               stop_lock_timer();
+               update_display_time();
+               if (pm_cur_state == S_NORMAL)
+                       states[pm_cur_state].trans(EVENT_INPUT);
+               break;
+       case SETTING_LOCK_SCREEN_BG:
+               set_lock_screen_bg_state(val);
+               update_display_time();
+               if (pm_cur_state == S_NORMAL)
+                       states[pm_cur_state].trans(EVENT_INPUT);
+               break;
+       case SETTING_POWEROFF:
+               switch (val) {
+               case POWER_OFF_NONE:
+               case POWER_OFF_POPUP:
+                       pm_status_flag &= ~PWROFF_FLAG;
+                       break;
+               case POWER_OFF_DIRECT:
+               case POWER_OFF_RESTART:
+                       pm_status_flag |= PWROFF_FLAG;
+                       break;
+               }
+               break;
+       case SETTING_POWER_CUSTOM_BRIGHTNESS:
+               if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
+                       backlight_ops.set_custom_status(true);
+               else
+                       backlight_ops.set_custom_status(false);
+               break;
+
+       default:
+               return -1;
+       }
+       return 0;
+}
+
+extern int get_charging_status(int *val);
+//static int get_charging_status(int *val)
+//{
+       //return vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, val);
+//}
+
+static void check_seed_status(void)
+{
+       int ret = -1;
+       int tmp = 0;
+       int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
+       int brt = 0;
+       int lock_state = -1;
+
+       /* Charging check */
+       if ((get_charging_status(&tmp) == 0) && (tmp > 0))
+               pm_status_flag |= CHRGR_FLAG;
+
+       ret = get_setting_brightness(&tmp);
+       if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
+               _I("fail to read vconf value for brightness");
+               brt = PM_DEFAULT_BRIGHTNESS;
+               if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)
+                       vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
+               tmp = brt;
+       }
+       _I("Set brightness from Setting App. %d", tmp);
+       backlight_ops.set_default_brt(tmp);
+
+       vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
+       if (low_battery_state(bat_state)) {
+               if (!(pm_status_flag & CHRGR_FLAG)) {
+                       power_saving_func(true);
+                       pm_status_flag |= LOWBT_FLAG;
+               }
+       }
+
+       /* lock screen check */
+       ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
+       set_lock_screen_state(lock_state);
+       if (lock_state == VCONFKEY_IDLE_LOCK) {
+               states[S_NORMAL].timeout = lock_screen_timeout;
+               _I("LCD NORMAL timeout is set by %d ms"
+                       " for lock screen", lock_screen_timeout);
+       }
+
+       return;
+}
+
+static void init_lcd_operation(void)
+{
+       const struct device_ops *ops = NULL;
+
+       ops = find_device("display");
+       if (!check_default(ops))
+               DD_LIST_APPEND(lcdon_ops, ops);
+
+       ops = find_device("touchkey");
+       if (!check_default(ops))
+               DD_LIST_APPEND(lcdon_ops, ops);
+
+       ops = find_device("touchscreen");
+       if (!check_default(ops))
+               DD_LIST_APPEND(lcdon_ops, ops);
+}
+
+static void exit_lcd_operation(void)
+{
+       dd_list *l = NULL;
+       dd_list *l_next = NULL;
+       const struct device_ops *ops = NULL;
+
+       DD_LIST_FOREACH_SAFE(lcdon_ops, l, l_next, ops)
+               DD_LIST_REMOVE_LIST(lcdon_ops, l);
+}
+
+enum {
+       INIT_SETTING = 0,
+       INIT_INTERFACE,
+       INIT_POLL,
+       INIT_FIFO,
+       INIT_DBUS,
+       INIT_END
+};
+
+static const char *errMSG[INIT_END] = {
+       [INIT_SETTING] = "setting init error",
+       [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
+       [INIT_POLL] = "input devices poll init error",
+       [INIT_FIFO] = "FIFO poll init error",
+       [INIT_DBUS] = "d-bus init error",
+};
+
+int set_lcd_timeout(int on, int dim, int holdkey_block, const char *name)
+{
+       if (on == 0 && dim == 0) {
+               _I("LCD timeout changed : default setting");
+               custom_normal_timeout = custom_dim_timeout = 0;
+       } else if (on < 0 || dim < 0) {
+               _E("fail to set value (%d,%d)", on, dim);
+               return -EINVAL;
+       } else {
+               _I("LCD timeout changed : on(%ds), dim(%ds)", on, dim);
+               custom_normal_timeout = SEC_TO_MSEC(on);
+               custom_dim_timeout = SEC_TO_MSEC(dim);
+       }
+       /* Apply new backlight time */
+       update_display_time();
+       if (pm_cur_state == S_NORMAL)
+               states[pm_cur_state].trans(EVENT_INPUT);
+
+       if (holdkey_block) {
+               custom_holdkey_block = true;
+               _I("hold key disabled !");
+       } else {
+               custom_holdkey_block = false;
+               _I("hold key enabled !");
+       }
+
+       if (custom_change_name) {
+               free(custom_change_name);
+               custom_change_name = 0;
+       }
+
+       if (custom_normal_timeout == 0 &&
+           custom_dim_timeout == 0 &&
+           !holdkey_block)
+               return 0;
+
+       custom_change_name = strndup(name, strlen(name));
+       if (!custom_change_name) {
+               _E("Malloc falied!");
+               custom_normal_timeout = custom_dim_timeout = 0;
+               custom_holdkey_block = false;
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+void reset_lcd_timeout(GDBusConnection *conn,
+       const gchar     *sender,
+       const gchar     *unique_name,
+       gpointer         data)
+{
+       if (!sender)
+               return;
+
+       if (!custom_change_name)
+               return;
+
+       if (strcmp(sender, custom_change_name))
+               return;
+
+       _I("reset lcd timeout %s: set default timeout", sender);
+
+       free(custom_change_name);
+       custom_change_name = 0;
+       custom_normal_timeout = custom_dim_timeout = 0;
+       custom_holdkey_block = false;
+
+       update_display_time();
+       if (pm_cur_state == S_NORMAL)
+               states[pm_cur_state].trans(EVENT_INPUT);
+}
+
+static int booting_done(void *data)
+{
+       static int done;
+
+       if (!data)
+               return done;
+
+       done = *(int*)data;
+       if (!done)
+               return done;
+
+       _I("booting done. Release display and power lock");
+       if (disp_plgn.pm_unlock_internal) {
+               disp_plgn.pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
+               disp_plgn.pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL, PM_SLEEP_MARGIN);
+       }
+
+       return done;
+}
+
+int device_poweroff(void *data)
+{
+       static int off;
+
+       if (!data)
+               return off;
+
+       off = *(int *)data;
+       if (off)
+               _I("Poweroff");
+
+       return off;
+}
+
+static int process_background(void *data)
+{
+       pid_t pid;
+       PmLockNode *node;
+
+       pid = *(pid_t *)data;
+
+       node = find_node(S_NORMAL, pid);
+       if (node) {
+               node->background = true;
+               _I("%d pid is background, then PM will be unlocked LCD_NORMAL", pid);
+       }
+
+       return 0;
+}
+
+static int process_foreground(void *data)
+{
+       pid_t pid;
+       PmLockNode *node;
+
+       pid = *(pid_t *)data;
+
+       node = find_node(S_NORMAL, pid);
+       if (node) {
+               node->background = false;
+               _I("%d pid is foreground, then PM will be maintained locked LCD_NORMAL", pid);
+       }
+
+       return 0;
+}
+
+static int display_load_config(struct parse_result *result, void *user_data)
+{
+       struct display_config *c = user_data;
+
+       _D("%s,%s,%s", result->section, result->name, result->value);
+
+       if (!c)
+               return -EINVAL;
+
+       if (!MATCH(result->section, "Display"))
+               return 0;
+
+       if (MATCH(result->name, "LockScreenWaitingTime")) {
+               SET_CONF(c->lock_wait_time, atof(result->value));
+               _D("lock wait time is %.3f", c->lock_wait_time);
+       } else if (MATCH(result->name, "LongPressInterval")) {
+               SET_CONF(c->longpress_interval, atof(result->value));
+               _D("long press interval is %.3f", c->longpress_interval);
+       } else if (MATCH(result->name, "LightSensorSamplingInterval")) {
+               SET_CONF(c->lightsensor_interval, atof(result->value));
+               _D("lightsensor interval is %.3f", c->lightsensor_interval);
+       } else if (MATCH(result->name, "LCDOffTimeout")) {
+               SET_CONF(c->lcdoff_timeout, atoi(result->value));
+               _D("lcdoff timeout is %d ms", c->lcdoff_timeout);
+       } else if (MATCH(result->name, "BrightnessChangeStep")) {
+               SET_CONF(c->brightness_change_step, atoi(result->value));
+               _D("brightness change step is %d", c->brightness_change_step);
+       } else if (MATCH(result->name, "LCDAlwaysOn")) {
+               c->lcd_always_on = (MATCH(result->value, "yes") ? 1 : 0);
+               _D("LCD always on is %d", c->lcd_always_on);
+       } else if (MATCH(result->name, "ChangedFrameRateAllowed")) {
+               if (strstr(result->value, "setting")) {
+                       c->framerate_app[REFRESH_SETTING] = 1;
+                       _D("framerate app is Setting");
+               }
+               if (strstr(result->value, "all")) {
+                       memset(c->framerate_app, 1, sizeof(c->framerate_app));
+                       _D("framerate app is All");
+               }
+       } else if (MATCH(result->name, "ControlDisplay")) {
+               c->control_display = (MATCH(result->value, "yes") ? 1 : 0);
+               _D("ControlDisplay is %d", c->control_display);
+       } else if (MATCH(result->name, "PowerKeyDoublePressSupport")) {
+               c->powerkey_doublepress = (MATCH(result->value, "yes") ? 1 : 0);
+               _D("PowerKeyDoublePressSupport is %d", c->powerkey_doublepress);
+       } else if (MATCH(result->name, "AccelSensorOn")) {
+               c->accel_sensor_on = (MATCH(result->value, "yes") ? 1 : 0);
+               _D("AccelSensorOn is %d", c->accel_sensor_on);
+       } else if (MATCH(result->name, "ContinuousSampling")) {
+               c->continuous_sampling = (MATCH(result->value, "yes") ? 1 : 0);
+               _D("ContinuousSampling is %d", c->continuous_sampling);
+       } else if (MATCH(result->name, "TimeoutEnable")) {
+               c->timeout_enable = (MATCH(result->value, "yes") ? true : false);
+               _D("Timeout is %s", c->timeout_enable ? "enalbed" : "disabled");
+       } else if (MATCH(result->name, "InputSupport")) {
+               c->input_support = (MATCH(result->value, "yes") ? true : false);
+               _D("Input is %s", c->input_support ? "supported" : "NOT supported");
+       }
+
+       return 0;
+}
+
+static bool check_wm_ready(void)
+{
+       if (access("/run/.wm_ready", F_OK) == 0) {
+               _I("Window manager is ready");
+               return true;
+       }
+
+       _I("Window manager is not ready");
+       return false;
+}
+
+static gboolean lcd_on_wm_ready(gpointer data)
+{
+       int timeout;
+
+       if (!check_wm_ready())
+               return G_SOURCE_CONTINUE;
+
+       switch (pm_cur_state) {
+       case S_NORMAL:
+       case S_LCDDIM:
+               lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
+               if (display_conf.timeout_enable) {
+                       timeout = states[S_NORMAL].timeout;
+                       /* check minimun lcd on time */
+                       if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
+                               timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
+                       reset_timeout(timeout);
+               }
+               break;
+       default:
+               break;
+       }
+
+       return G_SOURCE_REMOVE;
+}
+
+static void add_timer_for_wm_ready(void)
+{
+       guint id = g_timeout_add(500/* milliseconds */, lcd_on_wm_ready, NULL);
+       if (id == 0)
+               _E("Failed to add wm_ready timeout");
+}
+
+/**
+ * Power manager Main
+ *
+ */
+static int display_probe(void *data)
+{
+       int ret;
+
+       /**
+        * load display service
+        * if there is no display shared library,
+        * deviced does not provide any method and function of display.
+        */
+       ret = display_service_load();
+       if (ret)
+               return ret;
+
+       /* display_plugin instance initialization */
+       init_pm_internal();
+       disp_plgn.check_lcdoff_lock_state = __check_lcdoff_lock_state;
+
+       return 0;
+}
+
+static void display_init(void *data)
+{
+       int ret, i;
+       int timeout = 0;
+       bool wm_ready;
+
+       _I("Start power manager");
+
+       signal(SIGHUP, sig_hup);
+
+       power_saving_func = default_saving_mode;
+
+       /* load configutation */
+       ret = config_parse(DISPLAY_CONF_FILE, display_load_config, &display_conf);
+       if (ret < 0)
+               _W("Failed to load %s, %d Use default value!",
+                   DISPLAY_CONF_FILE, ret);
+
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+       register_notifier(DEVICE_NOTIFIER_PROCESS_BACKGROUND, process_background);
+       register_notifier(DEVICE_NOTIFIER_PROCESS_FOREGROUND, process_foreground);
+       register_notifier(DEVICE_NOTIFIER_POWEROFF, device_poweroff);
+
+       for (i = INIT_SETTING; i < INIT_END; i++) {
+               switch (i) {
+               case INIT_SETTING:
+                       ret = init_setting(update_setting);
+                       break;
+               case INIT_INTERFACE:
+                       if (display_conf.timeout_enable)
+                               get_lcd_timeout_from_settings();
+                       ret = init_sysfs();
+                       break;
+               case INIT_POLL:
+                       _I("input init");
+                       pm_callback = poll_callback;
+                       if (display_conf.input_support)
+                               ret = init_input();
+                       else
+                               ret = 0;
+                       break;
+               case INIT_DBUS:
+                       _I("dbus init");
+                       ret = init_pm_dbus();
+                       break;
+               }
+               if (ret != 0) {
+                       _E("%s", errMSG[i]);
+                       break;
+               }
+       }
+
+       if (i == INIT_END) {
+               display_ops_init(NULL);
+#ifdef ENABLE_PM_LOG
+               pm_history_init();
+#endif
+               init_lcd_operation();
+               check_seed_status();
+
+               /* wm_ready needs to be checked
+                * since display manager can be launched later than deviced.
+                * In the case, display cannot be turned on at the first booting */
+               wm_ready = check_wm_ready();
+               if (wm_ready)
+                       lcd_on_procedure(LCD_NORMAL, LCD_ON_BY_EVENT);
+               else
+                       add_timer_for_wm_ready();
+
+               if (display_conf.lcd_always_on) {
+                       _I("LCD always on!");
+                       trans_table[S_NORMAL][EVENT_TIMEOUT] = S_NORMAL;
+               }
+
+               _I("Start Power managing without noti");
+               if (power_ops.get_power_lock_support())
+                       power_ops.power_lock();
+
+               pm_cur_state = S_NORMAL;
+               set_setting_pmstate(pm_cur_state);
+
+               if (display_conf.timeout_enable) {
+                       timeout = states[S_NORMAL].timeout;
+                       /* check minimun lcd on time */
+                       if (timeout < SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT))
+                               timeout = SEC_TO_MSEC(DEFAULT_NORMAL_TIMEOUT);
+
+                       reset_timeout(timeout);
+               }
+
+               status = DEVICE_OPS_STATUS_START;
+               /*
+                * Lock lcd off until booting is done.
+                * deviced guarantees all booting script is executing.
+                * Last script of booting unlocks this suspend blocking state.
+                */
+               if (disp_plgn.pm_lock_internal) {
+                       disp_plgn.pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
+                                       STAY_CUR_STATE, BOOTING_DONE_WATING_TIME);
+                       disp_plgn.pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_NORMAL,
+                                       STAY_CUR_STATE, BOOTING_DONE_WATING_TIME);
+               }
+
+               if (display_conf.input_support)
+                       if (CHECK_OPS(keyfilter_ops, init))
+                               keyfilter_ops->init();
+       }
+}
+
+static void display_exit(void *data)
+{
+       int i = INIT_END;
+
+       status = DEVICE_OPS_STATUS_STOP;
+
+       /* Set current state to S_NORMAL */
+       pm_cur_state = S_NORMAL;
+       set_setting_pmstate(pm_cur_state);
+       /* timeout is not needed */
+       reset_timeout(TIMEOUT_NONE);
+
+       if (CHECK_OPS(keyfilter_ops, exit))
+               keyfilter_ops->exit();
+
+       display_ops_exit(NULL);
+
+       for (i = i - 1; i >= INIT_SETTING; i--) {
+               switch (i) {
+               case INIT_SETTING:
+                       exit_setting();
+                       break;
+               case INIT_INTERFACE:
+                       exit_sysfs();
+                       break;
+               case INIT_POLL:
+                       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+                       unregister_notifier(DEVICE_NOTIFIER_PROCESS_BACKGROUND, process_background);
+                       unregister_notifier(DEVICE_NOTIFIER_PROCESS_FOREGROUND, process_foreground);
+                       unregister_notifier(DEVICE_NOTIFIER_POWEROFF, device_poweroff);
+
+                       exit_input();
+                       break;
+               }
+       }
+
+       exit_lcd_operation();
+       free_lock_info_list();
+
+       /* free display service */
+       display_service_free();
+
+       _I("Stop power manager");
+}
+
+static int display_start(enum device_flags flags)
+{
+       /* NORMAL MODE */
+       if (flags & NORMAL_MODE) {
+               if (flags & LCD_PANEL_OFF_MODE)
+                       /* standby on */
+                       backlight_ops.standby(true);
+               else
+                       /* normal lcd on */
+                       backlight_ops.on(flags);
+               return 0;
+       }
+
+       /* CORE LOGIC MODE */
+       if (!(flags & CORE_LOGIC_MODE))
+               return 0;
+
+       if (status == DEVICE_OPS_STATUS_START)
+               return -EALREADY;
+
+       if (display_probe(NULL) < 0)
+               return -EPERM;
+
+       display_init(NULL);
+
+       return 0;
+}
+
+static int display_stop(enum device_flags flags)
+{
+       /* NORMAL MODE */
+       if (flags & NORMAL_MODE) {
+               backlight_ops.off(flags);
+               return 0;
+       }
+
+       /* CORE LOGIC MODE */
+       if (!(flags & CORE_LOGIC_MODE))
+               return 0;
+
+       if (status == DEVICE_OPS_STATUS_STOP)
+               return -EALREADY;
+
+       display_exit(NULL);
+
+       return 0;
+}
+
+static int display_status(void)
+{
+       return status;
+}
+
+static const struct device_ops display_device_ops = {
+       .priority = DEVICE_PRIORITY_HIGH,
+       .name     = "display",
+       .probe    = display_probe,
+       .init     = display_init,
+       .exit     = display_exit,
+       .start    = display_start,
+       .stop     = display_stop,
+       .status   = display_status,
+};
+
+DEVICE_OPS_REGISTER(&display_device_ops)
+
+/**
+ * @}
+ */
diff --git a/plugins/iot/display/device-interface.c b/plugins/iot/display/device-interface.c
new file mode 100755 (executable)
index 0000000..3e7144f
--- /dev/null
@@ -0,0 +1,711 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <math.h>
+#include <assert.h>
+#include <errno.h>
+#include <hw/display.h>
+
+#include "ambient-mode.h"
+#include "core/log.h"
+#include "core/devices.h"
+#include "core/list.h"
+#include "core/common.h"
+#include "util.h"
+#include "device-interface.h"
+#include "vconf.h"
+#include "core.h"
+#include "device-node.h"
+
+#define TOUCH_ON       1
+#define TOUCH_OFF      0
+
+#define LCD_PHASED_MIN_BRIGHTNESS      1
+#define LCD_PHASED_MAX_BRIGHTNESS      100
+#define LCD_PHASED_CHANGE_STEP         5
+#define LCD_PHASED_DELAY               35000 /* microsecond */
+
+#define POWER_AUTOSLEEP_PATH    "/sys/power/autosleep"
+#define POWER_LOCK_PATH         "/sys/power/wake_lock"
+#define POWER_UNLOCK_PATH       "/sys/power/wake_unlock"
+#define POWER_WAKEUP_PATH       "/sys/power/wakeup_count"
+#define POWER_STATE_PATH        "/sys/power/state"
+
+enum {
+       POWER_UNLOCK = 0,
+       POWER_LOCK,
+};
+
+struct _backlight_ops backlight_ops;
+struct _power_ops power_ops;
+
+static bool custom_status;
+static int custom_brightness;
+static int force_brightness;
+static int default_brightness;
+
+static struct display_device *display_dev;
+
+static int bl_onoff(int on)
+{
+       enum display_state val;
+
+       if (!display_dev || !display_dev->set_state)
+               return dpms_set_power(on);
+
+       switch (on) {
+       case DPMS_ON:
+               val = DISPLAY_ON;
+               break;
+       case DPMS_STANDBY:
+               val = DISPLAY_STANDBY;
+               break;
+       case DPMS_SUSPEND:
+               val = DISPLAY_SUSPEND;
+               break;
+       case DPMS_OFF:
+               val = DISPLAY_OFF;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return display_dev->set_state(val);
+}
+
+static int bl_brt(int brightness, int delay)
+{
+       int ret = -1;
+
+       if (delay > 0)
+               usleep(delay);
+
+       if (force_brightness > 0) {
+               _I("brightness(%d), force brightness(%d)",
+                   brightness, force_brightness);
+               brightness = force_brightness;
+       }
+
+       /* Update device brightness */
+       ret = backlight_ops.set_brightness(brightness);
+
+       _I("set brightness %d, %d", brightness, ret);
+
+       return ret;
+}
+
+static int system_suspend(void)
+{
+       int ret;
+
+       _I("system suspend");
+       ret = sys_set_str(POWER_STATE_PATH, "mem");
+       _I("system resume (result : %d)", ret);
+       return 0;
+}
+
+static int system_enable_autosleep(void)
+{
+       _I("system autosleep enabled");
+       return sys_set_str(POWER_AUTOSLEEP_PATH, "mem");
+}
+
+static int system_power_lock(void)
+{
+       dd_list *elem, *elem_n;
+       const struct device_ops *dev;
+       int ret;
+
+       _I("system power lock");
+       ret = sys_set_str(POWER_LOCK_PATH, "mainlock");
+
+       /* Devices Resume */
+       DD_LIST_FOREACH_SAFE(dev_head, elem, elem_n, dev) {
+               if (dev->resume)
+                       dev->resume();
+       }
+
+       return ret;
+}
+
+static int system_power_unlock(void)
+{
+       dd_list *elem, *elem_n;
+       const struct device_ops *dev;
+
+       /* Devices Suspend */
+       DD_LIST_FOREACH_SAFE(dev_head, elem, elem_n, dev) {
+               if (dev->suspend)
+                       dev->suspend();
+       }
+
+       _I("system power unlock");
+       return sys_set_str(POWER_UNLOCK_PATH, "mainlock");
+}
+
+static int system_get_power_lock_support(void)
+{
+       static int power_lock_support = -1;
+       int ret;
+
+       if (power_lock_support >= 0)
+               goto out;
+
+       ret = sys_check_node(POWER_LOCK_PATH);
+       if (ret < 0)
+               power_lock_support = false;
+       else
+               power_lock_support = true;
+
+       _I("system power lock : %s",
+                       (power_lock_support ? "support" : "not support"));
+
+out:
+       return power_lock_support;
+}
+
+static int get_lcd_power(void)
+{
+       enum dpms_state state;
+       enum display_state val;
+       int ret;
+
+       if (ambient_get_state())
+               return DPMS_OFF;
+
+       if (!display_dev || !display_dev->get_state) {
+               ret = dpms_get_power(&state);
+               if (ret < 0)
+                       return ret;
+               return state;
+       }
+
+       ret = display_dev->get_state(&val);
+       if (ret < 0)
+               return ret;
+
+       switch (val) {
+       case DISPLAY_ON:
+               return DPMS_ON;
+       case DISPLAY_STANDBY:
+               return DPMS_STANDBY;
+       case DISPLAY_SUSPEND:
+               return DPMS_SUSPEND;
+       case DISPLAY_OFF:
+               return DPMS_OFF;
+       default:
+               return -EINVAL;
+       }
+}
+
+void change_brightness(int start, int end, int step)
+{
+       int diff, val;
+       int ret = -1;
+       int prev;
+
+       if ((pm_status_flag & PWRSV_FLAG) &&
+           !(pm_status_flag & BRTCH_FLAG))
+               return;
+
+       ret = backlight_ops.get_brightness(&prev);
+       if (ret < 0) {
+               _E("fail to get brightness : %d", ret);
+               return;
+       }
+
+       if (prev == end)
+               return;
+
+       _D("start %d end %d step %d", start, end, step);
+
+       diff = end - start;
+
+       if (abs(diff) < step)
+               val = (diff > 0 ? 1 : -1);
+       else
+               val = (int)ceil((double)diff / step);
+
+       while (start != end) {
+               if (val == 0) break;
+
+               start += val;
+               if ((val > 0 && start > end) ||
+                   (val < 0 && start < end))
+                       start = end;
+
+               bl_brt(start, LCD_PHASED_DELAY);
+       }
+}
+
+static int backlight_on(enum device_flags flags)
+{
+       int ret = -1;
+
+       _D("LCD on %x", flags);
+
+       ret = bl_onoff(DPMS_ON);
+       if (ret < 0)
+               _E("Failed to turn on backlight");
+
+       if (flags & LCD_PHASED_TRANSIT_MODE)
+               change_brightness(LCD_PHASED_MIN_BRIGHTNESS,
+                   default_brightness, LCD_PHASED_CHANGE_STEP);
+
+       return ret;
+}
+
+static int backlight_off(enum device_flags flags)
+{
+       int ret = -1;
+
+       _D("LCD off %x", flags);
+
+       if (flags & LCD_PHASED_TRANSIT_MODE)
+               change_brightness(default_brightness,
+                   LCD_PHASED_MIN_BRIGHTNESS, LCD_PHASED_CHANGE_STEP);
+
+       if (flags & AMBIENT_MODE)
+               return 0;
+
+       ret = bl_onoff(DPMS_OFF);
+       if (ret < 0)
+               _E("Failed to turn off backlight");
+
+       return ret;
+}
+
+static int backlight_dim(void)
+{
+       int ret;
+       int brightness;
+
+       if (vconf_get_int(VCONFKEY_SETAPPL_LCD_DIM_BRIGHTNESS, &brightness) != 0) {
+               _E("Failed to get VCONFKEY_SETAPPL_LCD_DIM_BRIGHTNESS value");
+               return -EPERM;
+       }
+
+       ret = bl_brt(brightness, 0);
+#ifdef ENABLE_PM_LOG
+       if (!ret)
+               pm_history_save(PM_LOG_LCD_DIM, pm_cur_state);
+       else
+               pm_history_save(PM_LOG_LCD_DIM_FAIL, pm_cur_state);
+#endif
+       return ret;
+}
+
+static int set_custom_status(bool on)
+{
+       custom_status = on;
+       return 0;
+}
+
+static bool get_custom_status(void)
+{
+       return custom_status;
+}
+
+static int save_custom_brightness(void)
+{
+       int ret, brightness;
+
+       ret = backlight_ops.get_brightness(&brightness);
+
+       custom_brightness = brightness;
+
+       return ret;
+}
+
+static int custom_backlight_update(void)
+{
+       int ret = 0;
+
+       if (custom_brightness < PM_MIN_BRIGHTNESS ||
+           custom_brightness > PM_MAX_BRIGHTNESS)
+               return -EINVAL;
+
+       if ((pm_status_flag & PWRSV_FLAG) && !(pm_status_flag & BRTCH_FLAG)) {
+               ret = backlight_dim();
+       } else {
+               _I("custom brightness restored! %d", custom_brightness);
+               ret = bl_brt(custom_brightness, 0);
+       }
+
+       return ret;
+}
+
+static int set_force_brightness(int level)
+{
+       if (level < 0 ||  level > PM_MAX_BRIGHTNESS)
+               return -EINVAL;
+
+       force_brightness = level;
+
+       return 0;
+}
+
+static int backlight_update(void)
+{
+       int ret = 0;
+
+       if (get_custom_status()) {
+               _I("custom brightness mode! brt no updated");
+               return 0;
+       }
+       if ((pm_status_flag & PWRSV_FLAG) && !(pm_status_flag & BRTCH_FLAG))
+               ret = backlight_dim();
+       else
+               ret = bl_brt(default_brightness, 0);
+
+       return ret;
+}
+
+static int backlight_standby(int force)
+{
+       int ret = -1;
+
+       if ((get_lcd_power() == DPMS_ON) || force) {
+               _I("LCD standby");
+               ret = bl_onoff(DPMS_STANDBY);
+       }
+
+       return ret;
+}
+
+static int set_default_brt(int level)
+{
+       if (level < PM_MIN_BRIGHTNESS || level > PM_MAX_BRIGHTNESS)
+               level = PM_DEFAULT_BRIGHTNESS;
+
+       default_brightness = level;
+
+       return 0;
+}
+
+static int check_wakeup_src(void)
+{
+       /*  TODO if nedded.
+        * return wackeup source. user input or device interrupts? (EVENT_DEVICE or EVENT_INPUT)
+        */
+       return EVENT_DEVICE;
+}
+
+static int get_wakeup_count(int *cnt)
+{
+       int ret;
+       int wakeup_count;
+
+       if (!cnt)
+               return -EINVAL;
+
+       ret = sys_get_int(POWER_WAKEUP_PATH, &wakeup_count);
+       if (ret < 0)
+               return ret;
+
+       *cnt = wakeup_count;
+       return 0;
+}
+
+static int set_wakeup_count(int cnt)
+{
+       int ret;
+
+       ret = sys_set_int(POWER_WAKEUP_PATH, cnt);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int get_max_brightness(void)
+{
+       static int max = -1;
+       int ret;
+
+       if (max > 0)
+               return max;
+
+       if (!display_dev) {
+               _E("there is no display device");
+               return -ENOENT;
+       }
+
+       if (!display_dev->get_max_brightness) {
+               max = DEFAULT_DISPLAY_MAX_BRIGHTNESS;
+               return max;
+       }
+
+       ret = display_dev->get_max_brightness(&max);
+       if (ret < 0) {
+               _E("Failed to get max brightness (%d)", ret);
+               return ret;
+       }
+
+       return max;
+}
+
+static int set_brightness(int val)
+{
+       int max;
+
+       if (!display_dev || !display_dev->set_brightness) {
+               _E("there is no display device");
+               return -ENOENT;
+       }
+
+       max = get_max_brightness();
+       if (max < 0) {
+               _E("Failed to get max brightness");
+               return max;
+       }
+
+       /* Maximum Brightness to users is 100.
+        * Thus real brightness need to be calculated */
+       val = val * max / 100;
+
+       return display_dev->set_brightness(val);
+}
+
+static int get_brt_normalized(int brt_raw)
+{
+       int quotient, remainder;
+       int max;
+
+       max = get_max_brightness();
+       if (max < 0) {
+               _E("Failed to get max brightness");
+               return max;
+       }
+
+       /* Maximum Brightness to users is 100.
+        * Thus the brightness value need to be calculated using real brightness.
+        *    ex) Let's suppose that the maximum brightness of driver is 255.
+        *      case 1) When the user sets the brightness to 41,
+        *              real brightness is
+        *                 41 * 255 / 100 = 104.55 = 104 (rounded off)
+        *      case 2) When the user gets the brightness,
+        *              the driver returns the brightness 104.
+        *              Thus the brightness to users is
+        *                 104 * 100 / 255 = 40.7843.... = 41 (rounded up)
+        */
+       quotient = brt_raw * 100 / max;
+       remainder = brt_raw * 100 % max;
+       if (remainder > 0)
+               quotient++;
+
+       return quotient;
+}
+
+static int get_brightness(int *val)
+{
+       int brt, ret;
+
+       if (!display_dev || !display_dev->get_brightness) {
+               _E("there is no display device");
+               return -ENOENT;
+       }
+
+       ret = display_dev->get_brightness(&brt);
+       if (ret < 0) {
+               _E("failed to get brightness (%d)", ret);
+               return ret;
+       }
+
+       *val = get_brt_normalized(brt);
+       return 0;
+}
+
+static int get_brightness_by_light_sensor(float lmax, float lmin, float light, int *brt)
+{
+       int brt_raw;
+       int ret;
+
+       if (!display_dev || !display_dev->get_auto_brightness)
+               return -ENOTSUP;
+
+       ret = display_dev->get_auto_brightness(lmax, lmin, light, &brt_raw);
+       if (ret < 0) {
+               _E("failed to get brightness by light sensor(%d)", ret);
+               return ret;
+       }
+
+       *brt = get_brt_normalized(brt_raw);
+       return 0;
+}
+
+static int get_frame_rate(int *rate)
+{
+       if (!rate)
+               return -EINVAL;
+
+       if (!display_dev || !display_dev->get_frame_rate)
+               return -ENOTSUP;
+
+       return display_dev->get_frame_rate(rate);
+}
+
+static int set_frame_rate(int rate)
+{
+       int ret;
+       static int fmin = -1, fmax = -1;
+
+       if (!display_dev ||
+               !display_dev->set_frame_rate)
+               return -ENOTSUP;
+
+       if (display_dev->get_min_frame_rate) {
+               if (fmin < 0) {
+                       ret = display_dev->get_min_frame_rate(&fmin);
+                       if (ret < 0) {
+                               _E("Failed to get min frate rate (%d)", ret);
+                               return ret;
+                       }
+               }
+               if (rate < fmin) {
+                       _E("Invalid rate(%d)! (Valid rate: %d <= rate)", rate, fmin);
+                       return -EINVAL;
+               }
+       }
+
+       if (display_dev->get_max_frame_rate) {
+               if (fmax < 0) {
+                       ret = display_dev->get_max_frame_rate(&fmax);
+                       if (ret < 0) {
+                               _E("Failed to get max frate rate (%d)", ret);
+                               return ret;
+                       }
+               }
+               if (rate > fmax) {
+                       _E("Invalid rate(%d)! (Valid rate: rate <= %d)", rate, fmax);
+                       return -EINVAL;
+               }
+       }
+
+       return display_dev->set_frame_rate(rate);
+}
+
+static void _init_ops(void)
+{
+       backlight_ops.off = backlight_off;
+       backlight_ops.dim = backlight_dim;
+       backlight_ops.on = backlight_on;
+       backlight_ops.update = backlight_update;
+       backlight_ops.standby = backlight_standby;
+       backlight_ops.set_default_brt = set_default_brt;
+       backlight_ops.get_lcd_power = get_lcd_power;
+       backlight_ops.set_custom_status = set_custom_status;
+       backlight_ops.get_custom_status = get_custom_status;
+       backlight_ops.save_custom_brightness = save_custom_brightness;
+       backlight_ops.custom_update = custom_backlight_update;
+       backlight_ops.set_force_brightness = set_force_brightness;
+       backlight_ops.set_brightness = set_brightness;
+       backlight_ops.get_brightness = get_brightness;
+       backlight_ops.get_brightness_by_light_sensor = get_brightness_by_light_sensor;
+       backlight_ops.get_frame_rate = get_frame_rate;
+       backlight_ops.set_frame_rate = set_frame_rate;
+
+       power_ops.suspend = system_suspend;
+       power_ops.enable_autosleep = system_enable_autosleep;
+       power_ops.power_lock = system_power_lock;
+       power_ops.power_unlock = system_power_unlock;
+       power_ops.get_power_lock_support = system_get_power_lock_support;
+       power_ops.check_wakeup_src = check_wakeup_src;
+       power_ops.get_wakeup_count = get_wakeup_count;
+       power_ops.set_wakeup_count = set_wakeup_count;
+}
+
+int display_service_load(void)
+{
+       struct hw_info *info;
+       int r;
+
+       if (display_dev)
+               return 0;
+
+       r = hw_get_info(DISPLAY_HARDWARE_DEVICE_ID,
+                       (const struct hw_info **)&info);
+       if (r < 0) {
+               _I("display shared library is not supported: %d", r);
+               return -ENODEV;
+       }
+
+       if (!info->open) {
+               _E("fail to open display device : open(NULL)");
+               return -EPERM;
+       }
+
+       r = info->open(info, NULL, (struct hw_common **)&display_dev);
+       if (r < 0) {
+               _E("fail to get display device structure : %d", r);
+               return -EPERM;
+       }
+
+       _D("display device structure load success");
+       return 0;
+}
+
+int display_service_free(void)
+{
+       struct hw_info *info;
+
+       if (!display_dev)
+               return -ENOENT;
+
+       info = display_dev->common.info;
+
+       assert(info);
+
+       info->close((struct hw_common *)display_dev);
+       display_dev = NULL;
+
+       return 0;
+}
+
+int init_sysfs()
+{
+       _init_ops();
+       return 0;
+}
+
+int exit_sysfs(void)
+{
+       const struct device_ops *ops = NULL;
+
+       backlight_update();
+
+       ops = find_device("touchscreen");
+       if (!check_default(ops))
+               ops->start(NORMAL_MODE);
+
+       ops = find_device("touchkey");
+       if (!check_default(ops))
+               ops->start(NORMAL_MODE);
+
+       return 0;
+}
diff --git a/plugins/iot/display/display-actor.c b/plugins/iot/display/display-actor.c
new file mode 100644 (file)
index 0000000..bab8630
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+
+#include "util.h"
+#include "display-actor.h"
+#include "core/list.h"
+#include "core/common.h"
+
+static dd_list *actor_head;
+
+void display_add_actor(struct display_actor_ops *actor)
+{
+       DD_LIST_APPEND(actor_head, actor);
+}
+
+static struct display_actor_ops *display_find_actor(enum display_actor_id id)
+{
+       dd_list *elem;
+       struct display_actor_ops *actor;
+
+       DD_LIST_FOREACH(actor_head, elem, actor) {
+               if (actor->id == id)
+                       return actor;
+       }
+       return NULL;
+}
+
+int display_set_caps(enum display_actor_id id, unsigned int caps)
+{
+       struct display_actor_ops *actor;
+
+       if (id <= 0 || !caps)
+               return -EINVAL;
+
+       actor = display_find_actor(id);
+       if (!actor)
+               return -EINVAL;
+
+       actor->caps |= caps;
+
+       return 0;
+}
+
+int display_reset_caps(enum display_actor_id id, unsigned int caps)
+{
+       struct display_actor_ops *actor;
+
+       if (id <= 0 || !caps)
+               return -EINVAL;
+
+       actor = display_find_actor(id);
+       if (!actor)
+               return -EINVAL;
+
+       actor->caps &= ~caps;
+
+       return 0;
+}
+
+unsigned int display_get_caps(enum display_actor_id id)
+{
+       struct display_actor_ops *actor;
+
+       if (id <= 0)
+               return 0;
+
+       actor = display_find_actor(id);
+       if (!actor)
+               return 0;
+
+       return actor->caps;
+}
+
+int display_has_caps(unsigned int total_caps, unsigned int caps)
+{
+       if (!total_caps || !caps)
+               return false;
+
+       if ((total_caps & caps) == caps)
+               return true;
+
+       return false;
+}
+
diff --git a/plugins/iot/display/display-dbus.c b/plugins/iot/display/display-dbus.c
new file mode 100755 (executable)
index 0000000..be40ed8
--- /dev/null
@@ -0,0 +1,1146 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * @file       display-dbus.c
+ * @brief      dbus interface
+ *
+ */
+
+#include <error.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <device-node.h>
+#include <libgdbus/dbus-system.h>
+
+#include "ambient-mode.h"
+#include "core/log.h"
+#include "util.h"
+#include "core.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/device-idler.h"
+#include "apps/apps.h"
+#include "dd-display.h"
+#include "display-actor.h"
+#include "display-ops.h"
+#include <device/display.h>
+
+#define SIGNAL_HOMESCREEN       "HomeScreen"
+
+#define DUMP_MODE_WATING_TIME   600000
+
+#define EXPIRED_POPUP_TYPE_POWER   "power_lock_expired"
+#define EXPIRED_POPUP_PID    "_APP_PID_"
+#define EXPIRED_POPUP_COMM   "_APP_COMM_"
+#define EXPIRED_POPUP_ID     "_REQUEST_ID_"
+
+#define CHECK_POWEROFF() \
+       do { \
+               if (device_poweroff(NULL)) { \
+                       _E("Ignore requests for display during power off"); \
+                       return g_variant_new("(i)", -EBUSY); \
+               } \
+       } while (0)
+
+extern struct display_plugin disp_plgn;
+
+GVariant *dbus_start(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       static const struct device_ops *display_device_ops = NULL;
+
+       if (device_poweroff(NULL))
+               goto out;
+
+       if (!display_device_ops)
+               display_device_ops = find_device("display");
+       if (NOT_SUPPORT_OPS(display_device_ops))
+               goto out;
+
+       display_device_ops->start(CORE_LOGIC_MODE);
+out:
+       return dbus_handle_new_g_variant_tuple();
+}
+
+GVariant *dbus_stop(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       static const struct device_ops *display_device_ops = NULL;
+
+       if (device_poweroff(NULL))
+               goto out;
+
+       if (!display_device_ops)
+               display_device_ops = find_device("display");
+       if (NOT_SUPPORT_OPS(display_device_ops))
+               goto out;
+
+       display_device_ops->stop(CORE_LOGIC_MODE);
+out:
+       return dbus_handle_new_g_variant_tuple();
+}
+
+GVariant *dbus_lockstate(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       char *state_str;
+       char *option1_str;
+       char *option2_str;
+       int timeout;
+       pid_t pid;
+       int state;
+       int flag;
+       int ret = 0;
+       unsigned int caps;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(sssi)", &state_str, &option1_str, &option2_str, &timeout);
+
+       if (!state_str || timeout < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!strcmp(state_str, "privilege check"))
+               goto out;
+
+       pid = dbus_connection_get_sender_pid(conn, sender);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (!strcmp(state_str, PM_LCDON_STR))
+               state = LCD_NORMAL;
+       else if (!strcmp(state_str, PM_LCDDIM_STR))
+               state = LCD_DIM;
+       else if (!strcmp(state_str, PM_LCDOFF_STR))
+               state = LCD_OFF;
+       else {
+               _E("%s state is invalid, dbus ignored!", state_str);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!strcmp(option1_str, STAYCURSTATE_STR))
+               flag = STAY_CUR_STATE;
+       else if (!strcmp(option1_str, GOTOSTATENOW_STR))
+               flag = GOTO_STATE_NOW;
+       else {
+               _E("%s option is invalid. set default option!", option1_str);
+               flag = STAY_CUR_STATE;
+       }
+
+       if (!strcmp(option2_str, HOLDKEYBLOCK_STR))
+               flag |= HOLD_KEY_BLOCK;
+
+       if (flag & GOTO_STATE_NOW) {
+               caps = display_get_caps(DISPLAY_ACTOR_API);
+
+               if (!display_has_caps(caps, DISPLAY_CAPA_LCDON) &&
+                   state == LCD_NORMAL) {
+                       _D("No lcdon capability!");
+                       ret = -EPERM;
+                       goto out;
+               }
+               if (!display_has_caps(caps, DISPLAY_CAPA_LCDOFF) &&
+                   state == LCD_OFF) {
+                       _D("No lcdoff capability!");
+                       ret = -EPERM;
+                       goto out;
+               }
+       }
+
+       if (check_dimstay(state, flag) == true) {
+               _E("LCD state can not be changed to OFF state now!");
+               flag &= ~GOTO_STATE_NOW;
+               flag |= STAY_CUR_STATE;
+       }
+
+       if (disp_plgn.pm_lock_internal)
+               ret = disp_plgn.pm_lock_internal(pid, state, flag, timeout);
+out:
+       g_free(state_str);
+       g_free(option1_str);
+       g_free(option2_str);
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_unlockstate(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       char *state_str;
+       char *option_str;
+       pid_t pid;
+       int state;
+       int flag;
+       int ret = 0;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(ss)", &state_str, &option_str);
+
+       if (!state_str) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!strcmp(state_str, "privilege check"))
+               goto out;
+
+       pid = dbus_connection_get_sender_pid(conn, sender);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (!strcmp(state_str, PM_LCDON_STR))
+               state = LCD_NORMAL;
+       else if (!strcmp(state_str, PM_LCDDIM_STR))
+               state = LCD_DIM;
+       else if (!strcmp(state_str, PM_LCDOFF_STR))
+               state = LCD_OFF;
+       else {
+               _E("%s state is invalid, dbus ignored!", state_str);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!strcmp(option_str, SLEEP_MARGIN_STR))
+               flag = PM_SLEEP_MARGIN;
+       else if (!strcmp(option_str, RESET_TIMER_STR))
+               flag = PM_RESET_TIMER;
+       else if (!strcmp(option_str, KEEP_TIMER_STR))
+               flag = PM_KEEP_TIMER;
+       else {
+               _E("%s option is invalid. set default option!", option_str);
+               flag = PM_RESET_TIMER;
+       }
+
+       if (disp_plgn.pm_unlock_internal)
+               ret = disp_plgn.pm_unlock_internal(pid, state, flag);
+out:
+       g_free(state_str);
+       g_free(option_str);
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_changestate(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       char *state_str;
+       pid_t pid;
+       int state;
+       int ret = 0;
+       unsigned int caps;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(s)", &state_str);
+
+       if (!state_str) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!strcmp(state_str, "privilege check"))
+               goto out;
+
+       pid = dbus_connection_get_sender_pid(conn, sender);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (!strcmp(state_str, PM_LCDON_STR))
+               state = LCD_NORMAL;
+       else if (!strcmp(state_str, PM_LCDDIM_STR))
+               state = LCD_DIM;
+       else if (!strcmp(state_str, PM_LCDOFF_STR))
+               state = LCD_OFF;
+       else if (!strcmp(state_str, PM_STANDBY_STR))
+               state = STANDBY;
+       else if (!strcmp(state_str, PM_SUSPEND_STR))
+               state = SUSPEND;
+       else {
+               _E("%s state is invalid, dbus ignored!", state_str);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       caps = display_get_caps(DISPLAY_ACTOR_API);
+
+       if (!display_has_caps(caps, DISPLAY_CAPA_LCDON) &&
+           state == LCD_NORMAL) {
+               _D("No lcdon capability!");
+               ret = -EPERM;
+               goto out;
+       }
+       if (!display_has_caps(caps, DISPLAY_CAPA_LCDOFF) &&
+           state == LCD_OFF) {
+               _D("No lcdoff capability!");
+               ret = -EPERM;
+               goto out;
+       }
+
+       if (check_dimstay(state, GOTO_STATE_NOW) == true) {
+               _E("LCD state can not be changed to OFF state!");
+               ret = -EBUSY;
+               goto out;
+       }
+
+       if (disp_plgn.pm_change_internal)
+               ret = disp_plgn.pm_change_internal(pid, state);
+
+       if (!ret && state == LCD_OFF)
+               update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
+out:
+       g_free(state_str);
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_getdisplaycount(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret;
+
+       CHECK_POWEROFF();
+
+       ret = DEFAULT_DISPLAY_COUNT;
+
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_getmaxbrightness(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret, state;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(i)", &state);
+       if (state == DISPLAY_STATE_NORMAL)
+               ret = DEFAULT_DISPLAY_MAX_BRIGHTNESS;
+       else if (state == DISPLAY_STATE_SCREEN_DIM)
+               ret = DEFAULT_DISPLAY_MAX_DIM_BRIGHTNESS;
+       else
+               ret = -EINVAL;
+
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_setmaxbrightness(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret;
+
+       CHECK_POWEROFF();
+
+       ret = -ENOTSUP;
+
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_getbrightness(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int brt = -1, state, ret;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(i)", &state);
+
+       if (state == DISPLAY_STATE_NORMAL) {
+               ret = backlight_ops.get_brightness(&brt);
+       } else if (state == DISPLAY_STATE_SCREEN_DIM) {
+               ret = vconf_get_int(VCONFKEY_SETAPPL_LCD_DIM_BRIGHTNESS, &brt);
+       } else
+               ret = -EINVAL;
+
+       if (ret >= 0)
+               ret = brt;
+
+       _I("get brightness %d, %d", brt, ret);
+
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_setbrightness(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int state, brt, autobrt, ret = 0, caps;
+
+       CHECK_POWEROFF();
+
+       caps = display_get_caps(DISPLAY_ACTOR_API);
+
+       if (!display_has_caps(caps, DISPLAY_CAPA_BRIGHTNESS)) {
+               _D("No brightness changing capability!");
+               ret = -EPERM;
+               goto error;
+       }
+
+       g_variant_get(param, "(ii)", &state, &brt);
+
+       if (vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &autobrt) != 0) {
+               _E("Failed to get VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT value");
+               autobrt = SETTING_BRIGHTNESS_AUTOMATIC_OFF;
+       }
+
+       if (autobrt == SETTING_BRIGHTNESS_AUTOMATIC_ON) {
+               _E("auto_brightness state is ON, can not change the brightness value");
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (state == DISPLAY_STATE_NORMAL) {
+               ret = backlight_ops.set_brightness(brt);
+               if (ret < 0)
+                       goto error;
+
+               if (vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt) != 0)
+                       _E("Failed to set VCONFKEY_SETAPPL_LCD_BRIGHTNESS value");
+       } else if (state == DISPLAY_STATE_SCREEN_DIM) {
+               if (pm_cur_state == S_LCDDIM) {
+                       ret = backlight_ops.set_brightness(brt);
+                       if (ret < 0)
+                               goto error;
+               }
+
+               if (vconf_set_int(VCONFKEY_SETAPPL_LCD_DIM_BRIGHTNESS, brt) != 0)
+                       _E("Failed to set VCONFKEY_SETAPPL_LCD_DIM_BRIGHTNESS value");
+       } else
+               ret = -EINVAL;
+
+       _I("set brightness %d, %d", brt, ret);
+
+error:
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_holdbrightness(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int brt, autobrt, ret, caps;
+
+       CHECK_POWEROFF();
+
+       caps = display_get_caps(DISPLAY_ACTOR_API);
+
+       if (!display_has_caps(caps, DISPLAY_CAPA_BRIGHTNESS)) {
+               _D("No brightness changing capability!");
+               ret = -EPERM;
+               goto error;
+       }
+
+       g_variant_get(param, "(i)", &brt);
+
+       if (vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &autobrt) != 0) {
+               _E("Failed to get VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT value");
+               autobrt = SETTING_BRIGHTNESS_AUTOMATIC_OFF;
+       }
+
+       vconf_set_int(VCONFKEY_PM_CUSTOM_BRIGHTNESS_STATUS, VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON);
+
+       ret = backlight_ops.set_brightness(brt);
+       if (ret < 0)
+               goto error;
+
+       if (autobrt == SETTING_BRIGHTNESS_AUTOMATIC_ON) {
+               _D("Auto brightness will be paused");
+               vconf_set_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, SETTING_BRIGHTNESS_AUTOMATIC_PAUSE);
+       }
+
+       _I("hold brightness %d, %d", brt, ret);
+
+error:
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_releasebrightness(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int bat, charger, changed, setting, brt, autobrt, ret = 0;
+
+       CHECK_POWEROFF();
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat) != 0) {
+               _E("Failed to get VCONFKEY_SYSMAN_BATTERY_STATUS_LOW value");
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger) != 0) {
+               _E("Failed to get VCONFKEY_SYSMAN_CHARGER_STATUS value");
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (vconf_get_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, &changed) != 0) {
+               _E("Failed to get VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM value");
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (vconf_get_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, &setting) != 0) {
+               _E("Failed to get VCONFKEY_SETAPPL_LCD_BRIGHTNESS value");
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &autobrt) != 0) {
+               _E("Failed to get VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT value");
+               ret = -EPERM;
+               goto error;
+       }
+
+       vconf_set_int(VCONFKEY_PM_CUSTOM_BRIGHTNESS_STATUS, VCONFKEY_PM_CUSTOM_BRIGHTNESS_OFF);
+
+       ret = backlight_ops.get_brightness(&brt);
+       if (ret < 0)
+               brt = ret;
+
+       // check dim state
+       if (low_battery_state(bat) &&
+           charger == VCONFKEY_SYSMAN_CHARGER_DISCONNECTED && !changed) {
+               _D("batt warning low : brightness is not changed!");
+               if (brt != 0)
+                       backlight_ops.set_brightness(0);
+               goto error;
+       }
+
+       if (autobrt == SETTING_BRIGHTNESS_AUTOMATIC_OFF) {
+               if (brt != setting)
+                       backlight_ops.set_brightness(setting);
+       } else if (autobrt == SETTING_BRIGHTNESS_AUTOMATIC_PAUSE) {
+               _D("Auto brightness will be enable");
+               vconf_set_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, SETTING_BRIGHTNESS_AUTOMATIC_ON);
+       }
+
+error:
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_setrefreshrate(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int app, val, ret, control;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(ii)", &app, &val);
+
+       if (app < 0 || app >= ARRAY_SIZE(display_conf.framerate_app) || val < 0) {
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (!display_conf.framerate_app[app]) {
+               _I("This case(%d) is not support in this target", app);
+               ret = -EPERM;
+               goto error;
+       }
+
+       control = display_conf.control_display;
+
+       if (control)
+               backlight_ops.off(NORMAL_MODE);
+
+       _D("app : %d, value : %d", app, val);
+       ret = backlight_ops.set_frame_rate(val);
+       if (ret < 0)
+               _E("Failed to set frame rate (%d)", ret);
+
+       if (control)
+               backlight_ops.on(NORMAL_MODE);
+
+error:
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_setautobrightnessmin(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int val, ret;
+       pid_t pid;
+       int id = 0;
+
+       CHECK_POWEROFF();
+
+       if (!display_info.set_autobrightness_min) {
+               ret = -EIO;
+               goto error;
+       }
+       g_variant_get(param, "(i)", &val);
+
+       pid = dbus_connection_get_sender_pid(conn, sender);
+       ret = display_info.set_autobrightness_min(val, (char *)sender);
+       if (ret) {
+               _W("fail to set autobrightness min %d, %d by %d", val, ret, pid);
+               goto error;
+       }
+       if (display_info.reset_autobrightness_min) {
+               id = dbus_handle_watch_name(sender, display_info.reset_autobrightness_min, NULL, NULL, NULL);
+               if (id <= 0) {
+                       _E("failed to watch name %s, id %d", sender, id);
+                       //todo: set return value
+               }
+               _I("set autobrightness min %d by %d", val, pid);
+       }
+error:
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_setlcdtimeout(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int on, dim, holdkey_block, ret;
+       pid_t pid;
+       int id = 0;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(iii)", &on, &dim, &holdkey_block);
+
+       pid = dbus_connection_get_sender_pid(conn, sender);
+       ret = set_lcd_timeout(on, dim, holdkey_block, sender);
+       if (ret) {
+               _W("fail to set lcd timeout %d by %d", ret, pid);
+       } else {
+               id = dbus_handle_watch_name(sender, reset_lcd_timeout, NULL, NULL, NULL);
+               if (id <= 0) {
+                       _E("failed to watch name %s, id %d", sender, id);
+                       //todo: set return value
+               }
+               _I("set lcd timeout on %d, dim %d, holdblock %d by %d",
+                   on, dim, holdkey_block, pid);
+       }
+
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_lockscreenbgon(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret = 0;
+       char *on = NULL;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(s)", &on);
+
+       if (!strcmp(on, "true")) {
+               if (disp_plgn.update_pm_setting) 
+                       disp_plgn.update_pm_setting(SETTING_LOCK_SCREEN_BG, true);
+       } else if (!strcmp(on, "false")) {
+               if (disp_plgn.update_pm_setting) 
+                       disp_plgn.update_pm_setting(SETTING_LOCK_SCREEN_BG, false);
+       } else {
+               ret = -EINVAL;
+       }
+
+       g_free(on);
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_dumpmode(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret = 0;
+       char *on;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(s)", &on);
+
+       if (!strcmp(on, "on")) {
+               if (disp_plgn.pm_lock_internal)
+                       disp_plgn.pm_lock_internal(INTERNAL_LOCK_DUMPMODE, LCD_OFF,
+                               STAY_CUR_STATE, DUMP_MODE_WATING_TIME);
+       } else if (!strcmp(on, "off")) {
+               if (disp_plgn.pm_unlock_internal)
+                       disp_plgn.pm_unlock_internal(INTERNAL_LOCK_DUMPMODE, LCD_OFF, PM_SLEEP_MARGIN);
+       } else {
+               ret = -EINVAL;
+       }
+
+       g_free(on);
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_savelog(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       if (!device_poweroff(NULL))
+               save_display_log();
+       return dbus_handle_new_g_variant_tuple();
+}
+
+GVariant *dbus_powerkeyignore(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret = 0;
+       int on;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(i)", &on);
+
+       if (CHECK_OPS(keyfilter_ops, set_powerkey_ignore))
+               keyfilter_ops->set_powerkey_ignore(on == 1 ? true : false);
+
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_powerkeylcdoff(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret;
+
+       CHECK_POWEROFF();
+
+       if (CHECK_OPS(keyfilter_ops, powerkey_lcdoff))
+               ret = keyfilter_ops->powerkey_lcdoff();
+       else
+               ret = -ENOSYS;
+
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_customlcdon(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret = 0;
+       int timeout;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(i)", &timeout);
+
+       ret = custom_lcdon(timeout);
+
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_staytouchscreenoff(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret = 0;
+       int val;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(i)", &val);
+
+       set_stay_touchscreen_off(val);
+
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_lcdpaneloffmode(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret = 0;
+       int val;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(i)", &val);
+
+       set_lcd_paneloff_mode(val);
+
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_actorcontrol(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret = 0, val, actor;
+       char *op;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(sii)", &op, &actor, &val);
+
+       if (!strcmp(op, "set"))
+               ret = display_set_caps(actor, val);
+       else if (!strcmp(op, "reset"))
+               ret = display_reset_caps(actor, val);
+       else
+               ret = -EINVAL;
+
+       g_free(op);
+       return g_variant_new("(i)", ret);
+}
+
+GVariant *dbus_getcustombrightness(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int status = 0;
+
+       CHECK_POWEROFF();
+
+       status = backlight_ops.get_custom_status();
+
+       return g_variant_new("(i)", status);
+}
+
+struct pmlock_expired_s {
+       char req_id[32];
+       GDBusMethodInvocation *invocation;
+       int value;
+       pid_t pid;
+};
+
+static dd_list *expired_req_list;
+
+static int get_command(pid_t pid, char *comm, size_t len)
+{
+       FILE *fp;
+       char path[PATH_MAX];
+       char name[NAME_MAX];
+       char *tmp;
+       int ret;
+
+       snprintf(path, sizeof(path), "/proc/%d/comm", pid);
+
+       fp = fopen(path, "r");
+       if (!fp) {
+               _E("Failed to open file %s, errno:%d", path, errno);
+               return -errno;
+       }
+
+       ret = fread(name, 1, sizeof(name) - 1, fp);
+       name[ret] = '\0';
+       fclose(fp);
+
+       tmp = name;
+       while (*tmp != '\0') {
+               if (*tmp == '\n' ||
+                               *tmp == '\r') {
+                       *tmp = '\0';
+                       break;
+               }
+               tmp++;
+       }
+
+       snprintf(comm, len, "%s", name);
+
+       return 0;
+}
+
+GVariant *dbus_locktimeout_expired(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret;
+       char *req_id;
+       pid_t pid;
+       char pid_str[16];
+       char comm[NAME_MAX];
+       struct pmlock_expired_s *ex = NULL;
+       GVariant *gvar = NULL;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(s)", &req_id);
+
+       pid = dbus_connection_get_sender_pid(conn, sender);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       ret = get_command(pid, comm, sizeof(comm));
+       if (ret < 0) {
+               _E("Failed to get command (%d)", ret);
+               goto out;
+       }
+
+       ex = calloc(1, sizeof(struct pmlock_expired_s));
+       if (!ex) {
+               _E("calloc() failed");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       snprintf(pid_str, sizeof(pid_str), "%d", pid);
+       ret = launch_system_app(APP_DEFAULT, 8,
+                       APP_KEY_TYPE,
+                       EXPIRED_POPUP_TYPE_POWER,
+                       EXPIRED_POPUP_PID,
+                       pid_str,
+                       EXPIRED_POPUP_COMM,
+                       comm,
+                       EXPIRED_POPUP_ID,
+                       req_id);
+       if (ret < 0) {
+               _E("Failed to launch pmlock expired popup(%d)", ret);
+               goto out;
+       }
+
+       ex->pid = pid;
+       snprintf(ex->req_id, sizeof(ex->req_id), "%s", req_id);
+
+       ex->invocation = invocation;
+
+       DD_LIST_APPEND(expired_req_list, ex);
+
+       g_free(req_id);
+       return NULL;
+
+out:
+       gvar = g_variant_new("(si)", req_id, ret);
+       g_free(req_id);
+       if (ex)
+               free(ex);
+       return gvar;
+}
+
+static gboolean app_term(gpointer data)
+{
+       struct pmlock_expired_s *ex = data;
+
+       if (ex) {
+               if (kill(ex->pid, 0) != -1)
+                       kill(ex->pid, SIGKILL);
+               free(ex);
+       }
+       return G_SOURCE_REMOVE;
+}
+
+static void expired_deliver_result(void *data)
+{
+       struct pmlock_expired_s *ex = data;
+       struct pmlock_expired_s *item = NULL;
+       dd_list *l;
+       size_t len;
+       int value;
+       char *id;
+
+       if (!ex)
+               return;
+
+       len = strlen(ex->req_id) + 1;
+       DD_LIST_FOREACH(expired_req_list, l, item) {
+               if (!strncmp(item->req_id, ex->req_id, len)) {
+                       DD_LIST_REMOVE(expired_req_list, item);
+                       break;
+               }
+       }
+       if (!item)
+               goto out;
+
+       id = ex->req_id;
+       value = ex->value;
+
+       _I("User input of req_id(%s) is (%s)", id, value == 0 ? "ALLOW power lock" :
+                       (value == 2) ? "KILL app" : "Release power lock");
+
+       if (!item->invocation) {
+               _E("item->invocation is null");
+               goto out;
+       }
+       g_dbus_method_invocation_return_value(item->invocation, g_variant_new("(si)", id, value));
+
+       if (value == 2) {
+               kill(item->pid, SIGTERM);
+               g_timeout_add(3000, app_term, (gpointer)item);
+               item = NULL;
+       }
+
+out:
+       free(ex);
+       free(item);
+}
+
+GVariant *dbus_locktimeout_input(GDBusConnection *conn,
+       const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
+       GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       int ret;
+       char *req_id;
+       struct pmlock_expired_s *ex;
+       int value;
+
+       CHECK_POWEROFF();
+
+       g_variant_get(param, "(si)", &req_id, &value);
+
+       ex = calloc(1, sizeof(struct pmlock_expired_s));
+       if (!ex) {
+               _E("calloc() failed");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       snprintf(ex->req_id, sizeof(ex->req_id), "%s", req_id);
+       ex->value = value;
+
+       _I("req_id(%s), value(%d)", ex->req_id, ex->value);
+
+       add_idle_request(expired_deliver_result, ex);
+
+       ret = 0;
+
+out:
+       g_free(req_id);
+       return g_variant_new("(i)", ret);
+}
+
+static const dbus_method_s dbus_methods[] = {
+       { "start",           NULL,  NULL, dbus_start },
+       { "stop",            NULL,  NULL, dbus_stop },
+       { "lockstate",     "sssi",   "i", dbus_lockstate },
+       { "unlockstate",     "ss",   "i", dbus_unlockstate },
+       { "changestate",      "s",   "i", dbus_changestate },
+       { "ChangeState",      "s",   "i", dbus_changestate },
+       { "getbrightness",    "i",   "i", dbus_getbrightness }, /* deprecated */
+       { "setbrightness",   "ii",   "i", dbus_setbrightness }, /* deprecated */
+       { "setframerate",    "ii",   "i", dbus_setrefreshrate },        /* deprecated */
+       { "setautobrightnessmin", "i", "i", dbus_setautobrightnessmin },
+       { "setlcdtimeout",  "iii",   "i", dbus_setlcdtimeout },
+       { "LockScreenBgOn",   "s",   "i", dbus_lockscreenbgon },
+       { "GetDisplayCount", NULL,   "i", dbus_getdisplaycount },
+       { "GetMaxBrightness", "i",  "i", dbus_getmaxbrightness },
+       { "SetMaxBrightness", "i",   "i", dbus_setmaxbrightness },
+       { "GetBrightness",    "i",   "i", dbus_getbrightness },
+       { "SetBrightness",   "ii",   "i", dbus_setbrightness },
+       { "HoldBrightness",   "i",   "i", dbus_holdbrightness },
+       { "ReleaseBrightness", NULL, "i", dbus_releasebrightness },
+       { "SetRefreshRate",  "ii",   "i", dbus_setrefreshrate },
+       { "Dumpmode",         "s",   "i", dbus_dumpmode },
+       { "SaveLog",         NULL,  NULL, dbus_savelog },
+       { "PowerKeyIgnore",   "i",   "i", dbus_powerkeyignore },
+       { "PowerKeyLCDOff",  NULL,   "i", dbus_powerkeylcdoff },
+       { "CustomLCDOn",      "i",   "i", dbus_customlcdon },
+       { "StayTouchScreenOff", "i", "i", dbus_staytouchscreenoff },
+       { "LCDPanelOffMode",  "i",   "i", dbus_lcdpaneloffmode },
+       { "ActorControl",   "sii",   "i", dbus_actorcontrol },
+       { "CustomBrightness", NULL,  "i", dbus_getcustombrightness },
+       { "CurrentBrightness", NULL, "i", dbus_getbrightness }, /* deprecated. It is remained for tizen 2.4 */
+       { "LockTimeoutExpired", "s", "i", dbus_locktimeout_expired },
+       { "LockTimeoutInput",  "si", "i", dbus_locktimeout_input },
+       /* Add methods here */
+};
+
+static const dbus_interface_u dbus_interface = {
+       .oh = NULL,
+       .name = DEVICED_INTERFACE_DISPLAY,
+       .methods = dbus_methods,
+       .nr_methods = ARRAY_SIZE(dbus_methods),
+};
+
+static void homescreen_signal_handler(GDBusConnection  *conn,
+                                                                               const gchar      *sender,
+                                                                               const gchar      *path,
+                                                                               const gchar      *iface,
+                                                                               const gchar      *name,
+                                                                               GVariant         *param,
+                                                                               gpointer          data)
+{
+       char *screen;
+       pid_t pid;
+
+       g_variant_get(param, "(s)", &screen);
+
+       _D("screen : %s", screen);
+
+       pid = dbus_connection_get_sender_pid(conn, sender);
+       ambient_set_screen(screen, pid);
+       g_free(screen);
+}
+
+/*
+ * Default capability
+ * api      := LCDON | LCDOFF | BRIGHTNESS
+ * gesture  := LCDON
+ */
+static struct display_actor_ops display_api_actor = {
+       .id     = DISPLAY_ACTOR_API,
+       .caps   = DISPLAY_CAPA_LCDON |
+                 DISPLAY_CAPA_LCDOFF |
+                 DISPLAY_CAPA_BRIGHTNESS,
+};
+
+static struct display_actor_ops display_gesture_actor = {
+       .id     = DISPLAY_ACTOR_GESTURE,
+       .caps   = DISPLAY_CAPA_LCDON,
+};
+
+int init_pm_dbus(void)
+{
+       int ret;
+
+       display_add_actor(&display_api_actor);
+       display_add_actor(&display_gesture_actor);
+
+       ret = dbus_handle_add_dbus_object(NULL, DEVICED_PATH_DISPLAY, &dbus_interface);
+       if (ret < 0)
+               _E("fail to init dbus method(%d)", ret);
+
+       ret = subscribe_dbus_signal(NULL,
+                               DEVICED_OBJECT_PATH,
+                               DEVICED_INTERFACE_NAME,
+                               SIGNAL_HOMESCREEN,
+                               homescreen_signal_handler,
+                               NULL, NULL);
+       if (ret <= 0) {
+               _E("Failed to register signal handler! %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
diff --git a/plugins/iot/display/display-ops.c b/plugins/iot/display/display-ops.c
new file mode 100644 (file)
index 0000000..22b9137
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+
+#include "util.h"
+#include "display-ops.h"
+#include "core/list.h"
+#include "core/common.h"
+
+static dd_list *disp_head;
+
+void add_display(const struct display_ops *disp)
+{
+       DD_LIST_APPEND(disp_head, disp);
+}
+
+void remove_display(const struct display_ops *disp)
+{
+       DD_LIST_REMOVE(disp_head, disp);
+}
+
+const struct display_ops *find_display_feature(const char *name)
+{
+       dd_list *elem;
+       const struct display_ops *disp;
+
+       DD_LIST_FOREACH(disp_head, elem, disp) {
+               if (!strcmp(disp->name, name))
+                       return disp;
+       }
+       return NULL;
+}
+
+void display_ops_init(void *data)
+{
+       dd_list *elem;
+       const struct display_ops *disp;
+
+       DD_LIST_FOREACH(disp_head, elem, disp) {
+               _D("[%s] initialize", disp->name);
+               if (disp->init)
+                       disp->init(data);
+       }
+}
+
+void display_ops_exit(void *data)
+{
+       dd_list *elem;
+       const struct display_ops *disp;
+
+       DD_LIST_FOREACH(disp_head, elem, disp) {
+               _D("[%s] deinitialize", disp->name);
+               if (disp->exit)
+                       disp->exit(data);
+       }
+}
+
diff --git a/plugins/iot/display/dpms-wayland-none.c b/plugins/iot/display/dpms-wayland-none.c
new file mode 100644 (file)
index 0000000..cf1db2e
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <libgdbus/dbus-system.h>
+
+#include "device-interface.h"
+#include "util.h"
+#include "core.h"
+
+#define ENLIGHTENMENT_BUS_NAME          "org.enlightenment.wm"
+#define ENLIGHTENMENT_OBJECT_PATH       "/org/enlightenment/wm"
+#define ENLIGHTENMENT_INTERFACE_NAME    ENLIGHTENMENT_BUS_NAME".dpms"
+
+static void dpms_set_cb(GVariant *var, void *user_data, GError *err)
+{
+       int state;
+
+       if (!var) {
+               _E("no message [%s], Cannot get pmlock check",
+                   err->message);
+               return;
+       }
+
+       if (!dh_get_param_from_var(var, "(i)", &state)) {
+               _E("no message [%s]", g_variant_get_type_string(var));
+               goto out;
+       }
+
+       _D("DPMS was set %d", state);
+
+#ifdef ENABLE_PM_LOG
+       switch (state) {
+       case DPMS_ON:
+               pm_history_save(PM_LOG_LCD_ON, pm_cur_state);
+               break;
+       case DPMS_OFF:
+               pm_history_save(PM_LOG_LCD_OFF, pm_cur_state);
+               break;
+       default:
+               break;
+       }
+#endif
+
+out:
+       g_variant_unref(var);
+}
+
+int dpms_set_power(enum dpms_state state)
+{
+       int ret;
+
+       ret = dbus_handle_method_async_with_reply_var(ENLIGHTENMENT_BUS_NAME,
+                       ENLIGHTENMENT_OBJECT_PATH,
+                       ENLIGHTENMENT_INTERFACE_NAME,
+                       "set",
+                       g_variant_new("(u)", state),
+                       dpms_set_cb,
+                       -1,
+                       NULL);
+
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int dpms_get_power(enum dpms_state *state)
+{
+       int ret;
+
+       if (!state)
+               return -EINVAL;
+
+       ret = dbus_handle_method_sync(ENLIGHTENMENT_BUS_NAME,
+                       ENLIGHTENMENT_OBJECT_PATH,
+                       ENLIGHTENMENT_INTERFACE_NAME,
+                       "get",
+                       NULL, NULL);
+       if (ret < 0)
+               return ret;
+
+       *state = ret;
+       return 0;
+}
diff --git a/plugins/iot/display/input.c b/plugins/iot/display/input.c
new file mode 100644 (file)
index 0000000..95714ac
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <linux/input.h>
+#include <libinput.h>
+
+#include "util.h"
+#include "core.h"
+#include "poll.h"
+
+#define SEAT_NAME   "seat0"
+
+static struct udev *udev;
+static struct libinput *li;
+static guint efd;
+
+int (*pm_callback) (int, PMMsg *);
+
+static inline void process_event(struct libinput_event *ev)
+{
+       static const struct device_ops *display_device_ops;
+       struct input_event input;
+       struct libinput *li;
+       struct libinput_event_keyboard *k;
+       unsigned int time;
+       int fd;
+
+       if (!pm_callback)
+               return;
+
+       if (!display_device_ops) {
+               display_device_ops = find_device("display");
+               if (!display_device_ops)
+                       return;
+       }
+
+       /* do not operate when display stops */
+       if (device_get_status(display_device_ops)
+                       != DEVICE_OPS_STATUS_START) {
+               _E("display status is stop");
+               return;
+       }
+
+       switch (libinput_event_get_type(ev)) {
+       case LIBINPUT_EVENT_DEVICE_ADDED:
+               return;
+       case LIBINPUT_EVENT_KEYBOARD_KEY:
+               k = libinput_event_get_keyboard_event(ev);
+               time = libinput_event_keyboard_get_time(k);
+               li = libinput_event_get_context(ev);
+
+               input.time.tv_sec = MSEC_TO_SEC(time);
+               input.time.tv_usec = MSEC_TO_USEC(time % 1000);
+               input.type = EV_KEY;
+               input.code = libinput_event_keyboard_get_key(k);
+               input.value = libinput_event_keyboard_get_key_state(k);
+
+               fd = libinput_get_fd(li);
+               _D("time %d.%d type %d code %d value %d fd %d",
+                               input.time.tv_sec, input.time.tv_usec, input.type,
+                               input.code, input.value, fd);
+
+               if (CHECK_OPS(keyfilter_ops, check) &&
+                   keyfilter_ops->check(&input, fd) != 0)
+                       return;
+               break;
+       case LIBINPUT_EVENT_POINTER_MOTION:
+       case LIBINPUT_EVENT_POINTER_BUTTON:
+       case LIBINPUT_EVENT_POINTER_AXIS:
+               li = libinput_event_get_context(ev);
+               input.type = EV_REL;
+
+               fd = libinput_get_fd(li);
+               _D("type %d fd %d", input.type, fd);
+
+               if (CHECK_OPS(keyfilter_ops, check) &&
+                   keyfilter_ops->check(&input, fd) != 0)
+                       return;
+               break;
+       case LIBINPUT_EVENT_TOUCH_DOWN:
+       case LIBINPUT_EVENT_TOUCH_UP:
+       case LIBINPUT_EVENT_TOUCH_MOTION:
+       case LIBINPUT_EVENT_TOUCH_FRAME:
+               if (touch_event_blocked())
+                       return ;
+               break;
+       default:
+               break;
+       }
+
+       /* lcd on or update lcd timeout */
+       (*pm_callback) (INPUT_POLL_EVENT, NULL);
+}
+
+static gboolean input_handler(gint fd, GIOCondition cond, void *data)
+{
+       struct libinput_event *ev;
+       struct libinput *input = (struct libinput *)data;
+
+       /* Ignore input during poweroff */
+       if (device_poweroff(NULL))
+               return G_SOURCE_CONTINUE;
+
+       if (!input)
+               return G_SOURCE_CONTINUE;
+
+       libinput_dispatch(input);
+
+       while ((ev = libinput_get_event(input))) {
+               process_event(ev);
+
+               libinput_event_destroy(ev);
+               libinput_dispatch(input);
+       }
+
+       return G_SOURCE_CONTINUE;
+}
+
+static int open_restricted(const char *path, int flags, void *user_data)
+{
+       int fd;
+       unsigned int clockid = CLOCK_MONOTONIC;
+
+       if (!path)
+               return -EINVAL;
+
+       fd = open(path, flags);
+       if (fd >= 0) {
+               /* TODO Why does fd change the clock? */
+               if (ioctl(fd, EVIOCSCLOCKID, &clockid) < 0)
+                       _E("fail to change clock %s", path);
+       }
+
+       return fd < 0 ? -errno : fd;
+}
+
+static void close_restricted(int fd, void *user_data)
+{
+       close(fd);
+}
+
+static const struct libinput_interface interface = {
+       .open_restricted = open_restricted,
+       .close_restricted = close_restricted,
+};
+
+int init_input(void)
+{
+       int ret;
+       int fd;
+
+       udev = udev_new();
+       if (!udev) {
+               _E("fail to create udev library context");
+               return -EPERM;
+       }
+
+       li = libinput_udev_create_context(&interface, NULL, udev);
+       if (!li) {
+               _E("fail to create a new libinput context from udev");
+               return -EPERM;
+       }
+
+       ret = libinput_udev_assign_seat(li, SEAT_NAME);
+       if (ret < 0) {
+               _E("fail to assign a seat");
+               return -EPERM;
+       }
+
+       fd = libinput_get_fd(li);
+       if (fd < 0) {
+               _E("fail to get file descriptor from libinput context");
+               return -EPERM;
+       }
+
+       /* add to poll handler */
+       efd = g_unix_fd_add(fd, G_IO_IN,
+                       input_handler,
+                       (void *)((intptr_t)li));
+       if (!efd) {
+               _E("fail to g_unix_fd_add");
+               /* TODO Does it really need close()? */
+               close(fd);
+               return -EPERM;
+       }
+
+       return 0;
+}
+
+int exit_input(void)
+{
+       if (efd) {
+               g_source_remove(efd);
+               efd = -1;
+       }
+       /* todo: close fd */
+
+       if (li)
+               libinput_unref(li);
+
+       if (udev)
+               udev_unref(udev);
+
+       return 0;
+}
diff --git a/plugins/iot/display/key-filter.c b/plugins/iot/display/key-filter.c
new file mode 100644 (file)
index 0000000..5e7cde7
--- /dev/null
@@ -0,0 +1,709 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <vconf.h>
+#include <sys/types.h>
+#include <libgdbus/dbus-system.h>
+
+#include "ambient-mode.h"
+#include "util.h"
+#include "core.h"
+#include "poll.h"
+#include "device-node.h"
+#include "display-actor.h"
+#include "display-ops.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+#include "power/power-handler.h"
+#include "led/touch-key.h"
+
+#include <linux/input.h>
+#ifndef KEY_SCREENLOCK
+#define KEY_SCREENLOCK         0x98
+#endif
+#ifndef SW_GLOVE
+#define SW_GLOVE               0x16
+#endif
+
+#define PREDEF_LEAVESLEEP      "leavesleep"
+#define POWEROFF_ACT                   "poweroff"
+#define PWROFF_POPUP_ACT               "pwroff-popup"
+#define USEC_PER_SEC                   1000000
+
+#define CAPTURE_COMBINATION_INTERVAL           0.5     /* 0.5 second */
+
+#define KEY_MAX_DELAY_TIME             700     /* ms */
+
+#define KEY_RELEASED           0
+#define KEY_PRESSED            1
+#define KEY_BEING_PRESSED      2
+
+#define SIGNAL_CHANGE_HARDKEY          "ChangeHardkey"
+#define SIGNAL_LCDON_BY_POWERKEY       "LCDOnByPowerkey"
+#define SIGNAL_LCDOFF_BY_POWERKEY      "LCDOffByPowerkey"
+
+#define TOUCH_RELEASE          (-1)
+
+#define GLOVE_MODE     1
+
+extern struct display_plugin disp_plgn;
+
+enum key_combination_flags {
+       KEY_COMBINATION_STOP            = 0,
+       KEY_COMBINATION_POWERKEY        = BIT(0),
+       KEY_COMBINATION_MENUKEY         = BIT(1),
+};
+
+enum combination_process {
+       COMBINATION_STOP        = KEY_COMBINATION_STOP,
+       COMBINATION_SCREENCAPTURE       = KEY_COMBINATION_POWERKEY | KEY_COMBINATION_MENUKEY,
+};
+
+int __WEAK__ get_glove_state(void);
+void __WEAK__ switch_glove_key(int val);
+
+static struct timeval pressed_time;
+static guint longkey_timeout_id = 0;
+static int cancel_lcdoff;
+static int key_combination = KEY_COMBINATION_STOP;
+static double combination_pressed_time;
+static bool touch_pressed = false;
+static int skip_lcd_off = false;
+static int skip_combination = false;
+static const struct device_ops *touchled;
+
+static int booting_done(void *data)
+{
+       static int done = 0;
+
+       if (!data)
+               return done;
+
+       done = *(int *)data;
+
+       _I("Booting done(%d)", done);
+
+       return done;
+}
+
+static inline int current_state_in_on(void)
+{
+       return (pm_cur_state == S_LCDDIM || pm_cur_state == S_NORMAL);
+}
+
+static inline void restore_custom_brightness(void)
+{
+       if (pm_cur_state == S_LCDDIM &&
+           backlight_ops.get_custom_status())
+               backlight_ops.custom_update();
+}
+
+static int power_execute(void *data)
+{
+       static const struct device_ops *ops = NULL;
+
+       FIND_DEVICE_INT(ops, POWER_OPS_NAME);
+
+       return ops->execute(data);
+}
+
+static void longkey_pressed()
+{
+       char *opt;
+       unsigned int caps;
+
+       _I("Power key long pressed!");
+       cancel_lcdoff = 1;
+
+       caps = display_get_caps(DISPLAY_ACTOR_POWER_KEY);
+
+       if (display_has_caps(caps, DISPLAY_CAPA_LCDON)) {
+               /* change state - LCD on */
+               if (disp_plgn.pm_change_internal)
+                       disp_plgn.pm_change_internal(INTERNAL_LOCK_POWERKEY, LCD_NORMAL);
+               (*pm_callback)(INPUT_POLL_EVENT, NULL);
+       }
+
+       if (!display_has_caps(caps, DISPLAY_CAPA_LCDOFF)) {
+               _D("No poweroff capability!");
+               return;
+       }
+
+
+       if (display_conf.lcd_always_on)
+               opt = POWEROFF_ACT;
+       else
+               opt = PWROFF_POPUP_ACT;
+       power_execute(opt);
+}
+
+static gboolean longkey_pressed_cb(void *data)
+{
+       longkey_pressed();
+       longkey_timeout_id = 0;
+
+       return G_SOURCE_REMOVE;
+}
+
+static unsigned long timediff_usec(struct timeval t1, struct timeval t2)
+{
+       unsigned long udiff;
+
+       udiff = (t2.tv_sec - t1.tv_sec) * USEC_PER_SEC;
+       udiff += (t2.tv_usec - t1.tv_usec);
+
+       return udiff;
+}
+
+static inline void check_key_pair(int code, int new, int *old)
+{
+       if (new == *old)
+               _E("key pair is not matched! (%d, %d)", code, new);
+       else
+               *old = new;
+}
+
+static inline void broadcast_lcdon_by_powerkey(void)
+{
+       dbus_handle_broadcast_dbus_signal(DEVICED_PATH_DISPLAY,
+                                       DEVICED_INTERFACE_DISPLAY,
+                                       SIGNAL_LCDON_BY_POWERKEY,
+                                       NULL, NULL);
+}
+
+static inline void broadcast_lcdoff_by_powerkey(void)
+{
+       dbus_handle_broadcast_dbus_signal(DEVICED_PATH_DISPLAY,
+                                       DEVICED_INTERFACE_DISPLAY,
+                                       SIGNAL_LCDOFF_BY_POWERKEY,
+                                       NULL, NULL);
+}
+
+static inline bool switch_on_lcd(void)
+{
+       if (current_state_in_on())
+               return false;
+
+       if (backlight_ops.get_lcd_power() == DPMS_ON) {
+               if (ambient_get_state() == false)
+                       return false;
+       }
+
+       broadcast_lcdon_by_powerkey();
+
+       lcd_on_direct(LCD_ON_BY_POWER_KEY);
+
+       return true;
+}
+
+static inline void switch_off_lcd(void)
+{
+       if (!current_state_in_on())
+               return;
+
+       if (backlight_ops.get_lcd_power() == DPMS_OFF)
+               return;
+
+       broadcast_lcdoff_by_powerkey();
+
+       lcd_off_procedure(LCD_OFF_BY_POWER_KEY);
+}
+
+static void check_key_combination(struct input_event *pinput)
+{
+       double press_time, diff_time;
+       press_time = (pinput->time).tv_sec + USEC_TO_SEC((pinput->time).tv_usec);
+
+       switch (key_combination) {
+       case COMBINATION_SCREENCAPTURE:
+               diff_time = press_time - combination_pressed_time;
+               if (diff_time <= CAPTURE_COMBINATION_INTERVAL) {
+                       _I("Combination key : SCREENCAPTURE mode");
+                       skip_combination = true;
+               }
+               break;
+       default:
+               combination_pressed_time = press_time;
+               return;
+       }
+
+}
+
+static void start_key_combination(struct input_event *pinput)
+{
+       switch (pinput->code) {
+       case KEY_POWER:
+               key_combination |= KEY_COMBINATION_POWERKEY;
+               break;
+       case KEY_MENU:
+               key_combination |= KEY_COMBINATION_MENUKEY;
+               break;
+       default:
+               return;
+       }
+
+       check_key_combination(pinput);
+}
+
+static void stop_key_combination(struct input_event *pinput)
+{
+       if (pinput == NULL) {
+               key_combination = KEY_COMBINATION_STOP;
+               return;
+       }
+
+       switch (pinput->code) {
+       case KEY_POWER:
+               key_combination &= ~KEY_COMBINATION_POWERKEY;
+               break;
+       case KEY_MENU:
+               key_combination &= ~KEY_COMBINATION_MENUKEY;
+               break;
+       default:
+               _E("Thid code(%d) is not combination type", pinput->code);
+               break;
+       }
+}
+
+static void process_combination_key(struct input_event *pinput)
+{
+       if (pinput->value == KEY_PRESSED)
+               start_key_combination(pinput);
+       else if (pinput->value == KEY_RELEASED)
+               stop_key_combination(pinput);
+}
+
+static int process_menu_key(struct input_event *pinput)
+{
+       int caps;
+
+       caps = display_get_caps(DISPLAY_ACTOR_MENU_KEY);
+
+       if (!display_has_caps(caps, DISPLAY_CAPA_LCDON)) {
+               if (current_state_in_on())
+                       return false;
+               _D("No lcd-on capability!");
+               return true;
+       } else if (pinput->value == KEY_PRESSED) {
+               switch_on_lcd();
+       }
+
+       return false;
+}
+
+static int decide_lcdoff(void)
+{
+       /* It's not needed if it's already LCD off state */
+       if (!current_state_in_on() &&
+           backlight_ops.get_lcd_power() != DPMS_ON)
+               return false;
+
+       /*
+        * This flag is set at the moment
+        * that LCD is turned on by power key
+        * LCD has not to turned off in the situation.
+        */
+       if (skip_lcd_off)
+               return false;
+
+       /* LCD is not turned off when powerkey is pressed,not released */
+       if (key_combination == KEY_COMBINATION_POWERKEY)
+               return false;
+
+       /* LCD-off is blocked at the moment poweroff popup shows */
+       if (cancel_lcdoff)
+               return false;
+
+       /* LCD-off is blocked when powerkey and volmedown key are pressed */
+       if (skip_combination)
+               return false;
+
+       /* At booting time, display must do not turn off */
+       if (!booting_done(NULL))
+               return false;
+
+       return true;
+}
+
+static int lcdoff_powerkey(void)
+{
+       int ignore = true;
+
+       if (decide_lcdoff() == true) {
+               check_processes(S_NORMAL);
+               check_processes(S_LCDDIM);
+
+               if (!check_holdkey_block(S_NORMAL) &&
+                   !check_holdkey_block(S_LCDDIM)) {
+                       if (display_info.update_auto_brightness)
+                               display_info.update_auto_brightness(false);
+                       switch_off_lcd();
+                       delete_condition(S_NORMAL);
+                       delete_condition(S_LCDDIM);
+                       update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_POWERKEY);
+                       if (disp_plgn.pm_change_internal)
+                               disp_plgn.pm_change_internal(INTERNAL_LOCK_POWERKEY, LCD_OFF);
+               }
+       } else {
+               ignore = false;
+               skip_combination = false;
+       }
+       cancel_lcdoff = 0;
+
+       return ignore;
+}
+
+static bool release_short_powerkey(void)
+{
+// mobile d - no, a - no
+// wearable d - yes, a - no
+// tv d - no, a - yes
+       if (!display_conf.powerkey_doublepress && !display_conf.lcd_always_on) {
+               lcdoff_powerkey();
+               return true;
+       } else if (display_conf.powerkey_doublepress && !display_conf.lcd_always_on) {
+               if (skip_lcd_off)
+                       return false;
+               else
+                       return true;
+       } else if (!display_conf.powerkey_doublepress && display_conf.lcd_always_on) {
+               longkey_pressed();
+               return false;
+       }
+
+       return true;
+}
+
+static int process_power_key(struct input_event *pinput)
+{
+       int ignore = true;
+       static int value = KEY_RELEASED;
+       unsigned int caps;
+
+       caps = display_get_caps(DISPLAY_ACTOR_POWER_KEY);
+
+       switch (pinput->value) {
+       case KEY_RELEASED:
+               check_key_pair(pinput->code, pinput->value, &value);
+
+               ignore = release_short_powerkey();
+
+               if (!display_has_caps(caps, DISPLAY_CAPA_LCDON))
+                       ignore = true;
+
+               if (longkey_timeout_id > 0) {
+                       g_source_remove(longkey_timeout_id);
+                       longkey_timeout_id = 0;
+               }
+
+               break;
+       case KEY_PRESSED:
+               if (display_has_caps(caps, DISPLAY_CAPA_LCDON)) {
+                       skip_lcd_off = switch_on_lcd();
+               } else {
+                       _D("No lcdon capability!");
+                       skip_lcd_off = false;
+               }
+               check_key_pair(pinput->code, pinput->value, &value);
+               _I("power key pressed");
+               pressed_time.tv_sec = (pinput->time).tv_sec;
+               pressed_time.tv_usec = (pinput->time).tv_usec;
+               if (key_combination == KEY_COMBINATION_POWERKEY) {
+                       /* add long key timer */
+                       longkey_timeout_id = g_timeout_add_seconds(
+                                   display_conf.longpress_interval,
+                                   longkey_pressed_cb, NULL);
+               }
+               if (skip_lcd_off)
+                       ignore = false;
+               cancel_lcdoff = 0;
+
+               break;
+       case KEY_BEING_PRESSED:
+               if (timediff_usec(pressed_time, pinput->time) >
+                   (display_conf.longpress_interval * USEC_PER_SEC))
+                       longkey_pressed();
+               break;
+       }
+       return ignore;
+}
+
+static int process_screenlock_key(struct input_event *pinput)
+{
+       if (pinput->value != KEY_RELEASED) {
+               stop_key_combination(NULL);
+               return true;
+       }
+
+       if (!current_state_in_on())
+               return false;
+
+       check_processes(S_NORMAL);
+       check_processes(S_LCDDIM);
+
+       if (!check_holdkey_block(S_NORMAL) && !check_holdkey_block(S_LCDDIM)) {
+               delete_condition(S_NORMAL);
+               delete_condition(S_LCDDIM);
+               update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_POWERKEY);
+
+               /* LCD off forcly */
+               if (disp_plgn.pm_change_internal)
+                       disp_plgn.pm_change_internal(-1, LCD_OFF);
+       }
+
+       return true;
+}
+
+static void sound_vibrate_hardkey(void)
+{
+       /* device notify(vibrator) */
+       /* sound(dbus) */
+       /* Need to notify to deviced-vibrator. deviced-vibrator receives ChangedHardKey signal */
+       dbus_handle_broadcast_dbus_signal(DEVICED_PATH_KEY,
+                                       DEVICED_INTERFACE_KEY,
+                                       SIGNAL_CHANGE_HARDKEY,
+                                       NULL, NULL);
+}
+
+static void process_hardkey_backlight(struct input_event *pinput)
+{
+       int opt;
+
+       _E("pinput->value : %d", pinput->value);
+       if (pinput->value == KEY_PRESSED) {
+               if (touch_pressed) {
+                       _I("Touch is pressed, then hard key is not working!");
+                       return;
+               }
+               /* Sound & Vibrate only in unlock state */
+               if (__get_lock_screen_state() == VCONFKEY_IDLE_UNLOCK
+                   || get_lock_screen_bg_state())
+                       sound_vibrate_hardkey();
+
+               if (touchled && touchled->execute) {
+                       opt = TOUCHLED_PRESS;
+                       touchled->execute(&opt);
+               }
+       } else if (pinput->value == KEY_RELEASED) {
+               /* if lockscreen is idle lock */
+               if (__get_lock_screen_state() == VCONFKEY_IDLE_LOCK) {
+                       _D("Lock state, key backlight is off when phone is unlocked!");
+                       return;
+               }
+
+               if (touchled && touchled->execute) {
+                       opt = TOUCHLED_RELEASE;
+                       touchled->execute(&opt);
+               }
+       }
+}
+
+static int check_key(struct input_event *pinput, int fd)
+{
+       int ignore = true;
+
+       process_combination_key(pinput);
+       switch (pinput->code) {
+       case KEY_MENU:
+               ignore = process_menu_key(pinput);
+               break;
+       case KEY_POWER:
+               ignore = process_power_key(pinput);
+               if (current_state_in_on())
+                       ignore = false;
+               break;
+       case KEY_SCREENLOCK:
+               ignore = process_screenlock_key(pinput);
+               break;
+       case KEY_BACK:
+       case KEY_PHONE:
+               stop_key_combination(NULL);
+               if (current_state_in_on()) {
+                       process_hardkey_backlight(pinput);
+                       ignore = false;
+               }
+               break;
+       case KEY_VOLUMEUP:
+       case KEY_VOLUMEDOWN:
+       case KEY_CAMERA:
+       case KEY_EXIT:
+       case KEY_CONFIG:
+       case KEY_MEDIA:
+       case KEY_MUTE:
+       case KEY_PLAYPAUSE:
+       case KEY_PLAYCD:
+       case KEY_PAUSECD:
+       case KEY_STOPCD:
+       case KEY_NEXTSONG:
+       case KEY_PREVIOUSSONG:
+       case KEY_REWIND:
+       case KEY_FASTFORWARD:
+               stop_key_combination(NULL);
+               if (current_state_in_on())
+                       ignore = false;
+               break;
+       case 0x1DB:
+       case 0x1DC:
+       case 0x1DD:
+       case 0x1DE:
+               stop_key_combination(NULL);
+               break;
+       default:
+               stop_key_combination(NULL);
+               ignore = false;
+       }
+#ifdef ENABLE_PM_LOG
+       if (pinput->value == KEY_PRESSED)
+               pm_history_save(PM_LOG_KEY_PRESS, pinput->code);
+       else if (pinput->value == KEY_RELEASED)
+               pm_history_save(PM_LOG_KEY_RELEASE, pinput->code);
+#endif
+       return ignore;
+}
+
+static int check_key_filter(void *data, int fd)
+{
+       struct input_event *pinput = data;
+       int ignore = true;
+       static int old_fd, code, value;
+
+       assert(pinput);
+
+       switch (pinput->type) {
+       case EV_KEY:
+               if (pinput->code == BTN_TOUCH &&
+                       pinput->value == KEY_RELEASED)
+                       touch_pressed = false;
+               /*
+                * Normally, touch press/release events don't occur
+                * in lcd off state. But touch release events can occur
+                * in the state abnormally. Then touch events are ignored
+                * when lcd is off state.
+                */
+               if (pinput->code == BTN_TOUCH && !current_state_in_on())
+                       break;
+               if (pinput->code == code && pinput->value == value) {
+                       _E("Same key(%d, %d) is polled [%d,%d]",
+                               code, value, old_fd, fd);
+               }
+               old_fd = fd;
+               code = pinput->code;
+               value = pinput->value;
+
+               ignore = check_key(pinput, fd);
+               restore_custom_brightness();
+
+               break;
+       case EV_REL:
+               ignore = false;
+               break;
+       case EV_ABS:
+               if (current_state_in_on())
+                       ignore = false;
+
+               if (ambient_get_condition() == true) {
+                       switch_on_lcd();
+                       ignore = false;
+               }
+
+               restore_custom_brightness();
+
+               touch_pressed =
+                       (pinput->value == TOUCH_RELEASE ? false : true);
+               break;
+       case EV_SW:
+               if (!get_glove_state || !switch_glove_key)
+                       break;
+               if (pinput->code == SW_GLOVE &&
+                       get_glove_state() == GLOVE_MODE) {
+                       switch_glove_key(pinput->value);
+               }
+               break;
+       }
+
+       if (ignore)
+               return 1;
+
+       return 0;
+}
+
+/*
+ * Default capability
+ * powerkey := LCDON | LCDOFF | POWEROFF
+ * homekey  := LCDON
+ */
+static struct display_actor_ops display_powerkey_actor = {
+       .id     = DISPLAY_ACTOR_POWER_KEY,
+       .caps   = DISPLAY_CAPA_LCDON |
+                 DISPLAY_CAPA_LCDOFF |
+                 DISPLAY_CAPA_POWEROFF,
+};
+
+static struct display_actor_ops display_menukey_actor = {
+       .id     = DISPLAY_ACTOR_MENU_KEY,
+       .caps   = DISPLAY_CAPA_LCDON,
+};
+
+static void keyfilter_init(void)
+{
+       display_add_actor(&display_powerkey_actor);
+       display_add_actor(&display_menukey_actor);
+
+       touchled = find_device(TOUCHLED_NAME);
+
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+}
+
+static void keyfilter_exit(void)
+{
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+}
+
+static void key_backlight_enable(bool enable)
+{
+       int opt;
+
+       if (!touchled || !touchled->execute)
+               return;
+
+       if (enable)
+               opt = TOUCHLED_DIRECT_ON;
+       else
+               opt = TOUCHLED_DIRECT_OFF;
+
+       touchled->execute(&opt);
+}
+
+static const struct display_keyfilter_ops normal_keyfilter_ops = {
+       .init                   = keyfilter_init,
+       .exit                   = keyfilter_exit,
+       .check                  = check_key_filter,
+       .set_powerkey_ignore    = NULL,
+       .powerkey_lcdoff        = NULL,
+       .backlight_enable       = key_backlight_enable,
+};
+
+const struct display_keyfilter_ops *keyfilter_ops = &normal_keyfilter_ops;
+
diff --git a/plugins/iot/display/lock-detector.c b/plugins/iot/display/lock-detector.c
new file mode 100644 (file)
index 0000000..0560ef4
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * @file       lock-detector.c
+ * @brief
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "util.h"
+#include "core.h"
+#include "core/list.h"
+
+struct lock_info {
+       unsigned long hash;
+       char *name;
+       int state;
+       int count;
+       long locktime;
+       long unlocktime;
+       long time;
+};
+
+#define LIMIT_COUNT    128
+
+static dd_list *lock_info_list;
+
+static long get_time(void)
+{
+       struct timeval now;
+       gettimeofday(&now, NULL);
+       return (long)(now.tv_sec * 1000 + now.tv_usec / 1000);
+}
+
+static void shrink_lock_info_list(void)
+{
+       dd_list *l, *l_prev;
+       struct lock_info *info;
+       unsigned int count;
+
+       count = DD_LIST_LENGTH(lock_info_list);
+       if (count <= LIMIT_COUNT)
+               return;
+       _D("list is shrink : count %d", count);
+
+       DD_LIST_REVERSE_FOREACH_SAFE(lock_info_list, l, l_prev, info) {
+               if (info->locktime == 0) {
+                       DD_LIST_REMOVE_LIST(lock_info_list, l);
+                       if (info->name)
+                               free(info->name);
+                       free(info);
+                       count--;
+               }
+               if (count <= (LIMIT_COUNT / 2))
+                       break;
+       }
+}
+
+int set_lock_time(const char *pname, int state)
+{
+       struct lock_info *info;
+       dd_list *l;
+       unsigned long val;
+
+       if (!pname)
+               return -EINVAL;
+
+       if (state < S_NORMAL || state > S_SLEEP)
+               return -EINVAL;
+
+       val = g_str_hash(pname);
+
+       DD_LIST_FOREACH(lock_info_list, l, info)
+               if (info->hash == val &&
+                   !strncmp(info->name, pname, strlen(pname)+1) &&
+                   info->state == state) {
+                       info->count += 1;
+                       if (info->locktime == 0)
+                               info->locktime = get_time();
+                       info->unlocktime = 0;
+                       DD_LIST_REMOVE(lock_info_list, info);
+                       DD_LIST_PREPEND(lock_info_list, info);
+                       return 0;
+               }
+
+       info = malloc(sizeof(struct lock_info));
+       if (!info) {
+               _E("Malloc is failed for lock_info!");
+               return -ENOMEM;
+       }
+
+       info->hash = val;
+       info->name = strndup(pname, strlen(pname));
+       info->state = state;
+       info->count = 1;
+       info->locktime = get_time();
+       info->unlocktime = 0;
+       info->time = 0;
+
+       DD_LIST_APPEND(lock_info_list, info);
+
+       return 0;
+}
+
+int set_unlock_time(const char *pname, int state)
+{
+       bool find = false;
+       long diff;
+       struct lock_info *info;
+       dd_list *l;
+       unsigned long val;
+
+       if (!pname)
+               return -EINVAL;
+
+       if (state < S_NORMAL || state > S_SLEEP)
+               return -EINVAL;
+
+       val = g_str_hash(pname);
+
+       DD_LIST_FOREACH(lock_info_list, l, info)
+               if (info->hash == val &&
+                   !strncmp(info->name, pname, strlen(pname)+1) &&
+                   info->state == state) {
+                       DD_LIST_REMOVE(lock_info_list, info);
+                       DD_LIST_PREPEND(lock_info_list, info);
+                       find = true;
+                       break;
+               }
+
+       if (!find)
+               return -EINVAL;
+
+       if (info->locktime == 0)
+               return -EINVAL;
+
+       /* update time */
+       info->unlocktime = get_time();
+       diff = info->unlocktime - info->locktime;
+       if (diff > 0)
+               info->time += diff;
+       info->locktime = 0;
+
+       if (DD_LIST_LENGTH(lock_info_list) > LIMIT_COUNT)
+               shrink_lock_info_list();
+
+       return 0;
+}
+
+void free_lock_info_list(void)
+{
+       dd_list *l, *l_next;
+       struct lock_info *info;
+
+       if (!lock_info_list)
+               return;
+
+       DD_LIST_FOREACH_SAFE(lock_info_list, l, l_next, info) {
+               DD_LIST_REMOVE(lock_info_list, info);
+               if (info->name)
+                       free(info->name);
+               free(info);
+       }
+       lock_info_list = NULL;
+}
+
+void print_lock_info_list(int fd)
+{
+       struct lock_info *info;
+       dd_list *l;
+       char buf[255];
+       int ret;
+
+       if (!lock_info_list)
+               return;
+
+       snprintf(buf, sizeof(buf),
+           "current time : %ld ms\n", get_time());
+       ret = write(fd, buf, strlen(buf));
+       if (ret < 0)
+               _E("write() failed (%d)", errno);
+
+       snprintf(buf, sizeof(buf),
+           "[%10s %6s] %6s %10s %10s %10s %s\n", "hash", "state",
+           "count", "locktime", "unlocktime", "time", "process name");
+       ret = write(fd, buf, strlen(buf));
+       if (ret < 0)
+               _E("write() failed (%d)", errno);
+
+       DD_LIST_FOREACH(lock_info_list, l, info) {
+               long time = 0;
+               if (info->locktime != 0 && info->unlocktime == 0)
+                       time = get_time() - info->locktime;
+               snprintf(buf, sizeof(buf),
+                   "[%10lu %6d] %6d %10ld %10ld %10ld %s\n",
+                   info->hash,
+                   info->state,
+                   info->count,
+                   info->locktime,
+                   info->unlocktime,
+                   info->time + time,
+                   info->name);
+               ret = write(fd, buf, strlen(buf));
+               if (ret < 0)
+                       _E("write() failed (%d)", errno);
+       }
+}
+
diff --git a/plugins/iot/display/poll.c b/plugins/iot/display/poll.c
new file mode 100644 (file)
index 0000000..e5087dd
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+ * @file       poll.c
+ * @brief       Power Manager poll implementation
+ *
+ */
+
+#include <stdio.h>
+#include "util.h"
+#include "core.h"
+#include "poll.h"
+#include "display/display-ops.h"
+
+#define SHIFT_UNLOCK                    4
+#define SHIFT_UNLOCK_PARAMETER          12
+#define SHIFT_CHANGE_STATE              8
+#define SHIFT_CHANGE_TIMEOUT            20
+#define LOCK_FLAG_SHIFT                 16
+#define __HOLDKEY_BLOCK_BIT              0x1
+#define HOLDKEY_BLOCK_BIT               (__HOLDKEY_BLOCK_BIT << LOCK_FLAG_SHIFT)
+
+static PMMsg recv_data;
+extern struct display_plugin disp_plgn;
+
+int check_dimstay(int next_state, int flag)
+{
+       if (next_state != LCD_OFF)
+               return false;
+
+       if (!(flag & GOTO_STATE_NOW))
+               return false;
+
+       if (!(pm_status_flag & DIMSTAY_FLAG))
+               return false;
+
+       return true;
+}
+
+static enum state_t get_state(int s_bits)
+{
+       switch (s_bits) {
+       case LCD_NORMAL:
+               return S_NORMAL;
+       case LCD_DIM:
+               return S_LCDDIM;
+       case LCD_OFF:
+               return S_LCDOFF;
+       case STANDBY:
+               return S_STANDBY;
+       case SUSPEND:
+               return S_SLEEP;
+       default:
+               return -EINVAL;
+       }
+}
+
+static bool state_supported(enum state_t st)
+{
+       if (states[st].trans)
+               return true;
+       return false;
+}
+
+static int __pm_lock_internal(pid_t pid, int s_bits, int flag, int timeout)
+{
+       int cond;
+
+       if (!pm_callback)
+               return -1;
+
+       cond = get_state(s_bits);
+       if (cond < 0)
+               return cond;
+
+       if (!state_supported(cond))
+               return -ENOTSUP;
+
+       cond = SET_COND_REQUEST(cond, PM_REQUEST_LOCK);
+
+       if (flag & GOTO_STATE_NOW)
+               /* if the flag is true, go to the locking state directly */
+               cond = SET_COND_FLAG(cond, PM_REQUEST_CHANGE);
+
+       if (flag & HOLD_KEY_BLOCK)
+               cond = SET_COND_FLAG(cond, PM_FLAG_BLOCK_HOLDKEY);
+
+       recv_data.pid = pid;
+       recv_data.cond = cond;
+       recv_data.timeout = timeout;
+
+       (*pm_callback)(PM_CONTROL_EVENT, &recv_data);
+
+       return 0;
+}
+
+static int __pm_unlock_internal(pid_t pid, int s_bits, int flag)
+{
+       int cond;
+
+       if (!pm_callback)
+               return -1;
+
+       cond = get_state(s_bits);
+       if (cond < 0)
+               return cond;
+
+       if (!state_supported(cond))
+               return -ENOTSUP;
+
+       cond = SET_COND_REQUEST(cond, PM_REQUEST_UNLOCK);
+
+       if (flag & PM_KEEP_TIMER)
+               cond = SET_COND_FLAG(cond, PM_FLAG_KEEP_TIMER);
+
+       if (flag & PM_RESET_TIMER)
+               cond = SET_COND_FLAG(cond, PM_FLAG_RESET_TIMER);
+
+       recv_data.pid = pid;
+       recv_data.cond = cond;
+       recv_data.timeout = 0;
+
+       (*pm_callback)(PM_CONTROL_EVENT, &recv_data);
+
+       return 0;
+}
+
+static int __pm_change_internal(pid_t pid, int s_bits)
+{
+       int cond;
+
+       if (!pm_callback)
+               return -1;
+
+       cond = get_state(s_bits);
+       if (cond < 0)
+               return cond;
+
+       if (!state_supported(cond))
+               return -ENOTSUP;
+
+       cond = SET_COND_REQUEST(cond, PM_REQUEST_CHANGE);
+
+       recv_data.pid = pid;
+       recv_data.cond = cond;
+       recv_data.timeout = 0;
+
+       (*pm_callback)(PM_CONTROL_EVENT, &recv_data);
+
+       return 0;
+}
+
+void init_pm_internal()
+{
+       disp_plgn.pm_lock_internal = __pm_lock_internal;
+       disp_plgn.pm_unlock_internal = __pm_unlock_internal;
+       disp_plgn.pm_change_internal = __pm_change_internal;
+}
diff --git a/plugins/iot/display/setting.c b/plugins/iot/display/setting.c
new file mode 100644 (file)
index 0000000..4a41250
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <bundle.h>
+#include <eventsystem.h>
+
+#include "ambient-mode.h"
+#include "core.h"
+#include "util.h"
+#include "setting.h"
+#include "display-ops.h"
+
+#define LCD_DIM_RATIO          0.3
+#define LCD_MAX_DIM_TIMEOUT    7000
+#define LCD_MIN_DIM_TIMEOUT    500
+
+extern struct display_plugin disp_plgn;
+static const char *setting_keys[SETTING_GET_END] = {
+       [SETTING_TO_NORMAL] = VCONFKEY_SETAPPL_LCD_TIMEOUT_NORMAL,
+       [SETTING_BRT_LEVEL] = VCONFKEY_SETAPPL_LCD_BRIGHTNESS,
+       [SETTING_LOCK_SCREEN] = VCONFKEY_IDLE_LOCK_STATE,
+       [SETTING_POWER_CUSTOM_BRIGHTNESS] = VCONFKEY_PM_CUSTOM_BRIGHTNESS_STATUS,
+};
+
+static int lock_screen_state = VCONFKEY_IDLE_UNLOCK;
+static bool lock_screen_bg_state = false;
+static int force_lcdtimeout = 0;
+static int custom_on_timeout = 0;
+static int custom_normal_timeout = 0;
+static int custom_dim_timeout = 0;
+
+static void display_state_send_system_event(int state)
+{
+       bundle *b;
+       const char *str;
+
+       if (state == S_NORMAL)
+               str = EVT_VAL_DISPLAY_NORMAL;
+       else if (state == S_LCDDIM)
+               str = EVT_VAL_DISPLAY_DIM;
+       else if (state == S_LCDOFF)
+               str = EVT_VAL_DISPLAY_OFF;
+       else
+               return;
+
+       _I("eventsystem (%s)", str);
+
+       b = bundle_create();
+       bundle_add_str(b, EVT_KEY_DISPLAY_STATE, str);
+       eventsystem_send_system_event(SYS_EVENT_DISPLAY_STATE, b);
+       bundle_free(b);
+}
+
+int set_force_lcdtimeout(int timeout)
+{
+       if (timeout < 0)
+               return -EINVAL;
+
+       force_lcdtimeout = timeout;
+
+       return 0;
+}
+
+int __get_lock_screen_state(void)
+{
+       return lock_screen_state;
+}
+
+void set_lock_screen_state(int state)
+{
+       switch (state) {
+       case VCONFKEY_IDLE_LOCK:
+       case VCONFKEY_IDLE_UNLOCK:
+               lock_screen_state = state;
+               break;
+       default:
+               lock_screen_state = VCONFKEY_IDLE_UNLOCK;
+       }
+}
+
+int get_lock_screen_bg_state(void)
+{
+       return lock_screen_bg_state;
+}
+
+void set_lock_screen_bg_state(bool state)
+{
+       _I("state is %d", state);
+       lock_screen_bg_state = state;
+}
+
+int set_setting_pmstate(int val)
+{
+       static int old = -1;
+
+       if (old == val)
+               return 0;
+       old = val;
+
+       display_state_send_system_event(val);
+       return vconf_set_int(VCONFKEY_PM_STATE, val);
+}
+
+int get_setting_brightness(int *level)
+{
+       return vconf_get_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, level);
+}
+
+void get_dim_timeout(int *dim_timeout)
+{
+       int vconf_timeout, on_timeout, val, ret;
+
+       if (custom_dim_timeout > 0) {
+               *dim_timeout = custom_dim_timeout;
+               return;
+       }
+
+       if (ambient_get_condition() == true) {
+               *dim_timeout = LCD_MIN_DIM_TIMEOUT;
+               return;
+       }
+
+       ret = vconf_get_int(setting_keys[SETTING_TO_NORMAL], &vconf_timeout);
+       if (ret != 0) {
+               _E("Failed ro get setting timeout!");
+               vconf_timeout = DEFAULT_NORMAL_TIMEOUT;
+       }
+
+       if (force_lcdtimeout > 0)
+               on_timeout = SEC_TO_MSEC(force_lcdtimeout);
+       else
+               on_timeout = SEC_TO_MSEC(vconf_timeout);
+
+       val = (double)on_timeout * LCD_DIM_RATIO;
+       if (val > LCD_MAX_DIM_TIMEOUT)
+               val = LCD_MAX_DIM_TIMEOUT;
+
+       *dim_timeout = val;
+}
+
+void get_run_timeout(int *timeout)
+{
+       int dim_timeout = -1;
+       int vconf_timeout = -1;
+       int on_timeout;
+       int ret;
+
+       if (custom_normal_timeout > 0) {
+               *timeout = custom_normal_timeout;
+               return;
+       }
+
+       ret = vconf_get_int(setting_keys[SETTING_TO_NORMAL], &vconf_timeout);
+       if (ret != 0) {
+               _E("Failed ro get setting timeout!");
+               vconf_timeout = DEFAULT_NORMAL_TIMEOUT;
+       }
+
+       if (force_lcdtimeout > 0)
+               on_timeout = SEC_TO_MSEC(force_lcdtimeout);
+       else
+               on_timeout = SEC_TO_MSEC(vconf_timeout);
+
+       if (on_timeout == 0) {
+               *timeout = on_timeout;
+               return;
+       }
+
+       get_dim_timeout(&dim_timeout);
+       *timeout = on_timeout - dim_timeout;
+}
+
+int set_custom_lcdon_timeout(int timeout)
+{
+       int changed = (custom_on_timeout == timeout ? false : true);
+
+       custom_on_timeout = timeout;
+
+       if (timeout <= 0) {
+               custom_normal_timeout = 0;
+               custom_dim_timeout = 0;
+               return changed;
+       }
+
+       custom_dim_timeout = (double)timeout * LCD_DIM_RATIO;
+       custom_normal_timeout = timeout - custom_dim_timeout;
+
+       _I("custom normal(%d), dim(%d)", custom_normal_timeout,
+           custom_dim_timeout);
+
+       return changed;
+}
+
+static int setting_cb(keynode_t *key_nodes, void *data)
+{
+       keynode_t *tmp = key_nodes;
+       int index;
+
+       index = (int)((intptr_t)data);
+       if (index > SETTING_END) {
+               _E("Unknown setting key: %s, idx=%d",
+                      vconf_keynode_get_name(tmp), index);
+               return -1;
+       }
+       if (disp_plgn.update_pm_setting)
+               disp_plgn.update_pm_setting(index, vconf_keynode_get_int(tmp));
+
+       return 0;
+}
+
+int init_setting(int (*func) (int key_idx, int val))
+{
+       int i;
+
+       if (func != NULL) {
+               disp_plgn.update_pm_setting = func;
+       }
+
+       for (i = SETTING_BEGIN; i < SETTING_GET_END; i++) {
+               /*
+                * To pass an index data through the vconf infratstructure
+                * without memory allocation, an index data becomes typecast
+                * to proper pointer size on each architecture.
+                */
+               vconf_notify_key_changed(setting_keys[i], (void *)setting_cb,
+                                        (void *)((intptr_t)i));
+       }
+
+       disp_plgn.get_lock_screen_state = __get_lock_screen_state;
+
+       return 0;
+}
+
+int exit_setting(void)
+{
+       int i;
+       for (i = SETTING_BEGIN; i < SETTING_GET_END; i++)
+               vconf_ignore_key_changed(setting_keys[i], (void *)setting_cb);
+
+       return 0;
+}
+