From 0c984fff9da8352c7222de3976d6481668349e99 Mon Sep 17 00:00:00 2001 From: Kim Kibum Date: Fri, 8 Jun 2012 14:54:11 +0900 Subject: apply FSL(Flora Software License) --- AUTHORS | 2 + CMakeLists.txt | 58 ++ LICENSE | 75 +++ debian/changelog | 8 + debian/compat | 1 + debian/control | 20 + debian/copyright | 1 + debian/dirs | 2 + debian/docs | 1 + debian/power-manager-bin.install.in | 3 + debian/power-manager-bin.postinst.in | 11 + debian/rules | 138 ++++ main.c | 132 ++++ packaging/power-manager.spec | 70 ++ pm_conf.c | 80 +++ pm_conf.h | 25 + pm_core.c | 1166 ++++++++++++++++++++++++++++++++++ pm_core.h | 100 +++ pm_device_plugin.c | 63 ++ pm_device_plugin.h | 30 + pm_event/CMakeLists.txt | 34 + pm_event/pm_event.c | 40 ++ pm_key_filter.c | 233 +++++++ pm_llinterface.c | 209 ++++++ pm_llinterface.h | 56 ++ pm_lsensor.c | 247 +++++++ pm_poll.c | 299 +++++++++ pm_poll.h | 73 +++ pm_setting.c | 136 ++++ pm_setting.h | 128 ++++ pm_x_lcd_onoff.c | 66 ++ pmctrl.in | 61 ++ power_manager.sh | 5 + udev-rules/91-power-manager.rules.in | 3 + util.c | 213 +++++++ util.h | 120 ++++ 36 files changed, 3909 insertions(+) create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100755 LICENSE create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/dirs create mode 100644 debian/docs create mode 100644 debian/power-manager-bin.install.in create mode 100644 debian/power-manager-bin.postinst.in create mode 100755 debian/rules create mode 100644 main.c create mode 100644 packaging/power-manager.spec create mode 100644 pm_conf.c create mode 100644 pm_conf.h create mode 100644 pm_core.c create mode 100644 pm_core.h create mode 100644 pm_device_plugin.c create mode 100644 pm_device_plugin.h create mode 100644 pm_event/CMakeLists.txt create mode 100644 pm_event/pm_event.c create mode 100644 pm_key_filter.c create mode 100644 pm_llinterface.c create mode 100644 pm_llinterface.h create mode 100644 pm_lsensor.c create mode 100644 pm_poll.c create mode 100644 pm_poll.h create mode 100644 pm_setting.c create mode 100644 pm_setting.h create mode 100644 pm_x_lcd_onoff.c create mode 100644 pmctrl.in create mode 100755 power_manager.sh create mode 100644 udev-rules/91-power-manager.rules.in create mode 100644 util.c create mode 100644 util.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..67e6bd9 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,2 @@ +Jinkun Jang +DongGi Jang diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f09a755 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,58 @@ +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 ) + +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}/${PROJECT_NAME}.sh DESTINATION /etc/rc.d/init.d) + +ADD_SUBDIRECTORY(pm_event) diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..7ccb5b5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,75 @@ +Flora License + +Version 1.0, May, 2012 + +http://www.tizenopensource.org/license + +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. + +"Tizen Certified Platform" shall mean a software platform that complies with the standards set forth in the Compatibility Definition Document and passes the Compatibility Test Suite as defined from time to time by the Tizen Technical Steering Group and certified by the Tizen Association or its designated agent. + +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 solely as incorporated into a Tizen Certified Platform, 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 solely as incorporated into a Tizen Certified Platform 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 pursuant to the copyright license above, in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and + + 2. You must cause any modified files to carry prominent notices stating that You changed the files; and + + 3. 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 + + 4. 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 Flora License to your work + +To apply the Flora 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 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. diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..345debe --- /dev/null +++ b/debian/changelog @@ -0,0 +1,8 @@ +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 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 Jinkun Jang DongGi Jang TAESOO JUN +Uploaders: Jinkun Jang +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..9c188d0 --- /dev/null +++ b/debian/power-manager-bin.postinst.in @@ -0,0 +1,11 @@ +#!/bin/sh + +vconftool set -t int memory/pwrmgr/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..5078e43 --- /dev/null +++ b/main.c @@ -0,0 +1,132 @@ +/* + * 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 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...}
+ * + * Options:

+ *   -f --foreground
+ *     Run as foreground process

+ *   -d --direct
+ *     Start without notification

+ * + * @} + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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.spec b/packaging/power-manager.spec new file mode 100644 index 0000000..1427427 --- /dev/null +++ b/packaging/power-manager.spec @@ -0,0 +1,70 @@ +Name: power-manager +Summary: Power manager +Version: 1.3.21 +Release: 1 +Group: TO_BE/FILLED_IN +License: Flora Software License +Source0: %{name}-%{version}.tar.gz +Requires(post): /usr/bin/vconftool +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 + + +%package bin +Summary: Power manager +Group: TO_BE/FILLED_IN + +%description bin +Description: Power manager + + +%prep +%setup -q + +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} + +%build +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc3.d/ +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc5.d/ + +ln -s %{_sysconfdir}/init.d/power_manager.sh %{buildroot}%{_sysconfdir}/rc.d/rc3.d/S35power-manager +ln -s %{_sysconfdir}/init.d/power_manager.sh %{buildroot}%{_sysconfdir}/rc.d/rc5.d/S00power-manager + +%post bin +vconftool set -t int memory/pwrmgr/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 /usr/share/power-manager/udev-rules/91-power-manager.rules /etc/udev/rules.d/91-power-manager.rules +fi + + + +%files bin +%defattr(-,root,root,-) +/etc/rc.d/init.d/power_manager.sh +/etc/rc.d/rc3.d/S35power-manager +/etc/rc.d/rc5.d/S00power-manager +/usr/bin/pm_event +/usr/bin/pmctrl +/usr/bin/power_manager +/usr/share/power-manager/udev-rules/91-power-manager.rules + diff --git a/pm_conf.c b/pm_conf.c new file mode 100644 index 0000000..0d85251 --- /dev/null +++ b/pm_conf.c @@ -0,0 +1,80 @@ +/* + * 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. +*/ + +#include +#include +#include + +#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..0ce3fb3 --- /dev/null +++ b/pm_conf.h @@ -0,0 +1,25 @@ +/* + * 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. +*/ + + +#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..085bc19 --- /dev/null +++ b/pm_core.c @@ -0,0 +1,1166 @@ +/* + * 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 pm_core.c + * @version 0.2 + * @brief Power manager main loop. + * + * This file includes Main loop, the FSM, signal processing. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pm_device_plugin.h" +#include "pm_core.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; + +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 */ + {S_SLEEP, S_NORMAL}, /* S_LCDOFF */ + {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 + +static int received_sleep_cmd = 0; + +typedef struct _node { + pid_t pid; + int timeout_id; + 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) +{ + 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->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; + LOGDBG("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; + LOGDBG("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; + LOGDBG("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; + + 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); + } + tmp = find_node(S_LCDDIM, pid); + if (tmp == NULL) + tmp = add_node(S_LCDDIM, pid, cond_timeout_id); + else if (tmp->timeout_id > 0) { + g_source_remove(tmp->timeout_id); + tmp->timeout_id = cond_timeout_id; + } + /* 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); + } + tmp = find_node(S_LCDOFF, pid); + if (tmp == NULL) + tmp = add_node(S_LCDOFF, pid, cond_timeout_id); + else if (tmp->timeout_id > 0) { + g_source_remove(tmp->timeout_id); + tmp->timeout_id = cond_timeout_id; + } + /* 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) + tmp = add_node(S_SLEEP, pid, cond_timeout_id); + else if (tmp->timeout_id > 0) { + g_source_remove(tmp->timeout_id); + tmp->timeout_id = cond_timeout_id; + } + 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; + } + } + LOGDBG("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; +} + +/* SIGINT, SIGTERM, SIGQUIT signal handler */ +static void sig_quit(int signo) +{ + LOGDBG("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) +{ + LOGDBG("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; +} + +/* + * 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; + + next_state = (enum state_t)trans_table[cur_state][evt]; + + /* check conditions */ + while (st->check && !st->check(next_state)) { + /* There is a condition. */ + LOGDBG("%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 = 0; + + 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) { + for (i = 0; i < 10; 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); + } + backlight_on(); + backlight_restore(); + } 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(); + } + + break; + + case S_SLEEP: + /* 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); + LOGDBG("timout set: %s state %d sec", state_string[cur_state], timeout); + + return 0; + +go_suspend: + system_suspend(); + LOGINFO("system wakeup!!"); + 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; + + LOGDBG("trans_cond : %x", trans_cond); + + 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) + states[i].timeout = val; + else + states[i].timeout = 0; + LOGDBG("%s state : %d timeout", state_string[i], + states[i].timeout); + } + + return 0; +} + +static void default_saving_mode(int onoff) +{ + int ret = -1, val = 5; + char tmp[NAME_MAX]; + + if (onoff) { + status_flag |= PWRSV_FLAG; + get_env(EN_SYS_DIMBRT, tmp, sizeof(tmp)); + set_default_brt(atoi(tmp)); /* Minimum brightness */ + } else { + status_flag &= ~PWRSV_FLAG; + ret = get_setting_brightness(&val); + if (ret > -1) { + LOGDBG("Set brightness from Setting App. %d", ret); + set_default_brt(val); + } else { + LOGERR("Failed to get the brightness value"); + set_default_brt(5); + } + } + 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) { + + LOGDBG("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; + + switch (key_idx) { + case SETTING_TO_NORMAL: + ret = get_dim_timeout(&dim_timeout); + if(ret < 0) { + LOGERR("Can not get dim timeout. set default 5 seconds"); + dim_timeout = 5; + } + states[S_NORMAL].timeout = val - dim_timeout; + states[cur_state].trans(EVENT_INPUT); + break; + case SETTING_LOW_BATT: + if (val < VCONFKEY_SYSMAN_BAT_WARNING_LOW) { + power_saving_func(true); + status_flag |= LOWBT_FLAG; + } else { + if (status_flag & PWRSV_FLAG) + power_saving_func(false); + status_flag &= ~LOWBT_FLAG; + } + break; + case SETTING_BRT_LEVEL: + if (status_flag & PWRSV_FLAG) + break; + 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; + } + if (cur_state == S_NORMAL) { + states[cur_state].trans(EVENT_INPUT); + } + break; + default: + return -1; + } + return 0; +} + +static void check_seed_status(void) +{ + int ret = -1; + int tmp = 0; + int bat_state = 4; + int max_brt = 0; + int brt = 0; + int lock_state = -1; + + ret = get_setting_brightness(&tmp); + if (ret != 0 || tmp < 0) { + LOGDBG("fail to read vconf value for brightness"); + + if (0 > plugin_intf->OEM_sys_get_backlight_max_brightness(DEFAULT_DISPLAY, &max_brt)) + brt = 7; + else + brt = max_brt * 0.4; + if(tmp < 0) + vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt); + tmp=brt; + } + + vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state); + if(bat_state >= VCONFKEY_SYSMAN_BAT_WARNING_LOW || bat_state == -1 ) { + LOGDBG("Set brightness from Setting App. %d", tmp); + set_default_brt(tmp); + } else { + 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); + } + } + + /* 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", +}; + +static GList *find_glist(GList *glist, char *path) +{ + int i; + guint total=0; + indev *tmp; + + total=g_list_length(indev_list); + for(i=0;idata); + 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; + } + + 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) { + LOGDBG("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(SIGINT, sig_quit); + signal(SIGTERM, sig_quit); + signal(SIGQUIT, sig_quit); + signal(SIGHUP, sig_hup); + signal(SIGCHLD, SIG_IGN); + signal(SIGUSR1, sig_usr); + + 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: + LOGDBG("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); + } + + g_main_loop_run(mainloop); + g_main_loop_unref(mainloop); + } + + 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..4f7047a --- /dev/null +++ b/pm_core.h @@ -0,0 +1,100 @@ +/* + * 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 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 + +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..0cd2951 --- /dev/null +++ b/pm_device_plugin.c @@ -0,0 +1,63 @@ +/* + * 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. +*/ + +#include +#include + +#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..2dbd874 --- /dev/null +++ b/pm_device_plugin.h @@ -0,0 +1,30 @@ +/* + * 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. +*/ + + +#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..efdf43d --- /dev/null +++ b/pm_event/CMakeLists.txt @@ -0,0 +1,34 @@ +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(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME} DESTINATION bin) + + + diff --git a/pm_event/pm_event.c b/pm_event/pm_event.c new file mode 100644 index 0000000..31862d0 --- /dev/null +++ b/pm_event/pm_event.c @@ -0,0 +1,40 @@ +/* + * 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. +*/ + + +#include +#include +#include + +#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..3820c1e --- /dev/null +++ b/pm_key_filter.c @@ -0,0 +1,233 @@ +/* + * 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. +*/ + + +#include +#include +#include +#include +#include + +#include +#include + +#include "util.h" +#include "pm_core.h" +#include "pm_poll.h" + +#include +#ifndef KEY_SCREENLOCK +#define KEY_SCREENLOCK 0x98 +#endif + +#define PREDEF_PWROFF_POPUP "pwroff-popup" +#define PREDEF_LEAVESLEEP "leavesleep" +#define PREDEF_POWEROFF "poweroff" + +#define LONG_PRESS_INTERVAL 1000000 /* 1000 ms */ +#define COMBINATION_INTERVAL 300000 /* 300 ms */ + +#define VCONFKEY_TESTMODE_POWER_OFF_POPUP "db/testmode/pwr_off_popup" + +#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 guint longkey_timeout_id = 0; +static guint combination_timeout_id = 0; +static int cancel_lcdoff; +static int key_combination = KEY_COMBINATION_STOP; + +void unlock() +{ + vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_UNLOCK); +} + +static gboolean longkey_pressed(gpointer data) +{ + 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); + return FALSE; +} + +static gboolean combination_failed(gpointer data) +{ + key_combination = KEY_COMBINATION_STOP; + return 0; +} + +int check_key_filter(int length, char buf[]) +{ + struct input_event *pinput; + static struct timeval pressed_time; + int ignore = true; + int idx = 0; + int val = -1; + int val1 = -1; + int ret = -1; + int ret1 = -1; + + do { + pinput = (struct input_event *)&buf[idx]; + if (pinput->type == EV_SYN) ; + else if (pinput->type == EV_KEY) { + if (pinput->code == KEY_POWER) { + ret = vconf_get_int("memory/startapps/sequence", &val); + ret1 = vconf_get_int("memory/boot-animation/finished", &val1); + if ((val == 1 || ret != 0) && (val1 == 1 || ret1 != 0)) { + if (pinput->value == KEY_RELEASED) { /* release */ + if (!(cur_state == S_LCDOFF || cur_state == S_SLEEP) && !cancel_lcdoff && !(key_combination == KEY_COMBINATION_SCREENCAPTURE)) { + check_processes(S_LCDOFF); + check_processes(S_LCDDIM); + if (!(trans_condition & (MASK_DIM | MASK_OFF))) { + recv_data.pid = -1; + recv_data.cond = 0x400; /* go to S_LCDOFF */ + if(vconf_get_int(VCONFKEY_FLASHPLAYER_FULLSCREEN, &val)<0 || val == 0) + (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data); + } + } else + ignore = false; + key_combination = KEY_COMBINATION_STOP; + if (combination_timeout_id > 0) { + g_source_remove(combination_timeout_id); + combination_timeout_id = 0; + } + cancel_lcdoff = 0; + if (longkey_timeout_id > 0) { + g_source_remove(longkey_timeout_id); + longkey_timeout_id = 0; + } + } else if (pinput->value == KEY_PRESSED) { + 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, NULL, NULL); + key_combination = KEY_COMBINATION_START; + combination_timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT, COMBINATION_INTERVAL / 1000, + (GSourceFunc)combination_failed, 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_BEING_PRESSED && /* being pressed */ + (((pinput->time).tv_sec - pressed_time.tv_sec) * 1000000 + ((pinput->time).tv_usec - pressed_time.tv_usec)) + > LONG_PRESS_INTERVAL) { + longkey_pressed(NULL); + } + } else { + ignore = false; + } + } else { + if (pinput->code == KEY_VOLUMEDOWN) { + if (pinput->value == KEY_PRESSED) { /* press */ + 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, 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) { + key_combination = KEY_COMBINATION_STOP; + if (combination_timeout_id > 0) { + g_source_remove(combination_timeout_id); + combination_timeout_id = 0; + } + if (cur_state == S_LCDDIM || cur_state == S_NORMAL) + ignore = false; + } + } + } else { + key_combination = KEY_COMBINATION_STOP; + if (combination_timeout_id > 0) { + g_source_remove(combination_timeout_id); + combination_timeout_id = 0; + } + if (pinput->code == KEY_MENU) { + if (cur_state == S_LCDDIM || cur_state == S_NORMAL || cur_state == S_LCDOFF) + ignore = false; + } else if (pinput->code == KEY_VOLUMEUP + || pinput->code == KEY_VOLUMEDOWN + || pinput->code == KEY_CAMERA + || pinput->code == KEY_EXIT + || pinput->code == KEY_PHONE + || pinput->code == KEY_CONFIG + || pinput->code == KEY_SEARCH) { + if (cur_state == S_LCDDIM || cur_state == S_NORMAL) + ignore = false; + } else if (pinput->code == KEY_SCREENLOCK + || pinput->code == 0x1DB + || pinput->code == 0x1DC + || pinput->code == 0x1DD + || pinput->code == 0x1DE) + ; + else + ignore = false; + } + } + } + else if (pinput->type == EV_REL) + ignore = false; + else if (pinput->type == EV_ABS){ + if (cur_state == S_LCDDIM || cur_state == S_NORMAL) + ignore = false; + } + + 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..3690fb8 --- /dev/null +++ b/pm_llinterface.c @@ -0,0 +1,209 @@ +/* + * 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. +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pm_llinterface.h" +#include "pm_device_plugin.h" +#include "util.h" +#include "pm_conf.h" + +typedef struct _PMSys PMSys; +struct _PMSys { + int def_brt; + int dim_brt; + + int (*sys_suspend) (PMSys *); + int (*bl_onoff) (PMSys *, int); + int (*bl_brt) (PMSys *, int); +}; + +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) +{ + plugin_intf->OEM_sys_get_backlight_brightness(DEFAULT_DISPLAY, &(p->def_brt)); +} + +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) +{ + return plugin_intf->OEM_sys_set_backlight_brightness(DEFAULT_DISPLAY, brightness); +} + +static int _sys_suspend(PMSys *p) +{ + return plugin_intf->OEM_sys_set_power_state(POWER_STATE_SUSPEND); +} + +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_suspend = _sys_suspend; +} + +int system_suspend() +{ + if (pmsys && pmsys->sys_suspend) + return pmsys->sys_suspend(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; + if (pmsys && pmsys->bl_brt) { + ret = pmsys->bl_brt(pmsys, pmsys->def_brt); + } + return ret; +} + +int set_default_brt(int level) +{ + int max_brt; + + if (0 == plugin_intf->OEM_sys_get_backlight_max_brightness(DEFAULT_DISPLAY, &max_brt)) { + if (level > max_brt) { + pmsys->def_brt = max_brt; + + return 0; + } + } + 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_suspend == NULL) { + LOGERR + ("We have no managable resource to reduce the power consumption"); + return -1; + } + + return 0; +} + +int exit_sysfs() +{ + int fd; + + fd = open("/tmp/sem.pixmap_1", O_RDONLY); + if (fd == -1) { + LOGERR("X server disable"); + backlight_on(); + } + + backlight_restore(); + free(pmsys); + pmsys = NULL; + + return 0; +} diff --git a/pm_llinterface.h b/pm_llinterface.h new file mode 100644 index 0000000..5389805 --- /dev/null +++ b/pm_llinterface.h @@ -0,0 +1,56 @@ +/* + * 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 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 + +/* + * 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..0f1cf52 --- /dev/null +++ b/pm_lsensor.c @@ -0,0 +1,247 @@ +/* + * 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. +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 max_brightness = 10; +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; + value = max_brightness * (int)light_data.values[0] / 10; + plugin_intf->OEM_sys_get_backlight_brightness(DEFAULT_DISPLAY, &tmp_value); + 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_bool(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_BOOL, 0); + 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) +{ + LOGDBG("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 */ + LOGDBG("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() +{ + LOGDBG("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 int set_alc_function(keynode_t *key_nodes, void *data) +{ + int onoff = 0; + + if (key_nodes == NULL) { + LOGERR("wrong parameter, key_nodes is null"); + return -1; + } + + onoff = vconf_keynode_get_bool(key_nodes); + + if (onoff == true) { + if(connect_sfsvc() < 0) + return -1; + + /* 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 { + disconnect_sfsvc(); + } + + 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_bool(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_BOOL, &vconf_auto); + if (vconf_auto == true) { + 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; + + plugin_intf->OEM_sys_get_backlight_max_brightness(DEFAULT_DISPLAY, &max_brightness); + vconf_get_bool(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_BOOL, &alc_conf); + + if (alc_conf == true) { + 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_BOOL, + (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..82274fb --- /dev/null +++ b/pm_poll.c @@ -0,0 +1,299 @@ +/* + * 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 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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"); + 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; + + LOGDBG("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)) { + LOGDBG("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); + LOGDBG("pm_poll domain socket file: %s, fd: %d", + path_tok, gpollfd->fd); + } else { + gpollfd->fd = open(path_tok, O_RDONLY); + LOGDBG("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..f62236c --- /dev/null +++ b/pm_poll.h @@ -0,0 +1,73 @@ +/* + * 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 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 + +/** + * @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..8a1f5f3 --- /dev/null +++ b/pm_setting.c @@ -0,0 +1,136 @@ +/* + * 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. +*/ + + +#include +#include +#include "pm_setting.h" +#include "pm_conf.h" +#include "util.h" + +static const char *setting_keys[SETTING_GET_END] = { + [SETTING_TO_NORMAL] = VCONFKEY_SYSMAN_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, +}; + +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); + *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)); + LOGDBG("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)); + LOGDBG("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) { + 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..5672768 --- /dev/null +++ b/pm_setting.h @@ -0,0 +1,128 @@ +/* + * 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 pm_setting.h + * @version 0.1 + * @brief Power manager setting module header + */ +#ifndef __PM_SETTING_H__ +#define __PM_SETTING_H__ + +#include + +/* + * @addtogroup POWER_MANAGER + * @{ + */ + +enum { + SETTING_BEGIN = 0, + SETTING_TO_NORMAL = SETTING_BEGIN, + SETTING_LOW_BATT, + SETTING_CHARGING, + SETTING_BRT_LEVEL, + SETTING_LOCK_SCREEN, + 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..58980a8 --- /dev/null +++ b/pm_x_lcd_onoff.c @@ -0,0 +1,66 @@ +/* + * 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. +*/ + + +#ifndef __PM_X_LCD_ONOFF_C__ +#define __PM_X_LCD_ONOFF_C__ + +#include +#include +#include + +#include "pm_device_plugin.h" + +#define CMD_STANDBY "standby" +#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; + + LOGDBG("Backlight onoff=%d", onoff); + if (onoff == STATUS_ON) + snprintf(cmd_line, sizeof(cmd_line), "%s", CMD_STANDBY); + 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..e19815b --- /dev/null +++ b/pmctrl.in @@ -0,0 +1,61 @@ +#!/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= +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/} + fi + 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) + $PMD -d $OPT_X_DPMS + ;; + stop) + if [ -e /var/run/power-manager.pid ] ; then + kill `cat /var/run/power-manager.pid` + fi + ;; + restart) + if [ -e /var/run/power-manager.pid ] ; then + kill `cat /var/run/power-manager.pid` + fi + $PMD -d + ;; + log) + if [ -e /var/run/power-manager.pid ] ; then + kill -SIGHUP `cat /var/run/power-manager.pid` + fi + ;; + *) + echo "Usage: pmctrl {start | stop | restart | log}" + exit 1 +esac + +exit 0 + diff --git a/power_manager.sh b/power_manager.sh new file mode 100755 index 0000000..6916f4c --- /dev/null +++ b/power_manager.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +if [ ! -e /opt/etc/.hib_capturing ]; then + /usr/bin/pmctrl start +fi diff --git a/udev-rules/91-power-manager.rules.in b/udev-rules/91-power-manager.rules.in new file mode 100644 index 0000000..39c946a --- /dev/null +++ b/udev-rules/91-power-manager.rules.in @@ -0,0 +1,3 @@ +#input(like bt) +ACTION=="add" SUBSYSTEM=="input" DEVPATH=="*/input[1-9]*/event[1-9]*" RUN+="@PREFIX@/bin/pm_event add $DEVNAME" +ACTION=="remove" SUBSYSTEM=="input" DEVPATH=="*/input[1-9]*/event[1-9]*" RUN+="@PREFIX@/bin/pm_event remove $DEVNAME" 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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..d9f85e3 --- /dev/null +++ b/util.h @@ -0,0 +1,120 @@ +/* + * 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.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." 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 +/* + * @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 +# define LOGINFO(fmt, arg...) pm_log(LOG_INFO, fmt, ## arg) +# define LOGERR(fmt, arg...) pm_log(LOG_ERR, fmt, ## arg) +#endif + +/* + * @brief LOG_DEBUG wrapper + */ +#if defined(DEBUG_PRINT) && defined(ENABLE_DLOG_OUT) +# define LOGDBG(fmt, arg...) pm_log(DLOG_DEBUG, fmt, ## arg) +#elif defined(DEBUG_PRINT) +# define LOGDBG(fmt, arg...) pm_log(LOG_DEBUG, fmt, ## arg) +#else +# define LOGDBG(fmt, arg...) do { } while (0); +#endif + +/** + * @} + */ +#endif -- cgit v1.2.3