summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSehong Na <sehong.na@samsung.com>2014-05-31 13:01:11 +0900
committerSehong Na <sehong.na@samsung.com>2014-05-31 13:01:11 +0900
commit136ff6fa3493217189f4688f593d56c7408cef23 (patch)
treed59573778f717f8ff4d24ad0ef8a64acb4d9fbc6
downloadsystem-server-tizen_2.3.tar.gz
system-server-tizen_2.3.tar.bz2
system-server-tizen_2.3.zip
-rw-r--r--AUTHORS2
-rwxr-xr-xCMakeLists.txt124
-rw-r--r--LICENSE.APLv2202
-rw-r--r--NOTICE3
-rwxr-xr-xapp2ext.c135
-rw-r--r--app2ext.h25
-rw-r--r--debian/compat1
-rw-r--r--debian/control30
-rwxr-xr-xdebian/rules128
-rw-r--r--debian/system-server-bin.install.in3
-rw-r--r--debian/system-server-bin.postinst.in47
-rw-r--r--deviced.pc.in13
-rw-r--r--include/ss_data.h112
-rwxr-xr-xmmc-smack-label7
-rwxr-xr-xmovi_format.sh34
-rw-r--r--packaging/deviced.manifest5
-rw-r--r--packaging/system-server.manifest18
-rw-r--r--packaging/system-server.rule7
-rw-r--r--packaging/system-server.spec188
-rw-r--r--predefine_act_plugin/CMakeLists.txt38
-rwxr-xr-xpredefine_act_plugin/build.sh7
-rw-r--r--predefine_act_plugin/xxx-predefine.c40
-rw-r--r--restarter/CMakeLists.txt29
-rw-r--r--restarter/restart.c29
-rw-r--r--src/core/list.h74
-rw-r--r--src/deviced/dd-battery.h35
-rw-r--r--src/deviced/dd-mmc.h61
-rw-r--r--src/shared/battery.c25
-rw-r--r--src/shared/common.h49
-rw-r--r--src/shared/log.h45
-rw-r--r--src/shared/mmc.c162
-rw-r--r--ss_bs.c447
-rw-r--r--ss_bs.h23
-rw-r--r--ss_common.c23
-rw-r--r--ss_common.h7
-rw-r--r--ss_core.c171
-rw-r--r--ss_core.h27
-rw-r--r--ss_cpu_handler.c429
-rw-r--r--ss_cpu_handler.h23
-rwxr-xr-xss_device_change_handler.c670
-rw-r--r--ss_device_handler.h49
-rw-r--r--ss_launch.c338
-rw-r--r--ss_launch.h27
-rw-r--r--ss_log.c35
-rw-r--r--ss_log.h171
-rwxr-xr-xss_lowbat_handler.c380
-rw-r--r--ss_lowmem_handler.c343
-rw-r--r--ss_main.c128
-rw-r--r--ss_mmc_handler.c905
-rw-r--r--ss_noti.c55
-rw-r--r--ss_noti.h26
-rw-r--r--ss_pmon_handler.c266
-rw-r--r--ss_pmon_handler.h25
-rw-r--r--ss_predefine.c918
-rw-r--r--ss_predefine.h27
-rwxr-xr-xss_procmgr.c404
-rw-r--r--ss_procmgr.h26
-rw-r--r--ss_queue.c305
-rw-r--r--ss_queue.h66
-rw-r--r--ss_sig_handler.c74
-rw-r--r--ss_sig_handler.h23
-rwxr-xr-xss_sysnoti.c391
-rw-r--r--ss_sysnoti.h34
-rw-r--r--ss_ta_handler.c50
-rw-r--r--ss_timemgr.c258
-rw-r--r--ss_timemgr.h23
-rw-r--r--ss_usb_handler.c55
-rw-r--r--ss_vibrator.c312
-rw-r--r--ss_vibrator.h23
-rw-r--r--sys_event/CMakeLists.txt31
-rw-r--r--sys_event/sys_event.c30
-rwxr-xr-xsys_pci_noti/CMakeLists.txt30
-rw-r--r--sys_pci_noti/po_sys_pci_noti/CMakeLists.txt24
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/ar.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/az.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/bg.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/ca.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/cs.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/da.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/de_DE.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/el_GR.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/en.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/en_PH.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/en_US.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/es_ES.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/es_MX.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/es_US.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/et.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/eu.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/fi.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/fr_CA.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/fr_FR.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/ga.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/gl.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/hi.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/hr.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/hu.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/hy.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/is.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/it_IT.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/ja_JP.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/ka.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/kk.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/ko_KR.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/lt.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/lv.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/mk.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/nb.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/nl_NL.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/pl.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/pt_BR.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/pt_PT.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/ro.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/ru_RU.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/sk.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/sl.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/sr.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/sv.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/tr_TR.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/uk.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/uz.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/zh_CN.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/zh_HK.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/zh_SG.po6
-rwxr-xr-xsys_pci_noti/po_sys_pci_noti/zh_TW.po6
-rwxr-xr-xsys_pci_noti/sys_pci_noti.c83
-rwxr-xr-xsys_pci_noti/sys_pci_noti.h39
-rw-r--r--system-server.conf10
-rw-r--r--system_server.sh3
-rw-r--r--systemd/system-server.service14
-rw-r--r--systemd/system-server.socket10
-rw-r--r--udev-rules/91-system-server.rules.in39
132 files changed, 9860 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..6edd069
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Giyeol Ok <giyeol.ok@samsung.com>
+Taesoo Jun <steve.jun@samsung.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755
index 0000000..7b14e75
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,124 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(system_server C)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(LIBDIR "${PREFIX}/lib")
+
+# deviced
+SET(DEVICED_NAME deviced)
+SET(VERSION 0.1.0)
+
+SET(SRCS
+ ss_main.c
+ ss_sysnoti.c
+ ss_launch.c
+ ss_queue.c
+ ss_core.c
+ ss_sig_handler.c
+ ss_log.c
+ ss_device_change_handler.c
+ ss_predefine.c
+ ss_noti.c
+ ss_lowbat_handler.c
+ ss_lowmem_handler.c
+ ss_pmon_handler.c
+ ss_mmc_handler.c
+ ss_usb_handler.c
+ ss_ta_handler.c
+ ss_bs.c
+ ss_procmgr.c
+ ss_timemgr.c
+ ss_cpu_handler.c
+ ss_common.c
+ ss_vibrator.c
+ app2ext.c)
+
+# libdeviced
+SET(DEVICED_SRCS
+ src/shared/mmc.c)
+
+SET(DEVICED_HEADERS
+ src/deviced/dd-mmc.h)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src)
+
+# libdeviced
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/deviced)
+
+SET(MOVINAND_FORMAT movi_format.sh)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+ ecore
+ ecore-file
+ ecore-x
+ eina
+ sysman
+ vconf
+ heynoti
+ pmapi
+ tapi
+ dlog
+ syspopup-caller
+ notification
+ device-node
+ libsmack
+ libsystemd-daemon)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+# libdeviced
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+MESSAGE("FLAGS: ${CMAKE_C_FLAGS}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+ADD_DEFINITIONS("-DLIBDIR=\"${LIBDIR}\"")
+
+IF( $ENV{ARCH} MATCHES "arm" )
+ ADD_DEFINITIONS("-DTARGET")
+ENDIF()
+ADD_DEFINITIONS("-DDEBUG -DENABLE_DLOG_OUT")
+
+SET(UDEV_RULES_PATH share/system-server/udev-rules)
+SET(UDEV_RULES udev-rules/91-system-server.rules)
+
+CONFIGURE_FILE(${UDEV_RULES}.in ${UDEV_RULES} @ONLY)
+
+# libdeviced
+ADD_LIBRARY(${DEVICED_NAME} SHARED ${DEVICED_SRCS})
+TARGET_LINK_LIBRARIES(${DEVICED_NAME} ${pkgs_LDFLAGS})
+SET_TARGET_PROPERTIES(${DEVICED_NAME} PROPERTIES VERSION ${VERSION})
+INSTALL(TARGETS ${DEVICED_NAME} DESTINATION lib COMPONENT RuntimeLibraries)
+
+FOREACH(hfile ${DEVICED_HEADERS})
+ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${hfile} DESTINATION include/${DEVICED_NAME})
+ENDFOREACH(hfile)
+
+CONFIGURE_FILE(${DEVICED_NAME}.pc.in ${DEVICED_NAME}.pc @ONLY)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${DEVICED_NAME}.pc DESTINATION lib/pkgconfig)
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-ldl" "-ludev" "-lsmack")
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+
+INSTALL(FILES ${MOVINAND_FORMAT} DESTINATION bin)
+INSTALL(FILES ${UDEV_RULES} DESTINATION ${UDEV_RULES_PATH})
+INSTALL(PROGRAMS ${CMAKE_BINARY_DIR}/system_server.sh DESTINATION /etc/rc.d/init.d)
+INSTALL(FILES system-server.conf DESTINATION /etc/dbus-1/system.d)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/packaging/system-server.rule DESTINATION /opt/etc/smack/accesses.d)
+INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/mmc-smack-label DESTINATION bin)
+
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/systemd/system-server.service DESTINATION /usr/lib/systemd/system)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/systemd/system-server.socket DESTINATION /usr/lib/systemd/system)
+
+ADD_SUBDIRECTORY(restarter)
+ADD_SUBDIRECTORY(sys_event)
+ADD_SUBDIRECTORY(sys_pci_noti)
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE.APLv2
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..08a1d59
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, This software is licensed under Apache License, Version 2.
+Please, see the LICENSE.APLv2 file for Apache License terms and conditions.
diff --git a/app2ext.c b/app2ext.c
new file mode 100755
index 0000000..b9473f9
--- /dev/null
+++ b/app2ext.c
@@ -0,0 +1,135 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <errno.h>
+#include <dlfcn.h>
+
+#include "include/ss_data.h"
+#include "core/list.h"
+#include "ss_log.h"
+
+#define APP2EXT_PLUGIN_PATH LIBDIR"/libapp2ext.so.0"
+
+static void *app2ext_dl;
+static int (*app2ext_enable)(const char *pkgid);
+static int (*app2ext_disable)(const char *pkgid);
+
+static dd_list *pkgid_head;
+
+static int app2ext_mount(const char *pkgid)
+{
+ int r;
+
+ if (!app2ext_enable)
+ return -ENOENT;
+
+ PRT_TRACE_ERR("Attempt mount %s app to sdcard", pkgid);
+ r = app2ext_enable(pkgid);
+ if (r < 0)
+ return r;
+
+ PRT_TRACE_ERR("Mount %s app to sdcard", pkgid);
+ DD_LIST_APPEND(pkgid_head, strdup(pkgid));
+ return 0;
+}
+
+int app2ext_unmount(void)
+{
+ char *str;
+ dd_list *elem;
+ int r, n, i;
+
+ if (!app2ext_disable)
+ return -ENOENT;
+
+ /* if there is no mounted pkg */
+ if (!pkgid_head)
+ return 0;
+
+ n = DD_LIST_LENGTH(pkgid_head);
+ PRT_TRACE_ERR("pkgid_head count : %d", n);
+
+ for (i = 0; i < n; ++i) {
+ str = DD_LIST_NTH(pkgid_head, 0);
+ PRT_TRACE_ERR("Attempt unmount %s app from sdcard", str);
+ r = app2ext_disable(str);
+ if (r < 0)
+ return r;
+ PRT_TRACE_ERR("Unmount %s app from sdcard", str);
+ DD_LIST_REMOVE(pkgid_head, str);
+ free(str);
+ }
+
+ return 0;
+}
+
+static int mmc_mount_app2ext(int argc, char **argv)
+{
+ char *pkgid;
+
+ if (argc < 1)
+ return -EINVAL;
+
+ if (!mmc_check_mounted(MMC_MOUNT_POINT)) {
+ PRT_TRACE_ERR("Do not mounted");
+ return -ENODEV;
+ }
+
+ pkgid = argv[0];
+ return app2ext_mount(pkgid);
+}
+
+void app2ext_init(void)
+{
+ int ret;
+
+ app2ext_dl = dlopen(APP2EXT_PLUGIN_PATH, RTLD_LAZY|RTLD_GLOBAL);
+ if (!app2ext_dl) {
+ PRT_TRACE_ERR("dlopen error (%s)", dlerror());
+ return;
+ }
+
+ app2ext_enable = dlsym(app2ext_dl, "app2ext_enable_external_pkg");
+ if (!app2ext_enable) {
+ PRT_TRACE_ERR("dlsym error (%s)", dlerror());
+ dlclose(app2ext_dl);
+ app2ext_dl = NULL;
+ return;
+ }
+
+ app2ext_disable = dlsym(app2ext_dl, "app2ext_disable_external_pkg");
+ if (!app2ext_disable) {
+ PRT_TRACE_ERR("dlsym error (%s)", dlerror());
+ dlclose(app2ext_dl);
+ app2ext_dl = NULL;
+ return;
+ }
+
+ ss_action_entry_add_internal(PREDEF_MOUNT_APP2EXT, mmc_mount_app2ext, NULL, NULL);
+}
+
+void app2ext_exit(void)
+{
+ if(!app2ext_dl)
+ return;
+
+ dlclose(app2ext_dl);
+ app2ext_dl = NULL;
+}
diff --git a/app2ext.h b/app2ext.h
new file mode 100644
index 0000000..1130370
--- /dev/null
+++ b/app2ext.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __APP2EXT_H__
+#define __APP2EXT_H__
+
+int app2ext_unmount(void);
+void app2ext_init(void);
+void app2ext_exit(void);
+
+#endif /* __APP2EXT_H__ */
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..566063b
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,30 @@
+Source: system-server
+Section: tools
+Priority: extra
+Maintainer: Jonghoon Han <jonghoon.han@samsung.com> Jinkun Jang <jinkun.jang@samsung.com> DongGi Jang <dg0402.jang@samsung.com> TAESOO JUN <steve.jun@samsung.com>
+Uploaders: Jinkun Jang <jinkun.jang@samsung.com> Wonil Choi <wonil22.choi@samsung.com>
+Build-Depends: debhelper (>= 5),
+ libecore-dev,
+ libheynoti-dev,
+ libslp-setting-dev,
+ libslp-sysman-dev,
+ libslp-tapi-dev,
+ libslp-pm-dev,
+ libdevman-dev,
+ libdevman-plugin-dev,
+ libedbus-dev,
+ dlog-dev,
+ syspopup-caller-dev,
+ libattr1-dev
+Standards-Version: 3.7.2
+
+Package: system-server-bin
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: System server
+
+Package: system-server-bin-dbg
+Section: debug
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, system-server-bin (= ${Source-Version})
+Description: System server degug package (unstripped)
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..bff6ad4
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,128 @@
+#!/usr/bin/make -f
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+CFLAGS ?= -Wall -g
+LDFLAGS ?=
+PREFIX ?= /usr
+DATADIR ?= /opt
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -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)
+
+ 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 ./restarter/CMakeCache.txt
+ rm -rf ./restarter/CMakeFiles
+ rm -rf ./restarter/cmake_install.cmake
+ rm -rf ./restarter/Makefile
+ rm -rf ./restarter/install_manifest.txt
+ rm -rf ./sys_event/CMakeCache.txt
+ rm -rf ./sys_event/CMakeFiles
+ rm -rf ./sys_event/cmake_install.cmake
+ rm -rf ./sys_event/Makefile
+ rm -rf ./sys_event/install_manifest.txt
+ rm -rf ./udev-rules/*.rules
+
+ for f in `find $(CURDIR)/debian/ -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/tmp.
+ $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+ mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/
+ ln -s ../init.d/system_server.sh $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/S35system-server
+ mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/
+ ln -s ../init.d/system_server.sh $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/S00system-server
+
+# 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=system-server-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
diff --git a/debian/system-server-bin.install.in b/debian/system-server-bin.install.in
new file mode 100644
index 0000000..3c1f907
--- /dev/null
+++ b/debian/system-server-bin.install.in
@@ -0,0 +1,3 @@
+@PREFIX@/bin/*
+@PREFIX@/share/system-server/*
+/etc/*
diff --git a/debian/system-server-bin.postinst.in b/debian/system-server-bin.postinst.in
new file mode 100644
index 0000000..f449796
--- /dev/null
+++ b/debian/system-server-bin.postinst.in
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+vconftool set -t int memory/sysman/usbhost_status -1 -i
+vconftool set -t int memory/sysman/mmc -1 -i
+vconftool set -t int memory/sysman/earjack_key 0 -i
+
+vconftool set -t int memory/sysman/added_usb_storage 0 -i
+vconftool set -t int memory/sysman/removed_usb_storage 0 -i
+vconftool set -t int memory/sysman/charger_status -1 -i
+vconftool set -t int memory/sysman/charge_now -1 -i
+vconftool set -t int memory/sysman/battery_status_low -1 -i
+vconftool set -t int memory/sysman/battery_capacity -1 -i
+vconftool set -t int memory/sysman/usb_status -1 -i
+vconftool set -t int memory/sysman/earjack -1 -i
+vconftool set -t int memory/sysman/low_memory 1 -i
+vconftool set -t int memory/sysman/sliding_keyboard -1 -i
+vconftool set -t int memory/sysman/mmc_mount -1 -i
+vconftool set -t int memory/sysman/mmc_unmount -1 -i
+vconftool set -t int memory/sysman/mmc_format -1 -i
+
+vconftool set -t string memory/private/sysman/added_storage_uevent "" -i
+vconftool set -t string memory/private/sysman/removed_storage_uevent "" -i
+
+
+heynotitool set power_off_start
+
+heynotitool set mmcblk_add
+heynotitool set mmcblk_remove
+
+heynotitool set device_usb_chgdet
+heynotitool set device_ta_chgdet
+heynotitool set device_earjack_chgdet
+heynotitool set device_earkey_chgdet
+heynotitool set device_tvout_chgdet
+heynotitool set device_hdmi_chgdet
+heynotitool set device_charge_chgdet
+heynotitool set device_keyboard_chgdet
+heynotitool set device_keyboard_add
+heynotitool set device_keyboard_remove
+heynotitool set device_mouse_add
+heynotitool set device_mouse_remove
+
+mkdir -p /etc/udev/rules.d
+if ! [ -L /etc/udev/rules.d/91-system-server.rules ]; then
+ ln -s @PREFIX@/share/system-server/udev-rules/91-system-server.rules /etc/udev/rules.d/91-system-server.rules
+fi
+
diff --git a/deviced.pc.in b/deviced.pc.in
new file mode 100644
index 0000000..3de6ff0
--- /dev/null
+++ b/deviced.pc.in
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=/usr/lib
+includedir=/usr/include/deviced
+
+Name: deviced library
+Description: Tizen platform device control library
+Version: @VERSION@
+Requires:
+Libs: -L${libdir} -ldeviced
+Cflags: -I${includedir}
diff --git a/include/ss_data.h b/include/ss_data.h
new file mode 100644
index 0000000..98e1d5a
--- /dev/null
+++ b/include/ss_data.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SS_DATA_H__
+#define __SS_DATA_H__
+
+#include <Ecore.h>
+#include <unistd.h>
+
+enum {
+ WIN_CREATE = 0,
+ WIN_SHOW,
+ WIN_DELETE,
+ WIN_MAX
+};
+
+#define FM_RADIO_APP "FM_radio"
+#define MULTIMEDIA_APP "music"
+#define BLUETOOTH_APP "bluetooth"
+#define VOICERECORDER_APP "voicerecorder"
+
+#define MMC_DEV "/dev/mmcblk"
+
+#define VCONFKEY_INTERNAL_ADDED_USB_STORAGE "memory/private/sysman/added_storage_uevent"
+#define VCONFKEY_INTERNAL_REMOVED_USB_STORAGE "memory/private/sysman/removed_storage_uevent"
+
+#define PREDEF_CALL "call"
+#define PREDEF_LOWMEM "lowmem"
+#define PREDEF_LOWBAT "lowbat"
+#define PREDEF_USBCON "usbcon"
+#define PREDEF_POWEROFF "poweroff"
+#define PREDEF_REBOOT "reboot"
+#define PREDEF_PWROFF_POPUP "pwroff-popup"
+#define PREDEF_BACKGRD "backgrd"
+#define PREDEF_FOREGRD "foregrd"
+#define PREDEF_ACTIVE "active"
+#define PREDEF_USB_STORAGE_ADD "usbstorage-add"
+#define PREDEF_USB_STORAGE_REMOVE "usbstorage-remove"
+#define PREDEF_INACTIVE "inactive"
+#define PREDEF_HAPTIC "haptic"
+
+#define OOMADJ_SET "oomadj_set"
+#define LOW_MEM_ACT "low_mem_act"
+#define OOM_MEM_ACT "oom_mem_act"
+
+#define WARNING_LOW_BAT_ACT "warning_low_bat_act"
+#define CRITICAL_LOW_BAT_ACT "critical_low_bat_act"
+#define POWER_OFF_BAT_ACT "power_off_bat_act"
+#define CHARGE_BAT_ACT "charge_bat_act"
+#define CHARGE_CHECK_ACT "charge_check_act"
+#define CHARGE_ERROR_ACT "charge_error_act"
+
+#define PREDEF_EARJACKCON "earjack_predef_internal"
+
+#define PREDEF_SET_DATETIME "set_datetime"
+#define PREDEF_SET_TIMEZONE "set_timezone"
+
+#define PREDEF_MOUNT_MMC "mountmmc"
+#define PREDEF_UNMOUNT_MMC "unmountmmc"
+#define PREDEF_FORMAT_MMC "formatmmc"
+#define PREDEF_CHECK_SMACK_MMC "checksmackmmc"
+#define PREDEF_CHECK_MMC "checkmmc"
+#define PREDEF_CHECK_MMC_PROC "checkmmcproc"
+#define PREDEF_MOUNT_APP2EXT "mountapp2ext"
+
+#define PREDEF_SET_MAX_FREQUENCY "set_max_frequency"
+#define PREDEF_SET_MIN_FREQUENCY "set_min_frequency"
+#define PREDEF_RELEASE_MAX_FREQUENCY "release_max_frequency"
+#define PREDEF_RELEASE_MIN_FREQUENCY "release_min_frequency"
+
+#define PREDEF_FLIGHT_MODE "flightmode"
+
+#define PREDEF_DEVICE_CHANGED "device_changed"
+#define PREDEF_INTERNAL_POWEROFF "internal_poweroff"
+
+#define PROCESS_GROUP_SET "process_group_set"
+
+#define OOMADJ_SU (-17)
+#define OOMADJ_INIT (-16)
+#define OOMADJ_FOREGRD_LOCKED (-15)
+#define OOMADJ_FOREGRD_UNLOCKED (-10)
+#define OOMADJ_BACKGRD_LOCKED (-5)
+#define OOMADJ_BACKGRD_UNLOCKED (1)
+
+#define OOMADJ_APP_LIMIT (-16)
+
+#define MOVINAND_MOUNT_POINT "/opt/media"
+#define MMC_MOUNT_POINT "/opt/storage/sdcard"
+
+struct ui_contention_info {
+
+};
+
+struct ss_main_data {
+ int sysnoti_fd;
+ int noti_fd;
+};
+
+#endif /* __SS_DATA_H__ */
diff --git a/mmc-smack-label b/mmc-smack-label
new file mode 100755
index 0000000..4d8fcad
--- /dev/null
+++ b/mmc-smack-label
@@ -0,0 +1,7 @@
+#!/bin/bash
+MOUNT_DIRECTORY=$1
+find $MOUNT_DIRECTORY -type d | xargs chsmack -a 'system::ext_storage' -t
+find $MOUNT_DIRECTORY -type f | xargs chsmack -a 'system::ext_storage'
+find $MOUNT_DIRECTORY -type f | xargs chmod -x
+find $MOUNT_DIRECTORY | xargs chown app:app
+find $MOUNT_DIRECTORY | xargs chmod 777
diff --git a/movi_format.sh b/movi_format.sh
new file mode 100755
index 0000000..dbc2f84
--- /dev/null
+++ b/movi_format.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+fdisk -H 1 /dev/mmcblk0 << EOF
+d
+1
+d
+2
+d
+3
+n
+p
+1
+2
+728576
+n
+p
+2
+
+990720
+n
+p
+3
+
+1003520
+p
+wq
+EOF
+
+sleep 1
+
+fat.format -s 32 -S 512 -F 32 /dev/mmcblk0p1
+fat.format -s 32 -S 512 -F 32 /dev/mmcblk0p2
+fat.format -s 4 -S 4096 -F 16 /dev/mmcblk0p3
+
diff --git a/packaging/deviced.manifest b/packaging/deviced.manifest
new file mode 100644
index 0000000..3256181
--- /dev/null
+++ b/packaging/deviced.manifest
@@ -0,0 +1,5 @@
+<manifest>
+<request>
+ <domain name="_"/>
+</request>
+</manifest>
diff --git a/packaging/system-server.manifest b/packaging/system-server.manifest
new file mode 100644
index 0000000..2a56863
--- /dev/null
+++ b/packaging/system-server.manifest
@@ -0,0 +1,18 @@
+<manifest>
+ <define>
+ <domain name="deviced" policy="shared"/>
+ </define>
+ <assign>
+ <filesystem path="/etc/init.d/system_server.sh" label="_" exec_label="none" />
+ <filesystem path="/etc/rc.d/init.d/system_server.sh" label="_" exec_label="none" />
+ <filesystem path="/etc/rc.d/rc3.d/S35system-server" label="_" exec_label="none" />
+ <filesystem path="/etc/rc.d/rc5.d/S00system-server" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/systemd/system/system-server.service" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/systemd/system/multi-user.target.wants/system-server.service" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/systemd/system/system-server.socket" label="_" exec_label="none" />
+ <filesystem path="/usr/lib/systemd/system/sockets.target.wants/system-server.socket" label="_" exec_label="none" />
+ </assign>
+ <request>
+ <domain name="deviced"/>
+ </request>
+</manifest>
diff --git a/packaging/system-server.rule b/packaging/system-server.rule
new file mode 100644
index 0000000..23855cb
--- /dev/null
+++ b/packaging/system-server.rule
@@ -0,0 +1,7 @@
+deviced sys-assert::core rwxat
+deviced system::vconf rwxat
+deviced telephony_framework::api_manager r
+deviced telephony_framework::api_modem wx
+deviced data-provider-master::notification rw
+deviced data-provider-master::notification.client w
+pulseaudio deviced rw
diff --git a/packaging/system-server.spec b/packaging/system-server.spec
new file mode 100644
index 0000000..6f726f4
--- /dev/null
+++ b/packaging/system-server.spec
@@ -0,0 +1,188 @@
+#sbs-git:slp/pkgs/s/system-server system-server 0.1.51 56e16bca39f96d6c8aed9ed3df2fea9b393801be
+Name: system-server
+Summary: System server
+Version: 0.1.65
+Release: 6
+Group: Framework/system
+License: Apache-2.0
+Source0: system-server-%{version}.tar.gz
+Source2: system-server.manifest
+Source3: deviced.manifest
+BuildRequires: cmake
+BuildRequires: libattr-devel
+BuildRequires: pkgconfig(ecore)
+BuildRequires: pkgconfig(heynoti)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(sysman)
+BuildRequires: pkgconfig(tapi)
+BuildRequires: pkgconfig(pmapi)
+BuildRequires: pkgconfig(edbus)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(syspopup-caller)
+BuildRequires: pkgconfig(x11)
+BuildRequires: pkgconfig(notification)
+BuildRequires: pkgconfig(usbutils)
+BuildRequires: pkgconfig(udev)
+BuildRequires: pkgconfig(device-node)
+BuildRequires: pkgconfig(libsmack)
+BuildRequires: gettext
+BuildRequires: pkgconfig(libsystemd-daemon)
+%{?systemd_requires}
+Requires(preun): /usr/bin/systemctl
+Requires(post): /usr/bin/systemctl
+Requires(post): /usr/bin/vconftool
+Requires(postun): /usr/bin/systemctl
+
+%description
+Description: System server
+
+%package -n libdeviced
+Summary: Deviced library
+Group: Development/Libraries
+
+%description -n libdeviced
+Deviced library for device control
+
+%package -n libdeviced-devel
+Summary: Deviced library for (devel)
+Group: Development/Libraries
+Requires: libdeviced = %{version}-%{release}
+
+%description -n libdeviced-devel
+Deviced library for device control (devel)
+
+%prep
+%setup -q
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix}
+
+%build
+cp %{SOURCE2} .
+cp %{SOURCE3} .
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc3.d/
+ln -s %{_sysconfdir}/init.d/system_server.sh %{buildroot}%{_sysconfdir}/rc.d/rc3.d/S35system-server
+mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc5.d/
+ln -s %{_sysconfdir}/init.d/system_server.sh %{buildroot}%{_sysconfdir}/rc.d/rc5.d/S00system-server
+
+mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants
+mkdir -p %{buildroot}%{_libdir}/systemd/system/sockets.target.wants
+ln -s ../system-server.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/system-server.service
+ln -s ../system-server.service %{buildroot}%{_libdir}/systemd/system/sockets.target.wants/system-server.socket
+
+mkdir -p %{buildroot}%{_datadir}/license
+cp LICENSE.APLv2 %{buildroot}%{_datadir}/license/%{name}
+cp LICENSE.APLv2 %{buildroot}%{_datadir}/license/libdeviced
+cp LICENSE.APLv2 %{buildroot}%{_datadir}/license/libdeviced-devel
+
+%post
+
+vconftool set -t int memory/sysman/usbhost_status -1 -i
+vconftool set -t int memory/sysman/mmc 0 -i
+vconftool set -t int memory/sysman/earjack_key 0 -i
+vconftool set -t int memory/sysman/added_usb_storage 0 -i
+vconftool set -t int memory/sysman/removed_usb_storage 0 -i
+vconftool set -t int memory/sysman/charger_status -1 -i
+vconftool set -t int memory/sysman/charge_now -1 -i
+vconftool set -t int memory/sysman/battery_status_low -1 -i
+vconftool set -t int memory/sysman/battery_capacity -1 -i
+vconftool set -t int memory/sysman/usb_status -1 -i
+vconftool set -t int memory/sysman/earjack -1 -i
+vconftool set -t int memory/sysman/low_memory 1 -i
+vconftool set -t int memory/sysman/sliding_keyboard -1 -i
+vconftool set -t int memory/sysman/mmc_mount -1 -i
+vconftool set -t int memory/sysman/mmc_unmount -1 -i
+vconftool set -t int memory/sysman/mmc_format -1 -i
+vconftool set -t int memory/sysman/mmc_format_progress 0 -i
+vconftool set -t int memory/sysman/mmc_err_status 0 -i
+vconftool set -t int memory/sysman/power_off 0 -u 5000 -i -f
+vconftool set -t int memory/sysman/battery_level_status -1 -i
+vconftool set -t string memory/private/sysman/added_storage_uevent "" -i
+vconftool set -t string memory/private/sysman/removed_storage_uevent "" -u 5000 -i
+
+vconftool set -t int memory/sysman/hdmi 0 -i
+
+vconftool set -t int memory/sysman/stime_changed 0 -i
+
+#db type vconf key init
+vconftool set -t int db/sysman/mmc_dev_changed 0 -i
+
+heynotitool set power_off_start
+
+heynotitool set mmcblk_add
+heynotitool set mmcblk_remove
+heynotitool set device_charge_chgdet
+heynotitool set device_usb_host_add
+heynotitool set device_usb_host_remove
+heynotitool set device_pci_keyboard_add
+heynotitool set device_pci_keyboard_remove
+
+heynotitool set device_usb_chgdet
+heynotitool set device_ta_chgdet
+heynotitool set device_earjack_chgdet
+heynotitool set device_earkey_chgdet
+heynotitool set device_tvout_chgdet
+heynotitool set device_hdmi_chgdet
+heynotitool set device_keyboard_chgdet
+
+
+mkdir -p /etc/udev/rules.d
+if ! [ -L /etc/udev/rules.d/91-system-server.rules ]; then
+ ln -s %{_datadir}/system-server/udev-rules/91-system-server.rules /etc/udev/rules.d/91-system-server.rules
+fi
+
+systemctl daemon-reload
+if [ $1 == 1 ]; then
+ systemctl restart system-server.service
+fi
+
+%preun
+if [ $1 == 0 ]; then
+ systemctl stop system-server.service
+fi
+
+%postun
+systemctl daemon-reload
+
+
+%files
+%manifest system-server.manifest
+%config %{_sysconfdir}/dbus-1/system.d/system-server.conf
+%{_sysconfdir}/rc.d/init.d/system_server.sh
+%{_sysconfdir}/rc.d/rc3.d/S35system-server
+%{_sysconfdir}/rc.d/rc5.d/S00system-server
+%{_bindir}/system_server
+/opt/etc/smack/accesses.d/system-server.rule
+%if 0%{?simulator}
+%exclude %{_bindir}/restart
+%else
+%{_bindir}/restart
+%endif
+%{_bindir}/movi_format.sh
+%{_bindir}/sys_event
+%{_bindir}/sys_pci_noti
+%{_bindir}/mmc-smack-label
+%{_libdir}/systemd/system/multi-user.target.wants/system-server.service
+%{_libdir}/systemd/system/sockets.target.wants/system-server.socket
+%{_libdir}/systemd/system/system-server.service
+%{_libdir}/systemd/system/system-server.socket
+%{_datadir}/system-server/udev-rules/91-system-server.rules
+%{_datadir}/system-server/sys_pci_noti/res/locale/*/LC_MESSAGES/*.mo
+/usr/share/license/%{name}
+
+%files -n libdeviced
+%defattr(-,root,root,-)
+%{_libdir}/libdeviced.so.*
+%manifest deviced.manifest
+/usr/share/license/libdeviced
+
+%files -n libdeviced-devel
+%defattr(-,root,root,-)
+%{_includedir}/deviced/dd-mmc.h
+%{_libdir}/libdeviced.so
+%{_libdir}/pkgconfig/deviced.pc
+/usr/share/license/libdeviced-devel
diff --git a/predefine_act_plugin/CMakeLists.txt b/predefine_act_plugin/CMakeLists.txt
new file mode 100644
index 0000000..100c04f
--- /dev/null
+++ b/predefine_act_plugin/CMakeLists.txt
@@ -0,0 +1,38 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(xxx-predefine C)
+
+SET(SRCS xxx-predefine.c)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION 1.0)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED sysman)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+MESSAGE("FLAGS: ${CMAKE_C_FLAGS}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+ADD_DEFINITIONS("-DDEBUG")
+IF( $ENV{ARCH} MATCHES "arm" )
+ ADD_DEFINITIONS("-DTARGET")
+ENDIF()
+
+SET(CMAKE_LDFLAGS "-Wl,zdefs")
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib COMPONENT RuntimeLibraries)
+
diff --git a/predefine_act_plugin/build.sh b/predefine_act_plugin/build.sh
new file mode 100755
index 0000000..c0cc290
--- /dev/null
+++ b/predefine_act_plugin/build.sh
@@ -0,0 +1,7 @@
+cd `dirname $0`
+
+. ../../../../../setup.conf || exit 1
+
+. ${TPLDIR}/cmake.tpl
+run
+
diff --git a/predefine_act_plugin/xxx-predefine.c b/predefine_act_plugin/xxx-predefine.c
new file mode 100644
index 0000000..548cb4b
--- /dev/null
+++ b/predefine_act_plugin/xxx-predefine.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <sysman.h>
+
+int SS_PREDEFINE_ACT_FUNC(int argc, char **argv)
+{
+ int i;
+ printf("kqwekrqkwerqwer\n");
+ for (i = 0; i < argc; i++)
+ printf("%s\n", argv[i]);
+ return 0;
+}
+
+int SS_IS_ACCESSABLE_FUNC(int pid)
+{
+ printf("qwerqerqewr %d\n", pid);
+ return 1;
+}
+
+int SS_UI_VIEWABLE_FUNC()
+{
+ printf("kakak viewable\n");
+ return 1;
+}
diff --git a/restarter/CMakeLists.txt b/restarter/CMakeLists.txt
new file mode 100644
index 0000000..1a42ebf
--- /dev/null
+++ b/restarter/CMakeLists.txt
@@ -0,0 +1,29 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(restart C)
+
+SET(SRCS restart.c)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+
+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}")
+MESSAGE("FLAGS: ${CMAKE_C_FLAGS}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+IF( $ENV{ARCH} MATCHES "arm" )
+ ADD_DEFINITIONS("-DTARGET")
+ENDIF()
+ADD_DEFINITIONS("-DSLP_DEBUG")
+ADD_DEFINITIONS("-DSLP_PROF")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
diff --git a/restarter/restart.c b/restarter/restart.c
new file mode 100644
index 0000000..e869e41
--- /dev/null
+++ b/restarter/restart.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/reboot.h>
+
+int main(int argc, char *argv[])
+{
+ system("/etc/rc.d/rc.shutdown &");
+ sleep(1);
+ sync();
+ reboot(RB_AUTOBOOT);
+ return 0;
+}
diff --git a/src/core/list.h b/src/core/list.h
new file mode 100644
index 0000000..4217704
--- /dev/null
+++ b/src/core/list.h
@@ -0,0 +1,74 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LIST_H__
+#define __LIST_H__
+
+#include <Ecore.h>
+
+#define EINA_LIST_APPEND(a, b) \
+ a = eina_list_append(a, b)
+
+#define EINA_LIST_REMOVE(a, b) \
+ a = eina_list_remove(a, b)
+
+#define EINA_LIST_REMOVE_LIST(a, b) \
+ a = eina_list_remove_list(a, b)
+
+#define EINA_LIST_FREE_LIST(a) \
+ a = eina_list_free(a)
+
+#define EINA_LIST_PROMOTE_LIST(a, b) \
+ a = eina_list_promote_list(a, b)
+
+#ifdef EINA_LIST
+typedef Eina_List dd_list;
+#define DD_LIST_PREPEND(a, b) \
+ a = eina_list_prepend(a, b)
+#define DD_LIST_APPEND(a, b) \
+ a = eina_list_append(a, b)
+#define DD_LIST_REMOVE(a, b) \
+ a = eina_list_remove(a, b)
+#define DD_LIST_LENGTH(a) \
+ eina_list_count(a)
+#define DD_LIST_NTH(a, b) \
+ eina_list_nth(a, b)
+#define DD_LIST_FREE_LIST(a) \
+ a = eina_list_free(a)
+#define DD_LIST_FOREACH(head, elem, node) \
+ EINA_LIST_FOREACH(head, elem, node)
+#else
+#include <glib.h>
+typedef GList dd_list;
+#define DD_LIST_PREPEND(a, b) \
+ a = g_list_prepend(a, (gpointer)b)
+#define DD_LIST_APPEND(a, b) \
+ a = g_list_append(a, (gpointer)b)
+#define DD_LIST_REMOVE(a, b) \
+ a = g_list_remove(a, (gpointer)b)
+#define DD_LIST_LENGTH(a) \
+ g_list_length(a)
+#define DD_LIST_NTH(a, b) \
+ g_list_nth_data(a, b)
+#define DD_LIST_FREE_LIST(a) \
+ g_list_free(a)
+#define DD_LIST_FOREACH(head, elem, node) \
+ for (elem = head; elem && ((node = elem->data) != NULL); elem = elem->next, node = NULL)
+#endif
+
+#endif
diff --git a/src/deviced/dd-battery.h b/src/deviced/dd-battery.h
new file mode 100644
index 0000000..78fd9b3
--- /dev/null
+++ b/src/deviced/dd-battery.h
@@ -0,0 +1,35 @@
+/*
+ * deviced
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __DD_BATTERY_H__
+#define __DD_BATTERY_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file dd-battery.h
+ * @ingroup DEVICED_LIBRARY
+ * @brief This file provides for control of battery
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/deviced/dd-mmc.h b/src/deviced/dd-mmc.h
new file mode 100644
index 0000000..d8e9f3f
--- /dev/null
+++ b/src/deviced/dd-mmc.h
@@ -0,0 +1,61 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __DD_MMC_H__
+#define __DD_MMC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file dd-mmc.h
+ * @ingroup CAPI_SYSTEM_DEVICED
+ * @defgroup CAPI_SYSTEM_DEVICED_MMC_MODULE mmc
+ * @brief This file provides the API for control of mmc(sd-card)
+ */
+
+/**
+ * @addtogroup CAPI_SYSTEM_DEVICED_MMC_MODULE
+ * @{
+ */
+
+/**
+ * @par Description:
+ * This API is used to mount application to mmc.\n
+ * @param[in] pkgid what you want to mount and execute at mmc
+ * @return 0 on success, -1 if failed
+ * @par Example
+ * @code
+ * ...
+ * if (mmc_mount_app2ext("com.samsung.setting") < 0)
+ * printf("app2ext mount failed\n");
+ * ...
+ * @endcode
+ */
+int mmc_mount_app2ext(const char *pkdid);
+
+/**
+ * @} // end of CAPI_SYSTEM_DEVICED_MMC_MODULE
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/shared/battery.c b/src/shared/battery.c
new file mode 100644
index 0000000..7d7d238
--- /dev/null
+++ b/src/shared/battery.c
@@ -0,0 +1,25 @@
+/*
+ * deviced
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <vconf.h>
+#include <errno.h>
+#include <device-node.h>
+
+#include "log.h"
+#include "dd-battery.h"
diff --git a/src/shared/common.h b/src/shared/common.h
new file mode 100644
index 0000000..5a3ef23
--- /dev/null
+++ b/src/shared/common.h
@@ -0,0 +1,49 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DD_COMMON_H__
+#define __DD_COMMON_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifndef DEPRECATED
+#define DEPRECATED __attribute__ ((deprecated))
+#endif
+
+#ifndef __CONSTRUCTOR__
+#define __CONSTRUCTOR__ __attribute__ ((constructor))
+#endif
+
+#ifndef __DESTRUCTOR__
+#define __DESTRUCTOR__ __attribute__ ((destructor))
+#endif
+
+#ifdef __cplusplus
+
+}
+#endif
+#endif /* __DD_COMMON_H__ */
diff --git a/src/shared/log.h b/src/shared/log.h
new file mode 100644
index 0000000..1be64d7
--- /dev/null
+++ b/src/shared/log.h
@@ -0,0 +1,45 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __LOG_H__
+#define __LOG_H__
+
+#define FEATURE_DEVICED_DLOG
+
+#ifdef FEATURE_DEVICED_DLOG
+#define LOG_TAG "DEVICED"
+#include <dlog.h>
+#define _D(fmt, args...) SLOGD(fmt, ##args)
+#define _I(fmt, args...) SLOGI(fmt, ##args)
+#define _E(fmt, args...) SLOGE(fmt, ##args)
+#define _SD(fmt, arg...) SECURE_SLOGD(fmt, ##arg)
+#define _SI(fmt, arg...) SECURE_SLOGI(fmt, ##arg)
+#define _SW(fmt, arg...) SECURE_SLOGW(fmt, ##arg)
+#define _SE(fmt, arg...) SECURE_SLOGE(fmt, ##arg)
+#else
+#define _D(x, ...) do { } while (0)
+#define _I(x, ...) do { } while (0)
+#define _E(x, ...) do { } while (0)
+#define _SD(fmt, args...) do { } while (0)
+#define _SI(fmt, args...) do { } while (0)
+#define _SW(fmt, args...) do { } while (0)
+#define _SE(fmt, args...) do { } while (0)
+#endif
+
+#endif
diff --git a/src/shared/mmc.c b/src/shared/mmc.c
new file mode 100644
index 0000000..97c47f2
--- /dev/null
+++ b/src/shared/mmc.c
@@ -0,0 +1,162 @@
+/*
+ * deviced
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdarg.h>
+
+#include "common.h"
+#include "log.h"
+
+#define SYSMAN_MAXARG 16
+#define SYSMAN_MAXSTR 100
+#define BUFF_MAX 255
+
+struct sysnoti {
+ int pid;
+ int cmd;
+ char *type;
+ char *path;
+ int argc;
+ char *argv[SYSMAN_MAXARG];
+};
+
+#define PREDEF_MOUNT_APP2EXT "mountapp2ext"
+
+enum sysnoti_cmd {
+ ADD_SYSMAN_ACTION,
+ CALL_SYSMAN_ACTION
+};
+
+#define SYSNOTI_SOCKET_PATH "/tmp/sn"
+
+static inline int send_int(int fd, int val)
+{
+ return write(fd, &val, sizeof(int));
+}
+
+static inline int send_str(int fd, char *str)
+{
+ int len;
+ int ret;
+ if (str == NULL) {
+ len = 0;
+ ret = write(fd, &len, sizeof(int));
+ } else {
+ len = strlen(str);
+ if (len > SYSMAN_MAXSTR)
+ len = SYSMAN_MAXSTR;
+ write(fd, &len, sizeof(int));
+ ret = write(fd, str, len);
+ }
+ return ret;
+}
+
+static int sysnoti_send(struct sysnoti *msg)
+{
+ _E("--- %s: start", __FUNCTION__);
+ int client_len;
+ int client_sockfd;
+ int result;
+ struct sockaddr_un clientaddr;
+ int i;
+
+ client_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (client_sockfd == -1) {
+ _E("%s: socket create failed\n", __FUNCTION__);
+ return -1;
+ }
+ bzero(&clientaddr, sizeof(clientaddr));
+ clientaddr.sun_family = AF_UNIX;
+ strncpy(clientaddr.sun_path, SYSNOTI_SOCKET_PATH, sizeof(clientaddr.sun_path) - 1);
+ client_len = sizeof(clientaddr);
+
+ if (connect(client_sockfd, (struct sockaddr *)&clientaddr, client_len) <
+ 0) {
+ _E("%s: connect failed\n", __FUNCTION__);
+ close(client_sockfd);
+ return -1;
+ }
+
+ send_int(client_sockfd, msg->pid);
+ send_int(client_sockfd, msg->cmd);
+ send_str(client_sockfd, msg->type);
+ send_str(client_sockfd, msg->path);
+ send_int(client_sockfd, msg->argc);
+ for (i = 0; i < msg->argc; i++)
+ send_str(client_sockfd, msg->argv[i]);
+
+ _E("--- %s: read", __FUNCTION__);
+ read(client_sockfd, &result, sizeof(int));
+
+ close(client_sockfd);
+ _E("--- %s: end", __FUNCTION__);
+ return result;
+}
+
+static int deviced_call_predef_action(const char *type, int num, ...)
+{
+ _E("--- %s: start", __FUNCTION__);
+ struct sysnoti *msg;
+ int ret;
+ va_list argptr;
+
+ int i;
+ char *args = NULL;
+
+ if (type == NULL || num > SYSMAN_MAXARG) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ msg = malloc(sizeof(struct sysnoti));
+
+ if (msg == NULL) {
+ /* Do something for not enought memory error */
+ return -1;
+ }
+
+ msg->pid = getpid();
+ msg->cmd = CALL_SYSMAN_ACTION;
+ msg->type = (char *)type;
+ msg->path = NULL;
+
+ msg->argc = num;
+ va_start(argptr, num);
+ for (i = 0; i < num; i++) {
+ args = va_arg(argptr, char *);
+ msg->argv[i] = args;
+ }
+ va_end(argptr);
+
+ _E("--- %s: send msg", __FUNCTION__);
+ ret = sysnoti_send(msg);
+ free(msg);
+
+ _E("--- %s: end", __FUNCTION__);
+ return ret;
+}
+
+API int mmc_mount_app2ext(const char *str)
+{
+ return deviced_call_predef_action(PREDEF_MOUNT_APP2EXT, 1, str);
+}
diff --git a/ss_bs.c b/ss_bs.c
new file mode 100644
index 0000000..7548e11
--- /dev/null
+++ b/ss_bs.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sysman.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/types.h>
+#include <grp.h>
+#include <dirent.h>
+#include <Ecore_File.h>
+
+#include "ss_log.h"
+#include "ss_launch.h"
+
+#define CRASH_PID_MAX 7
+#define CRASH_MODE_MAX 2
+#define CRASH_TIME_MAX 65
+#define CRASH_POPUP_ON 1
+#define CRASH_POPUP_OFF 0
+#define CRASH_CHECK_SIZE (512 * 1024)
+#define CRASH_CHECK_DISK_PATH "/opt/usr"
+#define CRASH_LIMIT_NUM 5
+#define CRASH_ARG_NUM 6
+#define CRASH_DELIMITER "|"
+#define CRASH_VERIFY_MAX 5
+#define CRASH_PROCESSNAME_MAX NAME_MAX
+#define CRASH_EXEPATH_MAX NAME_MAX
+#define CRASH_ARG_MAX (CRASH_PROCESSNAME_MAX + CRASH_EXEPATH_MAX + CRASH_TIME_MAX + CRASH_PID_MAX + CRASH_MODE_MAX + CRASH_VERIFY_MAX)
+#define CRASH_NOTI_DIR "/opt/share/crash"
+#define CRASH_NOTI_FILE "curbs.log"
+#define CRASH_NOTI_PATH CRASH_NOTI_DIR"/"CRASH_NOTI_FILE
+#define CRASH_COREDUMP_PATH "/opt/usr/share/crash/core"
+#define CRASH_DUMP_PATH "/opt/usr/share/crash/dump"
+#define CRASH_INFO_PATH "/opt/share/crash/info"
+#define CRASH_WORKER_PATH "/usr/bin/crash-worker"
+#define CRASH_POPUP_PATH "/usr/apps/org.tizen.crash-popup/bin/crash-popup"
+
+static int noti_fd;
+static int add_noti(void);
+struct crash_arg
+{
+ char crash_mode[CRASH_MODE_MAX];
+ char crash_processname[CRASH_PROCESSNAME_MAX];
+ char crash_timestr[CRASH_TIME_MAX];
+ char crash_pid[CRASH_PID_MAX];
+ char crash_exepath[CRASH_EXEPATH_MAX];
+ char crash_verify[CRASH_VERIFY_MAX];
+};
+
+static int is_running_process(pid_t pid)
+{
+ char buf[PATH_MAX + 1];
+ snprintf(buf, sizeof(buf), "/proc/%d", pid);
+ if (!access(buf, R_OK))
+ return 1;
+ return 0;
+}
+static int make_noti_file(const char *path, const char *file)
+{
+ int fd;
+ char buf[PATH_MAX];
+ gid_t group_id;
+ struct group *group_entry;
+ mode_t old_mask;
+
+ PRT_TRACE("Make Noti File");
+ snprintf(buf, sizeof(buf), "%s/%s", path, file); /* buf - full path to file */
+ if (access(buf, F_OK) == 0) /* if file exists then return -1 */
+ return -1;
+
+ /* save old mask and set new calling process's file mode creation mask */
+ old_mask = umask(0);
+
+ mkdir(path, 0775); /* make directory, if exest then errno==EEXIST */
+ group_entry = getgrnam("crash"); /* need to find out group ID of "crash" group name */
+ if (group_entry == NULL) {
+ umask(old_mask); /* restore old file mask */
+ return -1;
+ }
+ chown(path, 0, group_entry->gr_gid); /* chown root:crash */
+ if ((fd = open(buf, O_CREAT, 0666)) < 0) { /* create crash file */
+ umask(old_mask); /* restore old file mask */
+ return -1;
+ }
+ fchown(fd, 0, group_entry->gr_gid); /* chown root:crash */
+ close(fd);
+ umask(old_mask); /* restore old file mask */
+
+ return 0;
+}
+static int make_coredump_dir(void)
+{
+ mode_t old_mask;
+ gid_t group_id;
+ struct group *group_entry;
+
+ PRT_TRACE("Make core dump directory");
+ if (access(CRASH_COREDUMP_PATH, F_OK) == 0) /* if file exists then return -1 */
+ return -1;
+
+ /* save old mask and set new calling process's file mode creation mask */
+ old_mask = umask(0);
+
+ mkdir(CRASH_COREDUMP_PATH, 0775); /* make directory, if exest then errno==EEXIST */
+ group_entry = getgrnam("crash"); /* need to find out group ID of "crash" group name*/
+ if (group_entry == NULL) {
+ umask(old_mask); /* restore old file mask */
+ return -1;
+ }
+ chown(CRASH_COREDUMP_PATH, 0, group_entry->gr_gid); /* chown root:crash */
+ umask(old_mask); /* restore old file mask */
+
+ return 0;
+}
+static int make_info_dir(void)
+{
+ mode_t old_mask;
+ gid_t group_id;
+ struct group *group_entry;
+
+ PRT_TRACE("Make crash info directory");
+ if (access(CRASH_INFO_PATH, F_OK) == 0) /* if file exists then return -1 */
+ return -1;
+
+ /* save old mask and set new calling process's file mode creation mask */
+ old_mask = umask(0);
+
+ mkdir(CRASH_INFO_PATH, 0775); /* make directory, if exest then errno==EEXIST */
+ group_entry = getgrnam("crash"); /* need to find out group ID of "crash" group name*/
+ if (group_entry == NULL) {
+ umask(old_mask); /* restore old file mask */
+ return -1;
+ }
+ chown(CRASH_INFO_PATH, 0, group_entry->gr_gid); /* chown root:crash */
+ umask(old_mask); /* restore old file mask */
+
+ return 0;
+}
+static int clean_coredump_dir(void)
+{
+ DIR *dir;
+ struct dirent *dp;
+ int dfd;
+ dir = opendir(CRASH_COREDUMP_PATH);
+ if (!dir) {
+ PRT_TRACE_ERR("opendir failed");
+ return 0;
+ }
+ dfd = dirfd(dir);
+ if (dfd < 0) return 0;
+ while ((dp = readdir(dir)) != NULL) {
+ const char *name = dp->d_name;
+ /* always skip "." and ".." */
+ if (name[0] == '.') {
+ if (name[1] == 0) continue;
+ if ((name[1] == '.') && (name[2] == 0)) continue;
+ }
+ if (unlinkat(dfd, name, 0) < 0) {
+ PRT_TRACE_ERR("clean_coredump_dir (%s)",name);
+ continue;
+ }
+ }
+ closedir(dir);
+ return 1;
+}
+static int clean_dump_dir(void)
+{
+ DIR *dir;
+ struct dirent *dp;
+ char dirname[PATH_MAX];
+
+ dir = opendir(CRASH_DUMP_PATH);
+ if (!dir) {
+ PRT_TRACE_ERR("opendir failed");
+ return 0;
+ }
+ while ((dp = readdir(dir)) != NULL) {
+ if (dp->d_type == DT_DIR) {
+ const char *name = dp->d_name;
+ /* always skip "." and ".." */
+ if (name[0] == '.') {
+ if (name[1] == 0) continue;
+ if ((name[1] == '.') && (name[2] == 0)) continue;
+ }
+ snprintf(dirname, sizeof(dirname), "%s/%s", CRASH_DUMP_PATH, name);
+ if (ecore_file_recursive_rm(dirname) == EINA_FALSE) {
+ PRT_TRACE_ERR("clean_dump_dir (%s)",dirname);
+ continue;
+ }
+ }
+ }
+ closedir(dir);
+ return 1;
+}
+static int clean_info_dir(void)
+{
+ DIR *dir;
+ struct dirent *dp;
+ int dfd;
+ dir = opendir(CRASH_INFO_PATH);
+ if (!dir) {
+ PRT_TRACE_ERR("opendir failed");
+ return 0;
+ }
+ dfd = dirfd(dir);
+ if (dfd < 0) return 0;
+ while ((dp = readdir(dir)) != NULL) {
+ const char *name = dp->d_name;
+ /* always skip "." and ".." */
+ if (name[0] == '.') {
+ if (name[1] == 0) continue;
+ if ((name[1] == '.') && (name[2] == 0)) continue;
+ }
+ if (unlinkat(dfd, name, 0) < 0) {
+ PRT_TRACE_ERR("clean_info_dir (%s)",name);
+ continue;
+ }
+ }
+ closedir(dir);
+ return 1;
+}
+static int crash_arg_parser(char *linebuffer, struct crash_arg *arg)
+{
+ char *ptr = NULL;
+ int verify_num = 0;
+ int verify_arg_num = 0;
+
+ if (linebuffer == NULL || arg == NULL) {
+ PRT_TRACE_ERR("crash_arg_parser input arguments is NULL");
+ return -1;
+ }
+ ptr = strtok(linebuffer, CRASH_DELIMITER);
+ if (ptr == NULL) {
+ PRT_TRACE_ERR("can't strtok linebuffer ptr(%s)", ptr);
+ return -1;
+ }
+ snprintf(arg->crash_mode, CRASH_MODE_MAX, "%s", ptr);
+ ptr = strtok(NULL, CRASH_DELIMITER);
+ if (ptr == NULL) {
+ PRT_TRACE_ERR("can't strtok linebuffer ptr(%s)", ptr);
+ return -1;
+ }
+ snprintf(arg->crash_processname, CRASH_PROCESSNAME_MAX, "%s", ptr);
+ ptr = strtok(NULL, CRASH_DELIMITER);
+ if (ptr == NULL) {
+ PRT_TRACE_ERR("can't strtok linebuffer ptr(%s)", ptr);
+ return -1;
+ }
+ snprintf(arg->crash_timestr, CRASH_TIME_MAX, "%s", ptr);
+ ptr = strtok(NULL, CRASH_DELIMITER);
+ if (ptr == NULL) {
+ PRT_TRACE_ERR("can't strtok linebuffer ptr(%s)", ptr);
+ return -1;
+ }
+ snprintf(arg->crash_pid, CRASH_PID_MAX, "%s", ptr);
+ ptr = strtok(NULL, CRASH_DELIMITER);
+ if (ptr == NULL) {
+ PRT_TRACE_ERR("can't strtok linebuffer ptr(%s)", ptr);
+ return -1;
+ }
+ snprintf(arg->crash_exepath, CRASH_EXEPATH_MAX, "%s", ptr);
+ ptr = strtok(NULL, CRASH_DELIMITER);
+ if (ptr == NULL) {
+ PRT_TRACE_ERR("can't strtok linebuffer ptr(%s)", ptr);
+ return -1;
+ }
+ snprintf(arg->crash_verify, CRASH_VERIFY_MAX, "%s", ptr);
+ verify_num = strlen(arg->crash_processname) + strlen(arg->crash_exepath);
+ verify_arg_num = atoi(arg->crash_verify);
+ PRT_TRACE("vnum %d vanum %d", verify_num, verify_arg_num);
+ if (verify_num == verify_arg_num)
+ return 1;
+ else
+ return 0;
+}
+static void launch_crash_worker(const char *filename, int popup_on)
+{
+ static int popup_pid = 0;
+ FILE *fp;
+ int ret = -1;
+ int len = 0;
+ char linebuffer[CRASH_ARG_MAX] = {0,};
+ char crash_worker_args[CRASH_ARG_MAX] = {0,};
+ struct crash_arg parsing_arg;
+ char param[CRASH_ARG_MAX];
+
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ return;
+ }
+ /* launch crash process */
+ while (fgets(linebuffer, CRASH_ARG_MAX, fp) != NULL) {
+ len = strlen(linebuffer);
+ if (!len || linebuffer[len - 1] != '\n') {
+ PRT_TRACE_ERR("crash inoti msg must be terminated with new line character\n");
+ break;
+ }
+ /* change last caracter from \n to \0 */
+ linebuffer[strlen(linebuffer) - 1] = '\0';
+ if (crash_arg_parser(linebuffer, &parsing_arg) != 1)
+ continue;
+ snprintf(crash_worker_args, sizeof(crash_worker_args), "%s %s %s %s %s",
+ parsing_arg.crash_mode, parsing_arg.crash_processname,
+ parsing_arg.crash_timestr, parsing_arg.crash_pid, parsing_arg.crash_exepath);
+ PRT_TRACE("crash_worker args(%s)", crash_worker_args);
+ PRT_TRACE("(%s%s%s)", parsing_arg.crash_mode,
+ parsing_arg.crash_processname, parsing_arg.crash_timestr);
+ ret = ss_launch_evenif_exist (CRASH_WORKER_PATH, crash_worker_args);
+ if (ret > 0) {
+ char buf[PATH_MAX];
+ FILE *fpAdj;
+ snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", ret);
+ fpAdj = fopen(buf, "w");
+ if (fpAdj != NULL) {
+ fprintf(fpAdj, "%d", (-17));
+ fclose(fpAdj);
+ }
+ }
+ if (popup_on) {
+ if (!is_running_process(popup_pid))
+ snprintf(param, sizeof(param), "%s %s",
+ parsing_arg.crash_processname, parsing_arg.crash_exepath);
+ popup_pid = ss_launch_evenif_exist (CRASH_POPUP_PATH, param);
+ }
+
+ if (popup_pid < 0) {
+ PRT_TRACE_ERR("popup failed)\n");
+ break;
+ }
+ }
+ fclose(fp);
+
+ if (ret != -1) {
+ fp = fopen(filename, "w");
+ if (fp == NULL) {
+ return;
+ }
+ fclose(fp);
+ }
+
+ return;
+}
+
+static Ecore_File_Monitor *crash_file_monitor;
+
+static Ecore_File_Monitor_Cb __crash_file_cb(void *data, Ecore_File_Monitor *em, Ecore_File_Event event, const char *path)
+{
+ switch (event) {
+ case ECORE_FILE_EVENT_DELETED_DIRECTORY:
+ case ECORE_FILE_EVENT_DELETED_SELF:
+ if (make_noti_file(CRASH_NOTI_DIR, CRASH_NOTI_FILE) < 0) {
+ launch_crash_worker(path, CRASH_POPUP_ON);
+ }
+ break;
+ case ECORE_FILE_EVENT_MODIFIED:
+ default:
+ launch_crash_worker(path, CRASH_POPUP_ON);
+ break;
+ }
+
+ return NULL;
+}
+static int _get_file_count(char *path)
+{
+ DIR *dir;
+ struct dirent *dp;
+ int count = 0;
+ dir = opendir(path);
+ if (!dir) return 0;
+ while ((dp = readdir(dir)) != NULL) {
+ const char *name = dp->d_name;
+ /* always skip "." and ".." */
+ if (name[0] == '.') {
+ if (name[1] == 0) continue;
+ if ((name[1] == '.') && (name[2] == 0)) continue;
+ }
+ count++;
+ }
+ closedir(dir);
+ return count;
+}
+/* check disk available size */
+static int _check_disk_available(void)
+{
+ struct statfs lstatfs;
+ int avail_size = 0;
+ if (statfs(CRASH_CHECK_DISK_PATH, &lstatfs) < 0)
+ return -1;
+ avail_size = (int)(lstatfs.f_bavail * (lstatfs.f_bsize/1024));
+ if (CRASH_CHECK_SIZE > avail_size)
+ return -1;
+ return 1;
+}
+
+int ss_bs_init(void)
+{
+ if (make_noti_file(CRASH_NOTI_DIR, CRASH_NOTI_FILE) < 0) {
+ PRT_TRACE_ERR("make_noti_file() failed");
+ launch_crash_worker(CRASH_NOTI_PATH, CRASH_POPUP_OFF);
+ }
+ if (make_info_dir() < 0) {
+ if (CRASH_LIMIT_NUM < _get_file_count(CRASH_INFO_PATH))
+ clean_info_dir();
+ }
+ if (make_coredump_dir() < 0) {
+ if (CRASH_LIMIT_NUM < _get_file_count(CRASH_COREDUMP_PATH)
+ || _check_disk_available() < 0)
+ clean_coredump_dir();
+ }
+ if (CRASH_LIMIT_NUM < _get_file_count(CRASH_DUMP_PATH))
+ clean_dump_dir();
+
+ if (ecore_file_init() == 0) {
+ PRT_TRACE_ERR("ecore_file_init() failed");
+ launch_crash_worker(CRASH_NOTI_PATH, CRASH_POPUP_OFF);
+ }
+
+ crash_file_monitor = ecore_file_monitor_add(CRASH_NOTI_PATH,(void *) __crash_file_cb, NULL);
+ if (!crash_file_monitor) {
+ PRT_TRACE_ERR("ecore_file_monitor_add() failed");
+ launch_crash_worker(CRASH_NOTI_PATH, CRASH_POPUP_OFF);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/ss_bs.h b/ss_bs.h
new file mode 100644
index 0000000..b7cc77f
--- /dev/null
+++ b/ss_bs.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_BS_H__
+#define __SS_BS_H__
+
+int ss_bs_init(void);
+
+#endif /* __SS_BS_H__ */
diff --git a/ss_common.c b/ss_common.c
new file mode 100644
index 0000000..fff43aa
--- /dev/null
+++ b/ss_common.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+/**
+ * Opens "/proc/$pid/oom_adj" file for w/r;
+ * Return: FILE pointer or NULL
+ */
+FILE * open_proc_oom_adj_file(int pid, const char *mode)
+{
+ char buf[32];
+ FILE *fp;
+
+ /* snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid); */
+ /*
+ * Warn that /proc/pid/oom_adj is deprecated, see
+ * Documentation/feature-removal-schedule.txt.
+ * Please use /proc/%d/oom_score_adj instead.
+ */
+ snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
+ fp = fopen(buf, mode);
+ return fp;
+}
+
diff --git a/ss_common.h b/ss_common.h
new file mode 100644
index 0000000..a7af544
--- /dev/null
+++ b/ss_common.h
@@ -0,0 +1,7 @@
+#ifndef _SS_COMMON_H
+#define _SS_COMMON_H
+
+FILE * open_proc_oom_adj_file(int pid, const char *mode);
+
+#endif /* _SS_COMMON_H */
+
diff --git a/ss_core.c b/ss_core.c
new file mode 100644
index 0000000..a5fb577
--- /dev/null
+++ b/ss_core.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <sysman.h>
+#include "include/ss_data.h"
+#include "ss_queue.h"
+#include "ss_log.h"
+#include "ss_predefine.h"
+#include "ss_core.h"
+
+enum ss_core_cmd_type {
+ SS_CORE_ACT_RUN,
+ SS_CORE_ACT_CLEAR
+};
+
+struct _internal_msg {
+ int type;
+ int pid;
+};
+
+static int core_pipe[2];
+Ecore_Fd_Handler *g_pipe_efd = NULL;
+
+static int __pipe_start(struct ss_main_data *ad);
+static int __pipe_stop(int fd);
+
+static int _ss_core_action_run(void *user_data,
+ struct ss_run_queue_entry *rq_entry)
+{
+ struct ss_action_entry *act_entry = rq_entry->action_entry;
+ int ret;
+ char tmp[128];
+
+ rq_entry->state = SS_STATE_RUNNING;
+ ret = act_entry->predefine_action(rq_entry->argc, rq_entry->argv);
+ if (ret <= 0) {
+ if (ret < 0)
+ PRT_TRACE_ERR("[SYSMAN] predefine action failed");
+ goto fast_done;
+ } else {
+ snprintf(tmp, sizeof(tmp), "/proc/%d/status", ret);
+ if (access(tmp, R_OK) == 0)
+ rq_entry->forked_pid = ret;
+ else
+ goto fast_done;
+ }
+ return 0;
+
+ fast_done:
+ rq_entry->forked_pid = -1;
+ rq_entry->state = SS_STATE_DONE;
+ ss_core_action_clear(-1);
+ return 0;
+}
+
+static int core_pipe_cb(void *userdata, Ecore_Fd_Handler * fd_handler)
+{
+ struct ss_main_data *ad = (struct ss_main_data *)userdata;
+ struct _internal_msg p_msg;
+ int retry_count = 0;
+ int r = -1;
+ if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
+ PRT_TRACE_ERR
+ ("ecore_main_fd_handler_active_get error , return\n");
+ return 1;
+ }
+
+ while (retry_count < 5) {
+ r = read(core_pipe[0], &p_msg, sizeof(struct _internal_msg));
+ if (r < 0) {
+ if (errno == EINTR) {
+ PRT_TRACE_ERR("Re-read for error(EINTR)");
+ retry_count++;
+ continue;
+ } else {
+ __pipe_stop(core_pipe[0]);
+ __pipe_stop(core_pipe[1]);
+ PRT_TRACE_ERR("restart pipe fd");
+ __pipe_start(ad);
+ }
+ } else {
+ break;
+ }
+ }
+
+ switch (p_msg.type) {
+ case SS_CORE_ACT_RUN:
+ ss_run_queue_run(SS_STATE_INIT, _ss_core_action_run, ad);
+ break;
+ case SS_CORE_ACT_CLEAR:
+ ss_run_queue_del_bypid(p_msg.pid);
+ break;
+ }
+ return 1;
+}
+
+int ss_core_action_run()
+{
+ struct _internal_msg p_msg;
+
+ p_msg.type = SS_CORE_ACT_RUN;
+ p_msg.pid = 0;
+ write(core_pipe[1], &p_msg, sizeof(struct _internal_msg));
+
+ return 0;
+}
+
+int ss_core_action_clear(int pid)
+{
+ struct _internal_msg p_msg;
+
+ p_msg.type = SS_CORE_ACT_CLEAR;
+ p_msg.pid = pid;
+ write(core_pipe[1], &p_msg, sizeof(struct _internal_msg));
+
+ return 0;
+}
+
+int ss_core_init(struct ss_main_data *ad)
+{
+ __pipe_stop(core_pipe[0]);
+ __pipe_stop(core_pipe[1]);
+
+ if (__pipe_start(ad) == -1) {
+ PRT_TRACE_ERR("fail pipe control fd init");
+ return -1;
+ }
+ return 0;
+}
+
+static int __pipe_start(struct ss_main_data *ad)
+{
+ if (pipe(core_pipe) < 0) {
+ PRT_TRACE_ERR("pipe cannot create");
+ exit(EXIT_FAILURE);
+ }
+
+ g_pipe_efd = ecore_main_fd_handler_add(core_pipe[0], ECORE_FD_READ,
+ core_pipe_cb, ad, NULL, NULL);
+ if (!g_pipe_efd) {
+ PRT_TRACE_ERR("error ecore_main_fd_handler_add");
+ return -1;
+ }
+ return 0;
+}
+
+static int __pipe_stop(int fd)
+{
+ if (g_pipe_efd) {
+ ecore_main_fd_handler_del(g_pipe_efd);
+ g_pipe_efd = NULL;
+ }
+ if (fd >=0)
+ close(fd);
+
+ return 0;
+}
diff --git a/ss_core.h b/ss_core.h
new file mode 100644
index 0000000..d35e345
--- /dev/null
+++ b/ss_core.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_CORE_H__
+#define __SS_CORE_H__
+
+#include "include/ss_data.h"
+
+int ss_core_action_run();
+int ss_core_action_clear(int pid);
+int ss_core_init(struct ss_main_data *ad);
+
+#endif /* __SS_CORE_H__ */
diff --git a/ss_cpu_handler.c b/ss_cpu_handler.c
new file mode 100644
index 0000000..e9a808e
--- /dev/null
+++ b/ss_cpu_handler.c
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <fcntl.h>
+
+#include "device-node.h"
+#include "ss_log.h"
+#include "include/ss_data.h"
+#include "vconf.h"
+
+#define DEFAULT_MAX_CPU_FREQ 1200000
+#define DEFAULT_MIN_CPU_FREQ 100000
+#define POWER_SAVING_CPUFREQ 800000
+
+static int max_cpu_freq_limit = -1;
+static int min_cpu_freq_limit = -1;
+static int cur_max_cpu_freq = INT_MAX;
+static int cur_min_cpu_freq = INT_MIN;
+
+static Eina_List *max_cpu_freq_list;
+static Eina_List *min_cpu_freq_list;
+
+struct cpu_freq_entry {
+ int pid;
+ int freq;
+};
+
+static void __set_freq_limit();
+static int __is_entry_enble(int pid);
+static int __remove_entry_from_max_cpu_freq_list(int pid);
+static int __remove_entry_from_min_cpu_freq_list(int pid);
+static int __add_entry_to_max_cpu_freq_list(int pid, int freq);
+static int __add_entry_to_min_cpu_freq_list(int pid, int freq);
+static int __write_max_cpu_freq(int freq);
+static int __write_min_cpu_freq(int freq);
+
+int set_max_frequency_action(int argc, char **argv)
+{
+ int r;
+
+ if (argc < 2)
+ return -1;
+
+ r = __add_entry_to_max_cpu_freq_list(atoi(argv[0]), atoi(argv[1]));
+ if (r < 0) {
+ PRT_TRACE_ERR("Add entry failed");
+ return -1;
+ }
+
+ r = __write_max_cpu_freq(cur_max_cpu_freq);
+ if (r < 0) {
+ PRT_TRACE_ERR("Write entry failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+int set_min_frequency_action(int argc, char **argv)
+{
+ int r;
+
+ if (argc < 2)
+ return -1;
+
+ r = __add_entry_to_min_cpu_freq_list(atoi(argv[0]), atoi(argv[1]));
+ if (r < 0) {
+ PRT_TRACE_ERR("Add entry failed");
+ return -1;
+ }
+
+ r = __write_min_cpu_freq(cur_min_cpu_freq);
+ if (r < 0) {
+ PRT_TRACE_ERR("Write entry failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+int release_max_frequency_action(int argc, char **argv)
+{
+ int r;
+ if (argc < 1)
+ return -1;
+
+ r = __remove_entry_from_max_cpu_freq_list(atoi(argv[0]));
+ if (r < 0) {
+ PRT_TRACE_ERR("Remove entry failed");
+ return -1;
+ }
+
+ if (cur_max_cpu_freq == INT_MAX)
+ cur_max_cpu_freq = max_cpu_freq_limit;
+
+ r = __write_max_cpu_freq(cur_max_cpu_freq);
+ if (r < 0) {
+ PRT_TRACE_ERR("Write freq failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+int release_min_frequency_action(int argc, char **argv)
+{
+ int r;
+
+ if (argc < 1)
+ return -1;
+
+ r = __remove_entry_from_min_cpu_freq_list(atoi(argv[0]));
+ if (r < 0) {
+ PRT_TRACE_ERR("Remove entry failed");
+ return -1;
+ }
+
+ if (cur_min_cpu_freq == INT_MIN)
+ cur_min_cpu_freq = min_cpu_freq_limit;
+
+ r = __write_min_cpu_freq(cur_min_cpu_freq);
+ if (r < 0) {
+ PRT_TRACE_ERR("Write entry failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int power_saving_cb(keynode_t *key_nodes, void *data)
+{
+ int ret = -1;
+ int power_saving_stat = -1;
+ int power_saving_cpu_stat = -1;
+
+ power_saving_stat = vconf_keynode_get_bool(key_nodes);
+ if (power_saving_stat == 1) {
+ if (vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_CPU, &power_saving_cpu_stat) == 0) {
+ if (power_saving_cpu_stat == 1) {
+ ret = __add_entry_to_max_cpu_freq_list(getpid(), POWER_SAVING_CPUFREQ);
+ if (ret < 0) {
+ PRT_TRACE_ERR("Add entry failed");
+ return -1;
+ }
+ }
+ } else {
+ PRT_TRACE_ERR("failed to get vconf key");
+ return -1;
+ }
+ } else {
+ ret = __remove_entry_from_max_cpu_freq_list(getpid());
+ if (ret < 0) {
+ PRT_TRACE_ERR("Remove entry failed");
+ return -1;
+ }
+ if (cur_max_cpu_freq == INT_MIN)
+ cur_max_cpu_freq = max_cpu_freq_limit;
+ }
+ ret = __write_max_cpu_freq(cur_max_cpu_freq);
+ if (ret < 0) {
+ PRT_TRACE_ERR("Write failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int power_saving_cpu_cb(keynode_t *key_nodes, void *data)
+{
+ int ret = -1;
+ int power_saving_stat = -1;
+ int power_saving_cpu_stat = -1;
+
+ if (vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS, &power_saving_stat) == 0) {
+ if (power_saving_stat == 1) {
+ power_saving_cpu_stat = vconf_keynode_get_bool(key_nodes);
+ if (power_saving_cpu_stat == 1) {
+ ret = __add_entry_to_max_cpu_freq_list(getpid(), POWER_SAVING_CPUFREQ);
+ if (ret < 0) {
+ PRT_TRACE_ERR("Add entry failed");
+ return -1;
+ }
+ } else {
+ ret = __remove_entry_from_max_cpu_freq_list(getpid());
+ if (ret < 0) {
+ PRT_TRACE_ERR("Remove entry failed");
+ return -1;
+ }
+ if (cur_max_cpu_freq == INT_MAX)
+ cur_max_cpu_freq = max_cpu_freq_limit;
+ }
+ ret = __write_max_cpu_freq(cur_max_cpu_freq);
+ if (ret < 0) {
+ PRT_TRACE_ERR("Write failed");
+ return -1;
+ }
+ }
+ } else {
+ PRT_TRACE_ERR("failed to get vconf key");
+ return -1;
+ }
+
+ return 0;
+}
+
+int ss_cpu_handler_init(void)
+{
+ __set_freq_limit();
+
+ ss_action_entry_add_internal(PREDEF_SET_MAX_FREQUENCY, set_max_frequency_action, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_SET_MIN_FREQUENCY, set_min_frequency_action, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_RELEASE_MAX_FREQUENCY, release_max_frequency_action, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_RELEASE_MIN_FREQUENCY, release_min_frequency_action, NULL, NULL);
+
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS, (void *)power_saving_cb, NULL);
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_CPU, (void *)power_saving_cpu_cb, NULL);
+
+ return 0;
+}
+
+static void __set_freq_limit()
+{
+ int ret;
+ int power_saving_stat = -1;
+ int power_saving_cpu_stat = -1;
+
+ ret = device_get_property(DEVICE_TYPE_CPU, PROP_CPU_CPUINFO_MAX_FREQ, &max_cpu_freq_limit);
+ if (ret < 0) {
+ PRT_TRACE_ERR("get cpufreq cpuinfo max readerror: %s", strerror(errno));
+ max_cpu_freq_limit = DEFAULT_MAX_CPU_FREQ;
+ }
+
+ ret = device_get_property(DEVICE_TYPE_CPU, PROP_CPU_CPUINFO_MIN_FREQ, &min_cpu_freq_limit);
+ if (ret < 0) {
+ PRT_TRACE_ERR("get cpufreq cpuinfo min readerror: %s", strerror(errno));
+ min_cpu_freq_limit = DEFAULT_MIN_CPU_FREQ;
+ }
+
+ /* check power saving */
+ if (vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS, &power_saving_stat) == 0) {
+ if (power_saving_stat == 1) {
+ if (vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_CPU, &power_saving_cpu_stat) == 0) {
+ if (power_saving_cpu_stat == 1) {
+ ret = __add_entry_to_max_cpu_freq_list(getpid(), POWER_SAVING_CPUFREQ);
+ if (ret < 0) {
+ PRT_TRACE_ERR("Add entry failed");
+ return;
+ }
+ ret = __write_max_cpu_freq(cur_max_cpu_freq);
+ if (ret < 0) {
+ PRT_TRACE_ERR("Write entry failed");
+ return;
+ }
+ }
+ } else {
+ PRT_TRACE_ERR("failed to get vconf key");
+ }
+ }
+ } else {
+ PRT_TRACE_ERR("failed to get vconf key");
+ }
+}
+
+static int __is_entry_enable(int pid)
+{
+ char pid_path[PATH_MAX];
+
+ snprintf(pid_path, PATH_MAX, "/proc/%d", pid);
+ if (access(pid_path, F_OK) < 0) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int __remove_entry_from_max_cpu_freq_list(int pid)
+{
+ Eina_List *tmp;
+ Eina_List *tmp_next;
+ struct cpu_freq_entry *entry;
+
+ cur_max_cpu_freq = INT_MAX;
+
+ EINA_LIST_FOREACH_SAFE(max_cpu_freq_list, tmp, tmp_next, entry) {
+ if (entry != NULL) {
+ if ((!__is_entry_enable(entry->pid)) || (entry->pid == pid)) {
+ max_cpu_freq_list = eina_list_remove(max_cpu_freq_list, entry);
+ free(entry);
+ continue;
+ }
+
+ if (entry->freq < cur_max_cpu_freq) {
+ cur_max_cpu_freq = entry->freq;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int __remove_entry_from_min_cpu_freq_list(int pid)
+{
+ Eina_List *tmp;
+ Eina_List *tmp_next;
+ struct cpu_freq_entry *entry;
+
+ cur_min_cpu_freq = INT_MIN;
+
+ EINA_LIST_FOREACH_SAFE(min_cpu_freq_list, tmp, tmp_next, entry) {
+ if (entry != NULL) {
+ if ((!__is_entry_enable(entry->pid)) || (entry->pid == pid)) {
+ min_cpu_freq_list = eina_list_remove(min_cpu_freq_list, entry);
+ free(entry);
+ continue;
+ }
+
+ if (entry->freq > cur_min_cpu_freq) {
+ cur_min_cpu_freq = entry->freq;
+ }
+
+ }
+ }
+
+ return 0;
+}
+
+static int __add_entry_to_max_cpu_freq_list(int pid, int freq)
+{
+ int r;
+ struct cpu_freq_entry *entry;
+
+ r = __remove_entry_from_max_cpu_freq_list(pid);
+ if (r < 0) {
+ PRT_TRACE_ERR("Remove duplicated entry failed");
+ }
+
+ if (freq < cur_max_cpu_freq) {
+ cur_max_cpu_freq = freq;
+ }
+
+ entry = malloc(sizeof(struct cpu_freq_entry));
+ if (!entry) {
+ PRT_TRACE_ERR("Malloc failed");
+ return -1;
+ }
+
+ entry->pid = pid;
+ entry->freq = freq;
+
+ max_cpu_freq_list = eina_list_prepend(max_cpu_freq_list, entry);
+ if (!max_cpu_freq_list) {
+ PRT_TRACE_ERR("eina_list_prepend failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __add_entry_to_min_cpu_freq_list(int pid, int freq)
+{
+ int r;
+ struct cpu_freq_entry *entry;
+
+ r = __remove_entry_from_min_cpu_freq_list(pid);
+ if (r < 0) {
+ PRT_TRACE_ERR("Remove duplicated entry failed");
+ }
+
+ if (freq > cur_min_cpu_freq) {
+ cur_min_cpu_freq = freq;
+ }
+
+ entry = malloc(sizeof(struct cpu_freq_entry));
+ if (!entry) {
+ PRT_TRACE_ERR("Malloc failed");
+ return -1;
+ }
+
+ entry->pid = pid;
+ entry->freq = freq;
+
+ min_cpu_freq_list = eina_list_prepend(min_cpu_freq_list, entry);
+ if (!min_cpu_freq_list) {
+ PRT_TRACE_ERR("eina_list_prepend failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __write_max_cpu_freq(int freq)
+{
+ int ret;
+
+ ret = device_set_property(DEVICE_TYPE_CPU, PROP_CPU_SCALING_MAX_FREQ, freq);
+ if (ret < 0) {
+ PRT_TRACE_ERR("set cpufreq max freq write error: %s", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __write_min_cpu_freq(int freq)
+{
+ int ret;
+
+ ret = device_set_property(DEVICE_TYPE_CPU, PROP_CPU_SCALING_MIN_FREQ, freq);
+ if (ret < 0) {
+ PRT_TRACE_ERR("set cpufreq min freq write error: %s", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/ss_cpu_handler.h b/ss_cpu_handler.h
new file mode 100644
index 0000000..7c72eb7
--- /dev/null
+++ b/ss_cpu_handler.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_CPU_HANDLER_H__
+#define __SS_CPU_HANDLER_H__
+
+int ss_cpu_handler_init(void);
+
+#endif /* __SS_CPU_HANDKER_H__ */
diff --git a/ss_device_change_handler.c b/ss_device_change_handler.c
new file mode 100755
index 0000000..9129a24
--- /dev/null
+++ b/ss_device_change_handler.c
@@ -0,0 +1,670 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <vconf.h>
+#include <sysman.h>
+#include <pmapi.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <syspopup_caller.h>
+#include <aul.h>
+#include <bundle.h>
+#include <dirent.h>
+#include <libudev.h>
+#include "ss_queue.h"
+#include "ss_log.h"
+#include "ss_device_handler.h"
+#include "device-node.h"
+#include "ss_noti.h"
+#include "include/ss_data.h"
+#include "sys_pci_noti/sys_pci_noti.h"
+#include "ss_predefine.h"
+#define BUFF_MAX 255
+#define SYS_CLASS_INPUT "/sys/class/input"
+#define USBCON_EXEC_PATH PREFIX"/bin/usb-server"
+#define DEFAULT_USB_INFO_PATH "/tmp/usb_default"
+#define STORE_DEFAULT_USB_INFO "usb-devices > "DEFAULT_USB_INFO_PATH
+#define HDMI_NOT_SUPPORTED (-1)
+#ifdef ENABLE_EDBUS_USE
+#include <E_DBus.h>
+static E_DBus_Connection *conn;
+#endif /* ENABLE_EDBUS_USE */
+
+typedef enum {
+ CB_NOTI_BATT_CHARGE,
+ CB_NOTI_BATT_LOW,
+ CB_NOTI_BATT_FULL,
+ CB_NOTI_MAX
+} cb_noti_type;
+
+typedef enum {
+ CB_NOTI_OFF = 0,
+ CB_NOTI_ON = 1
+} cb_noti_onoff_type;
+
+struct input_event {
+ long dummy[2];
+ unsigned short type;
+ unsigned short code;
+ int value;
+};
+
+enum snd_jack_types {
+ SND_JACK_HEADPHONE = 0x0001,
+ SND_JACK_MICROPHONE = 0x0002,
+ SND_JACK_HEADSET = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE,
+ SND_JACK_LINEOUT = 0x0004,
+ SND_JACK_MECHANICAL = 0x0008, /* If detected separately */
+ SND_JACK_VIDEOOUT = 0x0010,
+ SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT,
+};
+
+#define CHANGE_ACTION "change"
+#define ENV_FILTER "CHGDET"
+#define ENV_VALUE_USB "usb"
+#define ENV_VALUE_CHARGER "charger"
+#define ENV_VALUE_EARJACK "earjack"
+#define ENV_VALUE_EARKEY "earkey"
+#define ENV_VALUE_TVOUT "tvout"
+#define ENV_VALUE_HDMI "hdmi"
+#define ENV_VALUE_KEYBOARD "keyboard"
+
+
+#define ABNORMAL_POPUP_COUNTER 5
+
+static int input_device_number;
+
+static struct udev_monitor *mon = NULL;
+static struct udev *udev = NULL;
+static Ecore_Fd_Handler *ufdh = NULL;
+
+static int uevent_control_cb(void *data, Ecore_Fd_Handler *fd_handler);
+
+static int check_lowbat_charge_device(int bInserted)
+{
+ static int bChargeDeviceInserted = 0;
+ int val = -1;
+ int bat_state = -1;
+ int ret = -1;
+ if (bInserted == 1) {
+ if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_NOW, &val) == 0) {
+ if (val == 1)
+ bChargeDeviceInserted = 1;
+ return 0;
+ }
+ } else if (bInserted == 0) {
+ if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_NOW, &val) == 0) {
+ if (val == 0 && bChargeDeviceInserted == 1) {
+ bChargeDeviceInserted = 0;
+ //low bat popup during charging device removing
+ if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state) == 0) {
+ if(bat_state < VCONFKEY_SYSMAN_BAT_NORMAL
+ || bat_state == VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF) {
+ bundle *b = NULL;
+ b = bundle_create();
+ if(bat_state == VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF)
+ bundle_add(b,"_SYSPOPUP_CONTENT_", "poweroff");
+ else
+ bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
+ ret = syspopup_launch("lowbat-syspopup", b);
+ if (ret < 0) {
+ PRT_TRACE_EM("popup lauch failed\n");
+ }
+ bundle_free(b);
+ }
+ } else {
+ PRT_TRACE_ERR("failed to get vconf key");
+ return -1;
+ }
+ }
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static void usb_chgdet_cb(struct ss_main_data *ad)
+{
+ int val = -1;
+ char params[BUFF_MAX];
+
+ predefine_pm_change_state(LCD_NORMAL);
+
+ /* check charging now */
+ ss_lowbat_is_charge_in_now();
+ /* check current battery level */
+ ss_lowbat_monitor(NULL);
+ ss_action_entry_call_internal(PREDEF_USBCON, 0);
+ if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &val) == 0) {
+ PRT_TRACE("jack - usb changed %d",val);
+ check_lowbat_charge_device(val);
+ if (val==1) {
+ snprintf(params, sizeof(params), "%d", CB_NOTI_BATT_CHARGE);
+ ss_launch_if_noexist("/usr/bin/sys_device_noti", params);
+ PRT_TRACE("usb device notification");
+ }
+ } else {
+ PRT_TRACE_ERR("fail to get usb_online status");
+ }
+}
+
+static void __sync_usb_status(void)
+{
+ int val = -1;
+ int status = -1;
+ if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &val) != 0 ||
+ vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS,&status) != 0)
+ return;
+ if ((val == 1 && status == VCONFKEY_SYSMAN_USB_DISCONNECTED) ||
+ (val == 0 && status == VCONFKEY_SYSMAN_USB_AVAILABLE))
+ ss_action_entry_call_internal(PREDEF_USBCON, 0);
+}
+
+static void ta_chgdet_cb(struct ss_main_data *ad)
+{
+ int val = -1;
+ int ret = -1;
+ int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
+ char params[BUFF_MAX];
+
+ predefine_pm_change_state(LCD_NORMAL);
+
+ /* check charging now */
+ ss_lowbat_is_charge_in_now();
+ /* check current battery level */
+ ss_lowbat_monitor(NULL);
+
+ if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_TA_ONLINE, &val) == 0) {
+ PRT_TRACE("jack - ta changed %d",val);
+ check_lowbat_charge_device(val);
+ vconf_set_int(VCONFKEY_SYSMAN_CHARGER_STATUS, val);
+ if (val == 0) {
+ pm_unlock_state(LCD_OFF, STAY_CUR_STATE);
+ } else {
+ pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
+ snprintf(params, sizeof(params), "%d", CB_NOTI_BATT_CHARGE);
+ ss_launch_if_noexist("/usr/bin/sys_device_noti", params);
+ PRT_TRACE("ta device notification");
+ }
+ __sync_usb_status();
+ }
+ else
+ PRT_TRACE_ERR("failed to get ta status\n");
+}
+
+static void earjack_chgdet_cb(struct ss_main_data *ad)
+{
+ PRT_TRACE("jack - earjack changed\n");
+ ss_action_entry_call_internal(PREDEF_EARJACKCON, 0);
+}
+
+static void earkey_chgdet_cb(struct ss_main_data *ad)
+{
+ int val;
+ PRT_TRACE("jack - earkey changed\n");
+ if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_EARKEY_ONLINE, &val) == 0)
+ vconf_set_int(VCONFKEY_SYSMAN_EARJACKKEY, val);
+}
+
+static void tvout_chgdet_cb(struct ss_main_data *ad)
+{
+ PRT_TRACE("jack - tvout changed\n");
+ pm_change_state(LCD_NORMAL);
+}
+
+static void hdmi_chgdet_cb(struct ss_main_data *ad)
+{
+ int val;
+ int ret = -1;
+
+ pm_change_state(LCD_NORMAL);
+ if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_HDMI_SUPPORT, &val) == 0) {
+ if (val!=1) {
+ PRT_TRACE_ERR("target is not support HDMI");
+ vconf_set_int(VCONFKEY_SYSMAN_HDMI, HDMI_NOT_SUPPORTED);
+ return;
+ }
+ }
+ if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_HDMI_ONLINE, &val) == 0) {
+ PRT_TRACE("jack - hdmi changed %d",val);
+ vconf_set_int(VCONFKEY_SYSMAN_HDMI,val);
+ if(val == 1)
+ pm_lock_state(LCD_NORMAL, GOTO_STATE_NOW, 0);
+ else
+ pm_unlock_state(LCD_NORMAL, PM_SLEEP_MARGIN);
+ } else {
+ PRT_TRACE_ERR("failed to get hdmi_online status");
+ }
+}
+
+static void keyboard_chgdet_cb(struct ss_main_data *ad)
+{
+ int val = -1;
+
+ if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_KEYBOARD_ONLINE, &val) == 0) {
+ PRT_TRACE("jack - keyboard changed %d",val);
+ if(val != 1)
+ val = 0;
+ vconf_set_int(VCONFKEY_SYSMAN_SLIDING_KEYBOARD, val);
+ } else {
+ vconf_set_int(VCONFKEY_SYSMAN_SLIDING_KEYBOARD, VCONFKEY_SYSMAN_SLIDING_KEYBOARD_NOT_SUPPORTED);
+ }
+}
+
+static void mmc_chgdet_cb(void *data)
+{
+ static bool first, inserted;
+ int mmc_status;
+ int ret = -1;
+ int val = -1;
+
+ /* at first time, this part will be judge mmc is already inserted or not. */
+ if (!first) {
+ vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_status);
+ if (mmc_status == VCONFKEY_SYSMAN_MMC_MOUNTED)
+ inserted = true;
+ first = true;
+ }
+
+ if (data == NULL) {
+ /* when removed mmc, emul kernel notify twice
+ * So this code ignores second event */
+ if (!inserted)
+ return;
+ inserted = false;
+ PRT_TRACE("mmc removed");
+ ss_mmc_removed();
+ } else {
+ /* when inserted mmc, emul kernel notify twice(insert, changed)
+ * So this code ignores second event */
+ if (inserted)
+ return;
+ inserted = true;
+ PRT_TRACE("mmc added");
+ ret = ss_mmc_inserted();
+ if (ret == -1) {
+ vconf_get_int(VCONFKEY_SYSMAN_MMC_MOUNT,&val);
+ if (val == VCONFKEY_SYSMAN_MMC_MOUNT_FAILED) {
+ bundle *b = NULL;
+ b = bundle_create();
+ if (b == NULL) {
+ PRT_TRACE_ERR("error bundle_create()");
+ return;
+ }
+ bundle_add(b, "_SYSPOPUP_CONTENT_", "mounterr");
+ ret = syspopup_launch("mmc-syspopup", b);
+ if (ret < 0) {
+ PRT_TRACE_ERR("popup launch failed");
+ }
+ bundle_free(b);
+ } else if (val == VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED) {
+ bundle *b = NULL;
+ b = bundle_create();
+ if (b == NULL) {
+ PRT_TRACE_ERR("error bundle_create()");
+ return;
+ }
+ bundle_add(b, "_SYSPOPUP_CONTENT_", "mountrdonly");
+ ret = syspopup_launch("mmc-syspopup", b);
+ if (ret < 0) {
+ PRT_TRACE_ERR("popup launch failed");
+ }
+ bundle_free(b);
+ }
+ }
+ }
+}
+
+static void ums_unmount_cb(void *data)
+{
+ umount(MOVINAND_MOUNT_POINT);
+}
+
+static int __check_abnormal_popup_launch(void)
+{
+ static int noti_count = 0;
+ if (noti_count >= ABNORMAL_POPUP_COUNTER) {
+ noti_count = 0;
+ return 0;
+ } else {
+ noti_count++;
+ return -EAGAIN;
+ }
+}
+
+static void charge_cb(struct ss_main_data *ad)
+{
+ int val = -1;
+ int charge_now = -1;
+ int capacity = -1;
+ char params[BUFF_MAX];
+ static int bat_full_noti = 0;
+
+ ss_lowbat_monitor(NULL);
+
+ if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_NOW, &charge_now) != 0 ||
+ device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CAPACITY, &capacity) != 0)
+ PRT_TRACE_ERR("fail to get battery node value");
+ if (charge_now == 0 && capacity == 0) {
+ PRT_TRACE_ERR("target will be shut down");
+ ss_action_entry_call_internal(PREDEF_LOWBAT, 1, POWER_OFF_BAT_ACT);
+ return;
+ }
+
+ if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_HEALTH, &val) == 0) {
+ if (val==BATTERY_OVERHEAT || val==BATTERY_COLD) {
+ PRT_TRACE_ERR("Battery health status is not good (%d)", val);
+
+ if (__check_abnormal_popup_launch() != 0)
+ return;
+
+ if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CAPACITY, &val) == 0 && val <= 0)
+ ss_action_entry_call_internal(PREDEF_LOWBAT, 1, POWER_OFF_BAT_ACT);
+ else
+ ss_action_entry_call_internal(PREDEF_LOWBAT, 1, CHARGE_ERROR_ACT);
+ return;
+ }
+ } else {
+ PRT_TRACE_ERR("failed to get battery health status");
+ }
+ device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_FULL, &val);
+ if (val==0) {
+ if (bat_full_noti==1) {
+ snprintf(params, sizeof(params), "%d %d", CB_NOTI_BATT_FULL, CB_NOTI_OFF);
+ ss_launch_if_noexist("/usr/bin/sys_device_noti", params);
+ }
+ bat_full_noti = 0;
+ } else {
+ if (val==1 && bat_full_noti==0) {
+ bat_full_noti = 1;
+ PRT_TRACE("battery full noti");
+ snprintf(params, sizeof(params), "%d %d", CB_NOTI_BATT_FULL, CB_NOTI_ON);
+ ss_launch_if_noexist("/usr/bin/sys_device_noti", params);
+ }
+ }
+}
+
+#ifdef ENABLE_EDBUS_USE
+static void cb_xxxxx_signaled(void *data, DBusMessage * msg)
+{
+ char *args;
+ DBusError err;
+ struct ss_main_data *ad;
+
+ ad = data;
+
+ dbus_error_init(&err);
+ if (dbus_message_get_args
+ (msg, &err, DBUS_TYPE_STRING, &args, DBUS_TYPE_INVALID)) {
+ if (!strcmp(args, "action")) ; /* action */
+ }
+
+ return;
+}
+#endif /* ENABLE_EDBUS_USE */
+
+static void usb_host_chgdet_cb(keynode_t *in_key, struct ss_main_data *ad)
+{
+ PRT_TRACE("ENTER: usb_host_chgdet_cb()");
+ int status;
+ int ret = vconf_get_int(VCONFKEY_SYSMAN_USB_HOST_STATUS, &status);
+ if (ret != 0) {
+ PRT_TRACE_ERR("vconf get failed(VCONFKEY_SYSMAN_USB_HOST_STATUS)\n");
+ return ;
+ }
+
+ if(VCONFKEY_SYSMAN_USB_HOST_CONNECTED == status) {
+ int pid = ss_launch_if_noexist(USBCON_EXEC_PATH, NULL);
+ if (pid < 0) {
+ PRT_TRACE("usb-server launching failed\n");
+ return;
+ }
+ }
+ PRT_TRACE("EXIT: usb_host_chgdet_cb()");
+}
+
+static void usb_host_add_cb()
+{
+ PRT_TRACE("ENTER: usb_host_add_cb()\n");
+ int status;
+ int ret = vconf_get_int(VCONFKEY_SYSMAN_USB_HOST_STATUS, &status);
+ if (ret != 0) {
+ PRT_TRACE("vconf get failed ()\n");
+ return;
+ }
+
+ if (-1 == status) { /* '-1' means that USB host mode is not loaded yet */
+ PRT_TRACE("This usb device is connected defaultly\n");
+
+ ret = system(STORE_DEFAULT_USB_INFO);
+ PRT_TRACE("Return value of usb-devices: %d\n", ret);
+ if (0 != access(DEFAULT_USB_INFO_PATH, F_OK)) {
+ ret = system(STORE_DEFAULT_USB_INFO);
+ PRT_TRACE("Return value of usb-devices: %d\n", ret);
+ }
+ }
+ PRT_TRACE("EXIT: usb_host_add_cb()\n");
+}
+
+static int uevent_control_stop(int ufd)
+{
+ if (ufdh) {
+ ecore_main_fd_handler_del(ufdh);
+ ufdh = NULL;
+ }
+ if (ufd >= 0) {
+ close(ufd);
+ ufd = -1;
+ }
+ if (mon) {
+ udev_monitor_unref(mon);
+ mon = NULL;
+ }
+ if (udev) {
+ udev_unref(udev);
+ udev = NULL;
+ }
+ return 0;
+}
+
+static int uevent_control_start(void)
+{
+ int ufd = -1;
+
+ udev = udev_new();
+ if (!udev) {
+ PRT_TRACE_ERR("error create udev");
+ return -1;
+ }
+
+ mon = udev_monitor_new_from_netlink(udev, "kernel");
+ if (mon == NULL) {
+ PRT_TRACE_ERR("error udev_monitor create");
+ uevent_control_stop(-1);
+ return -1;
+ }
+
+ udev_monitor_set_receive_buffer_size(mon, 1024);
+ if (udev_monitor_filter_add_match_subsystem_devtype(mon, "platform", NULL) < 0) {
+ PRT_TRACE_ERR("error apply subsystem filter");
+ uevent_control_stop(-1);
+ return -1;
+ }
+
+ ufd = udev_monitor_get_fd(mon);
+ if (ufd == -1) {
+ PRT_TRACE_ERR("error udev_monitor_get_fd");
+ uevent_control_stop(ufd);
+ return -1;
+ }
+
+ ufdh = ecore_main_fd_handler_add(ufd, ECORE_FD_READ, uevent_control_cb, NULL, NULL, NULL);
+ if (!ufdh) {
+ PRT_TRACE_ERR("error ecore_main_fd_handler_add");
+ uevent_control_stop(ufd);
+ return -1;
+ }
+
+ if (udev_monitor_enable_receiving(mon) < 0) {
+ PRT_TRACE_ERR("error unable to subscribe to udev events");
+ uevent_control_stop(ufd);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int uevent_control_cb(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ struct udev_device *dev = NULL;
+ struct udev_list_entry *list_entry = NULL;
+ char *env_name = NULL;
+ char *env_value = NULL;
+ int ufd = -1;
+ int ret = -1;
+
+ if (!ecore_main_fd_handler_active_get(fd_handler,ECORE_FD_READ))
+ return -1;
+ if ((ufd = ecore_main_fd_handler_fd_get(fd_handler)) == -1)
+ return -1;
+ if ((dev = udev_monitor_receive_device(mon)) == NULL)
+ return -1;
+
+ udev_list_entry_foreach(list_entry,udev_device_get_properties_list_entry(dev)) {
+ env_name = udev_list_entry_get_name(list_entry);
+ if (strncmp(env_name, ENV_FILTER, strlen(ENV_FILTER)) == 0) {
+ env_value = udev_list_entry_get_value(list_entry);
+ ret = 0;
+ break;
+ }
+ }
+
+ if (ret != 0) {
+ udev_device_unref(dev);
+ return -1;
+ }
+
+ PRT_TRACE("UEVENT DETECTED (%s)",env_value);
+ ss_action_entry_call_internal(PREDEF_DEVICE_CHANGED,1,env_value);
+
+ udev_device_unref(dev);
+ uevent_control_stop(ufd);
+ uevent_control_start();
+
+ return 0;
+}
+
+int changed_device_def_predefine_action(int argc, char **argv)
+{
+ if (argc != 1 || argv[0] == NULL) {
+ PRT_TRACE_ERR("param is failed");
+ return -1;
+ }
+
+ if (strncmp(argv[0], ENV_VALUE_USB, strlen(ENV_VALUE_USB)) == 0)
+ usb_chgdet_cb(NULL);
+ if (strncmp(argv[0], ENV_VALUE_CHARGER, strlen(ENV_VALUE_CHARGER)) == 0)
+ ta_chgdet_cb(NULL);
+ if (strncmp(argv[0], ENV_VALUE_EARJACK, strlen(ENV_VALUE_EARJACK)) == 0)
+ earjack_chgdet_cb(NULL);
+ if (strncmp(argv[0], ENV_VALUE_EARKEY, strlen(ENV_VALUE_EARKEY)) == 0)
+ earkey_chgdet_cb(NULL);
+ if (strncmp(argv[0], ENV_VALUE_TVOUT, strlen(ENV_VALUE_TVOUT)) == 0)
+ tvout_chgdet_cb(NULL);
+ if (strncmp(argv[0], ENV_VALUE_HDMI, strlen(ENV_VALUE_HDMI)) == 0)
+ hdmi_chgdet_cb(NULL);
+ if (strncmp(argv[0], ENV_VALUE_KEYBOARD, strlen(ENV_VALUE_KEYBOARD)) == 0)
+ keyboard_chgdet_cb(NULL);
+
+ return 0;
+}
+
+static void pci_keyboard_add_cb(struct ss_main_data *ad)
+{
+ char params[BUFF_MAX];
+ PRT_TRACE("pci- keyboard inserted\n");
+ pm_change_state(LCD_NORMAL);
+
+ snprintf(params, sizeof(params), "%d", CB_NOTI_PCI_INSERTED);
+ ss_launch_if_noexist("/usr/bin/sys_pci_noti", params);
+
+}
+static void pci_keyboard_remove_cb(struct ss_main_data *ad)
+{
+ char params[BUFF_MAX];
+ PRT_TRACE("pci- keyboard removed\n");
+ pm_change_state(LCD_NORMAL);
+
+ snprintf(params, sizeof(params), "%d", CB_NOTI_PCI_REMOVED);
+ ss_launch_if_noexist("/usr/bin/sys_pci_noti", params);
+}
+int ss_device_change_init(struct ss_main_data *ad)
+{
+ ss_action_entry_add_internal(PREDEF_DEVICE_CHANGED, changed_device_def_predefine_action, NULL, NULL);
+
+ if (uevent_control_start() == -1) {
+ PRT_TRACE_ERR("fail uevent control init");
+ return -1;
+ }
+ /* for simple noti change cb */
+ ss_noti_add("device_usb_chgdet", (void *)usb_chgdet_cb, (void *)ad);
+ ss_noti_add("device_ta_chgdet", (void *)ta_chgdet_cb, (void *)ad);
+ ss_noti_add("device_earjack_chgdet", (void *)earjack_chgdet_cb, (void *)ad);
+ ss_noti_add("device_earkey_chgdet", (void *)earkey_chgdet_cb, (void *)ad);
+ ss_noti_add("device_tvout_chgdet", (void *)tvout_chgdet_cb, (void *)ad);
+ ss_noti_add("device_hdmi_chgdet", (void *)hdmi_chgdet_cb, (void *)ad);
+ ss_noti_add("device_keyboard_chgdet", (void *)keyboard_chgdet_cb, (void *)ad);
+
+ ss_noti_add("device_usb_host_add", (void *)usb_host_add_cb, (void *)ad);
+ ss_noti_add("mmcblk_add", (void *)mmc_chgdet_cb, (void *)1);
+ ss_noti_add("mmcblk_remove", (void *)mmc_chgdet_cb, NULL);
+
+ ss_noti_add("unmount_ums", (void *)ums_unmount_cb, NULL);
+ ss_noti_add("device_charge_chgdet", (void *)charge_cb, (void *)ad);
+
+ ss_noti_add("device_pci_keyboard_add", (void *)pci_keyboard_add_cb, (void *)ad);
+ ss_noti_add("device_pci_keyboard_remove", (void *)pci_keyboard_remove_cb, (void *)ad);
+
+ if (vconf_notify_key_changed(VCONFKEY_SYSMAN_USB_HOST_STATUS, usb_host_chgdet_cb, NULL) < 0) {
+ PRT_TRACE_ERR("vconf key notify failed(VCONFKEY_SYSMAN_USB_HOST_STATUS)");
+ }
+ /* dbus noti change cb */
+#ifdef ENABLE_EDBUS_USE
+ e_dbus_init();
+ conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
+ if (!conn)
+ PRT_TRACE_ERR("check system dbus running!\n");
+
+ e_dbus_signal_handler_add(conn, NULL, "/system/uevent/xxxxx",
+ "system.uevent.xxxxx",
+ "Change", cb_xxxxx_signaled, ad);
+#endif /* ENABLE_EDBUS_USE */
+
+ /* set initial state for devices */
+ input_device_number = 0;
+ keyboard_chgdet_cb(NULL);
+ hdmi_chgdet_cb(NULL);
+ system(STORE_DEFAULT_USB_INFO);
+
+ return 0;
+}
diff --git a/ss_device_handler.h b/ss_device_handler.h
new file mode 100644
index 0000000..d31f46b
--- /dev/null
+++ b/ss_device_handler.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_DEVICE_HANDLER_H__
+#define __SS_DEVICE_HANDLER_H__
+
+#include "include/ss_data.h"
+
+/* MMC functions */
+int ss_mmc_init();
+int ss_mmc_inserted();
+int ss_mmc_removed();
+
+/* USB Storage */
+int _ss_usb_storage_init(void);
+
+/* Battery functions */
+int ss_lowbat_init(struct ss_main_data *ad);
+int ss_lowbat_is_charge_in_now();
+int ss_lowbat_set_charge_on(int onoff);
+int ss_lowbat_monitor(void *data);
+
+/* Low memory functions */
+int ss_lowmem_init(struct ss_main_data *ad);
+
+/* USB functions */
+int ss_usb_init();
+
+/* TA functions */
+int ss_ta_init();
+
+/* device change init */
+int ss_device_change_init(struct ss_main_data *ad);
+
+#endif /* __SS_DEVICE_HANDLER_H__ */
diff --git a/ss_launch.c b/ss_launch.c
new file mode 100644
index 0000000..24b77c8
--- /dev/null
+++ b/ss_launch.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "vconf-keys.h"
+#include "ss_log.h"
+#include "ss_launch.h"
+
+#define MAX_ARGS 255
+
+#define _S(str) ((str == NULL) ? "" : str)
+
+int ss_set_current_lang(void)
+{
+ char *lang;
+ int ret;
+ lang = vconf_get_str(VCONFKEY_LANGSET);
+ if (lang == NULL)
+ return -1;
+ ret = setenv("LANG", lang, 1);
+ if (ret < 0)
+ return -1;
+ free(lang);
+ return 0;
+}
+
+
+static void prepare_exec(void)
+{
+ int i;
+ int maxfd;
+ FILE *fp;
+
+ maxfd = getdtablesize();
+ for (i = 3; i < maxfd; i++)
+ close(i);
+
+ for (i = 0; i < _NSIG; i++)
+ signal(i, SIG_DFL);
+
+}
+
+static int parse_cmd(const char *cmdline, char **argv, int max_args)
+{
+ const char *p;
+ char *buf, *bufp;
+ int nargs = 0;
+ int escape = 0, squote = 0, dquote = 0;
+ int bufsize;
+
+ if (cmdline == NULL || cmdline[0] == '\0')
+ return -1;
+ bufsize = strlen(cmdline)+1;
+ bufp = buf = malloc(bufsize);
+ if (bufp == NULL || buf == NULL)
+ return -1;
+ memset(buf, 0, bufsize);
+ p = cmdline;
+
+ while (*p) {
+ if (escape) {
+ *bufp++ = *p;
+ escape = 0;
+ } else {
+ switch (*p) {
+ case '\\':
+ escape = 1;
+ break;
+ case '"':
+ if (squote)
+ *bufp++ = *p;
+ else
+ dquote = !dquote;
+ break;
+ case '\'':
+ if (dquote)
+ *bufp++ = *p;
+ else
+ squote = !squote;
+ break;
+ case ' ':
+ if (!squote && !dquote) {
+ *bufp = '\0';
+ if (nargs < max_args)
+ argv[nargs++] = strdup(buf);
+ bufp = buf;
+ break;
+ }
+ default:
+ *bufp++ = *p;
+ break;
+ }
+ }
+ p++;
+ }
+
+ if (bufp != buf) {
+ *bufp = '\0';
+ if (nargs < max_args)
+ argv[nargs++] = strdup(buf);
+ }
+
+ argv[nargs++] = NULL;
+
+ free(buf);
+ return nargs;
+}
+
+int launch_app_with_nice(const char *file, char *const argv[], pid_t *pid, int _nice)
+{
+ int ret;
+ int _pid;
+
+ if (file == NULL || access(file, X_OK) != 0) {
+ PRT_TRACE_ERR("launch app error: Invalid input");
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (pid && (*pid > 0 && kill(*pid, 0) != -1))
+ return *pid;
+
+ _pid = fork();
+
+ if (_pid == -1) {
+ PRT_TRACE_ERR("fork error: %s", strerror(errno));
+ /* keep errno */
+ return -1;
+ }
+
+ if (_pid > 0) { /* parent */
+ if (pid)
+ *pid = _pid;
+ return _pid;
+ }
+
+ /* child */
+ prepare_exec();
+
+ ret = nice(_nice);
+
+ if (ret == -1 && errno != 0)
+ PRT_TRACE_ERR("nice error: %s", strerror(errno));
+
+ ret = execvp(file, argv);
+
+ /* If failed... */
+ PRT_TRACE_ERR("exec. error: %s", strerror(errno));
+ return -2;
+}
+
+int launch_app_cmd_with_nice(const char *cmdline, int _nice)
+{
+ int i;
+ int nargs;
+ int ret;
+ char *argv[MAX_ARGS + 1];
+
+ nargs = parse_cmd(cmdline, argv, MAX_ARGS + 1);
+ if (nargs == -1) {
+ PRT_TRACE_ERR("launch app error: Invalid input");
+ errno = EINVAL;
+ return -1;
+ }
+
+ ret = launch_app_with_nice(argv[0], argv, NULL, _nice);
+
+ for (i = 0; i < nargs; i++)
+ free(argv[i]);
+
+ return ret;
+}
+
+int launch_app_cmd(const char *cmdline)
+{
+ return launch_app_cmd_with_nice(cmdline, 0);
+}
+
+int ss_launch_if_noexist(const char *execpath, const char *arg, ...)
+{
+ char *buf;
+ int pid;
+ int nice_value = 0;
+ int flag = 0;
+ int buf_size = -1;
+ va_list argptr;
+
+ if (execpath == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (pid = sysman_get_pid(execpath) > 0)
+ return pid;
+
+ va_start(argptr, arg);
+ flag = va_arg(argptr, int);
+
+ if (flag & SS_LAUNCH_NICE)
+ nice_value = va_arg(argptr, int);
+
+ va_end(argptr);
+
+ ss_set_current_lang();
+ arg = _S(arg);
+
+ buf_size = strlen(execpath) + strlen(arg) + 10;
+ buf = malloc(buf_size);
+ if (buf == NULL) {
+ /* Do something for not enought memory error */
+ PRT_TRACE_ERR("Malloc failed");
+ return -1;
+ }
+
+ snprintf(buf, buf_size, "%s %s", execpath, arg);
+ //pid = launch_app_cmd_with_nice(buf, nice_value, flag);
+ pid = launch_app_cmd_with_nice(buf, nice_value);
+ if (pid == -2)
+ exit(EXIT_FAILURE);
+ free(buf);
+
+ return pid;
+}
+
+int ss_launch_evenif_exist(const char *execpath, const char *arg, ...)
+{
+ char *buf;
+ int pid;
+ int nice_value = 0;
+ int flag = 0;
+ int buf_size = -1;
+
+ va_list argptr;
+
+ if (execpath == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ va_start(argptr, arg);
+ flag = va_arg(argptr, int);
+
+ if (flag & SS_LAUNCH_NICE)
+ nice_value = va_arg(argptr, int);
+
+ va_end(argptr);
+
+ ss_set_current_lang();
+
+ arg = _S(arg);
+
+ buf_size = strlen(execpath) + strlen(arg) + 10;
+ buf = malloc(buf_size);
+ if (buf == NULL) {
+ // Do something for not enought memory error
+ PRT_TRACE_ERR("Malloc failed");
+ return -1;
+ }
+
+ snprintf(buf, buf_size, "%s %s", execpath, arg);
+ //pid = launch_app_cmd_with_nice(buf, nice_value, flag);
+ pid = launch_app_cmd_with_nice(buf, nice_value);
+ if (pid == -2)
+ exit(EXIT_FAILURE);
+ free(buf);
+
+ return pid;
+}
+
+int ss_launch_after_kill_if_exist(const char *execpath, const char *arg, ...)
+{
+ char *buf;
+ int pid;
+ int flag;
+ int buf_size;
+ int exist_pid;
+ va_list argptr;
+ int nice_value = 0;
+
+ if (execpath == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ((exist_pid = sysman_get_pid(execpath)) > 0)
+ kill(exist_pid, SIGTERM);
+
+ va_start(argptr, arg);
+ flag = va_arg(argptr, int);
+
+ if (flag & SS_LAUNCH_NICE)
+ nice_value = va_arg(argptr, int);
+
+ va_end(argptr);
+
+ ss_set_current_lang();
+
+ arg = _S(arg);
+
+ buf_size = strlen(execpath) + strlen(arg) + 10;
+ buf = malloc(buf_size);
+ if (buf == NULL) {
+ /* Do something for not enought memory error */
+ PRT_TRACE_ERR("Malloc Failed");
+ return -1;
+ }
+
+ snprintf(buf, buf_size, "%s %s", execpath, arg);
+ //pid = launch_app_cmd_with_nice(buf, nice_value, flag);
+ pid = launch_app_cmd_with_nice(buf, nice_value);
+ if (pid == -2) /* It means that the 'execvp' return -1 */
+ exit(EXIT_FAILURE);
+ free(buf);
+
+ return pid;
+
+}
diff --git a/ss_launch.h b/ss_launch.h
new file mode 100644
index 0000000..209d383
--- /dev/null
+++ b/ss_launch.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_LAUNCH_H__
+#define __SS_LAUNCH_H__
+
+#define SS_LAUNCH_NICE 0x0002
+
+int ss_launch_if_noexist(const char *execpath, const char *arg, ...);
+int ss_launch_evenif_exist(const char *execpath, const char *arg, ...);
+int ss_launch_after_kill_if_exist(const char *execpath, const char *arg, ...);
+
+#endif /* __SS_LAUNCH_H__ */
diff --git a/ss_log.c b/ss_log.c
new file mode 100644
index 0000000..3873373
--- /dev/null
+++ b/ss_log.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifdef DEBUG
+void __cyg_profile_func_enter(void *, void *)
+ __attribute__ ((no_instrument_function));
+void __cyg_profile_func_exit(void *, void *)
+ __attribute__ ((no_instrument_function));
+
+int g_trace_depth = -2;
+
+void __cyg_profile_func_enter(void *func, void *caller)
+{
+ g_trace_depth++;
+}
+
+void __cyg_profile_func_exit(void *func, void *caller)
+{
+ g_trace_depth--;
+}
+#endif
diff --git a/ss_log.h b/ss_log.h
new file mode 100644
index 0000000..b3b0af9
--- /dev/null
+++ b/ss_log.h
@@ -0,0 +1,171 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __LOG_H__
+#define __LOG_H__
+
+#include <stdio.h>
+
+#if defined(ENABLE_DLOG_OUT)
+#define LOG_TAG "SYSTEM_SERVER"
+#include <dlog.h>
+#define DLOG_ERR DLOG_ERROR
+#define __LOG(prio, fmt, arg...) \
+ do { SLOG(prio, LOG_TAG, fmt, ##arg); } while (0)
+#define __LOGD(prio, fmt, arg...) \
+ do { SLOG(prio, LOG_TAG, fmt, ##arg); } while (0)
+#define __PRT(prio, fmt, arg...) \
+ do { fprintf(((D##prio) == DLOG_ERR ? stderr : stdout), fmt"\n", ##arg); } while (0)
+#define __PRTD(prio, fmt, arg...) \
+ do { \
+ fprintf(((D##prio) == DLOG_ERR ? stderr : stdout), \
+ "%s: %s(%d) > "fmt"\n", __MODULE__, __func__, __LINE__, ##arg); \
+ } while (0)
+#else
+#include <syslog.h>
+#define __LOG(prio, fmt, arg...) \
+ do { syslog(prio, fmt, ##arg); } while (0)
+#define __LOGD(prio, fmt, arg...) \
+ do { syslog(prio, "%s: %s(%d) > "fmt"\n", __MODULE__, __func__, __LINE__, ##arg); } while (0)
+#define __PRT(prio, fmt, arg...) \
+ do { fprintf(((prio) == LOG_ERR ? stderr : stdout), fmt"\n", ##arg); } while (0)
+#define __PRTD(prio, fmt, arg...) \
+ do { \
+ fprintf(((prio) == LOG_ERR ? stderr : stdout), \
+ "%s: %s(%d) > "fmt"\n", __MODULE__, __func__, __LINE__, ##arg); \
+ } while (0)
+#endif
+
+#ifdef DEBUG
+extern int g_trace_depth;
+#define __PRT_TRACE(prio, fmt, arg...) \
+ do { __LOGD(prio, fmt, ##arg); } while (0)
+/* do { \
+ int ___i;\
+ for(___i=0;___i<g_trace_depth;___i++)\
+ {\
+ fprintf(stdout, " "); \
+ }\
+ fprintf(stdout,\
+ "[%s:%d] "fmt"\n", __FUNCTION__, __LINE__,##arg); \
+ __LOGD(prio, fmt, ##arg); \
+ } while (0) */
+#define __PRT_TRACE_ERR(prio, fmt, arg...) \
+ do { __LOGD(prio, fmt, ##arg); } while (0)
+/* do { \
+ int ___i;\
+ for(___i=0;___i<g_trace_depth;___i++)\
+ {\
+ fprintf(stdout, " "); \
+ }\
+ printf(\
+ "%c[1;31m[%s:%d] "fmt"%c[0m\n",27, __FUNCTION__, __LINE__,##arg,27); \
+ __LOGD(prio, fmt, ##arg); \
+ } while (0)*/
+#define __PRT_TRACE_EM(prio, fmt, arg...) \
+ do { __LOGD(prio, fmt, ##arg); } while (0)
+/* do { \
+ int ___i;\
+ for(___i=0;___i<g_trace_depth;___i++)\
+ {\
+ fprintf(stdout, " "); \
+ }\
+ printf(\
+ "%c[1;34m[%s:%d] "fmt"%c[0m\n",27, __FUNCTION__, __LINE__,##arg,27); \
+ __LOGD(prio, fmt, ##arg); \
+ } while (0)*/
+#endif
+
+#define _NOUT(prio, fmt, arg...) do { } while (0)
+
+#ifdef DEBUG
+# define _LOGD __LOGD
+# define _LOG __LOGD
+# define _PRTD __PRTD
+# define _PRT __PRTD
+# define _PRT_TRACE __PRT_TRACE
+# define _PRT_TRACE_ERR __PRT_TRACE_ERR
+# define _PRT_TRACE_EM __PRT_TRACE_EM
+#else
+# define _LOGD _NOUT
+# define _LOG __LOG
+# define _PRTD _NOUT
+# define _PRT __PRT
+# define _PRT_TRACE _NOUT
+# define _PRT_TRACE_ERR _NOUT
+# define _PRT_TRACE_EM _NOUT
+#endif
+
+#define PRT_INFO(fmt, arg...) _PRT(LOG_INFO, fmt, ##arg)
+#define PRT_ERR(fmt, arg...) _PRT(LOG_ERR, fmt, ##arg)
+#define PRT_DBG(fmt, arg...) _PRTD(LOG_DEBUG, fmt, ##arg)
+#define PRT_TRACE(fmt, arg...) _PRT_TRACE(LOG_DEBUG, fmt, ##arg)
+#define PRT_TRACE_ERR(fmt, arg...) _PRT_TRACE_ERR(LOG_ERR, fmt, ##arg)
+#define PRT_TRACE_EM(fmt, arg...) _PRT_TRACE_EM(LOG_DEBUG, fmt, ##arg)
+
+#if defined(SYSLOG_OUT)
+# define SYSLOG_INFO(fmt, arg...) _LOG(LOG_INFO, fmt, ##arg)
+# define SYSLOG_ERR(fmt, arg...) _LOG(LOG_ERR, fmt, ##arg)
+# define SYSLOG_DBG(fmt, arg...) _LOGD(LOG_DEBUG, fmt, ##arg)
+# define INFO SYSLOG_INFO
+# define ERR SYSLOG_ERR
+# define DBG SYSLOG_DBG
+#elif defined(ENABLE_DLOG_OUT)
+# define INFO SLOGI
+# define ERR SLOGE
+# define DBG SLOGD
+#else
+# define INFO PRT_INFO
+# define ERR PRT_ERR
+# define DBG PRT_DBG
+#endif
+
+#endif
+
+#ifndef FEATURE_DEVICE_DAEMON_DLOG
+#define FEATURE_DEVICE_DAEMON_DLOG
+#endif
+
+#ifdef FEATURE_DEVICE_DAEMON_DLOG
+#define _D(fmt, arg...) \
+ do { SLOGD(fmt, ##arg); } while(0)
+#define _I(fmt, arg...) \
+ do { SLOGI(fmt, ##arg); } while(0)
+#define _W(fmt, arg...) \
+ do { SLOGW(fmt, ##arg); } while(0)
+#define _E(fmt, arg...) \
+ do { SLOGE(fmt, ##arg); } while(0)
+#define _SD(fmt, arg...) \
+ do { SECURE_SLOGD(fmt, ##arg); } while(0)
+#define _SI(fmt, arg...) \
+ do { SECURE_SLOGI(fmt, ##arg); } while(0)
+#define _SW(fmt, arg...) \
+ do { SECURE_SLOGW(fmt, ##arg); } while(0)
+#define _SE(fmt, arg...) \
+ do { SECURE_SLOGE(fmt, ##arg); } while(0)
+#else
+#define _D(x, ...) do { } while (0)
+#define _I(x, ...) do { } while (0)
+#define _W(x, ...) do { } while (0)
+#define _E(x, ...) do { } while (0)
+#define _SD(fmt, args...) do { } while (0)
+#define _SI(fmt, args...) do { } while (0)
+#define _SW(fmt, args...) do { } while (0)
+#define _SE(fmt, args...) do { } while (0)
+#endif
diff --git a/ss_lowbat_handler.c b/ss_lowbat_handler.c
new file mode 100755
index 0000000..5f97290
--- /dev/null
+++ b/ss_lowbat_handler.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <assert.h>
+#include <limits.h>
+#include <heynoti.h>
+#include <vconf.h>
+#include <sysman.h>
+#include <fcntl.h>
+
+#include "ss_log.h"
+#include "ss_launch.h"
+#include "ss_noti.h"
+#include "ss_queue.h"
+#include "device-node.h"
+#include "include/ss_data.h"
+
+#define BAT_MON_INTERVAL 30
+#define BAT_MON_INTERVAL_MIN 2
+
+#define BATTERY_CHARGING 65535
+#define BATTERY_UNKNOWN -1
+#define BATTERY_FULL 100
+#define BATTERY_NORMAL 100
+#define BATTERY_WARNING_LOW 15
+#define BATTERY_CRITICAL_LOW 5
+#define BATTERY_POWER_OFF 1
+#define BATTERY_REAL_POWER_OFF 0
+
+#define MAX_BATTERY_ERROR 10
+#define RESET_RETRY_COUNT 3
+
+#define LOWBAT_EXEC_PATH PREFIX"/bin/lowbatt-popup"
+
+#define BATTERY_LEVEL_CHECK_FULL 95
+#define BATTERY_LEVEL_CHECK_HIGH 15
+#define BATTERY_LEVEL_CHECK_LOW 5
+#define BATTERY_LEVEL_CHECK_CRITICAL 1
+
+#define _SYS_LOW_POWER "LOW_POWER"
+
+struct lowbat_process_entry {
+ unsigned cur_bat_state;
+ unsigned new_bat_state;
+ int (*action) (void *);
+};
+
+static Ecore_Timer *lowbat_timer;
+static int cur_bat_state = BATTERY_UNKNOWN;
+static int cur_bat_capacity = -1;
+
+static int bat_err_count = 0;
+
+static int battery_warning_low_act(void *ad);
+static int battery_critical_low_act(void *ad);
+static int battery_power_off_act(void *ad);
+
+static struct lowbat_process_entry lpe[] = {
+ {BATTERY_NORMAL, BATTERY_WARNING_LOW, battery_warning_low_act},
+ {BATTERY_WARNING_LOW, BATTERY_CRITICAL_LOW, battery_critical_low_act},
+ {BATTERY_CRITICAL_LOW, BATTERY_POWER_OFF, battery_critical_low_act},
+ {BATTERY_POWER_OFF, BATTERY_REAL_POWER_OFF, battery_power_off_act},
+ {BATTERY_NORMAL, BATTERY_CRITICAL_LOW, battery_critical_low_act},
+ {BATTERY_WARNING_LOW, BATTERY_POWER_OFF, battery_critical_low_act},
+ {BATTERY_CRITICAL_LOW, BATTERY_REAL_POWER_OFF, battery_power_off_act},
+ {BATTERY_NORMAL, BATTERY_POWER_OFF, battery_critical_low_act},
+ {BATTERY_WARNING_LOW, BATTERY_REAL_POWER_OFF, battery_power_off_act},
+ {BATTERY_NORMAL, BATTERY_REAL_POWER_OFF, battery_power_off_act},
+};
+
+/*
+ * TODO: remove this function
+ */
+static void print_lowbat_state(unsigned int bat_percent)
+{
+#if 0
+ int i;
+ for (i = 0; i < BAT_MON_SAMPLES; i++)
+ PRT_TRACE("\t%d", recent_bat_percent[i]);
+#endif
+}
+
+static int battery_warning_low_act(void *data)
+{
+ char lowbat_noti_name[NAME_MAX];
+
+ heynoti_get_snoti_name(_SYS_LOW_POWER, lowbat_noti_name, NAME_MAX);
+ ss_noti_send(lowbat_noti_name);
+
+ ss_action_entry_call_internal(PREDEF_LOWBAT, 1, WARNING_LOW_BAT_ACT);
+ return 0;
+}
+
+static int battery_critical_low_act(void *data)
+{
+ ss_action_entry_call_internal(PREDEF_LOWBAT, 1, CRITICAL_LOW_BAT_ACT);
+ return 0;
+}
+
+static int battery_power_off_act(void *data)
+{
+ ss_action_entry_call_internal(PREDEF_LOWBAT, 1, POWER_OFF_BAT_ACT);
+ return 0;
+}
+
+static int battery_charge_act(void *data)
+{
+ return 0;
+}
+
+int ss_lowbat_set_charge_on(int onoff)
+{
+ if(vconf_set_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, onoff)!=0) {
+ PRT_TRACE_ERR("fail to set charge vconf value");
+ return -1;
+ }
+ return 0;
+}
+
+int ss_lowbat_is_charge_in_now()
+{
+ int val = 0;
+ if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_NOW, &val) < 0) {
+ PRT_TRACE_ERR("fail to read charge now from kernel");
+ ss_lowbat_set_charge_on(0);
+ return 0;
+ }
+
+ if (val == 1) {
+ ss_lowbat_set_charge_on(1);
+ return 1;
+ } else {
+ ss_lowbat_set_charge_on(0);
+ return 0;
+ }
+}
+
+static int lowbat_process(int bat_percent, void *ad)
+{
+ int new_bat_capacity;
+ int new_bat_state;
+ int vconf_state = -1;
+ int bat_full = -1;
+ int i, ret = 0;
+ int val = 0;
+ new_bat_capacity = bat_percent;
+ if (new_bat_capacity < 0)
+ return -1;
+ if (new_bat_capacity != cur_bat_capacity) {
+ PRT_TRACE("[BAT_MON] cur = %d new = %d", cur_bat_capacity, new_bat_capacity);
+ if (vconf_set_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, new_bat_capacity) == 0)
+ cur_bat_capacity = new_bat_capacity;
+ }
+
+
+ if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &vconf_state) < 0) {
+ PRT_TRACE_ERR("vconf_get_int() failed");
+ return -1;
+ }
+
+ if (new_bat_capacity <= BATTERY_REAL_POWER_OFF) {
+ if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_NOW, &val) < 0) {
+ PRT_TRACE_ERR("fail to read charge now from kernel");
+ }
+ PRT_TRACE("charge_now status %d",val);
+ if (val == 1) {
+ new_bat_state = BATTERY_POWER_OFF;
+ if (vconf_state != VCONFKEY_SYSMAN_BAT_POWER_OFF)
+ ret=vconf_set_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, VCONFKEY_SYSMAN_BAT_POWER_OFF);
+ } else {
+ new_bat_state = BATTERY_REAL_POWER_OFF;
+ if (vconf_state != VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF)
+ ret=vconf_set_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF);
+ }
+ } else if (new_bat_capacity <= BATTERY_POWER_OFF) {
+ new_bat_state = BATTERY_POWER_OFF;
+ if (vconf_state != VCONFKEY_SYSMAN_BAT_POWER_OFF)
+ ret=vconf_set_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, VCONFKEY_SYSMAN_BAT_POWER_OFF);
+ } else if (new_bat_capacity <= BATTERY_CRITICAL_LOW) {
+ new_bat_state = BATTERY_CRITICAL_LOW;
+ if (vconf_state != VCONFKEY_SYSMAN_BAT_CRITICAL_LOW)
+ ret=vconf_set_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, VCONFKEY_SYSMAN_BAT_CRITICAL_LOW);
+ } else if (new_bat_capacity <= BATTERY_WARNING_LOW) {
+ new_bat_state = BATTERY_WARNING_LOW;
+ if (vconf_state != VCONFKEY_SYSMAN_BAT_WARNING_LOW)
+ ret=vconf_set_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, VCONFKEY_SYSMAN_BAT_WARNING_LOW);
+ } else {
+ new_bat_state = BATTERY_NORMAL;
+ if (new_bat_capacity == BATTERY_FULL) {
+ device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_FULL, &bat_full);
+ if (bat_full == 1) {
+ if (vconf_state != VCONFKEY_SYSMAN_BAT_FULL)
+ ret=vconf_set_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, VCONFKEY_SYSMAN_BAT_FULL);
+ } else {
+ if (vconf_state != VCONFKEY_SYSMAN_BAT_NORMAL)
+ ret=vconf_set_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, VCONFKEY_SYSMAN_BAT_NORMAL);
+ }
+ } else {
+ if (vconf_state != VCONFKEY_SYSMAN_BAT_NORMAL)
+ ret=vconf_set_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, VCONFKEY_SYSMAN_BAT_NORMAL);
+ }
+ }
+
+ if(ret < 0)
+ return -1;
+
+ ss_lowbat_is_charge_in_now();
+
+ if (cur_bat_state == new_bat_state) {
+ return 0;
+ }
+
+ if (cur_bat_state == BATTERY_UNKNOWN) {
+ for (i = 0;
+ i < sizeof(lpe) / sizeof(struct lowbat_process_entry);
+ i++) {
+ if (new_bat_state == lpe[i].new_bat_state) {
+ lpe[i].action(ad);
+ cur_bat_state = new_bat_state;
+ return 0;
+ }
+ }
+ } else {
+ for (i = 0;
+ i < sizeof(lpe) / sizeof(struct lowbat_process_entry);
+ i++) {
+ if ((cur_bat_state == lpe[i].cur_bat_state)
+ && (new_bat_state == lpe[i].new_bat_state)) {
+ lpe[i].action(ad);
+ cur_bat_state = new_bat_state;
+ return 0;
+ }
+ }
+ }
+
+ PRT_TRACE("[BATMON] Unknown battery state cur:%d new:%d",cur_bat_state,new_bat_state);
+ cur_bat_state = new_bat_state;
+
+ if (new_bat_capacity != cur_bat_capacity)
+ return -1;
+
+ return 0;
+}
+
+static int lowbat_read(void)
+{
+ int bat_percent, r;
+
+ r = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CAPACITY, &bat_percent);
+ if (r < 0)
+ return r;
+
+ return bat_percent;
+}
+
+static void __ss_change_lowbat_level(int bat_percent)
+{
+ int prev, now;
+
+ if (cur_bat_capacity == bat_percent)
+ return;
+
+ if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_LEVEL_STATUS, &prev) < 0) {
+ PRT_TRACE_ERR("vconf_get_int() failed");
+ return;
+ }
+
+
+ if (bat_percent > BATTERY_LEVEL_CHECK_FULL) {
+ now = VCONFKEY_SYSMAN_BAT_LEVEL_FULL;
+ } else if (bat_percent > BATTERY_LEVEL_CHECK_HIGH) {
+ now = VCONFKEY_SYSMAN_BAT_LEVEL_HIGH;
+ } else if (bat_percent > BATTERY_LEVEL_CHECK_LOW) {
+ now = VCONFKEY_SYSMAN_BAT_LEVEL_LOW;
+ } else if (bat_percent > BATTERY_LEVEL_CHECK_CRITICAL) {
+ now = VCONFKEY_SYSMAN_BAT_LEVEL_CRITICAL;
+ } else {
+ now = VCONFKEY_SYSMAN_BAT_LEVEL_EMPTY;
+ }
+
+ if (prev != now)
+ vconf_set_int(VCONFKEY_SYSMAN_BATTERY_LEVEL_STATUS, now);
+}
+
+static int __check_lowbat_percent(int *pct)
+{
+ int bat_percent;
+
+ bat_percent = lowbat_read();
+ if (bat_percent < 0) {
+ ecore_timer_interval_set(lowbat_timer, BAT_MON_INTERVAL_MIN);
+ bat_err_count++;
+ if (bat_err_count > MAX_BATTERY_ERROR) {
+ PRT_TRACE_ERR
+ ("[BATMON] Cannot read battery gage. stop read fuel gage");
+ return -ENODEV;
+ }
+ return -ENODEV;
+ }
+ if (bat_percent > 100)
+ bat_percent = 100;
+ __ss_change_lowbat_level(bat_percent);
+ *pct = bat_percent;
+ return 0;
+}
+
+Eina_Bool ss_lowbat_monitor(void *data)
+{
+ struct ss_main_data *ad = (struct ss_main_data *)data;
+ int bat_percent, r;
+
+ r = __check_lowbat_percent(&bat_percent);
+ if (r < 0)
+ return ECORE_CALLBACK_RENEW;
+
+ print_lowbat_state(bat_percent);
+
+ if (lowbat_process(bat_percent, ad) < 0)
+ ecore_timer_interval_set(lowbat_timer, BAT_MON_INTERVAL_MIN);
+ else
+ ecore_timer_interval_set(lowbat_timer, BAT_MON_INTERVAL);
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+static int wakeup_cb(keynode_t *key_nodes, void *data)
+{
+ int pm_state = 0;
+
+ if ((pm_state =
+ vconf_keynode_get_int(key_nodes)) == VCONFKEY_PM_STATE_LCDOFF)
+ ss_lowbat_monitor(NULL);
+
+ return 0;
+}
+
+/* for debugging (request by kernel) */
+static int check_battery()
+{
+ int r;
+ int ret = -1;
+
+ if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_PRESENT, &ret) < 0) {
+ PRT_TRACE_ERR("[BATMON] battery check : %d", ret);
+ }
+ PRT_TRACE("[BATMON] battery check : %d", ret);
+
+ return ret;
+}
+
+int ss_lowbat_init(struct ss_main_data *ad)
+{
+ int i, pct;
+
+ /* need check battery */
+ lowbat_timer =
+ ecore_timer_add(BAT_MON_INTERVAL_MIN, ss_lowbat_monitor, ad);
+
+ __check_lowbat_percent(&pct);
+
+ ss_lowbat_is_charge_in_now();
+
+ vconf_notify_key_changed(VCONFKEY_PM_STATE, (void *)wakeup_cb, NULL);
+
+ return 0;
+}
diff --git a/ss_lowmem_handler.c b/ss_lowmem_handler.c
new file mode 100644
index 0000000..fb6db58
--- /dev/null
+++ b/ss_lowmem_handler.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <fcntl.h>
+#include <assert.h>
+#include <limits.h>
+#include <sysman.h>
+#include <heynoti.h>
+#include <vconf.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/shm.h>
+
+#include "device-node.h"
+#include "ss_log.h"
+#include "ss_noti.h"
+#include "ss_queue.h"
+#include "include/ss_data.h"
+
+#define DELETE_SM "sh -c "PREFIX"/bin/delete.sm"
+
+#define MEMNOTIFY_NORMAL 0x0000
+#define MEMNOTIFY_LOW 0xfaac
+#define MEMNOTIFY_CRITICAL 0xdead
+#define MEMNOTIFY_REBOOT 0xb00f
+
+#define _SYS_RES_CLEANUP "RES_CLEANUP"
+
+#define MEM_THRESHOLD_LV1 60
+#define MEM_THRESHOLD_LV2 40
+
+
+struct lowmem_process_entry {
+ unsigned cur_mem_state;
+ unsigned new_mem_state;
+ int (*action) (void *);
+};
+
+static int lowmem_fd = -1;
+static int cur_mem_state = MEMNOTIFY_NORMAL;
+
+Ecore_Timer *oom_timer;
+#define OOM_TIMER_INTERVAL 5
+
+static int memory_low_act(void *ad);
+static int memory_oom_act(void *ad);
+static int memory_normal_act(void *ad);
+
+static struct lowmem_process_entry lpe[] = {
+ {MEMNOTIFY_NORMAL, MEMNOTIFY_LOW, memory_low_act},
+ {MEMNOTIFY_NORMAL, MEMNOTIFY_CRITICAL, memory_oom_act},
+ {MEMNOTIFY_LOW, MEMNOTIFY_CRITICAL, memory_oom_act},
+ {MEMNOTIFY_CRITICAL, MEMNOTIFY_CRITICAL, memory_oom_act},
+ {MEMNOTIFY_LOW, MEMNOTIFY_NORMAL, memory_normal_act},
+ {MEMNOTIFY_CRITICAL, MEMNOTIFY_NORMAL, memory_normal_act},
+
+};
+
+unsigned int oom_delete_sm_time = 0;
+
+static int remove_shm()
+{
+ int maxid, shmid, id;
+ struct shmid_ds shmseg;
+ struct shm_info shm_info;
+
+ maxid = shmctl(0, SHM_INFO, (struct shmid_ds *)(void *)&shm_info);
+ if (maxid < 0) {
+ PRT_TRACE_ERR("shared mem error\n");
+ return -1;
+ }
+
+ for (id = 0; id <= maxid; id++) {
+ shmid = shmctl(id, SHM_STAT, &shmseg);
+ if (shmid < 0)
+ continue;
+ if (shmseg.shm_nattch == 0) {
+ PRT_TRACE("shared memory killer ==> %d killed\n",
+ shmid);
+ shmctl(shmid, IPC_RMID, NULL);
+ }
+ }
+ return 0;
+}
+
+static char *convert_to_str(unsigned int mem_state)
+{
+ char *tmp;
+ switch (mem_state) {
+ case MEMNOTIFY_NORMAL:
+ tmp = "mem normal";
+ break;
+ case MEMNOTIFY_LOW:
+ tmp = "mem low";
+ break;
+ case MEMNOTIFY_CRITICAL:
+ tmp = "mem critical";
+ break;
+ case MEMNOTIFY_REBOOT:
+ tmp = "mem reboot";
+ break;
+ default:
+ assert(0);
+ }
+ return tmp;
+}
+
+static void print_lowmem_state(unsigned int mem_state)
+{
+ PRT_TRACE("[LOW MEM STATE] %s ==> %s", convert_to_str(cur_mem_state),
+ convert_to_str(mem_state));
+}
+#define BUF_MAX 1024
+static int get_lowmemnotify_info(FILE *output_fp)
+{
+ FILE *fp;
+ char line[BUF_MAX];
+
+ if (output_fp == NULL)
+ return -1;
+
+ fp = fopen("/sys/class/memnotify/meminfo", "r");
+ if (fp == NULL)
+ return -1;
+ PRT_TRACE("make LOWMEM_LOG");
+ fprintf(output_fp,
+ "====================================================================\n");
+ fprintf(output_fp, "MEMORY INFO by lowmemnotify\n");
+
+ while (fgets(line, BUF_MAX, fp) != NULL) {
+ PRT_TRACE("%s",line);
+ fputs(line, output_fp);
+ }
+ fclose(fp);
+
+ return 0;
+}
+
+static void make_LMM_log(char *file, pid_t pid, char *victim_name)
+{
+ time_t now;
+ struct tm *cur_tm;
+ char new_log[NAME_MAX];
+ static pid_t old_pid = 0;
+ int ret=-1;
+ FILE *output_file = NULL;
+
+ if (old_pid == pid)
+ return;
+ old_pid = pid;
+
+ now = time(NULL);
+ cur_tm = (struct tm *)malloc(sizeof(struct tm));
+ if (cur_tm == NULL) {
+ PRT_TRACE_ERR("Fail to memory allocation");
+ return;
+ }
+
+ if (localtime_r(&now, cur_tm) == NULL) {
+ PRT_TRACE_ERR("Fail to get localtime");
+ free(cur_tm);
+ return;
+ }
+
+ PRT_TRACE("%s_%s_%d_%.4d%.2d%.2d_%.2d%.2d%.2d.log", file, victim_name,
+ pid, (1900 + cur_tm->tm_year), 1 + cur_tm->tm_mon,
+ cur_tm->tm_mday, cur_tm->tm_hour, cur_tm->tm_min,
+ cur_tm->tm_sec);
+ snprintf(new_log, sizeof(new_log),
+ "%s_%s_%d_%.4d%.2d%.2d_%.2d%.2d%.2d.log", file, victim_name,
+ pid, (1900 + cur_tm->tm_year), 1 + cur_tm->tm_mon,
+ cur_tm->tm_mday, cur_tm->tm_hour, cur_tm->tm_min,
+ cur_tm->tm_sec);
+
+ output_file = fopen(new_log, "w+");
+ if(!output_file) {
+ PRT_TRACE_ERR("cannot open output file(%s)",new_log);
+ free(cur_tm);
+ return;
+ }
+ get_lowmemnotify_info(output_file);
+ fclose(output_file);
+ free(cur_tm);
+}
+
+
+
+static int memory_low_act(void *data)
+{
+ char lowmem_noti_name[NAME_MAX];
+
+ PRT_TRACE("[LOW MEM STATE] memory low state");
+ make_LMM_log("/var/log/memps", 1, "LOWMEM_WARNING");
+ remove_shm();
+
+ heynoti_get_snoti_name(_SYS_RES_CLEANUP, lowmem_noti_name, NAME_MAX);
+ ss_noti_send(lowmem_noti_name);
+ vconf_set_int(VCONFKEY_SYSMAN_LOW_MEMORY,
+ VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING);
+
+ return 0;
+}
+
+static int memory_oom_act(void *data)
+{
+ unsigned int cur_time;
+ char lowmem_noti_name[NAME_MAX];
+
+ PRT_TRACE("[LOW MEM STATE] memory oom state");
+ cur_time = time(NULL);
+ PRT_TRACE("cur=%d, old=%d, cur-old=%d", cur_time, oom_delete_sm_time,
+ cur_time - oom_delete_sm_time);
+ if (cur_time - oom_delete_sm_time > 15) {
+ remove_shm();
+ oom_delete_sm_time = cur_time;
+ /* Also clean up unreturned memory of applications */
+ heynoti_get_snoti_name(_SYS_RES_CLEANUP, lowmem_noti_name,
+ NAME_MAX);
+ ss_noti_send(lowmem_noti_name);
+ }
+ ss_action_entry_call_internal(PREDEF_LOWMEM, 1, OOM_MEM_ACT);
+
+ vconf_set_int(VCONFKEY_SYSMAN_LOW_MEMORY,
+ VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING);
+
+
+ return 1;
+}
+
+static int memory_normal_act(void *data)
+{
+ PRT_TRACE("[LOW MEM STATE] memory normal state");
+ vconf_set_int(VCONFKEY_SYSMAN_LOW_MEMORY,
+ VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL);
+ return 0;
+}
+
+static int lowmem_process(unsigned int mem_state, void *ad)
+{
+ int i;
+ for (i = 0; i < sizeof(lpe) / sizeof(struct lowmem_process_entry); i++) {
+ if ((cur_mem_state == lpe[i].cur_mem_state)
+ && (mem_state == lpe[i].new_mem_state)) {
+
+ if(oom_timer != NULL) {
+ ecore_timer_del(oom_timer);
+ oom_timer = NULL;
+ }
+ lpe[i].action(ad);
+ if(mem_state == MEMNOTIFY_CRITICAL)
+ oom_timer = ecore_timer_add(OOM_TIMER_INTERVAL,lpe[i].action, ad);
+ return 0;
+ }
+ }
+ return 0;
+}
+
+static unsigned int lowmem_read(int fd)
+{
+ unsigned int mem_state;
+ read(fd, &mem_state, sizeof(mem_state));
+ return mem_state;
+}
+
+static int lowmem_cb(void *data, Ecore_Fd_Handler * fd_handler)
+{
+ int fd;
+ struct ss_main_data *ad = (struct ss_main_data *)data;
+ unsigned int mem_state;
+
+ if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
+ PRT_TRACE_ERR
+ ("ecore_main_fd_handler_active_get error , return\n");
+ return 1;
+ }
+
+ fd = ecore_main_fd_handler_fd_get(fd_handler);
+ if (fd < 0) {
+ PRT_TRACE_ERR("ecore_main_fd_handler_fd_get error , return");
+ return 1;
+ }
+ mem_state = lowmem_read(fd);
+ print_lowmem_state(mem_state);
+ lowmem_process(mem_state, ad);
+ cur_mem_state = mem_state;
+
+ return 1;
+}
+
+static int set_threshold()
+{
+ if (device_set_property(DEVICE_TYPE_MEMORY, PROP_MEMORY_THRESHOLD_LV1, MEM_THRESHOLD_LV1) < 0) {
+ PRT_TRACE_ERR("Set memnorify threshold lv1 failed");
+ return -1;
+ }
+
+ if (device_set_property(DEVICE_TYPE_MEMORY, PROP_MEMORY_THRESHOLD_LV2, MEM_THRESHOLD_LV2) < 0) {
+ PRT_TRACE_ERR("Set memnorify threshold lv2 failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+int ss_lowmem_init(struct ss_main_data *ad)
+{
+ char lowmem_dev_node[PATH_MAX];
+
+ if (device_get_property(DEVICE_TYPE_MEMORY, PROP_MEMORY_NODE, lowmem_dev_node) < 0) {
+ PRT_TRACE_ERR("Low memory handler fd init failed");
+ return -1;
+ }
+
+ lowmem_fd = open(lowmem_dev_node, O_RDONLY);
+ if (lowmem_fd < 0) {
+ PRT_TRACE_ERR("ss_lowmem_init fd open failed");
+ return -1;
+ }
+
+ oom_timer = NULL;
+ ecore_main_fd_handler_add(lowmem_fd, ECORE_FD_READ, lowmem_cb, ad, NULL,
+ NULL);
+ if (set_threshold() < 0) {
+ PRT_TRACE_ERR("Setting lowmem threshold is failed");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/ss_main.c b/ss_main.c
new file mode 100644
index 0000000..09c3520
--- /dev/null
+++ b/ss_main.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <systemd/sd-daemon.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <heynoti.h>
+#include <sys/reboot.h>
+
+#include "ss_log.h"
+#include "ss_core.h"
+#include "ss_sig_handler.h"
+#include "ss_device_handler.h"
+#include "ss_pmon_handler.h"
+#include "ss_sysnoti.h"
+#include "ss_noti.h"
+#include "ss_queue.h"
+#include "ss_predefine.h"
+#include "ss_bs.h"
+#include "ss_procmgr.h"
+#include "ss_timemgr.h"
+#include "ss_cpu_handler.h"
+#include "app2ext.h"
+#include "include/ss_data.h"
+
+static void fini(struct ss_main_data *ad)
+{
+ app2ext_exit();
+}
+
+static void init_ad(struct ss_main_data *ad)
+{
+ memset(ad, 0x0, sizeof(struct ss_main_data));
+}
+
+static void writepid(char *pidpath)
+{
+ FILE *fp;
+
+ fp = fopen(pidpath, "w");
+ if (fp != NULL) {
+ fprintf(fp, "%d", getpid());
+ fclose(fp);
+ }
+}
+
+static void system_server_init(struct ss_main_data *ad)
+{
+ ad->sysnoti_fd = ss_sysnoti_init();
+ if (ss_noti_init() < 0)
+ PRT_TRACE_ERR("init noti error");
+
+ ss_queue_init();
+ ss_core_init(ad);
+ ss_signal_init();
+ ss_predefine_internal_init();
+ ss_process_manager_init();
+ ss_time_manager_init();
+ ss_cpu_handler_init();
+
+ ss_lowmem_init(ad);
+ ss_lowbat_init(ad);
+ ss_usb_init();
+ ss_ta_init();
+ ss_pmon_init(ad);
+ ss_device_change_init(ad);
+ ss_mmc_init();
+ app2ext_init();
+ ss_bs_init();
+}
+
+#define SS_PIDFILE_PATH "/var/run/.system_server.pid"
+static void sig_quit(int signo)
+{
+ PRT_TRACE_ERR("received SIGTERM signal %d", signo);
+ if (is_power_off() == 1)
+ reboot(RB_POWER_OFF);
+}
+static int system_main(int argc, char **argv)
+{
+ struct ss_main_data ad;
+
+ init_ad(&ad);
+ if ((ad.noti_fd = heynoti_init()) < 0) {
+ PRT_TRACE_ERR("Hey Notification Initialize failed");
+ fini(&ad);
+ return 0;
+ }
+ if (heynoti_attach_handler(ad.noti_fd) != 0) {
+ PRT_TRACE_ERR("fail to attach hey noti handler");
+ fini(&ad);
+ return 0;
+ }
+
+ system_server_init(&ad);
+ signal(SIGTERM, sig_quit);
+
+ // Notyfication to systemd
+ if (sd_booted())
+ sd_notify(0, "READY=1");
+
+ ecore_main_loop_begin();
+
+ fini(&ad);
+ ecore_shutdown();
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ writepid(SS_PIDFILE_PATH);
+ ecore_init();
+ return system_main(argc, argv);
+}
diff --git a/ss_mmc_handler.c b/ss_mmc_handler.c
new file mode 100644
index 0000000..c837abd
--- /dev/null
+++ b/ss_mmc_handler.c
@@ -0,0 +1,905 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <sys/smack.h>
+#include <sys/statvfs.h>
+#include <errno.h>
+#include <vconf.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/statfs.h>
+#include <bundle.h>
+#include <mntent.h>
+#include "ss_log.h"
+#include "ss_device_handler.h"
+#include "ss_predefine.h"
+#include "app2ext.h"
+
+#define VCONFKEY_INTERNAL_PRIVATE_MMC_ID "db/private/sysman/mmc_device_id"
+
+#define MMC_MOUNT_POINT "/opt/storage/sdcard"
+
+#define MMC_DEV "/dev/mmcblk"
+#define MOVINAND_DEV "/dev/mmcblk0p1"
+#define FORMAT_MMC PREFIX"/sbin/mkfs.vfat "
+#define FORMAT_MOVINAND PREFIX"/bin/movi_format.sh"
+
+#define FS_VFAT_NAME "mkdosfs"
+#define FS_VFAT_MOUNT_OPT "uid=0,gid=0,dmask=0000,fmask=0111,iocharset=iso8859-1,utf8,shortname=mixed"
+#define FS_VFAT_CHECKER "/sbin/fsck.vfat"
+#define FS_EXT4_CHECKER "/sbin/fsck.ext4"
+#define FS_VFAT_CHECK_PARAM "-a %s"
+#define FS_EXT4_CHECK_PARAM "-f -y %s"
+#define FS_EXT4_SMACK_LABEL "mmc-smack-label "MMC_MOUNT_POINT
+
+#define SMACKFS_MAGIC 0x43415d53
+#define SMACKFS_MNT "/smack"
+#define SMACKFS_MOUNT_OPT "smackfsroot=*,smackfsdef=*"
+
+#ifndef ST_RDONLY
+#define ST_RDONLY 0x0001
+#endif
+
+#define MMC_PARENT_PATH "/opt/storage"
+
+#define BUF_LEN 20
+
+#define MMC_32GB_SIZE 61315072
+#define UNMOUNT_RETRY 5
+
+#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
+
+enum mount_operation {
+ UNMOUNT_NORMAL = 0,
+ UNMOUNT_FORCE,
+};
+
+typedef enum {
+ FS_TYPE_NONE = 0,
+ FS_TYPE_FAT = 1,
+ FS_TYPE_EXT4
+} mmc_fs_type;
+
+typedef enum {
+ FS_MOUNT_ERR = -1,
+ FS_MOUNT_FAIL = 0,
+ FS_MOUNT_SUCCESS = 1,
+} mmc_mount_type;
+
+
+struct fs_check {
+ unsigned int type;
+ char *name;
+ unsigned int offset;
+ unsigned int magic_sz;
+ char magic[4];
+};
+
+static struct fs_check fs_types[2] = {
+ {
+ FS_TYPE_FAT,
+ "vfat",
+ 0x1fe,
+ 2,
+ {0x55, 0xaa}
+ },
+ {
+ FS_TYPE_EXT4,
+ "ext4",
+ 0x438,
+ 2,
+ {0x53, 0xef}
+ },
+};
+
+
+static const char *fsstr[] = {
+ [FS_TYPE_FAT] = "mkdosfs",
+};
+
+static const char *vfat_arg[] = {
+ "/sbin/mkfs.vfat",
+ NULL, NULL,
+};
+
+static const char *ext4_arg[] = {
+ "/sbin/mkfs.ext4",
+ NULL, NULL,
+};
+
+static const char *vfat_check_arg[] = {
+ "/sbin/fsck.vfat",
+ "-a", NULL, NULL,
+};
+
+static const char *ext4_check_arg[] = {
+ "/sbin/fsck.ext4",
+ "-f", "-y", NULL, NULL,
+};
+
+
+static int smack;
+static int mmc_popup_pid;
+static mmc_fs_type inserted_type;
+
+static void __attribute__ ((constructor)) smack_check(void)
+{
+ struct statfs sfs;
+ int ret;
+
+ do {
+ ret = statfs(SMACKFS_MNT, &sfs);
+ } while (ret < 0 && errno == EINTR);
+
+ if (ret == 0 && sfs.f_type == SMACKFS_MAGIC)
+ smack = 1;
+ PRT_TRACE_ERR("smackfs check %d", smack);
+}
+
+static int exec_process(const char **argv)
+{
+ int pid;
+ int i;
+ int r;
+
+ if (!argv)
+ return -1;
+
+ pid = fork();
+ if (pid == -1)
+ return -1;
+
+ if (!pid) {
+ for (i = 0; i < _NSIG; ++i)
+ signal(i, SIG_DFL);
+ r = execv(argv[0], argv);
+ if (r == -1) {
+ PRT_TRACE_ERR("execv() error");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ return pid;
+}
+
+int get_mmcblk_num(void)
+{
+ DIR *dp;
+ struct dirent *dir;
+ struct stat stat;
+ char buf[255];
+ int fd;
+ int r;
+ int mmcblk_num;
+ char *pre_mmc_device_id = NULL;
+ int mmc_dev_changed = 0;
+
+ if ((dp = opendir("/sys/block")) == NULL) {
+ PRT_TRACE_ERR("Can not open directory..\n");
+ return -1;
+ }
+ chdir("/sys/block");
+
+ while ((dir = readdir(dp)) != NULL) {
+ memset(&stat, 0, sizeof(struct stat));
+ if(lstat(dir->d_name, &stat) < 0) {continue;}
+ if (S_ISDIR(stat.st_mode) || S_ISLNK(stat.st_mode)) {
+ if (strncmp(".", dir->d_name, 1) == 0
+ || strncmp("..", dir->d_name, 2) == 0)
+ continue;
+ if (strncmp("mmcblk", dir->d_name, 6) == 0) {
+ snprintf(buf, 255, "/sys/block/%s/device/type",
+ dir->d_name);
+
+ fd = open(buf, O_RDONLY);
+ if (fd == -1) {
+ PRT_TRACE_ERR("%s open error: %s", buf,
+ strerror(errno));
+ continue;
+ }
+ r = read(fd, buf, 10);
+ if ((r >= 0) && (r < 10))
+ buf[r] = '\0';
+ else
+ PRT_TRACE_ERR("%s read error: %s", buf,
+ strerror(errno));
+ close(fd);
+ if (strncmp("SD", buf, 2) == 0) {
+ char *str_mmcblk_num = strndup((dir->d_name) + 6, 1);
+ if (str_mmcblk_num == NULL) {
+ PRT_TRACE_ERR("Memory Allocation Failed");
+ closedir(dp);
+ return -1;
+ }
+ mmcblk_num =
+ atoi(str_mmcblk_num);
+
+ free(str_mmcblk_num);
+ closedir(dp);
+ PRT_TRACE("%d \n", mmcblk_num);
+
+ snprintf(buf, 255, "/sys/block/%s/device/cid", dir->d_name);
+
+ fd = open(buf, O_RDONLY);
+ if (fd == -1) {
+ PRT_TRACE_ERR("%s open error", buf, strerror(errno));
+ return mmcblk_num;
+ }
+ r = read(fd, buf, 255);
+ if ((r >=0) && (r < 255)) {
+ buf[r] = '\0';
+ } else {
+ PRT_TRACE_ERR("%s read error: %s", buf,strerror(errno));
+ }
+ close(fd);
+ pre_mmc_device_id = vconf_get_str(VCONFKEY_INTERNAL_PRIVATE_MMC_ID);
+ if (pre_mmc_device_id) {
+ if (strcmp(pre_mmc_device_id, "") == 0) {
+ vconf_set_str(VCONFKEY_INTERNAL_PRIVATE_MMC_ID, buf);
+ } else if (strncmp(pre_mmc_device_id,buf,33) == 0) {
+ if ( vconf_get_int(VCONFKEY_SYSMAN_MMC_DEVICE_CHANGED,&mmc_dev_changed) == 0
+ && mmc_dev_changed != VCONFKEY_SYSMAN_MMC_NOT_CHANGED) {
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_DEVICE_CHANGED, VCONFKEY_SYSMAN_MMC_NOT_CHANGED);
+ }
+ } else if (strncmp(pre_mmc_device_id,buf,32) != 0) {
+ vconf_set_str(VCONFKEY_INTERNAL_PRIVATE_MMC_ID, buf);
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_DEVICE_CHANGED, VCONFKEY_SYSMAN_MMC_CHANGED);
+ }
+ free(pre_mmc_device_id);
+ } else {
+ PRT_TRACE_ERR("failed to get pre_mmc_device_id");
+ }
+ return mmcblk_num;
+ }
+ }
+
+ }
+ }
+ closedir(dp);
+ PRT_TRACE_ERR("Failed to find mmc block number\n");
+ return -1;
+}
+
+static int __umount_fs(void)
+{
+ int ret;
+ if ((ret = umount2(MMC_MOUNT_POINT, MNT_DETACH)) != 0) {
+ PRT_TRACE_ERR("Failed to unmount mmc card : %s\n", strerror(errno));
+ }
+ return ret;
+}
+
+static int __check_mmc_fs_type(const char *path)
+{
+ int fd, ret, i;
+ char buf[20];
+ int len = 20;
+ char *tmpbuf = buf;
+ int cnr = 0;
+ struct statfs sfs;
+
+ inserted_type = FS_TYPE_NONE;
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ PRT_TRACE_ERR("can't open the '%s': %s", path, strerror(errno));
+ return -1;
+ }
+
+ while (len != 0 && (ret = read(fd, tmpbuf, len)) != 0) {
+ if (ret == -1) {
+ if (errno == EINTR) {
+ PRT_TRACE_ERR("check_mmc_fs error(%d)", errno);
+ continue;
+ }
+ PRT_TRACE_ERR("Can't read the '%s': %s", path, strerror(errno));
+ inserted_type = FS_TYPE_FAT;
+ goto check_return;
+ }
+ len -= ret;
+ tmpbuf += ret;
+ cnr += ret;
+ }
+ PRT_TRACE("mmc search path: %s, %s", path, buf);
+
+ /* check fs type with magic code */
+ for (i = 0; i < ARRAY_SIZE(fs_types); i++)
+ {
+ ret = lseek(fd, fs_types[i].offset, SEEK_SET);
+ if (ret < 0)
+ goto check_return;
+ ret = read(fd, buf, 2);
+ if (ret < 0)
+ goto check_return;
+ PRT_TRACE("mmc search magic : 0x%2x, 0x%2x", buf[0],buf[1]);
+ if (!memcmp(buf, fs_types[i].magic, fs_types[i].magic_sz)) {
+ inserted_type = fs_types[i].type;
+ PRT_TRACE("mmc type : %s", fs_types[i].name);
+ goto check_return;
+ }
+ }
+
+ if (inserted_type == FS_TYPE_NONE)
+ inserted_type = FS_TYPE_FAT;
+
+check_return:
+ close(fd);
+ return 0;
+}
+
+static int get_format_type(const char *path)
+{
+ unsigned int size;
+
+ if (__check_mmc_fs_type(path) != 0) {
+ PRT_TRACE_ERR("fail to check mount point %s", path);
+ return -1;
+ }
+ if (inserted_type == FS_TYPE_EXT4)
+ return 0;
+
+ return 0;
+}
+
+static const char **get_argument(const char *path, int fs)
+{
+ int argc;
+
+ switch (fs) {
+ case FS_TYPE_FAT:
+ argc = ARRAY_SIZE(vfat_arg);
+ vfat_arg[argc - 2] = path;
+ return vfat_arg;
+ case FS_TYPE_EXT4:
+ argc = ARRAY_SIZE(ext4_arg);
+ ext4_arg[argc - 2] = path;
+ return ext4_arg;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+bool mmc_check_mounted(const char *mount_point)
+{
+ struct stat parent_stat, mount_stat;
+ char parent_path[PATH_MAX];
+
+ snprintf(parent_path, sizeof(parent_path), "%s", MMC_PARENT_PATH);
+
+ if (stat(mount_point, &mount_stat) != 0 || stat(parent_path, &parent_stat) != 0)
+ return false;
+
+ if (mount_stat.st_dev == parent_stat.st_dev)
+ return false;
+
+ return true;
+}
+
+static int create_partition(const char *dev_path)
+{
+ int r;
+ char data[256];
+
+ snprintf(data, sizeof(data), "printf \"n\\n\\n\\n\\n\\nw\" | fdisk %s", dev_path);
+
+ r = system(data);
+ if (WIFSIGNALED(r) && (WTERMSIG(r) == SIGINT || WTERMSIG(r) == SIGQUIT || WEXITSTATUS(r)))
+ return -1;
+
+ return 0;
+}
+
+static int format_mmc(const char *path, int fs)
+{
+ mmc_fs_type type;
+ unsigned int size;
+ int mkfs_pid;
+ const char **argv;
+ char buf[NAME_MAX];
+ int r;
+
+ if (path == NULL) {
+ PRT_TRACE_ERR("Invalid parameter");
+ return -1;
+ }
+
+ argv = get_argument(path, fs);
+ if (argv == NULL) {
+ PRT_TRACE_ERR("get_argument fail");
+ return -1;
+ }
+
+ mkfs_pid = exec_process(argv);
+ if (mkfs_pid < 0) {
+ PRT_TRACE_ERR("%s fail");
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "%s%d", "/proc/", mkfs_pid);
+ PRT_TRACE_ERR("child process : %s", buf);
+ while (1) {
+ sleep(1);
+ PRT_TRACE_ERR("formatting....");
+ if (access(buf, R_OK) != 0)
+ break;
+ }
+
+ return 0;
+}
+
+static int format_exec(int blknum)
+{
+ char dev_mmcblk[NAME_MAX];
+ char dev_mmcblkp[NAME_MAX];
+ int fs, r;
+
+ if (mmc_check_mounted(MMC_MOUNT_POINT) == 1) {
+ PRT_TRACE_ERR("Mounted, will be unmounted");
+ r = __umount_fs();
+ if (r != 0) {
+ PRT_TRACE_ERR("unmount_mmc fail");
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, VCONFKEY_SYSMAN_MMC_FORMAT_FAILED);
+ return -1;
+ }
+ }
+
+ snprintf(dev_mmcblk, sizeof(dev_mmcblk), "%s%d", MMC_DEV, blknum);
+ snprintf(dev_mmcblkp, sizeof(dev_mmcblkp), "%sp1", dev_mmcblk);
+ if (access(dev_mmcblkp, R_OK) < 0) {
+ PRT_TRACE_ERR("%s is not valid, create the primary partition", dev_mmcblkp);
+ r = create_partition(dev_mmcblk);
+ if (r < 0) {
+ PRT_TRACE_ERR("create_partition failed");
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, VCONFKEY_SYSMAN_MMC_FORMAT_FAILED);
+ heynoti_publish("mmcblk_remove");
+ return -1;
+ }
+ }
+
+ PRT_TRACE_ERR("insert type : %d", inserted_type);
+
+ r = format_mmc(dev_mmcblkp, inserted_type);
+ if (r < 0) {
+ PRT_TRACE_ERR("%s format fail", dev_mmcblkp);
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, VCONFKEY_SYSMAN_MMC_FORMAT_FAILED);
+ heynoti_publish("mmcblk_remove");
+ return -1;
+ }
+
+ PRT_TRACE_ERR("Format Successful");
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, VCONFKEY_SYSMAN_MMC_FORMAT_COMPLETED);
+ return 0;
+}
+
+static const char **get_check_argument(const char *path)
+{
+ int argc;
+
+ switch (inserted_type) {
+ case FS_TYPE_EXT4:
+ argc = ARRAY_SIZE(ext4_check_arg);
+ ext4_check_arg[argc - 2] = path;
+ return ext4_check_arg;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static int mmc_check_process_launch(int argc, char **argv)
+{
+ const char **params;
+ char buf[NAME_MAX];
+ int pid;
+
+ params = get_check_argument((const char*)argv[1]);
+ if ((pid = exec_process(params)) < 0) {
+ PRT_TRACE_ERR("mmc checker failed");
+ goto run_mount;
+ }
+
+ snprintf(buf, sizeof(buf), "%s%d", "/proc/", pid);
+ PRT_TRACE_ERR("child process : %s", buf);
+
+ while (1) {
+ sleep(1);
+ PRT_TRACE_ERR("mmc checking ....");
+ if (access(buf, R_OK) != 0)
+ break;
+ }
+run_mount:
+ ss_action_entry_call_internal(PREDEF_CHECK_MMC,0);
+ return 0;
+
+}
+
+static int mmc_check(const char *path)
+{
+ int ret = false;
+ struct mntent* mnt;
+ const char* table = "/etc/mtab";
+ FILE* fp;
+
+ fp = setmntent(table, "r");
+ if (!fp)
+ return ret;
+ while (mnt=getmntent(fp)) {
+ if (!strcmp(mnt->mnt_dir, path)) {
+ ret = true;
+ break;
+ }
+ }
+ endmntent(fp);
+ return ret;
+}
+
+static int mmc_check_and_unmount(const char *path)
+{
+ if (mmc_check(path))
+ if (umount(path) < 0)
+ return -errno;
+ return 0;
+}
+
+static int kill_app_accessing_mmc(bool force)
+{
+ const char *argv[7] = {"/sbin/fuser", "-m", "-k", "-S", NULL, MMC_MOUNT_POINT, NULL};
+
+ if (force)
+ argv[4] = "-SIGKILL";
+ else
+ argv[4] = "-SIGTERM";
+
+ return exec_process(argv);
+}
+
+static int mmc_unmount(int option, const char *mount_point)
+{
+ int r, retry;
+ int kill_op;
+
+ if (!mmc_check_mounted(mount_point))
+ return 0;
+
+ r = mmc_check_and_unmount(mount_point);
+ if (!r)
+ return r;
+ if (option == UNMOUNT_NORMAL) {
+ PRT_TRACE_EM("Failed to unmount with normal option : %s", strerror(-r));
+ return r;
+ }
+
+ PRT_TRACE_EM("Execute force unmount!");
+ /* at first, it will be send SIGTERM
+ if app still access the SD-card, it will kill with SIGKILL */
+ for (retry = UNMOUNT_RETRY; retry > 0; --retry) {
+ switch (retry) {
+ case UNMOUNT_RETRY:
+ /* At first, notify to other app who already access sdcard */
+ PRT_TRACE_EM("Notify to other app who already access sdcard");
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
+ break;
+ case UNMOUNT_RETRY-1:
+ /* Second, kill app with SIGTERM */
+ PRT_TRACE_EM("Kill app with SIGTERM");
+ kill_app_accessing_mmc(false);
+ break;
+ case UNMOUNT_RETRY-2:
+ /* Last time, kill app with SIGKILL */
+ PRT_TRACE_EM("Kill app with SIGKILL");
+ kill_app_accessing_mmc(true);
+ break;
+ default:
+ break;
+ }
+
+ /* it takes some seconds til other app completely clean up */
+ usleep(500000);
+
+ /* try to unmount app2ext */
+ r = app2ext_unmount();
+ if (r < 0)
+ PRT_TRACE_ERR("Faild to unmount app2ext : %s", strerror(-r));
+
+ r = mmc_check_and_unmount(mount_point);
+ if (!r)
+ break;
+ }
+
+ return r;
+}
+
+int ss_mmc_unmounted(int argc, char **argv)
+{
+ int option = -1;
+ int r;
+ int mmc_err = 0;
+ if (argc < 1) {
+ PRT_TRACE_ERR("Option is wong");
+ return -1;
+ }
+ if ((option = atoi(argv[0])) < 0) {
+ PRT_TRACE_ERR("Option is wong : %d", option);
+ return -1;
+ }
+
+ r = mmc_unmount(option, MMC_MOUNT_POINT);
+ if (r < 0)
+ goto error;
+
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_UNMOUNT, VCONFKEY_SYSMAN_MMC_UNMOUNT_COMPLETED);
+ return 0;
+
+error:
+ PRT_TRACE_ERR("Failed to unmount mmc card : %s\n", strerror(-r));
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_UNMOUNT, VCONFKEY_SYSMAN_MMC_UNMOUNT_FAILED);
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_ERR_STATUS, -r);
+ return r;
+}
+
+
+static int __ss_rw_mount(const char* szPath)
+{
+ struct statvfs mount_stat;
+ if (!statvfs(szPath, &mount_stat)) {
+ if ((mount_stat.f_flag & ST_RDONLY) == ST_RDONLY)
+ return -1;
+ }
+ return 0;
+}
+
+static int __ss_check_smack_popup(void)
+{
+ bundle *b = NULL;
+ int ret = -1;
+ int val = -1;
+
+ b = bundle_create();
+ bundle_add(b, "_SYSPOPUP_CONTENT_", "checksmack");
+ ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &val);
+ if (val == 1 || ret != 0) {
+ if ((mmc_popup_pid = syspopup_launch("mmc-syspopup", b)) < 0) {
+ PRT_TRACE_EM("popup launch failed\n");
+ }
+ }
+ bundle_free(b);
+
+ if (ss_action_entry_call_internal(PREDEF_CHECK_SMACK_MMC, 0) < 0) {
+ PRT_TRACE_ERR("fail to launch mmc checker,direct mount mmc");
+ }
+ return 0;
+
+}
+
+static int __mount_fs(char *path, const char *fs_name, const char *mount_data)
+{
+ int ret, retry = 0;
+
+ do {
+ if ((ret = mount(path, MMC_MOUNT_POINT, fs_name, 0, mount_data)) == 0) {
+ PRT_TRACE_ERR("Mounted mmc card %s", fs_name);
+ return 0;
+ }
+ usleep(100000);
+ } while (ret == -1 && errno == ENOENT && retry++ < 10);
+
+ return errno;
+}
+
+static int __mmc_mount_fs(void)
+{
+ char buf[NAME_MAX];
+ char params[NAME_MAX];
+ char options[NAME_MAX];
+ int fd;
+ int blk_num;
+
+ if (access(MMC_MOUNT_POINT, R_OK) != 0) {
+ if (mkdir(MMC_MOUNT_POINT, 0755) < 0) {
+ PRT_TRACE_ERR("Make Directory is failed");
+ return errno;
+ }
+ }
+
+ blk_num = get_mmcblk_num();
+ if (blk_num == -1) {
+ PRT_TRACE_ERR("fail to check mmc block");
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "%s%dp1", MMC_DEV, blk_num);
+ fd = open(buf, O_RDONLY);
+ if (fd < 0) {
+ PRT_TRACE_ERR("can't open the '%s': %s", buf, strerror(errno));
+ snprintf(buf, sizeof(buf), "%s%d", MMC_DEV, blk_num);
+ } else
+ close(fd);
+
+ switch (inserted_type) {
+ case FS_TYPE_FAT:
+ if (smack)
+ snprintf(options, sizeof(options), "%s,%s", FS_VFAT_MOUNT_OPT, SMACKFS_MOUNT_OPT);
+ else
+ snprintf(options, sizeof(options), "%s", FS_VFAT_MOUNT_OPT);
+ if (__mount_fs(buf, "vfat", options) != 0)
+ return -1;
+ break;
+ case FS_TYPE_EXT4:
+ if (__mount_fs(buf, "ext4", NULL) != 0)
+ return errno;
+ if (smack) {
+ if (__ss_check_smack_popup() != 0)
+ return -1;
+ }
+ return smack;
+ }
+ return 0;
+}
+
+static int mmc_check_mount(int argc, char **argv)
+{
+ int r;
+ r = __mmc_mount_fs();
+ if (r == 0)
+ goto mount_complete;
+ else if (r == 1)
+ goto mount_wait;
+ else if (r == -1)
+ goto mount_fail;
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_FAILED);
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_ERR_STATUS, errno);
+ PRT_TRACE_ERR("Failed to mount mmc card\n");
+ return -1;
+
+mount_complete:
+ r = __ss_rw_mount(MMC_MOUNT_POINT);
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED);
+ if (r == -1)
+ return -1;
+ return 0;
+mount_fail:
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_REMOVED);
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_FAILED);
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_ERR_STATUS, VCONFKEY_SYSMAN_MMC_EINVAL);
+ return 0;
+mount_wait:
+ PRT_TRACE_ERR("wait ext4 smack rule checking");
+ return 0;
+}
+
+static int __check_mmc_fs(void)
+{
+ char buf[NAME_MAX];
+ char params[NAME_MAX];
+ char options[NAME_MAX];
+ int fd;
+ int blk_num;
+ int ret = 0;
+
+ if (access(MMC_MOUNT_POINT, R_OK) != 0) {
+ if (mkdir(MMC_MOUNT_POINT, 0755) < 0) {
+ PRT_TRACE_ERR("Make Directory is failed");
+ return errno;
+ }
+ }
+
+ blk_num = get_mmcblk_num();
+ if (blk_num == -1) {
+ PRT_TRACE_ERR("fail to check mmc block");
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "%s%dp1", MMC_DEV, blk_num);
+ fd = open(buf, O_RDONLY);
+ if (fd < 0) {
+ PRT_TRACE_ERR("can't open the '%s': %s", buf, strerror(errno));
+ snprintf(buf, sizeof(buf), "%s%d", MMC_DEV, blk_num);
+ }
+ else
+ close(fd);
+
+ if (__check_mmc_fs_type(buf) != 0) {
+ PRT_TRACE_ERR("fail to check mount point %s", buf);
+ return -1;
+ }
+ snprintf(params, sizeof(params), "%d", inserted_type);
+ if (ss_action_entry_call_internal(PREDEF_CHECK_MMC_PROC, 2, params, buf) < 0) {
+ PRT_TRACE_ERR("fail to launch mmc checker,direct mount mmc");
+ ret = mmc_check_mount(0, NULL);
+ }
+ return ret;
+}
+
+int ss_mmc_inserted(void)
+{
+ int mmc_status;
+ int ret;
+
+ vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmc_status);
+
+ if (mmc_status == VCONFKEY_SYSMAN_MMC_MOUNTED) {
+ PRT_DBG("Mmc is already mounted.\n");
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_ALREADY);
+ return 0;
+ }
+
+ if ((ret = __check_mmc_fs()) != 0)
+ PRT_TRACE_ERR("fail to check mmc");
+ return ret;
+}
+
+int ss_mmc_removed(void)
+{
+ int mmc_err = 0;
+ /* first, try to unmount app2ext */
+ app2ext_unmount();
+ /* unmount */
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_REMOVED);
+ mmc_err = __umount_fs();
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_ERR_STATUS, mmc_err);
+
+ return 0;
+}
+
+static int ss_mmc_format(int argc, char **argv)
+{
+ PRT_TRACE_ERR("mmc format called");
+ __umount_fs();
+
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS, VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS_NOW);
+ format_exec(get_mmcblk_num());
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS, VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS_NONE);
+
+ if (__check_mmc_fs() != 0)
+ PRT_TRACE_ERR("fail to check mmc");
+
+ return 0;
+}
+
+static int ss_mmc_check_smack(int argc, char **argv)
+{
+ int pid;
+ system(FS_EXT4_SMACK_LABEL);
+ PRT_TRACE_ERR("smack labeling script is run");
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
+ vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED);
+ if (mmc_popup_pid > 0) {
+ PRT_TRACE_ERR("will be killed mmc-popup(%d)", mmc_popup_pid);
+ kill(mmc_popup_pid, SIGTERM);
+ }
+ return 0;
+}
+
+int ss_mmc_init(void)
+{
+ ss_action_entry_add_internal(PREDEF_MOUNT_MMC, ss_mmc_inserted, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_UNMOUNT_MMC, ss_mmc_unmounted, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_FORMAT_MMC, ss_mmc_format, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_CHECK_SMACK_MMC, ss_mmc_check_smack, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_CHECK_MMC, mmc_check_mount, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_CHECK_MMC_PROC, mmc_check_process_launch, NULL, NULL);
+ /* mmc card mount */
+ if (__check_mmc_fs() != 0)
+ PRT_TRACE_ERR("fail to check mmc");
+ return 0;
+}
diff --git a/ss_noti.c b/ss_noti.c
new file mode 100644
index 0000000..c9ed285
--- /dev/null
+++ b/ss_noti.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <heynoti.h>
+#include "ss_log.h"
+
+static int noti_fd;
+
+int ss_noti_getfd()
+{
+ return noti_fd;
+}
+
+int ss_noti_send(char *filename)
+{
+ return heynoti_publish(filename);
+}
+
+int ss_noti_init()
+{
+ noti_fd = heynoti_init();
+ if (noti_fd < 0) {
+ PRT_TRACE_ERR("heynoti_init error");
+ return -1;
+ }
+
+ if (heynoti_attach_handler(noti_fd) < 0) {
+ PRT_TRACE_ERR("heynoti_attach_handler error");
+ return -1;
+ }
+
+ return 0;
+}
+
+int ss_noti_add(const char *noti, void (*cb) (void *), void *data)
+{
+ if (noti_fd < 0)
+ return -1;
+
+ return heynoti_subscribe(noti_fd, noti, cb, data);
+}
diff --git a/ss_noti.h b/ss_noti.h
new file mode 100644
index 0000000..8040035
--- /dev/null
+++ b/ss_noti.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_NOTI_H__
+#define __SS_NOTI_H__
+
+int ss_noti_getfd(void);
+int ss_noti_send(char *filename);
+int ss_noti_add(const char *noti, void (*cb) (void *), void *data);
+int ss_noti_init(void);
+
+#endif /* __SS_NOTI_H__ */
diff --git a/ss_pmon_handler.c b/ss_pmon_handler.c
new file mode 100644
index 0000000..c5476be
--- /dev/null
+++ b/ss_pmon_handler.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <sysman.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "device-node.h"
+#include "ss_log.h"
+#include "ss_launch.h"
+#include "include/ss_data.h"
+#include "ss_common.h"
+
+#define PMON_PERMANENT_DIR "/tmp/permanent"
+
+static Ecore_Fd_Handler *pmon_efd = NULL;
+
+static int __pmon_start(struct ss_main_data *ad);
+static int __pmon_stop(int fd);
+static int replace_char(int size, char *t)
+{
+ while (size > 0) {
+ if (*t == 0)
+ *t = ' ';
+ size--;
+ t++;
+ }
+ return 0;
+}
+
+static char *pmon_get_permanent_pname(int pid)
+{
+ int fd;
+ char buf[PATH_MAX];
+ struct stat st;
+ char *cmdline = NULL;
+
+ snprintf(buf, sizeof(buf), "%s/%d", PMON_PERMANENT_DIR, pid);
+ fd = open(buf, O_RDONLY);
+ if (fd == -1) {
+ PRT_TRACE_ERR("file open error");
+ return NULL;
+ }
+
+ if (fstat(fd, &st) < 0) {
+ PRT_TRACE_ERR("fstat error");
+ close(fd);
+ return NULL;
+ }
+ PRT_TRACE("size = %d", (int)st.st_size);
+
+ cmdline = malloc(st.st_size + 1);
+ if (cmdline == NULL) {
+ PRT_TRACE_ERR("Not enough memory");
+ close(fd);
+ return NULL;
+ }
+ memset(cmdline, 0, st.st_size + 1);
+
+ read(fd, cmdline, st.st_size);
+ /* TODO - must change more smarter */
+ replace_char(st.st_size - 1, cmdline);
+ close(fd);
+
+ return cmdline;
+}
+
+static void print_pmon_state(unsigned int dead_pid)
+{
+ PRT_TRACE("[Process MON] %d killed", dead_pid);
+}
+
+static int pmon_process(int pid, void *ad)
+{
+ char *cmdline;
+ int new_pid;
+ char old_file[PATH_MAX];
+ int fd;
+ int r;
+
+ if (sysconf_is_vip(pid)) {
+ PRT_TRACE_ERR("=======================================");
+ PRT_TRACE_ERR("[Process MON] VIP process dead.");
+ PRT_TRACE_ERR("=======================================");
+ }
+ /* If there is NOT a .hibernation_start file, run following codes
+ * On hibernation processing, just ignore relaunching */
+ else if (access("/tmp/.hibernation_start", R_OK) != 0) {
+ cmdline = pmon_get_permanent_pname(pid);
+ if (cmdline != NULL) {
+ PRT_TRACE("[Process MON] %s relaunch", cmdline);
+ new_pid = ss_launch_evenif_exist(cmdline, "");
+ free(cmdline);
+ if (new_pid > 0) {
+ /* TODO - set oom */
+ char buf[PATH_MAX];
+ char filepath[PATH_MAX];
+ int cnt;
+
+ if (access(PMON_PERMANENT_DIR, R_OK) < 0) {
+ PRT_TRACE("no predefined matrix dir = %s, so created", PMON_PERMANENT_DIR);
+ r = mkdir(PMON_PERMANENT_DIR, 0777);
+ if(r < 0) {
+ PRT_TRACE("Make Directory is failed");
+ return -1;
+ }
+ }
+
+ snprintf(filepath, sizeof(filepath), "%s/%d", PMON_PERMANENT_DIR, pid);
+ fd = open(filepath, O_RDONLY);
+ if (fd == -1) {
+ PRT_TRACE("Failed to open");
+ return -1;
+ }
+ cnt = read(fd, buf, PATH_MAX);
+ close(fd);
+
+ if (cnt <= 0) {
+ PRT_TRACE("Failed to read");
+ return -1;
+ }
+
+ snprintf(filepath, sizeof(filepath), "%s/%d", PMON_PERMANENT_DIR, new_pid);
+
+ fd = open(filepath, O_CREAT | O_WRONLY, 0644);
+ if (fd == -1) {
+ PRT_TRACE("Failed to open");
+ return -1;
+ }
+ if (write(fd, buf, cnt) == -1) {
+ PRT_TRACE("Failed to write");
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ if ( device_set_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_MP_PNP, new_pid) < 0) {
+ PRT_TRACE_ERR("Write new pid failed");
+ }
+ PRT_TRACE("[Process MON] %d ", new_pid);
+
+ FILE *fp;
+
+ PRT_TRACE
+ ("[Process MON] OOMADJ_SET : pid %d, new_oomadj %d",
+ new_pid, (-17));
+
+ fp = open_proc_oom_adj_file(new_pid, "w");
+ if (fp == NULL)
+ return -1;
+ fprintf(fp, "%d", (-17));
+ fclose(fp);
+
+ snprintf(old_file, sizeof(old_file), "%s/%d",
+ PMON_PERMANENT_DIR, pid);
+ unlink(old_file);
+ } else {
+ PRT_TRACE_ERR("[Process MON] failed relaunching");
+ }
+ }
+ }
+ return 0;
+}
+/*
+static unsigned int pmon_read(int fd)
+{
+ unsigned int pid;
+ read(fd, &pid, sizeof(pid));
+ return pid;
+}
+*/
+
+static int pmon_cb(void *data, Ecore_Fd_Handler * fd_handler)
+{
+ int fd;
+ struct ss_main_data *ad = (struct ss_main_data *)data;
+ int dead_pid;
+ if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
+ PRT_TRACE_ERR
+ ("ecore_main_fd_handler_active_get error , return\n");
+ return -1;
+ }
+
+ fd = ecore_main_fd_handler_fd_get(fd_handler);
+
+ if (fd < 0) {
+ PRT_TRACE_ERR("ecore_main_fd_handler_fd_get error , return");
+ return -1;
+ }
+ if (read(fd, &dead_pid, sizeof(dead_pid)) < 0) {
+ __pmon_stop(fd);
+ PRT_TRACE_ERR("Reading DEAD_PID failed, restart ecore fd");
+ __pmon_start(ad);
+ return -1;
+ }
+
+ print_pmon_state(dead_pid);
+ pmon_process(dead_pid, ad);
+
+ return 1;
+}
+
+int ss_pmon_init(struct ss_main_data *ad)
+{
+ int ret = -1;
+ if (pmon_efd) {
+ ecore_main_fd_handler_del(pmon_efd);
+ pmon_efd = NULL;
+ }
+ if (__pmon_start(ad) == -1) {
+ PRT_TRACE_ERR("fail pmon control fd init");
+ return -1;
+ }
+ return 0;
+}
+
+static int __pmon_start(struct ss_main_data *ad)
+{
+ int pmon_fd = -1;
+ char pmon_dev_node[PATH_MAX];
+
+ if (device_get_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_NODE, pmon_dev_node) < 0) {
+ PRT_TRACE_ERR("ss_pmon_init get dev node path failed");
+ return -1;
+ }
+
+ pmon_fd = open(pmon_dev_node, O_RDONLY);
+ if (pmon_fd < 0) {
+ PRT_TRACE_ERR("ss_pmon_init fd open failed");
+ return -1;
+ }
+ pmon_efd = ecore_main_fd_handler_add(pmon_fd, ECORE_FD_READ, pmon_cb, ad, NULL, NULL);
+ if (!pmon_efd) {
+ PRT_TRACE_ERR("error ecore_main_fd_handler_add");
+ return -1;
+ }
+ return 0;
+}
+static int __pmon_stop(int fd)
+{
+ if (pmon_efd) {
+ ecore_main_fd_handler_del(pmon_efd);
+ pmon_efd = NULL;
+ }
+ if (fd >=0) {
+ close(fd);
+ fd = -1;
+ }
+ return 0;
+}
diff --git a/ss_pmon_handler.h b/ss_pmon_handler.h
new file mode 100644
index 0000000..70c7fe4
--- /dev/null
+++ b/ss_pmon_handler.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_PMON_HANDLER_H__
+#define __SS_PMON_HANDLER_H__
+
+#include "include/ss_data.h"
+
+int ss_pmon_init(struct ss_main_data *ad);
+
+#endif /* __SS_PMON_HANDLER_H__ */
diff --git a/ss_predefine.c b/ss_predefine.c
new file mode 100644
index 0000000..44e8d28
--- /dev/null
+++ b/ss_predefine.c
@@ -0,0 +1,918 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <unistd.h>
+#include <time.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sysman.h>
+#include <vconf.h>
+#include <pmapi.h>
+#include <ITapiModem.h>
+#include <TelPower.h>
+#include <tapi_event.h>
+#include <tapi_common.h>
+#include <syspopup_caller.h>
+#include <sys/reboot.h>
+#include <sys/time.h>
+#include <mntent.h>
+#include <sys/mount.h>
+
+#include "ss_log.h"
+#include "ss_launch.h"
+#include "ss_queue.h"
+#include "ss_device_handler.h"
+#include "device-node.h"
+#include "ss_predefine.h"
+#include "ss_procmgr.h"
+#include "ss_vibrator.h"
+#include "include/ss_data.h"
+#include "ss_common.h"
+
+#define PREDEFINE_SO_DIR PREFIX"/lib/ss_predefine/"
+
+#define CALL_EXEC_PATH PREFIX"/bin/call"
+#define LOWMEM_EXEC_PATH PREFIX"/bin/lowmem-popup"
+#define LOWBAT_EXEC_PATH PREFIX"/bin/lowbatt-popup"
+#define USBCON_EXEC_PATH PREFIX"/bin/usb-server"
+#define TVOUT_EXEC_PATH PREFIX"/bin/tvout-selector"
+#define PWROFF_EXEC_PATH PREFIX"/bin/poweroff-popup"
+#define MEMPS_EXEC_PATH PREFIX"/bin/memps"
+#define HDMI_NOTI_EXEC_PATH PREFIX"/bin/hdmi_connection_noti"
+#define LOWBAT_POPUP_NAME "lowbat-syspopup"
+#define POWEROFF_POPUP_NAME "poweroff-syspopup"
+#define HDMI_POPUP_NAME "hdmi-syspopup"
+#define LOWMEM_POPUP_NAME "lowmem-syspopup"
+
+/* wait for 5 sec as victim process be dead */
+#define WAITING_INTERVAL 5
+
+#define TVOUT_X_BIN "/usr/bin/xberc"
+#define TVOUT_FLAG 0x00000001
+#define MEMPS_LOG_FILE "/var/log/memps"
+#define MAX_RETRY 2
+
+#define POWEROFF_DURATION 2
+#define POWEROFF_ANIMATION_PATH "/usr/bin/boot-animation"
+#define POWEROFF_NOTI_NAME "power_off_start"
+
+#define WM_READY_PATH "/tmp/.wm_ready"
+
+#define LOWBAT_OPT_WARNING 1
+#define LOWBAT_OPT_POWEROFF 2
+#define LOWBAT_OPT_CHARGEERR 3
+#define LOWBAT_OPT_CHECK 4
+
+static Ecore_Timer *lowbat_popup_id = NULL;
+static int lowbat_popup_option = 0;
+
+static struct timeval tv_start_poweroff;
+static void powerdown_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data);
+static void poweroff_control_cb(keynode_t *in_key, struct ss_main_data *ad);
+int internal_poweroff_def_predefine_action(int argc, char **argv);
+
+static int ss_flags = 0;
+
+static Ecore_Timer *poweroff_timer_id = NULL;
+static TapiHandle *tapi_handle = NULL;
+static int power_off = 0;
+
+static int __predefine_get_pid(const char *execpath)
+{
+ DIR *dp;
+ struct dirent *dentry;
+ int pid = -1, fd;
+ char buf[PATH_MAX];
+ char buf2[PATH_MAX];
+
+ dp = opendir("/proc");
+ if (!dp) {
+ PRT_TRACE_ERR("open /proc");
+ return -1;
+ }
+
+ while ((dentry = readdir(dp)) != NULL) {
+ if (!isdigit(dentry->d_name[0]))
+ continue;
+
+ pid = atoi(dentry->d_name);
+
+ snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
+ fd = open(buf, O_RDONLY);
+ if (fd < 0)
+ continue;
+ if (read(fd, buf2, PATH_MAX) < 0) {
+ close(fd);
+ continue;
+ }
+ close(fd);
+
+ if (!strcmp(buf2, execpath)) {
+ closedir(dp);
+ return pid;
+ }
+ }
+
+ errno = ESRCH;
+ closedir(dp);
+ return -1;
+}
+
+int is_power_off(void)
+{
+ return power_off;
+}
+
+static void make_memps_log(char *file, pid_t pid, char *victim_name)
+{
+ time_t now;
+ struct tm *cur_tm;
+ char params[4096];
+ char new_log[NAME_MAX];
+ static pid_t old_pid = 0;
+ int ret=-1;
+
+ if (old_pid == pid)
+ return;
+ old_pid = pid;
+
+ now = time(NULL);
+ cur_tm = (struct tm *)malloc(sizeof(struct tm));
+ if (cur_tm == NULL) {
+ PRT_TRACE_ERR("Fail to memory allocation");
+ return;
+ }
+
+ if (localtime_r(&now, cur_tm) == NULL) {
+ PRT_TRACE_ERR("Fail to get localtime");
+ free(cur_tm);
+ return;
+ }
+
+ PRT_TRACE("%s_%s_%d_%.4d%.2d%.2d_%.2d%.2d%.2d.log", file, victim_name,
+ pid, (1900 + cur_tm->tm_year), 1 + cur_tm->tm_mon,
+ cur_tm->tm_mday, cur_tm->tm_hour, cur_tm->tm_min,
+ cur_tm->tm_sec);
+ snprintf(new_log, sizeof(new_log),
+ "%s_%s_%d_%.4d%.2d%.2d_%.2d%.2d%.2d.log", file, victim_name,
+ pid, (1900 + cur_tm->tm_year), 1 + cur_tm->tm_mon,
+ cur_tm->tm_mday, cur_tm->tm_hour, cur_tm->tm_min,
+ cur_tm->tm_sec);
+
+ snprintf(params, sizeof(params), "-f %s", new_log);
+ ret = ss_launch_evenif_exist(MEMPS_EXEC_PATH, params);
+ /* will be removed, just for debugging */
+ if(ret > 0) {
+ FILE *fp;
+ fp = open_proc_oom_adj_file(ret, "w");
+ if (fp != NULL) {
+ fprintf(fp, "%d", (-17));
+ fclose(fp);
+ }
+ }
+ free(cur_tm);
+}
+
+static void remount_ro()
+{
+ struct mntent* mnt;
+ const char* table = "/etc/mtab";
+ const char mmtpoint[10][64];
+ FILE* fp;
+ int r = -1, foundmount=0;
+ char buf[256];
+ fp = setmntent(table, "r");
+
+ if (!fp)
+ return;
+
+ while (mnt=getmntent(fp)) {
+ if (foundmount >= 10)
+ continue;
+ if (!strcmp(mnt->mnt_type, "ext4") && strstr(mnt->mnt_opts, "rw")) {
+ memset(mmtpoint[foundmount], 0, 64);
+ strncpy(mmtpoint[foundmount], mnt->mnt_dir, 63);
+ foundmount++;
+ }
+ }
+ endmntent(fp);
+ while (foundmount) {
+ foundmount--;
+ snprintf(buf, sizeof(buf), "fuser -c %s -k -15", mmtpoint[foundmount]);
+ sleep(1);
+ umount2(mmtpoint[foundmount], MNT_DETACH);
+ }
+}
+
+static int lowmem_get_victim_pid()
+{
+ pid_t pid;
+ int fd;
+
+ if (device_get_property(DEVICE_TYPE_MEMORY, PROP_MEMORY_VICTIM_TASK, &pid) < 0) {
+ PRT_TRACE_ERR("Get victim task failed");
+ return -1;
+ }
+
+ return pid;
+}
+
+int lowmem_def_predefine_action(int argc, char **argv)
+{
+ int pid, ret, oom_adj;
+ char appname[PATH_MAX];
+
+ if (argc < 1)
+ return -1;
+
+ if (!strcmp(argv[0], OOM_MEM_ACT)) {
+ pid = lowmem_get_victim_pid();
+ if (pid > 0 && pid != sysman_get_pid(LOWMEM_EXEC_PATH) && pid != sysman_get_pid(MEMPS_EXEC_PATH)) {
+ if ((sysman_get_cmdline_name(pid, appname, PATH_MAX)) ==
+ 0) {
+ PRT_TRACE_EM
+ ("we will kill, lowmem lv2 = %d (%s)\n",
+ pid, appname);
+
+ make_memps_log(MEMPS_LOG_FILE, pid, appname);
+
+ if(get_app_oomadj(pid, &oom_adj) < 0) {
+ PRT_TRACE_ERR("Failed to get oom_adj");
+ return -1;
+ }
+ PRT_TRACE("%d will be killed with %d oom_adj value", pid, oom_adj);
+
+ kill(pid, SIGTERM);
+
+ if (oom_adj != OOMADJ_FOREGRD_LOCKED && oom_adj != OOMADJ_FOREGRD_UNLOCKED) {
+ return 0;
+ }
+
+ bundle *b = NULL;
+
+ b = bundle_create();
+ bundle_add(b, "_APP_NAME_", appname);
+ ret = syspopup_launch("lowmem-syspopup", b);
+ bundle_free(b);
+ if (ret < 0) {
+ PRT_TRACE_EM("popup lauch failed\n");
+ return -1;
+ }
+
+ if (set_app_oomadj(ret, OOMADJ_SU) < 0) {
+ PRT_TRACE_ERR("Failed to set oom_adj");
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+int usbcon_def_predefine_action(int argc, char **argv)
+{
+ int pid;
+ int val = -1;
+ int ret = -1;
+ int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
+
+ if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &val) == 0) {
+ if (val == 0) {
+ vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,
+ VCONFKEY_SYSMAN_USB_DISCONNECTED);
+ pm_unlock_state(LCD_OFF, STAY_CUR_STATE);
+ return 0;
+ }
+
+ if ( vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &val) == 0 && val == VCONFKEY_SYSMAN_USB_AVAILABLE)
+ return 0;
+
+ vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,
+ VCONFKEY_SYSMAN_USB_AVAILABLE);
+ pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
+ pid = ss_launch_if_noexist(USBCON_EXEC_PATH, NULL);
+ if (pid < 0) {
+ PRT_TRACE_ERR("usb predefine action failed\n");
+ return -1;
+ }
+ return pid;
+ }
+ PRT_TRACE_ERR("failed to get usb status\n");
+ return -1;
+}
+
+int earjackcon_def_predefine_action(int argc, char **argv)
+{
+ int val;
+
+ PRT_TRACE_EM("earjack_normal predefine action\n");
+ if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_EARJACK_ONLINE, &val) == 0) {
+ return vconf_set_int(VCONFKEY_SYSMAN_EARJACK, val);
+ }
+
+ return -1;
+}
+
+int lowbat_popup(void *data)
+{
+ int ret = -1, state = 0;
+ ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &state);
+ if (state == 1 || ret != 0) {
+ bundle *b = NULL;
+ b = bundle_create();
+ if (lowbat_popup_option == LOWBAT_OPT_WARNING || lowbat_popup_option == LOWBAT_OPT_CHECK) {
+ bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
+ } else if(lowbat_popup_option == LOWBAT_OPT_POWEROFF) {
+ bundle_add(b, "_SYSPOPUP_CONTENT_", "poweroff");
+ } else if(lowbat_popup_option == LOWBAT_OPT_CHARGEERR) {
+ bundle_add(b, "_SYSPOPUP_CONTENT_", "chargeerr");
+ } else {
+ bundle_add(b, "_SYSPOPUP_CONTENT_", "check");
+ }
+
+ ret = syspopup_launch("lowbat-syspopup", b);
+ if (ret < 0) {
+ PRT_TRACE_EM("popup lauch failed\n");
+ bundle_free(b);
+ return 1;
+ }
+ lowbat_popup_id = NULL;
+ lowbat_popup_option = 0;
+ bundle_free(b);
+ } else {
+ PRT_TRACE_EM("boot-animation running yet");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int predefine_control_launch(char *name, bundle *b)
+{
+ int pid;
+ static int launched_poweroff = 0;
+ //lowbat-popup
+ if (strncmp(name, LOWBAT_POPUP_NAME, strlen(LOWBAT_POPUP_NAME)) == 0) {
+ if (launched_poweroff == 1) {
+ PRT_TRACE_ERR("will be foreced power off");
+ internal_poweroff_def_predefine_action(0,NULL);
+ return 0;
+ }
+
+ if (lowbat_popup_option == LOWBAT_OPT_POWEROFF)
+ launched_poweroff = 1;
+
+ pid = __predefine_get_pid(LOWBAT_EXEC_PATH);
+ if (pid > 0) {
+ PRT_TRACE_ERR("pre launched %s destroy", LOWBAT_EXEC_PATH);
+ kill(pid, SIGTERM);
+ }
+ if (syspopup_launch(name, b) < 0)
+ return -1;
+ }
+ //poweroff-popup
+ if (strncmp(name, POWEROFF_POPUP_NAME, strlen(POWEROFF_POPUP_NAME)) == 0) {
+ if (syspopup_launch(name, b) < 0)
+ return -1;
+ }
+ //hdmi-popup
+ if (strncmp(name, HDMI_POPUP_NAME, strlen(HDMI_POPUP_NAME)) == 0) {
+ if (syspopup_launch(name, b) < 0)
+ return -1;
+ }
+ //hdmi-noti
+ if (strncmp(name, HDMI_NOTI_EXEC_PATH, strlen(HDMI_NOTI_EXEC_PATH)) == 0) {
+ if (ss_launch_if_noexist(name, "1") < 0)
+ return -1;
+ }
+ //user mem lowmem-popup
+ if (strncmp(name, LOWMEM_POPUP_NAME, strlen(LOWMEM_POPUP_NAME)) == 0) {
+ if (syspopup_launch(name, b) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+void predefine_pm_change_state(unsigned int s_bits)
+{
+ pm_change_state(s_bits);
+}
+
+int lowbat_def_predefine_action(int argc, char **argv)
+{
+ int ret, state=0;
+ char argstr[128];
+ char* option = NULL;
+
+ if (argc < 1)
+ return -1;
+
+ if (lowbat_popup_id != NULL) {
+ ecore_timer_del(lowbat_popup_id);
+ lowbat_popup_id = NULL;
+ }
+
+ bundle *b = NULL;
+ b = bundle_create();
+ if (!strcmp(argv[0],CRITICAL_LOW_BAT_ACT)) {
+ bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
+ lowbat_popup_option = LOWBAT_OPT_CHECK;
+ } else if(!strcmp(argv[0],WARNING_LOW_BAT_ACT)) {
+ bundle_add(b, "_SYSPOPUP_CONTENT_", "warning");
+ lowbat_popup_option = LOWBAT_OPT_WARNING;
+ } else if(!strcmp(argv[0],POWER_OFF_BAT_ACT)) {
+ bundle_add(b, "_SYSPOPUP_CONTENT_", "poweroff");
+ lowbat_popup_option = LOWBAT_OPT_POWEROFF;
+ } else if(!strcmp(argv[0],CHARGE_ERROR_ACT)) {
+ bundle_add(b, "_SYSPOPUP_CONTENT_", "chargeerr");
+ lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
+ }
+
+ ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &state);
+ if (state == 1 || ret != 0) {
+ if (predefine_control_launch("lowbat-syspopup", b) < 0) {
+ PRT_TRACE_ERR("popup lauch failed\n");
+ bundle_free(b);
+ lowbat_popup_option = 0;
+ return -1;
+ }
+ } else {
+ PRT_TRACE_EM("boot-animation running yet");
+ lowbat_popup_id = ecore_timer_add(1, lowbat_popup, NULL);
+ }
+ bundle_free(b);
+ return 0;
+}
+
+Eina_Bool powerdown_ap_by_force(void *data)
+{
+ struct timeval now;
+ int poweroff_duration = POWEROFF_DURATION;
+ char *buf;
+
+ if(tapi_handle != NULL)
+ {
+ tel_deinit(tapi_handle);
+ tapi_handle = NULL;
+ }
+ /* Getting poweroff duration */
+ buf = getenv("PWROFF_DUR");
+ if (buf != NULL && strlen(buf) < 1024)
+ poweroff_duration = atoi(buf);
+ if (poweroff_duration < 0 || poweroff_duration > 60)
+ poweroff_duration = POWEROFF_DURATION;
+
+ gettimeofday(&now, NULL);
+ /* Waiting until power off duration and displaying animation */
+ while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
+ usleep(100000);
+ gettimeofday(&now, NULL);
+ }
+
+ PRT_TRACE("Power off by force\n");
+ /* give a chance to be terminated for each process */
+ power_off = 1;
+ sync();
+ remount_ro();
+ reboot(RB_POWER_OFF);
+ return EINA_TRUE;
+}
+
+static void powerdown_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
+{
+ struct timeval now;
+ int poweroff_duration = POWEROFF_DURATION;
+ char *buf;
+
+ if (poweroff_timer_id) {
+ ecore_timer_del(poweroff_timer_id);
+ poweroff_timer_id = NULL;
+ }
+ if (tapi_handle) {
+ tel_deregister_noti_event(tapi_handle,TAPI_NOTI_MODEM_POWER);
+ tel_deinit(tapi_handle);
+ tapi_handle = NULL;
+ }
+ PRT_TRACE("Power off \n");
+
+ /* Getting poweroff duration */
+ buf = getenv("PWROFF_DUR");
+ if (buf != NULL && strlen(buf) < 1024)
+ poweroff_duration = atoi(buf);
+ if (poweroff_duration < 0 || poweroff_duration > 60)
+ poweroff_duration = POWEROFF_DURATION;
+
+ gettimeofday(&now, NULL);
+ /* Waiting until power off duration and displaying animation */
+ while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
+ usleep(100000);
+ gettimeofday(&now, NULL);
+ }
+
+ /* give a chance to be terminated for each process */
+ power_off = 1;
+ sync();
+ remount_ro();
+ reboot(RB_POWER_OFF);
+}
+static void powerdown_res_cb(TapiHandle *handle, int result, void *data, void *user_data)
+{
+ PRT_TRACE("poweroff command request : %d",result);
+}
+
+int poweroff_def_predefine_action(int argc, char **argv)
+{
+ int retry_count = 0;
+
+ heynoti_publish(POWEROFF_NOTI_NAME);
+
+ while (retry_count < MAX_RETRY) {
+ if (ss_action_entry_call_internal(PREDEF_INTERNAL_POWEROFF, 0) < 0) {
+ PRT_TRACE_ERR("failed to request poweroff to system_server \n");
+ retry_count++;
+ continue;
+ }
+ vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void*)poweroff_control_cb);
+ return 0;
+ }
+ return -1;
+}
+
+int internal_poweroff_def_predefine_action(int argc, char **argv)
+{
+ int ret;
+
+ system("/etc/rc.d/rc.shutdown &");
+ sync();
+
+ gettimeofday(&tv_start_poweroff, NULL);
+ if (tapi_handle) {
+ ret = tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER, powerdown_ap, NULL);
+
+ if (ret != TAPI_API_SUCCESS) {
+ PRT_TRACE_ERR
+ ("tel_register_event is not subscribed. error %d\n", ret);
+ powerdown_ap_by_force(NULL);
+ return 0;
+ }
+
+ ret = tel_process_power_command(tapi_handle, TAPI_PHONE_POWER_OFF, powerdown_res_cb, NULL);
+ if (ret != TAPI_API_SUCCESS) {
+ PRT_TRACE_ERR("tel_process_power_command() error %d\n", ret);
+ powerdown_ap_by_force(NULL);
+ return 0;
+ }
+ poweroff_timer_id = ecore_timer_add(15, powerdown_ap_by_force, NULL);
+ } else {
+ powerdown_ap_by_force(NULL);
+ }
+ return 0;
+}
+
+static void enter_flight_mode_cb(TapiHandle *handle, int result, void *data, void *user_data)
+{
+ int bCurFlightMode = 0;
+ if (result != TAPI_POWER_FLIGHT_MODE_ENTER) {
+ PRT_TRACE_ERR("flight mode enter failed %d",result);
+ } else {
+ PRT_TRACE("enter flight mode result : %d",result);
+ if (vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE,&bCurFlightMode) == 0) {
+ PRT_TRACE("Flight Mode is %d", bCurFlightMode);
+ } else {
+ PRT_TRACE_ERR("failed to get vconf key");
+ }
+ }
+}
+
+static void leave_flight_mode_cb(TapiHandle *handle, int result, void *data, void *user_data)
+{
+ int bCurFlightMode = 0;
+ if (result != TAPI_POWER_FLIGHT_MODE_LEAVE) {
+ PRT_TRACE_ERR("flight mode leave failed %d",result);
+ } else {
+ PRT_TRACE("leave flight mode result : %d",result);
+ if (vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE,&bCurFlightMode) == 0) {
+ PRT_TRACE("Flight Mode is %d", bCurFlightMode);
+ } else {
+ PRT_TRACE_ERR("failed to get vconf key");
+ }
+ }
+}
+
+int entersleep_def_predefine_action(int argc, char **argv)
+{
+ int ret;
+
+ pm_change_state(LCD_NORMAL);
+ sync();
+
+ ret = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_ENTER, enter_flight_mode_cb, NULL);
+ PRT_TRACE_ERR("request for changing into flight mode : %d\n", ret);
+
+ system("/etc/rc.d/rc.entersleep");
+ pm_change_state(POWER_OFF);
+
+ return 0;
+}
+
+int leavesleep_def_predefine_action(int argc, char **argv)
+{
+ int ret;
+
+ pm_change_state(LCD_NORMAL);
+ sync();
+
+ ret = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_LEAVE, leave_flight_mode_cb, NULL);
+ PRT_TRACE_ERR("request for changing into flight mode : %d\n", ret);
+
+ return 0;
+}
+
+static void restart_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data);
+
+Eina_Bool restart_ap_ecore(void *data)
+{
+ restart_ap(tapi_handle,NULL,(void *)-1,NULL);
+ return EINA_TRUE;
+}
+
+static void restart_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
+{
+ struct timeval now;
+ int poweroff_duration = POWEROFF_DURATION;
+ char *buf;
+
+ if (poweroff_timer_id) {
+ ecore_timer_del(poweroff_timer_id);
+ poweroff_timer_id = NULL;
+ }
+
+
+ if(tapi_handle != NULL)
+ {
+ tel_deregister_noti_event(tapi_handle,TAPI_NOTI_MODEM_POWER);
+ tel_deinit(tapi_handle);
+ tapi_handle = NULL;
+ }
+
+ PRT_INFO("Restart\n");
+ vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void*)poweroff_control_cb);
+ power_off = 1;
+ sync();
+
+ buf = getenv("PWROFF_DUR");
+ if (buf != NULL && strlen(buf) < 1024)
+ poweroff_duration = atoi(buf);
+ if (poweroff_duration < 0 || poweroff_duration > 60)
+ poweroff_duration = POWEROFF_DURATION;
+ gettimeofday(&now, NULL);
+ while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
+ usleep(100000);
+ gettimeofday(&now, NULL);
+ }
+ remount_ro();
+
+ reboot(RB_AUTOBOOT);
+}
+
+static void restart_ap_by_force(void *data)
+{
+ struct timeval now;
+ int poweroff_duration = POWEROFF_DURATION;
+ char *buf;
+
+ if (poweroff_timer_id) {
+ ecore_timer_del(poweroff_timer_id);
+ poweroff_timer_id = NULL;
+ }
+
+
+ if(tapi_handle != NULL)
+ {
+ tel_deinit(tapi_handle);
+ tapi_handle = NULL;
+ }
+
+ PRT_INFO("Restart\n");
+ power_off = 1;
+ sync();
+
+ buf = getenv("PWROFF_DUR");
+ if (buf != NULL && strlen(buf) < 1024)
+ poweroff_duration = atoi(buf);
+ if (poweroff_duration < 0 || poweroff_duration > 60)
+ poweroff_duration = POWEROFF_DURATION;
+ gettimeofday(&now, NULL);
+ while (now.tv_sec - tv_start_poweroff.tv_sec < poweroff_duration) {
+ usleep(100000);
+ gettimeofday(&now, NULL);
+ }
+ remount_ro();
+
+ reboot(RB_AUTOBOOT);
+}
+
+int restart_def_predefine_action(int argc, char **argv)
+{
+ int ret;
+
+ heynoti_publish(POWEROFF_NOTI_NAME);
+ pm_change_state(LCD_NORMAL);
+ system("/etc/rc.d/rc.shutdown &");
+ sync();
+
+ gettimeofday(&tv_start_poweroff, NULL);
+
+ ret =
+ tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER, restart_ap, NULL);
+ if (ret != TAPI_API_SUCCESS) {
+ PRT_TRACE_ERR
+ ("tel_register_event is not subscribed. error %d\n", ret);
+ restart_ap_by_force((void *)-1);
+ return 0;
+ }
+
+
+ ret = tel_process_power_command(tapi_handle, TAPI_PHONE_POWER_OFF, powerdown_res_cb, NULL);
+ if (ret != TAPI_API_SUCCESS) {
+ PRT_TRACE_ERR("tel_process_power_command() error %d\n", ret);
+ restart_ap_by_force((void *)-1);
+ return 0;
+ }
+
+ poweroff_timer_id = ecore_timer_add(15, restart_ap_ecore, NULL);
+ return 0;
+}
+
+int launching_predefine_action(int argc, char **argv)
+{
+ int ret;
+
+ if (argc < 0)
+ return -1;
+
+ /* current just launching poweroff-popup */
+ if (predefine_control_launch("poweroff-syspopup", NULL) < 0) {
+ PRT_TRACE_ERR("poweroff-syspopup launch failed");
+ return -1;
+ }
+ return 0;
+}
+
+int flight_mode_def_predefine_action(int argc, char **argv)
+{
+ int bCurFlightMode;
+ int err = TAPI_API_SUCCESS;
+ if (argc != 1 || argv[0] == NULL) {
+ PRT_TRACE_ERR("FlightMode Set predefine action failed");
+ return -1;
+ }
+ bCurFlightMode = atoi(argv[0]);
+ if (bCurFlightMode == 1) {
+ err = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_LEAVE, leave_flight_mode_cb, NULL);
+ } else if (bCurFlightMode == 0) {
+ err = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_ENTER, enter_flight_mode_cb, NULL);
+ }
+ if (err != TAPI_API_SUCCESS)
+ PRT_TRACE_ERR("FlightMode tel api action failed %d",err);
+ return 0;
+
+}
+
+static void ss_action_entry_load_from_sodir()
+{
+ DIR *dp;
+ struct dirent *dentry;
+ struct sysnoti *msg;
+ char *ext;
+ char tmp[128];
+
+ dp = opendir(PREDEFINE_SO_DIR);
+ if (!dp) {
+ ERR("fail open %s", PREDEFINE_SO_DIR);
+ return;
+ }
+
+ msg = malloc(sizeof(struct sysnoti));
+ if (msg == NULL) {
+ ERR("Malloc failed");
+ closedir(dp);
+ return;
+ }
+
+ msg->pid = getpid();
+
+ while ((dentry = readdir(dp)) != NULL) {
+ if ((ext = strstr(dentry->d_name, ".so")) == NULL)
+ continue;
+
+ snprintf(tmp, sizeof(tmp), "%s/%s", PREDEFINE_SO_DIR,
+ dentry->d_name);
+ msg->path = tmp;
+ *ext = 0;
+ msg->type = &(dentry->d_name[3]);
+ ss_action_entry_add(msg);
+ }
+ free(msg);
+
+ closedir(dp);
+}
+static void __tel_init_cb(keynode_t *key_nodes,void *data)
+{
+ int bTelReady = 0;
+ bTelReady = vconf_keynode_get_bool(key_nodes);
+ if (bTelReady == 1) {
+ vconf_ignore_key_changed(VCONFKEY_TELEPHONY_READY, (void*)__tel_init_cb);
+ tapi_handle = tel_init(NULL);
+ if (tapi_handle == NULL) {
+ PRT_TRACE_ERR("tapi init error");
+ }
+ } else {
+ PRT_TRACE_ERR("tapi is not ready yet");
+ }
+}
+static void poweroff_control_cb(keynode_t *in_key, struct ss_main_data *ad)
+{
+ int val;
+ if (vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val) != 0)
+ return;
+ switch (val) {
+ case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
+ ss_action_entry_call_internal(PREDEF_POWEROFF, 0);
+ break;
+ case VCONFKEY_SYSMAN_POWER_OFF_POPUP:
+ ss_action_entry_call_internal(PREDEF_PWROFF_POPUP, 0);
+ break;
+ case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
+ ss_action_entry_call_internal(PREDEF_REBOOT, 0);
+ break;
+ }
+}
+
+void ss_predefine_internal_init(void)
+{
+
+ /* telephony initialize */
+ int ret = 0;
+ int bTelReady = 0;
+ if (vconf_get_bool(VCONFKEY_TELEPHONY_READY,&bTelReady) == 0) {
+ if (bTelReady == 1) {
+ tapi_handle = tel_init(NULL);
+ if (tapi_handle == NULL) {
+ PRT_TRACE_ERR("tapi init error");
+ }
+ } else {
+ vconf_notify_key_changed(VCONFKEY_TELEPHONY_READY, (void *)__tel_init_cb, NULL);
+ }
+ } else {
+ PRT_TRACE_ERR("failed to get tapi vconf key");
+ }
+#ifdef NOUSE
+ ss_action_entry_add_internal(PREDEF_CALL, call_predefine_action, NULL,
+ NULL);
+#endif
+ ss_action_entry_add_internal(PREDEF_LOWMEM, lowmem_def_predefine_action,
+ NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_LOWBAT, lowbat_def_predefine_action,
+ NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_USBCON, usbcon_def_predefine_action,
+ NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_EARJACKCON,
+ earjackcon_def_predefine_action, NULL,
+ NULL);
+ ss_action_entry_add_internal(PREDEF_POWEROFF,
+ poweroff_def_predefine_action, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_PWROFF_POPUP,
+ launching_predefine_action, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_REBOOT,
+ restart_def_predefine_action, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_FLIGHT_MODE,
+ flight_mode_def_predefine_action, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_INTERNAL_POWEROFF,
+ internal_poweroff_def_predefine_action, NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_HAPTIC, haptic_def_predefine_action,
+ NULL, NULL);
+
+ if (vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void *)poweroff_control_cb, NULL) < 0) {
+ PRT_TRACE_ERR("Vconf notify key chaneged failed: KEY(%s)", VCONFKEY_SYSMAN_POWER_OFF_STATUS);
+ }
+ ss_action_entry_load_from_sodir();
+
+ /* check and set earjack init status */
+ earjackcon_def_predefine_action(0, NULL);
+}
diff --git a/ss_predefine.h b/ss_predefine.h
new file mode 100644
index 0000000..1548ec7
--- /dev/null
+++ b/ss_predefine.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_PREDEFINE_H__
+#define __SS_PREDEFINE_H__
+#include <bundle.h>
+
+int call_predefine_action(int argc, char **argv);
+void ss_predefine_internal_init(void);
+int is_power_off(void);
+void predefine_pm_change_state(unsigned int s_bits);
+int predefine_control_launch(char *popup_name, bundle *b);
+#endif /* __SS_PREDEFINE_H__ */
diff --git a/ss_procmgr.c b/ss_procmgr.c
new file mode 100755
index 0000000..de789eb
--- /dev/null
+++ b/ss_procmgr.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <device-node.h>
+
+#include <sysman.h>
+#include "include/ss_data.h"
+#include "ss_queue.h"
+#include "ss_log.h"
+
+#define LIMITED_BACKGRD_NUM 15
+#define MAX_BACKGRD_OOMADJ (OOMADJ_BACKGRD_UNLOCKED + LIMITED_BACKGRD_NUM)
+#define PROCESS_VIP "process_vip"
+#define PROCESS_PERMANENT "process_permanent"
+
+int get_app_oomadj(int pid, int *oomadj)
+{
+ if (pid < 0)
+ return -1;
+
+ char buf[PATH_MAX];
+ FILE *fp = NULL;
+
+ snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
+ fp = fopen(buf, "r");
+ if (fp == NULL)
+ return -1;
+ if (fgets(buf, PATH_MAX, fp) == NULL) {
+ fclose(fp);
+ return -1;
+ }
+ (*oomadj) = atoi(buf);
+ fclose(fp);
+ return 0;
+}
+
+int set_app_oomadj(pid_t pid, int new_oomadj)
+{
+ char buf[PATH_MAX];
+ FILE *fp;
+ int old_oomadj;
+ char exe_name[PATH_MAX];
+
+ if (sysman_get_cmdline_name(pid, exe_name, PATH_MAX) < 0)
+ snprintf(exe_name, sizeof(exe_name), "Unknown (maybe dead)");
+
+ snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
+ fp = fopen(buf, "r");
+ if (fp == NULL)
+ return -1;
+ if (fgets(buf, PATH_MAX, fp) == NULL) {
+ fclose(fp);
+ return -1;
+ }
+ old_oomadj = atoi(buf);
+ fclose(fp);
+ PRT_TRACE_EM("Process %s, pid %d, old_oomadj %d", exe_name, pid,
+ old_oomadj);
+
+ if (old_oomadj < OOMADJ_APP_LIMIT)
+ return 0;
+
+ PRT_TRACE_EM("Process %s, pid %d, new_oomadj %d", exe_name, pid,
+ new_oomadj);
+ snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
+ fp = fopen(buf, "w");
+ if (fp == NULL)
+ return -1;
+
+ fprintf(fp, "%d", new_oomadj);
+ fclose(fp);
+
+ return 0;
+}
+
+int set_oomadj_action(int argc, char **argv)
+{
+ int pid = -1;
+ int new_oomadj = -20;
+
+ if (argc < 2)
+ return -1;
+ if ((pid = atoi(argv[0])) < 0 || (new_oomadj = atoi(argv[1])) <= -20)
+ return -1;
+
+ char buf[255];
+ FILE *fp;
+
+ PRT_TRACE_EM("OOMADJ_SET : pid %d, new_oomadj %d", pid, new_oomadj);
+ snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
+ fp = fopen(buf, "w");
+ if (fp == NULL)
+ return -1;
+ fprintf(fp, "%d", new_oomadj);
+ fclose(fp);
+
+ return 0;
+}
+
+static int update_backgrd_app_oomadj(pid_t pid, int new_oomadj)
+{
+ char buf[PATH_MAX];
+ FILE* fp;
+
+ snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
+ fp = fopen(buf, "w");
+ if (fp == NULL)
+ return -1;
+
+ fprintf(fp, "%d", new_oomadj);
+ fclose(fp);
+
+ return 0;
+}
+
+int check_and_set_old_backgrd()
+{
+ int pid = -1;
+ DIR *dp;
+ struct dirent *dentry;
+ FILE *fp;
+ char buf[PATH_MAX];
+ int token =0;
+ int oom_adj, new_oomadj, i;
+ pid_t buckets[MAX_BACKGRD_OOMADJ][LIMITED_BACKGRD_NUM];
+
+ dp = opendir("/proc");
+ if (!dp) {
+ PRT_TRACE_EM("BACKGRD MANAGE : fail to open /proc : %s", strerror(errno));
+ return -1;
+ }
+
+ memset(buckets, 0, sizeof(buckets));
+ while ((dentry = readdir(dp)) != NULL) {
+ if (!isdigit(dentry->d_name[0]))
+ continue;
+
+ pid = atoi(dentry->d_name);
+
+ snprintf(buf, sizeof(buf), "/proc/%d/oom_adj", pid);
+ fp = fopen(buf, "r");
+ if (fp == NULL)
+ continue;
+ if (fgets(buf, sizeof(buf), fp) == NULL) {
+ fclose(fp);
+ continue;
+ }
+ oom_adj = atoi(buf);
+ if (oom_adj < MAX_BACKGRD_OOMADJ && oom_adj >= OOMADJ_BACKGRD_UNLOCKED) {
+ pid_t *bucket = buckets[oom_adj];
+ for (i = 0; i < LIMITED_BACKGRD_NUM; i++) {
+ if (!bucket[i])
+ break;
+ }
+ if (i >= LIMITED_BACKGRD_NUM)
+ PRT_TRACE_EM("BACKGRB MANAGE : background applications(oom_adj %d) exceeds limitation", i);
+ else
+ bucket[i] = pid;
+ }
+ fclose(fp);
+ }
+ closedir(dp);
+
+ new_oomadj = OOMADJ_BACKGRD_UNLOCKED + 1;
+ for (oom_adj = OOMADJ_BACKGRD_UNLOCKED; oom_adj < MAX_BACKGRD_OOMADJ; oom_adj++) {
+ for (i = 0; i < LIMITED_BACKGRD_NUM; i++) {
+ pid = buckets[oom_adj][i];
+ if (!pid)
+ break;
+ if (new_oomadj < MAX_BACKGRD_OOMADJ) {
+ if (new_oomadj != oom_adj)
+ update_backgrd_app_oomadj(pid, new_oomadj);
+ new_oomadj++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int set_active_action(int argc, char **argv)
+{
+ int pid = -1;
+ int ret = 0;
+ int oomadj = 0;
+
+ if (argc < 1)
+ return -1;
+ if ((pid = atoi(argv[0])) < 0)
+ return -1;
+
+ if (get_app_oomadj(pid, &oomadj) < 0)
+ return -1;
+
+ switch (oomadj) {
+ case OOMADJ_FOREGRD_LOCKED:
+ case OOMADJ_BACKGRD_LOCKED:
+ case OOMADJ_SU:
+ ret = 0;
+ break;
+ case OOMADJ_FOREGRD_UNLOCKED:
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_LOCKED);
+ break;
+ case OOMADJ_BACKGRD_UNLOCKED:
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
+ break;
+ case OOMADJ_INIT:
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
+ break;
+ default:
+ if(oomadj > OOMADJ_BACKGRD_UNLOCKED) {
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
+ } else {
+ PRT_TRACE_EM("Unknown oomadj value (%d) !", oomadj);
+ ret = -1;
+ }
+ break;
+ }
+ return ret;
+}
+
+int set_inactive_action(int argc, char **argv)
+{
+ int pid = -1;
+ int ret = 0;
+ int oomadj = 0;
+
+ if (argc < 1)
+ return -1;
+ if ((pid = atoi(argv[0])) < 0)
+ return -1;
+
+ if (get_app_oomadj(pid, &oomadj) < 0)
+ return -1;
+
+ switch (oomadj) {
+ case OOMADJ_FOREGRD_UNLOCKED:
+ case OOMADJ_BACKGRD_UNLOCKED:
+ case OOMADJ_SU:
+ ret = 0;
+ break;
+ case OOMADJ_FOREGRD_LOCKED:
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
+ break;
+ case OOMADJ_BACKGRD_LOCKED:
+ check_and_set_old_backgrd();
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
+ break;
+ case OOMADJ_INIT:
+ check_and_set_old_backgrd();
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
+ break;
+ default:
+ if(oomadj > OOMADJ_BACKGRD_UNLOCKED) {
+ ret = 0;
+ } else {
+ PRT_TRACE_EM("Unknown oomadj value (%d) !", oomadj);
+ ret = -1;
+ }
+ break;
+
+ }
+ return ret;
+}
+
+int set_foregrd_action(int argc, char **argv)
+{
+ int pid = -1;
+ int ret = 0;
+ int oomadj = 0;
+
+ if (argc < 1)
+ return -1;
+ if ((pid = atoi(argv[0])) < 0)
+ return -1;
+
+ if (get_app_oomadj(pid, &oomadj) < 0)
+ return -1;
+
+ switch (oomadj) {
+ case OOMADJ_FOREGRD_LOCKED:
+ case OOMADJ_FOREGRD_UNLOCKED:
+ case OOMADJ_SU:
+ ret = 0;
+ break;
+ case OOMADJ_BACKGRD_LOCKED:
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_LOCKED);
+ break;
+ case OOMADJ_BACKGRD_UNLOCKED:
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
+ break;
+ case OOMADJ_INIT:
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
+ break;
+ default:
+ if(oomadj > OOMADJ_BACKGRD_UNLOCKED) {
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
+ } else {
+ PRT_TRACE_EM("Unknown oomadj value (%d) !", oomadj);
+ ret = -1;
+ }
+ break;
+
+ }
+ return ret;
+}
+
+int set_backgrd_action(int argc, char **argv)
+{
+ int pid = -1;
+ int ret = 0;
+ int oomadj = 0;
+
+ if (argc < 1)
+ return -1;
+ if ((pid = atoi(argv[0])) < 0)
+ return -1;
+
+ if (get_app_oomadj(pid, &oomadj) < 0)
+ return -1;
+
+ switch (oomadj) {
+ case OOMADJ_BACKGRD_LOCKED:
+ case OOMADJ_BACKGRD_UNLOCKED:
+ case OOMADJ_SU:
+ ret = 0;
+ break;
+ case OOMADJ_FOREGRD_LOCKED:
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
+ break;
+ case OOMADJ_FOREGRD_UNLOCKED:
+ check_and_set_old_backgrd();
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
+ break;
+ case OOMADJ_INIT:
+ ret = set_app_oomadj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
+ break;
+ default:
+ if(oomadj > OOMADJ_BACKGRD_UNLOCKED) {
+ ret = 0;
+ } else {
+ PRT_TRACE_EM("Unknown oomadj value (%d) !", oomadj);
+ ret = -1;
+ }
+ break;
+ }
+ return ret;
+}
+
+int set_process_group_action(int argc, char **argv)
+{
+ int pid = -1;
+ int ret = -1;
+
+ if (argc != 2)
+ return -1;
+ if ((pid = atoi(argv[0])) < 0)
+ return -1;
+
+ if (strncmp(argv[1], PROCESS_VIP, strlen(PROCESS_VIP)) == 0)
+ ret = device_set_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_MP_VIP, pid);
+ else if (strncmp(argv[1], PROCESS_PERMANENT, strlen(PROCESS_PERMANENT)) == 0)
+ ret = device_set_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_MP_PNP, pid);
+
+ if (ret == 0)
+ PRT_TRACE_ERR("%s : pid %d", argv[1], pid);
+ else
+ PRT_TRACE_ERR("fail to set %s : pid %d",argv[1], pid);
+ return 0;
+}
+
+int ss_process_manager_init(void)
+{
+ ss_action_entry_add_internal(PREDEF_FOREGRD, set_foregrd_action, NULL,
+ NULL);
+ ss_action_entry_add_internal(PREDEF_BACKGRD, set_backgrd_action, NULL,
+ NULL);
+ ss_action_entry_add_internal(PREDEF_ACTIVE, set_active_action, NULL,
+ NULL);
+ ss_action_entry_add_internal(PREDEF_INACTIVE, set_inactive_action, NULL,
+ NULL);
+ ss_action_entry_add_internal(OOMADJ_SET, set_oomadj_action, NULL, NULL);
+ ss_action_entry_add_internal(PROCESS_GROUP_SET, set_process_group_action, NULL, NULL);
+ return 0;
+}
diff --git a/ss_procmgr.h b/ss_procmgr.h
new file mode 100644
index 0000000..d874e51
--- /dev/null
+++ b/ss_procmgr.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_PROCMGR_H__
+#define __SS_PROCMGR_H__
+
+int ss_process_manager_init(void);
+
+int get_app_oomadj(int pid, int *oomadj);
+int set_app_oomadj(int pid, int new_oomadj);
+
+#endif /* __SS_PROCMGR_H__ */
diff --git a/ss_queue.c b/ss_queue.c
new file mode 100644
index 0000000..4269d10
--- /dev/null
+++ b/ss_queue.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <sysman.h>
+#include <dlfcn.h>
+#include "include/ss_data.h"
+#include "ss_core.h"
+#include "ss_queue.h"
+#include "ss_log.h"
+
+#define SS_PREDEFINE_ACT_FUNC_STR "ss_predefine_action"
+#define SS_IS_ACCESSIBLE_FUNC_STR "ss_is_accessible"
+#define SS_UI_VIEWABLE_FUNC_STR "ss_ui_viewable"
+
+static Eina_List *predef_act_list;
+static Eina_List *run_queue;
+
+static struct ss_action_entry *ss_action_entry_find(char *type)
+{
+ Eina_List *tmp;
+ Eina_List *tmp_next;
+ struct ss_action_entry *data;
+
+ EINA_LIST_FOREACH_SAFE(predef_act_list, tmp, tmp_next, data) {
+ if ((data != NULL) && (!strcmp(data->type, type)))
+ return data;
+ }
+
+ return NULL;
+}
+
+int ss_action_entry_add_internal(char *type,
+ int (*predefine_action) (),
+ int (*ui_viewable) (),
+ int (*is_accessible) (int))
+{
+ struct ss_action_entry *data;
+
+ data = malloc(sizeof(struct ss_action_entry));
+
+ if (data == NULL) {
+ PRT_TRACE_ERR("Malloc failed");
+ return -1;
+ }
+
+ data->type = NULL;
+ if (ss_action_entry_find(type) != NULL)
+ goto err;
+
+ data->handle = NULL;
+ data->predefine_action = predefine_action;
+ if (data->predefine_action == NULL)
+ goto err;
+
+ data->is_accessible = is_accessible;
+ data->ui_viewable = ui_viewable;
+ data->owner_pid = getpid();
+ data->type = strdup(type);
+ data->path = strdup("");
+
+ predef_act_list = eina_list_prepend(predef_act_list, data);
+
+ PRT_TRACE_ERR("[SYSMAN] add predefine action entry suceessfully - %s",
+ data->type);
+ return 0;
+ err:
+ if (data->type != NULL)
+ PRT_TRACE_ERR("[SYSMAN] add predefine action entry -%s",
+ data->type);
+ free(data);
+ return -1;
+}
+
+int ss_action_entry_add(struct sysnoti *msg)
+{
+ struct ss_action_entry *data;
+
+ data = malloc(sizeof(struct ss_action_entry));
+
+ if (data == NULL) {
+ PRT_TRACE_ERR("Malloc failed");
+ return -1;
+ }
+
+ if (ss_action_entry_find(msg->type) != NULL)
+ goto err;
+
+ data->handle = dlopen(msg->path, RTLD_LAZY);
+ if (!data->handle) {
+ PRT_TRACE_ERR("cannot find such library");
+ goto err;
+ }
+
+ data->predefine_action = dlsym(data->handle, SS_PREDEFINE_ACT_FUNC_STR);
+ if (data->predefine_action == NULL) {
+ PRT_TRACE_ERR("cannot find predefine_action symbol : %s",
+ SS_PREDEFINE_ACT_FUNC_STR);
+ goto err;
+ }
+
+ data->is_accessible = dlsym(data->handle, SS_IS_ACCESSIBLE_FUNC_STR);
+ data->ui_viewable = dlsym(data->handle, SS_UI_VIEWABLE_FUNC_STR);
+ data->owner_pid = msg->pid;
+ data->type = strdup(msg->type);
+ data->path = strdup(msg->path);
+
+ predef_act_list = eina_list_prepend(predef_act_list, data);
+
+ PRT_TRACE_ERR("[SYSMAN]add predefine action entry suceessfully - %s",
+ data->type);
+ return 0;
+ err:
+ PRT_TRACE_ERR("[SYSMAN] FAIL predefine action entry - %s", msg->type);
+ free(data);
+ return -1;
+}
+
+int ss_action_entry_call_internal(char *type, int argc, ...)
+{
+ Eina_List *tmp;
+ Eina_List *tmp_next;
+ struct ss_action_entry *data;
+ va_list argptr;
+ int i;
+ char *args = NULL;
+ char *argv[SYSMAN_MAXARG];
+
+ if (argc > SYSMAN_MAXARG || type == NULL)
+ return -1;
+
+ EINA_LIST_FOREACH_SAFE(predef_act_list, tmp, tmp_next, data) {
+ if ((data != NULL) && (!strcmp(data->type, type))) {
+ va_start(argptr, argc);
+ for (i = 0; i < argc; i++) {
+ args = va_arg(argptr, char *);
+ if (args != NULL)
+ argv[i] = strdup(args);
+ else
+ argv[i] = NULL;
+ }
+ va_end(argptr);
+
+ int ret;
+ ret=ss_run_queue_add(data, argc, argv);
+ PRT_TRACE_ERR("ss_run_queue_add : %d",ret);
+ ret=ss_core_action_run();
+ PRT_TRACE_ERR("ss_core_action_run : %d",ret);
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+int ss_action_entry_call(struct sysnoti *msg, int sockfd)
+{
+ Eina_List *tmp;
+ Eina_List *tmp_next;
+ struct ss_action_entry *data;
+
+ EINA_LIST_FOREACH_SAFE(predef_act_list, tmp, tmp_next, data) {
+ if ((data != NULL) && (!strcmp(data->type, msg->type))) {
+ if (data->is_accessible != NULL
+ && data->is_accessible(sockfd) == 0) {
+ PRT_TRACE_ERR
+ ("%d cannot call that predefine module",
+ msg->pid);
+ return -1;
+ }
+ int ret;
+ ret=ss_run_queue_add(data, msg->argc, msg->argv);
+ PRT_TRACE_ERR("ss_run_queue_add : %d",ret);
+ ret=ss_core_action_run();
+ PRT_TRACE_ERR("ss_core_action_run : %d",ret);
+ return 0;
+ }
+ }
+
+ PRT_TRACE_EM("[SYSMAN] cannot found action");
+ return -1;
+}
+
+int ss_run_queue_add(struct ss_action_entry *act_entry, int argc, char **argv)
+{
+ struct ss_run_queue_entry *rq_entry;
+ int i;
+
+ rq_entry = malloc(sizeof(struct ss_run_queue_entry));
+
+ if (rq_entry == NULL) {
+ PRT_TRACE_ERR("Malloc failed");
+ return -1;
+ }
+
+ rq_entry->state = SS_STATE_INIT;
+ rq_entry->action_entry = act_entry;
+ rq_entry->forked_pid = 0;
+ if ( argc < 0 ) {
+ rq_entry->argc = 0;
+ } else {
+ rq_entry->argc = argc;
+ for (i = 0; i < argc; i++)
+ rq_entry->argv[i] = argv[i];
+ }
+
+ run_queue = eina_list_prepend(run_queue, rq_entry);
+
+ PRT_TRACE_EM("[SYSMAN] new action called : %s", act_entry->type);
+ return 0;
+}
+
+int ss_run_queue_run(enum ss_run_state state,
+ int (*run_func) (void *, struct ss_run_queue_entry *),
+ void *user_data)
+{
+ Eina_List *tmp;
+ Eina_List *tmp_next;
+ struct ss_run_queue_entry *rq_entry;
+
+ EINA_LIST_FOREACH_SAFE(run_queue, tmp, tmp_next, rq_entry) {
+ if ((rq_entry != NULL) && (rq_entry->state == state))
+ run_func(user_data, rq_entry);
+ }
+
+ return 0;
+}
+
+struct ss_run_queue_entry *ss_run_queue_find_bypid(int pid)
+{
+ Eina_List *tmp;
+ Eina_List *tmp_next;
+ struct ss_run_queue_entry *rq_entry;
+
+ EINA_LIST_FOREACH_SAFE(run_queue, tmp, tmp_next, rq_entry) {
+ if ((rq_entry != NULL) && (rq_entry->forked_pid == pid))
+ return rq_entry;
+ }
+
+ return NULL;
+}
+
+int ss_run_queue_del(struct ss_run_queue_entry *entry)
+{
+ Eina_List *tmp;
+ Eina_List *tmp_next;
+ struct ss_run_queue_entry *rq_entry;
+ int i;
+
+ EINA_LIST_FOREACH_SAFE(run_queue, tmp, tmp_next, rq_entry) {
+ if ((rq_entry != NULL) && (rq_entry == entry)) {
+ run_queue = eina_list_remove(run_queue, rq_entry);
+ PRT_TRACE_EM("[SYSMAN] action deleted : %s",
+ rq_entry->action_entry->type);
+ for (i = 0; i < rq_entry->argc; i++) {
+ if (rq_entry->argv[i])
+ free(rq_entry->argv[i]);
+ }
+ free(rq_entry);
+ }
+ }
+
+ return 0;
+}
+
+int ss_run_queue_del_bypid(int pid)
+{
+ Eina_List *tmp;
+ Eina_List *tmp_next;
+ struct ss_run_queue_entry *rq_entry;
+ int i;
+
+ EINA_LIST_FOREACH_SAFE(run_queue, tmp, tmp_next, rq_entry) {
+ if ((rq_entry != NULL) && (rq_entry->forked_pid == pid)) {
+ run_queue = eina_list_remove(run_queue, rq_entry);
+ PRT_TRACE_EM("[SYSMAN] action deleted : %s",
+ rq_entry->action_entry->type);
+ for (i = 0; i < rq_entry->argc; i++) {
+ if (rq_entry->argv[i])
+ free(rq_entry->argv[i]);
+ }
+ free(rq_entry);
+ }
+ }
+
+ return 0;
+}
+
+void ss_queue_init()
+{
+
+}
diff --git a/ss_queue.h b/ss_queue.h
new file mode 100644
index 0000000..6b9d899
--- /dev/null
+++ b/ss_queue.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_QUEUE_H__
+#define __SS_QUEUE_H__
+
+#include "ss_sysnoti.h"
+
+struct ss_action_entry {
+ int owner_pid;
+ void *handle;
+ char *type;
+ char *path;
+ int (*predefine_action) ();
+ int (*ui_viewable) ();
+ int (*is_accessible) (int caller_sockfd);
+};
+
+enum ss_run_state {
+ SS_STATE_INIT,
+ SS_STATE_RUNNING,
+ SS_STATE_DONE
+};
+
+struct ss_run_queue_entry {
+ enum ss_run_state state;
+ struct ss_action_entry *action_entry;
+ int forked_pid;
+ int argc;
+ char *argv[SYSMAN_MAXARG];
+};
+
+int ss_action_entry_add_internal(char *type,
+ int (*predefine_action) (),
+ int (*ui_viewable) (),
+ int (*is_accessible) (int));
+int ss_action_entry_add(struct sysnoti *msg);
+int ss_action_entry_call_internal(char *type, int argc, ...);
+int ss_action_entry_call(struct sysnoti *msg, int sockfd);
+
+int ss_run_queue_run(enum ss_run_state state,
+ int (*run_func) (void *, struct ss_run_queue_entry *),
+ void *user_data);
+
+struct ss_run_queue_entry *ss_run_queue_find_bypid(int pid);
+int ss_run_queue_add(struct ss_action_entry *act_entry, int argc, char **argv);
+int ss_run_queue_del(struct ss_run_queue_entry *entry);
+int ss_run_queue_del_bypid(int pid);
+
+void ss_queue_init();
+
+#endif /* __SS_QUEUE_H__ */
diff --git a/ss_sig_handler.c b/ss_sig_handler.c
new file mode 100644
index 0000000..b81dc55
--- /dev/null
+++ b/ss_sig_handler.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "ss_core.h"
+
+#define PRT_TRACE_ERR(format, args...) do { \
+ char buf[255];\
+ snprintf(buf, 255, format, ##args);\
+ write(2, buf, strlen(buf));\
+} while (0);
+
+#define PRT_TRACE(format, args...) do { \
+ char buf[255];\
+ snprintf(buf, 255, format, ##args);\
+ write(1, buf, strlen(buf));\
+} while (0);
+
+static struct sigaction sig_child_old_act;
+static struct sigaction sig_pipe_old_act;
+
+static void sig_child_handler(int signo, siginfo_t *info, void *data)
+{
+ pid_t pid;
+ int status;
+
+ pid = waitpid(info->si_pid, &status, 0);
+ if (pid == -1) {
+ PRT_TRACE_ERR("SIGCHLD received\n");
+ return;
+ }
+
+ PRT_TRACE("sig child actend call - %d\n", info->si_pid);
+
+ ss_core_action_clear(info->si_pid);
+}
+
+static void sig_pipe_handler(int signo, siginfo_t *info, void *data)
+{
+
+}
+
+void ss_signal_init()
+{
+ struct sigaction sig_act;
+
+ sig_act.sa_handler = NULL;
+ sig_act.sa_sigaction = sig_child_handler;
+ sig_act.sa_flags = SA_SIGINFO;
+ sigemptyset(&sig_act.sa_mask);
+ sigaction(SIGCHLD, &sig_act, &sig_child_old_act);
+
+ sig_act.sa_handler = NULL;
+ sig_act.sa_sigaction = sig_pipe_handler;
+ sig_act.sa_flags = SA_SIGINFO;
+ sigemptyset(&sig_act.sa_mask);
+ sigaction(SIGPIPE, &sig_act, &sig_pipe_old_act);
+}
diff --git a/ss_sig_handler.h b/ss_sig_handler.h
new file mode 100644
index 0000000..08ab66f
--- /dev/null
+++ b/ss_sig_handler.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_SIG_HANDLER_H__
+#define __SS_SIG_HANDLER_H__
+
+void ss_signal_init(void);
+
+#endif /* __SS_SIG_HANDLER_H__ */
diff --git a/ss_sysnoti.c b/ss_sysnoti.c
new file mode 100755
index 0000000..ec93479
--- /dev/null
+++ b/ss_sysnoti.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdbool.h>
+#include <systemd/sd-daemon.h>
+#include <sysman.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include "include/ss_data.h"
+#include "ss_log.h"
+#include "ss_queue.h"
+
+#define SYSNOTI_SOCKET_PATH "/tmp/sn"
+#define RETRY_READ_COUNT 5
+
+#define POWER_MANAGER_STR "power_manager"
+#define ACTIVE_STR "active"
+#define INACTIVE_STR "inactive"
+
+enum sysnoti_cmd {
+ ADD_SYSMAN_ACTION,
+ CALL_SYSMAN_ACTION
+};
+
+static Ecore_Fd_Handler *sysnoti_efd = NULL;
+
+static int __sysnoti_start(void);
+static int __sysnoti_stop(int fd);
+
+static void print_sysnoti_msg(const char *title, struct sysnoti *msg)
+{
+ int i;
+ char exe_name[PATH_MAX];
+
+ if (sysman_get_cmdline_name(msg->pid, exe_name, PATH_MAX) < 0)
+ snprintf(exe_name, sizeof(exe_name), "Unknown (maybe dead)");
+
+ PRT_TRACE_ERR("pid : %d name: %s cmd : %d type : %s path : %s",
+ msg->pid, exe_name, msg->cmd, msg->type, msg->path);
+}
+
+static inline int recv_int(int fd)
+{
+ int val, r = -1;
+ int retry_count = 0;
+ while (retry_count < RETRY_READ_COUNT) {
+ r = read(fd, &val, sizeof(int));
+ if (r < 0) {
+ if(errno == EINTR) {
+ PRT_TRACE_ERR("Re-read for error(EINTR)");
+ retry_count++;
+ continue;
+ }
+ else {
+ PRT_TRACE_ERR("Read fail for int");
+ return -1;
+ }
+ } else {
+ return val;
+ }
+ }
+ return -1;
+}
+
+static inline char *recv_str(int fd)
+{
+ int len, r = -1;
+ int retry_count = 0;
+ char *str;
+
+ while (retry_count < RETRY_READ_COUNT) {
+ r = read(fd, &len, sizeof(int));
+ if (r < 0) {
+ if(errno == EINTR) {
+ PRT_TRACE_ERR("Re-read for error(EINTR)");
+ retry_count++;
+ continue;
+ }
+ else {
+ PRT_TRACE_ERR("Read fail for str length");
+ return NULL;
+ }
+ } else
+ break;
+ }
+ if (retry_count == RETRY_READ_COUNT) {
+ PRT_TRACE_ERR("Read retry failed");
+ return NULL;
+ }
+ if (len <= 0) {
+ PRT_TRACE_ERR("str is null");
+ return NULL;
+ }
+
+ if (len >= INT_MAX) {
+ PRT_TRACE_ERR("size is over INT_MAX");
+ return NULL;
+ }
+
+ str = (char *)malloc(len + 1);
+ if (str == NULL) {
+ PRT_TRACE_ERR("Not enough memory");
+ return NULL;
+ }
+
+ retry_count = 0;
+ while (retry_count < RETRY_READ_COUNT) {
+ r = read(fd, str, len);
+ if(r < 0) {
+ if(errno == EINTR) {
+ PRT_TRACE_ERR("Re-read for error(EINTR)");
+ retry_count++;
+ continue;
+ }
+ else {
+ PRT_TRACE_ERR("Read fail for str");
+ free(str);
+ str = NULL;
+ return NULL;
+ }
+ } else
+ break;
+ }
+ if (retry_count == RETRY_READ_COUNT) {
+ PRT_TRACE_ERR("Read retry failed");
+ free(str);
+ str = NULL;
+ return NULL;
+ }
+
+ str[len] = 0;
+
+ return str;
+}
+
+static int read_message(int fd, struct sysnoti *msg)
+{
+ int i;
+
+ if ((msg->pid = recv_int(fd)) == -1)
+ return -1;
+ if ((msg->cmd = recv_int(fd)) == -1)
+ return -1;
+ if ((msg->type = recv_str(fd)) == NULL)
+ return -1;
+ msg->path = recv_str(fd);
+ msg->argc = recv_int(fd);
+
+ if (msg->argc < 0)
+ return -1;
+ for (i = 0; i < msg->argc; i++)
+ msg->argv[i] = recv_str(fd);
+
+ return 0;
+}
+
+static inline void internal_free(char *str)
+{
+ if (str)
+ free(str);
+}
+
+static inline void free_message(struct sysnoti *msg)
+{
+ internal_free(msg->type);
+ internal_free(msg->path);
+ free(msg);
+}
+
+static bool check_sync_request(struct sysnoti *msg)
+{
+ char path[PATH_MAX];
+
+ if (sysman_get_cmdline_name(msg->pid, path, PATH_MAX) < 0)
+ return true;
+
+ PRT_TRACE_ERR("path : %s, type : %s", path, msg->type);
+ if (!strcmp(path, POWER_MANAGER_STR) &&
+ (!strcmp(msg->type, INACTIVE_STR) || !strcmp(msg->type, ACTIVE_STR)))
+ return false;
+
+ return true;
+}
+
+static int sysnoti_cb(void *data, Ecore_Fd_Handler * fd_handler)
+{
+ int fd;
+ struct sysnoti *msg;
+ int ret = -1;
+ struct sockaddr_un client_address;
+ int client_sockfd;
+ int client_len;
+ bool sync;
+
+ if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
+ PRT_TRACE_ERR
+ ("ecore_main_fd_handler_active_get error , return\n");
+ return 1;
+ }
+
+ fd = ecore_main_fd_handler_fd_get(fd_handler);
+ msg = malloc(sizeof(struct sysnoti));
+ if (msg == NULL) {
+ PRT_TRACE_ERR("%s : Not enough memory", __FUNCTION__);
+ return 1;
+ }
+
+ client_len = sizeof(client_address);
+ client_sockfd = accept(fd, (struct sockaddr *)&client_address, (socklen_t *)&client_len);
+
+ if (client_sockfd == -1) {
+ PRT_TRACE_ERR("socket accept error");
+ free(msg);
+ return -1;
+ }
+ if (read_message(client_sockfd, msg) < 0) {
+ PRT_TRACE_ERR("%s : recv error msg", __FUNCTION__);
+ print_sysnoti_msg(__FUNCTION__, msg);
+ free_message(msg);
+ write(client_sockfd, &ret, sizeof(int));
+ close(client_sockfd);
+ __sysnoti_stop(fd);
+ __sysnoti_start();
+ return -1;
+ }
+
+ sync = check_sync_request(msg);
+
+ print_sysnoti_msg(__FUNCTION__, msg);
+ if (msg->argc > SYSMAN_MAXARG) {
+ PRT_TRACE_ERR("%s : error argument", __FUNCTION__);
+ free_message(msg);
+ if (sync)
+ write(client_sockfd, &ret, sizeof(int));
+ close(client_sockfd);
+ return -1;
+ }
+
+ switch (msg->cmd) {
+ case CALL_SYSMAN_ACTION:
+ ret = ss_action_entry_call(msg, client_sockfd);
+ break;
+ default:
+ ret = -1;
+ }
+
+ if (sync)
+ write(client_sockfd, &ret, sizeof(int));
+ close(client_sockfd);
+
+ free_message(msg);
+
+ return 1;
+}
+
+static int ss_sysnoti_systemd_socket_test(const char *path)
+{
+ int type = SOCK_STREAM;
+ int listening = 1;
+ size_t length = 0;
+ int fd = -1;
+ int rc;
+ int n;
+ int i;
+
+ // Gets number of created by systemd file descriptors that represent open sockets.
+ n = sd_listen_fds(0);
+ for (i = 0; i < n; i ++) {
+
+ // File descriptor calculation
+ fd = SD_LISTEN_FDS_START + i;
+
+ // File descriptor veryfication.
+ if ((rc = sd_is_socket_unix(fd, type, listening, path, length)) > 0)
+ return fd;
+
+ // Check error
+ if (rc < 0)
+ return -1;
+ }
+
+ // No proper socket
+ return -1;
+}
+
+static int ss_sysnoti_server_init(void)
+{
+ int fd;
+ struct sockaddr_un serveraddr;
+
+ // Getting systemd socket
+ fd = ss_sysnoti_systemd_socket_test(SYSNOTI_SOCKET_PATH);
+ if (fd >= 0)
+ return fd;
+
+ if (access(SYSNOTI_SOCKET_PATH, F_OK) == 0)
+ unlink(SYSNOTI_SOCKET_PATH);
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd < 0) {
+ PRT_ERR("%s: socket create failed\n", __FUNCTION__);
+ return -1;
+ }
+ if((fsetxattr(fd, "security.SMACK64IPOUT", "@", 2, 0)) < 0 ) {
+ PRT_ERR("%s: Socket SMACK labeling failed\n", __FUNCTION__);
+ if(errno != EOPNOTSUPP) {
+ close(fd);
+ return -1;
+ }
+ }
+
+ if((fsetxattr(fd, "security.SMACK64IPIN", "*", 2, 0)) < 0 ) {
+ PRT_ERR("%s: Socket SMACK labeling failed\n", __FUNCTION__);
+ if(errno != EOPNOTSUPP) {
+ close(fd);
+ return -1;
+ }
+ }
+
+ bzero(&serveraddr, sizeof(struct sockaddr_un));
+ serveraddr.sun_family = AF_UNIX;
+ strncpy(serveraddr.sun_path, SYSNOTI_SOCKET_PATH,
+ sizeof(serveraddr.sun_path));
+
+ if (bind(fd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr)) < 0) {
+ PRT_ERR("%s: socket bind failed\n", __FUNCTION__);
+ close(fd);
+ return -1;
+ }
+
+ if (chmod(SYSNOTI_SOCKET_PATH, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) /* 0777 */
+ PRT_ERR("failed to change the socket permission");
+
+ if (listen(fd, 5) < 0) {
+ PRT_ERR("failed to listen");
+ close(fd);
+ return -1;
+ }
+ PRT_INFO("socket create & listen ok\n");
+
+ return fd;
+}
+
+int ss_sysnoti_init(void)
+{
+ return __sysnoti_start();
+}
+
+static int __sysnoti_start(void)
+{
+ int fd;
+ fd = ss_sysnoti_server_init();
+ if ( fd < 0 )
+ return -1;
+ sysnoti_efd = ecore_main_fd_handler_add(fd, ECORE_FD_READ, sysnoti_cb, NULL, NULL,
+ NULL);
+ if (!sysnoti_efd) {
+ PRT_TRACE_ERR("error ecore_main_fd_handler_add");
+ return -1;
+ }
+ return fd;
+}
+
+static int __sysnoti_stop(int fd)
+{
+ if (sysnoti_efd) {
+ ecore_main_fd_handler_del(sysnoti_efd);
+ sysnoti_efd = NULL;
+ }
+ if (fd >=0) {
+ close(fd);
+ fd = -1;
+ }
+ return 0;
+}
diff --git a/ss_sysnoti.h b/ss_sysnoti.h
new file mode 100644
index 0000000..e76d156
--- /dev/null
+++ b/ss_sysnoti.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_SYSNOTI_H__
+#define __SS_SYSNOTI_H__
+
+#define SYSMAN_MAXARG 16
+
+struct sysnoti {
+ int pid;
+ int cmd;
+ char *type;
+ char *path;
+ int argc;
+ char *argv[SYSMAN_MAXARG];
+};
+
+int ss_sysnoti_init(void);
+
+#endif /* __SS_SYSNOTI_H__ */
diff --git a/ss_ta_handler.c b/ss_ta_handler.c
new file mode 100644
index 0000000..ac1e38a
--- /dev/null
+++ b/ss_ta_handler.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <pmapi.h>
+#include <vconf.h>
+#include <sysman.h>
+
+#include "device-node.h"
+#include "ss_log.h"
+#include "include/ss_data.h"
+
+#define RETRY 3
+
+int ss_ta_init()
+{
+ int val = -1, i = 0, pid;
+
+ PRT_TRACE("check ta connection");
+ if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_TA_ONLINE, &val) == 0) {
+ if ( val==1 ) {
+ vconf_set_int(VCONFKEY_SYSMAN_CHARGER_STATUS,
+ VCONFKEY_SYSMAN_CHARGER_CONNECTED);
+ while (i < RETRY
+ && pm_lock_state(LCD_OFF, STAY_CUR_STATE,
+ 0) == -1) {
+ i++;
+ sleep(1);
+ }
+ PRT_TRACE("ta is connected");
+ }
+ else if ( val==0 )
+ vconf_set_int(VCONFKEY_SYSMAN_CHARGER_STATUS,
+ VCONFKEY_SYSMAN_CHARGER_DISCONNECTED);
+ }
+ return 0;
+}
diff --git a/ss_timemgr.c b/ss_timemgr.c
new file mode 100644
index 0000000..cecbbb1
--- /dev/null
+++ b/ss_timemgr.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <pmapi.h>
+#include <vconf.h>
+
+#include <sysman.h>
+#include "include/ss_data.h"
+#include "ss_queue.h"
+#include "ss_log.h"
+
+#include <time.h>
+#include <sys/ioctl.h>
+#include <linux/rtc.h>
+#include <fcntl.h>
+#include <sys/timerfd.h>
+
+#ifndef TFD_TIMER_CANCELON_SET
+#define TFD_TIMER_CANCELON_SET (1<<1)
+#endif
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0x2000000
+#endif
+
+#ifndef O_NONBLOCK
+#define O_NONBLOCK 0x4000
+#endif
+
+#ifndef TFD_CLOEXEC
+#define TFD_CLOEXEC O_CLOEXEC
+#endif
+
+#ifndef TFD_NONBLOCK
+#define TFD_NONBLOCK O_NONBLOCK
+#endif
+static const char default_rtc0[] = "/dev/rtc0";
+static const char default_rtc1[] = "/dev/rtc1";
+static const char default_localtime[] = "/opt/etc/localtime";
+
+static const time_t default_time = 2147483645; // max(32bit) -3sec
+static Ecore_Fd_Handler *tfdh = NULL; // tfd change noti
+
+static int tfd_cb(void *data, Ecore_Fd_Handler * fd_handler);
+static int timerfd_check_stop(int fd);
+static int timerfd_check_start(void);
+
+char *substring(const char *str, size_t begin, size_t len)
+{
+ if (str == 0 || strlen(str) == 0 || strlen(str) < begin
+ || strlen(str) < (begin + len))
+ return 0;
+
+ return strndup(str + begin, len);
+}
+
+int handle_timezone(char *str)
+{
+ int ret;
+ struct stat sts;
+ const char *sympath = default_localtime;
+
+ if (str == NULL)
+ return -1;
+ const char *tzpath = str;
+
+ PRT_TRACE("TZPATH = %s\n", tzpath);
+
+ /* unlink current link
+ * eg. rm /opt/etc/localtime */
+ if (stat(sympath, &sts) == -1 && errno == ENOENT) {
+ /* DO NOTHING */
+ } else {
+ ret = unlink(sympath);
+ if (ret < 0) {
+ PRT_TRACE("unlink error : [%d]%s\n", ret,
+ strerror(errno));
+ return -1;
+ } else
+ PRT_TRACE("unlink success\n");
+
+ }
+
+ /* symlink new link
+ * eg. ln -s /usr/share/zoneinfo/Asia/Seoul /opt/etc/localtime */
+ ret = symlink(tzpath, sympath);
+ if (ret < 0) {
+ PRT_TRACE("symlink error : [%d]%s\n", ret, strerror(errno));
+ return -1;
+ } else
+ PRT_TRACE("symlink success\n");
+
+ tzset();
+ return 0;
+}
+
+/*
+ * TODO : error handling code should be added here.
+ */
+int handle_date(char *str)
+{
+ long int tmp = 0;
+ time_t timet = 0;
+ time_t before = 0;
+
+ if (str == NULL)
+ return -1;
+
+ tmp = (long int)atoi(str);
+ timet = (time_t) tmp;
+
+ PRT_TRACE("ctime = %s", ctime(&timet));
+ vconf_set_int(VCONFKEY_SYSTEM_TIMECHANGE, timet);
+
+ return 0;
+}
+
+int set_datetime_action(int argc, char **argv)
+{
+ int ret = 0;
+ unsigned int pm_state;
+ if (argc < 1)
+ return -1;
+ if (vconf_get_int(VCONFKEY_PM_STATE, &ret) != 0)
+ PRT_TRACE("Fail to get vconf value for pm state\n");
+ if (ret == 1)
+ pm_state = 0x1;
+ else if (ret == 2)
+ pm_state = 0x2;
+ else
+ pm_state = 0x4;
+
+ pm_lock_state(pm_state, STAY_CUR_STATE, 0);
+ ret = handle_date(argv[0]);
+ pm_unlock_state(pm_state, STAY_CUR_STATE);
+ return ret;
+}
+
+int set_timezone_action(int argc, char **argv)
+{
+ int ret;
+ unsigned int pm_state;
+ if (argc < 1)
+ return -1;
+ if (vconf_get_int(VCONFKEY_PM_STATE, &ret) != 0)
+ PRT_TRACE("Fail to get vconf value for pm state\n");
+ if (ret == 1)
+ pm_state = 0x1;
+ else if (ret == 2)
+ pm_state = 0x2;
+ else
+ pm_state = 0x4;
+
+ pm_lock_state(pm_state, STAY_CUR_STATE, 0);
+ ret = handle_timezone(argv[0]);
+ pm_unlock_state(pm_state, STAY_CUR_STATE);
+ return ret;
+}
+
+static int timerfd_check_start(void)
+{
+ int tfd;
+ struct itimerspec tmr;
+
+ if ((tfd = timerfd_create(CLOCK_REALTIME,TFD_NONBLOCK|TFD_CLOEXEC)) == -1) {
+ PRT_TRACE_ERR("error timerfd_create() %d",errno);
+ tfdh = NULL;
+ return -1;
+ }
+
+ tfdh = ecore_main_fd_handler_add(tfd,ECORE_FD_READ,tfd_cb,NULL,NULL,NULL);
+ if (!tfdh) {
+ PRT_TRACE_ERR("error ecore_main_fd_handler_add");
+ return -1;
+ }
+ memset(&tmr, 0, sizeof(tmr));
+ tmr.it_value.tv_sec = default_time;
+
+ if (timerfd_settime(tfd,TFD_TIMER_ABSTIME|TFD_TIMER_CANCELON_SET,&tmr,NULL) < 0) {
+ PRT_TRACE_ERR("error timerfd_settime() %d",errno);
+ return -1;
+ }
+ return 0;
+}
+
+static int timerfd_check_stop(int tfd)
+{
+ if (tfdh) {
+ ecore_main_fd_handler_del(tfdh);
+ tfdh = NULL;
+ }
+ if (tfd >=0) {
+ close(tfd);
+ tfd = -1;
+ }
+ return 0;
+}
+
+static int tfd_cb(void *data, Ecore_Fd_Handler * fd_handler)
+{
+ int tfd = -1;
+ u_int64_t ticks;
+ int ret = -1;
+
+ if (!ecore_main_fd_handler_active_get(fd_handler,ECORE_FD_READ)) {
+ PRT_TRACE_ERR("error ecore_main_fd_handler_get()");
+ return -1;
+ }
+
+ if((tfd = ecore_main_fd_handler_fd_get(fd_handler)) == -1) {
+ PRT_TRACE_ERR("error ecore_main_fd_handler_fd_get()");
+ return -1;
+ }
+
+ ret = read(tfd,&ticks,sizeof(ticks));
+
+ if (ret < 0 && errno == ECANCELED) {
+ vconf_set_int(VCONFKEY_SYSMAN_STIME, VCONFKEY_SYSMAN_STIME_CHANGED);
+ timerfd_check_stop(tfd);
+ PRT_TRACE("NOTIFICATION here");
+ timerfd_check_start();
+ } else {
+ PRT_TRACE("unexpected read (err:%d)",errno);
+ }
+ return 0;
+}
+
+int ss_time_manager_init(void)
+{
+ ss_action_entry_add_internal(PREDEF_SET_DATETIME, set_datetime_action,
+ NULL, NULL);
+ ss_action_entry_add_internal(PREDEF_SET_TIMEZONE, set_timezone_action,
+ NULL, NULL);
+ if (timerfd_check_start() == -1) {
+ PRT_TRACE_ERR("fail system time change detector init");
+ return -1;
+ }
+ return 0;
+}
diff --git a/ss_timemgr.h b/ss_timemgr.h
new file mode 100644
index 0000000..223f31e
--- /dev/null
+++ b/ss_timemgr.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_TIMEMGR_H__
+#define __SS_TIMEMGR_H__
+
+int ss_time_manager_init(void);
+
+#endif /* __SS_TIMEMGR_H__ */
diff --git a/ss_usb_handler.c b/ss_usb_handler.c
new file mode 100644
index 0000000..815aca7
--- /dev/null
+++ b/ss_usb_handler.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <pmapi.h>
+#include <vconf.h>
+#include <sysman.h>
+
+#include "ss_log.h"
+#include "device-node.h"
+#include "ss_launch.h"
+#include "include/ss_data.h"
+
+#define USBCON_EXEC_PATH PREFIX"/bin/usb-server"
+#define RETRY 3
+
+int ss_usb_init()
+{
+ int val = -1, i = 0, pid;
+
+ PRT_TRACE("check usb connection");
+ if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &val) == 0) {
+ if (val==1) {
+ vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,
+ VCONFKEY_SYSMAN_USB_AVAILABLE);
+ while (i < RETRY
+ && pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0) == -1) {
+ i++;
+ sleep(1);
+ }
+ pid = ss_launch_if_noexist(USBCON_EXEC_PATH, NULL);
+ if (pid < 0) {
+ PRT_TRACE_ERR("usb appl launching failed\n");
+ return -1;
+ }
+ }
+ else if (val==0)
+ vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,VCONFKEY_SYSMAN_USB_DISCONNECTED);
+ }
+
+ return 0;
+}
diff --git a/ss_vibrator.c b/ss_vibrator.c
new file mode 100644
index 0000000..9d5c7c8
--- /dev/null
+++ b/ss_vibrator.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <glib.h>
+#include <device-node.h>
+
+#include "ss_log.h"
+#include "ss_predefine.h"
+#include "include/ss_data.h"
+
+#ifndef MERGE_BTW_APPLICATIONS
+#define MERGE_BTW_APPLICATIONS
+#endif
+
+enum {
+ OPEN = 0,
+ CLOSE,
+ PLAY,
+ ONESHOT,
+ STOP,
+ LEVEL,
+};
+
+struct haptic_node {
+ int handle;
+ int level;
+ int play;
+};
+
+static GList *haptic_head;
+
+static int add_node(struct haptic_node *node)
+{
+ haptic_head = g_list_append(haptic_head, node);
+ return 0;
+}
+
+static int delete_node(struct haptic_node *node)
+{
+ haptic_head = g_list_remove(haptic_head, node);
+ return 0;
+}
+
+static struct haptic_node *find_node(int handle)
+{
+ GList *elem;
+ struct haptic_node *node;
+
+ for (elem = haptic_head; elem; elem = elem->next) {
+ node = elem->data;
+ if (node->handle == handle) {
+ return node;
+ }
+ }
+
+ return NULL;
+}
+#ifndef MERGE_BTW_APPLICATIONS
+static void stop_all_device(gpointer data, gpointer user_data)
+{
+ struct haptic_node *node = (struct haptic_node*)data;
+
+ node->level = 0;
+ node->play = 0;
+ PRT_TRACE_ERR("node handle : %d, level : %d, play : %d", node->handle, node->level, node->play);
+}
+#endif
+static int haptic_play(int handle)
+{
+ struct haptic_node *node;
+ int r;
+
+ PRT_TRACE("handle : %d", handle);
+ node = find_node(handle);
+ if (node == NULL) {
+ PRT_TRACE_ERR("find_node(%d) fail", handle);
+ return -1;
+ }
+#ifndef MERGE_BTW_APPLICATIONS
+ g_list_foreach(haptic_head, stop_all_device, NULL);
+#endif
+ r = device_set_property(DEVICE_TYPE_VIBRATOR, PROP_VIBRATOR_ENABLE, 1);
+ if (r < 0) {
+ PRT_TRACE_ERR("set enable fail");
+ return -1;
+ }
+
+ node->level = 0;
+ node->play = 1;
+ return 0;
+}
+
+static int haptic_oneshot(int handle, int duration, int level)
+{
+ struct haptic_node *node;
+ int r;
+
+ PRT_TRACE("handle : %d", handle);
+ node = find_node(handle);
+ if (node == NULL) {
+ PRT_TRACE_ERR("find_node(%d) fail", handle);
+ return 0;
+ }
+
+ r = device_set_property(DEVICE_TYPE_VIBRATOR, PROP_VIBRATOR_LEVEL, level);
+ if (r < 0) {
+ PRT_TRACE_ERR("set level fail");
+ return -1;
+ }
+
+ r = device_set_property(DEVICE_TYPE_VIBRATOR, PROP_VIBRATOR_ONESHOT, duration);
+ if (r < 0) {
+ PRT_TRACE_ERR("set oneshot fail");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void check_play_state(gpointer data, gpointer user_data)
+{
+ struct haptic_node *node = (struct haptic_node*)data;
+ int *play = (int*)user_data;
+
+ *play += node->play;
+ PRT_TRACE_ERR("node handle : %d, level : %d, play : %d", node->handle, node->level, node->play);
+}
+
+static int haptic_stop(int handle)
+{
+ struct haptic_node *node;
+ int play = 0;
+ int r;
+
+ PRT_TRACE("handle : %d", handle);
+ node = find_node(handle);
+ if (node == NULL) {
+ PRT_TRACE_ERR("find_node(%d) fail", handle);
+ return -1;
+ }
+
+ node->level = 0;
+ node->play = 0;
+
+ g_list_foreach(haptic_head, check_play_state, &play);
+ PRT_TRACE_ERR("play state : %d", play);
+
+ if (!play) {
+ PRT_TRACE_ERR("not playing anymore, will be stop");
+ r = device_set_property(DEVICE_TYPE_VIBRATOR, PROP_VIBRATOR_ENABLE, 0);
+ if (r < 0) {
+ PRT_TRACE_ERR("set enable fail");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+#ifdef MERGE_BTW_APPLICATIONS
+static void get_current_level(gpointer data, gpointer user_data)
+{
+ struct haptic_node *node = (struct haptic_node*)data;
+ int *sum = (int*)user_data;
+
+ PRT_TRACE_ERR("node handle : %d, level : %d, play : %d", node->handle, node->level, node->play);
+ if (node->play == 1) {
+ PRT_TRACE_ERR("node->play : %d, sum : %d", node->play, *sum);
+ *sum += node->level;
+ }
+}
+#endif
+static int haptic_change_level(int handle, int level)
+{
+ struct haptic_node *node;
+ int sum = 0;
+ int r;
+
+ PRT_TRACE_ERR("handle : %d, level : %d", handle, level);
+ node = find_node(handle);
+ if (node == NULL) {
+ PRT_TRACE_ERR("find_node(%d) fail", handle);
+ return -1;
+ }
+
+ node->level = level;
+#ifdef MERGE_BTW_APPLICATIONS
+ g_list_foreach(haptic_head, get_current_level, &sum);
+ PRT_TRACE_ERR("current sum level : %d", sum);
+#else
+ sum = level;
+ if (!node->play) {
+ PRT_TRACE_ERR("This handle is stoped by another handle");
+ return 0;
+ }
+#endif
+
+ r = device_set_property(DEVICE_TYPE_VIBRATOR, PROP_VIBRATOR_LEVEL, sum);
+ if (r < 0) {
+ PRT_TRACE_ERR("set level fail");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int haptic_open(int handle)
+{
+ struct haptic_node *node;
+
+ PRT_TRACE("handle : %d", handle);
+ node = malloc(sizeof(struct haptic_node));
+ if (node == NULL) {
+ PRT_TRACE_ERR("malloc fail");
+ return -1;
+ }
+
+ node->handle = handle;
+ node->level = 0;
+ node->play = 0;
+
+ add_node(node);
+ return 0;
+}
+
+static int haptic_close(int handle)
+{
+ struct haptic_node *node;
+ int play = 0;
+ int r;
+
+ PRT_TRACE("handle : %d", handle);
+ node = find_node(handle);
+ if (node == NULL) {
+ PRT_TRACE_ERR("find_node(%d) fail", handle);
+ return -1;
+ }
+
+ node->level = 0;
+ node->play = 0;
+
+ delete_node(node);
+ free(node);
+
+ g_list_foreach(haptic_head, check_play_state, &play);
+ PRT_TRACE_ERR("play state : %d", play);
+
+ if (!play) {
+ PRT_TRACE_ERR("not playing anymore, will be stop");
+ r = device_set_property(DEVICE_TYPE_VIBRATOR, PROP_VIBRATOR_ENABLE, 0);
+ if (r < 0) {
+ PRT_TRACE_ERR("set enable fail");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int haptic_def_predefine_action(int argc, char **argv)
+{
+ int i;
+ int pid;
+ int mode;
+ int handle;
+
+ PRT_TRACE_ERR("argc : %d", argc);
+ for (i = 0; i < argc; ++i)
+ PRT_TRACE_ERR("[%2d] %s", i, argv[i]);
+
+ if (argc <= 0 || argc > 5) {
+ PRT_TRACE_ERR("Haptic predefine action failed");
+ return -1;
+ }
+
+ pid = atoi(argv[0]);
+ mode = atoi(argv[1]);
+ handle = atoi(argv[2]);
+ PRT_TRACE_ERR("pid : %d, mode : %d", pid, mode);
+
+ switch(mode) {
+ case OPEN:
+ return haptic_open(handle);
+ case CLOSE:
+ return haptic_close(handle);
+ case PLAY:
+ return haptic_play(handle);
+ case ONESHOT:
+ return haptic_oneshot(handle, atoi(argv[3]), atoi(argv[4]));
+ case STOP:
+ return haptic_stop(handle);
+ case LEVEL:
+ return haptic_change_level(handle, atoi(argv[3]));
+ default:
+ break;
+ }
+
+ return -1;
+} \ No newline at end of file
diff --git a/ss_vibrator.h b/ss_vibrator.h
new file mode 100644
index 0000000..43c98c5
--- /dev/null
+++ b/ss_vibrator.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __SS_VIBRATOR_H__
+#define __SS_VIBRATOR_H__
+
+int haptic_def_predefine_action(int argc, char **argv);
+
+#endif /* __SS_VIBRATOR_H__ */
diff --git a/sys_event/CMakeLists.txt b/sys_event/CMakeLists.txt
new file mode 100644
index 0000000..f41228f
--- /dev/null
+++ b/sys_event/CMakeLists.txt
@@ -0,0 +1,31 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(sys_event C)
+
+SET(SRCS sys_event.c)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED heynoti)
+
+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}")
+MESSAGE("FLAGS: ${CMAKE_C_FLAGS}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+IF( $ENV{ARCH} MATCHES "arm" )
+ ADD_DEFINITIONS("-DTARGET")
+ENDIF()
+ADD_DEFINITIONS("-DSLP_DEBUG")
+ADD_DEFINITIONS("-DSLP_PROF")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+
diff --git a/sys_event/sys_event.c b/sys_event/sys_event.c
new file mode 100644
index 0000000..ca1a294
--- /dev/null
+++ b/sys_event/sys_event.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <heynoti.h>
+
+int main(int argc, char **argv)
+{
+ if (argc != 2) {
+ printf("[usage] sys_event <noti file>\n");
+ return -1;
+ }
+
+ heynoti_publish(argv[1]);
+ return 0;
+}
diff --git a/sys_pci_noti/CMakeLists.txt b/sys_pci_noti/CMakeLists.txt
new file mode 100755
index 0000000..964f5a4
--- /dev/null
+++ b/sys_pci_noti/CMakeLists.txt
@@ -0,0 +1,30 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(sys_pci_noti C)
+
+SET(SRCS sys_pci_noti.c)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+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}")
+MESSAGE("FLAGS: ${CMAKE_C_FLAGS}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+IF( $ENV{ARCH} MATCHES "arm" )
+ ADD_DEFINITIONS("-DTARGET")
+ENDIF()
+ADD_DEFINITIONS("-DSLP_DEBUG")
+ADD_DEFINITIONS("-DSLP_PROF")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+
+#i18n
+ADD_SUBDIRECTORY(po_sys_pci_noti)
diff --git a/sys_pci_noti/po_sys_pci_noti/CMakeLists.txt b/sys_pci_noti/po_sys_pci_noti/CMakeLists.txt
new file mode 100644
index 0000000..e4878ec
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/CMakeLists.txt
@@ -0,0 +1,24 @@
+# for i18n
+
+SET(POFILES ar.po el_GR.po es_ES.po fi.po gl.po hy.po ka.po lv.po pl.po ru_RU.po sv.po zh_CN.po az.po cs.po en_PH.po es_MX.po fr_CA.po hi.po is.po kk.po mk.po pt_BR.po sk.po tr_TR.po zh_HK.po bg.po da.po en.po et.po fr_FR.po hr.po it_IT.po ko_KR.po nb.po pt_PT.po sl.po uk.po zh_SG.po ca.po de_DE.po en_US.po eu.po ga.po hu.po ja_JP.po lt.po nl_NL.po ro.po sr.po uz.po zh_TW.po)
+
+SET(MSGFMT "/usr/bin/msgfmt")
+
+FOREACH(pofile ${POFILES})
+ SET(pofile ${CMAKE_CURRENT_SOURCE_DIR}/${pofile})
+ MESSAGE("PO: ${pofile}")
+ GET_FILENAME_COMPONENT(absPofile ${pofile} ABSOLUTE)
+ GET_FILENAME_COMPONENT(lang ${absPofile} NAME_WE)
+ SET(moFile ${CMAKE_CURRENT_BINARY_DIR}/${lang}.mo)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${moFile}
+ COMMAND ${MSGFMT} -o ${moFile} ${absPofile}
+ DEPENDS ${absPofile}
+ )
+ INSTALL(FILES ${moFile}
+ DESTINATION share/system-server/sys_pci_noti/res/locale/${lang}/LC_MESSAGES RENAME ${PROJECT_NAME}.mo)
+ SET(moFiles ${moFiles} ${moFile})
+ENDFOREACH(pofile)
+
+MESSAGE(".mo files: ${moFiles}")
+ADD_CUSTOM_TARGET(po_sys_pci_noti ALL DEPENDS ${moFiles})
diff --git a/sys_pci_noti/po_sys_pci_noti/ar.po b/sys_pci_noti/po_sys_pci_noti/ar.po
new file mode 100755
index 0000000..8e8ecef
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/ar.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "تم توصيل لوحة المفاتيح"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "تم فصل لوحة المفاتيح"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/az.po b/sys_pci_noti/po_sys_pci_noti/az.po
new file mode 100755
index 0000000..09395e4
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/az.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Klaviatura qoşuldu"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Klaviatura ilə əlaqə kəsildi"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/bg.po b/sys_pci_noti/po_sys_pci_noti/bg.po
new file mode 100755
index 0000000..0490340
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/bg.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Клавиатурата е свързана"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Връзката с клав. е прекъсната"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/ca.po b/sys_pci_noti/po_sys_pci_noti/ca.po
new file mode 100755
index 0000000..b67689d
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/ca.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Teclat connectat"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Teclat desconnectat"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/cs.po b/sys_pci_noti/po_sys_pci_noti/cs.po
new file mode 100755
index 0000000..4f34a72
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/cs.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Klávesnice byla připojena"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Klávesnice byla odpojena"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/da.po b/sys_pci_noti/po_sys_pci_noti/da.po
new file mode 100755
index 0000000..4e27dc2
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/da.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Tastatur tilsluttet"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Tastatur frakoblet"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/de_DE.po b/sys_pci_noti/po_sys_pci_noti/de_DE.po
new file mode 100755
index 0000000..6f0b207
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/de_DE.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Tastatur verbunden"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Tastatur getrennt"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/el_GR.po b/sys_pci_noti/po_sys_pci_noti/el_GR.po
new file mode 100755
index 0000000..c0835cc
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/el_GR.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Συνδέθηκε πληκτρολόγιο"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Το πληκτρολόγιο αποσυνδέθηκε"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/en.po b/sys_pci_noti/po_sys_pci_noti/en.po
new file mode 100755
index 0000000..724f9d7
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/en.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Keyboard connected"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Keyboard disconnected"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/en_PH.po b/sys_pci_noti/po_sys_pci_noti/en_PH.po
new file mode 100755
index 0000000..724f9d7
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/en_PH.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Keyboard connected"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Keyboard disconnected"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/en_US.po b/sys_pci_noti/po_sys_pci_noti/en_US.po
new file mode 100755
index 0000000..724f9d7
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/en_US.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Keyboard connected"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Keyboard disconnected"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/es_ES.po b/sys_pci_noti/po_sys_pci_noti/es_ES.po
new file mode 100755
index 0000000..cc8dfc7
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/es_ES.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Teclado conectado"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Teclado desconectado"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/es_MX.po b/sys_pci_noti/po_sys_pci_noti/es_MX.po
new file mode 100755
index 0000000..cc8dfc7
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/es_MX.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Teclado conectado"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Teclado desconectado"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/es_US.po b/sys_pci_noti/po_sys_pci_noti/es_US.po
new file mode 100755
index 0000000..cc8dfc7
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/es_US.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Teclado conectado"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Teclado desconectado"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/et.po b/sys_pci_noti/po_sys_pci_noti/et.po
new file mode 100755
index 0000000..cb33961
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/et.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Klaviatuur on ühendatud"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Klaviatuuri ühendus on katk."
+
diff --git a/sys_pci_noti/po_sys_pci_noti/eu.po b/sys_pci_noti/po_sys_pci_noti/eu.po
new file mode 100755
index 0000000..521651c
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/eu.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Teklatua konektatuta"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Teklatua deskonektatuta"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/fi.po b/sys_pci_noti/po_sys_pci_noti/fi.po
new file mode 100755
index 0000000..aa24538
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/fi.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Näppäimistö kytketty"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Näppäimistö irrotettu"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/fr_CA.po b/sys_pci_noti/po_sys_pci_noti/fr_CA.po
new file mode 100755
index 0000000..fe05fff
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/fr_CA.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Clavier connecté"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Clavier déconnecté"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/fr_FR.po b/sys_pci_noti/po_sys_pci_noti/fr_FR.po
new file mode 100755
index 0000000..fe05fff
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/fr_FR.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Clavier connecté"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Clavier déconnecté"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/ga.po b/sys_pci_noti/po_sys_pci_noti/ga.po
new file mode 100755
index 0000000..13e7950
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/ga.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Eochairchlár ceangailte"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Eochairchlár dícheangailte"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/gl.po b/sys_pci_noti/po_sys_pci_noti/gl.po
new file mode 100755
index 0000000..cc8dfc7
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/gl.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Teclado conectado"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Teclado desconectado"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/hi.po b/sys_pci_noti/po_sys_pci_noti/hi.po
new file mode 100755
index 0000000..c86fd0a
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/hi.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "कीबोर्ड कनेक्ट किया गया"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "कीबोर्ड डिसकनेक्ट किया गया"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/hr.po b/sys_pci_noti/po_sys_pci_noti/hr.po
new file mode 100755
index 0000000..71fccb9
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/hr.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Tipkovnica spojena"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Tipkovnica odspojena"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/hu.po b/sys_pci_noti/po_sys_pci_noti/hu.po
new file mode 100755
index 0000000..06a9d89
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/hu.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Billentyűzet csatlakoztatva"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Billentyűzet leválasztva"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/hy.po b/sys_pci_noti/po_sys_pci_noti/hy.po
new file mode 100755
index 0000000..4fd13d1
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/hy.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Ստեղնաշարը միացված է"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Ստեղնաշարն անջատված է"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/is.po b/sys_pci_noti/po_sys_pci_noti/is.po
new file mode 100755
index 0000000..391eaed
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/is.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Lyklaborð tengt"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Lyklaborð aftengt"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/it_IT.po b/sys_pci_noti/po_sys_pci_noti/it_IT.po
new file mode 100755
index 0000000..0e5c942
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/it_IT.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Tastiera connessa"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Tastiera disconnessa"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/ja_JP.po b/sys_pci_noti/po_sys_pci_noti/ja_JP.po
new file mode 100755
index 0000000..63b3ccf
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/ja_JP.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "キーボードが接続されました。"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "キーボードが取り外されました。"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/ka.po b/sys_pci_noti/po_sys_pci_noti/ka.po
new file mode 100755
index 0000000..72b72b7
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/ka.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "კლავიატურა დაკავშირებულია"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "კლავიატურა გათიშულია"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/kk.po b/sys_pci_noti/po_sys_pci_noti/kk.po
new file mode 100755
index 0000000..f3873db
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/kk.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Пернетақта қосылды"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Пернетақта ажыратылды"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/ko_KR.po b/sys_pci_noti/po_sys_pci_noti/ko_KR.po
new file mode 100755
index 0000000..8f73524
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/ko_KR.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "키보드가 연결되었습니다"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "키보드와 연결이 끊어졌습니다"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/lt.po b/sys_pci_noti/po_sys_pci_noti/lt.po
new file mode 100755
index 0000000..65ec0bb
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/lt.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Prijungta klaviatūra"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Klaviatūra atjungta"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/lv.po b/sys_pci_noti/po_sys_pci_noti/lv.po
new file mode 100755
index 0000000..d59b6aa
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/lv.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Tastatūra pievienota"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Tastatūra atvienota"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/mk.po b/sys_pci_noti/po_sys_pci_noti/mk.po
new file mode 100755
index 0000000..e95b1b1
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/mk.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Поврзана е тастатура"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Тастатурата не е поврзана"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/nb.po b/sys_pci_noti/po_sys_pci_noti/nb.po
new file mode 100755
index 0000000..5e04c0d
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/nb.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Tastatur tilkoblet"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Tastatur frakoblet"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/nl_NL.po b/sys_pci_noti/po_sys_pci_noti/nl_NL.po
new file mode 100755
index 0000000..d4f3d8f
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/nl_NL.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Toetsenbord aangesloten"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Toetsenbord losgekoppeld"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/pl.po b/sys_pci_noti/po_sys_pci_noti/pl.po
new file mode 100755
index 0000000..ef614e6
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/pl.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Klawiatura podłączona"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Klawiatura odłączona"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/pt_BR.po b/sys_pci_noti/po_sys_pci_noti/pt_BR.po
new file mode 100755
index 0000000..cc8dfc7
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/pt_BR.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Teclado conectado"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Teclado desconectado"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/pt_PT.po b/sys_pci_noti/po_sys_pci_noti/pt_PT.po
new file mode 100755
index 0000000..219f2eb
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/pt_PT.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Teclado ligado"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Teclado desligado"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/ro.po b/sys_pci_noti/po_sys_pci_noti/ro.po
new file mode 100755
index 0000000..758401c
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/ro.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Tastatură conectată"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Tastatură deconectată"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/ru_RU.po b/sys_pci_noti/po_sys_pci_noti/ru_RU.po
new file mode 100755
index 0000000..475bacc
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/ru_RU.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Клавиатура подключена"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Клавиатура отключена"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/sk.po b/sys_pci_noti/po_sys_pci_noti/sk.po
new file mode 100755
index 0000000..160dba2
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/sk.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Klávesnica je pripojená"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Klávesnica je odpojená"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/sl.po b/sys_pci_noti/po_sys_pci_noti/sl.po
new file mode 100755
index 0000000..ef46adf
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/sl.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Tipkovnica je povezana"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Tipkovnica je odstranjena"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/sr.po b/sys_pci_noti/po_sys_pci_noti/sr.po
new file mode 100755
index 0000000..12d0ca3
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/sr.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Tastatura je priključena"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Tastatura je otkačena"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/sv.po b/sys_pci_noti/po_sys_pci_noti/sv.po
new file mode 100755
index 0000000..58213f2
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/sv.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Tangentbord anslutet"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Tangentbord frånkopplat"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/tr_TR.po b/sys_pci_noti/po_sys_pci_noti/tr_TR.po
new file mode 100755
index 0000000..a173ebf
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/tr_TR.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Klavye bağlandı"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Klavye bağlı değil"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/uk.po b/sys_pci_noti/po_sys_pci_noti/uk.po
new file mode 100755
index 0000000..c746cdf
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/uk.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Клавіатуру підключено"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Клавіатуру відключено"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/uz.po b/sys_pci_noti/po_sys_pci_noti/uz.po
new file mode 100755
index 0000000..f9babff
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/uz.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "Klaviatura ulandi"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "Klaviatura chiqarib olindi"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/zh_CN.po b/sys_pci_noti/po_sys_pci_noti/zh_CN.po
new file mode 100755
index 0000000..a60aae3
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/zh_CN.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "键盘已连接"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "键盘已断开"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/zh_HK.po b/sys_pci_noti/po_sys_pci_noti/zh_HK.po
new file mode 100755
index 0000000..52b489c
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/zh_HK.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "鍵盤已連接"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "鍵盤已中斷連接"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/zh_SG.po b/sys_pci_noti/po_sys_pci_noti/zh_SG.po
new file mode 100755
index 0000000..a60aae3
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/zh_SG.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "键盘已连接"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "键盘已断开"
+
diff --git a/sys_pci_noti/po_sys_pci_noti/zh_TW.po b/sys_pci_noti/po_sys_pci_noti/zh_TW.po
new file mode 100755
index 0000000..52b489c
--- /dev/null
+++ b/sys_pci_noti/po_sys_pci_noti/zh_TW.po
@@ -0,0 +1,6 @@
+msgid "IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"
+msgstr "鍵盤已連接"
+
+msgid "IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"
+msgstr "鍵盤已中斷連接"
+
diff --git a/sys_pci_noti/sys_pci_noti.c b/sys_pci_noti/sys_pci_noti.c
new file mode 100755
index 0000000..919b82d
--- /dev/null
+++ b/sys_pci_noti/sys_pci_noti.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <libintl.h>
+#include <locale.h>
+#include <vconf.h>
+#include <syspopup_caller.h>
+#include <notification.h>
+#include "ss_log.h"
+#include "sys_pci_noti.h"
+
+static void show_tickernoti(char *msg)
+{
+ if (!msg)
+ return;
+
+ notification_error_e noti_err = NOTIFICATION_ERROR_NONE;
+ noti_err = notification_status_message_post(gettext(msg));
+ if (noti_err != NOTIFICATION_ERROR_NONE)
+ PRT_TRACE_ERR("FAIL: notification_status_message_post(msg)");
+}
+
+static void pci_noti(pci_noti_type iPCI)
+{
+ char *lang;
+ char *r;
+ int ret = -1;
+ const int arrSize = 2;
+ char str_tickernoti[arrSize];
+
+ lang = vconf_get_str(VCONFKEY_LANGSET);
+ if (lang) {
+ setenv("LANG", lang, 1);
+ setenv("LC_MESSAGES", lang, 1);
+ r = setlocale(LC_ALL, "");
+ if (r == NULL) {
+ setlocale(LC_ALL, lang);
+ }
+ free(lang);
+ }
+ bindtextdomain("sys_pci_noti","/usr/share/system-server/sys_pci_noti/res/locale/");
+ textdomain("sys_pci_noti");
+
+ if (iPCI == CB_NOTI_PCI_REMOVED)
+ show_tickernoti(_("IDS_COM_POP_KEYBOARD_DISCONNECTED_ABB2"));
+
+ else if (iPCI == CB_NOTI_PCI_INSERTED)
+ show_tickernoti(_("IDS_COM_POP_KEYBOARD_CONNECTED_ABB2"));
+
+}
+
+int main(int argc, char *argv[])
+{
+ int r = 0;
+ int handle = 0;
+ int bNoti = -1;
+ pci_noti_type cb_type = -1;
+
+ if (argc == 2) {
+ cb_type = (pci_noti_type)atoi(argv[1]);
+ pci_noti(cb_type);
+ }
+ else {
+ PRT_TRACE_ERR("FAIL param error");
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/sys_pci_noti/sys_pci_noti.h b/sys_pci_noti/sys_pci_noti.h
new file mode 100755
index 0000000..cfe10bc
--- /dev/null
+++ b/sys_pci_noti/sys_pci_noti.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#ifndef __SYS_PCI_NOTI_H__
+#define __SYS_PCI_NOTI_H__
+
+#ifndef _
+#define _(str) gettext(str)
+#endif
+
+#ifndef gettext_noop
+#define gettext_noop(str) (str)
+#endif
+
+#ifndef N_
+#define N_(str) gettext_noop(str)
+#endif
+
+typedef enum {
+ CB_NOTI_PCI_REMOVED = 0,
+ CB_NOTI_PCI_INSERTED
+}pci_noti_type;
+
+#endif /* __SYS_PCI_NOTI_H__ */
diff --git a/system-server.conf b/system-server.conf
new file mode 100644
index 0000000..21a6638
--- /dev/null
+++ b/system-server.conf
@@ -0,0 +1,10 @@
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+ <policy user="root">
+ <allow own="slp.system.server"/>
+ </policy>
+ <policy context="default">
+ <deny own="slp.system.server"/>
+ </policy>
+</busconfig>
diff --git a/system_server.sh b/system_server.sh
new file mode 100644
index 0000000..3db1e64
--- /dev/null
+++ b/system_server.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+/usr/bin/system_server &
diff --git a/systemd/system-server.service b/systemd/system-server.service
new file mode 100644
index 0000000..01cf784
--- /dev/null
+++ b/systemd/system-server.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Start the system server service
+After=vconf-setup.service
+
+[Service]
+# set DISPLAY for usb_setting launching
+Type=notify
+Environment=DISPLAY=:0
+ExecStart=/usr/bin/system_server
+TimeoutStopSec=2
+NotifyAccess=all
+
+[Install]
+WantedBy=multi-user.target
diff --git a/systemd/system-server.socket b/systemd/system-server.socket
new file mode 100644
index 0000000..aa36429
--- /dev/null
+++ b/systemd/system-server.socket
@@ -0,0 +1,10 @@
+[Unit]
+Description=System server socket
+
+[Socket]
+ListenStream=/tmp/sn
+SocketMode=0777
+PassCredentials=yes
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+Accept=false
diff --git a/udev-rules/91-system-server.rules.in b/udev-rules/91-system-server.rules.in
new file mode 100644
index 0000000..1c1d528
--- /dev/null
+++ b/udev-rules/91-system-server.rules.in
@@ -0,0 +1,39 @@
+#MMC
+ACTION=="add", KERNEL=="mmcblk[0-9]", SUBSYSTEM=="block", RUN+="@PREFIX@/bin/sys_event mmcblk_add"
+ACTION=="remove", KERNEL=="mmcblk[0-9]", SUBSYSTEM=="block", RUN+="@PREFIX@/bin/sys_event mmcblk_remove"
+
+#Process Monitor
+#ACTION=="change" SUBSYSTEM=="pmon", RUN+="@PREFIX@/bin/restart"
+
+#Jack
+ACTION=="change" DEVPATH=="/devices/platform/jack", ENV{CHGDET}=="cdrom" RUN+="@PREFIX@/bin/start_composite.sh"
+
+#USB Host Device
+ACTION=="add", SUBSYSTEM=="usb_device", RUN+="/usr/bin/sys_event device_usb_host_add"
+ACTION=="remove", SUBSYSTEM=="usb_device", RUN+="/usr/bin/sys_event device_usb_host_remove"
+ACTION=="change", SUBSYSTEM=="host_notify", ENV{STATE}=="ADD", RUN+="@PREFIX@/bin/vconftool set -t int memory/sysman/usbhost_status 1 -f"
+ACTION=="change", SUBSYSTEM=="host_notify", ENV{STATE}=="REMOVE", RUN+="@PREFIX@/bin/vconftool set -t int memory/sysman/usbhost_status 0 -f"
+ACTION=="change", SUBSYSTEM=="host_notify", ENV{STATE}=="OVERCURRENT", RUN+="@PREFIX@/bin/vconftool set -t int memory/sysman/usbhost_status 2 -f"
+
+#USB Storage
+ACTION=="add", KERNEL=="sd[a-z][0-9]", SUBSYSTEM=="block", RUN+="@PREFIX@/bin/vconftool set -t string memory/private/sysman/added_storage_uevent %N -f"
+ACTION=="remove", KERNEL=="sd[a-z][0-9]", SUBSYSTEM=="block", RUN+="@PREFIX@/bin/vconftool set -t string memory/private/sysman/removed_storage_uevent $name -f"
+
+#charge
+ACTION=="change" DEVPATH=="/devices/platform/samsung-battery/power_supply/battery" RUN+="/usr/bin/sys_event device_charge_chgdet"
+ACTION=="change" DEVPATH=="/devices/platform/charger-manager.0" RUN+="@PREFIX@/bin/sys_event device_charge_chgdet"
+ACTION=="change" DEVPATH=="/devices/virtual/power_supply/battery" RUN+="/usr/bin/sys_event device_charge_chgdet"
+ACTION=="change" DEVPATH=="/devices/platform/sec-battery/power_supply/battery" RUN+="/usr/bin/sys_event device_charge_chgdet"
+
+#USB Keyboard
+ACTION=="add" SUBSYSTEM=="input" DEVPATH=="*/input[1-9]*/event[1-9]*" ENV{ID_BUS}=="usb" ENV{ID_INPUT_KEYBOARD}=="?*" RUN+="/usr/bin/sys_event device_keyboard_add"
+ACTION=="remove" SUBSYSTEM=="input" DEVPATH=="*/input[1-9]*/event[1-9]*" ENV{ID_BUS}=="usb" ENV{ID_INPUT_KEYBOARD}=="?*" RUN+="/usr/bin/sys_event device_keyboard_remove"
+ACTION=="add" SUBSYSTEM=="input" DEVPATH=="*/input[1-9]*/event[1-9]*" ENV{ID_BUS}=="usb" ENV{ID_INPUT_MOUSE}=="?*" RUN+="/usr/bin/sys_event device_mouse_add"
+ACTION=="remove" SUBSYSTEM=="input" DEVPATH=="*/input[1-9]*/event[1-9]*" ENV{ID_BUS}=="usb" ENV{ID_INPUT_MOUSE}=="?*" RUN+="/usr/bin/sys_event device_mouse_remove"
+
+#PCI keyboard
+ACTION=="add" SUBSYSTEM=="input" DEVPATH=="*/virtio[1-9]*/input/input[1-9]*/event[1-9]*" ENV{ID_PATH}=="*virtio-pci*" ENV{ID_INPUT_KEYBOARD}=="?*" RUN+="/usr/bin/sys_event device_pci_keyboard_add"
+ACTION=="remove" SUBSYSTEM=="input" DEVPATH=="*/virtio[1-9]*/input/input[1-9]*/event[1-9]*" ENV{ID_PATH}=="*virtio-pci*" ENV{ID_INPUT_KEYBOARD}=="?*" RUN+="/usr/bin/sys_event device_pci_keyboard_remove"
+
+#Smart debug bridge
+ACTION=="add", KERNEL=="samsung_sdb", SYMLINK+="tizen_sdb"