Initialize Tizen 2.3 tizen_2.3 2.3a_release submit/tizen_2.3/20140531.112419
authorSehong Na <sehong.na@samsung.com>
Sat, 31 May 2014 04:01:11 +0000 (13:01 +0900)
committerSehong Na <sehong.na@samsung.com>
Sat, 31 May 2014 04:01:11 +0000 (13:01 +0900)
132 files changed:
AUTHORS [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0755]
LICENSE.APLv2 [new file with mode: 0644]
NOTICE [new file with mode: 0644]
app2ext.c [new file with mode: 0755]
app2ext.h [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/rules [new file with mode: 0755]
debian/system-server-bin.install.in [new file with mode: 0644]
debian/system-server-bin.postinst.in [new file with mode: 0644]
deviced.pc.in [new file with mode: 0644]
include/ss_data.h [new file with mode: 0644]
mmc-smack-label [new file with mode: 0755]
movi_format.sh [new file with mode: 0755]
packaging/deviced.manifest [new file with mode: 0644]
packaging/system-server.manifest [new file with mode: 0644]
packaging/system-server.rule [new file with mode: 0644]
packaging/system-server.spec [new file with mode: 0644]
predefine_act_plugin/CMakeLists.txt [new file with mode: 0644]
predefine_act_plugin/build.sh [new file with mode: 0755]
predefine_act_plugin/xxx-predefine.c [new file with mode: 0644]
restarter/CMakeLists.txt [new file with mode: 0644]
restarter/restart.c [new file with mode: 0644]
src/core/list.h [new file with mode: 0644]
src/deviced/dd-battery.h [new file with mode: 0644]
src/deviced/dd-mmc.h [new file with mode: 0644]
src/shared/battery.c [new file with mode: 0644]
src/shared/common.h [new file with mode: 0644]
src/shared/log.h [new file with mode: 0644]
src/shared/mmc.c [new file with mode: 0644]
ss_bs.c [new file with mode: 0644]
ss_bs.h [new file with mode: 0644]
ss_common.c [new file with mode: 0644]
ss_common.h [new file with mode: 0644]
ss_core.c [new file with mode: 0644]
ss_core.h [new file with mode: 0644]
ss_cpu_handler.c [new file with mode: 0644]
ss_cpu_handler.h [new file with mode: 0644]
ss_device_change_handler.c [new file with mode: 0755]
ss_device_handler.h [new file with mode: 0644]
ss_launch.c [new file with mode: 0644]
ss_launch.h [new file with mode: 0644]
ss_log.c [new file with mode: 0644]
ss_log.h [new file with mode: 0644]
ss_lowbat_handler.c [new file with mode: 0755]
ss_lowmem_handler.c [new file with mode: 0644]
ss_main.c [new file with mode: 0644]
ss_mmc_handler.c [new file with mode: 0644]
ss_noti.c [new file with mode: 0644]
ss_noti.h [new file with mode: 0644]
ss_pmon_handler.c [new file with mode: 0644]
ss_pmon_handler.h [new file with mode: 0644]
ss_predefine.c [new file with mode: 0644]
ss_predefine.h [new file with mode: 0644]
ss_procmgr.c [new file with mode: 0755]
ss_procmgr.h [new file with mode: 0644]
ss_queue.c [new file with mode: 0644]
ss_queue.h [new file with mode: 0644]
ss_sig_handler.c [new file with mode: 0644]
ss_sig_handler.h [new file with mode: 0644]
ss_sysnoti.c [new file with mode: 0755]
ss_sysnoti.h [new file with mode: 0644]
ss_ta_handler.c [new file with mode: 0644]
ss_timemgr.c [new file with mode: 0644]
ss_timemgr.h [new file with mode: 0644]
ss_usb_handler.c [new file with mode: 0644]
ss_vibrator.c [new file with mode: 0644]
ss_vibrator.h [new file with mode: 0644]
sys_event/CMakeLists.txt [new file with mode: 0644]
sys_event/sys_event.c [new file with mode: 0644]
sys_pci_noti/CMakeLists.txt [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/CMakeLists.txt [new file with mode: 0644]
sys_pci_noti/po_sys_pci_noti/ar.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/az.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/bg.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/ca.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/cs.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/da.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/de_DE.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/el_GR.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/en.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/en_PH.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/en_US.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/es_ES.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/es_MX.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/es_US.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/et.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/eu.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/fi.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/fr_CA.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/fr_FR.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/ga.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/gl.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/hi.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/hr.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/hu.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/hy.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/is.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/it_IT.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/ja_JP.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/ka.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/kk.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/ko_KR.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/lt.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/lv.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/mk.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/nb.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/nl_NL.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/pl.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/pt_BR.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/pt_PT.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/ro.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/ru_RU.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/sk.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/sl.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/sr.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/sv.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/tr_TR.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/uk.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/uz.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/zh_CN.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/zh_HK.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/zh_SG.po [new file with mode: 0755]
sys_pci_noti/po_sys_pci_noti/zh_TW.po [new file with mode: 0755]
sys_pci_noti/sys_pci_noti.c [new file with mode: 0755]
sys_pci_noti/sys_pci_noti.h [new file with mode: 0755]
system-server.conf [new file with mode: 0644]
system_server.sh [new file with mode: 0644]
systemd/system-server.service [new file with mode: 0644]
systemd/system-server.socket [new file with mode: 0644]
udev-rules/91-system-server.rules.in [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..6edd069
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Giyeol Ok <giyeol.ok@samsung.com>\r
+Taesoo Jun <steve.jun@samsung.com>\r
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..7b14e75
--- /dev/null
@@ -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 (file)
index 0000000..d645695
--- /dev/null
@@ -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 (file)
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 (executable)
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 (file)
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 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..566063b
--- /dev/null
@@ -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 (executable)
index 0000000..bff6ad4
--- /dev/null
@@ -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 (file)
index 0000000..3c1f907
--- /dev/null
@@ -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 (file)
index 0000000..f449796
--- /dev/null
@@ -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 (file)
index 0000000..3de6ff0
--- /dev/null
@@ -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 (file)
index 0000000..98e1d5a
--- /dev/null
@@ -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 (executable)
index 0000000..4d8fcad
--- /dev/null
@@ -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 (executable)
index 0000000..dbc2f84
--- /dev/null
@@ -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 (file)
index 0000000..3256181
--- /dev/null
@@ -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 (file)
index 0000000..2a56863
--- /dev/null
@@ -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 (file)
index 0000000..23855cb
--- /dev/null
@@ -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 (file)
index 0000000..6f726f4
--- /dev/null
@@ -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 (file)
index 0000000..100c04f
--- /dev/null
@@ -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 (executable)
index 0000000..c0cc290
--- /dev/null
@@ -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 (file)
index 0000000..548cb4b
--- /dev/null
@@ -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 (file)
index 0000000..1a42ebf
--- /dev/null
@@ -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 (file)
index 0000000..e869e41
--- /dev/null
@@ -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 (file)
index 0000000..4217704
--- /dev/null
@@ -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 (file)
index 0000000..78fd9b3
--- /dev/null
@@ -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 (file)
index 0000000..d8e9f3f
--- /dev/null
@@ -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 (file)
index 0000000..7d7d238
--- /dev/null
@@ -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 (file)
index 0000000..5a3ef23
--- /dev/null
@@ -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 (file)
index 0000000..1be64d7
--- /dev/null
@@ -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 (file)
index 0000000..97c47f2
--- /dev/null
@@ -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 (file)
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 (file)
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 (file)
index 0000000..fff43aa
--- /dev/null
@@ -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 (file)
index 0000000..a7af544
--- /dev/null
@@ -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 (file)
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 (file)
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 (file)
index 0000000..e9a808e
--- /dev/null
@@ -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 (file)
index 0000000..7c72eb7
--- /dev/null
@@ -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 (executable)
index 0000000..9129a24
--- /dev/null
@@ -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 (file)
index 0000000..d31f46b
--- /dev/null
@@ -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 (file)
index 0000000..24b77c8
--- /dev/null
@@ -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 (file)
index 0000000..209d383
--- /dev/null
@@ -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 (file)
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 (file)
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 (executable)
index 0000000..5f97290
--- /dev/null
@@ -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 (file)
index 0000000..fb6db58
--- /dev/null
@@ -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 (file)
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 (file)
index 0000000..c837abd
--- /dev/null
@@ -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 (file)
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 (file)
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 (file)
index 0000000..c5476be
--- /dev/null
@@ -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 (file)
index 0000000..70c7fe4
--- /dev/null
@@ -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 (file)
index 0000000..44e8d28
--- /dev/null
@@ -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 (file)
index 0000000..1548ec7
--- /dev/null
@@ -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 (executable)
index 0000000..de789eb
--- /dev/null
@@ -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 (file)
index 0000000..d874e51
--- /dev/null
@@ -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 (file)
index 0000000..4269d10
--- /dev/null
@@ -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 (file)
index 0000000..6b9d899
--- /dev/null
@@ -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 (file)
index 0000000..b81dc55
--- /dev/null
@@ -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 (file)
index 0000000..08ab66f
--- /dev/null
@@ -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 (executable)
index 0000000..ec93479
--- /dev/null
@@ -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 (file)
index 0000000..e76d156
--- /dev/null
@@ -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 (file)
index 0000000..ac1e38a
--- /dev/null
@@ -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 (file)
index 0000000..cecbbb1
--- /dev/null
@@ -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 (file)
index 0000000..223f31e
--- /dev/null
@@ -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 (file)
index 0000000..815aca7
--- /dev/null
@@ -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 (file)
index 0000000..9d5c7c8
--- /dev/null
@@ -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 (file)
index 0000000..43c98c5
--- /dev/null
@@ -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 (file)
index 0000000..f41228f
--- /dev/null
@@ -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 (file)
index 0000000..ca1a294
--- /dev/null
@@ -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 (executable)
index 0000000..964f5a4
--- /dev/null
@@ -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 (file)
index 0000000..e4878ec
--- /dev/null
@@ -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 (executable)
index 0000000..8e8ecef
--- /dev/null
@@ -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 (executable)
index 0000000..09395e4
--- /dev/null
@@ -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 (executable)
index 0000000..0490340
--- /dev/null
@@ -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 (executable)
index 0000000..b67689d
--- /dev/null
@@ -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 (executable)
index 0000000..4f34a72
--- /dev/null
@@ -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 (executable)
index 0000000..4e27dc2
--- /dev/null
@@ -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 (executable)
index 0000000..6f0b207
--- /dev/null
@@ -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 (executable)
index 0000000..c0835cc
--- /dev/null
@@ -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 (executable)
index 0000000..724f9d7
--- /dev/null
@@ -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 (executable)
index 0000000..724f9d7
--- /dev/null
@@ -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 (executable)
index 0000000..724f9d7
--- /dev/null
@@ -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 (executable)
index 0000000..cc8dfc7
--- /dev/null
@@ -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 (executable)
index 0000000..cc8dfc7
--- /dev/null
@@ -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 (executable)
index 0000000..cc8dfc7
--- /dev/null
@@ -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 (executable)
index 0000000..cb33961
--- /dev/null
@@ -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 (executable)
index 0000000..521651c
--- /dev/null
@@ -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 (executable)
index 0000000..aa24538
--- /dev/null
@@ -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 (executable)
index 0000000..fe05fff
--- /dev/null
@@ -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 (executable)
index 0000000..fe05fff
--- /dev/null
@@ -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 (executable)
index 0000000..13e7950
--- /dev/null
@@ -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 (executable)
index 0000000..cc8dfc7
--- /dev/null
@@ -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 (executable)
index 0000000..c86fd0a
--- /dev/null
@@ -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 (executable)
index 0000000..71fccb9
--- /dev/null
@@ -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 (executable)
index 0000000..06a9d89
--- /dev/null
@@ -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 (executable)
index 0000000..4fd13d1
--- /dev/null
@@ -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 (executable)
index 0000000..391eaed
--- /dev/null
@@ -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 (executable)
index 0000000..0e5c942
--- /dev/null
@@ -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 (executable)
index 0000000..63b3ccf
--- /dev/null
@@ -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 (executable)
index 0000000..72b72b7
--- /dev/null
@@ -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 (executable)
index 0000000..f3873db
--- /dev/null
@@ -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 (executable)
index 0000000..8f73524
--- /dev/null
@@ -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 (executable)
index 0000000..65ec0bb
--- /dev/null
@@ -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 (executable)
index 0000000..d59b6aa
--- /dev/null
@@ -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 (executable)
index 0000000..e95b1b1
--- /dev/null
@@ -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 (executable)
index 0000000..5e04c0d
--- /dev/null
@@ -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 (executable)
index 0000000..d4f3d8f
--- /dev/null
@@ -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 (executable)
index 0000000..ef614e6
--- /dev/null
@@ -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 (executable)
index 0000000..cc8dfc7
--- /dev/null
@@ -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 (executable)
index 0000000..219f2eb
--- /dev/null
@@ -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 (executable)
index 0000000..758401c
--- /dev/null
@@ -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 (executable)
index 0000000..475bacc
--- /dev/null
@@ -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 (executable)
index 0000000..160dba2
--- /dev/null
@@ -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 (executable)
index 0000000..ef46adf
--- /dev/null
@@ -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 (executable)
index 0000000..12d0ca3
--- /dev/null
@@ -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 (executable)
index 0000000..58213f2
--- /dev/null
@@ -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 (executable)
index 0000000..a173ebf
--- /dev/null
@@ -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 (executable)
index 0000000..c746cdf
--- /dev/null
@@ -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 (executable)
index 0000000..f9babff
--- /dev/null
@@ -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 (executable)
index 0000000..a60aae3
--- /dev/null
@@ -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 (executable)
index 0000000..52b489c
--- /dev/null
@@ -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 (executable)
index 0000000..a60aae3
--- /dev/null
@@ -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 (executable)
index 0000000..52b489c
--- /dev/null
@@ -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 (executable)
index 0000000..919b82d
--- /dev/null
@@ -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 (executable)
index 0000000..cfe10bc
--- /dev/null
@@ -0,0 +1,39 @@
+/*\r
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+\r
+\r
+#ifndef __SYS_PCI_NOTI_H__\r
+#define __SYS_PCI_NOTI_H__\r
+\r
+#ifndef _\r
+#define _(str) gettext(str)\r
+#endif\r
+\r
+#ifndef gettext_noop\r
+#define gettext_noop(str) (str)\r
+#endif\r
+\r
+#ifndef N_\r
+#define N_(str) gettext_noop(str)\r
+#endif\r
+\r
+typedef enum {\r
+       CB_NOTI_PCI_REMOVED = 0,\r
+       CB_NOTI_PCI_INSERTED\r
+}pci_noti_type;\r
+\r
+#endif /* __SYS_PCI_NOTI_H__ */\r
diff --git a/system-server.conf b/system-server.conf
new file mode 100644 (file)
index 0000000..21a6638
--- /dev/null
@@ -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 (file)
index 0000000..3db1e64
--- /dev/null
@@ -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 (file)
index 0000000..01cf784
--- /dev/null
@@ -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 (file)
index 0000000..aa36429
--- /dev/null
@@ -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 (file)
index 0000000..1c1d528
--- /dev/null
@@ -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"