summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--CMakeLists.txt59
-rw-r--r--LICENSE.APLv2202
-rw-r--r--NOTICE3
-rw-r--r--debian/changelog16
-rw-r--r--debian/compat1
-rw-r--r--debian/control20
-rw-r--r--debian/copyright1
-rw-r--r--debian/dirs2
-rw-r--r--debian/docs1
-rw-r--r--debian/power-manager-bin.install.in3
-rw-r--r--debian/power-manager-bin.postinst.in11
-rwxr-xr-xdebian/rules138
-rw-r--r--main.c133
-rw-r--r--packaging/power-manager.manifest13
-rw-r--r--packaging/power-manager.service10
-rw-r--r--packaging/power-manager.spec83
-rw-r--r--pm_battery.c424
-rw-r--r--pm_battery.h36
-rw-r--r--pm_conf.c81
-rw-r--r--pm_conf.h26
-rw-r--r--pm_core.c1356
-rw-r--r--pm_core.h104
-rw-r--r--pm_device_plugin.c64
-rw-r--r--pm_device_plugin.h31
-rw-r--r--pm_event/CMakeLists.txt30
-rw-r--r--pm_event/pm_event.c41
-rw-r--r--pm_key_filter.c301
-rw-r--r--pm_llinterface.c333
-rw-r--r--pm_llinterface.h65
-rw-r--r--pm_lsensor.c286
-rw-r--r--pm_poll.c301
-rw-r--r--pm_poll.h74
-rw-r--r--pm_setting.c146
-rw-r--r--pm_setting.h131
-rw-r--r--pm_x_lcd_onoff.c67
-rw-r--r--pmctrl.in86
-rw-r--r--udev-rules/91-power-manager.rules.in7
-rw-r--r--util.c213
-rw-r--r--util.h110
40 files changed, 5011 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..cc6ce5d
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Seunghun Pi <sh.pi at samsung dot com>
+Suchang Woo <suchang.woo at samsung dot com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..c75267d
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,59 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(power_manager C)
+
+SET(SRCS
+ util.c
+ main.c
+ pm_llinterface.c
+ pm_conf.c
+ pm_setting.c
+ pm_poll.c
+ pm_core.c
+ pm_lsensor.c
+ pm_device_plugin.c
+ pm_key_filter.c
+ pm_battery.c )
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+ SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED vconf glib-2.0 sysman aul dlog heynoti devman_plugin sensor)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_DEFINITIONS("-DENABLE_KEY_FILTER")
+ADD_DEFINITIONS("-DENABLE_X_LCD_ONOFF")
+ADD_DEFINITIONS("-DENABLE_DLOG_OUT")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} -ldl)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC ${PROJECT_NAME})
+CONFIGURE_FILE(pmctrl.in pmctrl @ONLY)
+
+SET(UDEV_RULES_PATH share/power-manager/udev-rules)
+SET(UDEV_RULES udev-rules/91-power-manager.rules)
+
+CONFIGURE_FILE(${UDEV_RULES}.in ${UDEV_RULES} @ONLY)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(PROGRAMS ${CMAKE_BINARY_DIR}/pmctrl DESTINATION bin)
+INSTALL(FILES ${UDEV_RULES} DESTINATION ${UDEV_RULES_PATH})
+INSTALL(PROGRAMS ${CMAKE_SOURCE_DIR}/pmctrl DESTINATION /etc/rc.d/init.d)
+
+ADD_SUBDIRECTORY(pm_event)
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE.APLv2
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..08a1d59
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, This software is licensed under Apache License, Version 2.
+Please, see the LICENSE.APLv2 file for Apache License terms and conditions.
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..f2640b9
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,16 @@
+power-manager (1.3.21-96) unstable; urgency=low
+
+ * Update for tizen 2.0
+ * Git: magnolia/framework/system/power-manager
+ * Tag: power-manager_1.3.21-96
+
+ -- Seunghun Pi <sh.pi@samsung.com> Thu, 23 Aug 2012 10:43:03 +0900
+
+power-manager (1.3.21-87) unstable; urgency=low
+
+ * update for new oal layer
+ * Git: slp/pkgs/p/power-manager
+ * Tag: power-manager_1.3.21-87
+
+ -- Jinkun Jang <jinkun.jang@samsung.com> Mon, 09 Apr 2012 14:47:03 +0900
+
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..7ed6ff8
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..d74f208
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,20 @@
+Source: power-manager
+Section: system
+Priority: extra
+Maintainer: Jonghoon Han <jonghoon.han@samsung.com> Jinkun Jang <jinkun.jang@samsung.com> DongGi Jang <dg0402.jang@samsung.com> TAESOO JUN <steve.jun@samsung.com>
+Uploaders: Jinkun Jang <jinkun.jang@samsung.com>
+Build-Depends: debhelper (>= 5), libglib2.0-dev, libslp-setting-dev, libslp-sysman-dev, libaul-1-dev, dlog-dev, libheynoti-dev, libslp-sensor-dev, libdevman-plugin-dev
+Standards-Version: 3.7.2
+
+Package: power-manager-bin
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Power manager
+ Power manager
+
+Package: power-manager-bin-dbg
+Section: debug
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, power-manager-bin (= ${Source-Version})
+Description: Power manager
+ Power manager (unstripped)
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..8d1c8b6
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1 @@
+
diff --git a/debian/dirs b/debian/dirs
new file mode 100644
index 0000000..ca882bb
--- /dev/null
+++ b/debian/dirs
@@ -0,0 +1,2 @@
+usr/bin
+usr/sbin
diff --git a/debian/docs b/debian/docs
new file mode 100644
index 0000000..a0f0008
--- /dev/null
+++ b/debian/docs
@@ -0,0 +1 @@
+CMakeLists.txt
diff --git a/debian/power-manager-bin.install.in b/debian/power-manager-bin.install.in
new file mode 100644
index 0000000..f564239
--- /dev/null
+++ b/debian/power-manager-bin.install.in
@@ -0,0 +1,3 @@
+@PREFIX@/bin/*
+@PREFIX@/share/power-manager/*
+etc/*
diff --git a/debian/power-manager-bin.postinst.in b/debian/power-manager-bin.postinst.in
new file mode 100644
index 0000000..7805f53
--- /dev/null
+++ b/debian/power-manager-bin.postinst.in
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+vconftool set -t int memory/pm/state 0 -i
+
+heynotitool set system_wakeup
+
+mkdir -p /etc/udev/rules.d
+if ! [ -L /etc/udev/rules.d/91-power-manager.rules ]; then
+ ln -s @PREFIX@/share/power-manager/udev-rules/91-power-manager.rules /etc/udev/rules.d/91-power-manager.rules
+fi
+
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..10c3e3d
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,138 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+CFLAGS ?= -Wall -g
+CXXFLAGS ?= -Wall -g
+LDFLAGS ?=
+PREFIX ?= /usr
+DATADIR ?= /opt
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+ CXXFLAGS += -O0
+else
+ CFLAGS += -O2
+ CXXFLAGS += -O2
+endif
+
+LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ # Add here commands to configure the package.
+ CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" cmake . -DCMAKE_INSTALL_PREFIX=$(PREFIX)
+
+ touch configure-stamp
+
+build: build-stamp
+
+build-stamp: configure-stamp
+ dh_testdir
+
+ # Add here commands to compile the package.
+ $(MAKE)
+ #docbook-to-man debian/wavplayer.sgml > wavplayer.1
+
+ for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+ cat $$f > $${f%.in}; \
+ sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \
+ sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \
+ done
+
+
+ touch $@
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+
+ # Add here commands to clean up after the build process.
+ -$(MAKE) clean
+ rm -rf CMakeCache.txt
+ rm -rf CMakeFiles
+ rm -rf cmake_install.cmake
+ rm -rf Makefile
+ rm -rf install_manifest.txt
+ rm -rf *.so
+ rm -rf ./pm_event/CMakeCache.txt
+ rm -rf ./pm_event/CMakeFiles
+ rm -rf ./pm_event/cmake_install.cmake
+ rm -rf ./pm_event/Makefile
+ rm -rf ./pm_event/install_manifest.txt
+ rm -rf ./pm_event/pm_event
+
+ for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+ rm -f $${f%.in}; \
+ done
+
+ for f in `find $(CURDIR)/ -name "*.in"`; do \
+ rm -f $${f%.in}; \
+ done
+
+
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/wavplayer.
+ $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+ mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/
+ mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/
+
+ ln -s ../init.d/power_manager.sh $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/S35power-manager
+ ln -s ../init.d/power_manager.sh $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/S00power-manager
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs
+ dh_installdocs
+ dh_installexamples
+ dh_install --sourcedir=debian/tmp
+# dh_installmenu
+# dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_python
+# dh_installinit
+# dh_installcron
+# dh_installinfo
+ dh_installman
+ dh_link
+# dh_strip
+ dh_strip --dbg-package=power-manager-bin-dbg
+ dh_compress
+ dh_fixperms
+# dh_perl
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure patch unpatch
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..75608a2
--- /dev/null
+++ b/main.c
@@ -0,0 +1,133 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 main.c
+ * @version 0.1
+ * @brief Power Manager main file
+ *
+ * Process the user options, Daemonize the process, Start Main loop
+ */
+
+/**
+ * @addtogroup POWER_MANAGER
+ * @{
+ *
+ * @section execution How to execute
+ * # powermanager {options...} <br>
+ *
+ * Options: <br><br>
+ * &nbsp; -f --foreground<br>
+ * &nbsp; &nbsp; Run as foreground process<br> <br>
+ * &nbsp; -d --direct<br>
+ * &nbsp; &nbsp; Start without notification<br> <br>
+ *
+ * @}
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "pm_core.h"
+
+/**
+ * Print the usage
+ *
+ * @internal
+ */
+void usage()
+{
+ printf("Options: \n");
+ printf(" -f, --foreground Run as foreground process\n");
+ printf(" -d, --direct Start without notification\n");
+ printf
+ (" -x, --xdpms With LCD-onoff control by x-dpms \n");
+ printf("\n");
+
+ exit(0);
+}
+
+/**
+ * Pid file path
+ */
+#define DEFAULT_PID_PATH "/var/run/power-manager.pid"
+
+int main(int argc, char *argv[])
+{
+ int c;
+ int runflags = 0; /* run as daemon */
+ unsigned int flags = 0x0; /* 0 : start with noti */
+
+ while (1) {
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"foreground", no_argument, NULL, 'f'},
+ {"direct", no_argument, NULL, 'd'},
+ {"xdpms", no_argument, NULL, 'x'},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long(argc, argv, "fdx", long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'f':
+ runflags = 1;
+ break;
+
+ case 'd':
+ flags = flags | WITHOUT_STARTNOTI; /* 0x1 : start without noti */
+ break;
+
+ case 'x':
+ flags = flags | FLAG_X_DPMS; /* 0x2 : X control LCD onoff */
+ break;
+
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (optind < argc)
+ usage();
+
+ if (access(DEFAULT_PID_PATH, F_OK) == 0) { /* pid file exist */
+ printf
+ ("Check the PM is running. If it isn't, delete \"%s\" and retry.\n",
+ DEFAULT_PID_PATH);
+ return -1;
+ }
+
+ if (!runflags)
+ daemonize();
+
+ writepid(DEFAULT_PID_PATH);
+
+ /* this function is main loop, defined in pm_core.c */
+ start_main(flags);
+
+ unlink(DEFAULT_PID_PATH);
+ return 0;
+}
diff --git a/packaging/power-manager.manifest b/packaging/power-manager.manifest
new file mode 100644
index 0000000..e4d4971
--- /dev/null
+++ b/packaging/power-manager.manifest
@@ -0,0 +1,13 @@
+<manifest>
+ <define>
+ <domain name="power_manager"/>
+ </define>
+ <request>
+ <domain name="power_manager"/>
+ </request>
+ <assign>
+ <filesystem path="/etc/rc.d/init.d/pmctrl" label="_" exec_label="none" />
+ <filesystem path="/etc/rc.d/rc3.d/S35power-manager" label="_" exec_label="none" />
+ </assign>
+</manifest>
+
diff --git a/packaging/power-manager.service b/packaging/power-manager.service
new file mode 100644
index 0000000..13609c8
--- /dev/null
+++ b/packaging/power-manager.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Start the power manager service
+
+[Service]
+Type=forking
+ExecStart=/usr/bin/pmctrl start
+Environment=DISPLAY=:0
+
+[Install]
+WantedBy=multi-user.target
diff --git a/packaging/power-manager.spec b/packaging/power-manager.spec
new file mode 100644
index 0000000..0004a9c
--- /dev/null
+++ b/packaging/power-manager.spec
@@ -0,0 +1,83 @@
+Name: power-manager
+Summary: Power manager
+Version: 1.3.23
+Release: 8
+Group: framework/system
+License: APLv2
+Source0: %{name}-%{version}.tar.gz
+Source1001: packaging/power-manager.manifest
+Requires(post): /usr/bin/vconftool
+Source1: power-manager.service
+BuildRequires: cmake
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(sysman)
+BuildRequires: pkgconfig(aul)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(sensor)
+BuildRequires: pkgconfig(devman)
+BuildRequires: pkgconfig(devman_plugin)
+BuildRequires: pkgconfig(heynoti)
+
+%description
+Description: Power manager
+
+
+%prep
+%setup -q
+
+%build
+cp %{SOURCE1001} .
+%ifnarch %arm
+%if 0%{?simulator}
+#for emulator
+CFLAGS+=" -DTIZEN_EMUL"
+%else
+#for real device
+CFLAGS+=" -DX86"
+%endif
+export CFLAGS
+%endif
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix}
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants
+install -m 0644 %{SOURCE1} %{buildroot}%{_libdir}/systemd/system/power-manager.service
+ln -s ../power-manager.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/power-manager.service
+
+mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc3.d/
+mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc5.d/
+ln -s %{_sysconfdir}/init.d/pmctrl %{buildroot}%{_sysconfdir}/rc.d/rc3.d/S35power-manager
+ln -s %{_sysconfdir}/init.d/pmctrl %{buildroot}%{_sysconfdir}/rc.d/rc5.d/S00power-manager
+
+%post
+vconftool set -t int memory/pm/state 0 -i
+vconftool set -t int memory/pm/battery_timetofull -1 -i
+vconftool set -t int memory/pm/battery_timetoempty -1 -i
+vconftool set -t int memory/pm/custom_brightness_status 0 -i -g 5000
+vconftool set -t bool memory/pm/brt_changed_lpm 0 -i
+
+heynotitool set system_wakeup
+heynotitool set pm_event
+
+mkdir -p /etc/udev/rules.d
+if ! [ -L /etc/udev/rules.d/91-power-manager.rules ]; then
+ ln -s %{_datadir}/power-manager/udev-rules/91-power-manager.rules /etc/udev/rules.d/91-power-manager.rules
+fi
+
+%files
+%manifest power-manager.manifest
+%{_sysconfdir}/rc.d/init.d/pmctrl
+%{_sysconfdir}/rc.d/rc3.d/S35power-manager
+%{_sysconfdir}/rc.d/rc5.d/S00power-manager
+%{_bindir}/pm_event
+%{_bindir}/pmctrl
+%{_bindir}/power_manager
+%{_libdir}/systemd/system/power-manager.service
+%{_libdir}/systemd/system/multi-user.target.wants/power-manager.service
+%{_datadir}/power-manager/udev-rules/91-power-manager.rules
diff --git a/pm_battery.c b/pm_battery.c
new file mode 100644
index 0000000..a413774
--- /dev/null
+++ b/pm_battery.c
@@ -0,0 +1,424 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 <glib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pm_core.h"
+#include "pm_device_plugin.h"
+#include "pm_battery.h"
+
+#define CHARGING_STATE(x) ((x) & CHRGR_FLAG)
+#define FULL_CAPACITY_RAW (10000)
+#define FULL_CAPACITY (100)
+#define BATTERY_FULL_THRESHOLD (98)
+#define MAX_COUNT_UNCHARGING (5)
+#define MAX_COUNT_CHARGING (5)
+#define PRINT_ALL_BATT_NODE(x) /*print_all_batt_node(x)*/
+
+int (*get_battery_capacity)();
+
+enum state_b {
+ B_UNCHARGING = 0,
+ B_CHARGING = 1,
+ B_END = 2
+};
+
+typedef struct _batt_node {
+ time_t clock;
+ int capacity;
+ struct _batt_node *preview;
+ struct _batt_node *next;
+} Batt_node;
+
+enum state_a {
+ A_TIMETOEMPTY = 0,
+ A_TIMETOFULL = 1,
+ A_END = 2
+};
+
+static int timeout_id = 0;
+static int noti_fd = 0;
+
+static Batt_node *batt_head[B_END];
+static Batt_node *batt_tail[B_END];
+static int MAX_VALUE_COUNT[B_END] = {MAX_COUNT_UNCHARGING, MAX_COUNT_CHARGING};
+static double avg_factor[B_END] = {-1.0, -1.0};
+static int full_capacity = 0;
+static int old_capacity = 0;
+static int charging_state = 0;
+static int multiply_value[B_END] = {-1, 1};
+
+static void print_all_batt_node(enum state_b b_index)
+{
+ Batt_node *node = NULL;
+ int cnt = 0;
+
+ LOGINFO("print_all_batt_node [%d]", b_index);
+
+ if(b_index < 0 || b_index >= B_END)
+ return;
+
+ if(batt_head[b_index] == NULL)
+ return;
+
+ node = batt_head[b_index];
+ while(node != NULL) {
+ cnt++;
+ LOGINFO("[%d] capacity %5d, time %s", cnt, node->capacity,
+ ctime(&node->clock));
+ node = node->next;
+ }
+}
+
+static int check_value_validity(enum state_b b_index,time_t clock,int capacity)
+{
+ time_t old_clock = 0;
+ int old_capacity = 0;
+ int capadiff = 0;
+
+ if(b_index < 0 || b_index >= B_END)
+ return -1;
+
+ if(batt_head[b_index] == NULL)
+ return 0;
+
+ old_capacity = batt_head[b_index]->capacity;
+
+ if(system_wakeup_flag == true) {
+ LOGERR("check value validity : invalid cuz system suspend!");
+ system_wakeup_flag = false;
+ return -1;
+ }
+ /* capacity */
+ capadiff = capacity - old_capacity;
+ if((capadiff * multiply_value[b_index]) <= 0) {
+ LOGERR("check value validity : capadiff(%d) wrong!", capadiff);
+ return -1;
+ }
+ return 0;
+}
+
+static int add_batt_node(enum state_b b_index, time_t clock, int capacity)
+{
+ Batt_node *node = NULL;
+
+ PRINT_ALL_BATT_NODE(b_index);
+
+ if(b_index < 0 || b_index >= B_END)
+ return -1;
+
+ node = (Batt_node *) malloc(sizeof(Batt_node));
+ if(node == NULL) {
+ LOGERR("Not enough memory, add battery node fail!");
+ return -1;
+ }
+
+ node->clock = clock;
+ node->capacity = capacity;
+
+ if(batt_head[b_index] == NULL && batt_tail[b_index] == NULL) {
+ batt_head[b_index] = batt_tail[b_index] = node;
+ node->preview = NULL;
+ node->next = NULL;
+ } else {
+ node->next = batt_head[b_index];
+ node->preview = NULL;
+ batt_head[b_index]->preview = node;
+ batt_head[b_index] = node;
+ }
+ PRINT_ALL_BATT_NODE(b_index);
+ return 0;
+}
+
+static int reap_batt_node(enum state_b b_index, int max_count)
+{
+ Batt_node *node = NULL;
+ Batt_node *tmp = NULL;
+ int cnt = 0;
+
+ PRINT_ALL_BATT_NODE(b_index);
+
+ if(b_index < 0 || b_index >= B_END)
+ return -1;
+
+ if(max_count <= 0)
+ return -1;
+
+ node = batt_head[b_index];
+
+ while(node != NULL) {
+ if(cnt >= max_count) break;
+ cnt++;
+ node = node->next;
+ }
+
+ if(node != NULL && node != batt_tail[b_index]) {
+ batt_tail[b_index] = node;
+ node = node->next;
+ batt_tail[b_index]->next = NULL;
+ while(node != NULL) {
+ tmp = node;
+ node = node->next;
+ free(tmp);
+ }
+ }
+ PRINT_ALL_BATT_NODE(b_index);
+ return 0;
+}
+
+static int del_all_batt_node(enum state_b b_index)
+{
+ Batt_node *node = NULL;
+
+ PRINT_ALL_BATT_NODE(b_index);
+
+ if(b_index < 0 || b_index >= B_END)
+ return -1;
+ if(batt_head[b_index] == NULL)
+ return 0;
+
+ while(batt_head[b_index] != NULL) {
+ node = batt_head[b_index];
+ batt_head[b_index] = batt_head[b_index]->next;
+ free(node);
+ }
+ batt_tail[b_index] = NULL;
+ PRINT_ALL_BATT_NODE(b_index);
+ return 0;
+}
+
+static float update_factor(enum state_b b_index)
+{
+ Batt_node *node = NULL;
+ double factor = 0.0;
+ double total_factor = 0.0;
+ int cnt = 0;
+ double timediff = 0.0;
+ double capadiff = 0.0;
+
+ if(b_index < 0 || b_index >= B_END)
+ return 0;
+
+ if(batt_head[b_index] == NULL || batt_head[b_index]->next == NULL)
+ return avg_factor[b_index];
+
+ node = batt_head[b_index];
+ while(1) {
+ timediff = difftime(node->clock, node->next->clock);
+ capadiff = node->capacity - node->next->capacity;
+ if(capadiff < 0)
+ capadiff*=(-1);
+ if(capadiff != 0)
+ factor = timediff / capadiff;
+ total_factor += factor;
+
+ node = node->next;
+ cnt++;
+
+ /*LOGINFO("[%d] timediff(%lf) / capadiff(%lf) = factor(%lf)",
+ cnt, timediff, capadiff, factor);*/
+ factor = 0.0;
+
+ if(node == NULL || node->next == NULL)
+ break;
+ if(cnt >= MAX_VALUE_COUNT[b_index]) {
+ reap_batt_node(b_index, MAX_VALUE_COUNT[b_index]);
+ break;
+ }
+ }
+ LOGINFO(" sum = %lf", total_factor);
+ total_factor /= (float)cnt;
+ LOGINFO(" avg_factor = %lf", total_factor);
+
+ return total_factor;
+}
+
+static void update_time(enum state_a a_index, int seconds)
+{
+ int clock;
+
+ if(a_index < 0 || a_index >= A_END)
+ return;
+
+ if(seconds <= 0)
+ return;
+
+ switch(a_index) {
+ case A_TIMETOFULL:
+ vconf_set_int(VCONFKEY_PM_BATTERY_TIMETOFULL,
+ seconds);
+ LOGINFO("update time[%d,%d]", a_index, seconds);
+ break;
+ case A_TIMETOEMPTY:
+ vconf_set_int(VCONFKEY_PM_BATTERY_TIMETOEMPTY,
+ seconds);
+ LOGINFO("update time[%d,%d]", a_index, seconds);
+ break;
+ }
+}
+
+void battinfo_calculation()
+{
+ time_t clock;
+ int capacity = 0;
+ int estimated_time = 0;
+ int tmp = 0;
+
+ capacity = get_battery_capacity();
+
+ if(capacity <= 0)
+ return;
+ if(capacity == old_capacity)
+ return;
+
+ old_capacity = capacity;
+
+ if(get_charging_status(&tmp) == 0)
+ charging_state = (tmp > 0 ? TRUE : FALSE);
+
+ clock = time(NULL);
+ if(charging_state == TRUE) {
+ del_all_batt_node(B_UNCHARGING);
+ if((capacity * 100 / full_capacity)
+ >= BATTERY_FULL_THRESHOLD) {
+ if(battery_charge_full()) {
+ del_all_batt_node(B_CHARGING);
+ LOGINFO("battery fully charged!");
+ update_time(A_TIMETOFULL, 0);
+ return;
+ }
+ }
+ if(batt_head[B_CHARGING] == NULL) {
+ add_batt_node(B_CHARGING, clock, capacity);
+ } else {
+ add_batt_node(B_CHARGING, clock, capacity);
+ avg_factor[B_CHARGING] = update_factor(B_CHARGING);
+ }
+ estimated_time = (float)(full_capacity - capacity) *
+ avg_factor[B_CHARGING];
+ update_time(A_TIMETOFULL, estimated_time);
+ } else {
+ del_all_batt_node(B_CHARGING);
+ if(system_wakeup_flag == true) {
+ del_all_batt_node(B_UNCHARGING);
+ system_wakeup_flag = false;
+ }
+ if(batt_head[B_UNCHARGING] == NULL) {
+ add_batt_node(B_UNCHARGING, clock, capacity);
+ } else {
+ add_batt_node(B_UNCHARGING, clock, capacity);
+ avg_factor[B_UNCHARGING] = update_factor(B_UNCHARGING);
+ }
+ estimated_time = (float)capacity * avg_factor[B_UNCHARGING];
+ update_time(A_TIMETOEMPTY, estimated_time);
+ }
+}
+
+static gboolean battinfo_cb(gpointer data)
+{
+ battinfo_calculation();
+ return TRUE;
+}
+
+static int init_battery_func()
+{
+ int ret = -1;
+ int value = -1;
+
+ ret = battery_capacity_raw(&value);
+ if(ret >= 0) {
+ get_battery_capacity = battery_capacity_raw;
+ full_capacity = FULL_CAPACITY_RAW;
+ LOGINFO("init_battery_func : full capacity(%d)", full_capacity);
+ return 0;
+ }
+
+ ret = battery_capacity(&value);
+ if(ret >= 0) {
+ get_battery_capacity = battery_capacity;
+ full_capacity = FULL_CAPACITY;
+ LOGINFO("init_battery_func : full capacity(%d)", full_capacity);
+ return 0;
+ }
+
+ LOGERR("init_battery_func : fail to get battery info!");
+ return -1;
+}
+
+int start_battinfo_gathering(int timeout)
+{
+ int ret;
+
+ LOGINFO("Start battery gathering!");
+
+ if(timeout < 0) {
+ LOGERR("invalid timeout value [%d]!", timeout);
+ return -1;
+ }
+ if(init_battery_func() != 0)
+ return -1;
+
+ old_capacity = 0;
+ battinfo_calculation();
+
+ if(timeout > 0) {
+ /* Using g_timer for gathering battery info */
+ timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT, timeout,
+ (GSourceFunc)battinfo_cb, NULL, NULL);
+ } else if(timeout == 0) {
+ /* Using heynoti from system-server(udev)
+ for gathering battery info */
+ if((noti_fd = heynoti_init()) < 0) {
+ LOGERR("heynoti init failed!");
+ return -1;
+ }
+ ret = heynoti_subscribe(noti_fd, "device_charge_chgdet",
+ (void *)battinfo_calculation, (void *)NULL);
+ if(ret != 0) {
+ LOGERR("heynoti subscribe fail!");
+ return -1;
+ }
+
+ ret = heynoti_attach_handler(noti_fd);
+ if(ret != 0) {
+ LOGERR("heynoti attach handler fail!");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void end_battinfo_gathering()
+{
+ LOGINFO("End battery gathering!");
+
+ if(timeout_id > 0) {
+ g_source_remove(timeout_id);
+ timeout_id = 0;
+ }
+ if(noti_fd > 0) {
+ heynoti_close(noti_fd);
+ noti_fd = 0;
+ }
+
+ del_all_batt_node(B_UNCHARGING);
+ del_all_batt_node(B_CHARGING);
+}
+
diff --git a/pm_battery.h b/pm_battery.h
new file mode 100644
index 0000000..1d5b0e7
--- /dev/null
+++ b/pm_battery.h
@@ -0,0 +1,36 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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.
+*/
+
+#ifndef __PM_BATTERY_H_
+#define __PM_BATTERY_H_
+
+#define BATTERY_POLLING_PERIOD 30000 /* ms */
+
+/*
+* If system is suspend state for a long time,
+* it's hard to expect power consumption.
+* Therefore, Previous capacity value is ignored
+* when system changes from suspend state to resume state.
+* This flag indicates phone wakes up from suspend state.
+* In this case, all nodes saved are ignored.
+*/
+extern int system_wakeup_flag;
+
+int start_battinfo_gathering(int timeout);
+void end_battinfo_gathering();
+
+#endif
diff --git a/pm_conf.c b/pm_conf.c
new file mode 100644
index 0000000..9ee6e54
--- /dev/null
+++ b/pm_conf.c
@@ -0,0 +1,81 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "pm_conf.h"
+
+enum {
+ IDX_NAME = 0,
+ IDX_DEFAULT,
+ IDX_END
+};
+
+static char *def_values[][IDX_END] = {
+ {"PM_INPUT", "/dev/event0:/dev/event1"},
+ {"PM_TO_START", "0"},
+ {"PM_TO_NORMAL", "600"},
+ {"PM_TO_LCDDIM", "5"},
+ {"PM_TO_LCDOFF", "5"},
+ {"PM_TO_SLEEP", "0"},
+ {"PM_SYS_POWER", "/sys/power/state"},
+ {"PM_SYS_BRIGHT", "/sys/class/backlight/mobile-bl/brightness"},
+ {"PM_SYS_BRIGHT", "/sys/class/backlight/mobile-bl/max_brightness"},
+ {"PM_SYS_BLPWR", "/sys/class/backlight/mobile-bl/bl_power"},
+ {"PM_SYS_DIMBRT", "0"},
+ {"PM_SYS_BLON", "0"},
+ {"PM_SYS_BLOFF", "4"},
+ {"PM_SYS_FB_NORMAL", "1"},
+ {"PM_SYS_STATE", "mem"},
+ {"PM_EXEC_PRG", NULL},
+ {"PM_END", ""},
+};
+
+static char *_find_default(char *name)
+{
+ char *ret = NULL;
+ int i = 0;
+
+ while (strcmp("PM_END", def_values[i][IDX_NAME])) {
+ if (!strcmp(name, def_values[i][IDX_NAME])) {
+ ret = def_values[i][IDX_DEFAULT];
+ break;
+ }
+ i++;
+ }
+ return ret;
+}
+
+int get_env(char *name, char *buf, int size)
+{
+ char *ret;
+
+ ret = getenv(name);
+ if ((ret == NULL) || (strlen(ret) > 1024)) {
+ ret = _find_default(name);
+ if (ret)
+ snprintf(buf, size, "%s", ret);
+ else
+ snprintf(buf, size, "");
+ } else {
+ snprintf(buf, size, "%s", ret);
+ }
+
+ return 0;
+}
diff --git a/pm_conf.h b/pm_conf.h
new file mode 100644
index 0000000..8a3894d
--- /dev/null
+++ b/pm_conf.h
@@ -0,0 +1,26 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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.
+*/
+
+
+#ifndef __POWER_MANAGER_CONF_H__
+#define __POWER_MANAGER_CONF_H__
+
+#define EN_SYS_DIMBRT "PM_SYS_DIMBRT"
+
+extern int get_env(char *, char *, int);
+
+#endif
diff --git a/pm_core.c b/pm_core.c
new file mode 100644
index 0000000..d53aa27
--- /dev/null
+++ b/pm_core.c
@@ -0,0 +1,1356 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 pm_core.c
+ * @version 0.2
+ * @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 <glib.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 <heynoti.h>
+#include <sysman.h>
+#include <aul.h>
+#include <vconf-keys.h>
+
+#include "pm_device_plugin.h"
+#include "pm_core.h"
+#include "pm_battery.h"
+
+#define USB_CON_PIDFILE "/var/run/.system_server.pid"
+#define PM_STATE_LOG_FILE "/var/log/pm_state.log"
+#define PM_WAKEUP_NOTI_NAME "system_wakeup"
+#define PM_EVENT_NOTI_NAME "pm_event"
+#define PM_EVENT_NOTI_PATH "/opt/share/noti/"PM_EVENT_NOTI_NAME
+
+/**
+ * @addtogroup POWER_MANAGER
+ * @{
+ */
+
+#define LOCKSTATUS_TIMEOUT 3
+#define TELEPHONY_SIGNAL_TIMEOUT 10
+
+#define SET_BRIGHTNESS_IN_BOOTLOADER "/usr/bin/save_blenv SLP_LCD_BRIGHT"
+
+/* default transition, action fuctions */
+static int default_trans(int evt);
+static int default_action(int timeout);
+static int default_check(int next);
+
+unsigned int status_flag;
+
+static void (*power_saving_func) (int onoff);
+static void reset_timeout(int timeout);
+
+int cur_state;
+int old_state;
+static GMainLoop *mainloop;
+guint timeout_src_id;
+static time_t last_t;
+static int pre_suspend_flag = false;
+int system_wakeup_flag = false;
+
+struct state states[S_END] = {
+ {S_START, default_trans, default_action, default_check,},
+ {S_NORMAL, default_trans, default_action, default_check,},
+ {S_LCDDIM, default_trans, default_action, default_check,},
+ {S_LCDOFF, default_trans, default_action, default_check,},
+ {S_SLEEP, default_trans, default_action, default_check,}
+};
+
+int (*pm_init_extention) (void *data);
+void (*pm_exit_extention) (void);
+
+static char state_string[5][10] =
+ { "S_START", "S_NORMAL", "S_LCDDIM", "S_LCDOFF", "S_SLEEP" };
+
+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 */
+#ifdef TIZEN_EMUL
+ {S_LCDOFF, S_NORMAL}, /* S_LCDOFF */
+#else
+ {S_SLEEP, S_NORMAL}, /* S_LCDOFF */
+#endif
+ {S_LCDOFF, S_NORMAL}, /* S_SLEEP, When wake up by devices, go lcd_off state */
+};
+
+#define SHIFT_UNLOCK 4
+#define MASK_RESET_TIMEOUT 0x8 /* 1000 */
+#define MASK_MARGIN_TIMEOUT (0x1 << 8)
+#define SHIFT_CHANGE_STATE 7
+#define CHANGE_STATE_BIT 0xF00 /* 1111 0000 0000 */
+#define LOCK_SCREEN_TIMEOUT 5
+#define SHIFT_HOLD_KEY_BLOCK 16
+
+#define DEFAULT_NORMAL_TIMEOUT 30
+#define DEFAULT_DIM_TIMEOUT 5
+#define DEFAULT_OFF_TIMEOUT 5
+#define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_HOLD_KEY_BLOCK) & 0x1)
+
+static int received_sleep_cmd = 0;
+
+typedef struct _node {
+ pid_t pid;
+ int timeout_id;
+ gboolean holdkey_block;
+ struct _node *next;
+} Node;
+
+static Node *cond_head[S_END];
+
+static int refresh_app_cond()
+{
+ trans_condition = 0;
+
+ if (cond_head[S_LCDDIM] != NULL)
+ trans_condition = trans_condition | MASK_DIM;
+ if (cond_head[S_LCDOFF] != NULL)
+ trans_condition = trans_condition | MASK_OFF;
+ if (cond_head[S_SLEEP] != NULL)
+ trans_condition = trans_condition | MASK_SLP;
+
+ return 0;
+}
+
+static Node *find_node(enum state_t s_index, pid_t pid)
+{
+ Node *t = cond_head[s_index];
+
+ while (t != NULL) {
+ if (t->pid == pid)
+ break;
+ t = t->next;
+ }
+ return t;
+}
+
+static Node *add_node(enum state_t s_index, pid_t pid, int timeout_id,
+ gboolean holdkey_block)
+{
+ Node *n;
+
+ n = (Node *) malloc(sizeof(Node));
+ if (n == NULL) {
+ LOGERR("Not enough memory, add cond. fail");
+ return NULL;
+ }
+
+ n->pid = pid;
+ n->timeout_id = timeout_id;
+ n->holdkey_block = holdkey_block;
+ n->next = cond_head[s_index];
+ cond_head[s_index] = n;
+
+ refresh_app_cond();
+ return n;
+}
+
+static int del_node(enum state_t s_index, Node *n)
+{
+ Node *t;
+ Node *prev;
+
+ if (n == NULL)
+ return 0;
+
+ t = cond_head[s_index];
+ prev = NULL;
+ while (t != NULL) {
+ if (t == n) {
+ if (prev != NULL)
+ prev->next = t->next;
+ else
+ cond_head[s_index] = cond_head[s_index]->next;
+ free(t);
+ break;
+ }
+ prev = t;
+ t = t->next;
+ }
+ refresh_app_cond();
+ return 0;
+}
+
+static gboolean del_dim_cond(gpointer data)
+{
+ Node *tmp = NULL;
+ LOGINFO("delete prohibit dim condition by timeout\n");
+
+ tmp = find_node(S_LCDDIM, (pid_t) data);
+ del_node(S_LCDDIM, tmp);
+
+ if (timeout_src_id == 0)
+ states[cur_state].trans(EVENT_TIMEOUT);
+
+ return FALSE;
+}
+
+static gboolean del_off_cond(gpointer data)
+{
+ Node *tmp = NULL;
+ LOGINFO("delete prohibit off condition by timeout\n");
+
+ tmp = find_node(S_LCDOFF, (pid_t) data);
+ del_node(S_LCDOFF, tmp);
+
+ if (timeout_src_id == 0)
+ states[cur_state].trans(EVENT_TIMEOUT);
+
+ return FALSE;
+}
+
+static gboolean del_sleep_cond(gpointer data)
+{
+ Node *tmp = NULL;
+ LOGINFO("delete prohibit sleep condition by timeout\n");
+
+ tmp = find_node(S_SLEEP, (pid_t) data);
+ del_node(S_SLEEP, tmp);
+
+ if (timeout_src_id == 0)
+ states[cur_state].trans(EVENT_TIMEOUT);
+
+ sysman_inform_inactive((pid_t) data);
+ return FALSE;
+}
+
+/* update transition condition for application requrements */
+static int proc_condition(PMMsg *data)
+{
+ Node *tmp = NULL;
+ unsigned int val = data->cond;
+ pid_t pid = data->pid;
+ int cond_timeout_id = -1;
+ gboolean holdkey_block = 0;
+
+ if (val == 0)
+ return 0;
+ /* for debug */
+ char pname[PATH_MAX];
+ char buf[PATH_MAX];
+ int fd_cmdline;
+ snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
+ fd_cmdline = open(buf, O_RDONLY);
+ if (fd_cmdline < 0) {
+ snprintf(pname, PATH_MAX,
+ "does not exist now(may be dead without unlock)");
+ } else {
+ read(fd_cmdline, pname, PATH_MAX);
+ close(fd_cmdline);
+ }
+
+ if (val & MASK_DIM) {
+ if (data->timeout > 0) {
+ cond_timeout_id =
+ g_timeout_add_full(G_PRIORITY_DEFAULT,
+ data->timeout,
+ (GSourceFunc) del_dim_cond,
+ (gpointer) pid, NULL);
+ }
+ holdkey_block = GET_HOLDKEY_BLOCK_STATE(val);
+ tmp = find_node(S_LCDDIM, pid);
+ if (tmp == NULL)
+ add_node(S_LCDDIM, pid, cond_timeout_id, holdkey_block);
+ else if (tmp->timeout_id > 0) {
+ g_source_remove(tmp->timeout_id);
+ tmp->timeout_id = cond_timeout_id;
+ tmp->holdkey_block = holdkey_block;
+ }
+ /* for debug */
+ LOGINFO("[%s] locked by pid %d - process %s\n", "S_NORMAL", pid,
+ pname);
+ }
+ if (val & MASK_OFF) {
+ if (data->timeout > 0) {
+ cond_timeout_id =
+ g_timeout_add_full(G_PRIORITY_DEFAULT,
+ data->timeout,
+ (GSourceFunc) del_off_cond,
+ (gpointer) pid, NULL);
+ }
+ holdkey_block = GET_HOLDKEY_BLOCK_STATE(val);
+ tmp = find_node(S_LCDOFF, pid);
+ if (tmp == NULL)
+ add_node(S_LCDOFF, pid, cond_timeout_id, holdkey_block);
+ else if (tmp->timeout_id > 0) {
+ g_source_remove(tmp->timeout_id);
+ tmp->timeout_id = cond_timeout_id;
+ tmp->holdkey_block = holdkey_block;
+ }
+ /* for debug */
+ LOGINFO("[%s] locked by pid %d - process %s\n", "S_LCDDIM", pid,
+ pname);
+ }
+ if (val & MASK_SLP) {
+ if (data->timeout > 0) {
+ cond_timeout_id =
+ g_timeout_add_full(G_PRIORITY_DEFAULT,
+ data->timeout,
+ (GSourceFunc) del_sleep_cond,
+ (gpointer) pid, NULL);
+ }
+ tmp = find_node(S_SLEEP, pid);
+ if (tmp == NULL)
+ add_node(S_SLEEP, pid, cond_timeout_id, 0);
+ else if (tmp->timeout_id > 0) {
+ g_source_remove(tmp->timeout_id);
+ tmp->timeout_id = cond_timeout_id;
+ tmp->holdkey_block = 0;
+ }
+ sysman_inform_active(pid);
+ /* for debug */
+ LOGINFO("[%s] locked by pid %d - process %s\n", "S_LCDOFF", pid,
+ pname);
+ }
+
+ /* UNLOCK(GRANT) condition processing */
+ val = val >> SHIFT_UNLOCK;
+ if (val & MASK_DIM) {
+ tmp = find_node(S_LCDDIM, pid);
+ del_node(S_LCDDIM, tmp);
+ LOGINFO("[%s] unlocked by pid %d - process %s\n", "S_LORMAL",
+ pid, pname);
+ }
+ if (val & MASK_OFF) {
+ tmp = find_node(S_LCDOFF, pid);
+ del_node(S_LCDOFF, tmp);
+ LOGINFO("[%s] unlocked by pid %d - process %s\n", "S_LCDDIM",
+ pid, pname);
+ }
+ if (val & MASK_SLP) {
+ tmp = find_node(S_SLEEP, pid);
+ del_node(S_SLEEP, tmp);
+ sysman_inform_inactive(pid);
+ LOGINFO("[%s] unlocked by pid %d - process %s\n", "S_LCDOFF",
+ pid, pname);
+ }
+ val = val >> 8;
+ if (val != 0) {
+ if ((val & 0x1)) {
+ reset_timeout(states[cur_state].timeout);
+ LOGINFO("reset timeout\n", "S_LCDOFF", pid, pname);
+ }
+ } else {
+ /* guard time for suspend */
+ if (cur_state == S_LCDOFF) {
+ reset_timeout(5);
+ LOGINFO("margin timeout (5 seconds)\n");
+ }
+ }
+
+ if (timeout_src_id == 0)
+ states[cur_state].trans(EVENT_TIMEOUT);
+
+ return 0;
+}
+
+static int proc_change_state(unsigned int cond)
+{
+ int next_state = 0;
+ struct state *st;
+ int i;
+
+ for (i = S_NORMAL; i < S_END; i++) {
+ if ((cond >> (SHIFT_CHANGE_STATE + i)) & 0x1) {
+ next_state = i;
+ break;
+ }
+ }
+ LOGINFO("Change State to %s", state_string[next_state]);
+
+ switch (next_state) {
+ case S_NORMAL:
+ case S_LCDDIM:
+ case S_LCDOFF:
+ /* state transition */
+ old_state = cur_state;
+ cur_state = next_state;
+ st = &states[cur_state];
+
+ /* enter action */
+ if (st->action) {
+ st->action(st->timeout);
+ }
+ break;
+ case S_SLEEP:
+ LOGINFO("Dangerous requests.");
+ /* at first LCD_OFF and then goto sleep */
+ /* state transition */
+ old_state = cur_state;
+ cur_state = S_LCDOFF;
+ st = &states[cur_state];
+ if (st->action) {
+ st->action(0);
+ }
+ old_state = cur_state;
+ cur_state = S_SLEEP;
+ st = &states[cur_state];
+ if (st->action) {
+ st->action(0);
+ }
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+/* If some changed, return 1 */
+int check_processes(enum state_t prohibit_state)
+{
+ Node *t = cond_head[prohibit_state];
+ Node *tmp = NULL;
+ int ret = 0;
+
+ while (t != NULL) {
+ if (kill(t->pid, 0) == -1) {
+ LOGERR
+ ("%d process does not exist, delete the REQ - prohibit state %d ",
+ t->pid, prohibit_state);
+ tmp = t;
+ ret = 1;
+ }
+ t = t->next;
+
+ if (tmp != NULL) {
+ del_node(prohibit_state, tmp);
+ tmp = NULL;
+ }
+ }
+
+ return ret;
+}
+
+int check_holdkey_block(enum state_t state)
+{
+ Node *t = cond_head[state];
+ int ret = 0;
+
+ LOGINFO("check holdkey block : state of %s", state_string[state]);
+
+ while(t != NULL) {
+ if(t->holdkey_block == true) {
+ ret = 1;
+ LOGINFO("Hold key blocked by pid(%d)!", t->pid);
+ break;
+ }
+ t = t->next;
+ }
+
+ return ret;
+}
+
+int delete_condition(enum state_t state)
+{
+ Node *t = cond_head[state];
+ int ret = 0;
+ Node *tmp = NULL;
+
+ LOGINFO("delete condition : state of %s", state_string[state]);
+
+ while(t != NULL) {
+ if(t->timeout_id > 0) {
+ g_source_remove(t->timeout_id);
+ }
+ tmp = t;
+ t = t->next;
+ LOGINFO("delete node of pid(%d)", tmp->pid);
+ del_node(state, tmp);
+ }
+
+ return 0;
+}
+
+/* SIGINT, SIGTERM, SIGQUIT signal handler */
+static void sig_quit(int signo)
+{
+ LOGINFO("received %d signal : stops a main loop", signo);
+ if (mainloop)
+ g_main_loop_quit(mainloop);
+}
+
+void print_info(int fd)
+{
+ int s_index = 0;
+ char buf[255];
+ int i = 1, ret;
+
+ if (fd < 0)
+ return;
+
+ snprintf(buf, sizeof(buf),
+ "\n======================================================================\n");
+ write(fd, buf, strlen(buf));
+ snprintf(buf, sizeof(buf),"Timeout Info: Run[%d] Dim[%d] Off[%d]\n",
+ states[S_NORMAL].timeout,
+ states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
+ write(fd, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
+ (trans_condition & MASK_DIM) ? state_string[S_NORMAL] : "-",
+ (trans_condition & MASK_OFF) ? state_string[S_LCDDIM] : "-",
+ (trans_condition & MASK_SLP) ? state_string[S_LCDOFF] : "-");
+ write(fd, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Current State: %s\n", state_string[cur_state]);
+ write(fd, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
+ write(fd, buf, strlen(buf));
+
+ for (s_index = S_NORMAL; s_index < S_END; s_index++) {
+ Node *t;
+ char pname[PATH_MAX];
+ int fd_cmdline;
+ t = cond_head[s_index];
+
+ while (t != NULL) {
+ snprintf(buf, sizeof(buf), "/proc/%d/cmdline", t->pid);
+ fd_cmdline = open(buf, O_RDONLY);
+ if (fd_cmdline < 0) {
+ snprintf(pname, PATH_MAX,
+ "does not exist now(may be dead without unlock)");
+ } else {
+ read(fd_cmdline, pname, PATH_MAX);
+ close(fd_cmdline);
+ }
+ snprintf(buf, sizeof(buf),
+ " %d: [%s] locked by pid %d - process %s\n",
+ i++, state_string[s_index - 1], t->pid, pname);
+ write(fd, buf, strlen(buf));
+ t = t->next;
+ }
+ }
+}
+
+/* SIGHUP signal handler
+ * For debug... print info to syslog
+ */
+static void sig_hup(int signo)
+{
+ int fd;
+ char buf[255];
+ time_t now_time;
+
+ time(&now_time);
+
+ fd = open(PM_STATE_LOG_FILE, O_CREAT | O_WRONLY, 0644);
+ if (fd != -1) {
+ snprintf(buf, sizeof(buf), "\npm_state_log now-time : %d (s)\n\n",
+ (int)now_time);
+ write(fd, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "status_flag: %x\n", status_flag);
+ write(fd, buf, strlen(buf));
+
+ snprintf(buf, sizeof(buf), "received sleep cmd count : %d\n",
+ received_sleep_cmd);
+ write(fd, buf, strlen(buf));
+
+ print_info(fd);
+ close(fd);
+ }
+
+ fd = open("/dev/console", O_WRONLY);
+ if (fd != -1) {
+ print_info(fd);
+ close(fd);
+ }
+}
+
+/* timeout handler */
+gboolean timeout_handler(gpointer data)
+{
+ LOGINFO("Time out state %s\n", state_string[cur_state]);
+
+ if (timeout_src_id != 0) {
+ g_source_remove(timeout_src_id);
+ timeout_src_id = 0;
+ }
+
+ if ((status_flag & VCALL_FLAG)
+ && (cur_state == S_LCDOFF || cur_state == S_SLEEP)) {
+ status_flag &= ~(VCALL_FLAG);
+ reset_timeout(TELEPHONY_SIGNAL_TIMEOUT);
+ return FALSE;
+ }
+ states[cur_state].trans(EVENT_TIMEOUT);
+ return FALSE;
+}
+
+static void reset_timeout(int timeout)
+{
+ if (timeout_src_id != 0) {
+ g_source_remove(timeout_src_id);
+ timeout_src_id = 0;
+ }
+ if (timeout > 0) {
+ timeout_src_id = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
+ timeout,
+ (GSourceFunc)
+ timeout_handler,
+ NULL, NULL);
+ }
+}
+
+static void sig_usr(int signo)
+{
+ status_flag |= VCALL_FLAG;
+}
+
+static void sig_break_block(int signo)
+{
+ LOGINFO("We got signal to break that pending checking in kernel\n");
+}
+
+/*
+ * default transition function
+ * 1. call check
+ * 2. transition
+ * 3. call enter action function
+ */
+static int default_trans(int evt)
+{
+ struct state *st = &states[cur_state];
+ int next_state;
+
+ if(cur_state == S_NORMAL && st->timeout == 0) {
+ LOGINFO("LCD always on enabled!");
+ return 0;
+ }
+
+ next_state = (enum state_t)trans_table[cur_state][evt];
+
+ /* check conditions */
+ while (st->check && !st->check(next_state)) {
+ /* There is a condition. */
+ LOGINFO("%s -> %s : check fail", state_string[cur_state],
+ state_string[next_state]);
+ if (!check_processes(next_state)) {
+ /* this is valid condition - the application that sent the condition is running now. */
+ return -1;
+ }
+ }
+
+ /* state transition */
+ old_state = cur_state;
+ cur_state = next_state;
+ st = &states[cur_state];
+
+ /* enter action */
+ if (st->action) {
+ st->action(st->timeout);
+ }
+
+ return 0;
+}
+
+/* default enter action function */
+static int default_action(int timeout)
+{
+ int ret;
+ int wakeup_count = -1;
+ char buf[NAME_MAX];
+ char *pkgname = NULL;
+ int i = 0;
+ int lock_state = -1;
+ struct itimerval val;
+
+ if (cur_state != old_state && cur_state != S_SLEEP)
+ set_setting_pmstate(cur_state);
+
+ switch (cur_state) {
+ case S_NORMAL:
+ /* normal state : backlight on and restore the previous brightness */
+ if (old_state == S_LCDOFF || old_state == S_SLEEP) {
+ if (pre_suspend_flag == true) {
+ system_post_resume();
+ pre_suspend_flag = false;
+ }
+ for (i = 0; i < 14; i++) {
+ vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
+ LOGERR("Idle lock check : %d, vonf : %d", i, lock_state);
+ if (lock_state)
+ break;
+ usleep(50000);
+ }
+#ifndef X86 /* Different with ARM FB driver, IA gfx driver is sensitive to the order. */
+ backlight_restore();
+ backlight_on();
+#else
+ backlight_on();
+ backlight_restore();
+#endif
+ } else if (old_state == S_LCDDIM)
+ backlight_restore();
+ break;
+
+ case S_LCDDIM:
+ if (old_state == S_LCDOFF || old_state == S_SLEEP) {
+ backlight_on();
+ }
+ /* lcd dim state : dim the brightness */
+ backlight_dim();
+ break;
+
+ case S_LCDOFF:
+ if (old_state != S_SLEEP && old_state != S_LCDOFF) {
+ /* lcd off state : turn off the backlight */
+ backlight_off();
+ if (pre_suspend_flag == false) {
+ pre_suspend_flag = true;
+ system_pre_suspend();
+ }
+ }
+ break;
+
+ case S_SLEEP:
+ /*
+ * We can not always be blocked here because of that
+ * in-progress checking in kernel for wakeup count,
+ * if we cannot get the result within some time, then
+ * just give it up and then retry it in the next time,
+ * this method would not break that original expected
+ * 'aggresive suspend' idea, but at the same time make
+ * the system is 'always' responsible to some keypress
+ * actions like power button press.
+ */
+ val.it_value.tv_sec = TOLERANCE_SLOT;
+ val.it_value.tv_usec = 0;
+ val.it_interval.tv_sec = val.it_interval.tv_usec = 0;
+ setitimer(ITIMER_REAL, &val, NULL);
+
+ /* sleep state : set system mode to SUSPEND */
+ if (0 > plugin_intf->OEM_sys_get_power_wakeup_count(&wakeup_count))
+ LOGERR("wakeup count read error");
+
+ if (wakeup_count < 0) {
+ LOGINFO("Wakup Event! Can not enter suspend mode.");
+ goto go_lcd_off;
+ }
+
+ if (0 > plugin_intf->OEM_sys_set_power_wakeup_count(wakeup_count)) {
+ LOGERR("wakeup count write error");
+ goto go_lcd_off;
+ }
+
+ goto go_suspend;
+ }
+
+ /* set timer with current state timeout */
+ reset_timeout(timeout);
+ LOGINFO("timout set: %s state %d sec", state_string[cur_state], timeout);
+
+ return 0;
+
+go_suspend:
+ system_suspend();
+ LOGINFO("system wakeup!!");
+ system_wakeup_flag = true;
+ heynoti_publish(PM_WAKEUP_NOTI_NAME);
+ /* Resume !! */
+ if (check_wakeup_src() == EVENT_DEVICE)
+ /* system waked up by devices */
+ states[cur_state].trans(EVENT_DEVICE);
+ else
+ /* system waked up by user input */
+ states[cur_state].trans(EVENT_INPUT);
+ return 0;
+
+go_lcd_off:
+ heynoti_publish(PM_WAKEUP_NOTI_NAME);
+ /* Resume !! */
+ states[cur_state].trans(EVENT_DEVICE);
+ return 0;
+}
+
+/*
+ * default check function
+ * return
+ * 0 : can't transit, others : transitable
+ */
+static int default_check(int next)
+{
+ int trans_cond = trans_condition & MASK_BIT;
+ int lock_state = -1;
+
+ LOGINFO("trans_cond : %x", trans_cond);
+
+ vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
+ if(lock_state==VCONFKEY_IDLE_LOCK && next != S_SLEEP) {
+ LOGINFO("default_check : LOCK STATE, it's transitable");
+ return 1;
+ }
+
+ switch (next) {
+ case S_LCDDIM:
+ trans_cond = trans_cond & MASK_DIM;
+ break;
+ case S_LCDOFF:
+ trans_cond = trans_cond & MASK_OFF;
+ break;
+ case S_SLEEP:
+ trans_cond = trans_cond & MASK_SLP;
+ break;
+ default: /* S_NORMAL is exceptional */
+ trans_cond = 0;
+ break;
+ }
+
+ if (trans_cond != 0)
+ return 0;
+
+ return 1; /* transitable */
+}
+
+/* get configurations from setting */
+static int get_settings()
+{
+ int i;
+ int val = 0;
+ int ret = -1;
+ char buf[255];
+
+ for (i = 0; i < S_END; i++) {
+ switch (states[i].state) {
+ case S_NORMAL:
+ ret = get_run_timeout(&val);
+ if (ret != 0) {
+ ret = get_env("PM_TO_NORMAL", buf, 255);
+ val = atoi(buf);
+ }
+ break;
+ case S_LCDDIM:
+ ret = get_dim_timeout(&val);
+ break;
+ case S_LCDOFF:
+ ret = get_off_timeout(&val);
+ break;
+ default:
+ /* This state doesn't need to set time out. */
+ ret = -1;
+ break;
+ }
+ if (ret == 0 || val < 0) {
+ states[i].timeout = val;
+ } else {
+ switch (states[i].state) {
+ case S_NORMAL:
+ states[i].timeout = DEFAULT_NORMAL_TIMEOUT;
+ break;
+ case S_LCDDIM:
+ states[i].timeout = DEFAULT_DIM_TIMEOUT;
+ break;
+ case S_LCDOFF:
+ states[i].timeout = DEFAULT_OFF_TIMEOUT;
+ break;
+ default:
+ states[i].timeout = 0;
+ break;
+ }
+ }
+ LOGINFO("%s state : %d timeout", state_string[i], states[i].timeout);
+ }
+
+ return 0;
+}
+
+static void default_saving_mode(int onoff)
+{
+ if (onoff) {
+ status_flag |= PWRSV_FLAG;
+ } else {
+ status_flag &= ~PWRSV_FLAG;
+ }
+ if (cur_state == S_NORMAL)
+ backlight_restore();
+}
+
+static int poll_callback(int condition, PMMsg *data)
+{
+ time_t now;
+
+ if (condition == INPUT_POLL_EVENT) {
+ if (cur_state == S_LCDOFF || cur_state == S_SLEEP)
+ LOGINFO("Power key input");
+ time(&now);
+ if (last_t != now) {
+ states[cur_state].trans(EVENT_INPUT);
+ last_t = now;
+ }
+ } else if (condition == PM_CONTROL_EVENT) {
+ LOGINFO("process pid(%d) pm_control condition : %x ", data->pid,
+ data->cond);
+
+ if (data->cond & MASK_BIT
+ || (data->cond >> SHIFT_UNLOCK) & MASK_BIT)
+ proc_condition(data);
+
+ if (data->cond & CHANGE_STATE_BIT) {
+
+ LOGINFO("Change state by pid(%d) request.", data->pid);
+ proc_change_state(data->cond);
+ }
+ }
+
+ return 0;
+}
+
+static int update_setting(int key_idx, int val)
+{
+ char buf[PATH_MAX];
+ int ret = -1;
+ int dim_timeout = -1;
+ int run_timeout = -1;
+ int power_saving_stat = -1;
+ int power_saving_display_stat = -1;
+
+ switch (key_idx) {
+ case SETTING_TO_NORMAL:
+ ret = get_dim_timeout(&dim_timeout);
+ if(ret < 0 || dim_timeout < 0) {
+ LOGERR("Can not get dim timeout. set default 5 seconds");
+ dim_timeout = 5;
+ }
+ if(val < 0) {
+ LOGERR("LCD timeout is wrong, set default 15 seconds");
+ val = 15;
+ }
+ if(val == 0) {
+ states[S_NORMAL].timeout = 0;
+ } else if(val > dim_timeout) {
+ states[S_NORMAL].timeout = val - dim_timeout;
+ } else {
+ states[S_NORMAL].timeout = 1;
+ }
+ states[cur_state].trans(EVENT_INPUT);
+ break;
+ case SETTING_LOW_BATT:
+ if (val < VCONFKEY_SYSMAN_BAT_WARNING_LOW) {
+ if (!(status_flag & CHRGR_FLAG))
+ power_saving_func(true);
+ status_flag |= LOWBT_FLAG;
+ } else {
+ if (status_flag & PWRSV_FLAG)
+ power_saving_func(false);
+ status_flag &= ~LOWBT_FLAG;
+ status_flag &= ~BRTCH_FLAG;
+ vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM,
+ false);
+ }
+ break;
+ case SETTING_CHARGING:
+ if (val) {
+ if (status_flag & LOWBT_FLAG) {
+ power_saving_func(false);
+ status_flag &= ~LOWBT_FLAG;
+ }
+ status_flag |= CHRGR_FLAG;
+ } else {
+ int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
+ vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
+ if(bat_state < VCONFKEY_SYSMAN_BAT_NORMAL) {
+ power_saving_func(true);
+ status_flag |= LOWBT_FLAG;
+ }
+ status_flag &= ~CHRGR_FLAG;
+ }
+ break;
+ case SETTING_BRT_LEVEL:
+ if (status_flag & PWRSV_FLAG) {
+ status_flag |= BRTCH_FLAG;
+ vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM,
+ true);
+ LOGINFO("brightness changed in low battery, escape dim state");
+ }
+ set_default_brt(val);
+ snprintf(buf, sizeof(buf), "%s %d", SET_BRIGHTNESS_IN_BOOTLOADER, val);
+ LOGINFO("Brightness set in bl : %d",val);
+ system(buf);
+ break;
+ case SETTING_LOCK_SCREEN:
+ if (val == VCONFKEY_IDLE_LOCK) {
+ states[S_NORMAL].timeout = LOCK_SCREEN_TIMEOUT;
+ LOGERR("LCD NORMAL timeout is set by %d seconds for lock screen", LOCK_SCREEN_TIMEOUT);
+ } else {
+ get_run_timeout(&run_timeout);
+ if(run_timeout < 0) {
+ LOGERR("Can not get run timeout. set default 15 seconds(includes dim 5 seconds)");
+ run_timeout = 10;
+ }
+ states[S_NORMAL].timeout = run_timeout;
+ LOGINFO("LCD NORMAL timeout is set by %d seconds because phone is unlocked", run_timeout);
+ }
+ if (cur_state == S_NORMAL) {
+ states[cur_state].trans(EVENT_INPUT);
+ }
+ break;
+ case SETTING_POWER_SAVING:
+ if (val == 1)
+ vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY, &power_saving_display_stat);
+ if (power_saving_display_stat != 1)
+ power_saving_display_stat = 0;
+ plugin_intf->OEM_sys_set_display_frame_rate(power_saving_display_stat);
+ backlight_restore();
+ break;
+ case SETTING_POWER_SAVING_DISPLAY:
+ vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS, &power_saving_stat);
+ if (power_saving_stat == 1) {
+ if (val == 1)
+ power_saving_display_stat = 1;
+ else
+ power_saving_display_stat = 0;
+ plugin_intf->OEM_sys_set_display_frame_rate(power_saving_display_stat);
+ backlight_restore();
+ }
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static void check_seed_status(void)
+{
+ int ret = -1;
+ int tmp = 0;
+ int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
+ int max_brt = 0;
+ int brt = 0;
+ int lock_state = -1;
+
+ /* Charging check */
+ if ((get_charging_status(&tmp) == 0) && (tmp > 0)) {
+ status_flag |= CHRGR_FLAG;
+ }
+
+ ret = get_setting_brightness(&tmp);
+ if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
+ LOGINFO("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;
+ }
+ LOGINFO("Set brightness from Setting App. %d", tmp);
+ set_default_brt(tmp);
+
+ vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
+ if (bat_state < VCONFKEY_SYSMAN_BAT_NORMAL) {
+ if (!(status_flag & CHRGR_FLAG)) {
+ power_saving_func(true);
+ status_flag |= LOWBT_FLAG;
+ }
+ }
+ backlight_restore();
+
+ /* USB connection check
+ * If connected, add sleep prohibit condition */
+ if ((get_usb_status(&tmp) == 0) && (tmp > 0)) {
+ tmp = readpid(USB_CON_PIDFILE);
+ if (tmp != -1) {
+ add_node(S_SLEEP, tmp, -1, 0);
+ }
+ }
+
+ /* lock screen check */
+ ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
+ if(lock_state == VCONFKEY_IDLE_LOCK) {
+ states[S_NORMAL].timeout = LOCK_SCREEN_TIMEOUT;
+ LOGERR("LCD NORMAL timeout is set by %d seconds for lock screen", LOCK_SCREEN_TIMEOUT);
+ }
+
+ return;
+}
+
+enum {
+ INIT_SETTING = 0,
+ INIT_INTERFACE,
+ INIT_POLL,
+ INIT_FIFO,
+ INIT_END
+};
+
+static 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",
+};
+
+/* logging indev_list for debug */
+void printglist()
+{
+ int i;
+ guint total=0;
+ indev *tmp;
+
+ total=g_list_length(indev_list);
+ LOGINFO("***** total list : %d *****",total);
+ for(i=0;i<total;i++) {
+ tmp=(indev*)(g_list_nth(indev_list, i)->data);
+ LOGINFO("* %d | path:%s, gsource:%d, gfd:%d", i, tmp->dev_path, tmp->dev_src, tmp->dev_fd);
+ if(i==total-1 && g_list_nth(indev_list, i)->next==NULL)
+ LOGINFO("okokok");
+ }
+ LOGINFO("***************************\n");
+}
+
+static GList *find_glist(GList *glist, char *path)
+{
+ int i;
+ guint total=0;
+ indev *tmp;
+
+ total=g_list_length(indev_list);
+ for(i=0;i<total;i++) {
+ tmp=(indev*)(g_list_nth(indev_list, i)->data);
+ if(!strcmp(tmp->dev_path, path)){
+ LOGINFO("nth : %d, path:%s, gsource:%d, gfd:%d", i, tmp->dev_path, tmp->dev_src, tmp->dev_fd);
+ return g_list_nth(indev_list, i);
+ }
+ }
+ return NULL;
+}
+
+static void input_cb(void* data)
+{
+ FILE *fp;
+ char input_act[NAME_MAX], input_path[MAX_INPUT];
+ char args[NAME_MAX + MAX_INPUT];
+ int i, ret = -1;
+ GList *glist = NULL;
+
+ fp = fopen((char *) data, "r");
+ if (fp == NULL) {
+ LOGERR("input file open fail");
+ return ;
+ }
+
+ while (fgets(args, NAME_MAX + MAX_INPUT, fp) != NULL){
+ if( args[strlen(args)-1] != '\n'){
+ LOGERR("input file must be terminated with new line character\n");
+ break;
+ }
+ args[strlen(args) - 1] = '\0';
+ for(i = 0; i< NAME_MAX + MAX_INPUT; i++){
+ if(args[i] == ' '){
+ if( i >= NAME_MAX ){
+ LOGERR("bsfile name is over the name_max(255)\n");
+ break;
+ }
+ strncpy(input_act, args, i < NAME_MAX ? i : NAME_MAX);
+ input_act[i]='\0';
+ strncpy(input_path, args + i + 1, MAX_INPUT);
+ input_path[MAX_INPUT - 1] = '\0';
+
+ if( !strcmp("add", input_act) ){
+ LOGINFO("add input path:%s",input_path);
+
+ ret=init_pm_poll_input(poll_callback, input_path);
+
+ } else if ( !strcmp("remove", input_act) ){
+ glist=find_glist(indev_list, input_path);
+ if(glist != NULL){
+ LOGINFO("remove input dev");
+ g_source_remove_poll(((indev*)(glist->data))->dev_src, ((indev*)(glist->data))->dev_fd);
+ g_source_destroy(((indev*)(glist->data))->dev_src);
+ close(((indev*)(glist->data))->dev_fd->fd);
+ g_free(((indev*)(glist->data))->dev_fd);
+ free(((indev*)(glist->data))->dev_path);
+ indev_list=g_list_remove(indev_list, glist->data);
+ }
+ ret=0;
+ }
+ /* debug */
+ printglist();
+
+ break;
+ }
+ }
+ if(ret<0)
+ break;
+ }
+ fclose(fp);
+
+ if ( ret != -1) {
+ fp = fopen((char *) data, "w");
+ if (fp == NULL) {
+ return ;
+ }
+ fclose(fp);
+ }
+
+ return ;
+}
+
+static int set_noti(int noti_fd)
+{
+ int fd;
+ char buf[PATH_MAX];
+
+ noti_fd = heynoti_init();
+ if (noti_fd < 0) {
+ LOGERR("heynoti_init error");
+ return -1;
+ }
+
+ if (heynoti_subscribe(noti_fd, PM_EVENT_NOTI_NAME, input_cb, PM_EVENT_NOTI_PATH) < 0) {
+ LOGERR("input file change noti add failed(%s). %s", buf, strerror(errno));
+ return -1;
+ } else {
+ LOGERR("input file change noti add ok");
+ }
+
+ if (heynoti_attach_handler(noti_fd) < 0) {
+ LOGERR("heynoti_attach_handler error");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int unset_noti(int noti_fd)
+{
+ if (noti_fd < 0) {
+ LOGINFO("set noti already failed. nothing to do in unset");
+ return 0;
+ }
+
+ if (heynoti_unsubscribe(noti_fd, PM_EVENT_NOTI_NAME, input_cb) < 0 || heynoti_detach_handler(noti_fd) < 0) {
+ LOGERR("heynoti unsubsribe or detach error");
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * Power manager Main loop
+ *
+ * @internal
+ * @param[in] flags If the first bit of this is set, start managing without Start notification.
+ * If the second bit of ths is set, use unified device manager functions.
+ */
+void start_main(unsigned int flags)
+{
+ int ret, i;
+
+ if (0 > _pm_devman_plugin_init()) {
+ LOGERR("Device Manager Plugin initialize failed");
+ exit (-1);
+ }
+
+ LOGINFO("Start power manager daemon");
+
+ signal(SIGHUP, sig_hup);
+ signal(SIGCHLD, SIG_IGN);
+ signal(SIGUSR1, sig_usr);
+ signal(SIGUSR2, sig_quit);
+ signal(SIGALRM, sig_break_block);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ power_saving_func = default_saving_mode;
+
+ /* noti init for new input device like bt mouse */
+ int noti_fd;
+ indev_list=NULL;
+ set_noti(noti_fd);
+
+ for (i = INIT_SETTING; i < INIT_END; i++) {
+ switch (i) {
+ case INIT_SETTING:
+ ret = init_setting(update_setting);
+ break;
+ case INIT_INTERFACE:
+ get_settings();
+ ret = init_sysfs(flags);
+ break;
+ case INIT_POLL:
+ LOGINFO("poll init");
+ ret = init_pm_poll(poll_callback);
+ break;
+ }
+ if (ret != 0) {
+ LOGERR(errMSG[i]);
+ break;
+ }
+ }
+
+ if (i == INIT_END) {
+ check_seed_status();
+
+ if (pm_init_extention != NULL)
+ pm_init_extention(NULL);
+
+ if (flags & WITHOUT_STARTNOTI) { /* start without noti */
+ LOGINFO("Start Power managing without noti");
+ cur_state = S_NORMAL;
+ set_setting_pmstate(cur_state);
+ reset_timeout(states[S_NORMAL].timeout);
+ }
+ if (start_battinfo_gathering(BATTERY_POLLING_PERIOD) < 0)
+ LOGERR("Start Battery time info failed!");
+
+ g_main_loop_run(mainloop);
+ g_main_loop_unref(mainloop);
+ }
+
+ end_battinfo_gathering();
+ 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:
+ unset_noti(noti_fd);
+ exit_pm_poll();
+ break;
+ }
+ }
+
+ if (pm_exit_extention != NULL)
+ pm_exit_extention();
+
+ LOGINFO("Terminate power manager daemon");
+}
+
+/**
+ * @}
+ */
diff --git a/pm_core.h b/pm_core.h
new file mode 100644
index 0000000..8df792a
--- /dev/null
+++ b/pm_core.h
@@ -0,0 +1,104 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 pm_core.h
+ * @author Suchang Woo (suchang.woo@samsung.com)
+ * @modified by Wonil Choi (wonil22.choi@samsung.com)
+ * @version 0.2
+ * @brief Power manager main loop header file
+ */
+#ifndef __POWER_MANAGER_H__
+#define __POWER_MANAGER_H__
+
+#include "util.h"
+#include "pm_poll.h"
+#include "pm_llinterface.h"
+#include "pm_setting.h"
+#include "pm_conf.h"
+
+#define WITHOUT_STARTNOTI 0x1
+#define MASK_BIT 0x7 /* 111 */
+#define MASK_DIM 0x1 /* 001 */
+#define MASK_OFF 0x2 /* 010 */
+#define MASK_SLP 0x4 /* 100 */
+
+#define VCALL_FLAG 0x00000001
+#define LOWBT_FLAG 0x00000100
+#define CHRGR_FLAG 0x00000200
+#define PWRSV_FLAG 0x00000400
+#define BRTCH_FLAG 0x00002000
+
+#define TOLERANCE_SLOT 2
+
+unsigned int status_flag;
+
+/*
+ * State enumeration
+ */
+enum state_t {
+ S_START = 0,
+ S_NORMAL, /*< normal state */
+ S_LCDDIM, /*< LCD dimming */
+ S_LCDOFF, /*< LCD off */
+ S_SLEEP, /*< system suspend */
+ S_END
+};
+
+/*
+ * Global variables
+ * cur_state : current state
+ * states : state definitions
+ * trans_table : state transition table
+ */
+int cur_state;
+int old_state;
+
+/*
+ * @brief State structure
+ */
+struct state {
+ enum state_t state; /**< state number */
+ int (*trans) (int evt); /**< transition function pointer */
+ int (*action) (int timeout); /**< enter action */
+ int (*check) (int next); /**< transition check function */
+ int timeout;
+} states[S_END];
+
+/* If the bit in a condition variable is set,
+ * we cannot transit the state until clear this bit. */
+int trans_condition;
+pid_t idle_pid;
+int (*pm_init_extention) (void *data); /**< extention init function */
+void (*pm_exit_extention) (void); /**< extention exit function */
+int check_processes(enum state_t prohibit_state);
+
+/*
+ * Power manager Main loop
+ *
+ * @internal
+ * @param[in] flags If the first bit of this is set, start managing without Start notification.
+ * If the second bit of ths is set, use unified device manager functions.
+ */
+void start_main(unsigned int flags);
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/pm_device_plugin.c b/pm_device_plugin.c
new file mode 100644
index 0000000..00663d6
--- /dev/null
+++ b/pm_device_plugin.c
@@ -0,0 +1,64 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 <dlfcn.h>
+#include <unistd.h>
+
+#include "util.h"
+#include "pm_device_plugin.h"
+
+static void *dlopen_handle;
+
+int _pm_devman_plugin_init()
+{
+ char *error;
+
+ dlopen_handle = dlopen(DEVMAN_PLUGIN_PATH, RTLD_NOW);
+ if (!dlopen_handle) {
+ LOGERR("dlopen() failed");
+ return -1;
+ }
+
+ const OEM_sys_devman_plugin_interface *(*get_devman_plugin_interface) ();
+ get_devman_plugin_interface = dlsym(dlopen_handle, "OEM_sys_get_devman_plugin_interface");
+ if ((error = dlerror()) != NULL) {
+ LOGERR("dlsym() failed: %s", error);
+ dlclose(dlopen_handle);
+ return -1;
+ }
+
+ plugin_intf = get_devman_plugin_interface();
+ if (!plugin_intf) {
+ LOGERR("get_devman_plugin_interface() failed");
+ dlclose(dlopen_handle);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int _pm_devman_plugin_fini()
+{
+ if (dlopen_handle) {
+ dlclose(dlopen_handle);
+ }
+
+ return 0;
+}
+
+
diff --git a/pm_device_plugin.h b/pm_device_plugin.h
new file mode 100644
index 0000000..1cf1b8e
--- /dev/null
+++ b/pm_device_plugin.h
@@ -0,0 +1,31 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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.
+*/
+
+
+#ifndef __PM_DEVICE_PLUGIN_H__
+#define __PM_DEVICE_PLUGIN_H__
+
+#include "devman_plugin_intf.h"
+
+#define DEVMAN_PLUGIN_PATH "/usr/lib/libslp_devman_plugin.so"
+
+int _pm_devman_plugin_init(void);
+int _pm_devman_plugin_fini(void);
+
+const OEM_sys_devman_plugin_interface *plugin_intf;
+
+#endif /* __PM_DEVICE_PLUGIN_H__ */
diff --git a/pm_event/CMakeLists.txt b/pm_event/CMakeLists.txt
new file mode 100644
index 0000000..2b69259
--- /dev/null
+++ b/pm_event/CMakeLists.txt
@@ -0,0 +1,30 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(pm_event C)
+
+SET(SRCS pm_event.c)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION 0.1.9)
+INCLUDE(FindPkgConfig)
+FOREACH(flag ${deep_pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${deep_pkgs_LDFLAGS})
+
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+ADD_DEFINITIONS("-DDATAFS=\"$ENV{DATADIR}\"")
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
diff --git a/pm_event/pm_event.c b/pm_event/pm_event.c
new file mode 100644
index 0000000..14167af
--- /dev/null
+++ b/pm_event/pm_event.c
@@ -0,0 +1,41 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 <string.h>
+#include <limits.h>
+
+#define PM_EVENT_NOTI_PATH "/opt/share/noti/pm_event"
+
+int main(int argc, char *argv[])
+{
+ if(argc != 3) {
+ return -1;
+ }
+
+ if(strlen(argv[1]) + strlen(argv[2]) > PATH_MAX) {
+ return -1;
+ }
+
+ int i;
+ char buf[PATH_MAX + 25];
+ snprintf(buf, PATH_MAX + 25, "echo %s %s >> %s", argv[1], argv[2], PM_EVENT_NOTI_PATH);
+ system(buf);
+
+ return 1;
+}
diff --git a/pm_key_filter.c b/pm_key_filter.c
new file mode 100644
index 0000000..2e282a9
--- /dev/null
+++ b/pm_key_filter.c
@@ -0,0 +1,301 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 <glib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include <vconf.h>
+#include <sysman.h>
+
+#include "util.h"
+#include "pm_core.h"
+#include "pm_poll.h"
+
+#include <linux/input.h>
+#ifndef KEY_SCREENLOCK
+#define KEY_SCREENLOCK 0x98
+#endif
+
+#define PREDEF_PWROFF_POPUP "pwroff-popup"
+#define PREDEF_LEAVESLEEP "leavesleep"
+#define PREDEF_POWEROFF "poweroff"
+
+#define USEC_PER_SEC 1000000
+#define LONG_PRESS_INTERVAL 1000000 /* 1000 ms */
+#define COMBINATION_INTERVAL 300000 /* 300 ms */
+#define POWER_KEY_PRESS_IGNORE_TIME 700000 /* 700 ms */
+
+#define KEY_RELEASED 0
+#define KEY_PRESSED 1
+#define KEY_BEING_PRESSED 2
+
+#define KEY_COMBINATION_STOP 0
+#define KEY_COMBINATION_START 1
+#define KEY_COMBINATION_SCREENCAPTURE 2
+
+static struct timeval pressed_time;
+static guint longkey_timeout_id = 0;
+static guint combination_timeout_id = 0;
+static int cancel_lcdoff;
+static int key_combination = KEY_COMBINATION_STOP;
+static int powerkey_ignored = false;
+
+void unlock()
+{
+ vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_UNLOCK);
+}
+
+static inline int current_state_in_on()
+{
+ return (cur_state == S_LCDDIM || cur_state == S_NORMAL);
+}
+
+static void longkey_pressed()
+{
+ int rc = -1, val = 0;
+ LOGINFO("Power key long pressed!");
+ cancel_lcdoff = 1;
+
+ rc = vconf_get_int(VCONFKEY_TESTMODE_POWER_OFF_POPUP, &val);
+
+ if (rc < 0 || val != 1) {
+ if (sysman_call_predef_action(PREDEF_PWROFF_POPUP, 0) <
+ 0)
+ LOGERR("poweroff popup exec failed");
+ } else {
+ if (sysman_call_predef_action(PREDEF_POWEROFF, 0) < 0) {
+ LOGERR("poweroff exec failed");
+ system("poweroff");
+ }
+
+ }
+ (*g_pm_callback) (INPUT_POLL_EVENT, NULL);
+}
+
+static gboolean longkey_pressed_cb(gpointer data)
+{
+ longkey_pressed();
+ longkey_timeout_id = 0;
+
+ return FALSE;
+}
+
+static gboolean combination_failed_cb(gpointer data)
+{
+ key_combination = KEY_COMBINATION_STOP;
+ combination_timeout_id = 0;
+
+ return FALSE;
+}
+
+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 void stop_key_combination()
+{
+ key_combination = KEY_COMBINATION_STOP;
+ if (combination_timeout_id > 0) {
+ g_source_remove(combination_timeout_id);
+ combination_timeout_id = 0;
+ }
+}
+
+static int process_power_key(struct input_event *pinput)
+{
+ int ignore = true;
+
+ switch (pinput->value) {
+ case KEY_RELEASED:
+ if (current_state_in_on() && !cancel_lcdoff &&
+ !(key_combination == KEY_COMBINATION_SCREENCAPTURE)) {
+ check_processes(S_LCDOFF);
+ check_processes(S_LCDDIM);
+
+ if (!check_holdkey_block(S_LCDOFF) &&
+ !check_holdkey_block(S_LCDDIM)) {
+ delete_condition(S_LCDOFF);
+ delete_condition(S_LCDDIM);
+ /* LCD off forcly */
+ recv_data.pid = -1;
+ recv_data.cond = 0x400;
+ (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data);
+ }
+ } else {
+ if (!powerkey_ignored)
+ ignore = false;
+ }
+
+ stop_key_combination();
+ cancel_lcdoff = 0;
+ if (longkey_timeout_id > 0) {
+ g_source_remove(longkey_timeout_id);
+ longkey_timeout_id = 0;
+ }
+ break;
+ case KEY_PRESSED:
+ if (timediff_usec(pressed_time, pinput->time) <
+ POWER_KEY_PRESS_IGNORE_TIME) {
+ LOGINFO("power key double pressed ignored");
+ powerkey_ignored = true;
+ break;
+ } else {
+ powerkey_ignored = false;
+ }
+ LOGINFO("power key pressed");
+ pressed_time.tv_sec = (pinput->time).tv_sec;
+ pressed_time.tv_usec = (pinput->time).tv_usec;
+ if (key_combination == KEY_COMBINATION_STOP) {
+ /* add long key timer */
+ longkey_timeout_id = g_timeout_add_full(
+ G_PRIORITY_DEFAULT,
+ LONG_PRESS_INTERVAL / 1000,
+ (GSourceFunc)longkey_pressed_cb,
+ NULL, NULL);
+ key_combination = KEY_COMBINATION_START;
+ combination_timeout_id = g_timeout_add_full(
+ G_PRIORITY_DEFAULT,
+ COMBINATION_INTERVAL / 1000,
+ (GSourceFunc)combination_failed_cb,
+ NULL, NULL);
+ } else if (key_combination == KEY_COMBINATION_START) {
+ if (combination_timeout_id > 0) {
+ g_source_remove(combination_timeout_id);
+ combination_timeout_id = 0;
+ }
+ LOGINFO("capture mode");
+ key_combination = KEY_COMBINATION_SCREENCAPTURE;
+ ignore = false;
+ }
+ break;
+ case KEY_BEING_PRESSED:
+ if (timediff_usec(pressed_time, pinput->time) >
+ LONG_PRESS_INTERVAL)
+ longkey_pressed();
+ break;
+ }
+
+ return ignore;
+}
+
+static int process_volumedown_key(struct input_event *pinput)
+{
+ int ignore = true;
+
+ if (pinput->value == KEY_PRESSED) {
+ if (key_combination == KEY_COMBINATION_STOP) {
+ key_combination = KEY_COMBINATION_START;
+ combination_timeout_id = g_timeout_add_full(
+ G_PRIORITY_DEFAULT,
+ COMBINATION_INTERVAL / 1000,
+ (GSourceFunc)combination_failed_cb,
+ NULL, NULL);
+ } else if (key_combination == KEY_COMBINATION_START) {
+ if (combination_timeout_id > 0) {
+ g_source_remove(combination_timeout_id);
+ combination_timeout_id = 0;
+ }
+ LOGINFO("capture mode");
+ key_combination = KEY_COMBINATION_SCREENCAPTURE;
+ ignore = false;
+ }
+ } else if (pinput->value == KEY_RELEASED) {
+ if (key_combination != KEY_COMBINATION_SCREENCAPTURE) {
+ stop_key_combination();
+ if (current_state_in_on())
+ ignore = false;
+ }
+ }
+
+ return ignore;
+}
+
+static int check_key(struct input_event *pinput)
+{
+ int ignore = true;
+
+ switch (pinput->code) {
+ case KEY_POWER:
+ ignore = process_power_key(pinput);
+ break;
+ case KEY_VOLUMEDOWN:
+ ignore = process_volumedown_key(pinput);
+ break;
+ case KEY_VOLUMEUP:
+ case KEY_CAMERA:
+ case KEY_EXIT:
+ case KEY_PHONE:
+ case KEY_CONFIG:
+ case KEY_SEARCH:
+ stop_key_combination();
+ if (current_state_in_on())
+ ignore = false;
+ break;
+ case KEY_SCREENLOCK:
+ case 0x1DB:
+ case 0x1DC:
+ case 0x1DD:
+ case 0x1DE:
+ stop_key_combination();
+ break;
+ default:
+ stop_key_combination();
+ ignore = false;
+ }
+
+ return ignore;
+}
+
+int check_key_filter(int length, char buf[])
+{
+ struct input_event *pinput;
+ int ignore = true;
+ int idx = 0;
+
+ do {
+ pinput = (struct input_event *)&buf[idx];
+ switch (pinput->type) {
+ case EV_KEY:
+ ignore = check_key(pinput);
+ break;
+ case EV_REL:
+ ignore = false;
+ break;
+ case EV_ABS:
+ if (current_state_in_on())
+ ignore = false;
+ break;
+ }
+
+ idx += sizeof(struct input_event);
+ if (ignore == true && length <= idx)
+ return 1;
+ } while (length > idx);
+
+ return 0;
+}
+
diff --git a/pm_llinterface.c b/pm_llinterface.c
new file mode 100644
index 0000000..df4ffdc
--- /dev/null
+++ b/pm_llinterface.c
@@ -0,0 +1,333 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 "pm_llinterface.h"
+#include "pm_device_plugin.h"
+#include "util.h"
+#include "pm_conf.h"
+#include "vconf.h"
+#include "pm_core.h"
+
+typedef struct _PMSys PMSys;
+struct _PMSys {
+ int def_brt;
+ int dim_brt;
+
+ int (*sys_power_state) (PMSys *, int);
+ int (*bl_onoff) (PMSys *, int);
+ int (*bl_brt) (PMSys *, int);
+ int (*sys_get_battery_capacity) (PMSys *p);
+ int (*sys_get_battery_capacity_raw) (PMSys *p);
+ int (*sys_get_battery_charge_full) (PMSys *p);
+};
+
+static PMSys *pmsys;
+
+#ifdef ENABLE_X_LCD_ONOFF
+#include "pm_x_lcd_onoff.c"
+static bool x_dpms_enable = false;
+#endif
+
+/*
+static void _update_curbrt(PMSys *p)
+{
+ int power_saving_stat = -1;
+ int power_saving_display_stat = -1;
+ vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS, &power_saving_stat);
+ if (power_saving_stat == 1)
+ vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY, &power_saving_display_stat);
+ if (power_saving_display_stat != 1)
+ power_saving_display_stat = 0;
+ plugin_intf->OEM_sys_get_backlight_brightness(DEFAULT_DISPLAY, &(p->def_brt), power_saving_display_stat);
+}
+*/
+
+static int _bl_onoff(PMSys *p, int onoff)
+{
+ return plugin_intf->OEM_sys_set_lcd_power(DEFAULT_DISPLAY, onoff);
+}
+
+static int _bl_brt(PMSys *p, int brightness)
+{
+ int power_saving_stat = -1;
+ int power_saving_display_stat = -1;
+ vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS, &power_saving_stat);
+ if (power_saving_stat == 1)
+ vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY, &power_saving_display_stat);
+ if (power_saving_display_stat != 1)
+ power_saving_display_stat = 0;
+ int ret = plugin_intf->OEM_sys_set_backlight_brightness(DEFAULT_DISPLAY, brightness, power_saving_display_stat);
+LOGERR("set brightness %d,%d(saving %d) %d", DEFAULT_DISPLAY, brightness, power_saving_display_stat, ret);
+ return ret;
+}
+
+static int _sys_power_state(PMSys *p, int state)
+{
+ if (state < POWER_STATE_SUSPEND || state > POWER_STATE_POST_RESUME)
+ return 0;
+ return plugin_intf->OEM_sys_set_power_state(state);
+}
+
+static int _sys_get_battery_capacity(PMSys *p)
+{
+ int value = 0;
+ int ret = -1;
+
+ ret = plugin_intf->OEM_sys_get_battery_capacity(&value);
+
+ if(ret < 0)
+ return -1;
+
+ if(value < 0)
+ return 0;
+
+ return value;
+}
+
+static int _sys_get_battery_capacity_raw(PMSys *p)
+{
+ int value = 0;
+ int ret = -1;
+
+ ret = plugin_intf->OEM_sys_get_battery_capacity_raw(&value);
+
+ if(ret < 0)
+ return -1;
+
+ if(value < 0)
+ return 0;
+
+ return value;
+}
+
+static int _sys_get_battery_charge_full(PMSys *p)
+{
+ int value = 0;
+ int ret = -1;
+
+ ret = plugin_intf->OEM_sys_get_battery_charge_full(&value);
+
+ if(ret < 0)
+ return -1;
+
+ if(value < 0)
+ return 0;
+
+ return value;
+}
+
+static void _init_bldev(PMSys *p, unsigned int flags)
+{
+ int ret;
+ //_update_curbrt(p);
+ p->bl_brt = _bl_brt;
+ p->bl_onoff = _bl_onoff;
+#ifdef ENABLE_X_LCD_ONOFF
+ if (flags & FLAG_X_DPMS) {
+ p->bl_onoff = pm_x_set_lcd_backlight;
+ x_dpms_enable = true;
+ }
+#endif
+}
+
+static void _init_pmsys(PMSys *p)
+{
+ char tmp[NAME_MAX];
+
+ get_env(EN_SYS_DIMBRT, tmp, sizeof(tmp));
+
+ p->dim_brt = atoi(tmp);
+ p->sys_power_state = _sys_power_state;
+ p->sys_get_battery_capacity = _sys_get_battery_capacity;
+ p->sys_get_battery_capacity_raw = _sys_get_battery_capacity_raw;
+ p->sys_get_battery_charge_full = _sys_get_battery_charge_full;
+}
+
+int system_suspend()
+{
+ LOGINFO("enter system suspend");
+ if (pmsys && pmsys->sys_power_state)
+ return pmsys->sys_power_state(pmsys, POWER_STATE_SUSPEND);
+
+ return 0;
+}
+
+int system_pre_suspend()
+{
+ LOGINFO("enter system pre suspend");
+ if (pmsys && pmsys->sys_power_state)
+ return pmsys->sys_power_state(pmsys, POWER_STATE_PRE_SUSPEND);
+
+ return 0;
+}
+
+int system_post_resume()
+{
+ LOGINFO("enter system post resume");
+ if (pmsys && pmsys->sys_power_state)
+ return pmsys->sys_power_state(pmsys, POWER_STATE_POST_RESUME);
+
+ return 0;
+}
+
+int battery_capacity()
+{
+ if (pmsys && pmsys->sys_get_battery_capacity)
+ return pmsys->sys_get_battery_capacity(pmsys);
+
+ return 0;
+}
+
+int battery_capacity_raw()
+{
+ if (pmsys && pmsys->sys_get_battery_capacity_raw)
+ return pmsys->sys_get_battery_capacity_raw(pmsys);
+
+ return 0;
+}
+
+int battery_charge_full()
+{
+ if (pmsys && pmsys->sys_get_battery_charge_full)
+ return pmsys->sys_get_battery_charge_full(pmsys);
+
+ return 0;
+}
+
+int backlight_on()
+{
+ LOGINFO("LCD on");
+
+ if (pmsys && pmsys->bl_onoff) {
+ return pmsys->bl_onoff(pmsys, STATUS_ON);
+ }
+
+ return 0;
+}
+
+int backlight_off()
+{
+ LOGINFO("LCD off");
+
+ if (pmsys && pmsys->bl_onoff) {
+#ifdef ENABLE_X_LCD_ONOFF
+ if (x_dpms_enable == false)
+#endif
+ usleep(30000);
+ return pmsys->bl_onoff(pmsys, STATUS_OFF);
+ }
+
+ return 0;
+}
+
+int backlight_dim()
+{
+ int ret = 0;
+ if (pmsys && pmsys->bl_brt) {
+ ret = pmsys->bl_brt(pmsys, pmsys->dim_brt);
+ }
+ return ret;
+}
+
+int backlight_restore()
+{
+ int ret = 0;
+ int val = -1;
+
+ ret = vconf_get_int(VCONFKEY_PM_CUSTOM_BRIGHTNESS_STATUS, &val);
+ if (ret == 0 && val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON) {
+ LOGINFO("custom brightness mode! brt no restored");
+ return 0;
+ }
+ if ((status_flag & PWRSV_FLAG) && !(status_flag & BRTCH_FLAG))
+ ret = backlight_dim();
+ else if (pmsys && pmsys->bl_brt)
+ ret = pmsys->bl_brt(pmsys, pmsys->def_brt);
+
+ return ret;
+}
+
+int set_default_brt(int level)
+{
+ if (level < PM_MIN_BRIGHTNESS || level > PM_MAX_BRIGHTNESS)
+ level = PM_DEFAULT_BRIGHTNESS;
+ pmsys->def_brt = level;
+
+ return 0;
+}
+
+inline int check_wakeup_src(void)
+{
+ /* TODO if nedded.
+ * return wackeup source. user input or device interrupts? (EVENT_DEVICE or EVENT_INPUT)
+ */
+ return EVENT_DEVICE;
+}
+
+int init_sysfs(unsigned int flags)
+{
+ int ret;
+
+ pmsys = (PMSys *) malloc(sizeof(PMSys));
+ if (pmsys == NULL) {
+ LOGERR("Not enough memory to alloc PM Sys");
+ return -1;
+ }
+
+ memset(pmsys, 0x0, sizeof(PMSys));
+
+ _init_pmsys(pmsys);
+ _init_bldev(pmsys, flags);
+
+ if (pmsys->bl_onoff == NULL && pmsys->sys_power_state == NULL) {
+ LOGERR
+ ("We have no managable resource to reduce the power consumption");
+ return -1;
+ }
+
+ return 0;
+}
+
+int exit_sysfs()
+{
+ int fd = -1;
+
+ fd = open("/tmp/sem.pixmap_1", O_RDONLY);
+ if (fd == -1) {
+ LOGERR("X server disable");
+ backlight_on();
+ }
+
+ backlight_restore();
+ free(pmsys);
+ pmsys = NULL;
+ if (fd != -1)
+ close(fd);
+
+ return 0;
+}
diff --git a/pm_llinterface.h b/pm_llinterface.h
new file mode 100644
index 0000000..83b00d6
--- /dev/null
+++ b/pm_llinterface.h
@@ -0,0 +1,65 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 pm_llinterface.h
+ * @author Suchang Woo (suchang.woo@samsung.com)
+ * @version 0.1
+ * @brief Power manager low-level interface module header
+ */
+#ifndef __PM_LLINTERFACE_H__
+#define __PM_LLINTERFACE_H__
+
+#define FLAG_X_DPMS 0x2
+
+#define DEFAULT_DISPLAY 0
+
+#define PM_MAX_BRIGHTNESS 100
+#define PM_MIN_BRIGHTNESS 1
+#ifdef TIZEN_EMUL
+# define PM_DEFAULT_BRIGHTNESS 100
+#else
+# define PM_DEFAULT_BRIGHTNESS 60
+#endif
+
+/*
+ * Event type enumeration
+ */
+enum {
+ EVENT_TIMEOUT = 0, /*< time out event from timer */
+ EVENT_DEVICE = EVENT_TIMEOUT, /*< wake up by devices except input devices */
+ EVENT_INPUT, /*< input event from noti service */
+ EVENT_END,
+};
+
+extern int init_sysfs(unsigned int);
+extern int exit_sysfs(void);
+
+extern int system_suspend(void);
+
+extern int backlight_on(void);
+extern int backlight_off(void);
+
+extern int backlight_dim(void);
+extern int backlight_restore(void);
+
+extern int set_default_brt(int level);
+
+extern int check_wakeup_src(void);
+
+#endif
diff --git a/pm_lsensor.c b/pm_lsensor.c
new file mode 100644
index 0000000..71d6ddb
--- /dev/null
+++ b/pm_lsensor.c
@@ -0,0 +1,286 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 <limits.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <glib.h>
+#include <vconf.h>
+#include <sensor.h>
+
+#include "pm_core.h"
+#include "pm_device_plugin.h"
+
+#define SAMPLING_INTERVAL 1 /* 1 sec */
+#define MAX_FAULT 5
+
+static int (*prev_init_extention) (void *data);
+static int (*_default_action) (int);
+static int alc_timeout_id = 0;
+static int sf_handle = -1;
+static int fault_count = 0;
+
+static gboolean alc_handler(gpointer data)
+{
+ int value = 0;
+ static int cur_index = 1;
+ static int old_index = 1;
+
+ sensor_data_t light_data;
+ if (cur_state != S_NORMAL){
+ if (alc_timeout_id != 0)
+ g_source_remove(alc_timeout_id);
+ alc_timeout_id = 0;
+ } else {
+ if (sf_get_data(sf_handle, LIGHT_BASE_DATA_SET, &light_data) < 0) {
+ fault_count++;
+ } else {
+ if (light_data.values[0] < 0.0 || light_data.values[0] > 10.0) {
+ LOGINFO("fail to load light data : %d", (int)light_data.values[0]);
+ fault_count++;
+ } else {
+ int tmp_value;
+ int power_saving_stat = -1;
+ int power_saving_display_stat = -1;
+ vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS, &power_saving_stat);
+ if (power_saving_stat == 1)
+ vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY, &power_saving_display_stat);
+ if (power_saving_display_stat != 1)
+ power_saving_display_stat = 0;
+ value = PM_MAX_BRIGHTNESS * (int)light_data.values[0] / 10;
+ plugin_intf->OEM_sys_get_backlight_brightness(DEFAULT_DISPLAY, &tmp_value, power_saving_display_stat);
+ if (tmp_value != value) {
+ set_default_brt(value);
+ backlight_restore();
+ }
+ LOGINFO("load light data : %d, brightness : %d", (int)light_data.values[0], value);
+ }
+ }
+ }
+
+ if (fault_count > MAX_FAULT) {
+ if (alc_timeout_id != 0)
+ g_source_remove(alc_timeout_id);
+ alc_timeout_id = 0;
+ vconf_set_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, SETTING_BRIGHTNESS_AUTOMATIC_OFF);
+ LOGERR("Fault counts is over 5, disable automatic brightness");
+ return FALSE;
+ }
+
+ if (alc_timeout_id != 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+static int alc_action(int timeout)
+{
+ LOGINFO("alc action");
+ /* sampling timer add */
+ if (alc_timeout_id == 0 && !(status_flag & PWRSV_FLAG))
+ alc_timeout_id =
+ g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
+ SAMPLING_INTERVAL,
+ (GSourceFunc) alc_handler, NULL,
+ NULL);
+
+ if (_default_action != NULL)
+ return _default_action(timeout);
+
+ /* unreachable code */
+ return -1;
+}
+
+static int connect_sfsvc()
+{
+ int sf_state = -1;
+ /* connect with sensor fw */
+ LOGINFO("connect with sensor fw");
+ sf_handle = sf_connect(LIGHT_SENSOR);
+ if (sf_handle < 0) {
+ LOGERR("sensor attach fail");
+ return -1;
+ }
+ sf_state = sf_start(sf_handle, 0);
+ if (sf_state < 0) {
+ LOGERR("sensor attach fail");
+ sf_disconnect(sf_handle);
+ sf_handle = -1;
+ return -2;
+ }
+ fault_count = 0;
+ return 0;
+}
+
+static int disconnect_sfsvc()
+{
+ LOGINFO("disconnect with sensor fw");
+ if(sf_handle >= 0)
+ {
+ sf_stop(sf_handle);
+ sf_disconnect(sf_handle);
+ sf_handle = -1;
+ }
+
+ 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;
+}
+
+static inline void set_brtch_state()
+{
+ if (status_flag & PWRSV_FLAG) {
+ status_flag |= BRTCH_FLAG;
+ vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
+ LOGINFO("brightness changed in low battery,"
+ "escape dim state (light)");
+ }
+}
+
+static int set_alc_function(keynode_t *key_nodes, void *data)
+{
+ int onoff = 0;
+ int ret = -1;
+ int brt = -1;
+ int default_brt = -1;
+ int max_brt = -1;
+
+ if (key_nodes == NULL) {
+ LOGERR("wrong parameter, key_nodes is null");
+ return -1;
+ }
+
+ onoff = vconf_keynode_get_int(key_nodes);
+
+ if (onoff == SETTING_BRIGHTNESS_AUTOMATIC_ON) {
+ if(connect_sfsvc() < 0)
+ return -1;
+ /* escape dim state if it's in low battery.*/
+ set_brtch_state();
+
+ /* change alc action func */
+ if (_default_action == NULL)
+ _default_action = states[S_NORMAL].action;
+ states[S_NORMAL].action = alc_action;
+ alc_timeout_id =
+ g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
+ SAMPLING_INTERVAL,
+ (GSourceFunc) alc_handler, NULL,
+ NULL);
+ } else if (onoff == SETTING_BRIGHTNESS_AUTOMATIC_PAUSE) {
+ LOGINFO("auto brightness paused!");
+ disconnect_sfsvc();
+ } else {
+ disconnect_sfsvc();
+ /* escape dim state if it's in low battery.*/
+ set_brtch_state();
+
+ ret = get_setting_brightness(&default_brt);
+ if (ret != 0 || (default_brt < PM_MIN_BRIGHTNESS || default_brt > PM_MAX_BRIGHTNESS)) {
+ LOGINFO("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;
+ }
+
+ set_default_brt(default_brt);
+ backlight_restore();
+ }
+
+ return 0;
+}
+
+static gboolean check_sfsvc(gpointer data)
+{
+ /* this function will return opposite value for re-callback in fail */
+ int vconf_auto;
+ int sf_state = 0;
+
+ LOGINFO("register sfsvc");
+
+ vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &vconf_auto);
+ if (vconf_auto == SETTING_BRIGHTNESS_AUTOMATIC_ON) {
+ if(connect_sfsvc() < 0)
+ return TRUE;
+
+ /* change alc action func */
+ if (_default_action == NULL)
+ _default_action = states[S_NORMAL].action;
+ states[S_NORMAL].action = alc_action;
+ alc_timeout_id =
+ g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
+ SAMPLING_INTERVAL,
+ (GSourceFunc) alc_handler, NULL,
+ NULL);
+ if (alc_timeout_id != 0)
+ return FALSE;
+ disconnect_sfsvc();
+ return TRUE;
+ }
+ LOGINFO("change vconf value before registering sfsvc");
+ return FALSE;
+}
+
+static int prepare_lsensor(void *data)
+{
+ int alc_conf;
+ int sf_state = 0;
+
+ vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &alc_conf);
+
+ if (alc_conf == SETTING_BRIGHTNESS_AUTOMATIC_ON) {
+ g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
+ SAMPLING_INTERVAL,
+ (GSourceFunc) check_sfsvc, NULL,
+ NULL);
+ }
+
+ /* add auto_brt_setting change handler */
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT,
+ (void *)set_alc_function, NULL);
+
+ if (prev_init_extention != NULL)
+ return prev_init_extention(data);
+
+ return 0;
+}
+
+static void __attribute__ ((constructor)) pm_lsensor_init()
+{
+ _default_action = NULL;
+ if (pm_init_extention != NULL)
+ prev_init_extention = pm_init_extention;
+ pm_init_extention = prepare_lsensor;
+}
+
+static void __attribute__ ((destructor)) pm_lsensor_fini()
+{
+
+}
diff --git a/pm_poll.c b/pm_poll.c
new file mode 100644
index 0000000..c91ca4d
--- /dev/null
+++ b/pm_poll.c
@@ -0,0 +1,301 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 pm_poll.c
+ * @version 0.2
+ * @brief Power Manager poll implementation (input devices & a domain socket file)
+ *
+ * This file includes the input device poll implementation.
+ * Default input devices are /dev/event0 and /dev/event1
+ * User can use "PM_INPUT" for setting another input device poll in an environment file (/etc/profile).
+ * (ex: PM_INPUT=/dev/event0:/dev/event1:/dev/event5 )
+ */
+
+#include <glib.h>
+#include <stdio.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "util.h"
+#include "pm_core.h"
+#include "pm_poll.h"
+
+#define DEV_PATH_DLM ":"
+
+PMMsg recv_data;
+int (*g_pm_callback) (int, PMMsg *);
+
+#ifdef ENABLE_KEY_FILTER
+extern int check_key_filter(int length, char buf[]);
+# define CHECK_KEY_FILTER(a, b) do {\
+ if (check_key_filter(a, b) != 0)\
+ return TRUE;\
+ } while (0);
+
+#else
+# define CHECK_KEY_FILTER(a, b)
+#endif
+
+#define DEFAULT_DEV_PATH "/dev/event1:/dev/event0"
+
+static GSource *src;
+static GSourceFuncs *funcs;
+static int sockfd;
+
+static gboolean pm_check(GSource *src)
+{
+ GSList *fd_list;
+ GPollFD *tmp;
+
+ fd_list = src->poll_fds;
+ do {
+ tmp = (GPollFD *) fd_list->data;
+ if ((tmp->revents & (POLLIN | POLLPRI)))
+ return TRUE;
+ fd_list = fd_list->next;
+ } while (fd_list);
+
+ return FALSE;
+}
+
+static gboolean pm_dispatch(GSource *src, GSourceFunc callback, gpointer data)
+{
+ callback(data);
+ return TRUE;
+}
+
+static gboolean pm_prepare(GSource *src, gint *timeout)
+{
+ return FALSE;
+}
+
+gboolean pm_handler(gpointer data)
+{
+ char buf[1024];
+ struct sockaddr_un clientaddr;
+
+ GPollFD *gpollfd = (GPollFD *) data;
+ int ret;
+ int clilen = sizeof(clientaddr);
+
+ if (g_pm_callback == NULL) {
+ return FALSE;
+ }
+ if (gpollfd->fd == sockfd) {
+ ret =
+ recvfrom(gpollfd->fd, &recv_data, sizeof(recv_data), 0,
+ (struct sockaddr *)&clientaddr,
+ (socklen_t *)&clilen);
+ (*g_pm_callback) (PM_CONTROL_EVENT, &recv_data);
+ } else {
+ ret = read(gpollfd->fd, buf, sizeof(buf));
+ CHECK_KEY_FILTER(ret, buf);
+ (*g_pm_callback) (INPUT_POLL_EVENT, NULL);
+ }
+
+ return TRUE;
+}
+
+static int init_sock(char *sock_path)
+{
+ struct sockaddr_un serveraddr;
+ int fd;
+
+ LOGINFO("initialize pm_socket for pm_control library");
+
+ if (sock_path == NULL || strcmp(sock_path, SOCK_PATH)) {
+ LOGERR("invalid sock_path= %s");
+ return -1;
+ }
+
+ fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ LOGERR("socket error");
+ return -1;
+ }
+
+ unlink(sock_path);
+
+ bzero(&serveraddr, sizeof(serveraddr));
+ serveraddr.sun_family = AF_UNIX;
+ strncpy(serveraddr.sun_path, sock_path, sizeof(serveraddr.sun_path) - 1);
+
+ if (bind(fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
+ LOGERR("bind error");
+ close(fd);
+ return -1;
+ }
+
+ if (chmod(sock_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) /* 0777 */
+ LOGERR("failed to change the socket permission");
+
+ if (!strcmp(sock_path, SOCK_PATH))
+ sockfd = fd;
+
+ LOGINFO("init sock() sueccess!");
+ return fd;
+}
+
+int init_pm_poll(int (*pm_callback) (int, PMMsg *))
+{
+
+ guint ret;
+ char *dev_paths, *path_tok, *pm_input_env, *save_ptr;
+ int dev_paths_size;
+
+ GPollFD *gpollfd;
+
+ g_pm_callback = pm_callback;
+
+ LOGINFO
+ ("initialize pm poll - input devices and domain socket(libpmapi)");
+
+ pm_input_env = getenv("PM_INPUT");
+ if ((pm_input_env != NULL) && (strlen(pm_input_env) < 1024)) {
+ LOGINFO("Getting input device path from environment: %s",
+ pm_input_env);
+ /* Add 2 bytes for following strncat() */
+ dev_paths_size = strlen(pm_input_env) + strlen(SOCK_PATH) + strlen(DEV_PATH_DLM) + 1;
+ dev_paths = (char *)malloc(dev_paths_size);
+ snprintf(dev_paths, dev_paths_size, "%s", pm_input_env);
+ } else {
+ /* Add 2 bytes for following strncat() */
+ dev_paths_size = strlen(DEFAULT_DEV_PATH) + strlen(SOCK_PATH) + strlen(DEV_PATH_DLM) + 1;
+ dev_paths = (char *)malloc(dev_paths_size);
+ snprintf(dev_paths, dev_paths_size, "%s", DEFAULT_DEV_PATH);
+ }
+
+ /* add the UNIX domain socket file path */
+ strncat(dev_paths, DEV_PATH_DLM, strlen(DEV_PATH_DLM));
+ strncat(dev_paths, SOCK_PATH, strlen(SOCK_PATH));
+ dev_paths[dev_paths_size - 1] = '\0';
+
+ path_tok = strtok_r(dev_paths, DEV_PATH_DLM, &save_ptr);
+ if (path_tok == NULL) {
+ LOGERR("Device Path Tokeninzing Failed");
+ free(dev_paths);
+ return -1;
+ }
+
+ funcs = (GSourceFuncs *) g_malloc(sizeof(GSourceFuncs));
+ funcs->prepare = pm_prepare;
+ funcs->check = pm_check;
+ funcs->dispatch = pm_dispatch;
+ funcs->finalize = NULL;
+
+ do {
+ src = g_source_new(funcs, sizeof(GSource));
+
+ gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
+ gpollfd->events = POLLIN;
+
+ if (strcmp(path_tok, SOCK_PATH) == 0) {
+ gpollfd->fd = init_sock(SOCK_PATH);
+ LOGINFO("pm_poll domain socket file: %s, fd: %d",
+ path_tok, gpollfd->fd);
+ } else {
+ gpollfd->fd = open(path_tok, O_RDONLY);
+ LOGINFO("pm_poll input device file: %s, fd: %d",
+ path_tok, gpollfd->fd);
+ }
+
+ if (gpollfd->fd == -1) {
+ LOGERR("Cannot open the file: %s", path_tok);
+ free(dev_paths);
+ return -1;
+ }
+ g_source_add_poll(src, gpollfd);
+ g_source_set_callback(src, (GSourceFunc) pm_handler,
+ (gpointer) gpollfd, NULL);
+
+ g_source_set_priority(src, G_PRIORITY_LOW);
+ ret = g_source_attach(src, NULL);
+ if (ret == 0) {
+ LOGERR("Failed g_source_attach() in init_pm_poll()");
+ free(dev_paths);
+ return -1;
+ }
+ g_source_unref(src);
+
+ } while ((path_tok = strtok_r(NULL, DEV_PATH_DLM, &save_ptr)));
+
+ free(dev_paths);
+ return 0;
+}
+
+int exit_pm_poll()
+{
+ g_free(funcs);
+ close(sockfd);
+ unlink(SOCK_PATH);
+ LOGINFO("pm_poll is finished");
+ return 0;
+}
+
+int init_pm_poll_input(int (*pm_callback)(int , PMMsg * ), const char *path)
+{
+ guint ret;
+ indev *adddev = NULL;
+
+ g_pm_callback = pm_callback;
+
+ GPollFD *gpollfd;
+ const char *devpath;
+ GSource *devsrc;
+
+ LOGINFO("initialize pm poll for bt %s",path);
+ adddev=(indev *)malloc(sizeof(indev));
+ adddev->dev_fd = (GPollFD *)g_malloc(sizeof(GPollFD));
+ (adddev->dev_fd)->events = POLLIN;
+ (adddev->dev_fd)->fd = open(path, O_RDONLY);
+ if((adddev->dev_fd)->fd == -1) {
+ LOGERR("Cannot open the file for BT: %s",path);
+ g_free(adddev->dev_fd);
+ free(adddev);
+ return -1;
+ }
+ adddev->dev_path = (char *)malloc(strlen(path) + 1);
+ strncpy(adddev->dev_path, path, strlen(path) + 1);
+ adddev->dev_src = g_source_new(funcs, sizeof(GSource));
+ LOGINFO("pm_poll for BT input device file(path: %s, gsource: %d, gpollfd: %d", adddev->dev_path, adddev->dev_src, adddev->dev_fd);
+ indev_list=g_list_append(indev_list, adddev);
+
+ g_source_add_poll(adddev->dev_src, adddev->dev_fd);
+
+ g_source_set_callback(adddev->dev_src, (GSourceFunc) pm_handler, (gpointer)adddev->dev_fd, NULL);
+
+
+ g_source_set_priority(adddev->dev_src, G_PRIORITY_LOW );
+
+ ret = g_source_attach(adddev->dev_src, NULL);
+ if(ret == 0)
+ {
+ LOGERR("Failed g_source_attach() in init_pm_poll()");
+ return -1;
+ }
+ g_source_unref(adddev->dev_src);
+ return 0;
+}
diff --git a/pm_poll.h b/pm_poll.h
new file mode 100644
index 0000000..d1fb454
--- /dev/null
+++ b/pm_poll.h
@@ -0,0 +1,74 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 pm_poll.h
+ * @version 0.2
+ * @brief Power Manager input device poll implementation
+ *
+ * This file includes the input device poll implementation.
+ * Default input devices are /dev/event0 and /dev/event1
+ * User can use "PM_INPUT_DEV" for setting another input device poll in an environment file (/etc/profile).
+ * (ex: PM_INPUT_DEV=/dev/event0:/dev/event1:/dev/event5 )
+ */
+
+#ifndef __PM_POLL_H__
+#define __PM_POLL_H__
+
+#include<glib.h>
+
+/**
+ * @addtogroup POWER_MANAGER
+ * @{
+ */
+
+enum {
+ INPUT_POLL_EVENT = -9,
+ SIDEKEY_POLL_EVENT,
+ PWRKEY_POLL_EVENT,
+ PM_CONTROL_EVENT,
+};
+
+#define SOCK_PATH "/tmp/pm_sock"
+
+typedef struct {
+ pid_t pid;
+ unsigned int cond;
+ unsigned int timeout;
+} PMMsg;
+
+typedef struct {
+ char *dev_path;
+ GSource *dev_src;
+ GPollFD *dev_fd;
+} indev;
+
+GList *indev_list;
+
+PMMsg recv_data;
+int (*g_pm_callback) (int, PMMsg *);
+
+extern int init_pm_poll(int (*pm_callback) (int, PMMsg *));
+extern int exit_pm_poll();
+extern int init_pm_poll_input(int (*pm_callback)(int , PMMsg * ), const char *path);
+
+/**
+ * @}
+ */
+
+#endif /*__PM_POLL_H__ */
diff --git a/pm_setting.c b/pm_setting.c
new file mode 100644
index 0000000..c552edb
--- /dev/null
+++ b/pm_setting.c
@@ -0,0 +1,146 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 "pm_setting.h"
+#include "pm_conf.h"
+#include "util.h"
+
+static const char *setting_keys[SETTING_GET_END] = {
+ [SETTING_TO_NORMAL] = VCONFKEY_SETAPPL_LCD_TIMEOUT_NORMAL,
+ [SETTING_LOW_BATT] = VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
+ [SETTING_CHARGING] = VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
+ [SETTING_BRT_LEVEL] = VCONFKEY_SETAPPL_LCD_BRIGHTNESS,
+ [SETTING_LOCK_SCREEN] = VCONFKEY_IDLE_LOCK_STATE,
+ [SETTING_POWER_SAVING] = VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS,
+ [SETTING_POWER_SAVING_DISPLAY] = VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY,
+};
+
+static int (*update_setting) (int key_idx, int val);
+
+int get_charging_status(int *val)
+{
+ return vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, val);
+}
+
+int get_lowbatt_status(int *val)
+{
+ return vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, val);
+}
+
+int get_usb_status(int *val)
+{
+ return vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, val);
+}
+
+int set_setting_pmstate(int val)
+{
+ return vconf_set_int(VCONFKEY_PM_STATE, val);
+}
+
+int get_setting_brightness(int *level)
+{
+ return vconf_get_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, level);
+}
+
+int get_run_timeout(int *timeout)
+{
+ int dim_timeout = -1, vconf_timeout = -1, ret;
+ get_dim_timeout(&dim_timeout);
+
+ if(dim_timeout < 0) {
+ LOGERR("Can not get dim timeout. set default 5 seconds");
+ dim_timeout = 5;
+ }
+
+ ret = vconf_get_int(setting_keys[SETTING_TO_NORMAL], &vconf_timeout);
+
+ if(vconf_timeout == 0)
+ *timeout = 0; //timeout 0 : Always ON (Do not apply dim_timeout)
+ else
+ *timeout = vconf_timeout - dim_timeout;
+ return ret;
+
+}
+
+int get_dim_timeout(int *timeout)
+{
+ char buf[255];
+ /* TODO if needed */
+ *timeout = 5; /* default timeout */
+ get_env("PM_TO_LCDDIM", buf, sizeof(buf));
+ LOGINFO("Get lcddim timeout [%s]", buf);
+ *timeout = atoi(buf);
+ return 0;
+}
+
+int get_off_timeout(int *timeout)
+{
+ char buf[255];
+ /* TODO if needed */
+ *timeout = 5; /* default timeout */
+ get_env("PM_TO_LCDOFF", buf, sizeof(buf));
+ LOGINFO("Get lcdoff timeout [%s]", buf);
+ *timeout = atoi(buf);
+ return 0;
+}
+
+static int setting_cb(keynode_t *key_nodes, void *data)
+{
+ keynode_t *tmp = key_nodes;
+
+ if ((int)data > SETTING_END) {
+ LOGERR("Unknown setting key: %s, idx= %d",
+ vconf_keynode_get_name, (int)data);
+ return -1;
+ }
+ if (update_setting != NULL) {
+ if ((int)data >= SETTING_POWER_SAVING)
+ update_setting((int)data, vconf_keynode_get_bool(tmp));
+ else
+ update_setting((int)data, vconf_keynode_get_int(tmp));
+ }
+
+ return 0;
+}
+
+int init_setting(int (*func) (int key_idx, int val))
+{
+ int i;
+
+ if (func != NULL)
+ update_setting = func;
+
+ for (i = SETTING_BEGIN; i < SETTING_GET_END; i++) {
+ vconf_notify_key_changed(setting_keys[i], (void *)setting_cb,
+ (void *)i);
+ }
+
+ return 0;
+}
+
+int exit_setting()
+{
+ int i;
+ for (i = SETTING_BEGIN; i < SETTING_GET_END; i++) {
+ vconf_ignore_key_changed(setting_keys[i], (void *)setting_cb);
+ }
+
+ return 0;
+}
diff --git a/pm_setting.h b/pm_setting.h
new file mode 100644
index 0000000..bf2b8e2
--- /dev/null
+++ b/pm_setting.h
@@ -0,0 +1,131 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 pm_setting.h
+ * @version 0.1
+ * @brief Power manager setting module header
+ */
+#ifndef __PM_SETTING_H__
+#define __PM_SETTING_H__
+
+#include <vconf.h>
+
+/*
+ * @addtogroup POWER_MANAGER
+ * @{
+ */
+
+enum {
+ SETTING_BEGIN = 0,
+ SETTING_TO_NORMAL = SETTING_BEGIN,
+ SETTING_LOW_BATT,
+ SETTING_CHARGING,
+ SETTING_BRT_LEVEL,
+ SETTING_LOCK_SCREEN,
+ SETTING_POWER_SAVING,
+ SETTING_POWER_SAVING_DISPLAY,
+ SETTING_GET_END,
+ SETTING_PM_STATE = SETTING_GET_END,
+ SETTING_END
+};
+
+extern int get_setting_brightness();
+
+/*
+ * @brief setting initialization function
+ *
+ * get the variables if it exists. otherwise, set the default.
+ * and register some callback functions.
+ *
+ * @internal
+ * @param[in] func configuration change callback function
+ * @return 0 : success, -1 : error
+ */
+extern int init_setting(int (*func) (int key_idx, int val));
+
+extern int exit_setting();
+
+/*
+ * get normal state timeout from SLP-setting SLP_SETTING_LCD_TIMEOUT_NORMAL
+ *
+ * @internal
+ * @param[out] timeout timeout variable pointer
+ * @return 0 : success, -1 : error
+ */
+extern int get_run_timeout(int *timeout);
+
+/*
+ * get LCD dim state timeout from environment variable.
+ *
+ * @internal
+ * @param[out] timeout timeout variable pointer
+ * @return 0 : success, -1 : error
+ */
+extern int get_dim_timeout(int *timeout);
+
+/*
+ * get LCD off state timeout from environment variable.
+ *
+ * @internal
+ * @param[out] timeout timeout variable pointer
+ * @return 0 : success, -1 : error
+ */
+extern int get_off_timeout(int *timeout);
+
+/*
+ * get USB connection status from SLP-setting SLP_SETTING_USB_STATUS
+ *
+ * @internal
+ * @param[out] val usb connection status variable pointer, 0 is disconnected, others is connected.
+ * @return 0 : success, -1 : error
+ */
+extern int get_usb_status(int *val);
+
+/*
+ * set Current power manager state at SLP-setting "memory/pwrmgr/state"
+ *
+ * @internal
+ * @param[in] val current power manager state.
+ * @return 0 : success, -1 : error
+ */
+extern int set_setting_pmstate(int val);
+
+/*
+ * get charging status at SLP-setting "memory/Battery/Charger"
+ *
+ * @internal
+ * @param[in] val charging or not (1 or 0 respectively).
+ * @return 0 : success, -1 : error
+ */
+extern int get_charging_status(int *val);
+
+/*
+ * get current battery low status at SLP-setting "memory/Battery/Status/Low"
+ *
+ * @internal
+ * @param[in] val current low battery status
+ * @return 0 : success, -1 : error
+ */
+extern int get_lowbatt_status(int *val);
+
+/*
+ * @}
+ */
+
+#endif
diff --git a/pm_x_lcd_onoff.c b/pm_x_lcd_onoff.c
new file mode 100644
index 0000000..01200ae
--- /dev/null
+++ b/pm_x_lcd_onoff.c
@@ -0,0 +1,67 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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.
+*/
+
+
+#ifndef __PM_X_LCD_ONOFF_C__
+#define __PM_X_LCD_ONOFF_C__
+
+#include <string.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+#include "pm_device_plugin.h"
+
+#define CMD_ON "on"
+#define CMD_OFF "off"
+
+static int pm_x_set_lcd_backlight(struct _PMSys *p, int onoff)
+{
+ pid_t pid;
+ char cmd_line[32];
+ int ret;
+
+ LOGINFO("Backlight onoff=%d", onoff);
+ if (onoff == STATUS_ON)
+ snprintf(cmd_line, sizeof(cmd_line), "%s", CMD_ON);
+ else
+ snprintf(cmd_line, sizeof(cmd_line), "%s", CMD_OFF);
+
+ signal(SIGCHLD, SIG_DFL);
+ pid = vfork();
+
+ if (pid < 0) {
+ LOGERR("[1] Failed to fork child process for LCD On/Off");
+ return -1;
+ }
+
+ if (pid == 0) {
+ LOGINFO("[1] Child proccess for LCD %s was created (%s)",
+ ((onoff == STATUS_ON) ? "ON" : "OFF"), cmd_line);
+ execl("/usr/bin/xset", "/usr/bin/xset", "dpms", "force",
+ cmd_line, NULL);
+ _exit(0);
+ } else if (pid != (ret = waitpid(pid, NULL, 0))) {
+ LOGERR
+ ("[1] Waiting failed for the child process pid: %d, ret: %d, errno: %d",
+ pid, ret, errno);
+ }
+
+ signal(SIGCHLD, SIG_IGN);
+ return 0;
+}
+
+#endif /*__PM_X_LCD_ONOFF_C__ */
diff --git a/pmctrl.in b/pmctrl.in
new file mode 100644
index 0000000..e6d8b5d
--- /dev/null
+++ b/pmctrl.in
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+KERNVER=`uname -r`
+
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib
+export PATH=$PATH:/usr/bin
+export ELM_FONT_PATH=@PREFIX@/share/SLP/fonts:@PREFIX@/share/SLP/licensed_fonts:@PREFIX@/share/fonts/truetype/ttf-bitstream-vera
+export PM_EXEC_PRG=@PREFIX@/bin/@IDLE_LOCK@
+
+export PM_TO_NORMAL=600 # normal state timeout seconds
+export PM_TO_LCDDIM=5 # dim state timeout seconds
+export PM_TO_LCDOFF=5 # off state timeout seconds
+#export PM_TO_LCDOFF=0 # prevent suspend mode
+
+export PM_SYS_DIMBRT=0
+
+DEV_INPUT=
+ABS_POSITION_X=0x15
+ABS_POSITION_Y=0x16
+for file in /sys/class/input/event*; do
+ if [ -e $file ]; then
+ dev_keytype=`cat ${file}/device/capabilities/key`
+ if [ "$dev_keytype" != 0 ]; then
+ DEV_INPUT=$DEV_INPUT:/dev/input/${file#/sys/class/input/}
+ continue
+ fi
+ abs_num=`cat ${file}/device/capabilities/abs | wc -w | cut -d ' ' -f 1`
+ if [ $abs_num != 2 ]; then
+ continue
+ fi
+ abs_val=`cat ${file}/device/capabilities/abs | cut -d ' ' -f 1`
+ if [ $(((0x$abs_val >> $ABS_POSITION_X) & 0x1)) != 1 ]; then
+ continue
+ fi
+ if [ $(((0x$abs_val >> $ABS_POSITION_Y) & 0x1)) != 1 ]; then
+ continue
+ fi
+ DEV_INPUT=$DEV_INPUT:/dev/input/${file#/sys/class/input/}
+ fi
+done
+
+export PM_INPUT=$DEV_INPUT
+
+PMD=@PREFIX@/bin/@EXEC@
+
+echo "Input Event: $PM_INPUT"
+ OPT_X_DPMS="-x"
+ echo "LCD Power: X-DPMS enabled"
+
+case "$1" in
+ start)
+ if [ ! -e /opt/etc/.hib_capturing ]; then
+ $PMD -d $OPT_X_DPMS
+ fi
+ ;;
+ stop)
+ if [ -e /var/run/power-manager.pid ] ; then
+ kill -USR2 `cat /var/run/power-manager.pid`
+ fi
+ ;;
+ restart)
+ if [ -e /var/run/power-manager.pid ] ; then
+ kill -USR2 `cat /var/run/power-manager.pid`
+ # sleep 1 second to wait PID file get removed
+ sleep 1
+ fi
+ if [ ! -e /opt/etc/.hib_capturing ]; then
+ $PMD -d $OPT_X_DPMS
+ fi
+ ;;
+ log)
+ if [ -e /var/run/power-manager.pid ] ; then
+ kill -HUP `cat /var/run/power-manager.pid`
+ fi
+ ;;
+ status)
+ echo "power manager is $([ ! -e /var/run/power-manager.pid ] &&
+ echo "not ")running"
+ ;;
+ *)
+ echo "Usage: pmctrl {start | stop | restart | log | status}"
+ exit 1
+esac
+
+exit 0
+
diff --git a/udev-rules/91-power-manager.rules.in b/udev-rules/91-power-manager.rules.in
new file mode 100644
index 0000000..45ffb59
--- /dev/null
+++ b/udev-rules/91-power-manager.rules.in
@@ -0,0 +1,7 @@
+#input(like bt)
+ACTION=="add" SUBSYSTEM=="input" DEVPATH=="*/input[0-9]*/event[0-9]*" RUN+="@PREFIX@/bin/pm_event add $DEVNAME"
+ACTION=="remove" SUBSYSTEM=="input" DEVPATH=="*/input[0-9]*/event[0-9]*" RUN+="@PREFIX@/bin/pm_event remove $DEVNAME"
+
+# Since power_manager is running as app user, make sure this user can read the input device nodes
+SUBSYSTEM=="input" DEVPATH=="*/input[0-9]*/event[0-9]*" GROUP="video"
+
diff --git a/util.c b/util.c
new file mode 100644
index 0000000..9368295
--- /dev/null
+++ b/util.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2012 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
+ *
+ * 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 util.c
+ * @version 0.1
+ * @brief Utilities for Power manager
+ *
+ * This file includes logging, daemonize
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+
+#ifdef ENABLE_DLOG_OUT
+#define LOG_TAG "POWER_MANAGER"
+#endif
+
+#include "util.h"
+
+/**
+ * @addtogroup POWER_MANAGER
+ * @{
+ */
+
+/**
+ * @brief logging function
+ *
+ * This is log wrapper
+ *
+ * @param[in] priority log pritority
+ * @param[in] fmt format string
+ */
+void pm_log(int priority, char *fmt, ...)
+{
+ va_list ap;
+ char buf[NAME_MAX]; /* NAME_MAX is 255 */
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+#ifdef ENABLE_DLOG_OUT
+ switch (priority) {
+ case DLOG_DEBUG:
+ SLOGD("%s", buf);
+ break;
+ case DLOG_ERROR:
+ SLOGE("%s", buf);
+ break;
+ case DLOG_INFO:
+ SLOGI("%s", buf);
+ break;
+ default:
+ SLOGV("%s", buf);
+ break;
+ }
+#else
+ syslog(priority, "%s", buf);
+#endif
+ printf("\x1b[1;33;44m[PowerManager] %s\x1b[0m\n\n", buf);
+}
+
+/**
+ * @brief write the pid
+ *
+ * get a pid and write it to pidpath
+ *
+ * @param[in] pidpath pid file path
+ * @return 0 (always)
+ */
+int writepid(char *pidpath)
+{
+ FILE *fp;
+
+ fp = fopen(pidpath, "w");
+ if (fp != NULL) {
+ fprintf(fp, "%d", getpid());
+ fclose(fp);
+ }
+
+ return 0;
+}
+
+/**
+ * @brief read the pid
+ *
+ * get a pid and write it to pidpath
+ *
+ * @param[in] pidpath pid file path
+ * @return pid : success, -1 : failed
+ */
+int readpid(char *pidpath)
+{
+ FILE *fp;
+ int ret = -1;
+
+ fp = fopen(pidpath, "r");
+ if (fp != NULL) {
+ fscanf(fp, "%5d", &ret);
+ fclose(fp);
+ }
+
+ return ret;
+}
+
+/**
+ * @brief daemonize function
+ *
+ * fork the process, kill the parent process
+ * and replace all the standard fds to /dev/null.
+ *
+ * @return 0 : success, -1 : fork() error
+ */
+int daemonize(void)
+{
+ pid_t pid;
+
+ pid = fork();
+ if (pid < 0)
+ return -1;
+ else if (pid != 0)
+ exit(0);
+
+ setsid();
+ chdir("/");
+
+ close(0);
+ close(1);
+ close(2);
+
+ open("/dev/null", O_RDONLY);
+ open("/dev/null", O_RDWR);
+ dup(1);
+
+ return 0;
+}
+
+/**
+ * @brief function to run a process
+ *
+ * fork the process, and run the other process if it is child.
+ *
+ * @return new process pid on success, -1 on error
+ */
+
+int exec_process(char *name)
+{
+ int ret, pid;
+ int i;
+
+ if (name[0] == '\0')
+ return 0;
+
+ pid = fork();
+ switch (pid) {
+ case -1:
+ LOGERR("Fork error");
+ ret = -1;
+ break;
+ case 0:
+ for (i = 0; i < _NSIG; i++)
+ signal(i, SIG_DFL);
+ execlp(name, name, NULL);
+ LOGERR("execlp() error : %s\n", strerror(errno));
+ exit(-1);
+ break;
+ default:
+ ret = pid;
+ break;
+ }
+ return ret;
+}
+
+char *get_pkgname(char *exepath)
+{
+ char *filename;
+ char pkgname[NAME_MAX];
+
+ filename = strrchr(exepath, '/');
+ if (filename == NULL)
+ filename = exepath;
+ else
+ filename = filename + 1;
+
+ snprintf(pkgname, NAME_MAX, "deb.com.samsung.%s", filename);
+
+ return strdup(pkgname);
+}
+
+/**
+ * @}
+ */
diff --git a/util.h b/util.h
new file mode 100644
index 0000000..de05fcf
--- /dev/null
+++ b/util.h
@@ -0,0 +1,110 @@
+/*
+ * power-manager
+ * Copyright (c) 2012 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 util.h
+ * @version 0.1
+ * @brief Utilities header for Power manager
+ */
+#ifndef __DEF_UTIL_H__
+#define __DEF_UTIL_H__
+
+/**
+ * @addtogroup POWER_MANAGER
+ * @{
+ */
+
+/*
+ * @brief write the pid
+ *
+ * get a pid and write it to pidpath
+ *
+ * @param[in] pidpath pid file path
+ * @return 0 (always)
+ */
+extern int writepid(char *pidpath);
+
+/*
+ * @brief read the pid
+ *
+ * get a pid and write it to pidpath
+ *
+ * @param[in] pidpath pid file path
+ * @return pid : success, -1 : failed
+ */
+extern int readpid(char *pidpath);
+
+/*
+ * @brief daemonize function
+ *
+ * fork the process, kill the parent process
+ * and replace all the standard fds to /dev/null.
+ *
+ * @return 0 : success, -1 : fork() error
+ */
+extern int daemonize(void);
+
+/**
+ * @brief function to run a process
+ *
+ * fork the process, and run the other process if it is child.
+ *
+ * @return new process pid on success, -1 on error
+ */
+extern int exec_process(char *name);
+
+/**
+ * @brief function to get the pkg name for AUL (Application Util Library)
+ *
+ * remove the path of exepath and make the "com.samsung.<exe_file_name>" string.
+ *
+ * @return new process pid on success, -1 on error
+ */
+extern char *get_pkgname(char *exepath);
+
+/*
+ * @brief logging function
+ *
+ * This is log wrapper
+ *
+ * @param[in] priority log pritority
+ * @param[in] fmt format string
+ */
+extern void pm_log(int priority, char *fmt, ...);
+
+#if defined(ENABLE_DLOG_OUT)
+# include <dlog.h>
+/*
+ * @brief LOG_INFO wrapper
+ */
+# define LOGINFO(fmt, arg...) pm_log(DLOG_INFO, fmt, ## arg)
+
+/*
+ * @brief LOG_ERR wrapper
+ */
+# define LOGERR(fmt, arg...) pm_log(DLOG_ERROR, fmt, ## arg)
+#else
+# include <syslog.h>
+# define LOGINFO(fmt, arg...) pm_log(LOG_INFO, fmt, ## arg)
+# define LOGERR(fmt, arg...) pm_log(LOG_ERR, fmt, ## arg)
+#endif
+
+/**
+ * @}
+ */
+#endif