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