Initialize Tizen 2.3 2.3a_release submit/tizen_2.3/20140531.065311
authorSehong Na <sehong.na@samsung.com>
Sat, 31 May 2014 03:35:48 +0000 (12:35 +0900)
committerSehong Na <sehong.na@samsung.com>
Sat, 31 May 2014 03:35:48 +0000 (12:35 +0900)
271 files changed:
AUTHORS [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0755]
LICENSE.Apache-2.0 [new file with mode: 0644]
README.error.code [new file with mode: 0644]
deviced.pc.in [new file with mode: 0644]
doxygen/Doxyfile.in [new file with mode: 0644]
packaging/README.api [new file with mode: 0644]
packaging/crash-daemon.service [new file with mode: 0644]
packaging/devicectl-start@.service [new file with mode: 0644]
packaging/devicectl-stop@.service [new file with mode: 0644]
packaging/deviced-pre.service [new file with mode: 0644]
packaging/deviced.manifest [new file with mode: 0644]
packaging/deviced.rule [new file with mode: 0644]
packaging/deviced.service [new file with mode: 0644]
packaging/deviced.spec [new file with mode: 0644]
packaging/libdeviced.manifest [new file with mode: 0644]
packaging/liblogd-db.manifest [new file with mode: 0644]
packaging/liblogd.manifest [new file with mode: 0644]
packaging/shutdown-notify.service [new file with mode: 0644]
packaging/zbooting-done.service [new file with mode: 0644]
scripts/deviced-pre.sh [new file with mode: 0755]
scripts/direct_set_debug.sh [new file with mode: 0755]
scripts/dump_pm.sh [new file with mode: 0644]
scripts/mmc-smack-label [new file with mode: 0755]
scripts/movi_format.sh [new file with mode: 0755]
scripts/set_usb_debug.sh [new file with mode: 0755]
scripts/start_dr.sh [new file with mode: 0755]
src/CMakeLists.txt [new file with mode: 0755]
src/apps/apps.c [new file with mode: 0755]
src/apps/apps.h [new file with mode: 0755]
src/apps/launch.c [new file with mode: 0644]
src/apps/lowbat.c [new file with mode: 0644]
src/apps/lowmem.c [new file with mode: 0644]
src/apps/mmc.c [new file with mode: 0644]
src/apps/poweroff.c [new file with mode: 0644]
src/apps/system.c [new file with mode: 0644]
src/apps/usb.c [new file with mode: 0644]
src/apps/usbotg.c [new file with mode: 0644]
src/auto-test/CMakeLists.txt [new file with mode: 0755]
src/auto-test/board-info.c [new file with mode: 0644]
src/auto-test/boot.c [new file with mode: 0644]
src/auto-test/cpu-info.c [new file with mode: 0644]
src/auto-test/cradle.c [new file with mode: 0644]
src/auto-test/earjack.c [new file with mode: 0644]
src/auto-test/hdmi.c [new file with mode: 0644]
src/auto-test/keyboard.c [new file with mode: 0644]
src/auto-test/main.c [new file with mode: 0644]
src/auto-test/power-supply.c [new file with mode: 0644]
src/auto-test/storage.c [new file with mode: 0644]
src/auto-test/test.c [new file with mode: 0644]
src/auto-test/test.h [new file with mode: 0644]
src/auto-test/time.c [new file with mode: 0644]
src/auto-test/tvout.c [new file with mode: 0644]
src/auto-test/udev.c [new file with mode: 0644]
src/auto-test/usb.c [new file with mode: 0644]
src/battery/battery-micro-emul.conf [new file with mode: 0644]
src/battery/battery-micro.conf [new file with mode: 0644]
src/battery/battery-time.c [new file with mode: 0644]
src/battery/battery.c [new file with mode: 0644]
src/battery/battery.conf [new file with mode: 0644]
src/battery/battery.h [new file with mode: 0644]
src/battery/config.c [new file with mode: 0644]
src/battery/config.h [new file with mode: 0644]
src/battery/lowbat-handler.c [new file with mode: 0644]
src/board/board-info.c [new file with mode: 0644]
src/control/control.c [new file with mode: 0644]
src/core/common.c [new file with mode: 0644]
src/core/common.h [new file with mode: 0644]
src/core/config-parser.c [new file with mode: 0644]
src/core/config-parser.h [new file with mode: 0644]
src/core/core.c [new file with mode: 0644]
src/core/core.h [new file with mode: 0644]
src/core/data.h [new file with mode: 0644]
src/core/device-change-handler.c [new file with mode: 0644]
src/core/device-handler.h [new file with mode: 0644]
src/core/device-notifier.c [new file with mode: 0644]
src/core/device-notifier.h [new file with mode: 0644]
src/core/device-plugin.c [new file with mode: 0644]
src/core/device-plugin.h [new file with mode: 0644]
src/core/devices.c [new file with mode: 0644]
src/core/devices.h [new file with mode: 0644]
src/core/edbus-handler.c [new file with mode: 0644]
src/core/edbus-handler.h [new file with mode: 0644]
src/core/emulator.h [new file with mode: 0644]
src/core/execute.c [new file with mode: 0755]
src/core/launch.c [new file with mode: 0644]
src/core/launch.h [new file with mode: 0644]
src/core/list.h [new file with mode: 0644]
src/core/log.h [new file with mode: 0644]
src/core/lowstorage.c [new file with mode: 0755]
src/core/main.c [new file with mode: 0644]
src/core/noti.c [new file with mode: 0644]
src/core/noti.h [new file with mode: 0644]
src/core/power-supply.c [new file with mode: 0644]
src/core/power-supply.h [new file with mode: 0644]
src/core/predefine.c [new file with mode: 0755]
src/core/predefine.h [new file with mode: 0644]
src/core/queue.c [new file with mode: 0644]
src/core/queue.h [new file with mode: 0644]
src/core/sig-handler.c [new file with mode: 0644]
src/core/sysnoti.c [new file with mode: 0755]
src/core/sysnoti.h [new file with mode: 0644]
src/core/udev.h [new file with mode: 0644]
src/cpu/cpu-handler.c [new file with mode: 0644]
src/devicectl/CMakeLists.txt [new file with mode: 0755]
src/devicectl/devicectl.c [new file with mode: 0644]
src/deviced/dd-battery.h [new file with mode: 0644]
src/deviced/dd-common.h [new file with mode: 0644]
src/deviced/dd-control.h [new file with mode: 0644]
src/deviced/dd-deviced-managed.h [new file with mode: 0644]
src/deviced/dd-deviced.h [new file with mode: 0644]
src/deviced/dd-display.h [new file with mode: 0644]
src/deviced/dd-haptic.h [new file with mode: 0644]
src/deviced/dd-led.h [new file with mode: 0644]
src/deviced/dd-mmc.h [new file with mode: 0644]
src/deviced/dd-storage.h [new file with mode: 0644]
src/deviced/dd-usbhost.h [new file with mode: 0644]
src/deviced/deviced_doc.h [new file with mode: 0644]
src/deviced/haptic-module.h [new file with mode: 0644]
src/deviced/haptic-plugin-intf.h [new file with mode: 0644]
src/display/alpm.c [new file with mode: 0644]
src/display/auto-brightness.c [new file with mode: 0644]
src/display/brightness.c [new file with mode: 0644]
src/display/brightness.h [new file with mode: 0644]
src/display/core.c [new file with mode: 0644]
src/display/core.h [new file with mode: 0644]
src/display/device-interface.c [new file with mode: 0644]
src/display/device-interface.h [new file with mode: 0644]
src/display/display-dbus.c [new file with mode: 0644]
src/display/display-emul.conf [new file with mode: 0644]
src/display/display-exynos.conf [new file with mode: 0644]
src/display/display-msm.conf [new file with mode: 0644]
src/display/display-ops.c [new file with mode: 0644]
src/display/display-ops.h [new file with mode: 0644]
src/display/enhance.c [new file with mode: 0644]
src/display/enhance.h [new file with mode: 0644]
src/display/hbm.c [new file with mode: 0644]
src/display/key-filter-micro.c [new file with mode: 0644]
src/display/key-filter.c [new file with mode: 0644]
src/display/lock-detector.c [new file with mode: 0644]
src/display/lock-detector.h [new file with mode: 0644]
src/display/poll.c [new file with mode: 0644]
src/display/poll.h [new file with mode: 0644]
src/display/setting.c [new file with mode: 0644]
src/display/setting.h [new file with mode: 0644]
src/display/smartstay.c [new file with mode: 0644]
src/display/util.h [new file with mode: 0644]
src/display/weaks.h [new file with mode: 0644]
src/display/x-lcd-on.c [new file with mode: 0644]
src/extcon/extcon.c [new file with mode: 0644]
src/hall/hall-handler.c [new file with mode: 0644]
src/hall/hall-handler.h [new file with mode: 0644]
src/haptic/HW_touch_30ms_sharp.ivt [new file with mode: 0755]
src/haptic/emulator.c [new file with mode: 0644]
src/haptic/external.c [new file with mode: 0644]
src/haptic/haptic.c [new file with mode: 0644]
src/haptic/haptic.h [new file with mode: 0644]
src/haptic/standard.c [new file with mode: 0644]
src/led/ir.c [new file with mode: 0644]
src/led/led.xml [new file with mode: 0644]
src/led/noti.c [new file with mode: 0644]
src/led/pattern.c [new file with mode: 0644]
src/led/rgb.c [new file with mode: 0644]
src/led/torch.c [new file with mode: 0644]
src/led/torch.h [new file with mode: 0644]
src/led/xml.c [new file with mode: 0644]
src/led/xml.h [new file with mode: 0644]
src/libdeviced/CMakeLists.txt [new file with mode: 0755]
src/libdeviced/battery.c [new file with mode: 0644]
src/libdeviced/control.c [new file with mode: 0644]
src/libdeviced/deviced-conf.c [new file with mode: 0755]
src/libdeviced/deviced-noti.c [new file with mode: 0755]
src/libdeviced/deviced-util.c [new file with mode: 0644]
src/libdeviced/display.c [new file with mode: 0644]
src/libdeviced/haptic.c [new file with mode: 0644]
src/libdeviced/led.c [new file with mode: 0644]
src/libdeviced/mmc.c [new file with mode: 0644]
src/libdeviced/storage.c [new file with mode: 0644]
src/libdeviced/usbhost.c [new file with mode: 0644]
src/mmc/app2ext.c [new file with mode: 0755]
src/mmc/config.c [new file with mode: 0644]
src/mmc/config.h [new file with mode: 0644]
src/mmc/cprm.c [new file with mode: 0755]
src/mmc/ext4.c [new file with mode: 0644]
src/mmc/mmc-handler.c [new file with mode: 0644]
src/mmc/mmc-handler.h [new file with mode: 0644]
src/mmc/mmc.conf [new file with mode: 0644]
src/mmc/uevent.c [new file with mode: 0644]
src/mmc/vfat.c [new file with mode: 0644]
src/pmqos/pmqos-plugin.c [new file with mode: 0644]
src/pmqos/pmqos.c [new file with mode: 0644]
src/pmqos/pmqos.conf [new file with mode: 0644]
src/pmqos/pmqos.h [new file with mode: 0644]
src/power/power-handler.c [new file with mode: 0644]
src/power/power-handler.h [new file with mode: 0644]
src/power/systemd-power.c [new file with mode: 0644]
src/powersaver/powersaver.c [new file with mode: 0644]
src/predefine_act_plugin/CMakeLists.txt [new file with mode: 0644]
src/predefine_act_plugin/build.sh [new file with mode: 0755]
src/predefine_act_plugin/xxx-predefine.c [new file with mode: 0644]
src/proc/cpu-info.c [new file with mode: 0644]
src/proc/pmon-handler.c [new file with mode: 0644]
src/proc/proc-handler.c [new file with mode: 0644]
src/proc/proc-handler.h [new file with mode: 0644]
src/restarter/CMakeLists.txt [new file with mode: 0644]
src/restarter/restart.c [new file with mode: 0644]
src/shared/CMakeLists.txt [new file with mode: 0755]
src/shared/common.h [new file with mode: 0644]
src/shared/dbus.c [new file with mode: 0644]
src/shared/dbus.h [new file with mode: 0644]
src/shared/deviced-internal.h [new file with mode: 0644]
src/shared/deviced-priv.h [new file with mode: 0644]
src/shared/list.h [new file with mode: 0644]
src/shared/log-macro.h [new file with mode: 0644]
src/shared/log.h [new file with mode: 0644]
src/shared/score-defines.h [new file with mode: 0644]
src/ta/ta-handler.c [new file with mode: 0644]
src/telephony/telephony.c [new file with mode: 0644]
src/testmode/testmode.c [new file with mode: 0644]
src/ticker/ticker.c [new file with mode: 0755]
src/ticker/ticker.h [new file with mode: 0755]
src/time/time-handler.c [new file with mode: 0644]
src/touch/touch-controller.c [new file with mode: 0644]
src/touch/touch-controller.h [new file with mode: 0644]
src/touch/touch-plugin.c [new file with mode: 0644]
src/touch/touch-plugin.h [new file with mode: 0644]
src/touch/touch-util.h [new file with mode: 0644]
src/touch/touch.c [new file with mode: 0644]
src/touch/touch.h [new file with mode: 0644]
src/usb/configurations/conf-supported.xml [new file with mode: 0644]
src/usb/configurations/usb-configurations.xml [new file with mode: 0644]
src/usb/usb-client-control.c [new file with mode: 0755]
src/usb/usb-client-dbus.c [new file with mode: 0755]
src/usb/usb-client-set.c [new file with mode: 0755]
src/usb/usb-client-xml.c [new file with mode: 0755]
src/usb/usb-client.c [new file with mode: 0755]
src/usb/usb-client.h [new file with mode: 0755]
src/usb/usb-common.c [new file with mode: 0755]
src/usb/usb-common.h [new file with mode: 0755]
src/usb/usb-handler.c [new file with mode: 0755]
src/usb/usb-host-camera.c [new file with mode: 0755]
src/usb/usb-host-dbus.c [new file with mode: 0755]
src/usb/usb-host-hid.c [new file with mode: 0755]
src/usb/usb-host-naming.c [new file with mode: 0755]
src/usb/usb-host-printer.c [new file with mode: 0755]
src/usb/usb-host-storage-vfat.c [new file with mode: 0644]
src/usb/usb-host-storage.c [new file with mode: 0755]
src/usb/usb-host.c [new file with mode: 0755]
src/usb/usb-host.h [new file with mode: 0755]
test/_export_env.sh [new file with mode: 0755]
test/_export_target_env.sh [new file with mode: 0755]
test/build.sh [new file with mode: 0755]
test/clean.sh [new file with mode: 0755]
test/config [new file with mode: 0644]
test/execute.sh [new file with mode: 0755]
test/push.sh [new file with mode: 0755]
test/testcase/Makefile [new file with mode: 0644]
test/testcase/tslist [new file with mode: 0644]
test/testcase/utc_system_deviced_battery.c [new file with mode: 0644]
test/testcase/utc_system_deviced_control.c [new file with mode: 0644]
test/testcase/utc_system_deviced_deviced.c [new file with mode: 0644]
test/testcase/utc_system_deviced_deviced_managed.c [new file with mode: 0644]
test/testcase/utc_system_deviced_display.c [new file with mode: 0644]
test/testcase/utc_system_deviced_haptic.c [new file with mode: 0644]
test/testcase/utc_system_deviced_led.c [new file with mode: 0644]
test/testcase/utc_system_deviced_mmc.c [new file with mode: 0644]
test/testcase/utc_system_deviced_storage.c [new file with mode: 0644]
test/tet_scen [new file with mode: 0644]
test/tetbuild.cfg [new file with mode: 0644]
test/tetclean.cfg [new file with mode: 0644]
test/tetexec.cfg [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..63a6fc5
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,8 @@
+ChanWoo Choi <cw00.choi@samsung.com>
+Byung-Soo Kim <bs1770.kim@samsung.com>
+Taeyoung Kim <ty317.kim@samsung.com>
+Gi-Yeol Ok <giyeol.ok@samsung.com>
+Kyungmin Park <kyungmin.park@samsung.com>
+SeungHun Pi <sh.pi@samsung.com>
+Juho Son <juho80.son@samsung.com>
+Jiyoung Yun <jy910.yun@samsung.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..3ce4663
--- /dev/null
@@ -0,0 +1,400 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(deviced C)
+
+########################################################
+# Generation options:
+# -DBUILD_DOC_ONLY - only doxygen documentation is build
+# -DBUILD_DOC - build also doxygen documentation
+#
+# NOTE:
+# Remember to add all directories with files to DOC_SRC_DIRS_IN list
+#
+########################################################
+
+IF(BUILD_DOC_ONLY)
+    SET(BUILD_EXECUTABLE FALSE)
+    SET(BUILD_DOC TRUE)
+ELSE(BUILD_DOC_ONLY)
+    SET(BUILD_EXECUTABLE TRUE)
+ENDIF(BUILD_DOC_ONLY)
+
+IF(BUILD_DOC)
+    SET( DOC_SRC_DIRS_IN
+        ${CMAKE_SOURCE_DIR}/src/deviced
+    )
+    FOREACH(doc_dir ${DOC_SRC_DIRS_IN})
+        SET(DOC_SRC_DIRS "${DOC_SRC_DIRS} ${doc_dir}")
+    ENDFOREACH(doc_dir)
+
+    FIND_PACKAGE(Doxygen REQUIRED)
+
+    get_filename_component( DOXYGEN_DOC_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} PATH)
+
+    #adjust the doxygen configuration for this project
+    configure_file(${CMAKE_SOURCE_DIR}/doxygen/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/doxygen/Doxyfile @ONLY)
+
+    #build the documentation
+    add_custom_target( doc ALL
+        ${DOXYGEN_EXECUTABLE}
+        ${CMAKE_CURRENT_BINARY_DIR}/doxygen/Doxyfile
+        WORKING_DIRECTORY ${CMAKE_DOXYGEN_DIRECTORY}
+        COMMENT "Generating documentation with Doxygen" VERBATIM
+    )
+
+ENDIF(BUILD_DOC)
+
+IF(BUILD_EXECUTABLE)
+
+########################################################
+# Build options:
+# -DMICRO_DD - for tizenw project
+# -DTIZEN_ENGINEER_MODE - 
+########################################################
+IF("$ENV{CFLAGS}" MATCHES "-DMICRO_DD")
+       OPTION(USE_MICRO_DD "Use Micro DD" ON)
+ENDIF()
+
+IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_ENGINEER_MODE")
+       OPTION(USE_ENGINEER_MODE "Use Engineer mode" ON)
+ENDIF()
+
+IF("${ARCH}" STREQUAL "emulator")
+       OPTION(USE_EMULATOR "Use Emulator" ON)
+ELSEIF("${ARCH}" STREQUAL "arm")
+       OPTION(USE_ARM "Use Arm" ON)
+ENDIF()
+
+IF("$ENV{CFLAGS}" MATCHES "-DSYSTEMD_SHUTDOWN")
+       OPTION(USE_SYSTEMD_SHUTDOWN "Use systemd shutdown" ON)
+ENDIF()
+
+########################################################
+# Deviced CMakeLists.txt
+########################################################
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "${PREFIX}/bin")
+SET(LIBDIR "${PREFIX}/lib")
+SET(INCLUDEDIR "${PREFIX}/include/${PROJECT_NAME}")
+SET(DATADIR "${PREFIX}/share/${PROJECT_NAME}")
+SET(VERSION 0.1.0)
+
+SET(SRCS
+       src/battery/config.c
+       src/battery/lowbat-handler.c
+       src/battery/battery.c
+       src/core/device-notifier.c
+       src/core/main.c
+       src/core/sysnoti.c
+       src/core/launch.c
+       src/core/queue.c
+       src/core/core.c
+       src/core/devices.c
+       src/core/sig-handler.c
+       src/core/device-change-handler.c
+       src/core/predefine.c
+       src/core/common.c
+       src/core/config-parser.c
+       src/core/execute.c
+       src/core/edbus-handler.c
+       src/core/power-supply.c
+       src/core/lowstorage.c
+       src/proc/cpu-info.c
+       src/board/board-info.c
+       src/proc/proc-handler.c
+       src/ta/ta-handler.c
+       src/time/time-handler.c
+       src/ticker/ticker.c
+       src/testmode/testmode.c
+)
+
+IF(USE_SYSTEMD_SHUTDOWN)
+SET(SRCS ${SRCS}
+       src/power/systemd-power.c
+)
+ELSE()
+SET(SRCS ${SRCS}
+       src/power/power-handler.c
+)
+ENDIF()
+
+IF(NOT USE_MICRO_DD)
+    IF(USE_EMULATOR)
+        ADD_DEFINITIONS("-DMOBILE_EMULATOR")
+        SET(SRCS ${SRCS}
+            src/core/noti.c
+        )
+    ENDIF(USE_EMULATOR)
+ENDIF(NOT USE_MICRO_DD)
+
+SET(SRCS ${SRCS}
+       src/apps/apps.c
+       src/apps/lowbat.c
+       src/apps/poweroff.c
+       src/pmqos/pmqos.c
+       src/pmqos/pmqos-plugin.c
+)
+
+IF(NOT USE_MICRO_DD)
+SET(SRCS ${SRCS}
+       src/battery/battery-time.c
+       src/extcon/extcon.c
+       src/cpu/cpu-handler.c
+       src/hall/hall-handler.c
+       src/proc/pmon-handler.c
+       src/apps/launch.c
+       src/apps/lowmem.c
+       src/apps/mmc.c
+       src/apps/usb.c
+       src/apps/usbotg.c
+       src/apps/system.c
+)
+
+IF(NOT USE_SYSTEMD_SHUTDOWN)
+SET(SRCS ${SRCS}
+       src/telephony/telephony.c
+)
+ENDIF()
+
+SET(SRCS ${SRCS}
+       src/mmc/mmc-handler.c
+       src/mmc/uevent.c
+       src/mmc/config.c
+       src/mmc/cprm.c
+       src/mmc/app2ext.c
+)
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARC")
+IF(USE_EMULATOR)
+SET(SRCS ${SRCS}
+       src/mmc/ext4.c
+       )
+ENDIF(USE_EMULATOR)
+
+SET(SRCS ${SRCS}
+       src/mmc/vfat.c
+)
+ENDIF(NOT USE_MICRO_DD)
+
+# display(pm)
+SET(SRCS ${SRCS}
+       src/display/core.c
+       src/display/display-dbus.c
+       src/display/hbm.c
+       src/display/device-interface.c
+       src/display/lock-detector.c
+       src/display/poll.c
+       src/display/setting.c
+       src/display/display-ops.c
+)
+
+IF(USE_MICRO_DD)
+SET(SRCS ${SRCS}
+       src/display/alpm.c
+       src/display/key-filter-micro.c
+)
+ELSE()
+SET(SRCS ${SRCS}
+       src/display/brightness.c
+       src/display/key-filter.c
+       src/display/enhance.c
+       src/display/auto-brightness.c
+       src/display/smartstay.c
+)
+ENDIF(USE_MICRO_DD)
+
+SET(SRCS ${SRCS}
+       src/led/ir.c
+       src/led/torch.c
+       src/led/pattern.c
+       src/led/noti.c
+       src/led/xml.c
+)
+
+IF(NOT USE_MICRO_DD)
+SET(SRCS ${SRCS}
+       src/touch/touch.c
+       src/touch/touch-controller.c
+       src/touch/touch-plugin.c)
+
+
+SET(SRCS ${SRCS}
+       src/led/rgb.c
+)
+ENDIF(NOT USE_MICRO_DD)
+
+SET(SRCS ${SRCS}
+       src/control/control.c
+)
+
+SET(SRCS ${SRCS}
+       src/haptic/haptic.c
+       src/haptic/standard.c
+       src/haptic/external.c
+       src/haptic/emulator.c)
+
+# usb client
+SET(SRCS ${SRCS}
+       src/usb/usb-common.c
+       src/usb/usb-client.c
+       src/usb/usb-client-xml.c
+       src/usb/usb-client-set.c
+       src/usb/usb-client-control.c
+       src/usb/usb-client-dbus.c
+)
+
+# usb host
+IF(NOT USE_MICRO_DD)
+SET(SRCS ${SRCS}
+       src/usb/usb-common.c
+       src/usb/usb-host.c
+       src/usb/usb-host-dbus.c
+       src/usb/usb-host-storage.c
+       src/usb/usb-host-storage-vfat.c
+       src/usb/usb-host-hid.c
+       src/usb/usb-host-camera.c
+       src/usb/usb-host-printer.c
+       src/usb/usb-host-naming.c
+)
+ENDIF(NOT USE_MICRO_DD)
+
+# powersaver mode
+IF(USE_MICRO_DD)
+SET(SRCS ${SRCS}
+       src/powersaver/powersaver.c
+)
+ENDIF(USE_MICRO_DD)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/deviced)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/logd/src/shared)
+
+SET(PKG_MODULES
+       ecore
+       ecore-file
+       ecore-x
+       edbus
+       eina
+       vconf
+       dlog
+       device-node
+       libxml-2.0
+       capi-base-common
+)
+
+IF(NOT USE_MICRO_DD)
+SET(PKG_MODULES ${PKG_MODULES}
+       tapi
+       modem
+       sensor
+)
+ENDIF()
+
+IF(USE_TRUSTZONE_QUALCOMM)
+SET(PKG_MODULES ${PKG_MODULES}
+       tee-qsee
+)
+ENDIF()
+
+IF(NOT USE_MICRO_DD)
+    IF(USE_EMULATOR)
+        SET(PKG_MODULES ${PKG_MODULES}
+            heynoti
+        )
+    ENDIF(USE_EMULATOR)
+ENDIF(NOT USE_MICRO_DD)
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED ${PKG_MODULES})
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Werror")
+IF(USE_ENGINEER_MODE)
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions")
+ELSE()
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer")
+ENDIF()
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt")
+MESSAGE("FLAGS: ${CMAKE_C_FLAGS}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+ADD_DEFINITIONS("-DLIBDIR=\"${LIBDIR}\"")
+ADD_DEFINITIONS("-DENABLE_KEY_FILTER")
+ADD_DEFINITIONS("-DENABLE_X_LCD_ONOFF")
+ADD_DEFINITIONS("-DENABLE_DEVICED_DLOG")
+ADD_DEFINITIONS("-DENABLE_LIBDEVICED_DLOG")
+ADD_DEFINITIONS("-DENABLE_PM_LOG")
+IF(USE_ARM)
+       ADD_DEFINITIONS("-DTARGET")
+ELSEIF(USE_EMULATOR)
+       ADD_DEFINITIONS("-DEMULATOR")
+ENDIF()
+ADD_DEFINITIONS("-DDEBUG")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-ldl" "-lm" "-ludev" "-ledbus" shared)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/deviced/ DESTINATION include/${PROJECT_NAME}
+               FILES_MATCHING
+               PATTERN "*_doc.h" EXCLUDE
+               PATTERN "*.h")
+
+CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION lib/pkgconfig)
+
+IF(USE_ARM AND NOT USE_MICRO_DD)
+       INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/src/haptic/HW_touch_30ms_sharp.ivt DESTINATION ${DATADIR})
+       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/led/led.xml DESTINATION ${DATADIR})
+ENDIF(USE_ARM AND NOT USE_MICRO_DD)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/dump_pm.sh DESTINATION /opt/etc/dump.d/module.d)
+
+IF(USE_TRUSTZONE_QUALCOMM)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/display/display-msm.conf DESTINATION /etc/deviced RENAME display.conf)
+ELSEIF(USE_EMULATOR)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/display/display-emul.conf DESTINATION /etc/deviced RENAME display.conf)
+ELSE()
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/display/display-exynos.conf DESTINATION /etc/deviced RENAME display.conf)
+ENDIF()
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/mmc/mmc.conf DESTINATION /etc/deviced RENAME mmc.conf)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/pmqos/pmqos.conf DESTINATION /etc/deviced RENAME pmqos.conf)
+
+IF(USE_MICRO_DD)
+    IF(USE_EMULATOR)
+        INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/battery/battery-micro-emul.conf DESTINATION /etc/deviced RENAME battery.conf)
+    ELSE(USR_EMULATOR)
+        INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/battery/battery-micro.conf DESTINATION /etc/deviced RENAME battery.conf)
+    ENDIF(USE_EMULATOR)
+ELSE(USE_MICRO_DD)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/battery/battery.conf DESTINATION /etc/deviced RENAME battery.conf)
+ENDIF(USE_MICRO_DD)
+
+INSTALL(PROGRAMS ${CMAKE_BINARY_DIR}/scripts/deviced-pre.sh DESTINATION bin)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/packaging/${PROJECT_NAME}.rule DESTINATION /etc/smack/accesses2.d)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/usb/configurations/conf-supported.xml      DESTINATION ${DATADIR}/usb-configurations)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/usb/configurations/usb-configurations.xml  DESTINATION ${DATADIR}/usb-configurations)
+
+IF(NOT USE_MICRO_DD)
+       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/movi_format.sh DESTINATION bin)
+       INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/mmc-smack-label DESTINATION bin)
+ENDIF(NOT USE_MICRO_DD)
+
+# USB (data-router)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/start_dr.sh  DESTINATION ${EXEC_PREFIX})
+
+# USB (Manual setting)
+IF(USE_ENGINEER_MODE)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/direct_set_debug.sh  DESTINATION ${EXEC_PREFIX})
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/scripts/set_usb_debug.sh     DESTINATION ${EXEC_PREFIX})
+ENDIF()
+
+ADD_SUBDIRECTORY(src)
+ADD_SUBDIRECTORY(src/libdeviced)
+ADD_SUBDIRECTORY(src/devicectl)
+ADD_SUBDIRECTORY(src/auto-test)
+
+ENDIF(BUILD_EXECUTABLE)
diff --git a/LICENSE.Apache-2.0 b/LICENSE.Apache-2.0
new file mode 100644 (file)
index 0000000..9c13a9b
--- /dev/null
@@ -0,0 +1,204 @@
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+                                 Apache License\r
+                           Version 2.0, January 2004\r
+                        http://www.apache.org/licenses/\r
+\r
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+   1. Definitions.\r
+\r
+      "License" shall mean the terms and conditions for use, reproduction,\r
+      and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+      "Licensor" shall mean the copyright owner or entity authorized by\r
+      the copyright owner that is granting the License.\r
+\r
+      "Legal Entity" shall mean the union of the acting entity and all\r
+      other entities that control, are controlled by, or are under common\r
+      control with that entity. For the purposes of this definition,\r
+      "control" means (i) the power, direct or indirect, to cause the\r
+      direction or management of such entity, whether by contract or\r
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+      outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+      "You" (or "Your") shall mean an individual or Legal Entity\r
+      exercising permissions granted by this License.\r
+\r
+      "Source" form shall mean the preferred form for making modifications,\r
+      including but not limited to software source code, documentation\r
+      source, and configuration files.\r
+\r
+      "Object" form shall mean any form resulting from mechanical\r
+      transformation or translation of a Source form, including but\r
+      not limited to compiled object code, generated documentation,\r
+      and conversions to other media types.\r
+\r
+      "Work" shall mean the work of authorship, whether in Source or\r
+      Object form, made available under the License, as indicated by a\r
+      copyright notice that is included in or attached to the work\r
+      (an example is provided in the Appendix below).\r
+\r
+      "Derivative Works" shall mean any work, whether in Source or Object\r
+      form, that is based on (or derived from) the Work and for which the\r
+      editorial revisions, annotations, elaborations, or other modifications\r
+      represent, as a whole, an original work of authorship. For the purposes\r
+      of this License, Derivative Works shall not include works that remain\r
+      separable from, or merely link (or bind by name) to the interfaces of,\r
+      the Work and Derivative Works thereof.\r
+\r
+      "Contribution" shall mean any work of authorship, including\r
+      the original version of the Work and any modifications or additions\r
+      to that Work or Derivative Works thereof, that is intentionally\r
+      submitted to Licensor for inclusion in the Work by the copyright owner\r
+      or by an individual or Legal Entity authorized to submit on behalf of\r
+      the copyright owner. For the purposes of this definition, "submitted"\r
+      means any form of electronic, verbal, or written communication sent\r
+      to the Licensor or its representatives, including but not limited to\r
+      communication on electronic mailing lists, source code control systems,\r
+      and issue tracking systems that are managed by, or on behalf of, the\r
+      Licensor for the purpose of discussing and improving the Work, but\r
+      excluding communication that is conspicuously marked or otherwise\r
+      designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+      "Contributor" shall mean Licensor and any individual or Legal Entity\r
+      on behalf of whom a Contribution has been received by Licensor and\r
+      subsequently incorporated within the Work.\r
+\r
+   2. Grant of Copyright License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      copyright license to reproduce, prepare Derivative Works of,\r
+      publicly display, publicly perform, sublicense, and distribute the\r
+      Work and such Derivative Works in Source or Object form.\r
+\r
+   3. Grant of Patent License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      (except as stated in this section) patent license to make, have made,\r
+      use, offer to sell, sell, import, and otherwise transfer the Work,\r
+      where such license applies only to those patent claims licensable\r
+      by such Contributor that are necessarily infringed by their\r
+      Contribution(s) alone or by combination of their Contribution(s)\r
+      with the Work to which such Contribution(s) was submitted. If You\r
+      institute patent litigation against any entity (including a\r
+      cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+      or a Contribution incorporated within the Work constitutes direct\r
+      or contributory patent infringement, then any patent licenses\r
+      granted to You under this License for that Work shall terminate\r
+      as of the date such litigation is filed.\r
+\r
+   4. Redistribution. You may reproduce and distribute copies of the\r
+      Work or Derivative Works thereof in any medium, with or without\r
+      modifications, and in Source or Object form, provided that You\r
+      meet the following conditions:\r
+\r
+      (a) You must give any other recipients of the Work or\r
+          Derivative Works a copy of this License; and\r
+\r
+      (b) You must cause any modified files to carry prominent notices\r
+          stating that You changed the files; and\r
+\r
+      (c) You must retain, in the Source form of any Derivative Works\r
+          that You distribute, all copyright, patent, trademark, and\r
+          attribution notices from the Source form of the Work,\r
+          excluding those notices that do not pertain to any part of\r
+          the Derivative Works; and\r
+\r
+      (d) If the Work includes a "NOTICE" text file as part of its\r
+          distribution, then any Derivative Works that You distribute must\r
+          include a readable copy of the attribution notices contained\r
+          within such NOTICE file, excluding those notices that do not\r
+          pertain to any part of the Derivative Works, in at least one\r
+          of the following places: within a NOTICE text file distributed\r
+          as part of the Derivative Works; within the Source form or\r
+          documentation, if provided along with the Derivative Works; or,\r
+          within a display generated by the Derivative Works, if and\r
+          wherever such third-party notices normally appear. The contents\r
+          of the NOTICE file are for informational purposes only and\r
+          do not modify the License. You may add Your own attribution\r
+          notices within Derivative Works that You distribute, alongside\r
+          or as an addendum to the NOTICE text from the Work, provided\r
+          that such additional attribution notices cannot be construed\r
+          as modifying the License.\r
+\r
+      You may add Your own copyright statement to Your modifications and\r
+      may provide additional or different license terms and conditions\r
+      for use, reproduction, or distribution of Your modifications, or\r
+      for any such Derivative Works as a whole, provided Your use,\r
+      reproduction, and distribution of the Work otherwise complies with\r
+      the conditions stated in this License.\r
+\r
+   5. Submission of Contributions. Unless You explicitly state otherwise,\r
+      any Contribution intentionally submitted for inclusion in the Work\r
+      by You to the Licensor shall be under the terms and conditions of\r
+      this License, without any additional terms or conditions.\r
+      Notwithstanding the above, nothing herein shall supersede or modify\r
+      the terms of any separate license agreement you may have executed\r
+      with Licensor regarding such Contributions.\r
+\r
+   6. Trademarks. This License does not grant permission to use the trade\r
+      names, trademarks, service marks, or product names of the Licensor,\r
+      except as required for reasonable and customary use in describing the\r
+      origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+   7. Disclaimer of Warranty. Unless required by applicable law or\r
+      agreed to in writing, Licensor provides the Work (and each\r
+      Contributor provides its Contributions) on an "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+      implied, including, without limitation, any warranties or conditions\r
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+      PARTICULAR PURPOSE. You are solely responsible for determining the\r
+      appropriateness of using or redistributing the Work and assume any\r
+      risks associated with Your exercise of permissions under this License.\r
+\r
+   8. Limitation of Liability. In no event and under no legal theory,\r
+      whether in tort (including negligence), contract, or otherwise,\r
+      unless required by applicable law (such as deliberate and grossly\r
+      negligent acts) or agreed to in writing, shall any Contributor be\r
+      liable to You for damages, including any direct, indirect, special,\r
+      incidental, or consequential damages of any character arising as a\r
+      result of this License or out of the use or inability to use the\r
+      Work (including but not limited to damages for loss of goodwill,\r
+      work stoppage, computer failure or malfunction, or any and all\r
+      other commercial damages or losses), even if such Contributor\r
+      has been advised of the possibility of such damages.\r
+\r
+   9. Accepting Warranty or Additional Liability. While redistributing\r
+      the Work or Derivative Works thereof, You may choose to offer,\r
+      and charge a fee for, acceptance of support, warranty, indemnity,\r
+      or other liability obligations and/or rights consistent with this\r
+      License. However, in accepting such obligations, You may act only\r
+      on Your own behalf and on Your sole responsibility, not on behalf\r
+      of any other Contributor, and only if You agree to indemnify,\r
+      defend, and hold each Contributor harmless for any liability\r
+      incurred by, or claims asserted against, such Contributor by reason\r
+      of your accepting any such warranty or additional liability.\r
+\r
+   END OF TERMS AND CONDITIONS\r
+\r
+   APPENDIX: How to apply the Apache License to your work.\r
+\r
+      To apply the Apache License to your work, attach the following\r
+      boilerplate notice, with the fields enclosed by brackets "[]"\r
+      replaced with your own identifying information. (Don't include\r
+      the brackets!)  The text should be enclosed in the appropriate\r
+      comment syntax for the file format. We also recommend that a\r
+      file or class name and description of purpose be included on the\r
+      same "printed page" as the copyright notice for easier\r
+      identification within third-party archives.\r
+\r
+   Copyright [yyyy] [name of copyright owner]\r
+\r
+   Licensed under the Apache License, Version 2.0 (the "License");\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
diff --git a/README.error.code b/README.error.code
new file mode 100644 (file)
index 0000000..61cd9c6
--- /dev/null
@@ -0,0 +1,9 @@
+DBus Error note
+
+Functions                                     Defines          Values
+======================================================================
+dbus_bus_get                                  EPERM            1
+dbus_message_get_args                         ENOMSG           42
+dbus_connection_send_with_reply_and_block     ECOMM            70
+dbus_connection_send                          ECOMM            70
+dbus_message_new_method_call                  EBADMSG          74
diff --git a/deviced.pc.in b/deviced.pc.in
new file mode 100644 (file)
index 0000000..6ce4c9b
--- /dev/null
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=/usr/lib
+includedir=/usr/include/deviced
+
+Name: deviced
+Description: Tizen platform device control library
+Version: @VERSION@
+Requires:
+Libs: -L${libdir} -ldeviced
+Cflags: -I${includedir}
diff --git a/doxygen/Doxyfile.in b/doxygen/Doxyfile.in
new file mode 100644 (file)
index 0000000..73655a4
--- /dev/null
@@ -0,0 +1,910 @@
+# Doxyfile 1.4.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+PROJECT_NAME = @CMAKE_PROJECT_NAME@
+PROJECT_NUMBER =
+OUTPUT_DIRECTORY = @DOXYGEN_DOC_OUTPUT_DIRECTORY@/doc
+CREATE_SUBDIRS = NO
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+INLINE_INHERITED_MEMB = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+JAVADOC_AUTOBRIEF = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+INHERIT_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+DISTRIBUTE_GROUP_DOC = NO
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+EXTRACT_LOCAL_METHODS = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is YES.
+SHOW_DIRECTORIES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command , where is the value of
+# the FILE_VERSION_FILTER tag, and is the name of an input file
+# provided by doxygen. Whatever the progam writes to standard output
+# is used as the file version. See the manual for examples.
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = YES
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+INPUT = @DOC_SRC_DIRS@
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+FILE_PATTERNS = *.c *.h
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command , where
+# is the value of the INPUT_FILTER tag, and is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+REFERENCES_RELATION = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+GENERATE_TREEVIEW = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_SCHEMA =
+XML_DTD =
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+HAVE_DOT = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+TEMPLATE_RELATIONS = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+DOT_PATH = /usr/bin
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that a graph may be further truncated if the graph's
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
+# the graph is not depth-constrained.
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+SEARCHENGINE = YES
diff --git a/packaging/README.api b/packaging/README.api
new file mode 100644 (file)
index 0000000..1f8c8ad
--- /dev/null
@@ -0,0 +1,108 @@
+This file has to be synced with packaging/deviced.manifest
+
+
+DBus method_call smack authority
+
+* : all user can access the methods.
+
+Display
+       org.tizen.system.deviced.display.start                      root only
+       org.tizen.system.deviced.display.stop                       root only
+       org.tizen.system.deviced.display.lockstate                  deviced::display
+       org.tizen.system.deviced.display.unlockstate                *
+       org.tizen.system.deviced.display.changestate                deviced::display
+       org.tizen.system.deviced.display.getbrightness              *
+       org.tizen.system.deviced.display.setbrightness              *
+       org.tizen.system.deviced.display.getautotone                *
+       org.tizen.system.deviced.display.setautotone                *
+       org.tizen.system.deviced.display.getimageenhance            *
+       org.tizen.system.deviced.display.setimageenhance            *
+       org.tizen.system.deviced.display.setframerate               *
+       org.tizen.system.deviced.display.getcolorblind              *
+       org.tizen.system.deviced.display.setcolorblind              *
+       org.tizen.system.deviced.display.setautobrightnessmin       *
+       org.tizen.system.deviced.display.setlcdtimeout              *
+       org.tizen.system.deviced.display.LockScreenBgOn             *
+       org.tizen.system.deviced.display.GetDisplayCount            *
+       org.tizen.system.deviced.display.GetMaxBrightness           *
+       org.tizen.system.deviced.display.GetBrightness              *
+       org.tizen.system.deviced.display.SetBrightness              *
+       org.tizen.system.deviced.display.HoldBrightness             deviced::display
+       org.tizen.system.deviced.display.ReleaseBrightness          *
+       org.tizen.system.deviced.display.GetAclStatus               *
+       org.tizen.system.deviced.display.SetAclStatus               *
+       org.tizen.system.deviced.display.GetAutoTone                *
+       org.tizen.system.deviced.display.SetAutoTone                *
+       org.tizen.system.deviced.display.GetEnhanceSupported        *
+       org.tizen.system.deviced.display.GetImageEnhance            *
+       org.tizen.system.deviced.display.SetImageEnhance            *
+       org.tizen.system.deviced.display.SetFrameRate               *
+       org.tizen.system.deviced.display.GetColorBlind              *
+       org.tizen.system.deviced.display.SetColorBlind              *
+Hapic
+       org.tizen.system.deviced.haptic.GetCount                    *
+       org.tizen.system.deviced.haptic.OpenDevice                  *
+       org.tizen.system.deviced.haptic.CloseDevice                 *
+       org.tizen.system.deviced.haptic.StopDevice                  *
+       org.tizen.system.deviced.haptic.VibrateMonotone             *
+       org.tizen.system.deviced.haptic.VibrateBuffer               *
+       org.tizen.system.deviced.haptic.GetState                    *
+       org.tizen.system.deviced.haptic.GetDuration                 *
+       org.tizen.system.deviced.haptic.CreateEffect                *
+       org.tizen.system.deviced.haptic.SaveBinary                  *
+Pass
+       org.tizen.system.deviced.pass.start                         root only
+       org.tizen.system.deviced.pass.stop                          root only
+       org.tizen.system.deviced.pass.bypass                        root only
+Hall
+       org.tizen.system.deviced.hall.getstatus                     *
+Power
+       org.tizen.system.deviced.power.setresetkeydisable           deviced::power
+       org.tizen.system.deviced.power.entersleep                   root only
+       org.tizen.system.deviced.power.leavesleep                   root only
+       org.tizen.system.deviced.power.reboot                       root only
+       org.tizen.system.deviced.power.reboot-recovery              root only
+       org.tizen.system.deviced.power.pwroff-popup                 *
+       org.tizen.system.deviced.power.flightmode                   root only
+Storage
+       org.tizen.system.deviced.storage.getstorage                 *
+Ode
+Lowmem
+Led
+       org.tizen.system.deviced.Led.playcustom                     *
+       org.tizen.system.deviced.Led.stopcustom                     *
+       org.tizen.system.deviced.Led.GetBrightness                  *
+       org.tizen.system.deviced.Led.GetMaxBrightness               *
+       org.tizen.system.deviced.Led.SetBrightness                  *
+       org.tizen.system.deviced.Led.SetIrCommand                   *
+       org.tizen.system.deviced.Led.SetMode                        *
+       org.tizen.system.deviced.Led.PrintMode                      *
+
+Process
+       org.tizen.system.deviced.Process.foregrd                    root only
+       org.tizen.system.deviced.Process.backgrd                    root only
+       org.tizen.system.deviced.Process.active                     *
+       org.tizen.system.deviced.Process.inactive                   *
+       org.tizen.system.deviced.Process.oomadj_set                 root only
+       org.tizen.system.deviced.Process.process_group_set          root only
+
+SysNoti
+       org.tizen.system.deviced.SysNoti.set_max_frequency          root only
+       org.tizen.system.deviced.SysNoti.set_min_frequency          root only
+       org.tizen.system.deviced.SysNoti.release_max_frequency      root only
+       org.tizen.system.deviced.SysNoti.release_min_frequency      root only
+       org.tizen.system.deviced.SysNoti.dump_log                   *
+       org.tizen.system.deviced.SysNoti.delete_dump                *
+       org.tizen.system.deviced.SysNoti.set_datetime               *
+       org.tizen.system.deviced.SysNoti.set_timezone               *
+       org.tizen.system.deviced.SysNoti.control                    *
+       org.tizen.system.deviced.SysNoti.device_changed             root only
+       org.tizen.system.deviced.SysNoti.power_supply               root only
+       org.tizen.system.deviced.SysNoti.udev                       root only
+       org.tizen.system.deviced.SysNoti.factorymode                root only
+       org.tizen.system.deviced.SysNoti.control                    root only
+Mmc
+       org.tizen.system.deviced.Mmc.RequestMount                   *
+       org.tizen.system.deviced.Mmc.RequestUnmount                 *
+       org.tizen.system.deviced.Mmc.RequestFormat                  *
+
diff --git a/packaging/crash-daemon.service b/packaging/crash-daemon.service
new file mode 100644 (file)
index 0000000..27e39bb
--- /dev/null
@@ -0,0 +1,11 @@
+[Unit]
+Description=Start the crash daemon service
+After=dbus.socket
+
+[Service]
+ExecStart=/usr/bin/crash-daemon
+Restart=always
+RestartSec=0
+
+[Install]
+WantedBy=multi-user.target
diff --git a/packaging/devicectl-start@.service b/packaging/devicectl-start@.service
new file mode 100644 (file)
index 0000000..3322274
--- /dev/null
@@ -0,0 +1,7 @@
+[Unit]
+Description=Device Control Start %I
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/devicectl %I start
diff --git a/packaging/devicectl-stop@.service b/packaging/devicectl-stop@.service
new file mode 100644 (file)
index 0000000..c242e72
--- /dev/null
@@ -0,0 +1,7 @@
+[Unit]
+Description=Device Control Stop %I
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/devicectl %I stop
diff --git a/packaging/deviced-pre.service b/packaging/deviced-pre.service
new file mode 100644 (file)
index 0000000..0992d9d
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=prepare device daemon
+DefaultDependencies=no
+Before=deviced.service
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/deviced-pre.sh
diff --git a/packaging/deviced.manifest b/packaging/deviced.manifest
new file mode 100644 (file)
index 0000000..97710e4
--- /dev/null
@@ -0,0 +1,40 @@
+<manifest>
+    <define>
+        <domain name="deviced"/>
+        <provide>
+            <label name="deviced::display" />
+            <label name="deviced::power" />
+        </provide>
+    </define>
+    <assign>
+        <filesystem path="/etc/init.d/device-daemon" label="_" exec_label="none" />
+        <filesystem path="/etc/rc.d/init.d/device-daemon" label="_" exec_label="none" />
+        <filesystem path="/opt/etc/dump.d/module.d/dump_pm.sh" label="_" exec_label="none" />
+        <dbus name="org.tizen.system.deviced" own="deviced" bus="system">
+            <node name="/Org/Tizen/System/DeviceD/Display">
+                <interface name="org.tizen.system.deviced.display">
+                    <!-- dbus smack label "deviced::display" -->
+                    <method name="lockstate">
+                        <annotation name="com.tizen.smack" value="deviced::display" />
+                    </method>
+                    <method name="changestate">
+                        <annotation name="com.tizen.smack" value="deviced::display" />
+                    </method>
+                    <method name="HoldBrightness">
+                        <annotation name="com.tizen.smack" value="deviced::display" />
+                    </method>
+                </interface>
+            </node>
+            <node name="/Org/Tizen/System/DeviceD/Power">
+                <interface name="org.tizen.system.deviced.power">
+                    <method name="setresetkeydisable">
+                        <annotation name="com.tizen.smack" value="deviced::power" />
+                    </method>
+                </interface>
+            </node>
+        </dbus>
+    </assign>
+    <request>
+        <domain name="deviced"/>
+    </request>
+</manifest>
diff --git a/packaging/deviced.rule b/packaging/deviced.rule
new file mode 100644 (file)
index 0000000..bce8fd6
--- /dev/null
@@ -0,0 +1,11 @@
+# subject rule
+deviced sys-assert::core rwxat
+deviced system::media rwxat
+deviced system::vconf rwxat
+deviced system::vconf_setting rw
+deviced com.samsung.setting::private r
+deviced system::vconf_system rw
+deviced testmode::vconf r
+deviced starter::vconf r
+# object rule
+pulseaudio deviced rw
diff --git a/packaging/deviced.service b/packaging/deviced.service
new file mode 100644 (file)
index 0000000..9f0661a
--- /dev/null
@@ -0,0 +1,14 @@
+[Unit]
+Description=System device daemon
+After=deviced-pre.service pulseaudio.service sound-init.service
+Requires=deviced-pre.service
+
+[Service]
+EnvironmentFile=/run/deviced/deviced_env
+ExecStart=/usr/bin/deviced
+Restart=always
+RestartSec=0
+KillSignal=SIGUSR1
+
+[Install]
+WantedBy=multi-user.target
diff --git a/packaging/deviced.spec b/packaging/deviced.spec
new file mode 100644 (file)
index 0000000..0739bbc
--- /dev/null
@@ -0,0 +1,266 @@
+Name:       deviced
+Summary:    deviced
+Version:    1.0.0
+Release:    1
+Group:      Framework/system
+License:    Apache License, Version 2.0
+Source0:    %{name}-%{version}.tar.gz
+Source1:    %{name}.service
+Source2:    zbooting-done.service
+Source3:    shutdown-notify.service
+Source4:    deviced-pre.service
+Source5:    devicectl-start@.service
+Source6:    devicectl-stop@.service
+Source1001: deviced.manifest
+Source1002: libdeviced.manifest
+Source1003: liblogd-db.manifest
+Source1004: liblogd.manifest
+
+BuildRequires:  cmake
+BuildRequires:  libattr-devel
+BuildRequires:  gettext-devel
+BuildRequires:  pkgconfig(ecore)
+BuildRequires:  pkgconfig(vconf)
+%ifnarch %{arm}
+BuildRequires:  pkgconfig(heynoti)
+%endif
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(usbutils)
+BuildRequires:  pkgconfig(device-node)
+BuildRequires:  pkgconfig(edbus)
+BuildRequires:  pkgconfig(libxml-2.0)
+BuildRequires:  pkgconfig(capi-base-common)
+BuildRequires:  systemd-devel
+BuildRequires: pkgconfig(systemd)
+BuildRequires: pkgconfig(sqlite3)
+Requires(preun): /usr/bin/systemctl
+Requires(post): sys-assert
+Requires(post): /usr/bin/systemctl
+Requires(post): /usr/bin/vconftool
+Requires(postun): /usr/bin/systemctl
+
+%description
+deviced
+
+%package deviced
+Summary:    deviced daemon
+Group:      main
+Requires:   %{name} = %{version}-%{release}
+
+%description deviced
+deviced daemon.
+
+%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)
+
+%package -n logd
+Summary: logd utils
+Group: Framework/system
+
+%description -n logd
+Utils for for logd
+
+%package -n liblogd
+Summary:       Activity logging API(Development)
+Group:         Development/Libraries
+
+%description -n liblogd
+logd library.
+
+%package -n liblogd-devel
+Summary:       Activity logging (Development)
+Summary:    SLP power manager client (devel)
+Group:         Development/Libraries
+
+%description -n liblogd-devel
+logd API library.
+
+%package -n liblogd-db
+Summary:       API to get activity data (Development)
+Group:         Development/Libraries
+
+%description -n liblogd-db
+logd-db library.
+
+%package -n liblogd-db-devel
+Summary:       API to get activity data (Development)
+Group:         Development/Libraries
+
+%description -n liblogd-db-devel
+logd-db API library.
+
+%prep
+%setup -q
+export CFLAGS+=" -DMICRO_DD"
+
+%if 0%{?sec_build_binary_debug_enable}
+export CFLAGS+=" -DTIZEN_DEBUG_ENABLE"
+%endif
+
+%if 0%{?tizen_build_binary_release_type_eng}
+export CFLAGS+=" -DTIZEN_ENGINEER_MODE"
+%define ENGINEER_MODE 1
+%else
+%define ENGINEER_MODE 0
+%endif
+
+%ifarch %{arm}
+%define ARCH arm
+%else
+%define ARCH emulator
+%endif
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DARCH=%{ARCH}
+
+%build
+cp %{SOURCE1001} .
+cp %{SOURCE1002} .
+cp %{SOURCE1003} .
+cp %{SOURCE1004} .
+
+make
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants
+mkdir -p %{buildroot}%{_libdir}/systemd/system/graphical.target.wants
+mkdir -p %{buildroot}%{_libdir}/systemd/system/shutdown.target.wants
+install -m 0644 %{SOURCE1} %{buildroot}%{_libdir}/systemd/system/deviced.service
+install -m 0644 %{SOURCE2} %{buildroot}%{_libdir}/systemd/system/zbooting-done.service
+install -m 0644 %{SOURCE3} %{buildroot}%{_libdir}/systemd/system/shutdown-notify.service
+install -m 0644 %{SOURCE4} %{buildroot}%{_libdir}/systemd/system/deviced-pre.service
+install -m 0644 %{SOURCE5} %{buildroot}%{_libdir}/systemd/system/devicectl-start@.service
+install -m 0644 %{SOURCE6} %{buildroot}%{_libdir}/systemd/system/devicectl-stop@.service
+ln -s ../deviced.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/deviced.service
+# Temporary symlink
+ln -s deviced.service %{buildroot}%{_libdir}/systemd/system/system-server.service
+ln -s ../zbooting-done.service %{buildroot}%{_libdir}/systemd/system/graphical.target.wants/zbooting-done.service
+ln -s ../shutdown-notify.service %{buildroot}%{_libdir}/systemd/system/shutdown.target.wants/shutdown-notify.service
+ln -s ../devicectl-stop@.service %{buildroot}%{_libdir}/systemd/system/shutdown.target.wants/devicectl-stop@display.service
+mkdir -p %{buildroot}%{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/
+ln -s %{_libdir}/systemd/system/deviced.service %{buildroot}%{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/
+
+mkdir -p %{buildroot}%{_datadir}/license
+cp LICENSE.Apache-2.0 %{buildroot}/usr/share/license/%{name}
+cp LICENSE.Apache-2.0 %{buildroot}/usr/share/license/libdeviced
+
+%post
+#memory type vconf key init
+vconftool set -t int memory/sysman/usbhost_status -1 -i -s system::vconf_system
+vconftool set -t int memory/sysman/charger_status 0 -i -s system::vconf_system
+vconftool set -t int memory/sysman/charge_now 0 -i -s system::vconf_system
+vconftool set -t int memory/sysman/battery_status_low -1 -i -s system::vconf_system
+vconftool set -t int memory/sysman/battery_capacity -1 -i -s system::vconf_system
+vconftool set -t int memory/sysman/usb_status -1 -i -s system::vconf_system
+vconftool set -t int memory/sysman/factory_mode 0 -i -s system::vconf_system
+vconftool set -t int memory/sysman/stime_changed 0 -i -s system::vconf_system
+vconftool set -t int memory/sysman/power_off 0 -u 5000 -i -f -s system::vconf_system
+vconftool set -t int memory/deviced/boot_power_on 0 -u 5000 -i -f -s system::vconf_system
+vconftool set -t int memory/sysman/battery_level_status -1 -i -s system::vconf_system
+
+#db type vconf key init
+vconftool set -t bool db/private/deviced/lcd_brightness_init 0 -i -s system::vconf_system
+
+vconftool set -t int memory/pm/state 0 -i -g 5000 -s system::vconf_system
+vconftool set -t int memory/pm/camera_status 0 -i -s system::vconf_system
+vconftool set -t int memory/pm/battery_timetofull -1 -i -s system::vconf_system
+vconftool set -t int memory/pm/battery_timetoempty -1 -i -s system::vconf_system
+vconftool set -t int memory/pm/sip_status 0 -i -g 5000 -s system::vconf_system
+vconftool set -t int memory/pm/custom_brightness_status 0 -i -g 5000 -s system::vconf_system
+vconftool set -t bool memory/pm/brt_changed_lpm 0 -i -s system::vconf_system
+vconftool set -t int memory/pm/current_brt 60 -i -g 5000 -s system::vconf_system
+vconftool set -t int memory/pm/lcdoff_source 0 -i -g 5000 -s system::vconf_system
+vconftool set -t int memory/pm/key_ignore 0 -i -g 5000 -s system::vconf_system
+
+#USB client
+vconftool set -t int memory/usb/cur_mode "0" -u 0 -i -s system::vconf_system
+vconftool set -t int db/usb/sel_mode "1" -s system::vconf_system
+vconftool set -t int db/private/usb/usb_control "1" -u 0 -i -s system::vconf_system
+vconftool set -t int memory/private/usb/conf_enabled "0" -u 0 -i -s system::vconf_system
+
+systemctl daemon-reload
+if [ $1 == 1 ]; then
+    systemctl restart deviced.service
+    systemctl restart zbooting-done.service
+fi
+
+%preun
+if [ $1 == 0 ]; then
+    systemctl stop deviced.service
+    systemctl stop zbooting-done.service
+fi
+
+%postun
+systemctl daemon-reload
+
+%files -n deviced
+%{_bindir}/deviced-pre.sh
+%{_bindir}/deviced
+%{_bindir}/devicectl
+%{_bindir}/deviced-auto-test
+%{_libdir}/systemd/system/deviced.service
+%{_libdir}/systemd/system/multi-user.target.wants/deviced.service
+%{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/deviced.service
+# Temporary symlink service
+%{_libdir}/systemd/system/system-server.service
+%{_libdir}/systemd/system/zbooting-done.service
+%{_libdir}/systemd/system/graphical.target.wants/zbooting-done.service
+%{_libdir}/systemd/system/shutdown-notify.service
+%{_libdir}/systemd/system/shutdown.target.wants/shutdown-notify.service
+%{_libdir}/systemd/system/deviced-pre.service
+%{_libdir}/systemd/system/devicectl-stop@.service
+%{_libdir}/systemd/system/devicectl-start@.service
+%{_libdir}/systemd/system/shutdown.target.wants/devicectl-stop@display.service
+%{_datadir}/license/%{name}
+%{_datadir}/deviced/usb-configurations/*
+%{_sysconfdir}/smack/accesses2.d/deviced.rule
+
+%manifest deviced.manifest
+%attr(110,root,root) /opt/etc/dump.d/module.d/dump_pm.sh
+%{_sysconfdir}/deviced/display.conf
+%{_sysconfdir}/deviced/mmc.conf
+%{_sysconfdir}/deviced/battery.conf
+%{_sysconfdir}/deviced/pmqos.conf
+
+%attr(750,root,root)%{_bindir}/start_dr.sh
+%if %ENGINEER_MODE
+%attr(750,root,root) %{_bindir}/set_usb_debug.sh
+%attr(750,root,root) %{_bindir}/direct_set_debug.sh
+%endif
+
+%files -n libdeviced
+%defattr(-,root,root,-)
+%{_libdir}/libdeviced.so.*
+%{_datadir}/license/libdeviced
+%manifest libdeviced.manifest
+
+%files -n libdeviced-devel
+%defattr(-,root,root,-)
+%{_includedir}/deviced/*.h
+%{_libdir}/libdeviced.so
+%{_libdir}/pkgconfig/deviced.pc
+
+%files -n logd
+
+%files -n liblogd
+%manifest liblogd.manifest
+
+%files -n liblogd-devel
+
+%files -n liblogd-db
+%manifest liblogd-db.manifest
+
+%files -n liblogd-db-devel
diff --git a/packaging/libdeviced.manifest b/packaging/libdeviced.manifest
new file mode 100644 (file)
index 0000000..3256181
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+<request>
+       <domain name="_"/>
+</request>
+</manifest>
diff --git a/packaging/liblogd-db.manifest b/packaging/liblogd-db.manifest
new file mode 100644 (file)
index 0000000..0a38a69
--- /dev/null
@@ -0,0 +1,11 @@
+<manifest>
+       <define>
+               <domain name="liblogd-db"/>
+       </define>
+       <request>
+               <domain name="liblogd-db"/>
+       </request>
+       <assign>
+               <filesystem path="/usr/lib/liblogd-db.so" label="_" exec_label="none"/>
+       </assign>
+</manifest>
diff --git a/packaging/liblogd.manifest b/packaging/liblogd.manifest
new file mode 100644 (file)
index 0000000..194afaf
--- /dev/null
@@ -0,0 +1,11 @@
+<manifest>
+       <define>
+               <domain name="liblogd"/>
+       </define>
+       <request>
+               <domain name="liblogd"/>
+       </request>
+       <assign>
+               <filesystem path="/usr/lib/liblogd.so" label="_" exec_label="none"/>
+       </assign>
+</manifest>
diff --git a/packaging/shutdown-notify.service b/packaging/shutdown-notify.service
new file mode 100644 (file)
index 0000000..4d274c9
--- /dev/null
@@ -0,0 +1,9 @@
+[Unit]
+Description=Broadcasing Shutdown
+DefaultDependencies=no
+
+[Service]
+ExecStart=/usr/bin/dbus-send --type=signal --system --dest=org.tizen.system.deviced.PowerOff /Org/Tizen/System/DeviceD/PowerOff org.tizen.system.deviced.PowerOff.ChangeState int32:2
+
+[Install]
+WantedBy=shutdown.target
diff --git a/packaging/zbooting-done.service b/packaging/zbooting-done.service
new file mode 100644 (file)
index 0000000..a7e7017
--- /dev/null
@@ -0,0 +1,10 @@
+[Unit]
+Description=Booting Done
+After=default.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/dbus-send --type=signal --system /Org/Tizen/System/DeviceD/Core org.tizen.system.deviced.core.BootingDone
+
+[Install]
+WantedBy=graphical.target
diff --git a/scripts/deviced-pre.sh b/scripts/deviced-pre.sh
new file mode 100755 (executable)
index 0000000..85850be
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+DEVICED_ENV_F=/run/deviced/deviced_env
+[ -e $DEVICED_ENV_F ] && /bin/rm -f $DEVICED_ENV_F
+[ -d ${DEVICED_ENV_F%/*} ] || /bin/mkdir -p ${DEVICED_ENV_F%/*}
+
+echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib" >> $DEVICED_ENV_F
+
+DEV_INPUT=
+TOUCHSCREEN=400
+TOUCHKEY=200
+
+for file in /sys/class/input/event*; do
+        if [ -e $file ]; then
+                dev_keytype=`/bin/cat ${file}/device/capabilities/key`
+                if [ "$dev_keytype" != 0 ]; then
+                        DEV_INPUT=$DEV_INPUT:/dev/input/${file#/sys/class/input/}
+                        var=${dev_keytype%%' '*}
+                        if [ $var == $TOUCHSCREEN  ]; then
+                                DEV_TOUCHSCREEN=/sys/class/input/${file#/sys/class/input/}/device/enabled
+                                echo ${var} ${file#/sys/class/input/}
+                        fi
+                        if [ $var == $TOUCHKEY ]; then
+                                dev_ledtype=`/bin/cat ${file}/device/capabilities/led`
+                                if [ "$dev_ledtype" != 0 ]; then
+                                        DEV_TOUCHKEY=/sys/class/input/${file#/sys/class/input/}/device/enabled
+                                        echo ${var} ${file#/sys/class/input/}
+                                fi
+                        fi
+                fi
+        fi
+done
+
+for file in /sys/class/lcd/*; do
+        if [ -e $file ]; then
+               hbm_state=`/bin/cat ${file}/device/hbm`
+               if [ "$hbm_state" != 0 ]; then
+                       HBM_NODE=${file}/device/hbm
+               fi
+               alpm_state=`/bin/cat ${file}/device/alpm`
+               if [ "$alpm_state" != 0 ]; then
+                       ALPM_NODE=${file}/device/alpm
+               fi
+       fi
+done
+
+echo "PM_INPUT=$DEV_INPUT" >> $DEVICED_ENV_F
+echo "PM_TOUCHSCREEN=$DEV_TOUCHSCREEN" >> $DEVICED_ENV_F
+echo "PM_TOUCHKEY=$DEV_TOUCHKEY" >> $DEVICED_ENV_F
+echo "HBM_NODE=$HBM_NODE" >> $DEVICED_ENV_F
+echo "ALPM_NODE=$ALPM_NODE" >> $DEVICED_ENV_F
+echo "PM_TO_NORMAL=30000" >> $DEVICED_ENV_F
+echo "PM_TO_LCDDIM=5000" >> $DEVICED_ENV_F
+echo "PM_SYS_DIMBRT=0" >> $DEVICED_ENV_F
+
diff --git a/scripts/direct_set_debug.sh b/scripts/direct_set_debug.sh
new file mode 100755 (executable)
index 0000000..396a768
--- /dev/null
@@ -0,0 +1,141 @@
+#!/bin/sh
+
+VERSION=
+
+check_driver_version() {
+       if [ -f /sys/class/usb_mode/version ]
+       then
+               VERSION=`/bin/cat /sys/class/usb_mode/version`
+       else
+               VERSION="0.0"
+       fi
+}
+
+load_usb_gadget_1_0() {
+       echo 0 > /sys/class/usb_mode/usb0/enable
+       echo 04e8 > /sys/class/usb_mode/usb0/idVendor
+       echo $1 > /sys/class/usb_mode/usb0/idProduct
+       echo $2 > /sys/class/usb_mode/usb0/functions
+       echo 239 > /sys/class/usb_mode/usb0/bDeviceClass
+       echo 2 > /sys/class/usb_mode/usb0/bDeviceSubClass
+       echo 1 > /sys/class/usb_mode/usb0/bDeviceProtocol
+       echo 1 > /sys/class/usb_mode/usb0/enable
+}
+
+load_usb_gadget_1_1() {
+       echo 0 > /sys/class/usb_mode/usb0/enable
+       echo 04e8 > /sys/class/usb_mode/usb0/idVendor
+       echo $1 > /sys/class/usb_mode/usb0/idProduct
+       echo $2 > /sys/class/usb_mode/usb0/funcs_fconf
+       echo $3 > /sys/class/usb_mode/usb0/funcs_sconf
+       echo 239 > /sys/class/usb_mode/usb0/bDeviceClass
+       echo 2 > /sys/class/usb_mode/usb0/bDeviceSubClass
+       echo 1 > /sys/class/usb_mode/usb0/bDeviceProtocol
+       echo 1 > /sys/class/usb_mode/usb0/enable
+}
+
+unload_usb_gadget_1() {
+       echo 0 > /sys/class/usb_mode/usb0/enable
+}
+
+sdb_set() {
+       case "$VERSION" in
+       "1.0")
+               load_usb_gadget_1_0 "6860" "mtp,acm,sdb"
+               ;;
+       "1.1")
+               load_usb_gadget_1_1 "6860" "mtp" "mtp,acm,sdb"
+               ;;
+       *)
+               echo "USB driver version $VERSION is not supported"
+               return
+               ;;
+       esac
+
+       /usr/bin/systemctl start sdbd.service
+       echo "SDB enabled"
+}
+
+ssh_set() {
+       case "$VERSION" in
+       "1.0")
+               load_usb_gadget_1_0 "6864" "rndis"
+               ;;
+       "1.1")
+               load_usb_gadget_1_1 "6864" "rndis" " "
+               ;;
+       *)
+               echo "USB driver version $VERSION is not supported"
+               return
+               ;;
+       esac
+
+       /sbin/ifconfig usb0 192.168.129.3 up
+       /sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0
+       /usr/bin/systemctl start sshd.service
+       echo "SSH enabled"
+}
+
+usb_unset() {
+       case "$VERSION" in
+       "1.0" | "1.1")
+               unload_usb_gadget_1
+               ;;
+       *)
+               echo "USB driver version $VERSION is not supported"
+               return
+               ;;
+       esac
+}
+
+sdb_unset() {
+       usb_unset
+       /usr/bin/systemctl stop sdbd.service
+       echo "SDB disabled"
+}
+
+ssh_unset() {
+       usb_unset
+       /sbin/ifconfig usb0 down
+       /usr/bin/systemctl stop sshd.service
+       echo "SSH disabled"
+}
+
+show_options() {
+       echo "direct_set_debug.sh: usage:"
+       echo "    --help       This message"
+       echo "    --sdb-set    Load sdb without usb-manager"
+       echo "    --sdb-unset  Unload sdb without usb-manager"
+       echo "    --ssh-set    Load ssh without usb-manager"
+       echo "    --ssh-unset  Unload ssh without usb-manager"
+}
+
+check_driver_version
+
+case "$1" in
+"--sdb-set")
+       sdb_set
+       /usr/bin/set_usb_debug.sh --mtp-sdb &
+       ;;
+
+"--ssh-set")
+       ssh_set
+       /usr/bin/set_usb_debug.sh --rndis &
+       ;;
+
+"--sdb-unset")
+       sdb_unset
+       ;;
+
+"--ssh-unset")
+       ssh_unset
+       ;;
+
+"--help")
+       show_options
+       ;;
+
+*)
+       echo "Wrong parameters. Please use option --help to check options "
+       ;;
+esac
diff --git a/scripts/dump_pm.sh b/scripts/dump_pm.sh
new file mode 100644 (file)
index 0000000..a43189f
--- /dev/null
@@ -0,0 +1,21 @@
+#--------------------------------------
+#   power-manager
+#--------------------------------------
+/usr/bin/devicectl display savelog
+PM_DEBUG=$1/power-manager
+PM_KMG=sleep_wakeup.log
+PM_KMG_SLEEP=/sys/kernel/debug/sleep_history
+PM_KMG_WAKEUP=/sys/kernel/debug/wakeup_sources
+/bin/mkdir -p ${PM_DEBUG}
+/bin/cp -rf /opt/var/log/pm_state.log ${PM_DEBUG}
+
+if [ -e $PM_KMG_SLEEP ];
+then
+/bin/cat ${PM_KMG_SLEEP} > ${PM_DEBUG}/${PM_KMG}
+fi
+
+if [ -e $PM_KMG_WAKEUP ];
+then
+/bin/cat ${PM_KMG_WAKEUP} >> ${PM_DEBUG}/${PM_KMG}
+fi
+
diff --git a/scripts/mmc-smack-label b/scripts/mmc-smack-label
new file mode 100755 (executable)
index 0000000..8bf29cf
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/bash
+MOUNT_DIRECTORY=$1
+/usr/bin/find $MOUNT_DIRECTORY -type d | /usr/bin/xargs /usr/bin/chsmack -a 'system::ext_storage' -e ''
+/usr/bin/find $MOUNT_DIRECTORY -type f | /usr/bin/xargs /usr/bin/chsmack -a 'system::ext_storage'
+/usr/bin/find $MOUNT_DIRECTORY | /usr/bin/xargs /bin/chown app:app
diff --git a/scripts/movi_format.sh b/scripts/movi_format.sh
new file mode 100755 (executable)
index 0000000..8946fbe
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+/sbin/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
+
+/bin/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/scripts/set_usb_debug.sh b/scripts/set_usb_debug.sh
new file mode 100755 (executable)
index 0000000..288ceea
--- /dev/null
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+case "$1" in
+
+"--debug")
+       /usr/bin/vconftool set -t int db/usb/sel_mode "2" -f
+       /usr/bin/vconftool set -t bool db/setting/debug_mode "1" -f
+       /usr/bin/vconftool set -t int db/setting/lcd_backlight_normal "600" -f
+       echo "The backlight time of the display is set to 10 minutes"
+       /usr/bin/vconftool set -t bool db/setting/brightness_automatic "1" -f
+       echo "Brightness is set automatic"
+       ;;
+
+"--mtp" | "--sshoff" | "--unset")
+       /usr/bin/vconftool set -t int db/usb/sel_mode "1" -f
+       /usr/bin/vconftool set -t bool db/setting/debug_mode "0" -f
+       ;;
+
+"--mtp-sdb" | "--set")
+       /usr/bin/vconftool set -t int db/usb/sel_mode "2" -f
+       /usr/bin/vconftool set -t bool db/setting/debug_mode "1" -f
+       ;;
+
+"--mtp-sdb-diag")
+       /usr/bin/vconftool set -t int db/usb/sel_mode "3" -f
+       /usr/bin/vconftool set -t bool db/setting/debug_mode "1" -f
+       ;;
+
+"--rndis-tethering")
+       /usr/bin/vconftool set -t int db/usb/sel_mode "4" -f
+       ;;
+
+"--rndis" | "--sshon")
+       /usr/bin/vconftool set -t int db/usb/sel_mode "5" -f
+       /usr/bin/vconftool set -t bool db/setting/debug_mode "0" -f
+       ;;
+
+"--rndis-sdb")
+       /usr/bin/vconftool set -t int db/usb/sel_mode "6" -f
+       /usr/bin/vconftool set -t bool db/setting/debug_mode "1" -f
+       ;;
+
+"--rndis-diag")
+       /usr/bin/vconftool set -t int db/usb/sel_mode "8" -f
+       /usr/bin/vconftool set -t bool db/setting/debug_mode "0" -f
+       ;;
+
+"--help")
+       echo "set_usb_debug.sh: usage:"
+       echo "    --help           This message "
+       echo "    --set            Load Debug mode"
+       echo "    --unset          Unload Debug mode"
+       echo "    --debug          Load debug mode with 10 minutes backlight time"
+       echo "                     and automatic brightness"
+       echo "    --sshon          Load SSH mode"
+       echo "    --sshoff         Unload SSH mode"
+       echo "    --mtp            Load mtp only"
+       echo "    --mtp-sdb        Load mtp and sdb"
+       echo "    --mtp-sdb-diag   Load mtp, sdb, and diag"
+       echo "                     If diag is not supported, mtp is loaded"
+       echo "    --rndis          Load rndis only"
+       echo "    --rndis-diag     Load rndis and diag"
+       echo "                     If diag is not supported, mtp is loaded"
+       ;;
+
+*)
+       echo "Wrong parameters. Please use option --help to check options "
+       ;;
+
+esac
diff --git a/scripts/start_dr.sh b/scripts/start_dr.sh
new file mode 100755 (executable)
index 0000000..8a5c958
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# start data-router
+if (/bin/ps -e | /bin/grep data-router); then
+  echo "Already DR activated. No need launch DR"
+else
+  echo "Launch DR"
+  /usr/bin/data-router &
+fi
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..c17e8b8
--- /dev/null
@@ -0,0 +1,3 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+ADD_SUBDIRECTORY(shared)
diff --git a/src/apps/apps.c b/src/apps/apps.c
new file mode 100755 (executable)
index 0000000..1560d1e
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * deviced
+ *
+ * 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 <vconf.h>
+#include "core/log.h"
+#include "apps.h"
+#include "core/devices.h"
+#include "core/list.h"
+
+static dd_list *apps_head = NULL;
+
+void add_apps(const struct apps_ops *dev)
+{
+       _I("add %s", dev->name);
+       DD_LIST_APPEND(apps_head, (void*)dev);
+}
+
+void remove_apps(const struct apps_ops *dev)
+{
+       DD_LIST_REMOVE(apps_head, (void*)dev);
+}
+
+static void apps_init(void *data)
+{
+       const struct apps_ops*dev;
+       dd_list *elem;
+       struct apps_data *input_data;
+       static int initialized =0;
+
+       if (!initialized) {
+               initialized = 1;
+               return;
+       }
+
+       input_data = (struct apps_data *)data;
+       if (input_data == NULL || input_data->name == NULL)
+               return;
+
+       DD_LIST_FOREACH(apps_head, elem, dev) {
+               if (!strncmp(dev->name, (char *)input_data->name, strlen(dev->name))) {
+                       if (dev->launch)
+                               dev->launch(data);
+                       break;
+               }
+       }
+}
+
+static void apps_exit(void *data)
+{
+       const struct apps_ops*dev;
+       dd_list *elem;
+       struct apps_data *input_data;
+
+       input_data = (struct apps_data *)data;
+       if (input_data == NULL || input_data->name == NULL)
+               return;
+
+       DD_LIST_FOREACH(apps_head, elem, dev) {
+               if (!strncmp(dev->name, (char *)input_data->name, strlen(dev->name))) {
+                       if (dev->terminate)
+                               dev->terminate(data);
+                       break;
+               }
+       }
+}
+
+static const struct device_ops apps_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "apps",
+       .init     = apps_init,
+       .exit     = apps_exit,
+};
+
+DEVICE_OPS_REGISTER(&apps_device_ops)
diff --git a/src/apps/apps.h b/src/apps/apps.h
new file mode 100755 (executable)
index 0000000..8dd93d9
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * deviced
+ *
+ * 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 __APPS_H__
+#define __APPS_H__
+
+
+#include "core/edbus-handler.h"
+#include "core/common.h"
+#include "core/data.h"
+
+#define APPS_OPS_REGISTER(dev) \
+static void __CONSTRUCTOR__ module_init(void)  \
+{      \
+       add_apps(dev);  \
+}      \
+static void __DESTRUCTOR__ module_exit(void)   \
+{      \
+       remove_apps(dev);       \
+}
+
+struct apps_data {
+       const char *name;
+       void *data;
+};
+
+struct apps_ops {
+       const char *name;
+       void (*init) (void);
+       void (*exit) (void);
+       int (*launch)(void *data);
+       int (*terminate)(void *data);
+};
+
+void add_apps(const struct apps_ops *dev);
+void remove_apps(const struct apps_ops *dev);
+
+#endif /* __APPS_H__ */
+
diff --git a/src/apps/launch.c b/src/apps/launch.c
new file mode 100644 (file)
index 0000000..6b25ddd
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * deviced
+ *
+ * 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 <vconf.h>
+#include "core/log.h"
+#include "core/common.h"
+#include "apps.h"
+#include "core/edbus-handler.h"
+
+#define PWLOCK_NAME    "pwlock"
+#define CRADLE_NAME    "desk-dock"
+
+#define RETRY_MAX 5
+
+struct popup_data {
+       char *name;
+       char *value;
+};
+
+static pid_t cradle_pid = 0;
+
+static int launch_app_pwlock(void);
+static int launch_app_cradle(void);
+
+void get_pwlock_app_pid(void *data, DBusMessage *msg, DBusError *err)
+{
+       DBusError r_err;
+       int ret;
+       pid_t pid;
+
+       if (!msg) {
+               _E("Cannot get pid of pwlock app");
+               ret = launch_app_pwlock();
+               if (ret < 0)
+                       _E("Failed to launch pwlock app(%d)", ret);
+               return;
+       }
+
+       dbus_error_init(&r_err);
+       ret = dbus_message_get_args(msg, &r_err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message [%s:%s]", r_err.name, r_err.message);
+               dbus_error_free(&r_err);
+               return;
+       }
+
+       _I("Pid of cradle app is (%d)", pid);
+}
+
+static int launch_app_pwlock(void)
+{
+       int i, ret;
+       char *pa[2];
+
+       pa[0] = "after_bootup";
+       pa[1] = "1";
+
+       i = 0;
+       do {
+               ret = dbus_method_async_with_reply(POPUP_BUS_NAME,
+                               POPUP_PATH_APP, POPUP_IFACE_APP,
+                               "PWLockAppLaunch", "ss", pa,
+                               get_pwlock_app_pid, -1, NULL);
+               if (ret < 0)
+                       _E("Failed to request launching cradle app(%d), retry(%d)", ret, i);
+               else
+                       break;
+       } while(i++ < RETRY_MAX);
+
+       return ret;
+}
+
+void get_cradle_app_pid(void *data, DBusMessage *msg, DBusError *err)
+{
+       DBusError r_err;
+       int ret;
+       pid_t pid;
+
+       if (!msg) {
+               _E("Cannot get pid of cradle app");
+               ret = launch_app_cradle();
+               if (ret < 0)
+                       _E("Failed to launch cradle app (%d)", ret);
+               return;
+       }
+
+       dbus_error_init(&r_err);
+       ret = dbus_message_get_args(msg, &r_err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message [%s:%s]", r_err.name, r_err.message);
+               dbus_error_free(&r_err);
+               return;
+       }
+
+       cradle_pid = pid;
+       _I("Pid of cradle app is (%d)", cradle_pid);
+}
+
+static int launch_app_cradle(void)
+{
+       int i, ret;
+
+       i = 0;
+       do {
+               ret = dbus_method_async_with_reply(POPUP_BUS_NAME,
+                               POPUP_PATH_APP, POPUP_IFACE_APP,
+                               "CradleAppLaunch", NULL, NULL,
+                               get_cradle_app_pid, -1, NULL);
+               if (ret < 0)
+                       _E("Failed to request launching cradle app(%d), retry(%d)", ret, i);
+               else
+                       break;
+       } while(i++ < RETRY_MAX);
+
+       return ret;
+}
+
+void get_terminate_app_result(void *data, DBusMessage *msg, DBusError *err)
+{
+       DBusError r_err;
+       int ret, result;
+
+       if (!msg) {
+               _E("Cannot get result of terminating app");
+               return;
+       }
+
+       dbus_error_init(&r_err);
+       ret = dbus_message_get_args(msg, &r_err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message [%s:%s]", r_err.name, r_err.message);
+               dbus_error_free(&r_err);
+               return;
+       }
+
+       _I("The result of terminating app is (%d)", result);
+}
+
+static int terminate_app_by_pid(pid_t pid)
+{
+       int i, ret;
+       char *pa[1];
+       char cPid[32];
+
+       if (pid <= 0)
+               return -EINVAL;
+
+       snprintf(cPid, sizeof(cPid), "%d", pid);
+       pa[0] = cPid;
+
+       i = 0;
+       do {
+               ret = dbus_method_async_with_reply(POPUP_BUS_NAME,
+                               POPUP_PATH_APP, POPUP_IFACE_APP,
+                               "AppTerminateByPid", "i", pa,
+                               get_terminate_app_result, -1, NULL);
+               if (ret < 0)
+                       _E("Failed to request terminating app(%d), retry(%d)", ret, i);
+               else
+                       break;
+       } while(i++ < RETRY_MAX);
+
+       return ret;
+}
+
+static int launch_app(void *data)
+{
+       int ret = 0;
+       struct popup_data *params;
+
+       if (!data)
+               return -ENOMEM;
+       params = (struct popup_data *)data;
+
+       _I("%s", params->value);
+       if (!strncmp(PWLOCK_NAME, params->value, strlen(params->value)))
+               ret = launch_app_pwlock();
+       else if (!strncmp(CRADLE_NAME, params->value, strlen(params->value)))
+               ret = launch_app_cradle();
+       return ret;
+}
+
+
+static int terminate_app(void *data)
+{
+       struct popup_data *params;
+
+       if (!data || cradle_pid == 0)
+               return -ENOMEM;
+       params = (struct popup_data *)data;
+       _I("%s", params->value);
+       if (!strncmp(CRADLE_NAME, params->value, strlen(params->value))) {
+               if (terminate_app_by_pid(cradle_pid) < 0)
+                       _E("Failed to terminate app (%d)", cradle_pid);
+               cradle_pid = 0;
+       }
+       return 0;
+}
+
+
+static const struct apps_ops launch_ops = {
+       .name           = "launch-app",
+       .launch         = launch_app,
+       .terminate      = terminate_app,
+};
+
+APPS_OPS_REGISTER(&launch_ops)
diff --git a/src/apps/lowbat.c b/src/apps/lowbat.c
new file mode 100644 (file)
index 0000000..b90a7ff
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * deviced
+ *
+ * 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 "core/log.h"
+#include "core/common.h"
+#include "apps.h"
+#include "core/edbus-handler.h"
+
+#define LOWBAT_WARNING  "warning"
+#define LOWBAT_CRITICAL  "critical"
+#define LOWBAT_POWEROFF "poweroff"
+
+struct popup_data {
+       char *name;
+       char *key;
+       char *value;
+};
+
+static int lowbat_pid = 0;
+
+static void lowbat_cb(void *data, DBusMessage *msg, DBusError *unused)
+{
+       DBusError err;
+       int ret, id;
+
+       if (!msg)
+               return;
+
+       dbus_error_init(&err);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &id, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               return;
+       }
+
+       lowbat_pid = id;
+       _I("Created popup : %d", lowbat_pid);
+}
+
+static int lowbat_launch(void *data)
+{
+       char *param[2];
+       struct popup_data * key_data = (struct popup_data *)data;
+       int ret;
+
+       param[0] = key_data->key;
+       param[1] = key_data->value;
+
+       ret = dbus_method_async_with_reply(POPUP_BUS_NAME,
+                       POPUP_PATH_LOWBAT,
+                       POPUP_INTERFACE_LOWBAT,
+                       POPUP_METHOD_LAUNCH,
+                       "ss", param, lowbat_cb, -1, NULL);
+
+       if (strncmp(key_data->value, LOWBAT_WARNING, strlen(LOWBAT_WARNING)) &&
+           strncmp(key_data->value, LOWBAT_CRITICAL, strlen(LOWBAT_CRITICAL)) &&
+           strncmp(key_data->value, LOWBAT_POWEROFF, strlen(LOWBAT_POWEROFF)))
+               _I("%s(%d)",key_data->name, ret);
+
+       return ret;
+}
+
+static int lowbat_terminate(void *data)
+{
+       int pid;
+       int ret;
+       char *param[1];
+       char buf[PATH_MAX];
+
+       printf("\n");
+
+       if (lowbat_pid <= 0)
+               return 0;
+
+       snprintf(buf, sizeof(buf), "%d", lowbat_pid);
+       param[0] = buf;
+
+       ret = dbus_method_sync(POPUP_BUS_NAME,
+                       POPUP_PATH_APP,
+                       POPUP_IFACE_APP,
+                       POPUP_METHOD_TERMINATE, "i", param);
+       if (ret < 0)
+               _E("FAIL: dbus_method_sync(): %d %d", ret, param);
+       lowbat_pid = 0;
+       return 0;
+}
+
+
+static const struct apps_ops lowbat_ops = {
+       .name   = "lowbat-syspopup",
+       .launch = lowbat_launch,
+       .terminate = lowbat_terminate,
+};
+
+APPS_OPS_REGISTER(&lowbat_ops)
diff --git a/src/apps/lowmem.c b/src/apps/lowmem.c
new file mode 100644 (file)
index 0000000..50755f0
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * deviced
+ *
+ * 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 "core/log.h"
+#include "core/common.h"
+#include "apps.h"
+#include "core/edbus-handler.h"
+
+struct popup_data {
+       char *name;
+       char *key;
+       char *value;
+};
+
+static int lowmem_launch(void *data)
+{
+       char *param[2];
+       struct popup_data *params = (struct popup_data *)data;
+
+       param[0] = params->key;
+       param[1] = params->value;
+
+       return dbus_method_sync(POPUP_BUS_NAME,
+                       POPUP_PATH_LOWMEM,
+                       POPUP_INTERFACE_LOWMEM,
+                       POPUP_METHOD_LAUNCH, "ss", param);
+}
+
+
+static const struct apps_ops lowmem_ops = {
+       .name   = "lowmem-syspopup",
+       .launch = lowmem_launch,
+};
+
+APPS_OPS_REGISTER(&lowmem_ops)
diff --git a/src/apps/mmc.c b/src/apps/mmc.c
new file mode 100644 (file)
index 0000000..6698e57
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * deviced
+ *
+ * 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 "core/log.h"
+#include "core/common.h"
+#include "apps.h"
+#include "core/edbus-handler.h"
+
+struct popup_data {
+       char *name;
+       char *key;
+       char *value;
+};
+
+static int mmc_launch(void *data)
+{
+       char *param[2];
+       struct popup_data *params = (struct popup_data *)data;
+
+       param[0] = params->key;
+       param[1] = params->value;
+
+       return dbus_method_sync(POPUP_BUS_NAME,
+                       POPUP_PATH_MMC,
+                       POPUP_INTERFACE_MMC,
+                       POPUP_METHOD_LAUNCH, "ss", param);
+}
+
+
+static const struct apps_ops mmc_ops = {
+       .name   = "mmc-syspopup",
+       .launch = mmc_launch,
+};
+
+APPS_OPS_REGISTER(&mmc_ops)
diff --git a/src/apps/poweroff.c b/src/apps/poweroff.c
new file mode 100644 (file)
index 0000000..3c9583b
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * deviced
+ *
+ * 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 "core/log.h"
+#include "core/common.h"
+#include "apps.h"
+#include "core/edbus-handler.h"
+#include "core/launch.h"
+
+#ifdef MICRO_DD
+#define POWEROFF_POPUP_BUS_NAME POPUP_BUS_NAME".Poweroff"
+#else
+#define POWEROFF_POPUP_BUS_NAME POPUP_BUS_NAME
+#endif
+
+static int poweroff_launch(void *data)
+{
+       return dbus_method_async(POWEROFF_POPUP_BUS_NAME,
+                       POPUP_PATH_POWEROFF,
+                       POPUP_INTERFACE_POWEROFF,
+                       POPUP_METHOD_LAUNCH, NULL, NULL);
+}
+
+
+static const struct apps_ops poweroff_ops = {
+       .name   = "poweroff-syspopup",
+       .launch = poweroff_launch,
+};
+
+APPS_OPS_REGISTER(&poweroff_ops)
diff --git a/src/apps/system.c b/src/apps/system.c
new file mode 100644 (file)
index 0000000..99cc2c8
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * deviced
+ *
+ * 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 "core/log.h"
+#include "core/common.h"
+#include "apps.h"
+#include "core/edbus-handler.h"
+
+#define METHOD_STORAGE_WARNING  "UsbotgWarningPopupLaunch"
+#define METHOD_WATCHDOG         "WatchdogPopupLaunch"
+#define METHOD_RECOVERY         "RecoveryPopupLaunch"
+
+struct popup_data {
+       char *name;
+       char *method;
+       char *key1;
+       char *value1;
+       char *key2;
+       char *value2;
+};
+
+static int system_launch_single_param(struct popup_data * key_data)
+{
+       char *param[2];
+
+       param[0] = key_data->key1;
+       param[1] = key_data->value1;
+
+       return dbus_method_sync(POPUP_BUS_NAME,
+                       POPUP_PATH_SYSTEM,
+                       POPUP_INTERFACE_SYSTEM,
+                       key_data->method, "ss", param);
+}
+
+static int system_launch_double_param(struct popup_data * key_data)
+{
+       char *param[4];
+
+       param[0] = key_data->key1;
+       param[1] = key_data->value1;
+       param[2] = key_data->key2;
+       param[3] = key_data->key2;
+
+       return dbus_method_sync(POPUP_BUS_NAME,
+                       POPUP_PATH_SYSTEM,
+                       POPUP_INTERFACE_SYSTEM,
+                       key_data->method, "ssss", param);
+}
+
+static int system_launch(void *data)
+{
+       struct popup_data *key_data = (struct popup_data *)data;
+       if (!key_data || !(key_data->method))
+               return -EINVAL;
+
+       if (!strncmp(key_data->method, METHOD_STORAGE_WARNING, strlen(METHOD_STORAGE_WARNING))) {
+               return system_launch_single_param(key_data);
+       }
+
+       if (!strncmp(key_data->method, METHOD_RECOVERY, strlen(METHOD_RECOVERY))) {
+               return system_launch_single_param(key_data);
+       }
+
+       if (!strncmp(key_data->method, METHOD_WATCHDOG, strlen(METHOD_WATCHDOG))) {
+               return system_launch_double_param(key_data);
+       }
+       return -EINVAL;
+}
+
+static const struct apps_ops system_popup_ops = {
+       .name   = "system-syspopup",
+       .launch = system_launch,
+};
+
+APPS_OPS_REGISTER(&system_popup_ops)
diff --git a/src/apps/usb.c b/src/apps/usb.c
new file mode 100644 (file)
index 0000000..1a8f8c8
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * deviced
+ *
+ * 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 "core/log.h"
+#include "core/common.h"
+#include "apps.h"
+#include "core/edbus-handler.h"
+
+struct popup_data {
+       char *name;
+       char *key;
+       char *value;
+};
+
+static int usb_launch(void *data)
+{
+       char *param[2];
+       struct popup_data * key_data = (struct popup_data *)data;
+
+       param[0] = key_data->key;
+       param[1] = key_data->value;
+
+       return dbus_method_sync(POPUP_BUS_NAME,
+                       POPUP_PATH_USB,
+                       POPUP_INTERFACE_USB,
+                       POPUP_METHOD_LAUNCH, "ss", param);
+}
+
+
+static const struct apps_ops usb_popup_ops = {
+       .name   = "usb-syspopup",
+       .launch = usb_launch,
+};
+
+APPS_OPS_REGISTER(&usb_popup_ops)
diff --git a/src/apps/usbotg.c b/src/apps/usbotg.c
new file mode 100644 (file)
index 0000000..e39a002
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * deviced
+ *
+ * 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 "core/log.h"
+#include "core/common.h"
+#include "apps.h"
+#include "core/edbus-handler.h"
+
+#define METHOD_STORAGE_MOUNT    "StoragePopupLaunch"
+#define METHOD_CAMERA           "CameraPopupLaunch"
+#define METHOD_STORAGE_UNMOUNT  "StorageUnmountPopupLaunch"
+
+#define RETRY_MAX 5
+
+struct popup_data {
+       char *name;
+       char *method;
+       char *key1;
+       char *value1;
+       char *key2;
+       char *value2;
+};
+
+static int system_launch_single_param(struct popup_data * key_data)
+{
+       int ret, i;
+       char *param[2];
+
+       param[0] = key_data->key1;
+       param[1] = key_data->value1;
+
+       i = 0;
+       do {
+               ret = dbus_method_sync(POPUP_BUS_NAME,
+                               POPUP_PATH_USBOTG,
+                               POPUP_INTERFACE_USBOTG,
+                               key_data->method, "ss", param);
+               if (ret >= 0)
+                       return ret;
+               _E("Failed to launch popup (%d).. retry (%d)", ret, i);
+       } while (i++ < RETRY_MAX);
+
+       return ret;
+}
+
+static int system_launch_double_param(struct popup_data * key_data)
+{
+       int ret, i;
+       char *param[4];
+
+       param[0] = key_data->key1;
+       param[1] = key_data->value1;
+       param[2] = key_data->key2;
+       param[3] = key_data->value2;
+
+       i = 0;
+       do {
+               ret = dbus_method_sync(POPUP_BUS_NAME,
+                               POPUP_PATH_USBOTG,
+                               POPUP_INTERFACE_USBOTG,
+                               key_data->method, "ssss", param);
+               if (ret >= 0)
+                       return ret;
+               _E("Failed to launch popup (%d).. retry (%d)", ret, i);
+       } while (i++ < RETRY_MAX);
+
+       return ret;
+}
+
+static int system_launch(void *data)
+{
+       struct popup_data *key_data = (struct popup_data *)data;
+       if (!key_data || !(key_data->method))
+               return -EINVAL;
+
+       if (!strncmp(key_data->method, METHOD_STORAGE_MOUNT, strlen(METHOD_STORAGE_MOUNT))) {
+               return system_launch_double_param(key_data);
+       }
+
+       if (!strncmp(key_data->method, METHOD_CAMERA, strlen(METHOD_CAMERA))) {
+               return system_launch_single_param(key_data);
+       }
+
+       if (!strncmp(key_data->method, METHOD_STORAGE_UNMOUNT, strlen(METHOD_STORAGE_UNMOUNT))) {
+               return system_launch_double_param(key_data);
+       }
+
+       return -EINVAL;
+}
+
+static const struct apps_ops usbotg_popup_ops = {
+       .name   = "usbotg-syspopup",
+       .launch = system_launch,
+};
+
+APPS_OPS_REGISTER(&usbotg_popup_ops)
diff --git a/src/auto-test/CMakeLists.txt b/src/auto-test/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..303482d
--- /dev/null
@@ -0,0 +1,66 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(deviced-auto-test C)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src)
+
+IF("$ENV{CFLAGS}" MATCHES "-DMICRO_DD")
+       OPTION(USE_MICRO_DD "Use Micro DD" ON)
+ENDIF()
+
+IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_ENGINEER_MODE")
+    OPTION(USE_ENGINEER_MODE "Use Engineer mode" ON)
+ENDIF()
+
+SET(SRCS
+       test.c
+       main.c
+       udev.c
+       boot.c
+       cpu-info.c
+       board-info.c
+       time.c
+)
+
+# extcon test
+SET(SRCS ${SRCS}
+       power-supply.c
+       storage.c
+       usb.c
+)
+
+IF(NOT USE_MICRO_DD)
+SET(SRCS ${SRCS}
+       cradle.c
+       earjack.c
+       hdmi.c
+       keyboard.c
+)
+ENDIF(NOT USE_MICRO_DD)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED edbus)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+IF(USE_ENGINEER_MODE)
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions")
+ELSE()
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer")
+ENDIF()
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+MESSAGE("FLAGS: ${CMAKE_C_FLAGS}")
+
+IF("$ENV{CFLAGS}" MATCHES "-DMICRO_DD")
+       OPTION(USE_MICRO_DD "Use Micro DD" ON)
+ENDIF()
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DENABLE_TEST_DLOG")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} shared)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
diff --git a/src/auto-test/board-info.c b/src/auto-test/board-info.c
new file mode 100644 (file)
index 0000000..ca4cc6d
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+#define METHOD_GET_SERIAL      "GetSerial"
+#define METHOD_GET_REVISION    "GetHWRev"
+
+void get_serial(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, val;
+       char *data;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME, DEVICED_PATH_BOARD,
+               DEVICED_INTERFACE_BOARD, METHOD_GET_SERIAL, NULL, NULL);
+       if (!msg) {
+               _E("fail send message");
+               return;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &data, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               return;
+       }
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _D("%s %d", data, val);
+}
+
+static void get_revision(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME, DEVICED_PATH_BOARD,
+               DEVICED_INTERFACE_BOARD, METHOD_GET_REVISION, NULL, NULL);
+       if (!msg) {
+               _E("fail send message");
+               return;
+       }
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               return;
+       }
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       _E("%s-%s : %d", DEVICED_INTERFACE_BOARD, METHOD_GET_REVISION, val);
+       if(val >= 8) {
+               _D("Rinato Neo");
+       } else {
+               _D("Rinato");
+       }
+}
+
+static void board_init(void *data)
+{
+       _I("start test");
+       get_revision();
+       get_serial();
+}
+
+static void board_exit(void *data)
+{
+       _I("end test");
+}
+
+static int board_unit(int argc, char **argv)
+{
+       get_revision();
+       get_serial();
+       return 0;
+}
+
+static const struct test_ops board_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "board",
+       .init     = board_init,
+       .exit    = board_exit,
+       .unit    = board_unit,
+};
+
+TEST_OPS_REGISTER(&board_test_ops)
diff --git a/src/auto-test/boot.c b/src/auto-test/boot.c
new file mode 100644 (file)
index 0000000..5374e57
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+#define EDBUS_INIT_RETRY_COUNT 5
+static int edbus_init_val;
+static DBusConnection *conn;
+static E_DBus_Connection *edbus_conn;
+
+static const struct boot_control_type {
+       char *name;
+       char *status;
+} boot_control_types [] = {
+       {"poweroffpopup",       "pwroff-popup"},
+       {"poweroffpopup",       "reboot"},
+       {"poweroffpopup",       "reboot-recovery"},
+       {"poweroffpopup",       "poweroff"},
+       {"poweroffpopup",       "fota"},
+};
+
+static void edbus_init(void)
+{
+       DBusError error;
+       int retry = 0;
+       int i, ret;
+
+       dbus_threads_init_default();
+       dbus_error_init(&error);
+
+       do {
+               edbus_init_val = e_dbus_init();
+               if (edbus_init_val)
+                       break;
+               if (retry == EDBUS_INIT_RETRY_COUNT) {
+                       _E("fail to init edbus");
+                       return;
+               }
+               retry++;
+       } while (retry <= EDBUS_INIT_RETRY_COUNT);
+
+       retry = 0;
+       do {
+               conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+               if (conn)
+                       break;
+               if (retry == EDBUS_INIT_RETRY_COUNT) {
+                       _E("fail to get dbus");
+                       goto out1;
+               }
+               retry++;
+       } while (retry <= EDBUS_INIT_RETRY_COUNT);
+
+       retry = 0;
+       do {
+               edbus_conn = e_dbus_connection_setup(conn);
+               if (edbus_conn)
+                       break;
+               if (retry == EDBUS_INIT_RETRY_COUNT) {
+                       _E("fail to get edbus");
+                       goto out2;
+               }
+               retry++;
+       } while (retry <= EDBUS_INIT_RETRY_COUNT);
+       return;
+out2:
+       dbus_connection_set_exit_on_disconnect(conn, FALSE);
+out1:
+       e_dbus_shutdown();
+}
+
+static void edbus_exit(void)
+{
+       e_dbus_connection_close(edbus_conn);
+       e_dbus_shutdown();
+}
+
+static int broadcast_edbus_signal(const char *path, const char *interface,
+               const char *name, const char *sig, char *param[])
+{
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       int r;
+
+       msg = dbus_message_new_signal(path, interface, name);
+       if (!msg) {
+               _E("fail to allocate new %s.%s signal", interface, name);
+               return -EPERM;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       r = append_variant(&iter, sig, param);
+       if (r < 0) {
+               _E("append_variant error(%d)", r);
+               return -EPERM;
+       }
+
+       e_dbus_message_send(edbus_conn, msg, NULL, -1, NULL);
+
+       dbus_message_unref(msg);
+       return 0;
+}
+
+static void poweroff_send_broadcast(char *status)
+{
+       char *arr[2];
+       char str_status[32];
+
+       snprintf(str_status, sizeof(str_status), "%s", status);
+       arr[0] = str_status;
+       arr[1] = "0";
+       _D("broadcast poweroff %s %s", arr[0], arr[1]);
+
+       edbus_init();
+       broadcast_edbus_signal(DEVICED_OBJECT_PATH, DEVICED_INTERFACE_NAME,
+                       "poweroffpopup", "si", arr);
+       edbus_exit();
+}
+
+static void unit(char *unit, char *status)
+{
+       int index;
+
+       for (index = 0; index < ARRAY_SIZE(boot_control_types); index++) {
+               if (strcmp(unit, boot_control_types[index].name) != 0 ||
+                   strcmp(status, boot_control_types[index].status) != 0)
+                       continue;
+               if (strcmp(unit, "poweroffpopup") == 0)
+                       poweroff_send_broadcast(boot_control_types[index].status);
+       }
+
+}
+
+static void boot_init(void *data)
+{
+}
+
+static void boot_exit(void *data)
+{
+}
+
+static int boot_unit(int argc, char **argv)
+{
+       int status;
+
+       if (argv[1] == NULL)
+               return -EINVAL;
+       if (argc < 3)
+               return -EAGAIN;
+       unit(argv[argc-2], argv[argc-1]);
+out:
+       return 0;
+}
+
+static const struct test_ops boot_test_ops = {
+       .priority = TEST_PRIORITY_HIGH,
+       .name     = "boot",
+       .init     = boot_init,
+       .exit    = boot_exit,
+       .unit    = boot_unit,
+};
+
+TEST_OPS_REGISTER(&boot_test_ops)
diff --git a/src/auto-test/cpu-info.c b/src/auto-test/cpu-info.c
new file mode 100644 (file)
index 0000000..9a5e156
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+#define METHOD_GET_REVISION    "GetRevision"
+
+static void get_revision(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI,
+               DEVICED_INTERFACE_SYSNOTI, METHOD_GET_REVISION, NULL, NULL);
+       if (!msg) {
+               _E("fail send message");
+               return;
+       }
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               return;
+       }
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       _E("%s-%s : %d", DEVICED_INTERFACE_SYSNOTI, METHOD_GET_REVISION, val);
+       if(val >= 8) {
+               _D("Rinato Neo");
+       } else {
+               _D("Rinato");
+       }
+}
+
+static void cpuinfo_init(void *data)
+{
+       _I("start test");
+       get_revision();
+}
+
+static void cpuinfo_exit(void *data)
+{
+       _I("end test");
+}
+
+static int cpuinfo_unit(int argc, char **argv)
+{
+       get_revision();
+       return 0;
+}
+
+static const struct test_ops cpuinfo_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "cpuinfo",
+       .init     = cpuinfo_init,
+       .exit    = cpuinfo_exit,
+       .unit    = cpuinfo_unit,
+};
+
+TEST_OPS_REGISTER(&cpuinfo_test_ops)
diff --git a/src/auto-test/cradle.c b/src/auto-test/cradle.c
new file mode 100644 (file)
index 0000000..3abe136
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+#define METHOD_GET_CRADLE      "GetCradle"
+
+static const struct device_change_type {
+       char *name;
+       char *status;
+} device_change_types [] = {
+       {"cradle",      "1"},
+       {"cradle",      "0"},
+};
+
+static int test_cradle(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, level;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_GET_CRADLE, NULL, NULL);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_GET_CRADLE);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &level,
+                       DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               level = -1;
+       }
+       _I("%d", level);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return level;
+}
+
+static int test(int index)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+       char *param[4];
+
+       param[0] = METHOD_SET_DEVICE;
+       param[1] = "2";
+       param[2] = device_change_types[index].name;
+       param[3] = device_change_types[index].status;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE, "siss", param);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (ret == 0) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+       _I("%s %s", device_change_types[index].name, device_change_types[index].status);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return ret_val;
+}
+
+static void unit(char *unit, char *status)
+{
+       int index;
+
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++) {
+               if (strcmp(unit, device_change_types[index].name) != 0 ||
+                   strcmp(status, device_change_types[index].status) != 0)
+                       continue;
+               test(index);
+               test_cradle();
+       }
+}
+
+static void cradle_init(void *data)
+{
+       int index;
+
+       _I("start test");
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
+               test(index);
+}
+
+static void cradle_exit(void *data)
+{
+       _I("end test");
+}
+
+static int cradle_unit(int argc, char **argv)
+{
+       int status;
+
+       if (argv[1] == NULL)
+               return -EINVAL;
+       if (argc != 4)
+               return -EAGAIN;
+
+       unit(argv[2], argv[3]);
+out:
+       return 0;
+}
+
+static const struct test_ops cradle_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "cradle",
+       .init     = cradle_init,
+       .exit    = cradle_exit,
+       .unit    = cradle_unit,
+};
+
+TEST_OPS_REGISTER(&cradle_test_ops)
diff --git a/src/auto-test/earjack.c b/src/auto-test/earjack.c
new file mode 100644 (file)
index 0000000..8643bdc
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+static const struct device_change_type {
+       char *name;
+       char *status;
+} device_change_types [] = {
+       {"jack",        "1"},
+       {"jack",        "0"},
+       {"key", "1"},
+       {"key", "0"},
+};
+
+static int test(int index)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+       char *param[4];
+
+       param[0] = METHOD_SET_DEVICE;
+       param[1] = "2";
+       param[2] = device_change_types[index].name;
+       param[3] = device_change_types[index].status;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE, "siss", param);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (ret == 0) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+       _I("%s %s", device_change_types[index].name, device_change_types[index].status);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return ret_val;
+}
+
+static void unit(char *unit, char *status)
+{
+       int index;
+
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++) {
+               if (strcmp(unit, device_change_types[index].name) != 0 ||
+                   strcmp(status, device_change_types[index].status) != 0)
+                       continue;
+               test(index);
+       }
+}
+
+static void earjack_init(void *data)
+{
+       int index;
+
+       _I("start test");
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
+               test(index);
+}
+
+static void earjack_exit(void *data)
+{
+       _I("end test");
+}
+
+static int earjack_unit(int argc, char **argv)
+{
+       int status;
+
+       if (argv[1] == NULL)
+               return -EINVAL;
+       if (argc != 3)
+               return -EAGAIN;
+
+       unit(argv[1], argv[2]);
+out:
+       return 0;
+}
+
+static const struct test_ops earjack_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "earjack",
+       .init     = earjack_init,
+       .exit    = earjack_exit,
+       .unit    = earjack_unit,
+};
+
+TEST_OPS_REGISTER(&earjack_test_ops)
+
diff --git a/src/auto-test/hdmi.c b/src/auto-test/hdmi.c
new file mode 100644 (file)
index 0000000..c1edf83
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+#define METHOD_GET_HDMI                "GetHDMI"
+#define METHOD_GET_HDCP                "GetHDCP"
+#define METHOD_GET_HDMI_AUDIO  "GetHDMIAudio"
+
+static const struct device_change_type {
+       char *name;
+       char *status;
+} device_change_types [] = {
+       {"hdmi",        "1"},
+       {"hdmi",        "0"},
+};
+
+static int test_hdmi(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, level;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_GET_HDMI, NULL, NULL);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_GET_HDMI);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &level,
+                       DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               level = -1;
+       }
+       _I("%d", level);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return level;
+}
+
+static int test_hdcp(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, level;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_GET_HDCP, NULL, NULL);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_GET_HDCP);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &level,
+                       DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               level = -1;
+       }
+       _I("%d", level);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return level;
+}
+
+static int test_hdmi_audio(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, level;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_GET_HDMI_AUDIO, NULL, NULL);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_GET_HDMI_AUDIO);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &level,
+                       DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               level = -1;
+       }
+       _I("%d", level);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return level;
+}
+
+static int test(int index)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+       char *param[4];
+
+       param[0] = METHOD_SET_DEVICE;
+       param[1] = "2";
+       param[2] = device_change_types[index].name;
+       param[3] = device_change_types[index].status;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE, "siss", param);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (ret == 0) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+       _I("%s %s", device_change_types[index].name, device_change_types[index].status);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return ret_val;
+}
+
+static void unit(char *unit, char *status)
+{
+       int index;
+
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++) {
+               if (strcmp(unit, device_change_types[index].name) != 0 ||
+                   strcmp(status, device_change_types[index].status) != 0)
+                       continue;
+               test(index);
+       }
+}
+
+static void hdmi_init(void *data)
+{
+       int index;
+
+       _I("start test");
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++) {
+               test(index);
+               test_hdmi();
+               test_hdcp();
+               test_hdmi_audio();
+       }
+}
+
+static void hdmi_exit(void *data)
+{
+       _I("end test");
+}
+
+static int hdmi_unit(int argc, char **argv)
+{
+       int status;
+
+       if (argv[1] == NULL)
+               return -EINVAL;
+       if (argc != 3)
+               return -EAGAIN;
+
+       unit(argv[1], argv[2]);
+out:
+       return 0;
+}
+
+static const struct test_ops hdmi_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "hdmi",
+       .init     = hdmi_init,
+       .exit    = hdmi_exit,
+       .unit    = hdmi_unit,
+};
+
+TEST_OPS_REGISTER(&hdmi_test_ops)
diff --git a/src/auto-test/keyboard.c b/src/auto-test/keyboard.c
new file mode 100644 (file)
index 0000000..e9cec63
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+static const struct device_change_type {
+       char *name;
+       char *status;
+} device_change_types [] = {
+       {"keyboard",    "1"},
+       {"keyboard",    "0"},
+};
+
+static int test(int index)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+       char *param[4];
+
+       param[0] = METHOD_SET_DEVICE;
+       param[1] = "2";
+       param[2] = device_change_types[index].name;
+       param[3] = device_change_types[index].status;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE, "siss", param);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (ret == 0) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+       _I("%s %s", device_change_types[index].name, device_change_types[index].status);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return ret_val;
+}
+
+static void unit(char *unit, char *status)
+{
+       int index;
+
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++) {
+               if (strcmp(unit, device_change_types[index].name) != 0 ||
+                   strcmp(status, device_change_types[index].status) != 0)
+                       continue;
+               test(index);
+       }
+}
+
+static void keyboard_init(void *data)
+{
+       int index;
+
+       _I("start test");
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
+               test(index);
+}
+
+static void keyboard_exit(void *data)
+{
+       _I("end test");
+}
+
+static int keyboard_unit(int argc, char **argv)
+{
+       int status;
+
+       if (argv[1] == NULL)
+               return -EINVAL;
+       if (argc != 3)
+               return -EAGAIN;
+
+       unit(argv[1], argv[2]);
+out:
+       return 0;
+}
+
+static const struct test_ops keyboard_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "keyboard",
+       .init     = keyboard_init,
+       .exit    = keyboard_exit,
+       .unit    = keyboard_unit,
+};
+
+TEST_OPS_REGISTER(&keyboard_test_ops)
diff --git a/src/auto-test/main.c b/src/auto-test/main.c
new file mode 100644 (file)
index 0000000..8344cac
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+static void test_main(int argc, char **argv)
+{
+       _I("auto test all");
+       test_init((void *)NULL);
+       test_exit((void *)NULL);
+}
+
+static void unit_test(int argc, char **argv)
+{
+       const struct test_ops *ops;
+
+       ops = find_test(argv[1]);
+       if (!ops) {
+               _E("there is no test ops : %s", argv[1]);
+               return;
+       }
+       ops->unit(argc, argv);
+}
+
+int main(int argc, char **argv)
+{
+       if (argc >= 2 )
+               unit_test(argc, argv);
+       else
+               test_main(argc, argv);
+       return 0;
+}
+
diff --git a/src/auto-test/power-supply.c b/src/auto-test/power-supply.c
new file mode 100644 (file)
index 0000000..d63a577
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+#define S_ENTER        1
+#define S_LEAVE        0
+
+#define SIGNAL_CHARGE_NOW "ChargeNow"
+#define SIGNAL_CHARGER_STATUS "ChargerStatus"
+#define SIGNAL_TEMP_GOOD "TempGood"
+
+static E_DBus_Signal_Handler *edbus_charge_now_handler;
+static E_DBus_Signal_Handler *edbus_charger_status_handler;
+static E_DBus_Signal_Handler *edbus_temp_good_handler;
+static E_DBus_Connection     *edbus_conn;
+
+static struct power_supply_type {
+       char *scenario;
+       int status;
+       char *capacity;
+       char *charge_status;
+       char *health;
+       char *online;
+       char *present;
+       char *name;
+} power_supply_types [] = {
+       {"norm", S_ENTER, "100","Charging",    "Good", "2", "1", "CHARGE"},
+       {"norm", S_ENTER, "100","Discharging", "Good", "1", "1", "DISCHARGE"},
+       {"norm", S_LEAVE, "100","Discharging", "Good", "1", "1", NULL}, //init
+
+       {"heat1",S_ENTER, "100","Discharging", "Overheat", "1", "1", NULL},
+       {"heat1",S_ENTER, "100","Not charging","Overheat", "2", "1", "HEALTH(H) BEFORE CHARGE"},
+       {"heat1",S_LEAVE, "100","Discharging", "Overheat", "1", "1", "DISCHARGE"},
+       {"heat1",S_LEAVE, "100","Discharging", "Good", "1", "1", NULL}, //init
+
+       {"heat2",S_ENTER, "100","Charging",    "Good", "2", "1", NULL},
+       {"heat2",S_ENTER, "100","Not charging","Overheat", "2", "1", "HEALTH(H) AFTER CHARGE"},
+       {"heat2",S_LEAVE, "100","Discharging", "Overheat", "1", "1", "DISCHARGE"},
+       {"heat2",S_LEAVE, "100","Discharging", "Good", "1", "1", NULL}, //init
+
+       {"cold1",S_ENTER, "100","Discharging", "Cold", "1", "1", NULL},
+       {"cold1",S_ENTER, "100","Not charging","Cold", "2", "1", "HEALTH(L) BEFORE CHARGE"},
+       {"cold1",S_LEAVE, "100","Discharging", "Cold", "1", "1", "DISCHARGE"},
+       {"cold1",S_LEAVE, "100","Discharging", "Good", "1", "1", NULL}, //init
+
+       {"cold2",S_ENTER, "100","Charging",    "Good", "2", "1", NULL},
+       {"cold2",S_ENTER, "100","Not charging","Cold", "2", "1", "HEALTH(L) AFTER CHARGE"},
+       {"cold2",S_LEAVE, "100","Discharging", "Cold", "1", "1", "DISCHARGE"},
+       {"cold2",S_LEAVE, "100","Discharging", "Good", "1", "1", NULL}, //init
+
+       {"ovp",  S_ENTER, "100","Discharging", "Over voltage", "1", "1", "OVP"},
+       {"ovp",  S_LEAVE, "100","Discharging", "Good", "1", "1", NULL}, //init
+
+       {"pres1",S_ENTER, "100","Discharging", "Good", "1", "0", NULL},
+       {"pres1",S_ENTER, "100","Not charging","Good", "2", "0", "PRESENT BEFORE CHARGE"},
+       {"pres1",S_LEAVE, "100","Discharging", "Good", "1", "0", "DISCHARGE"},
+       {"pres1",S_LEAVE, "100","Discharging", "Good", "1", "1", NULL}, //init
+
+       {"pres2",S_ENTER, "100","Charging",    "Good", "2", "1", NULL},
+       {"pres2",S_ENTER, "100","Not charging","Good", "2", "0", "PRESENT AFTER CHARGE"},
+       {"pres2",S_LEAVE, "100","Discharging", "Good", "1", "0", "DISCHARGE"},
+       {"pres2",S_LEAVE, "100","Discharging", "Good", "1", "1", NULL}, //init
+
+       {"bat15",S_ENTER, "15", "Discharging", "Good", "1", "1", "LOWBAT 15%"}, //lowbat 15%
+       {"bat15",S_LEAVE, "15", "Charging",    "Good", "2", "1", "LOWBAT 15%"},
+       {"bat5", S_ENTER, "5",  "Discharging", "Good", "1", "1", "LOWBAT 5%"},  //lowbat 5%
+       {"bat5", S_LEAVE, "5",  "Charging",    "Good", "2", "1", "LOWBAT 5%"},
+       {"bat3", S_ENTER, "3",  "Discharging", "Good", "1", "1", "LOWBAT 3%"},  //lowbat 3%
+       {"bat3", S_LEAVE, "3",  "Charging",    "Good", "2", "1", "LOWBAT 3%"},
+       {"bat1", S_ENTER, "1",  "Discharging", "Good", "1", "1", "LOWBAT 1%"},  //lowbat 1%
+       {"bat1", S_LEAVE, "1",  "Charging",    "Good", "2", "1", "LOWBAT 1%"},
+
+       {"ta",   S_ENTER, "100","Charging",    "Good", "2", "1", "CHARGE"},   //charging
+       {"ta",   S_LEAVE, "100","Discharging", "Good", "1", "1", "DISCHARGE"},//discharging
+       {"capacity",   S_ENTER, "100","Discharging", "Good", "1", "1", "CAPACITY"},//charging
+       {"capacity",   S_LEAVE, "100","Charging", "Good", "2", "1", "CAPACITY"},//discharging
+};
+
+static void unregister_edbus_signal_handler(void)
+{
+       e_dbus_signal_handler_del(edbus_conn, edbus_charge_now_handler);
+       e_dbus_signal_handler_del(edbus_conn, edbus_charger_status_handler);
+       e_dbus_signal_handler_del(edbus_conn, edbus_temp_good_handler);
+       e_dbus_connection_close(edbus_conn);
+       e_dbus_shutdown();
+}
+
+static void power_supply_changed(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       int val;
+       int r;
+
+       _I("edbus signal Received");
+
+       r = dbus_message_is_signal(msg, DEVICED_INTERFACE_BATTERY, SIGNAL_CHARGE_NOW);
+       if (!r) {
+               _E("dbus_message_is_signal error");
+               return;
+       }
+
+       _I("%s - %s", DEVICED_INTERFACE_BATTERY, SIGNAL_CHARGE_NOW);
+
+       dbus_error_init(&err);
+       r = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!r) {
+               _E("dbus_message_get_args error");
+               return;
+       }
+       _I("receive data : %d", val);
+}
+
+static int register_charge_now_handler(void)
+{
+       int ret;
+
+       e_dbus_init();
+
+       edbus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
+       if (!(edbus_conn)) {
+               ret = -ECONNREFUSED;
+               goto edbus_handler_out;
+       }
+
+       edbus_charge_now_handler = e_dbus_signal_handler_add(edbus_conn, NULL, DEVICED_PATH_BATTERY,
+                       DEVICED_INTERFACE_BATTERY, SIGNAL_CHARGE_NOW, power_supply_changed, NULL);
+       if (!(edbus_charge_now_handler)) {
+               ret = -ECONNREFUSED;
+               goto edbus_handler_connection_out;
+       }
+       return 0;
+
+edbus_handler_connection_out:
+       e_dbus_connection_close(edbus_conn);
+edbus_handler_out:
+       e_dbus_shutdown();
+       return ret;
+}
+
+static void charger_status_changed(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       int val;
+       int r;
+
+       _I("edbus signal Received");
+
+       r = dbus_message_is_signal(msg, DEVICED_INTERFACE_BATTERY, SIGNAL_CHARGER_STATUS);
+       if (!r) {
+               _E("dbus_message_is_signal error");
+               return;
+       }
+
+       _I("%s - %s", DEVICED_INTERFACE_BATTERY, SIGNAL_CHARGER_STATUS);
+
+       dbus_error_init(&err);
+       r = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!r) {
+               _E("dbus_message_get_args error");
+               return;
+       }
+       _I("receive data : %d", val);
+}
+
+static int register_charger_status_handler(void)
+{
+       int ret;
+
+       e_dbus_init();
+
+       edbus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
+       if (!(edbus_conn)) {
+               ret = -ECONNREFUSED;
+               goto edbus_handler_out;
+       }
+
+       edbus_charger_status_handler = e_dbus_signal_handler_add(edbus_conn, NULL, DEVICED_PATH_BATTERY,
+                       DEVICED_INTERFACE_BATTERY, SIGNAL_CHARGER_STATUS, charger_status_changed, NULL);
+       if (!(edbus_charger_status_handler)) {
+               ret = -ECONNREFUSED;
+               goto edbus_handler_connection_out;
+       }
+       return 0;
+
+edbus_handler_connection_out:
+       e_dbus_connection_close(edbus_conn);
+edbus_handler_out:
+       e_dbus_shutdown();
+       return ret;
+}
+
+static void temp_status_changed(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       int val;
+       int r;
+
+       _I("edbus signal Received");
+
+       r = dbus_message_is_signal(msg, DEVICED_INTERFACE_BATTERY, SIGNAL_TEMP_GOOD);
+       if (!r) {
+               _E("dbus_message_is_signal error");
+               return;
+       }
+
+       _I("%s - %s", DEVICED_INTERFACE_BATTERY, SIGNAL_TEMP_GOOD);
+}
+
+static int register_temp_good_handler(void)
+{
+       int ret;
+
+       e_dbus_init();
+
+       edbus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
+       if (!(edbus_conn)) {
+               ret = -ECONNREFUSED;
+               goto edbus_handler_out;
+       }
+
+       edbus_temp_good_handler = e_dbus_signal_handler_add(edbus_conn, NULL, DEVICED_PATH_BATTERY,
+                       DEVICED_INTERFACE_BATTERY, SIGNAL_TEMP_GOOD, temp_status_changed, NULL);
+       if (!(edbus_temp_good_handler)) {
+               ret = -ECONNREFUSED;
+               goto edbus_handler_connection_out;
+       }
+       return 0;
+
+edbus_handler_connection_out:
+       e_dbus_connection_close(edbus_conn);
+edbus_handler_out:
+       e_dbus_shutdown();
+       return ret;
+}
+static void test_signal(void)
+{
+       _I("test");
+       register_charge_now_handler();
+       register_charger_status_handler();
+       register_temp_good_handler();
+       ecore_main_loop_begin();
+}
+
+static int test(int index)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+       char *param[7];
+
+       param[0] = POWER_SUBSYSTEM;
+       param[1] = "5";
+       param[2] = power_supply_types[index].capacity;
+       param[3] = power_supply_types[index].charge_status;
+       param[4] = power_supply_types[index].health;
+       param[5] = power_supply_types[index].online;
+       param[6] = power_supply_types[index].present;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       POWER_SUBSYSTEM, "sisssss", param);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       POWER_SUBSYSTEM);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (ret == 0) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       if (power_supply_types[index].name != NULL)
+               _I("++++++++++[START] %s ++++++++++", power_supply_types[index].name);
+       _I("CAPACITY(%s , %s) P(%s) STATUS(%s) HEALTH(%s)",
+               power_supply_types[index].capacity,
+               power_supply_types[index].online,
+               power_supply_types[index].present,
+               power_supply_types[index].charge_status,
+               power_supply_types[index].health);
+       if (power_supply_types[index].name != NULL)
+               _I("++++++++++[END] %s ++++++++++", power_supply_types[index].name);
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return ret_val;
+}
+
+static void scenario(char *scenario)
+{
+       int index;
+
+       for (index = 0; index < ARRAY_SIZE(power_supply_types); index++) {
+               if (strcmp(scenario, power_supply_types[index].scenario) != 0)
+                       continue;
+               test(index);
+       }
+}
+
+static void unit(char *unit, int status)
+{
+       int index;
+       int found = 0;
+       char *scenario = NULL;
+
+       for (index = 0; index < ARRAY_SIZE(power_supply_types); index++) {
+               scenario = power_supply_types[index].scenario;
+               if (strcmp(unit, scenario) != 0 ||
+                   power_supply_types[index].status != status)
+                       continue;
+               found = 1;
+               test(index);
+       }
+
+       if (found)
+               return;
+
+       index = strlen(unit);
+       if (index < 0 || index > 3)
+               return;
+
+       index = strtol(unit, NULL, 10);
+       if (index < 0 || index > 100)
+               return;
+
+       for (index = 0; index < ARRAY_SIZE(power_supply_types); index++) {
+               if (strcmp("capacity", power_supply_types[index].scenario) != 0 ||
+                   power_supply_types[index].status != status)
+                       continue;
+               power_supply_types[index].capacity = unit;
+               _D("%s", power_supply_types[index].capacity);
+               test(index);
+       }
+}
+
+static void power_supply_init(void *data)
+{
+       int index;
+
+       _I("start test");
+       for (index = 0; index < ARRAY_SIZE(power_supply_types); index++)
+               test(index);
+}
+
+static void power_supply_exit(void *data)
+{
+       _I("end test");
+}
+
+static int power_supply_unit(int argc, char **argv)
+{
+       if (argv[1] == NULL)
+               return -EINVAL;
+       else if (argc != 4)
+               return -EAGAIN;
+       if (strcmp("wait", argv[2]) == 0)
+               test_signal();
+       else if (strcmp("scenario", argv[2]) == 0)
+               scenario(argv[3]);
+       else if (strcmp("enter", argv[3]) == 0)
+               unit(argv[2], S_ENTER);
+       else if (strcmp("leave", argv[3]) == 0)
+               unit(argv[2], S_LEAVE);
+       return 0;
+}
+
+static const struct test_ops power_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "power",
+       .init     = power_supply_init,
+       .exit    = power_supply_exit,
+       .unit    = power_supply_unit,
+};
+
+TEST_OPS_REGISTER(&power_test_ops)
diff --git a/src/auto-test/storage.c b/src/auto-test/storage.c
new file mode 100644 (file)
index 0000000..dad9a7c
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+#define METHOD_GET_STORAGE     "getstorage"
+#define METHOD_MEM_TRIM        "MemTrim"
+
+static void mem_trim(void *data, DBusMessage *msg, DBusError *tmp)
+{
+       DBusError err;
+       int ret, result;
+
+       if (!msg)
+               return;
+
+       dbus_error_init(&err);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               return;
+       }
+       _D("succeed mem trim : %d", result);
+}
+
+static int request_mem_trim(void)
+{
+       int ret;
+
+       ret = dbus_method_async_with_reply(DEVICED_BUS_NAME,
+               DEVICED_PATH_STORAGE, DEVICED_INTERFACE_STORAGE,
+               METHOD_MEM_TRIM, NULL, NULL, mem_trim, -1, NULL);
+       if (ret == 0)
+               _D("request mem trim");
+       return ret;
+}
+
+static int test_storage(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret;
+       double dAvail;
+       double dTotal;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_STORAGE,
+                       DEVICED_INTERFACE_STORAGE,
+                       METHOD_GET_STORAGE, NULL, NULL);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_GET_STORAGE);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT64, &dTotal, DBUS_TYPE_INT64, &dAvail, DBUS_TYPE_INVALID);;
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+       }
+       _I("total : %4.4lf avail %4.4lf", dTotal, dAvail);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return ret;
+}
+
+static void storage_init(void *data)
+{
+       _I("start test");
+       test_storage();
+}
+
+static void storage_exit(void *data)
+{
+       _I("end test");
+}
+
+static int storage_unit(int argc, char **argv)
+{
+       int status;
+
+       if (argv[1] == NULL)
+               return -EINVAL;
+       test_storage();
+       request_mem_trim();
+       ecore_main_loop_begin();
+out:
+       return 0;
+}
+
+static const struct test_ops storage_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "storage",
+       .init     = storage_init,
+       .exit    = storage_exit,
+       .unit    = storage_unit,
+};
+
+TEST_OPS_REGISTER(&storage_test_ops)
diff --git a/src/auto-test/test.c b/src/auto-test/test.c
new file mode 100644 (file)
index 0000000..6253487
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+static dd_list *dd_head;
+
+void add_test(const struct test_ops *d)
+{
+       if (d->priority == TEST_PRIORITY_HIGH)
+               DD_LIST_PREPEND(dd_head, d);
+       else
+               DD_LIST_APPEND(dd_head, d);
+}
+
+void remove_test(const struct test_ops *d)
+{
+       DD_LIST_REMOVE(dd_head, d);
+}
+
+const struct test_ops *find_test(const char *name)
+{
+       dd_list *elem;
+       const struct test_ops *d;
+
+       DD_LIST_FOREACH(dd_head, elem, d) {
+               if (!strcmp(d->name, name))
+                       return d;
+       }
+       return NULL;
+}
+
+void test_init(void *data)
+{
+       dd_list *elem;
+       const struct test_ops *d;
+
+       DD_LIST_FOREACH(dd_head, elem, d) {
+               _D("[%s] initialize", d->name);
+               if (d->init)
+                       d->init(data);
+       }
+}
+
+void test_exit(void *data)
+{
+       dd_list *elem;
+       const struct test_ops *d;
+
+       DD_LIST_FOREACH(dd_head, elem, d) {
+               _D("[%s] deinitialize", d->name);
+               if (d->exit)
+                       d->exit(data);
+       }
+}
\ No newline at end of file
diff --git a/src/auto-test/test.h b/src/auto-test/test.h
new file mode 100644 (file)
index 0000000..2f68f3c
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 __TEST_H__
+#define __TEST_H__
+#include <stdio.h>
+#include <errno.h>
+#include <E_DBus.h>
+
+#include "core/list.h"
+#include "core/common.h"
+#include "core/udev.h"
+#include "shared/dbus.h"
+
+#ifdef ENABLE_TEST_DLOG
+#define ENABLE_DLOG
+#endif
+
+#define LOG_TAG "AUTO_TEST"
+#include "shared/log-macro.h"
+
+#define TEST_WAIT_TIME_INTERVAL        5
+#define METHOD_SET_DEVICE      "device_changed"
+
+enum test_priority {
+       TEST_PRIORITY_NORMAL = 0,
+       TEST_PRIORITY_HIGH,
+};
+
+struct test_ops {
+       enum test_priority priority;
+       char *name;
+       void (*init) (void *data);
+       void (*exit) (void *data);
+       int (*start) (void);
+       int (*stop) (void);
+       int (*status) (void);
+       int (*unit) (int argc, char **argv);
+};
+
+enum test_ops_status {
+       TEST_OPS_STATUS_UNINIT,
+       TEST_OPS_STATUS_START,
+       TEST_OPS_STATUS_STOP,
+       TEST_OPS_STATUS_MAX,
+};
+
+void test_init(void *data);
+void test_exit(void *data);
+
+static inline int test_start(const struct test_ops *c)
+{
+       if (c && c->start)
+               return c->start();
+
+       return -EINVAL;
+}
+
+static inline int test_stop(const struct test_ops *c)
+{
+       if (c && c->stop)
+               return c->stop();
+
+       return -EINVAL;
+}
+
+static inline int test_get_status(const struct test_ops *c)
+{
+       if (c && c->status)
+               return c->status();
+
+       return -EINVAL;
+}
+
+#define TEST_OPS_REGISTER(c)   \
+static void __CONSTRUCTOR__ module_init(void)  \
+{      \
+       add_test(c);    \
+}      \
+static void __DESTRUCTOR__ module_exit(void)   \
+{      \
+       remove_test(c); \
+}
+DBusMessage *deviced_dbus_method_sync_with_reply(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[]);
+void add_test(const struct test_ops *c);
+void remove_test(const struct test_ops *c);
+const struct test_ops *find_test(const char *name);
+
+#endif
diff --git a/src/auto-test/time.c b/src/auto-test/time.c
new file mode 100644 (file)
index 0000000..71edb14
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+#define TIME_CHANGE_SIGNAL "STimeChanged"
+
+static E_DBus_Signal_Handler *edbus_handler;
+static E_DBus_Connection     *edbus_conn;
+
+static void unregister_edbus_signal_handler(void)
+{
+       e_dbus_signal_handler_del(edbus_conn, edbus_handler);
+       e_dbus_connection_close(edbus_conn);
+       e_dbus_shutdown();
+}
+
+static void time_changed(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       int val;
+       int r;
+
+       _I("edbus signal Received");
+
+       r = dbus_message_is_signal(msg, DEVICED_INTERFACE_TIME, TIME_CHANGE_SIGNAL);
+       if (!r) {
+               _E("dbus_message_is_signal error");
+               return;
+       }
+
+       _I("%s - %s", DEVICED_INTERFACE_TIME, TIME_CHANGE_SIGNAL);
+
+       unregister_edbus_signal_handler();
+       ecore_shutdown();
+}
+
+static int register_edbus_signal_handler(void)
+{
+       int ret;
+
+       e_dbus_init();
+
+       edbus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
+       if (!(edbus_conn)) {
+               ret = -ECONNREFUSED;
+               goto edbus_handler_out;
+       }
+
+       edbus_handler = e_dbus_signal_handler_add(edbus_conn, NULL, DEVICED_PATH_TIME,
+                       DEVICED_INTERFACE_TIME, TIME_CHANGE_SIGNAL, time_changed, NULL);
+       if (!(edbus_handler)) {
+               ret = -ECONNREFUSED;
+               goto edbus_handler_connection_out;
+       }
+       return 0;
+
+edbus_handler_connection_out:
+       e_dbus_connection_close(edbus_conn);
+edbus_handler_out:
+       e_dbus_shutdown();
+       return ret;
+}
+
+static void test_signal(void)
+{
+       _I("test");
+       register_edbus_signal_handler();
+       ecore_main_loop_begin();
+}
+
+static void time_init(void *data)
+{
+}
+
+static void time_exit(void *data)
+{
+}
+
+static int time_unit(int argc, char **argv)
+{
+       if (argv[1] == NULL)
+               return -EINVAL;
+       else if (argc != 4)
+               return -EAGAIN;
+       if (strcmp("wait", argv[2]) == 0)
+               test_signal();
+       return 0;
+}
+
+static const struct test_ops power_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "time",
+       .init     = time_init,
+       .exit    = time_exit,
+       .unit    = time_unit,
+};
+
+TEST_OPS_REGISTER(&power_test_ops)
diff --git a/src/auto-test/tvout.c b/src/auto-test/tvout.c
new file mode 100644 (file)
index 0000000..3b75459
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+static const struct device_change_type {
+       char *name;
+       char *status;
+} device_change_types [] = {
+       {"tvout",       "1"},
+       {"tvout",       "0"},
+};
+
+static int test(int index)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+       char *param[4];
+
+       param[0] = METHOD_SET_DEVICE;
+       param[1] = "2";
+       param[2] = device_change_types[index].name;
+       param[3] = device_change_types[index].status;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE, "siss", param);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (ret == 0) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+       _I("%s %s", device_change_types[index].name, device_change_types[index].status);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return ret_val;
+}
+
+static void unit(char *unit, char *status)
+{
+       int index;
+
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++) {
+               if (strcmp(unit, device_change_types[index].name) != 0 ||
+                   strcmp(status, device_change_types[index].status) != 0)
+                       continue;
+               test(index);
+       }
+}
+
+static void tvout_init(void *data)
+{
+       int index;
+
+       _I("start test");
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
+               test(index);
+}
+
+static void tvout_exit(void *data)
+{
+       _I("end test");
+}
+
+static int tvout_unit(int argc, char **argv)
+{
+       int status;
+
+       if (argv[1] == NULL)
+               return -EINVAL;
+       if (argc != 3)
+               return -EAGAIN;
+
+       unit(argv[1], argv[2]);
+out:
+       return 0;
+}
+
+static const struct test_ops tvout_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "tvout",
+       .init     = tvout_init,
+       .exit    = tvout_exit,
+       .unit    = tvout_unit,
+};
+
+TEST_OPS_REGISTER(&tvout_test_ops)
diff --git a/src/auto-test/udev.c b/src/auto-test/udev.c
new file mode 100644 (file)
index 0000000..c9818e3
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+static const struct device_change_type {
+       char *name;
+       char *status;
+} device_change_types [] = {
+       {"udev",                "start"},
+       {"udev",                "stop"},
+};
+
+static int test(int index)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+       char *param[3];
+
+       param[0] = UDEV;
+       param[1] = "1";
+       param[2] = device_change_types[index].status;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       UDEV, "sis", param);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       UDEV);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               ret_val = -EBADMSG;
+       }
+       _I("START");
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return ret_val;
+}
+
+static void unit(char *unit, char *status)
+{
+       int index;
+
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++) {
+               if (strcmp(unit, device_change_types[index].name) != 0 ||
+                   strcmp(status, device_change_types[index].status) != 0)
+                       continue;
+               test(index);
+       }
+}
+
+static void udev_init(void *data)
+{
+       int index;
+
+       _I("start test");
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
+               test(index);
+}
+
+static void udev_exit(void *data)
+{
+       _I("end test");
+}
+
+static int udev_unit(int argc, char **argv)
+{
+       int status;
+
+       if (argv[1] == NULL)
+               return -EINVAL;
+       if (argc != 3)
+               return -EAGAIN;
+
+       unit(argv[1], argv[2]);
+out:
+       return 0;
+}
+
+static const struct test_ops udev_test_ops = {
+       .priority = TEST_PRIORITY_HIGH,
+       .name     = "udev",
+       .init     = udev_init,
+       .exit    = udev_exit,
+       .unit    = udev_unit,
+};
+
+TEST_OPS_REGISTER(&udev_test_ops)
diff --git a/src/auto-test/usb.c b/src/auto-test/usb.c
new file mode 100644 (file)
index 0000000..2a8a901
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * test
+ *
+ * Copyright (c) 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 "test.h"
+
+static const struct device_change_type {
+       char *name;
+       char *status;
+} device_change_types [] = {
+       {"usb",         "1"},
+       {"usb",         "0"},
+};
+
+static int test(int index)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+       char *param[4];
+
+       param[0] = METHOD_SET_DEVICE;
+       param[1] = "2";
+       param[2] = device_change_types[index].name;
+       param[3] = device_change_types[index].status;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE, "siss", param);
+       if (!msg) {
+               _E("fail : %s %s %s %s",
+                       DEVICED_BUS_NAME, DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       METHOD_SET_DEVICE);
+               return -EBADMSG;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (ret == 0) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+       _I("%s %s", device_change_types[index].name, device_change_types[index].status);
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+       sleep(TEST_WAIT_TIME_INTERVAL);
+       return ret_val;
+}
+
+static void unit(char *unit, char *status)
+{
+       int index;
+
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++) {
+               if (strcmp(unit, device_change_types[index].name) != 0 ||
+                   strcmp(status, device_change_types[index].status) != 0)
+                       continue;
+               test(index);
+       }
+}
+
+static void usb_init(void *data)
+{
+       int index;
+
+       _I("start test");
+       for (index = 0; index < ARRAY_SIZE(device_change_types); index++)
+               test(index);
+}
+
+static void usb_exit(void *data)
+{
+       _I("end test");
+}
+
+static int usb_unit(int argc, char **argv)
+{
+       int status;
+
+       if (argv[1] == NULL)
+               return -EINVAL;
+       if (argc != 3)
+               return -EAGAIN;
+
+       unit(argv[1], argv[2]);
+out:
+       return 0;
+}
+
+static const struct test_ops usb_test_ops = {
+       .priority = TEST_PRIORITY_NORMAL,
+       .name     = "usb",
+       .init     = usb_init,
+       .exit    = usb_exit,
+       .unit    = usb_unit,
+};
+
+TEST_OPS_REGISTER(&usb_test_ops)
diff --git a/src/battery/battery-micro-emul.conf b/src/battery/battery-micro-emul.conf
new file mode 100644 (file)
index 0000000..3a3083a
--- /dev/null
@@ -0,0 +1,7 @@
+[LOWBAT]
+#low battery level
+Normal=100
+Warning=15
+Critical=5
+PowerOff=3
+RealOff=0
diff --git a/src/battery/battery-micro.conf b/src/battery/battery-micro.conf
new file mode 100644 (file)
index 0000000..3a3083a
--- /dev/null
@@ -0,0 +1,7 @@
+[LOWBAT]
+#low battery level
+Normal=100
+Warning=15
+Critical=5
+PowerOff=3
+RealOff=0
diff --git a/src/battery/battery-time.c b/src/battery/battery-time.c
new file mode 100644 (file)
index 0000000..3759949
--- /dev/null
@@ -0,0 +1,473 @@
+/*
+ * 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 <Ecore.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <vconf.h>
+#include <device-node.h>
+
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/log.h"
+
+#define CHARGING_STATE(x)      ((x) & CHRGR_FLAG)
+#define FULL_CAPACITY_RAW      (10000)
+#define FULL_CAPACITY          (100)
+#define BATTERY_FULL_THRESHOLD (98)
+#define MAX_COUNT_UNCHARGING   (10)
+#define MAX_COUNT_CHARGING     (10)
+#define PRINT_ALL_BATT_NODE(x) /*print_all_batt_node(x)*/
+#define POLLING_TIME           (30)    /* seconds */
+
+int (*get_battery_capacity_cb)(void);
+
+enum state_b {
+       B_UNCHARGING = 0,
+       B_CHARGING = 1,
+       B_END = 2
+};
+
+typedef struct _batt_node {
+       time_t clock;
+       int capacity;
+       struct _batt_node *preview;
+       struct _batt_node *next;
+} Batt_node;
+
+enum state_a {
+       A_TIMETOEMPTY = 0,
+       A_TIMETOFULL = 1,
+       A_END = 2
+};
+
+static Ecore_Timer *timeout_id = NULL;
+
+static Batt_node *batt_head[B_END];
+static Batt_node *batt_tail[B_END];
+static int MAX_VALUE_COUNT[B_END] = {MAX_COUNT_UNCHARGING, MAX_COUNT_CHARGING};
+static double avg_factor[B_END] = {-1.0, -1.0};
+static int full_capacity = 0;
+static int old_capacity = 0;
+static int charging_state = 0;
+static int multiply_value[B_END] = {-1, 1};
+extern int system_wakeup_flag;
+
+static int get_battery_capacity(void)
+{
+       int value = 0;
+       int ret = -1;
+
+       ret = device_get_property(DEVICE_TYPE_POWER,
+           PROP_POWER_CAPACITY, &value);
+
+       if (ret < 0)
+               return ret;
+
+       if (value < 0)
+               return 0;
+
+       return value;
+}
+
+static int get_battery_capacity_raw(void)
+{
+       int value = 0;
+       int ret = -1;
+
+       ret = device_get_property(DEVICE_TYPE_POWER,
+           PROP_POWER_CAPACITY_RAW, &value);
+
+       if (ret < 0)
+               return ret;
+
+       if (value < 0)
+               return 0;
+
+       return value;
+}
+
+static int get_battery_charge_full(void)
+{
+       int value = 0;
+       int ret = -1;
+
+       ret = device_get_property(DEVICE_TYPE_POWER,
+           PROP_POWER_CHARGE_FULL, &value);
+
+       if (ret < 0)
+               return ret;
+
+       if (value < 0)
+               return 0;
+
+       return value;
+}
+
+static void print_all_batt_node(enum state_b b_index)
+{
+       Batt_node *node = NULL;
+       int cnt = 0;
+
+       _I("print_all_batt_node [%d]", b_index);
+
+       if(b_index < 0 || b_index >= B_END)
+               return;
+
+       if(batt_head[b_index] == NULL)
+               return;
+
+       node = batt_head[b_index];
+       while(node != NULL) {
+               cnt++;
+               _I("[%d] capacity %5d, time %s", cnt, node->capacity,
+                               ctime(&node->clock));
+               node = node->next;
+       }
+}
+
+static int check_value_validity(enum state_b b_index,time_t clock,int capacity)
+{
+       time_t old_clock = 0;
+       int old_capacity = 0;
+       int capadiff = 0;
+
+       if(b_index < 0 || b_index >= B_END)
+               return -1;
+
+       if(batt_head[b_index] == NULL)
+               return 0;
+
+       old_capacity = batt_head[b_index]->capacity;
+
+       if(system_wakeup_flag == true) {
+               _E("check value validity : invalid cuz system suspend!");
+               system_wakeup_flag = false;
+               return -1;
+       }
+       /* capacity */
+       capadiff = capacity - old_capacity;
+       if((capadiff * multiply_value[b_index]) <= 0) {
+               _E("check value validity : capadiff(%d) wrong!", capadiff);
+               return -1;
+       }
+       return 0;
+}
+
+static int add_batt_node(enum state_b b_index, time_t clock, int capacity)
+{
+       Batt_node *node = NULL;
+
+       PRINT_ALL_BATT_NODE(b_index);
+
+       if(b_index < 0 || b_index >= B_END)
+               return -1;
+
+       node = (Batt_node *) malloc(sizeof(Batt_node));
+       if(node == NULL) {
+               _E("Not enough memory, add battery node fail!");
+               return -1;
+       }
+
+       node->clock = clock;
+       node->capacity = capacity;
+
+       if(batt_head[b_index] == NULL && batt_tail[b_index] == NULL) {
+               batt_head[b_index] = batt_tail[b_index] = node;
+               node->preview = NULL;
+               node->next = NULL;
+       } else {
+               node->next = batt_head[b_index];
+               node->preview = NULL;
+               batt_head[b_index]->preview = node;
+               batt_head[b_index] = node;
+       }
+       PRINT_ALL_BATT_NODE(b_index);
+       return 0;
+}
+
+static int reap_batt_node(enum state_b b_index, int max_count)
+{
+       Batt_node *node = NULL;
+       Batt_node *tmp = NULL;
+       int cnt = 0;
+
+       PRINT_ALL_BATT_NODE(b_index);
+
+       if(b_index < 0 || b_index >= B_END)
+               return -1;
+
+       if(max_count <= 0)
+               return -1;
+
+       node = batt_head[b_index];
+
+       while(node != NULL) {
+               if(cnt >= max_count) break;
+               cnt++;
+               node = node->next;
+       }
+
+       if(node != NULL && node != batt_tail[b_index]) {
+               batt_tail[b_index] = node;
+               node = node->next;
+               batt_tail[b_index]->next = NULL;
+               while(node != NULL) {
+                       tmp = node;
+                       node = node->next;
+                       free(tmp);
+               }
+       }
+       PRINT_ALL_BATT_NODE(b_index);
+       return 0;
+}
+
+static int del_all_batt_node(enum state_b b_index)
+{
+       Batt_node *node = NULL;
+
+       PRINT_ALL_BATT_NODE(b_index);
+
+       if(b_index < 0 || b_index >= B_END)
+               return -1;
+       if(batt_head[b_index] == NULL)
+               return 0;
+
+       while(batt_head[b_index] != NULL) {
+               node = batt_head[b_index];
+               batt_head[b_index] = batt_head[b_index]->next;
+               free(node);
+       }
+       batt_tail[b_index] = NULL;
+       PRINT_ALL_BATT_NODE(b_index);
+       return 0;
+}
+
+static float update_factor(enum state_b b_index)
+{
+       Batt_node *node = NULL;
+       double factor = 0.0;
+       double total_factor = 0.0;
+       int cnt = 0;
+       double timediff = 0.0;
+       double capadiff = 0.0;
+
+       if(b_index < 0 || b_index >= B_END)
+               return 0;
+
+       if(batt_head[b_index] == NULL || batt_head[b_index]->next == NULL)
+               return  avg_factor[b_index];
+
+       node = batt_head[b_index];
+       while(1) {
+               timediff = difftime(node->clock, node->next->clock);
+               capadiff = node->capacity - node->next->capacity;
+               if(capadiff < 0)
+                       capadiff*=(-1);
+               if(capadiff != 0)
+                       factor = timediff / capadiff;
+               total_factor += factor;
+
+               node = node->next;
+               cnt++;
+
+               /*_I("[%d] timediff(%lf) / capadiff(%lf) = factor(%lf)",
+                       cnt, timediff, capadiff, factor);*/
+               factor = 0.0;
+
+               if(node == NULL || node->next == NULL)
+                       break;
+               if(cnt >= MAX_VALUE_COUNT[b_index]) {
+                       reap_batt_node(b_index, MAX_VALUE_COUNT[b_index]);
+                       break;
+               }
+       }
+       total_factor /= (float)cnt;
+
+       return total_factor;
+}
+
+static void update_time(enum state_a a_index, int seconds)
+{
+       int clock;
+
+       if(a_index < 0 || a_index >= A_END)
+               return;
+
+       if(seconds <= 0)
+               return;
+
+       switch(a_index) {
+               case A_TIMETOFULL:
+                       vconf_set_int(VCONFKEY_PM_BATTERY_TIMETOFULL,
+                               seconds);
+                       break;
+               case A_TIMETOEMPTY:
+                       vconf_set_int(VCONFKEY_PM_BATTERY_TIMETOEMPTY,
+                               seconds);
+                       break;
+       }
+}
+
+static int battinfo_calculation(void)
+{
+       time_t clock;
+       int capacity = 0;
+       int estimated_time = 0;
+       int tmp = 0;
+
+       capacity = get_battery_capacity_cb();
+
+       if(capacity <= 0)
+               return -1;
+       if(capacity == old_capacity)
+               return 0;
+
+       old_capacity = capacity;
+
+       if(get_charging_status(&tmp) == 0)
+               charging_state = (tmp > 0 ? EINA_TRUE : EINA_FALSE);
+
+       clock = time(NULL);
+       if(charging_state == EINA_TRUE) {
+               del_all_batt_node(B_UNCHARGING);
+               if((capacity * 100 / full_capacity)
+                               >= BATTERY_FULL_THRESHOLD) {
+                       if (get_battery_charge_full()) {
+                               del_all_batt_node(B_CHARGING);
+                               _I("battery fully charged!");
+                               update_time(A_TIMETOFULL, 0);
+                               return 0;
+                       }
+               }
+               if(batt_head[B_CHARGING] == NULL) {
+                       add_batt_node(B_CHARGING, clock, capacity);
+               } else {
+                       add_batt_node(B_CHARGING, clock, capacity);
+                       avg_factor[B_CHARGING] = update_factor(B_CHARGING);
+               }
+               estimated_time = (float)(full_capacity - capacity) *
+                               avg_factor[B_CHARGING];
+               update_time(A_TIMETOFULL, estimated_time);
+       } else {
+               del_all_batt_node(B_CHARGING);
+               if(system_wakeup_flag == true) {
+                       del_all_batt_node(B_UNCHARGING);
+                       system_wakeup_flag = false;
+               }
+               if(batt_head[B_UNCHARGING] == NULL) {
+                       add_batt_node(B_UNCHARGING, clock, capacity);
+               } else {
+                       add_batt_node(B_UNCHARGING, clock, capacity);
+                       avg_factor[B_UNCHARGING] = update_factor(B_UNCHARGING);
+               }
+               estimated_time = (float)capacity * avg_factor[B_UNCHARGING];
+               update_time(A_TIMETOEMPTY, estimated_time);
+       }
+       return 0;
+}
+
+static Eina_Bool battinfo_cb(void *data)
+{
+       battinfo_calculation();
+       return ECORE_CALLBACK_RENEW;
+}
+
+static int init_battery_func(void)
+{
+       int ret = -1;
+
+       ret = get_battery_capacity_raw();
+       if(ret >= 0) {
+               get_battery_capacity_cb = get_battery_capacity_raw;
+               full_capacity = FULL_CAPACITY_RAW;
+               _I("init_battery_func : full capacity(%d)", full_capacity);
+               return 0;
+       }
+
+       ret = get_battery_capacity();
+       if(ret >= 0) {
+               get_battery_capacity_cb = get_battery_capacity;
+               full_capacity = FULL_CAPACITY;
+               _I("init_battery_func : full capacity(%d)", full_capacity);
+               return 0;
+       }
+
+       _E("init_battery_func : fail to get battery info!");
+       return -1;
+}
+
+static int start_battinfo_gathering(int timeout)
+{
+       int ret;
+
+       _I("Start battery gathering!");
+
+       if(timeout <= 0) {
+               _E("invalid timeout value [%d]!", timeout);
+               return -1;
+       }
+       if(init_battery_func() != 0)
+               return -1;
+
+       old_capacity = 0;
+       battinfo_calculation();
+
+       if(timeout > 0) {
+               /* Using g_timer for gathering battery info */
+               timeout_id = ecore_timer_add(timeout,
+                       (Ecore_Task_Cb)battinfo_cb, NULL);
+       }
+
+       return 0;
+}
+
+static void end_battinfo_gathering(void)
+{
+       _I("End battery gathering!");
+
+       if (timeout_id) {
+               ecore_timer_del(timeout_id);
+               timeout_id = NULL;
+       }
+
+       del_all_batt_node(B_UNCHARGING);
+       del_all_batt_node(B_CHARGING);
+}
+
+static void battery_init(void *data)
+{
+       start_battinfo_gathering(POLLING_TIME);
+}
+
+static void battery_exit(void *data)
+{
+       end_battinfo_gathering();
+}
+
+static const struct device_ops battery_time_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "battery-time",
+       .init     = battery_init,
+       .exit     = battery_exit,
+};
+
+DEVICE_OPS_REGISTER(&battery_time_device_ops)
+
diff --git a/src/battery/battery.c b/src/battery/battery.c
new file mode 100644 (file)
index 0000000..a48ddfa
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ */
+
+#define USE_LOGD 1
+
+#include <stdbool.h>
+#include <assert.h>
+#include <limits.h>
+#include "core/log.h"
+#include "core/devices.h"
+#include "core/udev.h"
+#include "device-node.h"
+#include "core/device-handler.h"
+#include "core/device-notifier.h"
+#include "core/edbus-handler.h"
+
+/*
+ * get_capacity - get battery capacity value
+ * using device_get_property
+ */
+static int get_capacity(void)
+{
+       int val, ret;
+
+       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CAPACITY, &val);
+       if (ret < 0) {
+               _E("fail to get battery capacity value");
+               val = ret;
+       }
+       return val;
+}
+
+static int update_battery(void *data)
+{
+       static int capacity = -1;
+       static int charge_now = -1;
+
+       if (battery.capacity != capacity) {
+               _D("capacity is changed %d -> %d", capacity, battery.capacity);
+               capacity = battery.capacity;
+       }
+
+       if (battery.charge_now != charge_now) {
+               _D("chaging status is changed %d -> %d", charge_now, battery.charge_now);
+               charge_now = battery.charge_now;
+       }
+       return 0;
+}
+
+static DBusMessage *edbus_get_percent(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = battery.capacity;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_get_percent_raw(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret, val;
+
+       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CAPACITY_RAW, &val);
+       if (ret < 0)
+               goto exit;
+
+       if (val > 10000)
+               val = 10000;
+
+       ret = val;
+
+exit:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_is_full(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = battery.charge_full;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_get_health(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = battery.health;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "GetPercent",    NULL,   "i", edbus_get_percent },
+       { "GetPercentRaw", NULL,   "i", edbus_get_percent_raw },
+       { "IsFull",        NULL,   "i", edbus_is_full },
+       { "GetHealth",     NULL,   "i", edbus_get_health },
+       /* Add methods here */
+};
+
+/* battery ops init funcion */
+static void battery_init(void *data)
+{
+       int ret;
+
+       /* init dbus interface */
+       ret = register_edbus_method(DEVICED_PATH_BATTERY,
+                       edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       /* get initial battery capacity */
+       battery.capacity = get_capacity();
+       battery.charge_now = POWER_SUPPLY_STATUS_UNKNOWN;
+
+       /* register notifier */
+       register_notifier(DEVICE_NOTIFIER_POWER_SUPPLY, update_battery);
+}
+
+/* battery ops exit funcion */
+static void battery_exit(void *data)
+{
+       /* unregister notifier */
+       unregister_notifier(DEVICE_NOTIFIER_POWER_SUPPLY, update_battery);
+}
+
+static const struct device_ops battery_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "battery",
+       .init     = battery_init,
+       .exit     = battery_exit,
+};
+
+DEVICE_OPS_REGISTER(&battery_device_ops)
diff --git a/src/battery/battery.conf b/src/battery/battery.conf
new file mode 100644 (file)
index 0000000..48402cc
--- /dev/null
@@ -0,0 +1,7 @@
+[LOWBAT]
+#low battery level
+Normal=100
+Warning=15
+Critical=5
+PowerOff=1
+RealOff=0
diff --git a/src/battery/battery.h b/src/battery/battery.h
new file mode 100644 (file)
index 0000000..b1828bd
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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 __BATTERY_H__
+#define __BATTERY_H__
+
+#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 LOWBAT_OPT_WARNING             1
+#define LOWBAT_OPT_POWEROFF            2
+#define LOWBAT_OPT_CHARGEERR           3
+#define LOWBAT_OPT_CHECK               4
+
+struct battery_config_info {
+       int normal;
+       int warning;
+       int critical;
+       int poweroff;
+       int realoff;
+};
+
+int battery_charge_err_low_act(void *data);
+int battery_charge_err_high_act(void *data);
+#endif /* __BATTERY_H__ */
diff --git a/src/battery/config.c b/src/battery/config.c
new file mode 100644 (file)
index 0000000..4dd42c1
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 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 <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <stdbool.h>
+#include <assert.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/config-parser.h"
+#include "battery.h"
+#include "config.h"
+
+#define BAT_CONF_FILE  "/etc/deviced/battery.conf"
+
+static int load_config(struct parse_result *result, void *user_data)
+{
+       struct battery_config_info *info = user_data;
+       char *name;
+       char *value;
+
+       _D("%s,%s,%s", result->section, result->name, result->value);
+
+       if (!info)
+               return -EINVAL;
+
+       if (!MATCH(result->section, "LOWBAT"))
+               return -EINVAL;
+
+       name = result->name;
+       value = result->value;
+       if (MATCH(name, "Normal"))
+               info->normal = atoi(value);
+       else if (MATCH(name, "Warning"))
+               info->warning = atoi(value);
+       else if (MATCH(name, "Critical"))
+               info->critical = atoi(value);
+       else if (MATCH(name, "PowerOff"))
+               info->poweroff = atoi(value);
+       else if (MATCH(name, "RealOff"))
+               info->realoff = atoi(value);
+
+       return 0;
+}
+
+void battery_config_load(struct battery_config_info *info)
+{
+       int ret;
+
+       ret = config_parse(BAT_CONF_FILE, load_config, info);
+       if (ret < 0)
+               _E("Failed to load %s, %d Use default value!", BAT_CONF_FILE, ret);
+}
diff --git a/src/battery/config.h b/src/battery/config.h
new file mode 100644 (file)
index 0000000..5f68716
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 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 __BATTERY_CONFIG_H__
+#define __BATTERY_CONFIG_H__
+
+void battery_config_load(struct battery_config_info *info);
+#endif /* __BATTERY_CONFIG_H__ */
diff --git a/src/battery/lowbat-handler.c b/src/battery/lowbat-handler.c
new file mode 100644 (file)
index 0000000..3d82613
--- /dev/null
@@ -0,0 +1,627 @@
+/*
+ * 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 <stdbool.h>
+#include <assert.h>
+#include <limits.h>
+#include <vconf.h>
+#include <fcntl.h>
+
+#include "battery.h"
+#include "config.h"
+#include "core/log.h"
+#include "core/launch.h"
+#include "core/noti.h"
+#include "core/queue.h"
+#include "core/data.h"
+#include "core/devices.h"
+#include "core/device-handler.h"
+#include "core/device-notifier.h"
+#include "core/common.h"
+#include "core/list.h"
+#include "device-node.h"
+#include "display/setting.h"
+#include "display/poll.h"
+#include "core/edbus-handler.h"
+#include "core/power-supply.h"
+
+#define PREDEF_LOWBAT                  "lowbat"
+#define PREDEF_LOWBAT_CHANGE_FREQ      "lowbat_change_freq"
+
+#define CHARGE_POWERSAVE_FREQ_ACT      "charge_powersave_freq_act"
+#define CHARGE_RELEASE_FREQ_ACT                "charge_release_freq_act"
+
+
+#define BATTERY_CHARGING       65535
+#define BATTERY_UNKNOWN                -1
+#define BATTERY_FULL           100
+
+#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 CHARGE_ERROR_LOW_ACT                   "charge_error_low_act"
+#define CHARGE_ERROR_HIGH_ACT                  "charge_error_high_act"
+#define CHARGE_ERROR_OVP_ACT                   "charge_error_ovp_act"
+#define WAITING_INTERVAL       10
+
+#define LOWBAT_CPU_CTRL_ID     "id6"
+#define LOWBAT_CPU_FREQ_RATE   (0.7)
+
+#define LOWBAT_POPUP_NAME "lowbat-syspopup"
+#define LOWBAT_EXEC_PATH               PREFIX"/bin/lowbatt-popup"
+
+struct popup_data {
+       char *name;
+       char *key;
+       char *value;
+};
+
+struct lowbat_process_entry {
+       int old;
+       int now;
+       int (*func) (void *data);
+};
+
+static int cur_bat_state = BATTERY_UNKNOWN;
+static int cur_bat_capacity = -1;
+
+static int lowbat_popup_option = 0;
+static int lowbat_freq = -1;
+static struct battery_config_info battery_info;
+
+static dd_list *lpe = NULL;
+static int scenario_count = 0;
+
+static int lowbat_initialized(void *data)
+{
+       static int status;
+
+       if (!data)
+               return status;
+
+       status = *(int *)data;
+       return status;
+}
+
+int lowbat_scenario(int old, int now, void *data)
+{
+       dd_list *n;
+       struct lowbat_process_entry *scenario;
+       int found = 0;
+
+       DD_LIST_FOREACH(lpe, n, scenario) {
+               if (old != scenario->old || now != scenario->now)
+                       continue;
+               if (!scenario->func)
+                       continue;
+               scenario->func(data);
+               found = 1;
+               break;
+       }
+       return found;
+}
+
+int lowbat_add_scenario(int old, int now, int (*func)(void *data))
+{
+       struct lowbat_process_entry *scenario;
+
+       _I("%d %d, %x", old, now, func);
+
+       if (!func) {
+               _E("invalid func address!");
+               return -EINVAL;
+       }
+
+       scenario = malloc(sizeof(struct lowbat_process_entry));
+       if (!scenario) {
+               _E("Fail to malloc for notifier!");
+               return -ENOMEM;
+       }
+
+       scenario->old = old;
+       scenario->now = now;
+       scenario->func = func;
+
+       DD_LIST_APPEND(lpe, scenario);
+       scenario_count++;
+       return 0;
+}
+
+static void print_lowbat_state(unsigned int bat_percent)
+{
+#if 0
+       int i;
+       for (i = 0; i < BAT_MON_SAMPLES; i++)
+               _D("\t%d", recent_bat_percent[i]);
+#endif
+}
+
+int battery_check_act(void *data)
+{
+       notify_action(PREDEF_LOWBAT, 1, CHARGE_CHECK_ACT);
+       return 0;
+}
+
+int battery_warning_low_act(void *data)
+{
+       notify_action(PREDEF_LOWBAT, 1, WARNING_LOW_BAT_ACT);
+       return 0;
+}
+
+int battery_critical_low_act(void *data)
+{
+       notify_action(PREDEF_LOWBAT, 1, CRITICAL_LOW_BAT_ACT);
+       return 0;
+}
+
+int battery_power_off_act(void *data)
+{
+       vconf_set_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, VCONFKEY_SYSMAN_POWER_OFF_DIRECT);
+       return 0;
+}
+
+int battery_charge_err_act(void *data)
+{
+       notify_action(PREDEF_LOWBAT, 1, CHARGE_ERROR_ACT);
+       return 0;
+}
+
+int battery_charge_err_low_act(void *data)
+{
+       notify_action(PREDEF_LOWBAT, 1, CHARGE_ERROR_LOW_ACT);
+       return 0;
+}
+
+int battery_charge_err_high_act(void *data)
+{
+       notify_action(PREDEF_LOWBAT, 1, CHARGE_ERROR_HIGH_ACT);
+       return 0;
+}
+
+int battery_charge_err_ovp_act(void *data)
+{
+       notify_action(PREDEF_LOWBAT, 1, CHARGE_ERROR_OVP_ACT);
+       return 0;
+}
+
+static int battery_charge_act(void *data)
+{
+#ifdef NOUSE
+       int val;
+       char argstr[128];
+
+       /* instead of adding action to the queue, execute it right here */
+       if (device_get_property(DEVTYPE_JACK, JACK_PROP_TA_ONLINE, &val) == 0
+           && val == 1) {
+               snprintf(argstr, 128, "-t 4");
+               launch_after_kill_if_exist(LOWBAT_EXEC_PATH, argstr);
+       }
+#endif
+       return 0;
+}
+
+static void lowbat_scenario_init(void)
+{
+       lowbat_add_scenario(battery_info.normal, battery_info.warning, battery_warning_low_act);
+       lowbat_add_scenario(battery_info.warning, battery_info.critical, battery_warning_low_act);
+       lowbat_add_scenario(battery_info.critical, battery_info.poweroff, battery_critical_low_act);
+       lowbat_add_scenario(battery_info.poweroff, battery_info.realoff, battery_power_off_act);
+       lowbat_add_scenario(battery_info.normal, battery_info.critical, battery_warning_low_act);
+       lowbat_add_scenario(battery_info.warning, battery_info.poweroff, battery_critical_low_act);
+       lowbat_add_scenario(battery_info.critical, battery_info.realoff, battery_power_off_act);
+       lowbat_add_scenario(battery_info.normal, battery_info.poweroff, battery_critical_low_act);
+       lowbat_add_scenario(battery_info.warning, battery_info.realoff, battery_power_off_act);
+       lowbat_add_scenario(battery_info.normal, battery_info.realoff, battery_power_off_act);
+       lowbat_add_scenario(battery_info.realoff, battery_info.realoff, battery_power_off_act);
+       lowbat_add_scenario(battery_info.realoff, battery_info.normal, battery_check_act);
+       lowbat_add_scenario(battery_info.realoff, battery_info.warning, battery_check_act);
+       lowbat_add_scenario(battery_info.realoff, battery_info.critical, battery_check_act);
+       lowbat_add_scenario(battery_info.realoff, battery_info.poweroff, battery_check_act);
+}
+
+static void 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) {
+               _E("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 lowbat_process(int bat_percent, void *ad)
+{
+       int new_bat_capacity;
+       int new_bat_state;
+       int vconf_state = -1;
+       int i, ret = 0;
+       int status = -1;
+       bool low_bat = false;
+       bool full_bat = false;
+       int extreme = 0;
+       int result = 0;
+
+       new_bat_capacity = bat_percent;
+       if (new_bat_capacity < 0)
+               return -EINVAL;
+       change_lowbat_level(new_bat_capacity);
+       pm_lock_internal(INTERNAL_LOCK_BATTERY, LCD_OFF, STAY_CUR_STATE, 0);
+
+       if (new_bat_capacity != cur_bat_capacity) {
+               _D("[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) {
+               _E("vconf_get_int() failed");
+               result = -EIO;
+               goto exit;
+       }
+
+       if (new_bat_capacity <= battery_info.realoff) {
+               if (battery.charge_now) {
+                       new_bat_state = battery_info.poweroff;
+                       if (vconf_state != VCONFKEY_SYSMAN_BAT_POWER_OFF)
+                               status = VCONFKEY_SYSMAN_BAT_POWER_OFF;
+               } else {
+                       new_bat_state = battery_info.realoff;
+                       if (vconf_state != VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF)
+                               status = VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF;
+               }
+       } else if (new_bat_capacity <= battery_info.poweroff) {
+               new_bat_state = battery_info.poweroff;
+               if (vconf_state != VCONFKEY_SYSMAN_BAT_POWER_OFF)
+                       status = VCONFKEY_SYSMAN_BAT_POWER_OFF;
+       } else if (new_bat_capacity <= battery_info.critical) {
+               new_bat_state = battery_info.critical;
+               if (vconf_state != VCONFKEY_SYSMAN_BAT_CRITICAL_LOW)
+                       status = VCONFKEY_SYSMAN_BAT_CRITICAL_LOW;
+       } else if (new_bat_capacity <= battery_info.warning) {
+               new_bat_state = battery_info.warning;
+               if (vconf_state != VCONFKEY_SYSMAN_BAT_WARNING_LOW)
+                       status = VCONFKEY_SYSMAN_BAT_WARNING_LOW;
+       } else {
+               new_bat_state = battery_info.normal;
+               if (new_bat_capacity == BATTERY_FULL) {
+                       if (battery.charge_full) {
+                               if (vconf_state != VCONFKEY_SYSMAN_BAT_FULL)
+                                       status = VCONFKEY_SYSMAN_BAT_FULL;
+                               full_bat = true;
+                       } else {
+                               if (vconf_state != VCONFKEY_SYSMAN_BAT_NORMAL)
+                                       status = VCONFKEY_SYSMAN_BAT_NORMAL;
+                       }
+               } else {
+                       if (vconf_state != VCONFKEY_SYSMAN_BAT_NORMAL)
+                               status = VCONFKEY_SYSMAN_BAT_NORMAL;
+               }
+       }
+
+
+       if (status != -1) {
+               ret = vconf_set_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, status);
+               power_supply_broadcast(CHARGE_LEVEL_SIGNAL, status);
+               if (update_pm_setting)
+                       update_pm_setting(SETTING_LOW_BATT, status);
+       }
+
+       if (ret < 0) {
+               result = -EIO;
+               goto exit;
+       }
+
+       if (vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &extreme) == 0 && extreme == TRUE &&
+           (status > VCONFKEY_SYSMAN_BAT_POWER_OFF && status <= VCONFKEY_SYSMAN_BAT_FULL))
+               if (vconf_set_int(VCONFKEY_PM_KEY_IGNORE, FALSE) == 0)
+                       _I("release key ignore");
+
+       if (new_bat_capacity <= battery_info.warning)
+               low_bat = true;
+
+       device_notify(DEVICE_NOTIFIER_LOWBAT, (void*)low_bat);
+
+       if (cur_bat_state == new_bat_state && new_bat_state > battery_info.realoff)
+               goto exit;
+
+       if (cur_bat_state == BATTERY_UNKNOWN)
+               cur_bat_state = battery_info.normal;
+       result = lowbat_scenario(cur_bat_state, new_bat_state, NULL);
+       if (result)
+               _I("cur_bat_state %d, new_bat_state %d", cur_bat_state, new_bat_state);
+       cur_bat_state = new_bat_state;
+exit:
+       pm_unlock_internal(INTERNAL_LOCK_BATTERY, LCD_OFF, PM_SLEEP_MARGIN);
+
+       return result;
+}
+
+static int lowbat_read()
+{
+       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 change_lowbat_cpu_freq(int bat_percent)
+{
+       static int init_cpu_freq = 0;
+       static int power_save = 0;
+       if (cur_bat_capacity == bat_percent)
+               return;
+
+       if (bat_percent > battery_info.poweroff && init_cpu_freq == 0) {
+               init_cpu_freq = 1;
+               notify_action(PREDEF_LOWBAT_CHANGE_FREQ, 1, CHARGE_RELEASE_FREQ_ACT);
+               return;
+       }
+
+       if (bat_percent <= battery_info.poweroff && power_save == 0) {
+               power_save = 1;
+               notify_action(PREDEF_LOWBAT_CHANGE_FREQ, 1, CHARGE_POWERSAVE_FREQ_ACT);
+       } else if (power_save == 1) {
+               power_save = 0;
+               notify_action(PREDEF_LOWBAT_CHANGE_FREQ, 1, CHARGE_RELEASE_FREQ_ACT);
+       }
+}
+
+static int check_lowbat_percent(int *pct)
+{
+       int bat_percent;
+
+       bat_percent = lowbat_read();
+       if (bat_percent < 0) {
+               _E("[BATMON] Cannot read battery gage. stop read fuel gage");
+               return -ENODEV;
+       }
+       if (bat_percent > 100)
+               bat_percent = 100;
+       change_lowbat_level(bat_percent);
+       change_lowbat_cpu_freq(bat_percent);
+       *pct = bat_percent;
+       return 0;
+}
+
+void lowbat_monitor(void *data)
+{
+       int bat_percent, r;
+
+       r = lowbat_initialized(NULL);
+       if (!r)
+               return;
+
+       if (data == NULL) {
+               r = check_lowbat_percent(&bat_percent);
+               if (r < 0)
+                       return;
+       } else
+               bat_percent = *(int *)data;
+       print_lowbat_state(bat_percent);
+       lowbat_process(bat_percent, NULL);
+}
+
+/* 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) {
+               _E("FAIL: device_get_property(): [BATMON] battery check : %d", ret);
+       }
+       _D("[BATMON] battery check : %d", ret);
+
+       return ret;
+}
+
+static int booting_done(void *data)
+{
+       static int done = 0;
+
+       if (data == NULL)
+               goto out;
+       done = (int)data;
+       if (!done)
+               goto out;
+       _I("booting done");
+out:
+       return done;
+}
+
+int lowbat_action(int argc, char **argv)
+{
+       int ret, state=0;
+       char argstr[128];
+       char* option = NULL;
+       char *value;
+       static int launched_poweroff = 0;
+       pid_t pid;
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+
+       if (argc < 1)
+               return -1;
+
+       if (strcmp(argv[0], POWER_OFF_BAT_ACT))
+               launched_poweroff = 0;
+
+       if (!strcmp(argv[0], CRITICAL_LOW_BAT_ACT)) {
+               value = "extreme";
+               lowbat_popup_option = LOWBAT_OPT_CHECK;
+       } else if (!strcmp(argv[0], WARNING_LOW_BAT_ACT)) {
+               if (is_factory_mode() == 1)
+                       return 0;
+               value = "warning";
+               lowbat_popup_option = LOWBAT_OPT_WARNING;
+       } else if (!strcmp(argv[0], POWER_OFF_BAT_ACT)) {
+               value = "poweroff";
+               lowbat_popup_option = LOWBAT_OPT_POWEROFF;
+       } else if (!strcmp(argv[0], CHARGE_ERROR_ACT)) {
+               value = "chargeerr";
+               lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
+       } else if (!strcmp(argv[0], CHARGE_ERROR_LOW_ACT)) {
+               value = "chargeerrlow";
+               lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
+       } else if (!strcmp(argv[0], CHARGE_ERROR_HIGH_ACT)) {
+               value = "chargeerrhigh";
+               lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
+       } else if (!strcmp(argv[0], CHARGE_ERROR_OVP_ACT)) {
+               value = "chargeerrovp";
+               lowbat_popup_option = LOWBAT_OPT_CHARGEERR;
+       } else if (!strcmp(argv[0], CHARGE_CHECK_ACT)) {
+               launched_poweroff = 0;
+               return 0;
+       } else
+               return -1;
+       _D("%s", value);
+       ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &state);
+       if (state == 1 || ret != 0 || booting_done(NULL)) {
+
+               if (launched_poweroff == 1) {
+                       _I("will be foreced power off");
+                       do_poweroff(0, NULL);
+                       return 0;
+               }
+
+               if (lowbat_popup_option == LOWBAT_OPT_POWEROFF)
+                       launched_poweroff = 1;
+
+               pid = predefine_get_pid(LOWBAT_EXEC_PATH);
+               if (pid > 0) {
+                       _I("pre launched %s destroy", LOWBAT_EXEC_PATH);
+                       kill(pid, SIGTERM);
+               }
+               if (apps == NULL) {
+                       apps = find_device("apps");
+                       if (apps == NULL)
+                               return 0;
+               }
+               params = malloc(sizeof(struct popup_data));
+               if (params == NULL) {
+                       _E("Malloc failed");
+                       return -1;
+               }
+               pm_change_internal(getpid(), LCD_NORMAL);
+               params->name = LOWBAT_POPUP_NAME;
+               params->key = POPUP_KEY_CONTENT;
+               params->value = strdup(value);
+               apps->init((void *)params);
+               free(params->value);
+               free(params);
+       } else {
+               _D("boot-animation running yet");
+       }
+
+       return 0;
+}
+
+static int check_power_save_mode(void)
+{
+       int ret = 0;
+       int power_saving_cpu_stat = -1;
+
+       ret = vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_CPU,
+                       &power_saving_cpu_stat);
+       if (ret < 0) {
+               _E("failed to get vconf key");
+               return ret;
+       }
+
+       if (power_saving_cpu_stat == 1)
+               ret = 1;
+       return ret;
+}
+
+int change_freq_action(int argc, char **argv)
+{
+       int val = 0;
+
+       if (argc < 1)
+               return -1;
+
+       if (!strcmp(argv[0], CHARGE_POWERSAVE_FREQ_ACT))
+               val = 1;
+       device_notify(DEVICE_NOTIFIER_PMQOS_LOWBAT, (void*)val);
+       return 0;
+}
+
+static int lowbat_monitor_init(void *data)
+{
+       int status = 1;
+
+       lowbat_initialized(&status);
+       unregister_notifier(DEVICE_NOTIFIER_POWER_SUPPLY, lowbat_monitor_init);
+       battery_config_load(&battery_info);
+       _I("%d %d %d %d %d", battery_info.normal, battery_info.warning,
+               battery_info.critical, battery_info.poweroff, battery_info.realoff);
+       lowbat_scenario_init();
+       register_action(PREDEF_LOWBAT, lowbat_action, NULL, NULL);
+       register_action(PREDEF_LOWBAT_CHANGE_FREQ, change_freq_action, NULL, NULL);
+       lowbat_process(battery.capacity, NULL);
+       return 0;
+}
+
+static void lowbat_init(void *data)
+{
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+       register_notifier(DEVICE_NOTIFIER_POWER_SUPPLY, lowbat_monitor_init);
+}
+
+static void lowbat_exit(void *data)
+{
+       int status = 0;
+
+       lowbat_initialized(&status);
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+}
+
+static const struct device_ops lowbat_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "lowbat",
+       .init     = lowbat_init,
+       .exit    = lowbat_exit,
+};
+
+DEVICE_OPS_REGISTER(&lowbat_device_ops)
diff --git a/src/board/board-info.c b/src/board/board-info.c
new file mode 100644 (file)
index 0000000..32b53f6
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * 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 <fcntl.h>
+
+#include "core/log.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+#include "core/common.h"
+
+#define FILE_BUFF_MAX  1024
+#define NOT_INITIALIZED        (-1)
+
+#define METHOD_GET_SERIAL      "GetSerial"
+#define SERIAL_PATH_NAME       "/csa/imei/serialno.dat"
+
+#define METHOD_GET_REVISION    "GetHWRev"
+#define PATH_NAME              "/proc/cpuinfo"
+#define REVISION_NAME  "Revision"
+#define TOK_DELIMITER  ":"
+#define END_DELIMITER  " \n"
+
+#define CONVERT_TYPE   10
+#define REVISION_SIZE  4
+
+static int read_from_file(const char *path, char *buf, size_t size)
+{
+       int fd;
+       size_t count;
+
+       if (!path)
+               return -1;
+
+       fd = open(path, O_RDONLY, 0);
+       if (fd == -1) {
+               _E("Could not open '%s'", path);
+               return -1;
+       }
+
+       count = read(fd, buf, size);
+
+       if (count > 0) {
+               count = (count < size) ? count : size - 1;
+               while (count > 0 && buf[count - 1] == '\n')
+                       count--;
+               buf[count] = '\0';
+       } else {
+               buf[0] = '\0';
+       }
+
+       close(fd);
+
+       return 0;
+}
+
+static int get_revision(char *rev)
+{
+       char buf[FILE_BUFF_MAX];
+       char *tag;
+       char *start, *ptr;
+       long rev_num;
+       const int radix = 16;
+
+       if (rev == NULL) {
+               _E("Invalid argument !\n");
+               return -1;
+       }
+
+       if (read_from_file(PATH_NAME, buf, FILE_BUFF_MAX) < 0) {
+               _E("fail to read %s\n", PATH_NAME);
+               return -1;
+       }
+
+       tag = strstr(buf, REVISION_NAME);
+       if (tag == NULL) {
+               _E("cannot find Hardware in %s\n", PATH_NAME);
+               return -1;
+       }
+
+       start = strstr(tag, TOK_DELIMITER);
+       if (start == NULL) {
+               _E("cannot find Hardware in %s\n", PATH_NAME);
+               return -1;
+       }
+
+       start ++;
+       ptr = strtok(start, END_DELIMITER);
+       ptr += strlen(ptr);
+       ptr -=2;
+
+       memset(rev, 0x00, REVISION_SIZE);
+       rev_num = strtol(ptr, NULL, radix);
+       sprintf(rev, "%d", rev_num);
+
+       return 0;
+}
+
+static DBusMessage *dbus_revision_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char rev[FILE_BUFF_MAX];
+       char *ptr;
+       static int ret = NOT_INITIALIZED;
+
+       if (ret != NOT_INITIALIZED)
+               goto out;
+       ret = get_revision(rev);
+       if (ret == 0)
+               ret = strtol(rev, &ptr, CONVERT_TYPE);
+out:
+       _D("rev : %d", ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static int get_serial(unsigned char *buf)
+{
+       int fd;
+       int r;
+       int ret = 0;
+
+       fd = open(SERIAL_PATH_NAME, O_RDONLY, 0);
+       if (fd < 0)
+               return -ENOENT;
+
+       r = read(fd, buf, FILE_BUFF_MAX);
+       if ((r >= 0) && (r < FILE_BUFF_MAX))
+               buf[r] = '\0';
+       else
+               ret = -EIO;
+
+       close(fd);
+       return ret;
+}
+
+static DBusMessage *dbus_serial_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter, arr;
+       DBusMessage *reply;
+       static int len = 0;
+       static char buf[FILE_BUFF_MAX];
+       static char *param = buf;
+       static int ret = NOT_INITIALIZED;
+
+       if (ret == 0)
+               goto out;
+       ret = get_serial(buf);
+       if (ret == 0) {
+               len = strlen(buf);
+               goto out;
+       }
+       _E("fail to get serial");
+out:
+       _D("serial : %s %d", buf, len);
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &param);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { METHOD_GET_SERIAL,   NULL, "si", dbus_serial_handler },
+       { METHOD_GET_REVISION,   NULL, "i", dbus_revision_handler },
+};
+
+static void board_init(void *data)
+{
+       int ret;
+
+       ret = register_edbus_method(DEVICED_PATH_BOARD, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+}
+
+static const struct device_ops board_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "board",
+       .init     = board_init,
+};
+
+DEVICE_OPS_REGISTER(&board_device_ops)
diff --git a/src/control/control.c b/src/control/control.c
new file mode 100644 (file)
index 0000000..dcb21a9
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * 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 <assert.h>
+#include <sys/types.h>
+#include <dd-control.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+
+#define CONTROL_HANDLER_NAME           "control"
+#define CONTROL_GETTER_NAME                    "getcontrol"
+
+static const struct control_device {
+       const int id;
+       const char *name;
+} devices[] = {
+       /* Add id & ops to provide start/stop control */
+       { DEVICE_CONTROL_MMC,               "mmc" },
+       { DEVICE_CONTROL_USBCLIENT,   "usbclient" },
+       { DEVICE_CONTROL_RGBLED,         "rgbled" },
+};
+
+static int control_handler(int argc, char **argv)
+{
+       int i;
+       int pid;
+       int device;
+       bool enable;
+       int ret;
+       const struct device_ops *dev_ops;
+
+       _I("argc : %d", argc);
+       for (i = 0; i < argc; ++i)
+               _I("[%2d] %s", i, argv[i]);
+
+       if (argc > 5) {
+               _E("Invalid argument");
+               errno = EINVAL;
+               return -1;
+       }
+
+       pid = atoi(argv[0]);
+       device = atoi(argv[1]);
+       enable = atoi(argv[2]);
+       _I("pid : %d, device : %d, enable :%d", pid, device, enable);
+
+       for (i = 0; i < ARRAY_SIZE(devices); i++)
+               if (devices[i].id == device)
+                       break;
+
+       if (i >= ARRAY_SIZE(devices))
+               return -EINVAL;
+
+       dev_ops = find_device(devices[i].name);
+       if (!dev_ops)
+               return -ENODEV;
+
+       if (enable)
+               ret = device_start(dev_ops);
+       else
+               ret = device_stop(dev_ops);
+
+       return ret;
+}
+
+static int get_control_handler(int argc, char **argv)
+{
+       int i;
+       int pid;
+       int device;
+       bool enable;
+       int ret;
+       const struct device_ops *dev_ops;
+
+       _I("argc : %d", argc);
+       for (i = 0; i < argc; ++i)
+               _I("[%2d] %s", i, argv[i]);
+
+       if (argc > 4) {
+               _E("Invalid argument");
+               errno = EINVAL;
+               return -1;
+       }
+
+       pid = atoi(argv[0]);
+       device = atoi(argv[1]);
+       _I("pid : %d, device : %d", pid, device);
+
+       for (i = 0; i < ARRAY_SIZE(devices); i++)
+               if (devices[i].id == device)
+                       break;
+
+       if (i >= ARRAY_SIZE(devices))
+               return -EINVAL;
+
+       dev_ops = find_device(devices[i].name);
+       if (!dev_ops)
+               return -ENODEV;
+
+       return device_get_status(dev_ops);
+}
+
+
+static DBusMessage *dbus_control_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+       char *argv[3];
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv[0],
+                   DBUS_TYPE_STRING, &argv[1],
+                   DBUS_TYPE_STRING, &argv[2], DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       ret = control_handler(argc, (char **)&argv);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *dbus_get_control_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+       char *argv[2];
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv[0],
+                   DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       ret = get_control_handler(argc, (char **)&argv);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { CONTROL_HANDLER_NAME, "sisss", "i", dbus_control_handler     },
+       { CONTROL_GETTER_NAME ,  "siss", "i", dbus_get_control_handler },
+};
+
+static void control_init(void *data)
+{
+       int ret;
+
+       ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       register_action(CONTROL_HANDLER_NAME, control_handler, NULL, NULL);
+}
+
+static const struct device_ops control_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "control",
+       .init     = control_init,
+};
+
+DEVICE_OPS_REGISTER(&control_device_ops)
diff --git a/src/core/common.c b/src/core/common.c
new file mode 100644 (file)
index 0000000..7370ce0
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ * 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 <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <poll.h>
+#include <mntent.h>
+#include "log.h"
+
+#define PERMANENT_DIR          "/tmp/permanent"
+#define VIP_DIR                        "/tmp/vip"
+#define BUFF_MAX 255
+
+/**
+ * Opens "/proc/$pid/oom_score_adj" file for w/r;
+ * Return: FILE pointer or NULL
+ */
+FILE * open_proc_oom_score_adj_file(int pid, const char *mode)
+{
+        char buf[32];
+        FILE *fp;
+
+       snprintf(buf, sizeof(buf), "/proc/%d/oom_score_adj", pid);
+       fp = fopen(buf, mode);
+       return fp;
+}
+
+int get_exec_pid(const char *execpath)
+{
+       DIR *dp;
+       struct dirent *dentry;
+       int pid = -1, fd;
+       int ret;
+       char buf[PATH_MAX];
+       char buf2[PATH_MAX];
+
+       dp = opendir("/proc");
+       if (!dp) {
+               _E("FAIL: 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;
+               ret = read(fd, buf2, PATH_MAX);
+               close(fd);
+
+               if (ret < 0 || ret >= PATH_MAX)
+                       continue;
+
+               buf2[ret] = '\0';
+
+               if (!strcmp(buf2, execpath)) {
+                       closedir(dp);
+                       return pid;
+               }
+       }
+
+       errno = ESRCH;
+       closedir(dp);
+       return -1;
+}
+
+int get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
+{
+       int fd, ret;
+       char buf[PATH_MAX + 1];
+       char *filename;
+
+       snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
+       fd = open(buf, O_RDONLY);
+       if (fd < 0) {
+               errno = ESRCH;
+               return -1;
+       }
+
+       ret = read(fd, buf, PATH_MAX);
+       close(fd);
+       buf[PATH_MAX] = '\0';
+
+       filename = strrchr(buf, '/');
+       if (filename == NULL)
+               filename = buf;
+       else
+               filename = filename + 1;
+
+       if (cmdline_size < strlen(filename) + 1) {
+               errno = EOVERFLOW;
+               return -1;
+       }
+
+       strncpy(cmdline, filename, cmdline_size - 1);
+       cmdline[cmdline_size - 1] = '\0';
+       return 0;
+}
+
+int is_vip(int pid)
+{
+       if (pid < 1)
+               return -1;
+
+       char buf[PATH_MAX];
+
+       snprintf(buf, PATH_MAX, "%s/%d", VIP_DIR, pid);
+
+       if (access(buf, R_OK) == 0)
+               return 1;
+       else
+               return 0;
+}
+
+static int remove_dir_internal(int fd)
+{
+       DIR *dir;
+       struct dirent *de;
+       int subfd, ret = 0;
+
+       dir = fdopendir(fd);
+       if (!dir)
+               return -1;
+       while ((de = readdir(dir))) {
+               if (de->d_type == DT_DIR) {
+                       if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
+                               continue;
+                       subfd = openat(fd, de->d_name, O_RDONLY | O_DIRECTORY);
+                       if (subfd < 0) {
+                               _SE("Couldn't openat %s: %s\n", de->d_name, strerror(errno));
+                               ret = -1;
+                               continue;
+                       }
+                       if (remove_dir_internal(subfd)) {
+                               ret = -1;
+                       }
+                       close(subfd);
+                       if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
+                               _SE("Couldn't unlinkat %s: %s\n", de->d_name, strerror(errno));
+                               ret = -1;
+                       }
+               } else {
+                       if (unlinkat(fd, de->d_name, 0) < 0) {
+                               _SE("Couldn't unlinkat %s: %s\n", de->d_name, strerror(errno));
+                               ret = -1;
+                       }
+               }
+       }
+       closedir(dir);
+       return ret;
+}
+
+int remove_dir(char *path, int del_dir)
+{
+       int fd, ret = 0;
+
+       if (!path)
+               return -1;
+       fd = open(path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
+       if (fd < 0) {
+               _SE("Couldn't opendir %s: %s\n", path, strerror(errno));
+               return -errno;
+       }
+       ret = remove_dir_internal(fd);
+       close(fd);
+
+       if (del_dir) {
+               if (rmdir(path)) {
+                       _SE("Couldn't rmdir %s: %s\n", path, strerror(errno));
+                       ret = -1;
+               }
+       }
+       return ret;
+}
+
+/*
+ * Helper function
+ * - Read from sysfs entry
+ * - Write to sysfs entry
+ */
+static int sys_read_buf(char *file, char *buf)
+{
+       int fd;
+       int r;
+       int ret = 0;
+
+       fd = open(file, O_RDONLY);
+       if (fd == -1)
+               return -ENOENT;
+
+       r = read(fd, buf, BUFF_MAX);
+       if ((r >= 0) && (r < BUFF_MAX))
+               buf[r] = '\0';
+       else
+               ret = -EIO;
+
+       close(fd);
+
+       return ret;
+}
+
+static int sys_write_buf(char *file, char *buf)
+{
+       int fd;
+       int r;
+       int ret = 0;
+
+       fd = open(file, O_WRONLY);
+       if (fd == -1)
+               return -ENOENT;
+
+       r = write(fd, buf, strlen(buf));
+       if (r < 0)
+               ret = -EIO;
+
+       close(fd);
+
+       return ret;
+}
+
+int sys_get_int(char *fname, int *val)
+{
+       char buf[BUFF_MAX];
+       int ret = 0;
+
+       if (sys_read_buf(fname, buf) == 0) {
+               *val = atoi(buf);
+       } else {
+               *val = -1;
+               ret = -EIO;
+       }
+
+       return ret;
+}
+
+int sys_set_int(char *fname, int val)
+{
+       char buf[BUFF_MAX];
+       int ret = 0;
+
+       snprintf(buf, sizeof(buf), "%d", val);
+
+       if (sys_write_buf(fname, buf) != 0)
+               ret = -EIO;
+
+       return ret;
+}
+
+int sys_get_str(char *fname, char *str)
+{
+       char buf[BUFF_MAX] = {0};
+
+       if (sys_read_buf(fname, buf) == 0) {
+               strncpy(str, buf, strlen(buf));
+               return 0;
+       }
+
+       return -1;
+}
+
+int sys_set_str(char *fname, char *val)
+{
+       int r = -1;
+
+       if (val != NULL) {
+               if (sys_write_buf(fname, val) == 0)
+                       r = 0;
+       }
+
+       return r;
+}
+
+int terminate_process(char* partition, bool force)
+{
+       const char *argv[7] = {"/sbin/fuser", "-m", "-k", "-S", NULL, NULL, NULL};
+       int argc;
+
+       if (force)
+               argv[4] = "-SIGKILL";
+       else
+               argv[4] = "-SIGTERM";
+       argv[5] = partition;
+       argc = sizeof(argv) / sizeof(argv[0]);
+       return run_child(argc, argv);
+}
+
+int mount_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;
+}
diff --git a/src/core/common.h b/src/core/common.h
new file mode 100644 (file)
index 0000000..b25e101
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * 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 __CORE_COMMON_H__
+#define __CORE_COMMON_H__
+
+#include <stdio.h>
+#include <error.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
+
+/*
+ * One byte digit has 3 position in decimal representation
+ * 2 - 5
+ * 4 - 10
+ * 8 - 20
+ * >8 - compile time error
+ * plus 1 null termination byte
+ * plus 1 for negative prefix
+ */
+#define MAX_DEC_SIZE(type) \
+       (2 + (sizeof(type) <= 1 ? 3 : \
+       sizeof(type) <= 2 ? 5 : \
+       sizeof(type) <= 4 ? 10 : \
+       sizeof(type) <= 8 ? 20 : \
+       sizeof(int[-2*(sizeof(type) > 8)])))
+
+#ifndef __CONSTRUCTOR__
+#define __CONSTRUCTOR__ __attribute__ ((constructor))
+#endif
+
+#ifndef __DESTRUCTOR__
+#define __DESTRUCTOR__ __attribute__ ((destructor))
+#endif
+
+#ifndef __WEAK__
+#define __WEAK__ __attribute__ ((weak))
+#endif
+
+#ifndef max
+#define max(a, b)                      \
+       __extension__ ({                \
+               typeof(a) _a = (a);     \
+               typeof(b) _b = (b);     \
+               _a > _b ? _a : _b;      \
+       })
+#endif
+
+#ifndef min
+#define min(a, b)                      \
+       __extension__ ({                \
+               typeof(a) _a = (a);     \
+               typeof(b) _b = (b);     \
+               _a < _b ? _a : _b;      \
+       })
+#endif
+
+#ifndef clamp
+#define clamp(x, low, high)                                            \
+       __extension__ ({                                                \
+               typeof(x) _x = (x);                                     \
+               typeof(low) _low = (low);                               \
+               typeof(high) _high = (high);                            \
+               ((_x > _high) ? _high : ((_x < _low) ? _low : _x));     \
+       })
+#endif
+
+#ifndef SEC_TO_MSEC
+#define SEC_TO_MSEC(x)         ((x)*1000)
+#endif
+#ifndef NSEC_TO_MSEC
+#define NSEC_TO_MSEC(x)                ((double)x/1000000)
+#endif
+#ifndef USEC_TO_MSEC
+#define USEC_TO_MSEC(x)                ((double)x/1000)
+#endif
+
+FILE * open_proc_oom_score_adj_file(int pid, const char *mode);
+int get_exec_pid(const char *execpath);
+int get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size);
+int is_vip(int pid);
+int run_child(int argc, const char *argv[]);
+int remove_dir(const char *path, int del_dir);
+int sys_get_int(char *fname, int *val);
+int sys_set_int(char *fname, int val);
+int terminate_process(char* partition, bool force);
+int mount_check(const char* path);
+
+#endif /* __CORE_COMMON_H__ */
+
diff --git a/src/core/config-parser.c b/src/core/config-parser.c
new file mode 100644 (file)
index 0000000..b7e164b
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 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 <string.h>
+#include <errno.h>
+#include "log.h"
+#include "config-parser.h"
+
+#define MAX_LINE       128
+#define MAX_SECTION    64
+#define WHITESPACE     " \t"
+#define NEWLINE                "\n\r"
+#define COMMENT                '#'
+
+static inline char *trim_str(char *s)
+{
+       char *t;
+       /* left trim */
+       s += strspn(s, WHITESPACE);
+
+       /* right trim */
+       for (t = strchr(s, 0); t > s; t--)
+               if (!strchr(WHITESPACE, t[-1]))
+                       break;
+       *t = 0;
+       return s;
+}
+
+int config_parse(const char *file_name, int cb(struct parse_result *result,
+    void *user_data), void *user_data)
+{
+       FILE *f = NULL;
+       struct parse_result result;
+       /* use stack for parsing */
+       char line[MAX_LINE];
+       char section[MAX_SECTION];
+       char *start, *end, *name, *value;
+       int lineno = 0, ret = 0;
+
+       if (!file_name || !cb) {
+               ret = -EINVAL;
+               goto error;
+       }
+
+       /* open conf file */
+       f = fopen(file_name, "r");
+       if (!f) {
+               _E("Failed to open file %s", file_name);
+               ret = -EIO;
+               goto error;
+       }
+
+       /* parsing line by line */
+       while (fgets(line, MAX_LINE, f) != NULL) {
+               lineno++;
+
+               start = line;
+               start[strcspn(start, NEWLINE)] = '\0';
+               start = trim_str(start);
+
+               if (*start == COMMENT) {
+                       continue;
+               } else if (*start == '[') {
+                       /* parse section */
+                       end = strchr(start, ']');
+                       if (!end || *end != ']') {
+                               ret = -EBADMSG;
+                               goto error;
+                       }
+
+                       *end = '\0';
+                       strncpy(section, start + 1, sizeof(section));
+                       section[MAX_SECTION-1] = '\0';
+               } else if (*start) {
+                       /* parse name & value */
+                       end = strchr(start, '=');
+                       if (!end || *end != '=') {
+                               ret = -EBADMSG;
+                               goto error;
+                       }
+                       *end = '\0';
+                       name = trim_str(start);
+                       value = trim_str(end + 1);
+                       end = strchr(value, COMMENT);
+                       if (end && *end == COMMENT) {
+                               *end = '\0';
+                               value = trim_str(value);
+                       }
+
+                       result.section = section;
+                       result.name = name;
+                       result.value = value;
+                       /* callback with parse result */
+                       ret = cb(&result, user_data);
+                       if (ret < 0) {
+                               ret = -EBADMSG;
+                               goto error;
+                       }
+               }
+       }
+       _D("Success to load %s", file_name);
+       fclose(f);
+       return 0;
+
+error:
+       if (f)
+               fclose(f);
+       _E("Failed to read %s:%d!", file_name, lineno);
+       return ret;
+}
+
diff --git a/src/core/config-parser.h b/src/core/config-parser.h
new file mode 100644 (file)
index 0000000..ed3675f
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 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 __CONFIG_PARSER_H__
+#define __CONFIG_PARSER_H__
+
+#define MATCH(a, b)            (!strncmp(a, b, strlen(a)))
+#define SET_CONF(a, b)         (a = (b > 0.0 ? b : a))
+
+struct parse_result {
+       char *section;
+       char *name;
+       char *value;
+};
+
+/**
+ * @brief Parse config file and call callback\n
+ * @param[in] file_name conf file.
+ * @param[in] cb cb is called when conf file is parsed line by line.
+ * @param[in] user_data user data is passed to cb.
+ * @return 0 on success, negative if failed
+ */
+int config_parse(const char *file_name, int cb(struct parse_result *result,
+    void *user_data), void *user_data);
+
+#endif
+
diff --git a/src/core/core.c b/src/core/core.c
new file mode 100644 (file)
index 0000000..1ee910d
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * 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 "data.h"
+#include "queue.h"
+#include "log.h"
+#include "predefine.h"
+#include "core.h"
+#include "devices.h"
+#include "common.h"
+
+enum core_cmd_type {
+       CORE_ACT_RUN,
+       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 main_data *ad);
+static int __pipe_stop(int fd);
+
+static int _core_action_run(void *user_data,
+                              struct run_queue_entry *rq_entry)
+{
+       struct action_entry *act_entry = rq_entry->action_entry;
+       int ret;
+       char tmp[128];
+
+       rq_entry->state = STATE_RUNNING;
+       ret = act_entry->predefine_action(rq_entry->argc, rq_entry->argv);
+       if (ret <= 0) {
+               if (ret < 0)
+                       _E("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 = STATE_DONE;
+       core_action_clear(-1);
+       return 0;
+}
+
+static Eina_Bool core_pipe_cb(void *userdata, Ecore_Fd_Handler * fd_handler)
+{
+       struct main_data *ad = (struct 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)) {
+               _E("ecore_main_fd_handler_active_get error , return");
+               return EINA_TRUE;
+       }
+
+       while (retry_count < 5) {
+               r = read(core_pipe[0], &p_msg, sizeof(struct _internal_msg));
+               if (r < 0) {
+                       if (errno == EINTR) {
+                               _D("Re-read for error(EINTR)");
+                               retry_count++;
+                               continue;
+                       } else {
+                               __pipe_stop(core_pipe[0]);
+                               __pipe_stop(core_pipe[1]);
+                               _D("restart pipe fd");
+                               __pipe_start(ad);
+                       }
+               } else {
+                       break;
+               }
+       }
+
+       switch (p_msg.type) {
+       case CORE_ACT_RUN:
+               run_queue_run(STATE_INIT, _core_action_run, ad);
+               break;
+       case CORE_ACT_CLEAR:
+               run_queue_del_bypid(p_msg.pid);
+               break;
+       }
+       return EINA_TRUE;
+}
+
+int core_action_run()
+{
+       struct _internal_msg p_msg;
+
+       p_msg.type = CORE_ACT_RUN;
+       p_msg.pid = 0;
+       write(core_pipe[1], &p_msg, sizeof(struct _internal_msg));
+
+       return 0;
+}
+
+int core_action_clear(int pid)
+{
+       struct _internal_msg p_msg;
+
+       p_msg.type = CORE_ACT_CLEAR;
+       p_msg.pid = pid;
+       write(core_pipe[1], &p_msg, sizeof(struct _internal_msg));
+
+       return 0;
+}
+
+static int __pipe_start(struct main_data *ad)
+{
+       if (pipe(core_pipe) < 0) {
+               _E("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) {
+               _E("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;
+}
+
+static void core_init(void *data)
+{
+       struct main_data *ad = (struct main_data*)data;
+
+       __pipe_stop(core_pipe[0]);
+       __pipe_stop(core_pipe[1]);
+
+       if (__pipe_start(ad) == -1)
+               _E("fail pipe control fd init");
+}
+
+static const struct device_ops core_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "core",
+       .init     = core_init,
+};
+
+DEVICE_OPS_REGISTER(&core_device_ops)
diff --git a/src/core/core.h b/src/core/core.h
new file mode 100644 (file)
index 0000000..0ae3bbc
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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_CORE_H__
+#define __DD_CORE_H__
+
+#include "data.h"
+
+int core_action_run();
+int core_action_clear(int pid);
+
+#endif /* __DD_CORE_H__ */
diff --git a/src/core/data.h b/src/core/data.h
new file mode 100644 (file)
index 0000000..d07c356
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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_DATA_H__
+#define __DD_DATA_H__
+
+#include <Ecore.h>
+#include <unistd.h>
+
+struct main_data {
+       int sysnoti_fd;
+       int noti_fd;
+};
+
+#endif /* __DD_DATA_H__ */
diff --git a/src/core/device-change-handler.c b/src/core/device-change-handler.c
new file mode 100644 (file)
index 0000000..bd3c8ba
--- /dev/null
@@ -0,0 +1,1767 @@
+/*
+ * 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 <stdbool.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <vconf.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <dirent.h>
+#include <fnmatch.h>
+#include "dd-deviced.h"
+#include "queue.h"
+#include "log.h"
+#include "device-notifier.h"
+#include "device-handler.h"
+#include "device-node.h"
+#include "noti.h"
+#include "data.h"
+#include "predefine.h"
+#include "display/poll.h"
+#include "devices.h"
+#include "hall/hall-handler.h"
+#include "udev.h"
+#include "common.h"
+#include "common.h"
+#include "list.h"
+#include "proc/proc-handler.h"
+#include "edbus-handler.h"
+#include "emulator.h"
+#include "devices.h"
+#include "power-supply.h"
+#include "display/setting.h"
+#include "display/core.h"
+
+#define PREDEF_EARJACKCON              "earjack_predef_internal"
+#define PREDEF_DEVICE_CHANGED          "device_changed"
+#define PREDEF_POWER_CHANGED           POWER_SUBSYSTEM
+#define PREDEF_UDEV_CONTROL            UDEV
+
+#define TVOUT_X_BIN                    "/usr/bin/xberc"
+#define TVOUT_FLAG                     0x00000001
+
+#define MOVINAND_MOUNT_POINT           "/opt/media"
+#define BUFF_MAX               255
+#define SYS_CLASS_INPUT                "/sys/class/input"
+
+#ifdef MICRO_DD
+#define USB_STATE_PATH "/sys/devices/platform/jack/usb_online"
+#else
+#define USB_STATE_PATH "/sys/devices/virtual/switch/usb_cable/state"
+#endif
+
+#define HDMI_NOT_SUPPORTED     (-1)
+#ifdef ENABLE_EDBUS_USE
+#include <E_DBus.h>
+static E_DBus_Connection *conn;
+#endif                         /* ENABLE_EDBUS_USE */
+
+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 CRADLE_APP_NAME                "com.samsung.desk-dock"
+#define VIRTUAL_CONTROLLER_APP_NAME            "com.samsung.virtual-controller"
+
+#define CHANGE_ACTION          "change"
+#define ENV_FILTER             "CHGDET"
+#define USB_NAME               "usb"
+#define USB_NAME_LEN           3
+
+#define CHARGER_NAME           "charger"
+#define CHARGER_NAME_LEN       7
+
+#define EARJACK_NAME           "earjack"
+#define EARJACK_NAME_LEN       7
+
+#define EARKEY_NAME            "earkey"
+#define EARKEY_NAME_LEN        6
+
+#define TVOUT_NAME             "tvout"
+#define TVOUT_NAME_LEN         5
+
+#define HDMI_NAME              "hdmi"
+#define HDMI_NAME_LEN          4
+
+#define HDCP_NAME              "hdcp"
+#define HDCP_NAME_LEN          4
+
+#define HDMI_AUDIO_NAME        "ch_hdmi_audio"
+#define HDMI_AUDIO_LEN         13
+
+#define CRADLE_NAME            "cradle"
+#define CRADLE_NAME_LEN        6
+
+#define KEYBOARD_NAME          "keyboard"
+#define KEYBOARD_NAME_LEN      8
+
+#define POWER_SUPPLY_NAME_LEN  12
+
+#define CHARGE_NAME_LEN        17
+#define BATTERY_NAME           "battery"
+#define BATTERY_NAME_LEN       7
+#define CHARGEFULL_NAME        "Full"
+#define CHARGEFULL_NAME_LEN    4
+#define CHARGENOW_NAME         "Charging"
+#define CHARGENOW_NAME_LEN     8
+#define DISCHARGE_NAME         "Discharging"
+#define DISCHARGE_NAME_LEN     11
+#define NOTCHARGE_NAME         "Not charging"
+#define NOTCHARGE_NAME_LEN     12
+#define OVERHEAT_NAME          "Overheat"
+#define OVERHEAT_NAME_LEN      8
+#define TEMPCOLD_NAME          "Cold"
+#define TEMPCOLD_NAME_LEN      4
+#define OVERVOLT_NAME          "Over voltage"
+#define OVERVOLT_NAME_LEN      12
+
+#define SWITCH_DEVICE_USB      "usb_cable"
+
+#define LAUNCH_APP     "launch-app"
+#define DESK_DOCK      "desk-dock"
+
+/* Ticker notification */
+#define DOCK_CONNECTED    "dock-connected"
+#define HDMI_CONNECTED    "hdmi-connected"
+#define HDMI_DISCONNECTED "hdmi-disconnected"
+
+#define METHOD_GET_HDMI                "GetHDMI"
+#define METHOD_GET_HDCP                "GetHDCP"
+#define METHOD_GET_HDMI_AUDIO  "GetHDMIAudio"
+#define SIGNAL_HDMI_STATE      "ChangedHDMI"
+#define SIGNAL_HDCP_STATE      "ChangedHDCP"
+#define SIGNAL_HDMI_AUDIO_STATE        "ChangedHDMIAudio"
+
+#define HDCP_HDMI_VALUE(HDCP, HDMI)    ((HDCP << 1) | HDMI)
+
+#define METHOD_GET_CRADLE      "GetCradle"
+#define SIGNAL_CRADLE_STATE    "ChangedCradle"
+
+struct ticker_data {
+       char *name;
+       int type;
+};
+
+struct popup_data {
+       char *name;
+       char *key;
+       char *value;
+};
+
+static int ss_flags = 0;
+
+static int input_device_number;
+
+/* Uevent */
+static struct udev *udev = NULL;
+/* Kernel Uevent */
+static struct udev_monitor *mon = NULL;
+static Ecore_Fd_Handler *ufdh = NULL;
+static int ufd = -1;
+/* Udev Uevent */
+static struct udev_monitor *mon_udev = NULL;
+static Ecore_Fd_Handler *ufdh_udev = NULL;
+static int ufd_udev = -1;
+
+static dd_list *opt_uevent_list = NULL;
+static dd_list *opt_kernel_uevent_list = NULL;
+static int hdmi_status = 0;
+static const struct device_ops *lowbat_ops;
+
+enum udev_subsystem_type {
+       UDEV_HALL_IC,
+       UDEV_INPUT,
+       UDEV_LCD_EVENT,
+       UDEV_PLATFORM,
+       UDEV_POWER,
+       UDEV_SWITCH,
+};
+
+static const struct udev_subsystem {
+       const enum udev_subsystem_type type;
+       const char *str;
+       const char *devtype;
+} udev_subsystems[] = {
+       { UDEV_HALL_IC,          HALL_IC_SUBSYSTEM, NULL},
+       { UDEV_INPUT,            INPUT_SUBSYSTEM, NULL },
+       { UDEV_LCD_EVENT,        LCD_EVENT_SUBSYSTEM, NULL },
+       { UDEV_PLATFORM,         PLATFORM_SUBSYSTEM, NULL },
+       { UDEV_POWER,            POWER_SUBSYSTEM, NULL},
+       { UDEV_SWITCH,           SWITCH_SUBSYSTEM, NULL },
+};
+
+static struct extcon_device {
+       const enum extcon_type type;
+       const char *str;
+       int fd;
+       int count;
+} extcon_devices[] = {
+       { EXTCON_TA, "/csa/factory/batt_cable_count", 0, 0},
+       { EXTCON_EARJACK, "/csa/factory/earjack_count", 0, 0},
+};
+
+extern int battery_power_off_act(void *data);
+extern int battery_charge_err_act(void *data);
+
+int extcon_set_count(int index)
+{
+       int r;
+       int ret = 0;
+       char buf[BUFF_MAX];
+
+       extcon_devices[index].count++;
+
+       if (extcon_devices[index].fd < 0) {
+               _E("cannot open file(%s)", extcon_devices[index].str);
+               return -ENOENT;
+       }
+       lseek(extcon_devices[index].fd, 0, SEEK_SET);
+       _I("ext(%d) count %d", index, extcon_devices[index].count);
+       snprintf(buf, sizeof(buf), "%d", extcon_devices[index].count);
+
+       r = write(extcon_devices[index].fd, buf, strlen(buf));
+       if (r < 0)
+               ret = -EIO;
+       return ret;
+}
+
+static int extcon_get_count(int index)
+{
+       int fd;
+       int r;
+       int ret = 0;
+       char buf[BUFF_MAX];
+
+       fd = open(extcon_devices[index].str, O_RDWR);
+       if (fd < 0)
+               return -ENOENT;
+
+       r = read(fd, buf, BUFF_MAX);
+       if ((r >= 0) && (r < BUFF_MAX))
+               buf[r] = '\0';
+       else
+               ret = -EIO;
+
+       if (ret != 0) {
+               close(fd);
+               return ret;
+       }
+       extcon_devices[index].fd = fd;
+       extcon_devices[index].count = atoi(buf);
+       _I("get extcon(%d:%x) count %d",
+               index, extcon_devices[index].fd, extcon_devices[index].count);
+
+       return ret;
+}
+
+static int extcon_create_count(int index)
+{
+       int fd;
+       int r;
+       int ret = 0;
+       char buf[BUFF_MAX];
+       fd = open(extcon_devices[index].str, O_RDWR | O_CREAT, 0644);
+       if (fd < 0) {
+               _E("cannot open file(%s)", extcon_devices[index].str);
+               return -ENOENT;
+       }
+       snprintf(buf, sizeof(buf), "%d", extcon_devices[index].count);
+       r = write(fd, buf, strlen(buf));
+       if (r < 0)
+               ret = -EIO;
+
+       if (ret != 0) {
+               close(fd);
+               _E("cannot write file(%s)", extcon_devices[index].str);
+               return ret;
+       }
+       extcon_devices[index].fd = fd;
+       _I("create extcon(%d:%x) %s",
+               index, extcon_devices[index].fd, extcon_devices[index].str);
+       return ret;
+}
+
+static int extcon_count_init(void)
+{
+       int i;
+       int ret = 0;
+       for (i = 0; i < ARRAY_SIZE(extcon_devices); i++) {
+               if (extcon_get_count(i) >= 0)
+                       continue;
+               ret = extcon_create_count(i);
+               if (ret < 0)
+                       break;
+       }
+       return ret;
+}
+
+int get_usb_state_direct(void)
+{
+       FILE *fp;
+       char str[2];
+       int state;
+
+       fp = fopen(USB_STATE_PATH, "r");
+       if (!fp) {
+               _E("Cannot open jack node");
+               return -ENOMEM;
+       }
+
+       if (!fgets(str, sizeof(str), fp)) {
+               _E("cannot get string from jack node");
+               fclose(fp);
+               return -ENOMEM;
+       }
+
+       fclose(fp);
+
+       return atoi(str);
+}
+
+static void usb_chgdet_cb(void *data)
+{
+       int val = -1;
+       int ret = 0;
+       char params[BUFF_MAX];
+
+       if (data == NULL)
+               ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &val);
+       else
+               val = *(int *)data;
+       if (ret == 0) {
+               if (val < 0)
+                       val = get_usb_state_direct();
+
+               _I("jack - usb changed %d",val);
+               check_lowbat_charge_device(val);
+               if (val==1) {
+                       battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
+                       _D("usb device notification");
+               }
+       } else {
+               _E("fail to get usb_online status");
+       }
+}
+
+static void show_ticker_notification(char *text, int queue)
+{
+       struct ticker_data t_data;
+       static const struct device_ops *ticker = NULL;
+
+       if (!ticker) {
+               ticker = find_device("ticker");
+               if (!ticker)
+                       return;
+       }
+
+       t_data.name = text;
+       t_data.type = queue;
+       if (ticker->init)
+               ticker->init(&t_data);
+}
+
+static void launch_cradle(int val)
+{
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+
+       if (apps == NULL) {
+               apps = find_device("apps");
+               if (apps == NULL)
+                       return;
+       }
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return;
+       }
+       params->name = LAUNCH_APP;
+       params->key = DESK_DOCK;
+       _I("%s %s %x", params->name, params->key, params);
+       if (val == 0) {
+               if (apps->exit)
+                       apps->exit((void *)params);
+       } else {
+               show_ticker_notification(DOCK_CONNECTED, 0);
+               if (apps->init)
+                       apps->init((void *)params);
+       }
+       free(params);
+
+}
+
+static int display_changed(void *data)
+{
+       enum state_t state = (enum state_t)data;
+       int ret, cradle = 0;
+
+       if (battery.charge_now == CHARGER_ABNORMAL && battery.health == HEALTH_BAD) {
+               pm_lock_internal(INTERNAL_LOCK_POPUP, LCD_DIM, STAY_CUR_STATE, 0);
+               return 0;
+       }
+
+       if (state != S_NORMAL)
+               return 0;
+
+       ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
+       if (ret >= 0 && cradle == DOCK_SOUND) {
+               pm_lock_internal(getpid(), LCD_DIM, STAY_CUR_STATE, 0);
+               _I("sound dock is connected! dim lock is on.");
+       }
+       if (hdmi_status) {
+               pm_lock_internal(getpid(), LCD_DIM, STAY_CUR_STATE, 0);
+               _I("hdmi is connected! dim lock is on.");
+       }
+       return 0;
+}
+
+static void cradle_send_broadcast(int status)
+{
+       static int old = 0;
+       char *arr[1];
+       char str_status[32];
+
+       if (old == status)
+               return;
+
+       _I("broadcast cradle status %d", status);
+       old = status;
+       snprintf(str_status, sizeof(str_status), "%d", status);
+       arr[0] = str_status;
+
+       broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       SIGNAL_CRADLE_STATE, "i", arr);
+}
+
+static int cradle_cb(void *data)
+{
+       static int old = 0;
+       int val = 0;
+       int ret = 0;
+
+       if (data == NULL)
+               return old;
+
+       val = *(int *)data;
+
+       if (old == val)
+               return old;
+
+       old = val;
+       cradle_send_broadcast(old);
+       return old;
+}
+
+static void cradle_chgdet_cb(void *data)
+{
+       int val;
+       int ret = 0;
+
+       pm_change_internal(getpid(), LCD_NORMAL);
+
+       if (data)
+               val = *(int *)data;
+       else {
+               ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_CRADLE_ONLINE, &val);
+               if (ret != 0) {
+                       _E("failed to get status");
+                       return;
+               }
+       }
+
+       _I("jack - cradle changed %d", val);
+       cradle_cb((void *)&val);
+       if (vconf_set_int(VCONFKEY_SYSMAN_CRADLE_STATUS, val) != 0) {
+               _E("failed to set vconf status");
+               return;
+       }
+
+       if (val == DOCK_SOUND)
+               pm_lock_internal(getpid(), LCD_DIM, STAY_CUR_STATE, 0);
+       else if (val == DOCK_NONE)
+               pm_unlock_internal(getpid(), LCD_DIM, PM_SLEEP_MARGIN);
+
+       launch_cradle(val);
+}
+
+void sync_cradle_status(void)
+{
+       int val;
+       int status;
+       if ((device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_CRADLE_ONLINE, &val) != 0) ||
+           vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &status) != 0)
+               return;
+       if ((val != 0 && status == 0) || (val == 0 && status != 0))
+               cradle_chgdet_cb(NULL);
+}
+
+static void ta_chgdet_cb(struct main_data *ad)
+{
+       int val = -1;
+       int ret = -1;
+       int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
+       char params[BUFF_MAX];
+
+       if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_TA_ONLINE, &val) == 0) {
+               _I("jack - ta changed %d",val);
+               check_lowbat_charge_device(val);
+               vconf_set_int(VCONFKEY_SYSMAN_CHARGER_STATUS, val);
+               if (val == 0) {
+                       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_INSUSPEND_CHARGING_SUPPORT, &val);
+                       if (ret != 0)
+                               val = 0;
+                       if (val == 0)
+                               pm_unlock_internal(INTERNAL_LOCK_TA, LCD_OFF, STAY_CUR_STATE);
+                       device_notify(DEVICE_NOTIFIER_BATTERY_CHARGING, (void*)FALSE);
+               } else {
+                       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_INSUSPEND_CHARGING_SUPPORT, &val);
+                       if (ret != 0)
+                               val = 0;
+                       if (val == 0)
+                               pm_lock_internal(INTERNAL_LOCK_TA, LCD_OFF, STAY_CUR_STATE, 0);
+                       battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
+                       _D("ta device notification");
+                       device_notify(DEVICE_NOTIFIER_BATTERY_CHARGING, (void*)TRUE);
+               }
+               sync_cradle_status();
+       }
+       else
+               _E("failed to get ta status");
+}
+
+static void earjack_chgdet_cb(void *data)
+{
+       int val;
+       int ret = 0;
+
+       if (data)
+               val = *(int *)data;
+       else {
+               ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_EARJACK_ONLINE, &val);
+               if (ret != 0) {
+                       _E("failed to get status");
+                       return;
+               }
+       }
+       _I("jack - earjack changed %d", val);
+       if (CONNECTED(val)) {
+               extcon_set_count(EXTCON_EARJACK);
+               predefine_pm_change_state(LCD_NORMAL);
+       }
+       vconf_set_int(VCONFKEY_SYSMAN_EARJACK, val);
+}
+
+static void earkey_chgdet_cb(void *data)
+{
+       int val;
+       int ret = 0;
+
+       if (data)
+               val = *(int *)data;
+       else {
+               ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_EARKEY_ONLINE, &val);
+               if (ret != 0) {
+                       _E("failed to get status");
+                       return;
+               }
+       }
+       _I("jack - earkey changed %d", val);
+       vconf_set_int(VCONFKEY_SYSMAN_EARJACKKEY, val);
+}
+
+static void tvout_chgdet_cb(void *data)
+{
+       _I("jack - tvout changed");
+       pm_change_internal(getpid(), LCD_NORMAL);
+}
+
+static void hdcp_hdmi_send_broadcast(int status)
+{
+       static int old = 0;
+       char *arr[1];
+       char str_status[32];
+
+       if (old == status)
+               return;
+
+       _I("broadcast hdmi status %d", status);
+       old = status;
+       snprintf(str_status, sizeof(str_status), "%d", status);
+       arr[0] = str_status;
+
+       broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       SIGNAL_HDMI_STATE, "i", arr);
+}
+
+static int hdcp_hdmi_cb(void *data)
+{
+       static int old = 0;
+       int val = 0;
+       int ret = 0;
+
+       if (data == NULL)
+               return old;
+
+       val = *(int *)data;
+       val = HDCP_HDMI_VALUE(val, hdmi_status);
+
+       if (old == val)
+               return old;
+
+       old = val;
+       hdcp_hdmi_send_broadcast(old);
+       return old;
+}
+
+static void hdmi_chgdet_cb(void *data)
+{
+       int val;
+       int ret = 0;
+
+       pm_change_internal(getpid(), LCD_NORMAL);
+       if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_HDMI_SUPPORT, &val) == 0) {
+               if (val!=1) {
+                       _I("target is not support HDMI");
+                       vconf_set_int(VCONFKEY_SYSMAN_HDMI, HDMI_NOT_SUPPORTED);
+                       return;
+               }
+       }
+
+       if (data)
+               val = *(int *)data;
+       else {
+               ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_HDMI_ONLINE, &val);
+               if (ret != 0) {
+                       _E("failed to get status");
+                       return;
+               }
+       }
+
+       _I("jack - hdmi changed %d", val);
+       vconf_set_int(VCONFKEY_SYSMAN_HDMI, val);
+       hdmi_status = val;
+       device_notify(DEVICE_NOTIFIER_HDMI, (void *)val);
+
+       if(val == 1) {
+               pm_lock_internal(INTERNAL_LOCK_HDMI, LCD_DIM, STAY_CUR_STATE, 0);
+               show_ticker_notification(HDMI_CONNECTED, 0);
+       } else {
+               show_ticker_notification(HDMI_DISCONNECTED, 0);
+               pm_unlock_internal(INTERNAL_LOCK_HDMI, LCD_DIM, PM_SLEEP_MARGIN);
+       }
+}
+
+static void hdcp_send_broadcast(int status)
+{
+       static int old = 0;
+       char *arr[1];
+       char str_status[32];
+
+       if (old == status)
+               return;
+
+       _D("broadcast hdcp status %d", status);
+       old = status;
+       snprintf(str_status, sizeof(str_status), "%d", status);
+       arr[0] = str_status;
+
+       broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       SIGNAL_HDCP_STATE, "i", arr);
+}
+
+static int hdcp_chgdet_cb(void *data)
+{
+       static int old = 0;
+       int val = 0;
+
+       if (data == NULL)
+               return old;
+
+       val = *(int *)data;
+       if (old == val)
+               return old;
+
+       old = val;
+       hdcp_send_broadcast(old);
+       return old;
+}
+
+static void hdmi_audio_send_broadcast(int status)
+{
+       static int old = 0;
+       char *arr[1];
+       char str_status[32];
+
+       if (old == status)
+               return;
+
+       _D("broadcast hdmi audio status %d", status);
+       old = status;
+       snprintf(str_status, sizeof(str_status), "%d", status);
+       arr[0] = str_status;
+
+       broadcast_edbus_signal(DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       SIGNAL_HDMI_AUDIO_STATE, "i", arr);
+}
+
+static int hdmi_audio_chgdet_cb(void *data)
+{
+       static int old = 0;
+       int val = 0;
+
+       if (data == NULL)
+               return old;
+
+       val = *(int *)data;
+       if (old == val)
+               return old;
+
+       old = val;
+       hdmi_audio_send_broadcast(old);
+       return old;
+}
+
+static void keyboard_chgdet_cb(void *data)
+{
+       int val = -1;
+       int ret = 0;
+
+       if (data)
+               val = *(int *)data;
+       else {
+               ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_KEYBOARD_ONLINE, &val);
+               if (ret != 0) {
+                       _E("failed to get status");
+                       vconf_set_int(VCONFKEY_SYSMAN_SLIDING_KEYBOARD, VCONFKEY_SYSMAN_SLIDING_KEYBOARD_NOT_SUPPORTED);
+                       return;
+               }
+       }
+       _I("jack - keyboard changed %d", val);
+       if(val != 1)
+               val = 0;
+       vconf_set_int(VCONFKEY_SYSMAN_SLIDING_KEYBOARD, val);
+}
+
+static void ums_unmount_cb(void *data)
+{
+       umount(MOVINAND_MOUNT_POINT);
+}
+
+#ifdef ENABLE_EDBUS_USE
+static void cb_xxxxx_signaled(void *data, DBusMessage * msg)
+{
+       char *args;
+       DBusError err;
+       struct 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 check_capacity_status(const char *env_value)
+{
+       if (env_value == NULL)
+               return;
+       battery.capacity = atoi(env_value);
+}
+
+static void check_charge_status(const char *env_value)
+{
+       if (env_value == NULL)
+               return;
+       if (strncmp(env_value, CHARGEFULL_NAME , CHARGEFULL_NAME_LEN) == 0) {
+               battery.charge_full = CHARGING_FULL;
+               battery.charge_now = CHARGER_DISCHARGING;
+       } else if (strncmp(env_value, CHARGENOW_NAME, CHARGENOW_NAME_LEN) == 0) {
+               battery.charge_full = CHARGING_NOT_FULL;
+               battery.charge_now = CHARGER_CHARGING;
+       } else if (strncmp(env_value, DISCHARGE_NAME, DISCHARGE_NAME_LEN) == 0) {
+               battery.charge_full = CHARGING_NOT_FULL;
+               battery.charge_now = CHARGER_DISCHARGING;
+       } else if (strncmp(env_value, NOTCHARGE_NAME, NOTCHARGE_NAME_LEN) == 0) {
+               battery.charge_full = CHARGING_NOT_FULL;
+               battery.charge_now = CHARGER_ABNORMAL;
+       } else {
+               battery.charge_full = CHARGING_NOT_FULL;
+               battery.charge_now = CHARGER_DISCHARGING;
+       }
+}
+
+static void check_health_status(const char *env_value)
+{
+       if (env_value == NULL) {
+               battery.health = HEALTH_GOOD;
+               battery.temp = TEMP_LOW;
+               battery.ovp = OVP_NORMAL;
+               return;
+       }
+       if (strncmp(env_value, OVERHEAT_NAME, OVERHEAT_NAME_LEN) == 0) {
+               battery.health = HEALTH_BAD;
+               battery.temp = TEMP_HIGH;
+               battery.ovp = OVP_NORMAL;
+       } else if (strncmp(env_value, TEMPCOLD_NAME, TEMPCOLD_NAME_LEN) == 0) {
+               battery.health = HEALTH_BAD;
+               battery.temp = TEMP_LOW;
+               battery.ovp = OVP_NORMAL;
+       } else if (strncmp(env_value, OVERVOLT_NAME, OVERVOLT_NAME_LEN) == 0) {
+               battery.health = HEALTH_GOOD;
+               battery.temp = TEMP_LOW;
+               battery.ovp = OVP_ABNORMAL;
+       } else {
+               battery.health = HEALTH_GOOD;
+               battery.temp = TEMP_LOW;
+               battery.ovp = OVP_NORMAL;
+       }
+}
+
+static void check_online_status(const char *env_value)
+{
+       if (env_value == NULL)
+               return;
+       battery.online = atoi(env_value);
+}
+
+static void check_present_status(const char *env_value)
+{
+       if (env_value == NULL) {
+               battery.present = PRESENT_NORMAL;
+               return;
+       }
+       battery.present = atoi(env_value);
+}
+
+static Eina_Bool uevent_kernel_control_cb(void *data, Ecore_Fd_Handler *fd_handler)
+{
+       struct udev_device *dev = NULL;
+       struct udev_list_entry *list_entry = NULL;
+       const char *subsystem = NULL;
+       const char *env_name = NULL;
+       const char *env_value = NULL;
+       const char *devpath;
+       const char *devnode;
+       const char *action;
+       const char *siop_level;
+       const char *rear_level;
+       dd_list *l;
+       void *l_data;
+       struct uevent_handler *uh;
+       int ret = -1;
+       int i, len;
+
+       if ((dev = udev_monitor_receive_device(mon)) == NULL)
+               return EINA_TRUE;
+
+       subsystem = udev_device_get_subsystem(dev);
+
+       for (i = 0; i < ARRAY_SIZE(udev_subsystems); i++) {
+               len = strlen(udev_subsystems[i].str);
+               if (!strncmp(subsystem, udev_subsystems[i].str, len))
+                       break;
+       }
+
+       if (i >= ARRAY_SIZE(udev_subsystems))
+               goto out;
+
+       devpath = udev_device_get_devpath(dev);
+
+       switch (udev_subsystems[i].type) {
+       case UDEV_HALL_IC:
+               if (!strncmp(devpath, HALL_IC_PATH, strlen(HALL_IC_PATH))) {
+                       notify_action(PREDEF_HALL_IC, 1, HALL_IC_NAME);
+                       goto out;
+               }
+               break;
+       case UDEV_INPUT:
+               /* check new input device */
+               if (!fnmatch(INPUT_PATH, devpath, 0)) {
+                       action = udev_device_get_action(dev);
+                       devnode = udev_device_get_devnode(dev);
+                       if (!strcmp(action, UDEV_ADD))
+                               device_notify(DEVICE_NOTIFIER_INPUT_ADD, (void *)devnode);
+                       else if (!strcmp(action, UDEV_REMOVE))
+                               device_notify(DEVICE_NOTIFIER_INPUT_REMOVE, (void *)devnode);
+                       goto out;
+               }
+               break;
+       case UDEV_LCD_EVENT:
+               /* check new esd device */
+               if (!fnmatch(LCD_ESD_PATH, devpath, 0)) {
+                       action = udev_device_get_action(dev);
+                       if (!strcmp(action, UDEV_CHANGE))
+                               device_notify(DEVICE_NOTIFIER_LCD_ESD, "ESD");
+                       goto out;
+               }
+               break;
+       case UDEV_SWITCH:
+               env_name = udev_device_get_property_value(dev, "SWITCH_NAME");
+               env_value = udev_device_get_property_value(dev, "SWITCH_STATE");
+               notify_action(PREDEF_DEVICE_CHANGED, 2, env_name, env_value);
+               break;
+       case UDEV_PLATFORM:
+               if (!fnmatch(THERMISTOR_PATH, devpath, 0)) {
+                       siop_level = udev_device_get_property_value(dev, "TEMPERATURE");
+                       rear_level = udev_device_get_property_value(dev, "REAR_TEMPERATURE");
+                       notify_action(SIOP_CHANGED, 2, siop_level, rear_level);
+                       goto out;
+               }
+
+               env_value = udev_device_get_property_value(dev, ENV_FILTER);
+               if (!env_value)
+                       break;
+               notify_action(PREDEF_DEVICE_CHANGED, 1, env_value);
+               break;
+       case UDEV_POWER:
+               udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(dev)) {
+                       env_name = udev_list_entry_get_name(list_entry);
+                       if (env_name == NULL)
+                               continue;
+                       if (strncmp(env_name, CHARGE_NAME, CHARGE_NAME_LEN) == 0) {
+                               env_value = udev_list_entry_get_value(list_entry);
+                               if (env_value == NULL)
+                                       continue;
+                               if (strncmp(env_value, BATTERY_NAME, BATTERY_NAME_LEN) == 0) {
+                                       ret = 0;
+                                       break;
+                               }
+                       }
+               }
+               if (ret != 0)
+                       goto out;
+               env_value = udev_device_get_property_value(dev, CHARGE_STATUS);
+               check_charge_status(env_value);
+               env_value = udev_device_get_property_value(dev, CHARGE_ONLINE);
+               check_online_status(env_value);
+               env_value = udev_device_get_property_value(dev, CHARGE_HEALTH);
+               check_health_status(env_value);
+               env_value = udev_device_get_property_value(dev, CHARGE_PRESENT);
+               check_present_status(env_value);
+               env_value = udev_device_get_property_value(dev, CAPACITY);
+               check_capacity_status(env_value);
+               battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
+               if (env_value)
+                       notify_action(PREDEF_DEVICE_CHANGED, 2, subsystem, env_value);
+               else
+                       notify_action(PREDEF_DEVICE_CHANGED, 1, subsystem);
+               break;
+       }
+
+out:
+       DD_LIST_FOREACH(opt_kernel_uevent_list, l, l_data) {
+               uh = (struct uevent_handler *)l_data;
+               if (strncmp(subsystem, uh->subsystem, strlen(uh->subsystem)))
+                       continue;
+               uh->uevent_func(dev);
+       }
+
+       udev_device_unref(dev);
+       return EINA_TRUE;
+}
+
+static Eina_Bool uevent_udev_control_cb(void *data, Ecore_Fd_Handler *fd_handler)
+{
+       struct udev_device *dev = NULL;
+       dd_list *l;
+       void *l_data;
+       struct uevent_handler *uh;
+       const char *subsystem = NULL;
+
+       dev = udev_monitor_receive_device(mon_udev);
+       if (!dev)
+               return EINA_TRUE;
+
+       subsystem = udev_device_get_subsystem(dev);
+       if (!subsystem) {
+               _E("Failed to get subsystem from uevent");
+               goto out;
+       }
+
+       DD_LIST_FOREACH(opt_uevent_list, l, l_data) {
+               uh = (struct uevent_handler *)l_data;
+               if (strncmp(subsystem, uh->subsystem, strlen(uh->subsystem)))
+                       continue;
+               uh->uevent_func(dev);
+       }
+
+out:
+       udev_device_unref(dev);
+       return EINA_TRUE;
+}
+
+static int uevent_kernel_control_stop(void)
+{
+       struct udev_device *dev = NULL;
+
+       if (ufdh) {
+               ecore_main_fd_handler_del(ufdh);
+               ufdh = NULL;
+       }
+       if (ufd >= 0) {
+               close(ufd);
+               ufd = -1;
+       }
+       if (mon) {
+               dev = udev_monitor_receive_device(mon);
+               if (dev) {
+                       udev_device_unref(dev);
+                       dev = NULL;
+               }
+               udev_monitor_unref(mon);
+               mon = NULL;
+       }
+       if (udev && !mon_udev) {
+               udev_unref(udev);
+               udev = NULL;
+       }
+       return 0;
+}
+
+static int uevent_udev_control_stop(void)
+{
+       struct udev_device *dev = NULL;
+
+       if (ufdh_udev) {
+               ecore_main_fd_handler_del(ufdh_udev);
+               ufdh_udev = NULL;
+       }
+       if (ufd_udev >= 0) {
+               close(ufd_udev);
+               ufd_udev = -1;
+       }
+       if (mon_udev) {
+               dev = udev_monitor_receive_device(mon_udev);
+               if (dev) {
+                       udev_device_unref(dev);
+                       dev = NULL;
+               }
+               udev_monitor_unref(mon_udev);
+               mon_udev = NULL;
+       }
+       if (udev && !mon) {
+               udev_unref(udev);
+               udev = NULL;
+       }
+       return 0;
+}
+
+static int uevent_kernel_control_start(void)
+{
+       int i, ret;
+
+       if (udev && mon) {
+               _E("uevent control routine is alreay started");
+               return -EINVAL;
+       }
+
+       if (!udev) {
+               udev = udev_new();
+               if (!udev) {
+                       _E("error create udev");
+                       return -EINVAL;
+               }
+       }
+
+       mon = udev_monitor_new_from_netlink(udev, UDEV);
+       if (mon == NULL) {
+               _E("error udev_monitor create");
+               goto stop;
+       }
+
+       if (udev_monitor_set_receive_buffer_size(mon, UDEV_MONITOR_SIZE) != 0) {
+               _E("fail to set receive buffer size");
+               goto stop;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(udev_subsystems); i++) {
+               ret = udev_monitor_filter_add_match_subsystem_devtype(mon,
+                           udev_subsystems[i].str, udev_subsystems[i].devtype);
+               if (ret < 0) {
+                       _E("error apply subsystem filter");
+                       goto stop;
+               }
+       }
+
+       ret = udev_monitor_filter_update(mon);
+       if (ret < 0)
+               _E("error udev_monitor_filter_update");
+
+       ufd = udev_monitor_get_fd(mon);
+       if (ufd == -1) {
+               _E("error udev_monitor_get_fd");
+               goto stop;
+       }
+
+       ufdh = ecore_main_fd_handler_add(ufd, ECORE_FD_READ,
+                       uevent_kernel_control_cb, NULL, NULL, NULL);
+       if (!ufdh) {
+               _E("error ecore_main_fd_handler_add");
+               goto stop;
+       }
+
+       if (udev_monitor_enable_receiving(mon) < 0) {
+               _E("error unable to subscribe to udev events");
+               goto stop;
+       }
+
+       return 0;
+stop:
+       uevent_kernel_control_stop();
+       return -EINVAL;
+
+}
+
+static int uevent_udev_control_start(void)
+{
+       int i, ret;
+
+       if (udev && mon_udev) {
+               _E("uevent control routine is alreay started");
+               return 0;
+       }
+
+       if (!udev) {
+               udev = udev_new();
+               if (!udev) {
+                       _E("error create udev");
+                       return -EINVAL;
+               }
+       }
+
+       mon_udev = udev_monitor_new_from_netlink(udev, "udev");
+       if (mon_udev == NULL) {
+               _E("error udev_monitor create");
+               goto stop;
+       }
+
+       if (udev_monitor_set_receive_buffer_size(mon_udev, UDEV_MONITOR_SIZE_LARGE) != 0) {
+               _E("fail to set receive buffer size");
+               goto stop;
+       }
+
+       ufd_udev = udev_monitor_get_fd(mon_udev);
+       if (ufd_udev == -1) {
+               _E("error udev_monitor_get_fd");
+               goto stop;
+       }
+
+       ufdh_udev = ecore_main_fd_handler_add(ufd_udev, ECORE_FD_READ,
+                       uevent_udev_control_cb, NULL, NULL, NULL);
+       if (!ufdh_udev) {
+               _E("error ecore_main_fd_handler_add");
+               goto stop;
+       }
+
+       if (udev_monitor_enable_receiving(mon_udev) < 0) {
+               _E("error unable to subscribe to udev events");
+               goto stop;
+       }
+
+       return 0;
+stop:
+       uevent_udev_control_stop();
+       return -EINVAL;
+}
+
+int register_uevent_control(const struct uevent_handler *uh)
+{
+       int ret;
+
+       if (!mon || !uh)
+               return -EINVAL;
+
+       ret = udev_monitor_filter_add_match_subsystem_devtype(mon_udev,
+                       uh->subsystem, NULL);
+       if (ret < 0) {
+               _E("FAIL: udev_monitor_filter_add_match_subsystem_devtype()");
+               return -ENOMEM;
+       }
+
+       ret = udev_monitor_filter_update(mon_udev);
+       if (ret < 0)
+               _E("error udev_monitor_filter_update");
+
+       DD_LIST_APPEND(opt_uevent_list, uh);
+
+       return 0;
+}
+
+void unregister_uevent_control(const struct uevent_handler *uh)
+{
+       dd_list *l;
+       void *data;
+       struct uevent_handler *handler;
+
+       DD_LIST_FOREACH(opt_uevent_list, l, data) {
+               handler = (struct uevent_handler *)data;
+               if (strncmp(handler->subsystem, uh->subsystem, strlen(uh->subsystem)))
+                       continue;
+               if (handler->uevent_func != uh->uevent_func)
+                       continue;
+
+               DD_LIST_REMOVE(opt_uevent_list, handler);
+               free(handler);
+               break;
+       }
+}
+
+int register_kernel_uevent_control(const struct uevent_handler *uh)
+{
+       int ret;
+
+       if (!mon || !uh)
+               return -EINVAL;
+
+       ret = udev_monitor_filter_add_match_subsystem_devtype(mon,
+                       uh->subsystem, NULL);
+       if (ret < 0) {
+               _E("FAIL: udev_monitor_filter_add_match_subsystem_devtype()");
+               return -ENOMEM;
+       }
+
+       ret = udev_monitor_filter_update(mon);
+       if (ret < 0)
+               _E("error udev_monitor_filter_update");
+
+       DD_LIST_APPEND(opt_kernel_uevent_list, uh);
+
+       return 0;
+}
+
+void unregister_kernel_uevent_control(const struct uevent_handler *uh)
+{
+       dd_list *l;
+       void *data;
+       struct uevent_handler *handler;
+
+       DD_LIST_FOREACH(opt_kernel_uevent_list, l, data) {
+               handler = (struct uevent_handler *)data;
+               if (strncmp(handler->subsystem, uh->subsystem, strlen(uh->subsystem)))
+                       continue;
+               if (handler->uevent_func != uh->uevent_func)
+                       continue;
+
+               DD_LIST_REMOVE(opt_kernel_uevent_list, data);
+               break;
+       }
+}
+
+int uevent_udev_get_path(const char *subsystem, dd_list **list)
+{
+       struct udev_enumerate *enumerate = NULL;
+       struct udev_list_entry *devices, *dev_list_entry;
+       int ret;
+
+       if (!udev) {
+               udev = udev_new();
+               if (!udev) {
+                       _E("error create udev");
+                       return -EIO;
+               }
+       }
+
+       enumerate = udev_enumerate_new(udev);
+       if (!enumerate)
+               return -EIO;
+
+       ret = udev_enumerate_add_match_subsystem(enumerate, subsystem);
+       if (ret < 0)
+               return -EIO;
+
+       ret = udev_enumerate_scan_devices(enumerate);
+       if (ret < 0)
+               return -EIO;
+
+       devices = udev_enumerate_get_list_entry(enumerate);
+
+       udev_list_entry_foreach(dev_list_entry, devices) {
+               const char *path;
+               path = udev_list_entry_get_name(dev_list_entry);
+               _D("subsystem : %s, path : %s", subsystem, path);
+               DD_LIST_APPEND(*list, (void*)path);
+       }
+
+       return 0;
+}
+
+static int changed_device(int argc, char **argv)
+{
+       int val = 0;
+       int *state = NULL;
+       int i;
+
+       for (i = 0 ; i < argc ; i++) {
+               if (argv[i] == NULL) {
+                       _E("param is failed");
+                       return -EINVAL;
+               }
+       }
+
+       if (argc ==  2) {
+               if (argv[1] == NULL)
+                       val = 0;
+               else
+                       val = atoi(argv[1]);
+               state = &val;
+       }
+
+       if (strncmp(argv[0], USB_NAME, USB_NAME_LEN) == 0)
+               usb_chgdet_cb((void *)state);
+       else if (strncmp(argv[0], EARJACK_NAME, EARJACK_NAME_LEN) == 0)
+               earjack_chgdet_cb((void *)state);
+       else if (strncmp(argv[0], EARKEY_NAME, EARKEY_NAME_LEN) == 0)
+               earkey_chgdet_cb((void *)state);
+       else if (strncmp(argv[0], TVOUT_NAME, TVOUT_NAME_LEN) == 0)
+               tvout_chgdet_cb((void *)state);
+       else if (strncmp(argv[0], HDMI_NAME, HDMI_NAME_LEN) == 0)
+               hdmi_chgdet_cb((void *)state);
+       else if (strncmp(argv[0], HDCP_NAME, HDCP_NAME_LEN) == 0) {
+               hdcp_chgdet_cb((void *)state);
+               hdcp_hdmi_cb((void *)state);
+       }
+       else if (strncmp(argv[0], HDMI_AUDIO_NAME, HDMI_AUDIO_LEN) == 0)
+               hdmi_audio_chgdet_cb((void *)state);
+       else if (strncmp(argv[0], CRADLE_NAME, CRADLE_NAME_LEN) == 0)
+               cradle_chgdet_cb((void *)state);
+       else if (strncmp(argv[0], KEYBOARD_NAME, KEYBOARD_NAME_LEN) == 0)
+               keyboard_chgdet_cb((void *)state);
+       else if (strncmp(argv[0], POWER_SUBSYSTEM, POWER_SUPPLY_NAME_LEN) == 0)
+               power_supply((void *)state);
+
+       return 0;
+}
+
+static int changed_dev_earjack(int argc, char **argv)
+{
+       int val;
+
+       /* TODO
+        * if we can recognize which type of jack is changed,
+        * should move following code for TVOUT to a new action function */
+       /*
+          if(device_get_property(DEVTYPE_JACK,JACK_PROP_TVOUT_ONLINE,&val) == 0)
+          {
+          if (val == 1 &&
+          vconf_get_int(VCONFKEY_SETAPPL_TVOUT_TVSYSTEM_INT, &val) == 0) {
+          _E("Start TV out %s\n", (val==0)?"NTSC":(val==1)?"PAL":"Unsupported");
+          switch (val) {
+          case 0:              // NTSC
+          launch_after_kill_if_exist(TVOUT_X_BIN, "-connect 2");
+          break;
+          case 1:              // PAL
+          launch_after_kill_if_exist(TVOUT_X_BIN, "-connect 3");
+          break;
+          default:
+          _E("Unsupported TV system type:%d \n", val);
+          return -1;
+          }
+          // UI clone on
+          launch_evenif_exist(TVOUT_X_BIN, "-clone 1");
+          ss_flags |= TVOUT_FLAG;
+          return vconf_set_int(VCONFKEY_SYSMAN_EARJACK, VCONFKEY_SYSMAN_EARJACK_TVOUT);
+          }
+          else {
+          if(val == 1) {
+          _E("TV type is not set. Please set the TV type first.\n");
+          return -1;
+          }
+          if (ss_flags & TVOUT_FLAG) {
+          _E("TV out Jack is disconnected.\n");
+          // UI clone off
+          launch_after_kill_if_exist(TVOUT_X_BIN, "-clone 0");
+          ss_flags &= ~TVOUT_FLAG;
+          return vconf_set_int(VCONFKEY_SYSMAN_EARJACK, VCONFKEY_SYSMAN_EARJACK_REMOVED);
+          }
+          // Current event is not TV out event. Fall through
+          }
+          }
+        */
+       if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_EARJACK_ONLINE, &val) == 0) {
+               if (CONNECTED(val))
+                       extcon_set_count(EXTCON_EARJACK);
+               return vconf_set_int(VCONFKEY_SYSMAN_EARJACK, val);
+       }
+
+       return -1;
+}
+
+static DBusMessage *dbus_cradle_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = cradle_cb(NULL);
+       _I("cradle %d", ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_hdcp_hdmi_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = hdcp_hdmi_cb(NULL);
+       _I("hdmi %d", ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_hdcp_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = hdcp_chgdet_cb(NULL);
+       _I("hdcp %d", ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_hdmi_audio_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = hdmi_audio_chgdet_cb(NULL);
+       _I("hdmi audio %d", ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_device_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+       char *argv[2];
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv[0],
+                   DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       changed_device(argc, (char **)&argv);
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *dbus_battery_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+       char *argv[5];
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv[0],
+                   DBUS_TYPE_STRING, &argv[1],
+                   DBUS_TYPE_STRING, &argv[2],
+                   DBUS_TYPE_STRING, &argv[3],
+                   DBUS_TYPE_STRING, &argv[4], DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+       check_capacity_status(argv[0]);
+       check_charge_status(argv[1]);
+       check_health_status(argv[2]);
+       check_online_status(argv[3]);
+       check_present_status(argv[4]);
+       _I("%d %d %d %d %d %d %d %d",
+               battery.capacity,
+               battery.charge_full,
+               battery.charge_now,
+               battery.health,
+               battery.online,
+               battery.ovp,
+               battery.present,
+               battery.temp);
+       battery_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON);
+       notify_action(PREDEF_DEVICE_CHANGED, 2, POWER_SUBSYSTEM, argv[0]);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *dbus_udev_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+       char *argv;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (strncmp(argv, "start", strlen("start")) == 0) {
+               uevent_kernel_control_start();
+               uevent_udev_control_start();
+       } else if (strncmp(argv, "stop", strlen("stop")) == 0) {
+               uevent_kernel_control_stop();
+               uevent_udev_control_stop();
+       }
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { PREDEF_DEVICE_CHANGED,"siss",         "i",    dbus_device_handler },
+       { PREDEF_POWER_CHANGED, "sisssss",      "i",    dbus_battery_handler },
+       { PREDEF_UDEV_CONTROL,  "sis",          "i",    dbus_udev_handler },
+       { METHOD_GET_HDCP,      NULL,           "i",    dbus_hdcp_handler },
+       { METHOD_GET_HDMI_AUDIO,NULL,           "i",    dbus_hdmi_audio_handler },
+       { METHOD_GET_HDMI,      NULL,           "i",    dbus_hdcp_hdmi_handler },
+       { METHOD_GET_CRADLE,    NULL,           "i",    dbus_cradle_handler },
+};
+
+static int booting_done(void *data)
+{
+       static int done = 0;
+       int ret;
+       int val;
+
+       if (data == NULL)
+               return done;
+       done = (int)data;
+       if (done == 0)
+               return done;
+
+       _I("booting done");
+
+       register_action(PREDEF_EARJACKCON, changed_dev_earjack, NULL, NULL);
+       register_action(PREDEF_DEVICE_CHANGED, changed_device, NULL, NULL);
+
+       power_supply_timer_stop();
+       power_supply_init(NULL);
+
+       if (uevent_kernel_control_start() != 0) {
+               _E("fail uevent control init");
+               return 0;
+       }
+
+       if (uevent_udev_control_start() != 0) {
+               _E("fail uevent control init");
+               return 0;
+       }
+
+       /* set initial state for devices */
+       input_device_number = 0;
+       cradle_chgdet_cb(NULL);
+       keyboard_chgdet_cb(NULL);
+       hdmi_chgdet_cb(NULL);
+
+       ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &val);
+       if (ret == 0 && val != 0)
+               launch_cradle(val);
+       return done;
+}
+
+static int device_change_poweroff(void *data)
+{
+       uevent_kernel_control_stop();
+       uevent_udev_control_stop();
+       return 0;
+}
+
+static void device_change_init(void *data)
+{
+       int ret;
+
+       power_supply_timer_start();
+       if (extcon_count_init() != 0)
+               _E("fail to init extcon files");
+       register_notifier(DEVICE_NOTIFIER_POWEROFF, device_change_poweroff);
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+       register_notifier(DEVICE_NOTIFIER_LCD, display_changed);
+       ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       /* for simple noti change cb */
+       emulator_add_callback("device_usb_chgdet", (void *)usb_chgdet_cb, NULL);
+       emulator_add_callback("device_ta_chgdet", (void *)ta_chgdet_cb, data);
+       emulator_add_callback("device_earjack_chgdet", (void *)earjack_chgdet_cb, data);
+       emulator_add_callback("device_earkey_chgdet", (void *)earkey_chgdet_cb, data);
+       emulator_add_callback("device_tvout_chgdet", (void *)tvout_chgdet_cb, data);
+       emulator_add_callback("device_hdmi_chgdet", (void *)hdmi_chgdet_cb, data);
+       emulator_add_callback("device_cradle_chgdet", (void *)cradle_chgdet_cb, data);
+       emulator_add_callback("device_keyboard_chgdet", (void *)keyboard_chgdet_cb, data);
+
+       emulator_add_callback("unmount_ums", (void *)ums_unmount_cb, NULL);
+
+       /* check and set earjack init status */
+       changed_dev_earjack(0, NULL);
+       /* dbus noti change cb */
+#ifdef ENABLE_EDBUS_USE
+       e_dbus_init();
+       conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
+       if (!conn)
+               _E("check system dbus running!\n");
+
+       e_dbus_signal_handler_add(conn, NULL, "/system/uevent/xxxxx",
+                                 "system.uevent.xxxxx",
+                                 "Change", cb_xxxxx_signaled, data);
+#endif                         /* ENABLE_EDBUS_USE */
+}
+
+static void device_change_exit(void *data)
+{
+       int i;
+       unregister_notifier(DEVICE_NOTIFIER_POWEROFF, device_change_poweroff);
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+       unregister_notifier(DEVICE_NOTIFIER_LCD, display_changed);
+       for (i = 0; i < ARRAY_SIZE(extcon_devices); i++) {
+               if (extcon_devices[i].fd <= 0)
+                       continue;
+               close(extcon_devices[i].fd);
+       }
+
+}
+
+static const struct device_ops change_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "device change",
+       .init     = device_change_init,
+       .exit     = device_change_exit,
+};
+
+DEVICE_OPS_REGISTER(&change_device_ops)
diff --git a/src/core/device-handler.h b/src/core/device-handler.h
new file mode 100644 (file)
index 0000000..071b882
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * 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 __DEVICE_HANDLER_H__
+#define __DEVICE_HANDLER_H__
+
+#include "data.h"
+
+enum extcon_type {
+       EXTCON_TA = 0,
+       EXTCON_EARJACK,
+};
+
+enum device_change_type {
+       DEVICE_CHANGE_ABNORMAL  = 0,
+       DEVICE_CHANGE_NORMAL    = 1,
+};
+
+enum charge_full_type {
+       CHARGING_NOT_FULL       = 0,
+       CHARGING_FULL           = 1,
+};
+enum charge_now_type {
+       CHARGER_ABNORMAL        = -1,
+       CHARGER_DISCHARGING     = 0,
+       CHARGER_CHARGING        = 1,
+};
+enum health_type {
+       HEALTH_BAD              = 0,
+       HEALTH_GOOD             = 1,
+};
+
+enum temp_type {
+       TEMP_LOW                = 0,
+       TEMP_HIGH               = 1,
+};
+
+enum present_type {
+       PRESENT_ABNORMAL        = 0,
+       PRESENT_NORMAL          = 1,
+};
+
+enum ovp_type {
+       OVP_NORMAL              = 0,
+       OVP_ABNORMAL            = 1,
+};
+
+enum battery_noti_type {
+       DEVICE_NOTI_BATT_CHARGE = 0,
+       DEVICE_NOTI_BATT_LOW,
+       DEVICE_NOTI_BATT_FULL,
+       DEVICE_NOTI_MAX,
+};
+
+enum battery_noti_status {
+       DEVICE_NOTI_OFF = 0,
+       DEVICE_NOTI_ON  = 1,
+};
+
+enum dock_type {
+       DOCK_NONE       = 0,
+       DOCK_SOUND      = 7,
+};
+
+struct battery_status {
+       int capacity;
+       int charge_full;
+       int charge_now;
+       int health;
+       int present;
+       int online;
+       int temp;
+       int ovp;
+};
+
+struct battery_status battery;
+
+#define CONNECTED(val) ((val) != 0)
+
+/* Battery functions */
+void lowbat_monitor(void *data);
+
+int extcon_set_count(int index);
+
+int get_usb_state_direct(void);
+
+void sync_cradle_status(void);
+
+#endif /* __DEVICE_HANDLER_H__ */
diff --git a/src/core/device-notifier.c b/src/core/device-notifier.c
new file mode 100644 (file)
index 0000000..a02584a
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 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 "log.h"
+#include "devices.h"
+#include "device-notifier.h"
+#include "list.h"
+#include "common.h"
+
+struct device_notifier {
+       enum device_notifier_type status;
+       int (*func)(void *data);
+};
+
+static dd_list *device_notifier_list;
+
+#define FIND_NOTIFIER(a, b, d, e, f) \
+       DD_LIST_FOREACH(a, b, d) \
+               if (e == d->e && f == (d->f))
+
+int register_notifier(enum device_notifier_type status, int (*func)(void *data))
+{
+       dd_list *n;
+       struct device_notifier *data, *notifier;
+
+       _I("%d, %x", status, func);
+
+       if (!func) {
+               _E("invalid func address!");
+               return -EINVAL;
+       }
+
+       FIND_NOTIFIER(device_notifier_list, n, notifier, status, func) {
+               _E("function is already registered! [%d, %x]",
+                   status, func);
+               return -EINVAL;
+       }
+
+       notifier = malloc(sizeof(struct device_notifier));
+       if (!notifier) {
+               _E("Fail to malloc for notifier!");
+               return -ENOMEM;
+       }
+
+       notifier->status = status;
+       notifier->func = func;
+
+       DD_LIST_APPEND(device_notifier_list, notifier);
+
+       return 0;
+}
+
+int unregister_notifier(enum device_notifier_type status, int (*func)(void *data))
+{
+       dd_list *n;
+       struct device_notifier *notifier;
+
+       if (!func) {
+               _E("invalid func address!");
+               return -EINVAL;
+       }
+
+       FIND_NOTIFIER(device_notifier_list, n, notifier, status, func) {
+               _I("[%d, %x]", status, func);
+               DD_LIST_REMOVE(device_notifier_list, notifier);
+               free(notifier);
+       }
+
+       return 0;
+}
+
+void device_notify(enum device_notifier_type status, void *data)
+{
+       dd_list *n, *next;
+       struct device_notifier *notifier;
+       int cnt = 0;
+
+       DD_LIST_FOREACH_SAFE(device_notifier_list, n, next, notifier) {
+               if (status == notifier->status) {
+                       if (notifier->func) {
+                               notifier->func(data);
+                               cnt++;
+                       }
+               }
+       }
+}
+
+static void device_notifier_exit(void *data)
+{
+       dd_list *n;
+       struct device_notifier *notifier;
+
+       DD_LIST_FOREACH(device_notifier_list, n, notifier)
+               DD_LIST_REMOVE(device_notifier_list, notifier);
+               free(notifier);
+}
+
+static const struct device_ops notifier_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "notifier",
+       .exit     = device_notifier_exit,
+};
+
+DEVICE_OPS_REGISTER(&notifier_device_ops)
diff --git a/src/core/device-notifier.h b/src/core/device-notifier.h
new file mode 100644 (file)
index 0000000..490a98d
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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 __DEVICE_NOTIFIER_H__
+#define __DEVICE_NOTIFIER_H__
+
+enum device_notifier_type {
+       DEVICE_NOTIFIER_BOOTING_DONE,
+       DEVICE_NOTIFIER_HALLIC_OPEN,
+       DEVICE_NOTIFIER_HDMI,
+       DEVICE_NOTIFIER_LCD,
+       DEVICE_NOTIFIER_LCD_ESD,
+       DEVICE_NOTIFIER_MMC,
+       DEVICE_NOTIFIER_MMC_MOUNTED,
+       DEVICE_NOTIFIER_LOWBAT,
+       DEVICE_NOTIFIER_FULLBAT,
+       DEVICE_NOTIFIER_INPUT_ADD,
+       DEVICE_NOTIFIER_INPUT_REMOVE,
+       DEVICE_NOTIFIER_PROCESS_TERMINATED,
+       DEVICE_NOTIFIER_TOUCH_HARDKEY,
+       DEVICE_NOTIFIER_PMQOS_POWERSAVING,
+       DEVICE_NOTIFIER_PMQOS_LOWBAT,
+       DEVICE_NOTIFIER_PMQOS_EMERGENCY,
+       DEVICE_NOTIFIER_PMQOS_POWEROFF,
+       DEVICE_NOTIFIER_POWER_SUPPLY,
+       DEVICE_NOTIFIER_BATTERY_HEALTH,
+       DEVICE_NOTIFIER_BATTERY_OVP,
+       DEVICE_NOTIFIER_BATTERY_CHARGING,
+       DEVICE_NOTIFIER_POWEROFF,
+       DEVICE_NOTIFIER_POWEROFF_HAPTIC,
+       DEVICE_NOTIFIER_PMQOS,
+       DEVICE_NOTIFIER_POWERSAVER,
+       DEVICE_NOTIFIER_MAX,
+};
+
+/*
+ * This is for internal callback method.
+ */
+int register_notifier(enum device_notifier_type status, int (*func)(void *data));
+int unregister_notifier_del(enum device_notifier_type status, int (*func)(void *data));
+void device_notify(enum device_notifier_type status, void *value);
+
+#endif /* __DEVICE_NOTIFIER_H__ */
diff --git a/src/core/device-plugin.c b/src/core/device-plugin.c
new file mode 100644 (file)
index 0000000..3048892
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *  deviced
+ *
+ * Copyright (c) 2000 - 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.
+ */
+
+
+#include <dlfcn.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "device-plugin.h"
+
+static void *dlopen_handle;
+
+int _ss_devman_plugin_init()
+{
+       char *error;
+
+       dlopen_handle = dlopen(DEVMAN_PLUGIN_PATH, RTLD_NOW);
+       if (!dlopen_handle) {
+               _E("dlopen() failed");
+               return -1;
+       }
+
+       const OEM_sys_devman_plugin_interface *(*get_devman_plugin_interface) ();
+       get_devman_plugin_interface = dlsym(dlopen_handle, "OEM_sys_get_devman_plugin_interface");
+       if ((error = dlerror()) != NULL) {
+               _E("dlsym() failed: %s", error);
+               dlclose(dlopen_handle);
+               return -1;
+       }
+
+       plugin_intf = get_devman_plugin_interface();
+       if (!plugin_intf) {
+               _E("get_devman_plugin_interface() failed");
+               dlclose(dlopen_handle);
+               return -1;
+       }
+
+       return 0;
+}
+
+
+int _ss_devman_plugin_fini()
+{
+       if (dlopen_handle) {
+               dlclose(dlopen_handle);
+       }
+
+       return 0;
+}
+
+
diff --git a/src/core/device-plugin.h b/src/core/device-plugin.h
new file mode 100644 (file)
index 0000000..3c6df87
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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 __SS_DEVICE_PLUGIN_H__
+#define __SS_DEVICE_PLUGIN_H__
+
+#include "devman-plugin-intf.h"
+
+#define DEVMAN_PLUGIN_PATH      "/usr/lib/libslp_devman_plugin.so"
+
+int _ss_devman_plugin_init(void);
+int _ss_devman_plugin_fini(void);
+
+const OEM_sys_devman_plugin_interface *plugin_intf;
+
+#endif  /* __SS_DEVICE_PLUGIN_H__ */
diff --git a/src/core/devices.c b/src/core/devices.c
new file mode 100644 (file)
index 0000000..da2292f
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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 "log.h"
+#include "list.h"
+#include "common.h"
+#include "devices.h"
+
+static dd_list *dev_head;
+
+void add_device(const struct device_ops *dev)
+{
+       if (dev->priority == DEVICE_PRIORITY_HIGH)
+               DD_LIST_PREPEND(dev_head, dev);
+       else
+               DD_LIST_APPEND(dev_head, dev);
+}
+
+void remove_device(const struct device_ops *dev)
+{
+       DD_LIST_REMOVE(dev_head, dev);
+}
+
+const struct device_ops *find_device(const char *name)
+{
+       dd_list *elem;
+       const struct device_ops *dev;
+
+       DD_LIST_FOREACH(dev_head, elem, dev) {
+               if (!strcmp(dev->name, name))
+                       return dev;
+       }
+       return NULL;
+}
+
+void devices_init(void *data)
+{
+       dd_list *elem;
+       const struct device_ops *dev;
+
+       DD_LIST_FOREACH(dev_head, elem, dev) {
+               _D("[%s] initialize", dev->name);
+               if (dev->init)
+                       dev->init(data);
+       }
+}
+
+void devices_exit(void *data)
+{
+       dd_list *elem;
+       const struct device_ops *dev;
+
+       DD_LIST_FOREACH(dev_head, elem, dev) {
+               _D("[%s] deinitialize", dev->name);
+               if (dev->exit)
+                       dev->exit(data);
+       }
+}
diff --git a/src/core/devices.h b/src/core/devices.h
new file mode 100644 (file)
index 0000000..b4537ad
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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 __DEVICES_H__
+#define __DEVICES_H__
+
+#include <errno.h>
+#include "common.h"
+
+enum device_priority {
+       DEVICE_PRIORITY_NORMAL = 0,
+       DEVICE_PRIORITY_HIGH,
+};
+
+struct device_ops {
+       enum device_priority priority;
+       char *name;
+       void (*init) (void *data);
+       void (*exit) (void *data);
+       int (*start) (void);
+       int (*stop) (void);
+       int (*status) (void);
+};
+
+enum device_ops_status {
+       DEVICE_OPS_STATUS_UNINIT,
+       DEVICE_OPS_STATUS_START,
+       DEVICE_OPS_STATUS_STOP,
+       DEVICE_OPS_STATUS_MAX,
+};
+
+void devices_init(void *data);
+void devices_exit(void *data);
+
+static inline int device_start(const struct device_ops *dev)
+{
+       if (dev && dev->start)
+               return dev->start();
+
+       return -EINVAL;
+}
+
+static inline int device_stop(const struct device_ops *dev)
+{
+       if (dev && dev->stop)
+               return dev->stop();
+
+       return -EINVAL;
+}
+
+static inline int device_get_status(const struct device_ops *dev)
+{
+       if (dev && dev->status)
+               return dev->status();
+
+       return -EINVAL;
+}
+
+#define DEVICE_OPS_REGISTER(dev)       \
+static void __CONSTRUCTOR__ module_init(void)  \
+{      \
+       add_device(dev);        \
+}      \
+static void __DESTRUCTOR__ module_exit(void)   \
+{      \
+       remove_device(dev);     \
+}
+
+void add_device(const struct device_ops *dev);
+void remove_device(const struct device_ops *dev);
+const struct device_ops *find_device(const char *name);
+
+#endif
diff --git a/src/core/edbus-handler.c b/src/core/edbus-handler.c
new file mode 100644 (file)
index 0000000..f03a051
--- /dev/null
@@ -0,0 +1,587 @@
+/*
+ * 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 <stdbool.h>
+#include "core/log.h"
+#include "core/data.h"
+#include "core/edbus-handler.h"
+#include "core/common.h"
+#include "core/device-notifier.h"
+#include "core/list.h"
+
+#define EDBUS_INIT_RETRY_COUNT 5
+#define NAME_OWNER_CHANGED "NameOwnerChanged"
+#define NAME_OWNER_MATCH "type='signal',sender='org.freedesktop.DBus',\
+       path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',\
+       member='NameOwnerChanged',arg0='%s'"
+
+/* -1 is a default timeout value, it's converted to 25*1000 internally. */
+#define DBUS_REPLY_TIMEOUT     (-1)
+#define RETRY_MAX 5
+
+struct edbus_list{
+       char *signal_name;
+       E_DBus_Signal_Handler *handler;
+};
+
+static struct edbus_object {
+       const char *path;
+       const char *interface;
+       E_DBus_Object *obj;
+       E_DBus_Interface *iface;
+} edbus_objects[] = {
+       { DEVICED_PATH_CORE   , DEVICED_INTERFACE_CORE   , NULL, NULL },
+       { DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY, NULL, NULL },
+       { DEVICED_PATH_PASS   , DEVICED_INTERFACE_PASS   , NULL, NULL },
+       { DEVICED_PATH_HALL   , DEVICED_INTERFACE_HALL   , NULL, NULL },
+       { DEVICED_PATH_POWER  , DEVICED_INTERFACE_POWER  , NULL, NULL },
+       { DEVICED_PATH_STORAGE, DEVICED_INTERFACE_STORAGE, NULL, NULL },
+       { DEVICED_PATH_HAPTIC , DEVICED_INTERFACE_HAPTIC , NULL, NULL },
+       { DEVICED_PATH_LED    , DEVICED_INTERFACE_LED    , NULL, NULL },
+       { DEVICED_PATH_MMC    , DEVICED_INTERFACE_MMC    , NULL, NULL },
+       { DEVICED_PATH_PROCESS, DEVICED_INTERFACE_PROCESS, NULL, NULL },
+       { DEVICED_PATH_KEY    , DEVICED_INTERFACE_KEY    , NULL, NULL },
+       { DEVICED_PATH_CPU    , DEVICED_INTERFACE_CPU    , NULL, NULL },
+       { DEVICED_PATH_PMQOS  , DEVICED_INTERFACE_PMQOS  , NULL, NULL },
+       { DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI, NULL, NULL },
+       { DEVICED_PATH_USBHOST, DEVICED_INTERFACE_USBHOST, NULL, NULL },
+       { DEVICED_PATH_EXTCON , DEVICED_INTERFACE_EXTCON , NULL, NULL },
+       { DEVICED_PATH_BATTERY, DEVICED_INTERFACE_BATTERY, NULL, NULL },
+       { DEVICED_PATH_BOARD, DEVICED_INTERFACE_BOARD, NULL, NULL },
+       { DEVICED_PATH_TESTMODE, DEVICED_INTERFACE_TESTMODE, NULL, NULL},
+       /* Add new object & interface here*/
+};
+
+static dd_list *edbus_handler_list;
+static dd_list *edbus_watch_list;
+static int edbus_init_val;
+static DBusConnection *conn;
+static E_DBus_Connection *edbus_conn;
+static DBusPendingCall *edbus_request_name;
+
+static int register_edbus_interface(struct edbus_object *object)
+{
+       int ret;
+
+       if (!object) {
+               _E("object is invalid value!");
+               return -1;
+       }
+
+       object->obj = e_dbus_object_add(edbus_conn, object->path, NULL);
+       if (!object->obj) {
+               _E("fail to add edbus obj");
+               return -1;
+       }
+
+       object->iface = e_dbus_interface_new(object->interface);
+       if (!object->iface) {
+               _E("fail to add edbus interface");
+               return -1;
+       }
+
+       e_dbus_object_interface_attach(object->obj, object->iface);
+
+       return 0;
+}
+
+E_DBus_Interface *get_edbus_interface(const char *path)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(edbus_objects); i++)
+               if (!strcmp(path, edbus_objects[i].path))
+                       return edbus_objects[i].iface;
+
+       return NULL;
+}
+
+pid_t get_edbus_sender_pid(DBusMessage *msg)
+{
+       const char *sender;
+       DBusMessage *send_msg;
+       DBusPendingCall *pending;
+       DBusMessageIter iter;
+       int ret;
+       pid_t pid;
+
+       if (!msg) {
+               _E("invalid argument!");
+               return -1;
+       }
+
+       sender = dbus_message_get_sender(msg);
+       if (!sender) {
+               _E("invalid sender!");
+               return -1;
+       }
+
+       send_msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS,
+                                   DBUS_PATH_DBUS,
+                                   DBUS_INTERFACE_DBUS,
+                                   "GetConnectionUnixProcessID");
+       if (!send_msg) {
+               _E("invalid send msg!");
+               return -1;
+       }
+
+       ret = dbus_message_append_args(send_msg, DBUS_TYPE_STRING,
+                                   &sender, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("fail to append args!");
+               dbus_message_unref(send_msg);
+               return -1;
+       }
+
+       pending = e_dbus_message_send(edbus_conn, send_msg, NULL, -1, NULL);
+       if (!pending) {
+               _E("pending is null!");
+               dbus_message_unref(send_msg);
+               return -1;
+       }
+
+       dbus_message_unref(send_msg);
+
+       /* block until reply is received */
+       dbus_pending_call_block(pending);
+
+       msg = dbus_pending_call_steal_reply(pending);
+       dbus_pending_call_unref(pending);
+       if (!msg) {
+               _E("reply msg is null!");
+               return -1;
+       }
+
+       dbus_message_iter_init(msg, &iter);
+       dbus_message_iter_get_basic(&iter, &pid);
+       dbus_message_unref(msg);
+
+       return pid;
+}
+
+static void unregister_edbus_signal_handle(void)
+{
+       dd_list *tmp;
+       struct edbus_list *entry;
+
+       DD_LIST_FOREACH(edbus_handler_list, tmp, entry) {
+               e_dbus_signal_handler_del(edbus_conn, entry->handler);
+               DD_LIST_REMOVE(edbus_handler_list, entry);
+               free(entry->signal_name);
+               free(entry);
+       }
+}
+
+int register_edbus_signal_handler(const char *path, const char *interface,
+               const char *name, E_DBus_Signal_Cb cb)
+{
+       dd_list *tmp;
+       struct edbus_list *entry;
+       E_DBus_Signal_Handler *handler;
+
+       DD_LIST_FOREACH(edbus_handler_list, tmp, entry) {
+               if (strncmp(entry->signal_name, name, strlen(name)) == 0)
+                       return -EEXIST;
+       }
+
+       handler = e_dbus_signal_handler_add(edbus_conn, NULL, path,
+                               interface, name, cb, NULL);
+
+       if (!handler) {
+               _E("fail to add edbus handler");
+               return -ENOMEM;
+       }
+
+       entry = malloc(sizeof(struct edbus_list));
+
+       if (!entry) {
+               _E("Malloc failed");
+               return -ENOMEM;
+       }
+
+       entry->signal_name = strndup(name, strlen(name));
+
+       if (!entry->signal_name) {
+               _E("Malloc failed");
+               free(entry);
+               return -ENOMEM;
+       }
+
+       entry->handler = handler;
+       DD_LIST_PREPEND(edbus_handler_list, entry);
+       if (!edbus_handler_list) {
+               _E("eina_list_prepend failed");
+               free(entry->signal_name);
+               free(entry);
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+int broadcast_edbus_signal(const char *path, const char *interface,
+               const char *name, const char *sig, char *param[])
+{
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       int r;
+
+       msg = dbus_message_new_signal(path, interface, name);
+       if (!msg) {
+               _E("fail to allocate new %s.%s signal", interface, name);
+               return -EPERM;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       r = append_variant(&iter, sig, param);
+       if (r < 0) {
+               _E("append_variant error(%d)", r);
+               return -EPERM;
+       }
+
+       e_dbus_message_send(edbus_conn, msg, NULL, -1, NULL);
+
+       dbus_message_unref(msg);
+       return 0;
+}
+
+static DBusHandlerResult message_filter(DBusConnection *connection,
+               DBusMessage *message, void *data)
+{
+       char match[256];
+       int ret;
+       const char *iface, *member, *arg = NULL;
+       struct watch *watch;
+       dd_list *n;
+
+       if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+       iface = dbus_message_get_interface(message);
+       member = dbus_message_get_member(message);
+
+       if (strcmp(iface, DBUS_INTERFACE_DBUS))
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+       if (strcmp(member, NAME_OWNER_CHANGED))
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+       ret = dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg,
+                   DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message");
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+       }
+
+       _D("Argument : %s", arg);
+
+       DD_LIST_FOREACH(edbus_watch_list, n, watch) {
+               if (strcmp(arg, watch->name)) continue;
+
+               if (watch->func)
+                       watch->func(watch->name, watch->id);
+
+               DD_LIST_REMOVE(edbus_watch_list, watch);
+               free(watch->name);
+               free(watch);
+       }
+
+       /* remove registered sender */
+       snprintf(match, sizeof(match), NAME_OWNER_MATCH, arg);
+       dbus_bus_remove_match(conn, match, NULL);
+
+
+       if (DD_LIST_LENGTH(edbus_watch_list) == 0) {
+               dbus_connection_remove_filter(conn, message_filter, NULL);
+               _I("remove message filter, no watcher!");
+       }
+
+       return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+int register_edbus_watch(DBusMessage *msg, enum watch_id id, int (*func)(char *name, enum watch_id id))
+{
+       char match[256];
+       const char *sender;
+       struct watch *watch;
+       dd_list *n;
+       int ret;
+       bool matched = false;
+
+       if (!msg) {
+               _E("invalid argument!");
+               return -EINVAL;
+       }
+
+       sender = dbus_message_get_sender(msg);
+       if (!sender) {
+               _E("invalid sender!");
+               return -EINVAL;
+       }
+
+       /* check the sender&id is already registered */
+       DD_LIST_FOREACH(edbus_watch_list, n, watch) {
+               if (strcmp(sender, watch->name))
+                       continue;
+               if (id != watch->id) {
+                       matched = true;
+                       continue;
+               }
+
+               _I("%s(%d) is already watched!", watch->name, watch->id);
+
+               return 0;
+       }
+
+        watch = malloc(sizeof(struct watch));
+        if (!watch) {
+                _E("Fail to malloc for watch!");
+                return -ENOMEM;
+        }
+
+       watch->id = id;
+       watch->func = func;
+       watch->name = strndup(sender, strlen(sender));
+
+       if (!watch->name) {
+               _E("Fail to malloc for watch name");
+               free(watch);
+               return -ENOMEM;
+       }
+
+       /* Add message filter */
+       if (DD_LIST_LENGTH(edbus_watch_list) == 0) {
+               ret = dbus_connection_add_filter(conn, message_filter, NULL, NULL);
+               if (!ret) {
+                       _E("fail to add message filter!");
+                       free(watch->name);
+                       free(watch);
+                       return -ENOMEM;
+               }
+               _I("success to add message filter!");
+       }
+
+       /* Add watch to watch list */
+       DD_LIST_APPEND(edbus_watch_list, watch);
+
+       if (!matched) {
+               snprintf(match, sizeof(match), NAME_OWNER_MATCH, watch->name);
+               dbus_bus_add_match(conn, match, NULL);
+       }
+
+       _I("%s(%d) is watched by dbus!", watch->name, watch->id);
+
+       return 0;
+}
+
+int unregister_edbus_watch(DBusMessage *msg, enum watch_id id)
+{
+       char match[256];
+       const char *sender;
+       struct watch *watch;
+       dd_list *n;
+       bool matched = false;
+
+       if (!msg) {
+               _E("invalid argument!");
+               return -EINVAL;
+       }
+
+       sender = dbus_message_get_sender(msg);
+       if (!sender) {
+               _E("invalid sender!");
+               return -EINVAL;
+       }
+
+       DD_LIST_FOREACH(edbus_watch_list, n, watch) {
+               if (strcmp(sender, watch->name))
+                       continue;
+
+               if (id != watch->id) {
+                       matched = true;
+                       continue;
+               }
+               DD_LIST_REMOVE(edbus_watch_list, watch);
+               free(watch->name);
+               free(watch);
+       }
+
+       /* remove match */
+       if (!matched) {
+                snprintf(match, sizeof(match), NAME_OWNER_MATCH, sender);
+                dbus_bus_remove_match(conn, match, NULL);
+
+               if (DD_LIST_LENGTH(edbus_watch_list) == 0)
+                       dbus_connection_remove_filter(conn, message_filter,
+                           NULL);
+       }
+
+       return 0;
+}
+
+static void unregister_edbus_watch_all(void)
+{
+       char match[256];
+       dd_list *n;
+       struct watch *watch;
+
+       if (DD_LIST_LENGTH(edbus_watch_list) > 0)
+               dbus_connection_remove_filter(conn, message_filter, NULL);
+
+       DD_LIST_FOREACH(edbus_watch_list, n, watch) {
+               snprintf(match, sizeof(match), NAME_OWNER_MATCH, watch->name);
+               dbus_bus_remove_match(conn, match, NULL);
+               DD_LIST_REMOVE(edbus_watch_list, watch);
+               free(watch->name);
+               free(watch);
+       }
+}
+
+int register_edbus_method(const char *path, const struct edbus_method *edbus_methods, int size)
+{
+       E_DBus_Interface *iface;
+       int ret;
+       int i;
+
+       iface = get_edbus_interface(path);
+
+       if (!iface) {
+               _E("fail to get edbus interface!");
+               return -ENODEV;
+       }
+
+       for (i = 0; i < size; i++) {
+               ret = e_dbus_interface_method_add(iface,
+                                   edbus_methods[i].member,
+                                   edbus_methods[i].signature,
+                                   edbus_methods[i].reply_signature,
+                                   edbus_methods[i].func);
+               if (!ret) {
+                       _E("fail to add method %s!", edbus_methods[i].member);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static void request_name_cb(void *data, DBusMessage *msg, DBusError *error)
+{
+       DBusError err;
+       unsigned int val;
+       int r;
+
+       if (!msg) {
+               _D("invalid DBusMessage!");
+               return;
+       }
+
+       dbus_error_init(&err);
+       r = dbus_message_get_args(msg, &err, DBUS_TYPE_UINT32, &val, DBUS_TYPE_INVALID);
+       if (!r) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               return;
+       }
+
+       _I("Request Name reply : %d", val);
+}
+
+void edbus_init(void *data)
+{
+       DBusError error;
+       int retry = 0;
+       int i, ret;
+
+       dbus_threads_init_default();
+       dbus_error_init(&error);
+
+       do {
+               edbus_init_val = e_dbus_init();
+               if (edbus_init_val)
+                       break;
+               if (retry == EDBUS_INIT_RETRY_COUNT) {
+                       _E("fail to init edbus");
+                       return;
+               }
+               retry++;
+       } while (retry <= EDBUS_INIT_RETRY_COUNT);
+
+       retry = 0;
+       do {
+               conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+               if (conn)
+                       break;
+               if (retry == EDBUS_INIT_RETRY_COUNT) {
+                       _E("fail to get dbus");
+                       goto out1;
+               }
+               retry++;
+       } while (retry <= EDBUS_INIT_RETRY_COUNT);
+
+       retry = 0;
+       do {
+               edbus_conn = e_dbus_connection_setup(conn);
+               if (edbus_conn)
+                       break;
+               if (retry == EDBUS_INIT_RETRY_COUNT) {
+                       _E("fail to get edbus");
+                       goto out2;
+               }
+               retry++;
+       } while (retry <= EDBUS_INIT_RETRY_COUNT);
+
+       retry = 0;
+       do {
+               edbus_request_name = e_dbus_request_name(edbus_conn, DEVICED_BUS_NAME,
+                               DBUS_NAME_FLAG_REPLACE_EXISTING, request_name_cb, NULL);
+               if (edbus_request_name)
+                       break;
+               if (retry == EDBUS_INIT_RETRY_COUNT) {
+                       _E("fail to request edbus name");
+                       goto out3;
+               }
+               retry++;
+       } while (retry <= EDBUS_INIT_RETRY_COUNT);
+
+       for (i = 0; i < ARRAY_SIZE(edbus_objects); i++) {
+               ret = register_edbus_interface(&edbus_objects[i]);
+               if (ret < 0) {
+                       _E("fail to add obj & interface for %s",
+                                   edbus_objects[i].interface);
+                       return;
+               }
+               _D("add new obj for %s", edbus_objects[i].interface);
+       }
+       return;
+
+out3:
+       e_dbus_connection_close(edbus_conn);
+out2:
+       dbus_connection_set_exit_on_disconnect(conn, FALSE);
+out1:
+       e_dbus_shutdown();
+}
+
+void edbus_exit(void *data)
+{
+       unregister_edbus_signal_handle();
+       unregister_edbus_watch_all();
+       e_dbus_connection_close(edbus_conn);
+       e_dbus_shutdown();
+}
diff --git a/src/core/edbus-handler.h b/src/core/edbus-handler.h
new file mode 100644 (file)
index 0000000..88f2cd2
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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 __EDBUS_HANDLE_H__
+#define __EDBUS_HANDLE_H__
+
+#include <E_DBus.h>
+#include "shared/dbus.h"
+
+struct edbus_method {
+       const char *member;
+       const char *signature;
+       const char *reply_signature;
+       E_DBus_Method_Cb func;
+};
+
+enum watch_id {
+       WATCH_DISPLAY_AUTOBRIGHTNESS_MIN,
+       WATCH_DISPLAY_LCD_TIMEOUT,
+       WATCH_DISPLAY_LOCK_STATE,
+       WATCH_DISPLAY_HOLD_BRIGHTNESS,
+       WATCH_HAPTIC_OPEN_DEVICE,
+       WATCH_POWER_RESETKEY_DISABLE,
+       WATCH_POWER_WAKEUPKEY,
+};
+
+struct watch {
+       enum watch_id id;
+       char *name;
+       int (*func)(char *name, enum watch_id id);
+};
+
+int register_edbus_method(const char *path, const struct edbus_method *edbus_methods, int size);
+int register_edbus_signal_handler(const char *path, const char *interface,
+               const char *name, E_DBus_Signal_Cb cb);
+E_DBus_Interface *get_edbus_interface(const char *path);
+pid_t get_edbus_sender_pid(DBusMessage *msg);
+int broadcast_edbus_signal(const char *path, const char *interface,
+               const char *name, const char *sig, char *param[]);
+int register_edbus_watch(DBusMessage *msg, enum watch_id id, int (*func)(char *name, enum watch_id id));
+int unregister_edbus_watch(DBusMessage *msg, enum watch_id id);
+
+void edbus_init(void *data);
+void edbus_exit(void *data);
+
+#endif /* __EDBUS_HANDLE_H__ */
diff --git a/src/core/emulator.h b/src/core/emulator.h
new file mode 100644 (file)
index 0000000..71a5edf
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __EMULATOR_H__
+#define __EMULATOR_H__
+
+#include "noti.h"
+
+#ifdef MOBILE_EMULATOR
+static inline int emulator_add_callback(const char *noti,
+    void (*cb) (void *), void *data)
+{
+       return noti_add(noti, cb, data);
+}
+#else
+#define emulator_add_callback(a, b, c) do { } while (0)
+#endif
+
+#endif
diff --git a/src/core/execute.c b/src/core/execute.c
new file mode 100755 (executable)
index 0000000..1c664da
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "log.h"
+
+static int parent(pid_t pid)
+{
+       int status;
+
+       /* wait for child */
+       if (waitpid(pid, &status, 0) != -1) {
+               /* terminated normally */
+               if (WIFEXITED(status)) {
+                       _I("%d terminated by exit(%d)", pid, WEXITSTATUS(status));
+                       return WEXITSTATUS(status);
+               } else if (WIFSIGNALED(status))
+                       _I("%d terminated by signal %d", pid, WTERMSIG(status));
+               else if (WIFSTOPPED(status))
+                       _I("%d stopped by signal %d", pid, WSTOPSIG(status));
+       } else
+               _I("%d waitpid() failed : %s", pid, strerror(errno));
+
+       return -EAGAIN;
+}
+
+static void child(int argc, const char *argv[])
+{
+       int i, r;
+
+       for (i = 0; i < _NSIG; ++i)
+               signal(i, SIG_DFL);
+
+       r = execv(argv[0], (char **)argv);
+       if (r < 0)
+               exit(EXIT_FAILURE);
+}
+
+int run_child(int argc, const char *argv[])
+{
+       pid_t pid;
+       struct sigaction act, oldact;
+       int r;
+
+       if (!argv)
+               return -EINVAL;
+
+       /* Use default signal handler */
+       act.sa_handler = SIG_DFL;
+       act.sa_sigaction = NULL;
+       act.sa_flags = 0;
+       sigemptyset(&act.sa_mask);
+
+       if (sigaction(SIGCHLD, &act, &oldact) < 0)
+               return -errno;
+
+       pid = fork();
+       if (pid < 0) {
+               _E("failed to fork");
+               r = -errno;
+       } else if (pid == 0) {
+               child(argc, argv);
+       } else
+               r = parent(pid);
+
+       if (sigaction(SIGCHLD, &oldact, NULL) < 0)
+               _E("failed to restore sigaction");
+
+       return r;
+}
diff --git a/src/core/launch.c b/src/core/launch.c
new file mode 100644 (file)
index 0000000..eb59419
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * 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 <sys/types.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "vconf-keys.h"
+#include "log.h"
+#include "launch.h"
+#include "common.h"
+
+#define MAX_ARGS 255
+
+#define _S(str) ((str == NULL) ? "" : str)
+
+static int set_current_lang(void)
+{
+       char *lang;
+       int ret;
+
+       lang = (char *)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) {
+               _E("launch app error: Invalid input");
+               errno = EINVAL;
+               return -1;
+       }
+
+       if (pid && (*pid > 0 && kill(*pid, 0) != -1))
+               return *pid;
+
+       _pid = fork();
+
+       if (_pid == -1) {
+               _E("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)
+               _E("nice error: %s", strerror(errno));
+
+       ret = execvp(file, argv);
+
+       /* If failed... */
+       _E("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) {
+               _E("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 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 = get_exec_pid(execpath) > 0)
+               return pid;
+
+       va_start(argptr, arg);
+       flag = va_arg(argptr, int);
+
+       if (flag & LAUNCH_NICE)
+               nice_value = va_arg(argptr, int);
+
+       va_end(argptr);
+
+       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 */
+               _E("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 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 & LAUNCH_NICE)
+               nice_value = va_arg(argptr, int);
+
+       va_end(argptr);
+
+       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
+               _E("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 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 = get_exec_pid(execpath)) > 0)
+               kill(exist_pid, SIGTERM);
+
+       va_start(argptr, arg);
+       flag = va_arg(argptr, int);
+
+       if (flag & LAUNCH_NICE)
+               nice_value = va_arg(argptr, int);
+
+       va_end(argptr);
+
+       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 */
+               _E("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/src/core/launch.h b/src/core/launch.h
new file mode 100644 (file)
index 0000000..495512c
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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 __LAUNCH_H__
+#define __LAUNCH_H__
+
+#define LAUNCH_NICE          0x0002
+
+int launch_if_noexist(const char *execpath, const char *arg, ...);
+int launch_evenif_exist(const char *execpath, const char *arg, ...);
+int launch_after_kill_if_exist(const char *execpath, const char *arg, ...);
+
+#endif /* __LAUNCH_H__ */
diff --git a/src/core/list.h b/src/core/list.h
new file mode 100644 (file)
index 0000000..b688dec
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 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>
+#include <stdio.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)
+#define DD_LIST_FOREACH_SAFE(head, elem, elem_next, node) \
+       EINA_LIST_FOREACH_SAFE(head, elem, elem_next, 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, node = NULL; elem && ((node = elem->data) != NULL); elem = elem->next, node = NULL)
+#define DD_LIST_FOREACH_SAFE(head, elem, elem_next, node) \
+       for (elem = head, elem_next = g_list_next(elem), node = NULL; \
+                       elem && ((node = elem->data) != NULL); \
+                       elem = elem_next, elem_next = g_list_next(elem), node = NULL)
+
+#endif
+
+#endif
diff --git a/src/core/log.h b/src/core/log.h
new file mode 100644 (file)
index 0000000..758151e
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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__
+
+#ifdef ENABLE_DEVICED_DLOG
+#define ENABLE_DLOG
+#endif
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "DEVICED"
+#include "shared/log-macro.h"
+
+#endif
diff --git a/src/core/lowstorage.c b/src/core/lowstorage.c
new file mode 100755 (executable)
index 0000000..ce6a98e
--- /dev/null
@@ -0,0 +1,439 @@
+/*
+ * 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 <fcntl.h>
+#include <assert.h>
+#include <limits.h>
+#include <vconf.h>
+#include <sys/types.h>
+#include <sys/statvfs.h>
+#include <sys/stat.h>
+#include <sys/shm.h>
+#include <time.h>
+
+#include "device-node.h"
+#include "core/log.h"
+#include "core/noti.h"
+#include "core/queue.h"
+#include "core/predefine.h"
+#include "core/data.h"
+#include "core/devices.h"
+#include "core/common.h"
+#include "core/edbus-handler.h"
+#include "core/device-notifier.h"
+
+#define MEMNOTIFY_NORMAL       0x0000
+#define MEMNOTIFY_LOW          0xfaac
+#define MEMNOTIFY_CRITICAL     0xdead
+#define MEMNOTIFY_REBOOT       0xb00f
+
+#define MEMORY_STATUS_USR_PATH         "/opt/usr"
+#define MEMORY_MAX_MEM_STR_LEN         30
+#define MEMORY_KILOBYTE_VALUE          1024
+#define MEMORY_MEGABYTE_VALUE          1048576
+#define MEMORY_GIGABYTE_VALUE          1073741824
+#define MEMORY_RESERVE_VALUE           (100*MEMORY_MEGABYTE_VALUE)
+#define MEMNOTI_WARNING_VALUE          (5) // 5% under
+#define MEMNOTI_CRITICAL_VALUE         (0.1) // 0.1% under
+#define MEMNOTI_CRITICAL_SIZE(val)     ((val*MEMNOTI_CRITICAL_VALUE)/100)
+#define MEMNOTI_FULL_SIZE              (MEMORY_RESERVE_VALUE + MEMORY_MEGABYTE_VALUE)
+
+#define SIGNAL_LOWMEM_STATE    "ChangeState"
+#define SIGNAL_LOWMEM_FULL     "Full"
+
+#define POPUP_KEY_MEMNOTI      "_MEM_NOTI_"
+#define POPUP_KEY_APPNAME      "_APP_NAME_"
+
+#define LOWMEM_POPUP_NAME      "lowmem-syspopup"
+
+#define MEMNOTI_TIMER_INTERVAL 5
+#define MEM_TRIM_TIMER_INTERVAL        86400 /* 24 hour */
+#define MEM_FSTRIM_PATH                "/sbin/fstrim"
+
+#define MEM_TRIM_START_TIME    2 // AM 02:00:00
+#define MIN_SEC                        (60)
+#define HOUR_SEC               (MIN_SEC * MIN_SEC)
+
+#define BUF_MAX 1024
+
+enum memnoti_level {
+       MEMNOTI_LEVEL_CRITICAL = 0,
+       MEMNOTI_LEVEL_WARNING,
+       MEMNOTI_LEVEL_NORMAL,
+} ;
+
+struct popup_data {
+       char *name;
+       char *key;
+       char *value;
+};
+
+static Ecore_Fd_Handler *lowmem_efd = NULL;
+static int lowmem_fd;
+static int cur_mem_state = MEMNOTIFY_NORMAL;
+
+static Ecore_Timer *memnoti_timer = NULL;
+static Ecore_Timer *mem_trim_timer = NULL;
+
+static double memnoti_warning_level = MEMNOTI_WARNING_VALUE;
+static double memnoti_critical_level = MEMNOTI_CRITICAL_VALUE;
+static double memnoti_full_level;
+
+static void memnoti_send_broadcast(int status)
+{
+       static int old = 0;
+       char *arr[1];
+       char str_status[32];
+
+       if (old == status)
+               return;
+
+       old = status;
+       snprintf(str_status, sizeof(str_status), "%d", status);
+       arr[0] = str_status;
+       broadcast_edbus_signal(DEVICED_PATH_LOWMEM, DEVICED_INTERFACE_LOWMEM,
+                       SIGNAL_LOWMEM_STATE, "i", arr);
+}
+
+static void memnoti_level_broadcast(enum memnoti_level level)
+{
+       static int status = 0;
+       if (level == MEMNOTI_LEVEL_CRITICAL && status == 0)
+               status = 1;
+       else if (level != MEMNOTI_LEVEL_CRITICAL && status == 1)
+               status = 0;
+       else
+               return;
+       _D("send user mem noti : %d %d", level, status);
+       memnoti_send_broadcast(status);
+}
+
+static int memnoti_popup(enum memnoti_level level)
+{
+       int ret = -1;
+       int val = -1;
+       char *value = NULL;
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+
+       if (level != MEMNOTI_LEVEL_WARNING && level != MEMNOTI_LEVEL_CRITICAL) {
+               _E("level check error : %d",level);
+               return 0;
+       }
+
+       if (level == MEMNOTI_LEVEL_WARNING) {
+               value = "warning";
+       } else if (level == MEMNOTI_LEVEL_CRITICAL) {
+               value = "critical";
+       }
+
+       ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &val);
+       if (val == 0 || ret != 0)
+               goto out;
+       if (apps == NULL) {
+               apps = find_device("apps");
+               if (apps == NULL)
+                       return 0;
+       }
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return -1;
+       }
+       params->name = LOWMEM_POPUP_NAME;
+       params->key = POPUP_KEY_MEMNOTI;
+       params->value = strdup(value);
+       apps->init((void *)params);
+       free(params);
+       return 0;
+out:
+       return -1;
+}
+
+static enum memnoti_level check_memnoti_level(double total, double avail)
+{
+       double tmp_size = (avail/total)*100;
+
+       if (tmp_size > memnoti_warning_level)
+               return MEMNOTI_LEVEL_NORMAL;
+       if (tmp_size > memnoti_critical_level)
+               return MEMNOTI_LEVEL_WARNING;
+       return MEMNOTI_LEVEL_CRITICAL;
+}
+
+static void memnoti_full_broadcast(double total, double avail)
+{
+       static int status = 0;
+       int tmp = 0;
+       double tmp_size = (avail/total)*100;
+       char *arr[1];
+       char str_status[32];
+
+       tmp = status;
+       if (tmp_size <= memnoti_full_level && status == 0)
+               status = 1;
+       else if (tmp_size > memnoti_full_level && status == 1)
+               status = 0;
+       if (status == tmp)
+               return;
+
+       _D("send memory full noti : %d (total: %4.4lf avail: %4.4lf)", status, total, avail);
+       snprintf(str_status, sizeof(str_status), "%d", status);
+       arr[0] = str_status;
+       broadcast_edbus_signal(DEVICED_PATH_LOWMEM, DEVICED_INTERFACE_LOWMEM,
+                       SIGNAL_LOWMEM_FULL, "i", arr);
+}
+
+static int __fs_stat(double* pdTotal, double* pdAvail, const char* szPath)
+{
+       struct statvfs s;
+       double reserved;
+
+       if (NULL == pdAvail) {
+               _E("input param error");
+               return 0;
+       }
+
+       if (!statvfs(szPath, &s)) {
+               reserved = MEMORY_RESERVE_VALUE/s.f_bsize;
+               if (s.f_bavail < reserved)
+                       s.f_bavail = 0;
+               else
+                       s.f_bavail -= reserved;
+               *pdTotal = (double)s.f_frsize * s.f_blocks;
+               *pdAvail = (double)s.f_bsize * s.f_bavail;
+       } else {
+               _E("fail to get memory size");
+               return 0;
+       }
+
+       return 1;
+}
+
+static void memory_status_set_full_mem_size(void)
+{
+       double dAvail = 0.0;
+       double dTotal = 0.0;
+
+       if (__fs_stat(&dTotal, &dAvail, MEMORY_STATUS_USR_PATH) == 0) {
+               _E("fail to get mem size of %s",MEMORY_STATUS_USR_PATH);
+               return;
+       }
+
+       memnoti_full_level = (MEMNOTI_FULL_SIZE/dTotal)*100;
+       _I("memnoti_full_level : %4.4lf(%d)", memnoti_full_level, MEMNOTI_FULL_SIZE);
+}
+
+static Eina_Bool memory_status_get_available_size(void *data)
+{
+       static enum memnoti_level old = MEMNOTI_LEVEL_NORMAL;
+       enum memnoti_level now;
+       int ret;
+       double dAvail = 0.0;
+       double dTotal = 0.0;
+
+       ret = __fs_stat(&dTotal, &dAvail, MEMORY_STATUS_USR_PATH);
+       if (ret == 0) {
+               _E("fail to get mem size of %s",MEMORY_STATUS_USR_PATH);
+               goto out;
+       }
+
+       memnoti_full_broadcast(dTotal, dAvail);
+
+       now = check_memnoti_level(dTotal, dAvail);
+
+       memnoti_level_broadcast(now);
+
+       if (now < MEMNOTI_LEVEL_NORMAL && now < old) {
+               ret = memnoti_popup(now);
+               if (ret != 0)
+                       now = MEMNOTI_LEVEL_NORMAL;
+       }
+       old = now;
+       if (memnoti_timer)
+               ecore_timer_interval_set(memnoti_timer, MEMNOTI_TIMER_INTERVAL);
+out:
+       return EINA_TRUE;
+}
+
+static int __memnoti_fd_init(struct main_data *ad)
+{
+       memory_status_set_full_mem_size();
+       memory_status_get_available_size(ad);
+       memnoti_timer = ecore_timer_add(MEMNOTI_TIMER_INTERVAL,
+                               memory_status_get_available_size, ad);
+       if (memnoti_timer == NULL)
+           _E("fail mem available noti timer add");
+       return 0;
+}
+
+static Eina_Bool memory_trim_cb(void *data)
+{
+       ecore_timer_interval_set(memnoti_timer, MEM_TRIM_TIMER_INTERVAL);
+       if (launch_if_noexist(MEM_FSTRIM_PATH, MEMORY_STATUS_USR_PATH) == -1) {
+               _E("fail to launch fstrim");
+       } else {
+               _D("fs memory trim is operated");
+       }
+       return EINA_TRUE;
+}
+
+static int __mem_trim_delta(struct tm *cur_tm)
+{
+       int delta = 0;
+       int sign_val;
+
+       if (cur_tm->tm_hour < MEM_TRIM_START_TIME)
+               sign_val = 1;
+       else
+               sign_val = -1;
+       delta += ((sign_val) * (MEM_TRIM_START_TIME - cur_tm->tm_hour) * HOUR_SEC);
+       delta -= ((sign_val) * (cur_tm->tm_min * MIN_SEC + cur_tm->tm_sec));
+       return delta;
+}
+
+static int __run_mem_trim(void)
+{
+       time_t now;
+       struct tm *cur_tm;
+       int mem_trim_time;
+
+       now = time(NULL);
+       cur_tm = (struct tm *)malloc(sizeof(struct tm));
+       if (cur_tm == NULL) {
+               _E("Fail to memory allocation");
+               return -1;
+       }
+
+       if (localtime_r(&now, cur_tm) == NULL) {
+               _E("Fail to get localtime");
+               free(cur_tm);
+               return -1;
+       }
+
+       mem_trim_time = MEM_TRIM_TIMER_INTERVAL + __mem_trim_delta(cur_tm);
+       _D("start mem trim timer", mem_trim_time);
+       mem_trim_timer = ecore_timer_add(mem_trim_time, memory_trim_cb, NULL);
+       if (mem_trim_timer == NULL) {
+               _E("Fail to add mem trim timer");
+               free(cur_tm);
+               return -1;
+       }
+       free(cur_tm);
+       return 0;
+}
+
+static DBusMessage *edbus_getstatus(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+       double dAvail = 0.0;
+       double dTotal = 0.0;
+
+       ret = __fs_stat(&dTotal, &dAvail, MEMORY_STATUS_USR_PATH);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT64, &dTotal);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT64, &dAvail);
+       return reply;
+}
+
+static DBusMessage *edbus_memtrim(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = launch_if_noexist(MEM_FSTRIM_PATH, MEMORY_STATUS_USR_PATH);
+       if (ret == -1) {
+               _E("fail to launch fstrim");
+       } else {
+               _D("fs memory trim is operated");
+       }
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "getstorage",       NULL,   "i", edbus_getstatus },
+       { "MemTrim",       NULL,   "i", edbus_memtrim },
+       /* Add methods here */
+};
+
+static int booting_done(void *data)
+{
+       static int done = 0;
+
+       if (data != NULL) {
+               done = (int)data;
+               if (done)
+                       _I("booting done");
+               if (__memnoti_fd_init(NULL) == -1)
+                       _E("fail remain mem noti control fd init");
+       }
+       return done;
+}
+
+static int lowmem_poweroff(void *data)
+{
+       if (memnoti_timer) {
+               ecore_timer_del(memnoti_timer);
+               memnoti_timer = NULL;
+       }
+       if (mem_trim_timer) {
+               ecore_timer_del(mem_trim_timer);
+               mem_trim_timer = NULL;
+       }
+       return 0;
+}
+
+static void lowmem_init(void *data)
+{
+       struct main_data *ad = (struct main_data*)data;
+       int ret;
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+       register_notifier(DEVICE_NOTIFIER_POWEROFF, lowmem_poweroff);
+       ret = register_edbus_method(DEVICED_PATH_STORAGE, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       if (__run_mem_trim() < 0) {
+               _E("fail mem trim timer start");
+       }
+}
+
+static void lowmem_exit(void *data)
+{
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+       unregister_notifier(DEVICE_NOTIFIER_POWEROFF, lowmem_poweroff);
+}
+
+static const struct device_ops lowmem_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "lowmem",
+       .init     = lowmem_init,
+       .exit     = lowmem_exit,
+};
+
+DEVICE_OPS_REGISTER(&lowmem_device_ops)
diff --git a/src/core/main.c b/src/core/main.c
new file mode 100644 (file)
index 0000000..977eb06
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * 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 <fcntl.h>
+#include <sys/reboot.h>
+
+#include "display/core.h"
+#include "log.h"
+#include "data.h"
+#include "edbus-handler.h"
+#include "devices.h"
+#include "shared/dbus.h"
+#include "device-notifier.h"
+
+#define PIDFILE_PATH           "/var/run/.deviced.pid"
+
+static void init_ad(struct main_data *ad)
+{
+       memset(ad, 0x0, sizeof(struct main_data));
+}
+
+static void writepid(char *pidpath)
+{
+       FILE *fp;
+
+       fp = fopen(pidpath, "w");
+       if (fp != NULL) {
+               fprintf(fp, "%d", getpid());
+               fclose(fp);
+       }
+}
+
+static void sig_quit(int signo)
+{
+       _D("received SIGTERM signal %d", signo);
+}
+
+static void sig_usr1(int signo)
+{
+       _D("received SIGUSR1 signal %d, deviced'll be finished!", signo);
+
+       ecore_main_loop_quit();
+}
+
+static void check_systemd_active(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       DBusMessageIter iter, sub;
+       const char *state;
+       char *pa[2];
+
+       pa[0] = "org.freedesktop.systemd1.Unit";
+       pa[1] = "ActiveState";
+
+       _I("%s %s", pa[0], pa[1]);
+
+       msg = dbus_method_sync_with_reply("org.freedesktop.systemd1",
+                       "/org/freedesktop/systemd1/unit/default_2etarget",
+                       "org.freedesktop.DBus.Properties",
+                       "Get", "ss", pa);
+       if (!msg)
+               return;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_iter_init(msg, &iter) ||
+           dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+               goto out;
+
+       dbus_message_iter_recurse(&iter, &sub);
+
+       if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
+               goto out;
+
+       dbus_message_iter_get_basic(&sub, &state);
+
+       if (strncmp(state, "active", 6) == 0) {
+               _I("notify relaunch");
+               device_notify(DEVICE_NOTIFIER_BOOTING_DONE, (void *)TRUE);
+       }
+out:
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+}
+
+static int system_main(int argc, char **argv)
+{
+       struct main_data ad;
+
+       init_ad(&ad);
+       edbus_init(&ad);
+       devices_init(&ad);
+       check_systemd_active();
+       signal(SIGTERM, sig_quit);
+       signal(SIGUSR1, sig_usr1);
+
+       ecore_main_loop_begin();
+
+       devices_exit(&ad);
+       edbus_exit(&ad);
+       ecore_shutdown();
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       writepid(PIDFILE_PATH);
+       ecore_init();
+       return system_main(argc, argv);
+}
diff --git a/src/core/noti.c b/src/core/noti.c
new file mode 100644 (file)
index 0000000..8eda5d6
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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 <heynoti.h>
+#include "log.h"
+#include "data.h"
+#include "devices.h"
+#include "common.h"
+
+static int noti_fd;
+
+int noti_getfd()
+{
+       return noti_fd;
+}
+
+int noti_send(char *filename)
+{
+       return heynoti_publish(filename);
+}
+
+int noti_add(const char *noti, void (*cb) (void *), void *data)
+{
+       if (noti_fd < 0)
+               return -1;
+
+       return heynoti_subscribe(noti_fd, noti, cb, data);
+}
+
+static void noti_init(void *data)
+{
+       struct main_data *ad = (struct main_data*)data;
+
+       if ((ad->noti_fd = heynoti_init()) < 0) {
+               _E("Hey Notification Initialize failed");
+               return;
+       }
+       if (heynoti_attach_handler(ad->noti_fd) != 0) {
+               _E("fail to attach hey noti handler");
+               return;
+       }
+
+       noti_fd = heynoti_init();
+       if (noti_fd < 0) {
+               _E("heynoti_init error");
+               return;
+       }
+
+       if (heynoti_attach_handler(noti_fd) < 0) {
+               _E("heynoti_attach_handler error");
+               return;
+       }
+}
+
+static void noti_exit(void *data)
+{
+       struct main_data *ad = (struct main_data*)data;
+
+       heynoti_close(ad->noti_fd);
+       heynoti_close(noti_fd);
+}
+
+static const struct device_ops noti_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "noti",
+       .init     = noti_init,
+       .exit     = noti_exit,
+};
+
+DEVICE_OPS_REGISTER(&noti_device_ops)
diff --git a/src/core/noti.h b/src/core/noti.h
new file mode 100644 (file)
index 0000000..6895e31
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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 __NOTI_H__
+#define __NOTI_H__
+
+int noti_getfd(void);
+int noti_send(char *filename);
+int noti_add(const char *noti, void (*cb) (void *), void *data);
+int noti_init(void);
+
+#endif /* __NOTI_H__ */
diff --git a/src/core/power-supply.c b/src/core/power-supply.c
new file mode 100644 (file)
index 0000000..e058023
--- /dev/null
@@ -0,0 +1,815 @@
+/*
+ * 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 <stdbool.h>
+#include <vconf.h>
+#include <Ecore.h>
+#include <device-node.h>
+
+#include "devices.h"
+#include "predefine.h"
+#include "device-handler.h"
+#include "device-notifier.h"
+#include "udev.h"
+#include "log.h"
+#include "emulator.h"
+#include "display/poll.h"
+#include "display/setting.h"
+#include "proc/proc-handler.h"
+#include "config-parser.h"
+#include "power-supply.h"
+
+#define BUFF_MAX               255
+#define POPUP_KEY_CONTENT              "_SYSPOPUP_CONTENT_"
+
+#define PREDEF_BATTERY_CF_OPENED       "battery_cf_opened"
+#define SIGNAL_CHARGEERR_RESPONSE      "ChargeErrResponse"
+#define SIGNAL_TEMP_GOOD               "TempGood"
+
+#define ABNORMAL_CHECK_TIMER_INTERVAL  60
+
+#define METHOD_FULL_NOTI_ON            "BatteryFullNotiOn"
+#define METHOD_FULL_NOTI_OFF   "BatteryFullNotiOff"
+#define METHOD_CHARGE_NOTI_ON  "BatteryChargeNotiOn"
+
+#define SIOP_DISABLE   "memory/private/sysman/siop_disable"
+
+#define RETRY_MAX 5
+#define BATTERY_CHECK_TIMER_INTERVAL   (0.5)
+
+#ifdef MICRO_DD
+#define DEVICE_NOTIFIER "/usr/bin/sys_device_noti"
+#define BATT_CHARGE_NOTI "0"
+#define BATT_FULL_NOTI   "2"
+#endif
+struct popup_data {
+       char *name;
+       char *key;
+       char *value;
+};
+
+static Ecore_Timer *power_timer = NULL;
+static Ecore_Timer *abnormal_timer = NULL;
+extern int battery_power_off_act(void *data);
+
+static void pm_check_and_change(int bInserted)
+{
+       static int old = -1;
+       if (old != bInserted) {
+               old = bInserted;
+               predefine_pm_change_state(LCD_NORMAL);
+       }
+}
+
+int check_lowbat_charge_device(int bInserted)
+{
+       static int bChargeDeviceInserted = 0;
+       int val = -1;
+       int bat_state = -1;
+       int ret = -1;
+       char *value;
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+
+       pm_check_and_change(bInserted);
+       if (bInserted == 1) {
+               if (battery.charge_now)
+                       bChargeDeviceInserted = 1;
+               return 0;
+       } else if (bInserted == 0) {
+               if (!battery.charge_now && 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) {
+                                       if (apps == NULL) {
+                                               apps = find_device("apps");
+                                               if (apps == NULL)
+                                                       return 0;
+                                       }
+                                       if(bat_state == VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF)
+                                               value = "poweroff";
+                                       else if (bat_state == VCONFKEY_SYSMAN_BAT_POWER_OFF)
+                                               value = "extreme";
+                                       else
+                                               value = "warning";
+                                       params = malloc(sizeof(struct popup_data));
+                                       if (params == NULL) {
+                                               _E("Malloc failed");
+                                               return -1;
+                                       }
+                                       params->name = "lowbat-syspopup";
+                                       params->key = POPUP_KEY_CONTENT;
+                                       params->value = value;
+                                       _I("%s %s %s(%x)", params->name, params->key, params->value, params);
+                                       if (apps->init)
+                                               apps->init((void *)params);
+                                       free(params);
+                               }
+                       } else {
+                               _E("failed to get vconf key");
+                               return -1;
+                       }
+               }
+               return 0;
+       }
+       return -1;
+}
+
+static int changed_battery_cf(int argc, char **argv)
+{
+       int present_status;
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+
+       if (argc != 1)
+               return -EINVAL;
+       present_status = atoi(argv[0]);
+
+       if (apps == NULL) {
+               apps = find_device("apps");
+               if (apps == NULL)
+                       return 0;
+       }
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return -ENOMEM;
+       }
+       params->name = "lowbat-syspopup";
+       params->key = POPUP_KEY_CONTENT;
+       params->value = "battdisconnect";
+       if (apps->init == NULL || apps->exit == NULL)
+               goto out;
+       if (present_status == PRESENT_ABNORMAL)
+               apps->init((void *)params);
+       else
+               apps->exit((void *)params);
+out:
+       free(params);
+       return 0;
+}
+
+int check_abnormal_popup(void)
+{
+       int ret = HEALTH_BAD;
+
+       if (abnormal_timer)
+               ret =  HEALTH_GOOD;
+       return ret;
+}
+
+static void abnormal_popup_timer_init(void)
+{
+       if (abnormal_timer == NULL)
+               return;
+       ecore_timer_del(abnormal_timer);
+       abnormal_timer = NULL;
+       _I("delete health timer");
+}
+
+static void health_status_broadcast(void)
+{
+       broadcast_edbus_signal(DEVICED_PATH_BATTERY, DEVICED_INTERFACE_BATTERY,
+           SIGNAL_TEMP_GOOD, NULL, NULL);
+}
+
+static int clean_health_popup(void)
+{
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+
+       if (apps == NULL) {
+               apps = find_device("apps");
+               if (apps == NULL)
+                       return 0;
+       }
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return -ENOMEM;
+       }
+       params->name = "lowbat-syspopup";
+       params->key = POPUP_KEY_CONTENT;
+       if (apps->exit)
+               apps->exit((void *)params);
+       health_status_broadcast();
+out:
+       free(params);
+       return 0;
+
+}
+
+static void health_timer_reset(void)
+{
+       abnormal_timer = NULL;
+}
+
+static Eina_Bool health_timer_cb(void *data)
+{
+       health_timer_reset();
+
+       if (battery.health == HEALTH_GOOD)
+               return EINA_FALSE;
+
+       _I("popup - Battery health status is not good");
+       vconf_set_int(SIOP_DISABLE, 1);
+       device_notify(DEVICE_NOTIFIER_BATTERY_HEALTH, (void *)HEALTH_BAD);
+       pm_change_internal(getpid(), LCD_NORMAL);
+       pm_lock_internal(INTERNAL_LOCK_POPUP, LCD_DIM, STAY_CUR_STATE, 0);
+       if (battery.temp == TEMP_LOW)
+               battery_charge_err_low_act(NULL);
+       else if (battery.temp == TEMP_HIGH)
+               battery_charge_err_high_act(NULL);
+       return EINA_FALSE;
+}
+
+static void abnormal_popup_edbus_signal_handler(void *data, DBusMessage *msg)
+{
+       if (battery.health == HEALTH_GOOD)
+               return;
+       _I("restart health timer");
+       abnormal_timer = ecore_timer_add(ABNORMAL_CHECK_TIMER_INTERVAL,
+                                               health_timer_cb, NULL);
+       if (abnormal_timer == NULL)
+               _E("Fail to add abnormal check timer");
+}
+
+static int noti_id;
+
+static void full_noti_cb(void *data, DBusMessage *msg, DBusError *err)
+{
+       DBusError r_err;
+       int ret, id;
+
+       if (!msg)
+               return;
+
+       dbus_error_init(&r_err);
+       ret = dbus_message_get_args(msg, &r_err, DBUS_TYPE_INT32, &id, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message [%s:%s]", r_err.name, r_err.message);
+               dbus_error_free(&r_err);
+               return;
+       }
+
+       noti_id = id;
+       _D("Inserted battery full noti : %d", noti_id);
+}
+
+static int send_full_noti(enum charge_full_type state)
+{
+       int ret = 0;
+#ifdef MICRO_DD
+       char params[BUFF_MAX];
+       snprintf(params, sizeof(params), "%s %d", BATT_FULL_NOTI, state);
+       launch_evenif_exist(DEVICE_NOTIFIER, params);
+#else
+       int retry;
+       char str_id[32];
+       char *arr[1];
+
+       switch (state) {
+       case CHARGING_FULL:
+               for (retry = RETRY_MAX; retry > 0 ;retry--) {
+                       ret = dbus_method_async_with_reply(POPUP_BUS_NAME,
+                                       POPUP_PATH_BATTERY,
+                                       POPUP_INTERFACE_BATTERY,
+                                       METHOD_FULL_NOTI_ON,
+                                       NULL, NULL, full_noti_cb, -1, NULL);
+                       if (ret == 0) {
+                               _D("Created battery full noti");
+                               return ret;
+                       }
+               }
+               _E("Failed to call dbus method (err: %d)", ret);
+       break;
+       case CHARGING_NOT_FULL:
+               if (noti_id <= 0)
+                       return -EPERM;
+               snprintf(str_id, sizeof(str_id), "%d", noti_id);
+               arr[0] = str_id;
+               for (retry = RETRY_MAX; retry > 0 ;retry--) {
+                       ret = dbus_method_async(POPUP_BUS_NAME,
+                                       POPUP_PATH_BATTERY,
+                                       POPUP_INTERFACE_BATTERY,
+                                       METHOD_FULL_NOTI_OFF,
+                                       "i", arr);
+                       if (ret == 0) {
+                               _D("Deleted battery full noti");
+                               noti_id = 0;
+                               return ret;
+                       }
+               }
+               _E("Failed to call dbus method (err: %d)", ret);
+       break;
+       }
+#endif
+       return ret;
+}
+
+int send_charge_noti(void)
+{
+       int ret = 0;
+#ifdef MICRO_DD
+       launch_evenif_exist(DEVICE_NOTIFIER, BATT_CHARGE_NOTI);
+#else
+       int retry;
+
+       for (retry = RETRY_MAX; retry > 0 ;retry--) {
+               ret = dbus_method_async(POPUP_BUS_NAME,
+                               POPUP_PATH_BATTERY,
+                               POPUP_INTERFACE_BATTERY,
+                               METHOD_CHARGE_NOTI_ON,
+                               NULL, NULL);
+               if (ret == 0) {
+                       _D("Created battery charge noti");
+                       return ret;
+               }
+       }
+       _E("Failed to call dbus method (err: %d)", ret);
+#endif
+       return ret;
+}
+
+void battery_noti(enum battery_noti_type type, enum battery_noti_status status)
+{
+       static int charge = CHARGER_DISCHARGING;
+       static int full = CHARGING_NOT_FULL;
+       int ret, i;
+
+       if (type == DEVICE_NOTI_BATT_FULL && status == DEVICE_NOTI_ON &&
+           full == CHARGING_NOT_FULL) {
+               ret = send_full_noti(CHARGING_FULL);
+               if (ret == 0)
+                       full = CHARGING_FULL;
+       } else if (type == DEVICE_NOTI_BATT_FULL && status == DEVICE_NOTI_OFF &&
+           full == CHARGING_FULL) {
+               ret = send_full_noti(CHARGING_NOT_FULL);
+               if (ret == 0)
+                       full = CHARGING_NOT_FULL;
+       } else if (type == DEVICE_NOTI_BATT_CHARGE &&
+           battery.charge_now == CHARGER_CHARGING &&
+           charge == CHARGER_DISCHARGING) {
+               if (full == CHARGING_FULL) {
+                       ret = send_full_noti(CHARGING_NOT_FULL);
+                       if (ret == 0)
+                               full = CHARGING_NOT_FULL;
+               }
+               send_charge_noti();
+       }
+       charge = battery.charge_now;
+}
+
+static void noti_batt_full(void)
+{
+       char params[BUFF_MAX];
+       static int bat_full_noti = 0;
+
+       if (!battery.charge_full && bat_full_noti == 1) {
+               battery_noti(DEVICE_NOTI_BATT_FULL, DEVICE_NOTI_OFF);
+               bat_full_noti = 0;
+               /* off the full charge state */
+               device_notify(DEVICE_NOTIFIER_FULLBAT, (void*)false);
+       }
+       if (battery.charge_full && bat_full_noti == 0) {
+               battery_noti(DEVICE_NOTI_BATT_FULL, DEVICE_NOTI_ON);
+               bat_full_noti = 1;
+               /* turn on LCD, if battery is full charged */
+               pm_change_internal(getpid(), LCD_NORMAL);
+               /* on the full charge state */
+               device_notify(DEVICE_NOTIFIER_FULLBAT, (void*)true);
+       }
+}
+
+static void check_power_supply(int state)
+{
+       int ret = -1;
+       int val = 0;
+       char params[BUFF_MAX];
+
+       check_lowbat_charge_device(state);
+       if (update_pm_setting)
+               update_pm_setting(SETTING_CHARGING, state);
+
+       ret = device_get_property(DEVICE_TYPE_POWER,
+               PROP_POWER_INSUSPEND_CHARGING_SUPPORT, &val);
+
+       if (ret != 0 || val == 1) {
+               _D("fail to check charger insuspend");
+               goto out;
+       }
+
+       if (state == 0)
+               pm_unlock_internal(INTERNAL_LOCK_TA, LCD_OFF, STAY_CUR_STATE);
+       else
+               pm_lock_internal(INTERNAL_LOCK_TA, LCD_OFF, STAY_CUR_STATE, 0);
+out:
+       _I("ta device %d", state);
+
+       sync_cradle_status();
+}
+
+static void update_present(enum battery_noti_status status)
+{
+       static int old = DEVICE_NOTI_OFF;
+       char params[BUFF_MAX];
+
+       if (old == status)
+               return;
+       _I("charge %d present %d", battery.charge_now, battery.present);
+       old = status;
+       pm_change_internal(getpid(), LCD_NORMAL);
+       if (status == DEVICE_NOTI_ON)
+               snprintf(params, sizeof(params), "%d", PRESENT_ABNORMAL);
+       else
+               snprintf(params, sizeof(params), "%d", PRESENT_NORMAL);
+       notify_action(PREDEF_BATTERY_CF_OPENED, 1, params);
+}
+
+static void update_health(enum battery_noti_status status)
+{
+       static int old = DEVICE_NOTI_OFF;
+
+       if (old == status)
+               return;
+       _I("charge %d health %d", battery.charge_now, battery.health);
+       old = status;
+       pm_change_internal(getpid(), LCD_NORMAL);
+       if (status == DEVICE_NOTI_ON) {
+               _I("popup - Battery health status is not good");
+               vconf_set_int(SIOP_DISABLE, 1);
+               device_notify(DEVICE_NOTIFIER_BATTERY_HEALTH, (void *)HEALTH_BAD);
+               pm_lock_internal(INTERNAL_LOCK_POPUP, LCD_DIM, STAY_CUR_STATE, 0);
+               if (battery.temp == TEMP_LOW)
+                       battery_charge_err_low_act(NULL);
+               else if (battery.temp == TEMP_HIGH)
+                       battery_charge_err_high_act(NULL);
+       } else {
+               vconf_set_int(SIOP_DISABLE, 0);
+               device_notify(DEVICE_NOTIFIER_BATTERY_HEALTH, (void *)HEALTH_GOOD);
+               pm_unlock_internal(INTERNAL_LOCK_POPUP, LCD_DIM, PM_SLEEP_MARGIN);
+               clean_health_popup();
+               abnormal_popup_timer_init();
+       }
+}
+
+static void update_ovp(enum battery_noti_status status)
+{
+       static int old = DEVICE_NOTI_OFF;
+
+       if (old == status)
+               return;
+       _I("charge %d ovp %d", battery.charge_now, battery.ovp);
+       old = status;
+       pm_change_internal(getpid(), LCD_NORMAL);
+       if (status == DEVICE_NOTI_ON)
+               device_notify(DEVICE_NOTIFIER_BATTERY_OVP, (void *)OVP_ABNORMAL);
+       else
+               device_notify(DEVICE_NOTIFIER_BATTERY_OVP, (void *)OVP_NORMAL);
+}
+
+static void check_battery_status(void)
+{
+       static int old = DEVICE_CHANGE_NORMAL;
+       int status;
+
+       if (battery.charge_now == CHARGER_ABNORMAL &&
+           (battery.health == HEALTH_BAD || battery.present == PRESENT_ABNORMAL))
+               status = DEVICE_CHANGE_ABNORMAL;
+       else if (battery.ovp == OVP_ABNORMAL)
+               status = DEVICE_CHANGE_ABNORMAL;
+       else
+               status = DEVICE_CHANGE_NORMAL;
+       if (old == status)
+               return;
+       old = status;
+
+       if (battery.charge_now == CHARGER_ABNORMAL) {
+               if (battery.health == HEALTH_BAD) {
+                       update_health(DEVICE_NOTI_ON);
+                       return;
+               } else if (battery.present == PRESENT_ABNORMAL) {
+                       update_present(DEVICE_NOTI_ON);
+                       return;
+               }
+       }
+       if (battery.ovp == OVP_ABNORMAL) {
+               update_ovp(DEVICE_NOTI_ON);
+               return;
+       }
+
+       if (battery.charge_now != CHARGER_ABNORMAL &&
+           status == DEVICE_CHANGE_NORMAL) {
+               update_health(DEVICE_NOTI_OFF);
+               update_ovp(DEVICE_NOTI_OFF);
+               update_present(DEVICE_NOTI_OFF);
+       }
+}
+
+static void check_online(void)
+{
+       static int old_online;
+
+       if (battery.online > POWER_SUPPLY_TYPE_BATTERY &&
+           old_online == VCONFKEY_SYSMAN_CHARGER_DISCONNECTED) {
+               old_online = VCONFKEY_SYSMAN_CHARGER_CONNECTED;
+               vconf_set_int(VCONFKEY_SYSMAN_CHARGER_STATUS, old_online);
+               power_supply_broadcast(CHARGER_STATUS_SIGNAL, old_online);
+               extcon_set_count(EXTCON_TA);
+               check_power_supply(old_online);
+       } else if (battery.online <= POWER_SUPPLY_TYPE_BATTERY &&
+           old_online == VCONFKEY_SYSMAN_CHARGER_CONNECTED) {
+               old_online = VCONFKEY_SYSMAN_CHARGER_DISCONNECTED;
+               vconf_set_int(VCONFKEY_SYSMAN_CHARGER_STATUS, old_online);
+               power_supply_broadcast(CHARGER_STATUS_SIGNAL, old_online);
+               check_power_supply(old_online);
+       }
+}
+
+static void charge_cb(struct main_data *ad)
+{
+       int val = -1;
+       int ret;
+       static int present_status = PRESENT_NORMAL;
+
+       lowbat_monitor(NULL);
+
+       if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_NOW, &battery.charge_now) != 0 ||
+           device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CAPACITY, &battery.capacity) != 0)
+               _E("fail to get battery node value");
+
+       if (battery.charge_now > 0)
+               battery.charge_now = CHARGER_CHARGING;
+       else
+               battery.charge_now = CHARGER_DISCHARGING;
+
+       if (battery.charge_now != CHARGER_CHARGING && battery.capacity == 0) {
+               _I("target will be shut down");
+               battery_power_off_act(NULL);
+               return;
+       }
+
+       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_PRESENT, &val);
+       if (ret != 0) {
+               battery.present = PRESENT_NORMAL;
+               _E("fail to get battery present value");
+               goto check_health;
+       }
+check_health:
+       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_HEALTH, &val);
+       if (ret != 0) {
+               battery.health = HEALTH_GOOD;
+               battery.ovp = OVP_NORMAL;
+               _E("failed to get battery health status");
+               goto check_full;
+       }
+       if (val != BATTERY_GOOD)
+               _I("Battery health status is not good (%d)", val);
+       if (val == BATTERY_OVERHEAT) {
+               battery.health = HEALTH_BAD;
+               battery.charge_now = CHARGER_ABNORMAL;
+               battery.temp = TEMP_HIGH;
+       } else if (val == BATTERY_COLD) {
+               battery.health = HEALTH_BAD;
+               battery.charge_now = CHARGER_ABNORMAL;
+               battery.temp = TEMP_LOW;
+       } else {
+               battery.health = HEALTH_GOOD;
+       }
+check_full:
+       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_FULL, &val);
+       if (ret == 0)
+               battery.charge_full = val;
+       noti_batt_full();
+       check_battery_status();
+       device_notify(DEVICE_NOTIFIER_BATTERY_CHARGING, (void*)battery.charge_now);
+}
+
+static int load_uevent(struct parse_result *result, void *user_data)
+{
+       struct battery_status *info = user_data;
+
+       if (!info)
+               return -EINVAL;
+
+       if (MATCH(result->name, CHARGE_STATUS)) {
+               if (strstr(result->value, "Charging")) {
+                       info->charge_now = CHARGER_CHARGING;
+                       info->charge_full = CHARGING_NOT_FULL;
+               } else if (strstr(result->value, "Discharging")) {
+                       info->charge_now = CHARGER_DISCHARGING;
+                       info->charge_full = CHARGING_NOT_FULL;
+               } else if (strstr(result->value, "Full")) {
+                       info->charge_now = CHARGER_DISCHARGING;
+                       info->charge_full = CHARGING_FULL;
+               } else if (strstr(result->value, "Not charging")) {
+                       info->charge_now = CHARGER_ABNORMAL;
+                       info->charge_full = CHARGING_NOT_FULL;
+               }
+       }
+       else if (MATCH(result->name, CAPACITY))
+               info->capacity = atoi(result->value);
+       return 0;
+}
+
+static void power_load_uevent(void)
+{
+       int ret;
+       ret = config_parse(POWER_SUPPLY_UEVENT, load_uevent, &battery);
+       if (ret < 0)
+               _E("Failed to load %s, %d Use default value!", POWER_SUPPLY_UEVENT, ret);
+}
+
+void power_supply(void *data)
+{
+       int ret;
+
+       static int old_charge;
+
+       if (old_charge != battery.charge_now || battery.charge_now == CHARGER_ABNORMAL) {
+               old_charge = battery.charge_now;
+               vconf_set_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, old_charge);
+               power_supply_broadcast(CHARGE_NOW_SIGNAL, old_charge);
+       }
+
+       lowbat_monitor(data);
+       check_online();
+       noti_batt_full();
+       check_battery_status();
+       device_notify(DEVICE_NOTIFIER_POWER_SUPPLY, NULL);
+       device_notify(DEVICE_NOTIFIER_BATTERY_CHARGING, (void*)battery.charge_now);
+}
+
+void power_supply_status_init(void)
+{
+       int ret, val;
+       static int charge_now = -1;
+       static int charge_full = -1;
+       static int capacity = -1;
+
+       power_load_uevent();
+       battery.health = HEALTH_GOOD;
+       battery.ovp = OVP_NORMAL;
+       battery.present = PRESENT_NORMAL;
+       battery.temp = TEMP_LOW;
+
+       if (charge_now == battery.charge_now &&
+           charge_full == battery.charge_full &&
+           capacity == battery.capacity)
+               return;
+
+       if (charge_now != battery.charge_now ||
+           charge_full != battery.charge_full ||
+           capacity != battery.capacity)
+               _I("charging %d full %d capacity %d", battery.charge_now, battery.charge_full, battery.capacity);
+
+       if (charge_now != battery.charge_now) {
+               vconf_set_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, battery.charge_now);
+               power_supply_broadcast(CHARGE_NOW_SIGNAL, battery.charge_now);
+       }
+       if (capacity != battery.capacity)
+               vconf_set_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, battery.capacity);
+
+       charge_now = battery.charge_now;
+       charge_full = battery.charge_full;
+       capacity =  battery.capacity;
+}
+
+static Eina_Bool power_supply_update(void *data)
+{
+       power_supply_status_init();
+       return EINA_TRUE;
+}
+
+void power_supply_timer_start(void)
+{
+       _D("battery init timer during booting");
+       power_timer = ecore_timer_add(BATTERY_CHECK_TIMER_INTERVAL,
+                               power_supply_update, NULL);
+       if (power_timer == NULL)
+           _E("fail to add battery init timer during booting");
+}
+
+void power_supply_timer_stop(void)
+{
+    _D("battery init timer during booting");
+       if (!power_timer)
+               return;
+       ecore_timer_del(power_timer);
+       power_timer = NULL;
+}
+
+void power_supply_broadcast(char *sig, int status)
+{
+       static int old = 0;
+       static char sig_old[32];
+       char *arr[1];
+       char str_status[32];
+
+       if (strcmp(sig_old, sig) == 0 && old == status)
+               return;
+
+       _D("%s %d", sig, status);
+
+       old = status;
+       snprintf(sig_old, sizeof(sig_old), "%s", sig);
+       snprintf(str_status, sizeof(str_status), "%d", status);
+       arr[0] = str_status;
+
+       broadcast_edbus_signal(DEVICED_PATH_BATTERY, DEVICED_INTERFACE_BATTERY,
+                       sig, "i", arr);
+}
+
+static DBusMessage *dbus_get_charger_status(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &ret) < 0) {
+               _E("vconf_get_int() failed");
+               ret = -EIO;
+       }
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_get_charge_now(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = battery.charge_now;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_get_charge_level(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &ret) < 0) {
+               _E("vconf_get_int() failed");
+               ret = -EIO;
+       }
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { CHARGER_STATUS_SIGNAL, NULL, "i", dbus_get_charger_status },
+       { CHARGE_NOW_SIGNAL,     NULL, "i", dbus_get_charge_now },
+       { CHARGE_LEVEL_SIGNAL,   NULL, "i", dbus_get_charge_level },
+};
+
+int power_supply_init(void *data)
+{
+       int ret;
+       ret = register_edbus_method(DEVICED_PATH_BATTERY, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+       ret = register_edbus_signal_handler(DEVICED_PATH_SYSNOTI,
+                       DEVICED_INTERFACE_SYSNOTI, SIGNAL_CHARGEERR_RESPONSE,
+                       abnormal_popup_edbus_signal_handler);
+       if (ret < 0)
+               _E("fail to init edbus signal(%d)", ret);
+
+       register_action(PREDEF_BATTERY_CF_OPENED, changed_battery_cf,
+               NULL, NULL);
+
+       /* for simple noti change cb */
+       emulator_add_callback("device_charge_chgdet", (void *)charge_cb, data);
+       power_supply_status_init();
+       power_supply(NULL);
+       return ret;
+}
diff --git a/src/core/power-supply.h b/src/core/power-supply.h
new file mode 100644 (file)
index 0000000..3dd2f94
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef __POWER_SUPPLY_H__
+#define __POWER_SUPPLY_H__
+
+#define CHARGER_STATUS_SIGNAL "ChargerStatus"
+#define CHARGE_NOW_SIGNAL     "ChargeNow"
+#define CHARGE_LEVEL_SIGNAL   "BatteryStatusLow"
+
+int check_abnormal_popup(void);
+int check_lowbat_charge_device(int bInserted);
+void power_supply(void *data);
+int power_supply_init(void *data);
+void power_supply_status_init(void);
+void power_supply_timer_start(void);
+void power_supply_timer_stop(void);
+void power_supply_broadcast(char *sig, int status);
+#endif /* __POWER_SUPPLY_H__ */
diff --git a/src/core/predefine.c b/src/core/predefine.c
new file mode 100755 (executable)
index 0000000..3b6c515
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * 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 <unistd.h>
+#include <time.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <vconf.h>
+
+#include <sys/reboot.h>
+#include <sys/time.h>
+#include <mntent.h>
+#include <sys/mount.h>
+#include "dd-deviced.h"
+#include "log.h"
+#include "launch.h"
+#include "queue.h"
+#include "device-handler.h"
+#include "device-node.h"
+#include "predefine.h"
+#include "proc/proc-handler.h"
+#include "data.h"
+#include "common.h"
+#include "display/poll.h"
+#include "display/setting.h"
+#include "devices.h"
+#include "battery/battery.h"
+#include "edbus-handler.h"
+
+#define VCONFKEY_SYSMAN_FACTORY_MODE                   "memory/sysman/factory_mode"
+
+#define PREDEFINE_SO_DIR               PREFIX"/lib/ss_predefine/"
+#define PREDEF_CALL                    "call"
+#define PREDEF_FACTORY_MODE            "factorymode"
+
+#define CALL_EXEC_PATH                 PREFIX"/bin/call"
+
+#define LOWBAT_EXEC_PATH               PREFIX"/bin/lowbatt-popup"
+
+#define HDMI_NOTI_EXEC_PATH            PREFIX"/bin/hdmi_connection_noti"
+
+
+static int bFactoryMode = 0;
+
+int predefine_get_pid(const char *execpath)
+{
+       DIR *dp;
+       struct dirent *dentry;
+       int pid = -1, fd;
+       int ret;
+       char buf[PATH_MAX];
+       char buf2[PATH_MAX];
+
+       dp = opendir("/proc");
+       if (!dp) {
+               _E("FAIL: 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;
+               ret = read(fd, buf2, PATH_MAX);
+               close(fd);
+
+               if (ret < 0 || ret >=PATH_MAX)
+                       continue;
+
+               buf2[ret] = '\0';
+
+               if (!strcmp(buf2, execpath)) {
+                       closedir(dp);
+                       return pid;
+               }
+       }
+
+       errno = ESRCH;
+       closedir(dp);
+       return -1;
+}
+
+#ifdef NOUSE
+int call_predefine_action(int argc, char **argv)
+{
+       char argstr[128];
+       int pid;
+
+       if (argc < 2)
+               return -1;
+
+       snprintf(argstr, sizeof(argstr), "-t MT -n %s -i %s", argv[0], argv[1]);
+       pid = launch_if_noexist(CALL_EXEC_PATH, argstr);
+       if (pid < 0) {
+               _E("call predefine action failed");
+               return -1;
+       }
+       return pid;
+}
+#endif
+
+void predefine_pm_change_state(unsigned int s_bits)
+{
+       if (is_factory_mode() == 1)
+               _D("skip LCD control for factory mode");
+       else
+               pm_change_internal(getpid(), s_bits);
+}
+
+int is_factory_mode(void)
+{
+       return bFactoryMode;
+}
+int set_factory_mode(int bOn)
+{
+       int ret = -1;
+       if ( bOn==1 || bOn==0 ) {
+               bFactoryMode = bOn;
+               /* For USB-server to refer the value */
+               ret = vconf_set_int(VCONFKEY_SYSMAN_FACTORY_MODE, bOn);
+               if(ret != 0) {
+                       _E("FAIL: vconf_set_int()");
+               }
+       }
+       return bFactoryMode;
+}
+
+int factory_mode_action(int argc, char **argv)
+{
+       int bOn;
+       if (argc != 1 || argv[0] == NULL) {
+               _E("Factory Mode Set predefine action failed");
+               return -1;
+       }
+       bOn = atoi(argv[0]);
+       bOn = set_factory_mode(bOn);
+       return 0;
+
+}
+
+static void 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) {
+               _E("fail open %s", PREDEFINE_SO_DIR);
+               return;
+       }
+
+       msg = malloc(sizeof(struct sysnoti));
+       if (msg == NULL) {
+               _E("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]);
+               register_msg(msg);
+       }
+       free(msg);
+
+       closedir(dp);
+}
+
+static DBusMessage *dbus_factory_mode(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+       char *argv;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       ret = set_factory_mode(atoi(argv));
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { PREDEF_FACTORY_MODE, "sis", "i", dbus_factory_mode },
+};
+
+static void predefine_init(void *data)
+{
+       /* telephony initialize */
+       int ret;
+
+       ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+#ifdef NOUSE
+       register_action(PREDEF_CALL, call_predefine_action, NULL, NULL);
+#endif
+       register_action(PREDEF_FACTORY_MODE, factory_mode_action, NULL, NULL);
+
+       action_entry_load_from_sodir();
+}
+
+static const struct device_ops predefine_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "predefine",
+       .init     = predefine_init,
+};
+
+DEVICE_OPS_REGISTER(&predefine_device_ops)
diff --git a/src/core/predefine.h b/src/core/predefine.h
new file mode 100644 (file)
index 0000000..a20aaf5
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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 __PREDEFINE_H__
+#define __PREDEFINE_H__
+
+int call_predefine_action(int argc, char **argv);
+int is_factory_mode(void);
+void predefine_pm_change_state(unsigned int s_bits);
+int predefine_get_pid(const char *execpath);
+#endif /* __PREDEFINE_H__ */
diff --git a/src/core/queue.c b/src/core/queue.c
new file mode 100644 (file)
index 0000000..d0da9b2
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * 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 <dlfcn.h>
+#include "data.h"
+#include "core.h"
+#include "queue.h"
+#include "log.h"
+#include "list.h"
+
+#define PREDEFINE_ACT_FUNC_STR         "predefine_action"
+#define IS_ACCESSIBLE_FUNC_STR         "is_accessible"
+#define UI_VIEWABLE_FUNC_STR                   "ui_viewable"
+
+static dd_list *predef_act_list;
+static dd_list *run_queue;
+
+static struct action_entry *find_action_entry(char *type)
+{
+       dd_list *tmp;
+       struct action_entry *data;
+
+       DD_LIST_FOREACH(predef_act_list, tmp, data) {
+               if (!strcmp(data->type, type))
+                       return data;
+       }
+
+       return NULL;
+}
+
+int register_action(char *type,
+                                int (*predefine_action) (),
+                                int (*ui_viewable) (),
+                                int (*is_accessible) (int))
+{
+       struct action_entry *data;
+
+       data = malloc(sizeof(struct action_entry));
+
+       if (data == NULL) {
+               _E("Malloc failed");
+               return -1;
+       }
+
+       data->type = NULL;
+       if (find_action_entry(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("");
+
+       DD_LIST_PREPEND(predef_act_list, data);
+
+       _D("add predefine action entry suceessfully - %s",
+                 data->type);
+       return 0;
+ err:
+       if (data->type != NULL)
+               _E("adding predefine action entry failed - %s",
+                             data->type);
+       free(data);
+       return -1;
+}
+
+int register_msg(struct sysnoti *msg)
+{
+       struct action_entry *data;
+
+       data = malloc(sizeof(struct action_entry));
+
+       if (data == NULL) {
+               _E("Malloc failed");
+               return -1;
+       }
+
+       if (find_action_entry(msg->type) != NULL)
+               goto err;
+
+       data->handle = dlopen(msg->path, RTLD_LAZY);
+       if (!data->handle) {
+               _E("cannot find such library");
+               goto err;
+       }
+
+       data->predefine_action = dlsym(data->handle, PREDEFINE_ACT_FUNC_STR);
+       if (data->predefine_action == NULL) {
+               _E("cannot find predefine_action symbol : %s",
+                             PREDEFINE_ACT_FUNC_STR);
+               goto err;
+       }
+
+       data->is_accessible = dlsym(data->handle, IS_ACCESSIBLE_FUNC_STR);
+       data->ui_viewable = dlsym(data->handle, UI_VIEWABLE_FUNC_STR);
+       data->owner_pid = msg->pid;
+       data->type = strdup(msg->type);
+       data->path = strdup(msg->path);
+
+       DD_LIST_PREPEND(predef_act_list, data);
+
+       _D("add predefine action entry suceessfully - %s",
+                 data->type);
+       return 0;
+ err:
+       _E("adding predefine action entry failed - %s", msg->type);
+       free(data);
+       return -1;
+}
+
+int notify_action(char *type, int argc, ...)
+{
+       dd_list *tmp;
+       struct action_entry *data;
+       va_list argptr;
+       int i;
+       int ret;
+       char *args = NULL;
+       char *argv[SYSMAN_MAXARG];
+
+       if (argc > SYSMAN_MAXARG || type == NULL)
+               return -1;
+
+       DD_LIST_FOREACH(predef_act_list, tmp, data) {
+               if (strcmp(data->type, type))
+                       continue;
+               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);
+               ret=run_queue_add(data, argc, argv);
+               ret=core_action_run();
+               return 0;
+       }
+
+       return 0;
+}
+
+int notify_msg(struct sysnoti *msg, int sockfd)
+{
+       dd_list *tmp;
+       struct action_entry *data;
+       int ret;
+
+       DD_LIST_FOREACH(predef_act_list, tmp, data) {
+               if (strcmp(data->type, msg->type))
+                       continue;
+               if (data->is_accessible != NULL
+                   && data->is_accessible(sockfd) == 0) {
+                       _E("%d cannot call that predefine module", msg->pid);
+                       return -1;
+               }
+               ret=run_queue_add(data, msg->argc, msg->argv);
+               ret=core_action_run();
+               return 0;
+       }
+
+       _E("cannot found action");
+       return -1;
+}
+
+int run_queue_add(struct action_entry *act_entry, int argc, char **argv)
+{
+       struct run_queue_entry *rq_entry;
+       int i;
+
+       rq_entry = malloc(sizeof(struct run_queue_entry));
+
+       if (rq_entry == NULL) {
+               _E("Malloc failed");
+               return -1;
+       }
+
+       rq_entry->state = 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];
+       }
+
+       DD_LIST_PREPEND(run_queue, rq_entry);
+
+       return 0;
+}
+
+int run_queue_run(enum run_state state,
+                    int (*run_func) (void *, struct run_queue_entry *),
+                    void *user_data)
+{
+       dd_list *tmp;
+       struct run_queue_entry *rq_entry;
+
+       DD_LIST_FOREACH(run_queue, tmp, rq_entry) {
+               if (rq_entry->state == state)
+                       run_func(user_data, rq_entry);
+       }
+
+       return 0;
+}
+
+struct run_queue_entry *run_queue_find_bypid(int pid)
+{
+       dd_list *tmp;
+       struct run_queue_entry *rq_entry;
+
+       DD_LIST_FOREACH(run_queue, tmp, rq_entry) {
+               if (rq_entry->forked_pid == pid)
+                       return rq_entry;
+       }
+
+       return NULL;
+}
+
+int run_queue_del(struct run_queue_entry *entry)
+{
+       dd_list *tmp;
+       struct run_queue_entry *rq_entry;
+       int i;
+
+       DD_LIST_FOREACH(run_queue, tmp, rq_entry) {
+               if (rq_entry == entry) {
+                       DD_LIST_REMOVE(run_queue, rq_entry);
+                       for (i = 0; i < rq_entry->argc; i++) {
+                               if (rq_entry->argv[i])
+                                       free(rq_entry->argv[i]);
+                       }
+                       free(rq_entry);
+               }
+       }
+
+       return 0;
+}
+
+int run_queue_del_bypid(int pid)
+{
+       dd_list *tmp;
+       struct run_queue_entry *rq_entry;
+       int i;
+
+       DD_LIST_FOREACH(run_queue, tmp, rq_entry) {
+               if (rq_entry->forked_pid == pid) {
+                       DD_LIST_REMOVE(run_queue, rq_entry);
+                       for (i = 0; i < rq_entry->argc; i++) {
+                               if (rq_entry->argv[i])
+                                       free(rq_entry->argv[i]);
+                       }
+                       free(rq_entry);
+               }
+       }
+
+       return 0;
+}
diff --git a/src/core/queue.h b/src/core/queue.h
new file mode 100644 (file)
index 0000000..dee1e7e
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * 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 __QUEUE_H__
+#define __QUEUE_H__
+
+#include "sysnoti.h"
+
+struct action_entry {
+       int owner_pid;
+       void *handle;
+       char *type;
+       char *path;
+       int (*predefine_action) ();
+       int (*ui_viewable) ();
+       int (*is_accessible) (int caller_sockfd);
+};
+
+enum run_state {
+       STATE_INIT,
+       STATE_RUNNING,
+       STATE_DONE
+};
+
+struct run_queue_entry {
+       enum run_state state;
+       struct action_entry *action_entry;
+       int forked_pid;
+       int argc;
+       char *argv[SYSMAN_MAXARG];
+};
+
+int register_action(char *type,
+                                int (*predefine_action) (),
+                                int (*ui_viewable) (),
+                                int (*is_accessible) (int));
+int notify_action(char *type, int argc, ...);
+
+int register_msg(struct sysnoti *msg);
+int notify_msg(struct sysnoti *msg, int sockfd);
+
+int run_queue_run(enum run_state state,
+                    int (*run_func) (void *, struct run_queue_entry *),
+                    void *user_data);
+
+struct run_queue_entry *run_queue_find_bypid(int pid);
+int run_queue_add(struct action_entry *act_entry, int argc, char **argv);
+int run_queue_del(struct run_queue_entry *entry);
+int run_queue_del_bypid(int pid);
+
+#endif /* __QUEUE_H__ */
diff --git a/src/core/sig-handler.c b/src/core/sig-handler.c
new file mode 100644 (file)
index 0000000..89deee8
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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 <sys/types.h>
+#include <sys/wait.h>
+#include <vconf.h>
+#include "core.h"
+#include "log.h"
+#include "edbus-handler.h"
+#include "display/poll.h"
+#include "devices.h"
+#include "common.h"
+
+#if 0
+#define _E(format, args...) do { \
+       char buf[255];\
+       snprintf(buf, 255, format, ##args);\
+       write(2, buf, strlen(buf));\
+} while (0);
+
+#define _D(format, args...) do { \
+       char buf[255];\
+       snprintf(buf, 255, format, ##args);\
+       write(1, buf, strlen(buf));\
+} while (0);
+#endif
+
+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;
+
+       if (!info || signo != SIGCHLD)
+               return;
+
+       pid = waitpid(info->si_pid, &status, 0);
+       if (pid == -1) {
+               _E("SIGCHLD received\n");
+               return;
+       }
+
+       _D("sig child actend call - %d\n", info->si_pid);
+}
+
+static void sig_pipe_handler(int signo, siginfo_t *info, void *data)
+{
+
+}
+
+static void signal_init(void *data)
+{
+       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);
+}
+
+static const struct device_ops signal_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "signal",
+       .init     = signal_init,
+};
+
+DEVICE_OPS_REGISTER(&signal_device_ops)
diff --git a/src/core/sysnoti.c b/src/core/sysnoti.c
new file mode 100755 (executable)
index 0000000..7fe6b2f
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * 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 <limits.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include "data.h"
+#include "log.h"
+#include "queue.h"
+#include "common.h"
+#include "devices.h"
+
+#define SYSNOTI_SOCKET_PATH "/tmp/sn"
+#define RETRY_READ_COUNT       5
+enum sysnoti_cmd {
+       REGISTER_MSG,
+       NOTIFY_MSG
+};
+
+static Ecore_Fd_Handler *sysnoti_efd = NULL;
+static int sysnoti_fd;
+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 (get_cmdline_name(msg->pid, exe_name, PATH_MAX) < 0)
+               snprintf(exe_name, sizeof(exe_name), "Unknown (maybe dead)");
+
+       _SD("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) {
+                               _D("Re-read for error(EINTR)");
+                               retry_count++;
+                               continue;
+                       }
+                       else {
+                               _E("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) {
+                               _D("Re-read for error(EINTR)");
+                               retry_count++;
+                               continue;
+                       }
+                       else {
+                               _E("Read fail for str length");
+                               return NULL;
+                       }
+               } else
+                       break;
+       }
+       if (retry_count == RETRY_READ_COUNT) {
+               _E("Read retry failed");
+               return NULL;
+       }
+       if (len <= 0)
+               return NULL;
+
+       if (len >= INT_MAX) {
+               _E("size is over INT_MAX");
+               return NULL;
+       }
+
+       str = (char *)malloc(len + 1);
+       if (str == NULL) {
+               _E("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) {
+                               _D("Re-read for error(EINTR)");
+                               retry_count++;
+                               continue;
+                       } else {
+                               _E("Read fail for str");
+                               free(str);
+                               str = NULL;
+                               return NULL;
+                       }
+               } else
+                       break;
+       }
+       if (retry_count == RETRY_READ_COUNT) {
+               _E("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 Eina_Bool sysnoti_cb(void *data, Ecore_Fd_Handler * fd_handler)
+{
+       struct sysnoti *msg;
+       int ret = -1;
+       struct sockaddr_un client_address;
+       int client_sockfd;
+       int client_len;
+
+       if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
+               _E("ecore_main_fd_handler_active_get error , return");
+               goto out;
+       }
+
+       msg = malloc(sizeof(struct sysnoti));
+       if (msg == NULL) {
+               _E("Not enough memory");
+               goto out;
+       }
+
+       client_len = sizeof(client_address);
+       client_sockfd = accept(sysnoti_fd, (struct sockaddr *)&client_address, (socklen_t *)&client_len);
+
+       if (client_sockfd == -1) {
+               _E("socket accept error");
+               free(msg);
+               goto out;
+       }
+       if (read_message(client_sockfd, msg) < 0) {
+               _E("recv error msg");
+               print_sysnoti_msg(__FUNCTION__, msg);
+               free_message(msg);
+               write(client_sockfd, &ret, sizeof(int));
+               close(client_sockfd);
+               __sysnoti_stop(sysnoti_fd);
+               __sysnoti_start();
+               goto out;
+       }
+
+       print_sysnoti_msg(__FUNCTION__, msg);
+       if (msg->argc > SYSMAN_MAXARG) {
+               _E("error argument");
+               free_message(msg);
+               write(client_sockfd, &ret, sizeof(int));
+               close(client_sockfd);
+               goto out;
+       }
+
+       switch (msg->cmd) {
+#ifdef NOUSE
+       case REGISTER_MSG:
+               ret = register_msg(msg);
+               _E("%d", ret);
+               break;
+#endif
+       case NOTIFY_MSG:
+               ret = notify_msg(msg, client_sockfd);
+               break;
+       default:
+               ret = -1;
+       }
+
+
+       write(client_sockfd, &ret, sizeof(int));
+       close(client_sockfd);
+
+       free_message(msg);
+out:
+       return EINA_TRUE;
+}
+
+static int sysnoti_server_init(void)
+{
+       int fd;
+       struct sockaddr_un serveraddr;
+
+       if (access(SYSNOTI_SOCKET_PATH, F_OK) == 0)
+               unlink(SYSNOTI_SOCKET_PATH);
+
+       fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (fd < 0) {
+               _E("socket create failed");
+               return -1;
+       }
+       if((fsetxattr(fd, "security.SMACK64IPOUT", "@", 2, 0)) < 0 ) {
+               _E("Socket SMACK labeling failed");
+               if(errno != EOPNOTSUPP) {
+                       close(fd);
+                       return -1;
+               }
+       }
+
+       if((fsetxattr(fd, "security.SMACK64IPIN", "*", 2, 0)) < 0 ) {
+               _E("Socket SMACK labeling failed");
+               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) {
+               _E("socket bind failed");
+               close(fd);
+               return -1;
+       }
+
+       if (chmod(SYSNOTI_SOCKET_PATH, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0)      /* 0777 */
+               _E("failed to change the socket permission");
+
+       if (listen(fd, 5) < 0) {
+               _E("failed to listen");
+               close(fd);
+               return -1;
+       }
+
+       return fd;
+}
+
+static int __sysnoti_start(void)
+{
+       sysnoti_fd = sysnoti_server_init();
+       if ( sysnoti_fd < 0 )
+               return -1;
+       sysnoti_efd = ecore_main_fd_handler_add(sysnoti_fd, ECORE_FD_READ, sysnoti_cb, NULL, NULL,
+                                 NULL);
+       if (!sysnoti_efd) {
+               _E("error ecore_main_fd_handler_add");
+               close(sysnoti_fd);
+               return -1;
+       }
+       return 0;
+}
+
+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;
+}
+
+static void sysnoti_init(void *data)
+{
+       struct main_data *ad = (struct main_data*)data;
+
+       if (__sysnoti_start() == -1)
+               _E("fail sys socket fd init");
+}
+
+static const struct device_ops sysnoti_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "sysnoti",
+       .init     = sysnoti_init,
+};
+
+DEVICE_OPS_REGISTER(&sysnoti_device_ops)
diff --git a/src/core/sysnoti.h b/src/core/sysnoti.h
new file mode 100644 (file)
index 0000000..aee5fee
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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 __SYSNOTI_H__
+#define __SYSNOTI_H__
+
+#define SYSMAN_MAXARG  16
+
+struct sysnoti {
+       int pid;
+       int cmd;
+       char *type;
+       char *path;
+       int argc;
+       char *argv[SYSMAN_MAXARG];
+};
+
+#endif /* __SYSNOTI_H__ */
diff --git a/src/core/udev.h b/src/core/udev.h
new file mode 100644 (file)
index 0000000..69a0934
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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 __UDEV_H__
+#define __UDEV_H__
+
+#include <libudev.h>
+
+#define UDEV                   "kernel"
+#define UDEV_SUBSYSTEM         "SUBSYSTEM"
+
+#define UDEV_ACTION            "ACTION"
+#define UDEV_CHANGE            "change"
+#define UDEV_ADD               "add"
+#define UDEV_REMOVE            "remove"
+
+#define UDEV_DEVPATH           "DEVPATH"
+
+#define UDEV_MONITOR_SIZE      (10*1024)
+#define UDEV_MONITOR_SIZE_LARGE (128*1024*1024)
+
+/* platform */
+#define PLATFORM_SUBSYSTEM     "platform"
+#define THERMISTOR_PATH                "*/sec-thermistor"
+
+/* battery device */
+#define POWER_SUBSYSTEM                "power_supply"
+#define POWER_PATH                     "/sys/class/power_supply/battery"
+#define POWER_SUPPLY_UEVENT POWER_PATH"/uevent"
+#define CAPACITY                       "POWER_SUPPLY_CAPACITY"
+#define CHARGE_FULL                    "POWER_SUPPLY_CHARGE_FULL"
+#define CHARGE_NOW                     "POWER_SUPPLY_CHARGE_NOW"
+#define CHARGE_HEALTH          "POWER_SUPPLY_HEALTH"
+#define CHARGE_PRESENT         "POWER_SUPPLY_PRESENT"
+#define CHARGE_NAME                    "POWER_SUPPLY_NAME"
+#define CHARGE_STATUS          "POWER_SUPPLY_STATUS"
+#define CHARGE_ONLINE          "POWER_SUPPLY_ONLINE"
+
+/* input device */
+#define INPUT_SUBSYSTEM                "input"
+#define INPUT_PATH                     "*/input[0-9]*/event[0-9]*"
+
+/* lcd esd device */
+#define LCD_EVENT_SUBSYSTEM    "lcd_event"
+#define LCD_ESD_PATH           "*/lcd_event/esd"
+
+/* switch device */
+#define SWITCH_SUBSYSTEM       "switch"
+
+/* host device */
+#define HOST_SUBSYSTEM         "host_notify"
+
+/* power supply status */
+enum {
+       POWER_SUPPLY_STATUS_UNKNOWN = 0,
+       POWER_SUPPLY_STATUS_CHARGING,
+       POWER_SUPPLY_STATUS_DISCHARGING,
+       POWER_SUPPLY_STATUS_NOT_CHARGING,
+       POWER_SUPPLY_STATUS_FULL,
+};
+
+enum {
+        POWER_SUPPLY_TYPE_UNKNOWN = 0,
+        POWER_SUPPLY_TYPE_BATTERY,
+        POWER_SUPPLY_TYPE_UPS,
+        POWER_SUPPLY_TYPE_MAINS,
+        POWER_SUPPLY_TYPE_USB,
+};
+
+struct uevent_handler {
+       char *subsystem;
+       void (*uevent_func)(struct udev_device *dev);
+       void *data;
+};
+
+int register_uevent_control(const struct uevent_handler *uh);
+void unregister_uevent_control(const struct uevent_handler *uh);
+int register_kernel_uevent_control(const struct uevent_handler *uh);
+void unregister_kernel_uevent_control(const struct uevent_handler *uh);
+
+
+#endif /* __UDEV_H__ */
diff --git a/src/cpu/cpu-handler.c b/src/cpu/cpu-handler.c
new file mode 100644 (file)
index 0000000..bc17054
--- /dev/null
@@ -0,0 +1,617 @@
+/*
+ * 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 <fcntl.h>
+#include <device-node.h>
+#include <vconf.h>
+
+#include "core/list.h"
+#include "core/log.h"
+#include "core/data.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+#include "core/common.h"
+#include "core/device-notifier.h"
+#include "proc/proc-handler.h"
+
+#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_CPU_COUNT       "set_cpu_count"
+
+#define POWER_SAVING_CPU_FREQ_RATE     (0.7)
+
+#define DEFAULT_MAX_CPU_FREQ           1200000
+#define DEFAULT_MIN_CPU_FREQ           100000
+
+enum emergency_type {
+       EMERGENCY_UNLOCK = 0,
+       EMERGENCY_LOCK = 1,
+};
+
+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 int power_saving_freq = -1;
+
+static dd_list *max_cpu_freq_list;
+static dd_list *min_cpu_freq_list;
+
+static int cpu_number_limit = -1;
+static int cur_cpu_number = INT_MAX;
+static dd_list *cpu_number_list;
+
+struct cpu_freq_entry {
+       int pid;
+       int freq;
+};
+
+struct cpu_number_entry {
+       int pid;
+       int number;
+};
+
+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 write_min_cpu_freq(int freq)
+{
+       int ret;
+
+       ret = device_set_property(DEVICE_TYPE_CPU, PROP_CPU_SCALING_MIN_FREQ, freq);
+       if (ret < 0) {
+               _E("set cpufreq min freq write error: %s", strerror(errno));
+               return ret;
+       }
+
+       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) {
+               _E("set cpufreq max freq write error: %s", strerror(errno));
+               return ret;
+       }
+
+       return 0;
+}
+
+static int remove_entry_from_min_cpu_freq_list(int pid)
+{
+       dd_list *tmp;
+       struct cpu_freq_entry *entry;
+
+       cur_min_cpu_freq = INT_MIN;
+
+       DD_LIST_FOREACH(min_cpu_freq_list, tmp, entry) {
+               if ((!is_entry_enable(entry->pid)) || (entry->pid == pid)) {
+                       DD_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 remove_entry_from_max_cpu_freq_list(int pid)
+{
+       dd_list *tmp;
+       struct cpu_freq_entry *entry;
+
+       cur_max_cpu_freq = INT_MAX;
+
+       DD_LIST_FOREACH(max_cpu_freq_list, tmp, entry) {
+               if ((!is_entry_enable(entry->pid)) || (entry->pid == pid)) {
+                       DD_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;
+}
+
+int release_max_frequency_action(int argc, char **argv)
+{
+       int r;
+
+       if (argc < 1)
+               return -EINVAL;
+
+       r = remove_entry_from_max_cpu_freq_list(atoi(argv[0]));
+       if (r < 0) {
+               _E("Remove entry failed");
+               return r;
+       }
+
+       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) {
+               _E("Write freq failed");
+               return r;
+       }
+
+       return 0;
+}
+
+int release_min_frequency_action(int argc, char **argv)
+{
+       int r;
+
+       if (argc < 1)
+               return -EINVAL;
+
+       r = remove_entry_from_min_cpu_freq_list(atoi(argv[0]));
+       if (r < 0) {
+               _E("Remove entry failed");
+               return r;
+       }
+
+       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) {
+               _E("Write entry failed");
+               return r;
+       }
+
+       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) {
+               _E("Remove duplicated entry failed");
+       }
+
+       entry = malloc(sizeof(struct cpu_freq_entry));
+       if (!entry) {
+               _E("Malloc failed");
+               return -ENOMEM;
+       }
+
+       entry->pid = pid;
+       entry->freq = freq;
+
+       DD_LIST_PREPEND(max_cpu_freq_list, entry);
+       if (!max_cpu_freq_list) {
+               _E("eina_list_prepend failed");
+               return -ENOSPC;
+       }
+       if (freq < cur_max_cpu_freq) {
+               cur_max_cpu_freq = freq;
+       }
+       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) {
+               _E("Remove duplicated entry failed");
+       }
+
+       entry = malloc(sizeof(struct cpu_freq_entry));
+       if (!entry) {
+               _E("Malloc failed");
+               return -ENOMEM;
+       }
+
+       entry->pid = pid;
+       entry->freq = freq;
+
+       DD_LIST_PREPEND(min_cpu_freq_list, entry);
+       if (!min_cpu_freq_list) {
+               _E("eina_list_prepend failed");
+               return -ENOSPC;
+       }
+       if (freq > cur_min_cpu_freq) {
+               cur_min_cpu_freq = freq;
+       }
+       return 0;
+}
+
+int set_max_frequency_action(int argc, char **argv)
+{
+       int r;
+
+       if (argc < 2)
+               return -EINVAL;
+
+       r = add_entry_to_max_cpu_freq_list(atoi(argv[0]), atoi(argv[1]));
+       if (r < 0) {
+               _E("Add entry failed");
+               return r;
+       }
+
+       r = write_max_cpu_freq(cur_max_cpu_freq);
+       if (r < 0) {
+               _E("Write entry failed");
+               return r;
+       }
+
+       return 0;
+}
+
+int set_min_frequency_action(int argc, char **argv)
+{
+       int r;
+
+       if (argc < 2)
+               return -EINVAL;
+
+       r = add_entry_to_min_cpu_freq_list(atoi(argv[0]), atoi(argv[1]));
+       if (r < 0) {
+               _E("Add entry failed");
+               return r;
+       }
+
+       r = write_min_cpu_freq(cur_min_cpu_freq);
+       if (r < 0) {
+               _E("Write entry failed");
+               return r;
+       }
+
+       return 0;
+}
+
+static int power_saving_cpu_cb(keynode_t *key_nodes, void *data)
+{
+       int ret = 0;
+       int val = 0;
+       int power_saving_cpu_stat = -1;
+
+       power_saving_cpu_stat = vconf_keynode_get_bool(key_nodes);
+       if (power_saving_cpu_stat == 1) {
+               val = 1;
+               ret = add_entry_to_max_cpu_freq_list(getpid(), power_saving_freq);
+               if (ret < 0) {
+                       _E("Add entry failed");
+                       goto out;
+               }
+       } else {
+               ret = remove_entry_from_max_cpu_freq_list(getpid());
+               if (ret < 0) {
+                       _E("Remove entry failed");
+                       goto out;
+               }
+               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)
+               _E("Write failed");
+out:
+       device_notify(DEVICE_NOTIFIER_PMQOS_POWERSAVING, (void*)val);
+       return ret;
+}
+
+static void set_emergency_limit(void)
+{
+       int ret, val;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &val);
+       if (ret < 0) {
+               _E("failed to get vconf key");
+               return;
+       }
+       if (val != SETTING_PSMODE_EMERGENCY)
+               return;
+
+       val = EMERGENCY_LOCK;
+       device_notify(DEVICE_NOTIFIER_PMQOS_EMERGENCY, (void*)val);
+
+}
+static int emergency_cpu_cb(keynode_t *key_nodes, void *data)
+{
+       int val;
+
+       val = vconf_keynode_get_int(key_nodes);
+       if (val == SETTING_PSMODE_EMERGENCY)
+               val = EMERGENCY_LOCK;
+       else
+               val = EMERGENCY_UNLOCK;
+
+       device_notify(DEVICE_NOTIFIER_PMQOS_EMERGENCY, (void*)val);
+       return 0;
+}
+
+static void set_freq_limit(void)
+{
+       int ret = 0;
+       int val = 0;
+       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) {
+               _E("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) {
+               _E("get cpufreq cpuinfo min readerror: %s", strerror(errno));
+               min_cpu_freq_limit = DEFAULT_MIN_CPU_FREQ;
+       }
+       power_saving_freq = (int)(max_cpu_freq_limit * POWER_SAVING_CPU_FREQ_RATE);
+       _I("max(%d) , ps(%d), min(%d)",
+               max_cpu_freq_limit,
+               power_saving_freq,
+               min_cpu_freq_limit);
+
+       ret = vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_CPU,
+                       &power_saving_cpu_stat);
+       if (ret < 0) {
+               _E("failed to get vconf key");
+               return;
+       }
+       if (power_saving_cpu_stat != 1)
+               return;
+       val = 1;
+       ret = add_entry_to_max_cpu_freq_list(getpid(), power_saving_freq);
+       if (ret < 0) {
+               _E("Add entry failed");
+               goto out;
+       }
+       ret = write_max_cpu_freq(cur_max_cpu_freq);
+       if (ret < 0)
+               _E("Write entry failed");
+out:
+       _I("init");
+       device_notify(DEVICE_NOTIFIER_PMQOS_POWERSAVING, (void*)val);
+}
+
+static void set_cpu_number_limit(void)
+{
+       device_get_property(DEVICE_TYPE_CPU, PROP_CPU_ENABLE_MAX_NUMBER,
+               &cpu_number_limit);
+}
+
+static int write_cpu_number(int number)
+{
+       int ret;
+
+       ret = device_set_property(DEVICE_TYPE_CPU, PROP_CPU_ENABLE_MAX_NUMBER,
+                       number);
+       if (ret < 0) {
+               _E("set cpu number max write error: %s", strerror(errno));
+               return ret;
+       }
+
+       return 0;
+}
+
+static int remove_entry_from_cpu_number_list(int pid)
+{
+       dd_list *tmp;
+       struct cpu_number_entry *entry;
+
+       cur_cpu_number = INT_MAX;
+
+       DD_LIST_FOREACH(cpu_number_list, tmp, entry) {
+               if ((!is_entry_enable(entry->pid)) || (entry->pid == pid)) {
+                       DD_LIST_REMOVE(cpu_number_list, entry);
+                       free(entry);
+                       continue;
+               }
+               if (entry->number < cur_cpu_number) {
+                       cur_cpu_number = entry->number;
+               }
+       }
+
+       return 0;
+}
+
+static int add_entry_to_cpu_number_list(int pid, int number)
+{
+       int r;
+       struct cpu_number_entry *entry;
+
+       r = remove_entry_from_cpu_number_list(pid);
+       if (r < 0) {
+               _E("Remove duplicated entry failed");
+       }
+
+
+
+       entry = malloc(sizeof(struct cpu_number_entry));
+       if (!entry) {
+               _E("Malloc failed");
+               return -ENOMEM;
+       }
+
+       entry->pid = pid;
+       entry->number = number;
+
+       DD_LIST_PREPEND(cpu_number_list, entry);
+       if (!cpu_number_list) {
+               _E("eina_list_prepend failed");
+               return -ENOSPC;
+       }
+       if (number < cur_cpu_number) {
+               cur_cpu_number = number;
+       }
+       return 0;
+}
+
+int set_cpu_number_action(int argc, char **argv)
+{
+       int r;
+
+       if(cur_siop_level() != 0)
+               return -EINVAL;
+
+       if (argc == 1) {// release cpu number
+               r = remove_entry_from_cpu_number_list(atoi(argv[0]));
+               if (r < 0) {
+                       _E("Remove entry failed");
+                       return r;
+               }
+
+               if (cur_cpu_number == INT_MAX)
+                       cur_cpu_number = cpu_number_limit;
+
+               r = write_cpu_number(cur_cpu_number);
+               if (r < 0) {
+                       _E("Write cpu number failed");
+                       return r;
+               }
+       } else if (argc ==2) {//set cpu number
+               r = add_entry_to_cpu_number_list(atoi(argv[0]), atoi(argv[1]));
+               if (r < 0) {
+                       _E("Add entry failed");
+                       return r;
+               }
+
+               r = write_cpu_number(cur_cpu_number);
+               if (r < 0) {
+                       _E("Write entry failed");
+                       return r;
+               }
+       }
+       return 0;
+}
+
+static int booting_done(void *data)
+{
+       set_freq_limit();
+       set_emergency_limit();
+       return 0;
+}
+
+static DBusMessage *dbus_cpu_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+       char *argv[2];
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv[0],
+                   DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (strncmp(type_str, PREDEF_SET_MAX_FREQUENCY, strlen(PREDEF_SET_MAX_FREQUENCY)) == 0)
+               ret = set_max_frequency_action(argc, (char **)&argv);
+       else if (strncmp(type_str, PREDEF_SET_MIN_FREQUENCY, strlen(PREDEF_SET_MIN_FREQUENCY)) == 0)
+               ret = set_min_frequency_action(argc, (char **)&argv);
+       else if (strncmp(type_str, PREDEF_RELEASE_MAX_FREQUENCY, strlen(PREDEF_RELEASE_MAX_FREQUENCY)) == 0)
+               ret = release_max_frequency_action(argc, (char **)&argv);
+       else if (strncmp(type_str, PREDEF_RELEASE_MIN_FREQUENCY, strlen(PREDEF_RELEASE_MIN_FREQUENCY)) == 0)
+               ret = release_min_frequency_action(argc, (char **)&argv);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { PREDEF_SET_MAX_FREQUENCY,     "siss", "i", dbus_cpu_handler },
+       { PREDEF_SET_MIN_FREQUENCY,     "siss", "i", dbus_cpu_handler },
+       { PREDEF_RELEASE_MAX_FREQUENCY, "siss", "i", dbus_cpu_handler },
+       { PREDEF_RELEASE_MIN_FREQUENCY, "siss", "i", dbus_cpu_handler },
+};
+
+static void cpu_init(void *data)
+{
+       int ret;
+
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+       ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+       set_cpu_number_limit();
+       register_action(PREDEF_SET_MAX_FREQUENCY, set_max_frequency_action, NULL, NULL);
+       register_action(PREDEF_SET_MIN_FREQUENCY, set_min_frequency_action, NULL, NULL);
+       register_action(PREDEF_RELEASE_MAX_FREQUENCY, release_max_frequency_action, NULL, NULL);
+       register_action(PREDEF_RELEASE_MIN_FREQUENCY, release_min_frequency_action, NULL, NULL);
+       register_action(PREDEF_CPU_COUNT, set_cpu_number_action, NULL, NULL);
+
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_CPU, (void *)power_saving_cpu_cb, NULL);
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE, (void *)emergency_cpu_cb, NULL);
+}
+
+static const struct device_ops cpu_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "cpu",
+       .init     = cpu_init,
+};
+
+DEVICE_OPS_REGISTER(&cpu_device_ops)
diff --git a/src/devicectl/CMakeLists.txt b/src/devicectl/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..5d12dc4
--- /dev/null
@@ -0,0 +1,39 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(devicectl C)
+
+IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_ENGINEER_MODE")
+    OPTION(USE_ENGINEER_MODE "Use Engineer mode" ON)
+ENDIF()
+
+SET(SRCS
+       devicectl.c
+)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED dbus-1)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+IF(USE_ENGINEER_MODE)
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions")
+ELSE()
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer")
+ENDIF()
+
+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_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} shared)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+
diff --git a/src/devicectl/devicectl.c b/src/devicectl/devicectl.c
new file mode 100644 (file)
index 0000000..d9dcfef
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * devicectl
+ *
+ * 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.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <dbus/dbus.h>
+#include <shared/dbus.h>
+#include <core/common.h>
+
+/*
+ * devicectl [device] [action]
+ * ex> devicectl display stop
+ *     devicectl pass start
+ */
+
+enum device_type {
+       DEVICE_CORE,
+       DEVICE_DISPLAY,
+       DEVICE_LED,
+       DEVICE_PASS,
+       DEVICE_MAX,
+       DEVICE_ALL,
+};
+static enum device_type arg_id;
+
+static const struct device {
+       const enum device_type id;
+       const char *name;
+       const char *path;
+       const char *iface;
+} devices[] = {
+       { DEVICE_CORE,    "core",    DEVICED_PATH_CORE,    DEVICED_INTERFACE_CORE    },
+       { DEVICE_DISPLAY, "display", DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY },
+       { DEVICE_LED,     "led",     DEVICED_PATH_LED,     DEVICED_INTERFACE_LED     },
+       { DEVICE_PASS,    "pass",    DEVICED_PATH_PASS,    DEVICED_INTERFACE_PASS    },
+};
+
+static int start_device(char **args)
+{
+       DBusMessage *msg;
+
+       if (!args[1])
+               return -EINVAL;
+
+       printf("start %s device!\n", args[1]);
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                   devices[arg_id].path, devices[arg_id].iface,
+                   "start", NULL, NULL);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_message_unref(msg);
+
+       return 0;
+}
+
+static int stop_device(char **args)
+{
+       DBusMessage *msg;
+
+       if (!args[1])
+               return -EINVAL;
+
+       printf("start %s device!\n", args[1]);
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                   devices[arg_id].path, devices[arg_id].iface,
+                   "stop", NULL, NULL);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_message_unref(msg);
+
+       return 0;
+}
+
+static int dump_mode(char **args)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, val;
+       char *arr[1];
+
+       if (!args[1] || !args[2] || !args[3])
+               return -EINVAL;
+
+       printf("%s (%s %s)!\n", args[1], args[2], args[3]);
+
+       arr[0] = args[3];
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                   devices[arg_id].path, devices[arg_id].iface,
+                   "Dumpmode", "s", arr);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               printf("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               val = -ENOMSG;
+       }
+
+       dbus_message_unref(msg);
+       return val;
+}
+
+static int save_log(char **args)
+{
+       DBusMessage *msg;
+
+       if (!args[1])
+               return -EINVAL;
+
+       printf("save log %s device!\n", args[1]);
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                   devices[arg_id].path, devices[arg_id].iface,
+                   "SaveLog", NULL, NULL);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_message_unref(msg);
+
+       return 0;
+}
+
+static const struct action {
+       const enum device_type id;
+       const char *action;
+       const int argc;
+       int (* const func)(char **args);
+} actions[] = {
+       { DEVICE_ALL,       "start",           3, start_device          },
+       { DEVICE_ALL,       "stop",            3, stop_device           },
+       { DEVICE_DISPLAY,   "dumpmode",        4, dump_mode             },
+       { DEVICE_LED,       "dumpmode",        4, dump_mode             },
+       { DEVICE_DISPLAY,   "savelog",         3, save_log              },
+};
+
+static inline void usage()
+{
+       printf("[usage] devicectl <device_name> <action>\n");
+}
+
+int main(int argc, char *argv[])
+{
+       int i;
+
+       if (argc < 3) {
+               usage();
+               return -EINVAL;
+       }
+
+       for (i = 0; i < argc; i++)
+               if (argv[i] == NULL) {
+                       usage();
+                       return -EINVAL;
+               }
+
+       for (i = 0; i < ARRAY_SIZE(devices); i++)
+               if (!strcmp(argv[1], devices[i].name))
+                       break;
+
+       if (i >= ARRAY_SIZE(devices)) {
+               printf("invalid device name! %s\n", argv[1]);
+               usage();
+               return -EINVAL;
+       }
+
+       arg_id = devices[i].id;
+
+       for (i = 0; i < ARRAY_SIZE(actions); i++)
+               if (actions[i].id == arg_id || actions[i].id == DEVICE_ALL)
+                       if (!strcmp(argv[2], actions[i].action))
+                               break;
+
+       if (i >= ARRAY_SIZE(actions)) {
+               printf("invalid action name! %s\n", argv[2]);
+               usage();
+               return -EINVAL;
+       }
+
+       if (actions[i].argc != argc) {
+               printf("invalid arg count!\n");
+               usage();
+               return -EINVAL;
+       }
+
+       return actions[i].func(argv);
+}
+
diff --git a/src/deviced/dd-battery.h b/src/deviced/dd-battery.h
new file mode 100644 (file)
index 0000000..72beda3
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * 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
+ * @defgroup    CAPI_SYSTEM_DEVICED_BATTERY_MODULE Battery
+ * @ingroup     CAPI_SYSTEM_DEVICED
+ * @brief       This file provides the API for control of battery
+ * @section CAPI_SYSTEM_DEVICED_BATTERY_MODULE_HEADER Required Header
+ *   \#include <dd-battery.h>
+ */
+
+/**
+ * @addtogroup CAPI_SYSTEM_DEVICED_BATTERY_MODULE
+ * @{
+ */
+
+/**
+ * @par Description
+ * Battery Health status
+ */
+enum {
+       BAT_UNKNOWN = 0,
+       BAT_GOOD,
+       BAT_OVERHEAT,
+       BAT_DEAD,
+       BAT_OVERVOLTAGE,
+       BAT_UNSPECIFIED,
+       BAT_COLD,
+       BAT_HEALTH_MAX,
+};
+
+/**
+ * @par Description:
+ *      This API is used to get the remaining battery percentage.\n
+ *      It gets the Battery percentage by calling device_get_property() function.\n
+ *      It returns integer value(0~100) that indicates remaining batterty percentage on success.\n
+ *      Or a negative value(-1) is returned on failure.
+ * @return On success, integer value(0~100) is returned.
+ *  Or a negative value(-1) is returned on failure.
+ * @see battery_is_full(), battery_get_percent_raw()
+ * @par Example
+ * @code
+ *  ...
+ *  int battery;
+ *  battery = battery_get_percent();
+ *  if( battery < 0 )
+ *      printf("Fail to get the remaining battery percentage.\n");
+ *  else
+ *      printf("remaining battery percentage : %d\n", battery);
+ *  ...
+ * @endcode
+ */
+int battery_get_percent(void);
+
+/**
+ * @par Description:
+ *      This API is used to get the remaining battery percentage expressed 1/10000.\n
+ *      It gets the Battery percentage by calling device_get_property() function.\n
+ *      It returns integer value(0~10000) that indicates remaining batterty percentage on success.\n
+ *      Or a negative value(-1) is returned on failure.
+ * @return On success, integer value(0~10000) is returned.
+ *  Or a negative value(-1) is returned on failure.
+ * @see battery_is_full(), battery_get_percent()
+ * @par Example
+ * @code
+ *  ...
+ *  int battery;
+ *  battery = battery_get_percent_raw();
+ *  if( battery < 0 )
+ *      printf("Fail to get the remaining battery percentage.\n");
+ *  else
+ *      printf("remaining battery percentage expressed 1/10000 : %d\n", battery);
+ *  ...
+ * @endcode
+ */
+int battery_get_percent_raw(void);
+
+/**
+ * @par Description:
+ *      This API is used to get the fully charged status of battery.\n
+ *  It gets the fully charged status of Battery by calling device_get_property() function.\n
+ *      If the status of battery is full, it returns 1.\n
+ *      Or a negative value(-1) is returned, if the status of battery is not full.
+ * @return 1 with battery full, or 0 on not full-charged, -1 if failed
+ * @see battery_get_percent()
+ * @par Example
+ * @code
+ *  ...
+ *  if( battery_is_full() > 0 )
+ *      printf("battery fully chared\n");
+ *  ...
+ * @endcode
+ */
+int battery_is_full(void);
+
+/**
+ * @par Description:
+ *  This API is used to get the battery health status.\n
+ *  It gets the battery health status by calling device_get_property() function.\n
+ *      It returns integer value(0~7) that indicate battery health status on success.\n
+ *  Or a negative value(-1) is returned, if the status of battery is not full.
+ * @return integer value, -1 if failed\n
+ * (0 BATTERY_UNKNOWN, 1 GOOD, 2 OVERHEAT, 3 DEAD, 4 OVERVOLTAGE, 5 UNSPECIFIED, 6 COLD, 7 BAT_HEALTH_MAX)
+ * @par Example
+ * @code
+ *  ...
+ *  int bat_health;
+ *  bat_health = battery_get_health();
+ *  if( bat_health != BAT_GOOD )
+ *      printf("battery health is not good\n");
+ *  ...
+ * @endcode
+ */
+int battery_get_health(void);
+
+/**
+ * @} // end of CAPI_SYSTEM_DEVICED_BATTERY_MODULE
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/deviced/dd-common.h b/src/deviced/dd-common.h
new file mode 100644 (file)
index 0000000..fdfc2ac
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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_COMMON_H__
+#define __DD_COMMON_H__
+
+/**
+ * @file        dd-common.h
+ * @ingroup     CAPI_SYSTEM_DEVICED
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef DEPRECATED
+#define DEPRECATED __attribute__((deprecated))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif                         /* __DD_COMMON_H__ */
diff --git a/src/deviced/dd-control.h b/src/deviced/dd-control.h
new file mode 100644 (file)
index 0000000..c094196
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * 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_CONTROL_H__
+#define __DD_CONTROL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+
+/**
+ * @file        dd-control.h
+ * @defgroup    CAPI_SYSTEM_DEVICED_CONTROL_MODULE Control
+ * @ingroup     CAPI_SYSTEM_DEVICED
+ * @brief       This file provides the API to enable/disable devices
+ * @section CAPI_SYSTEM_DEVICED_CONTROL_MODULE_HEADER Required Header
+ *   \#include <dd-control.h>
+ */
+
+/**
+ * @addtogroup CAPI_SYSTEM_DEVICED_CONTROL_MODULE
+ * @{
+ */
+
+/**
+ * @par Description
+ * Control Device type
+ */
+enum control_device_type {
+/* Add device define here  */
+       DEVICE_CONTROL_MMC,
+       DEVICE_CONTROL_USBCLIENT,
+       DEVICE_CONTROL_RGBLED,
+       DEVICE_CONTROL_MAX,
+};
+
+/**
+ * @par Description:
+ *  This API is used to enable/disable mmc device.\n
+ * @param[in] enable enable/disable mmc device
+ * @return 0 on success, -1 if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if( deviced_mmc_control(1) < 0 )
+ *      printf("Enable mmc device failed\n");
+ *  ...
+ * @endcode
+ */
+int deviced_mmc_control(bool enable);
+
+/**
+ * @par Description:
+ *  This API is used to enable/disable usb device.\n
+ * @param[in] enable enable/disable usb device
+ * @return 0 on success, -1 if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if( deviced_usb_control(1) < 0 )
+ *      printf("Enable usb device failed\n");
+ *  ...
+ * @endcode
+ */
+int deviced_usb_control(bool enable);
+
+/* Only USB-manager will use the api */
+/**
+ * @par Description:
+ * @return
+ * @par Example
+ * @code
+ * @endcode
+ * @todo describe function
+ */
+int deviced_get_usb_control(void);
+
+/**
+ * @par Description:
+ *  This API is used to enable/disable rgbled device.\n
+ * @param[in] enable enable/disable usb device
+ * @return 0 on success, -1 if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if( deviced_rgbled_control(true) < 0 )
+ *      printf("Enable rgbled device failed\n");
+ *  ...
+ * @endcode
+ */
+int deviced_rgbled_control(bool enable);
+
+/**
+ * @} // end of CAPI_SYSTEM_DEVICED_CONTROL_MODULE
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/deviced/dd-deviced-managed.h b/src/deviced/dd-deviced-managed.h
new file mode 100644 (file)
index 0000000..ba0af77
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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_DEVICED_MANAGED_H__
+#define __DD_DEVICED_MANAGED_H__
+
+#include <sys/time.h>
+#include "dd-mmc.h"
+
+/**
+ * @file        dd-deviced-managed.h
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_SYSTEM_DEVICED
+ * @{
+ */
+
+/**
+ * @fn int deviced_get_pid(const char *execpath)
+ * @brief This API is used to get the pid of the process which has the specified execpath.\n
+ *             Internally, this API searches /proc/{pid}/cmdline and compares the parameter execpath with 1st argument of cmdline. \n
+ *             If there is no process that has same execpath in /proc/{pid}/cmdline, it will return -1.
+ * @param[in] execpath program path which you want to know whether it is run or not
+ * @return pid when the program is running, -1 if it is not.
+ */
+int deviced_get_pid(const char *execpath);
+
+/**
+ * @fn int deviced_set_datetime(time_t timet)
+ * @brief This API is used to set date time.\n
+ *             Internally, this API call predefined action API. That is send a notify message. \n
+ * @param[in] timet type of time which you want to set.
+ * @return pid when the program is running, -1 if param is less than 0 or when failed set datetime.
+ */
+int deviced_set_datetime(time_t timet);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __DD_DEVICED_MANAGED_H__ */
diff --git a/src/deviced/dd-deviced.h b/src/deviced/dd-deviced.h
new file mode 100644 (file)
index 0000000..92ef751
--- /dev/null
@@ -0,0 +1,402 @@
+/*
+ * 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_DEVICED__
+#define __DD_DEVICED__
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include "dd-deviced-managed.h"
+
+/**
+ * @file        dd-deviced.h
+ * @defgroup    CAPI_SYSTEM_DEVICED_UTIL_MODULE Util
+ * @ingroup     CAPI_SYSTEM_DEVICED
+ * @section CAPI_SYSTEM_DEVICED_UTIL_MODULE_HEADER Required Header
+ *   \#include <dd-deviced.h>
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_SYSTEM_DEVICED_UTIL_MODULE
+ * @{
+ */
+
+/**
+ * @brief Policy for low memory
+ */
+enum mem_policy {
+       OOM_LIKELY,     /**< For miscellaneous applications */
+       OOM_IGNORE      /**< For daemons */
+};
+
+#define CRASH_TICKET_PATH               "/opt/usr/share/crash/ticket"
+#define FORCED_DUMP_DIR_PATH            "/opt/usr/media/SLP_debug"
+#define FORCED_DUMP_ZIP_PATH            "/opt/usr/media/SLP_debug/zip"
+
+/**
+ * @brief Logs dump type
+ */
+enum dump_log_type {
+       AP_DUMP = 0,    /**< Application logs dump */
+       CP_DUMP = 1,    /**< Modem logs dump */
+       ALL_DUMP = 2    /**< All logs dump - application and modem */
+};
+
+/* deviced_util */
+
+/**
+ * @fn int deviced_get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
+ * @brief This API is used to get the file name of command line of the process from the proc fs.
+ *             Caller process MUST allocate enough memory for the cmdline parameter. \n
+ *             Its size should be assigned to cmdline_size. \n
+ *             Internally it reads the 1st argument of /proc/{pid}/cmdline and copies it to cmdline.
+ * @param[in] pid pid of the process that you want to get the file name of command line
+ * @param[out] cmdline command line of the process that you want to get the file name <br>
+ *                     Callers should allocate memory to this parameter before calling this function.
+ *                     The allocated memory size must be large enough to store the file name.
+ *                     The result will include the terminating null byte('\0') at the end of the string.
+ * @param[in] cmdline_size
+ * @return 0 on success, -1 if failed.\n
+ *         If the size of cmdline is smaller than the result, it will return -1 and  \n
+ *         errno will be set as EOVERFLOW. \n
+ *         If the function cannot open /proc/%d/cmdline file then it will return -1 and \n
+ *         errno will be set as ESRCH.
+ */
+int deviced_get_cmdline_name(pid_t pid, char *cmdline,
+                                   size_t cmdline_size);
+
+/**
+ * @fn int deviced_get_apppath(pid_t pid, char *app_path, size_t app_path_size)
+ * @brief This API is used to get the execution path of the process specified by the pid parameter.\n
+ *             Caller process MUST allocate enough memory for the app_path parameter. \n
+ *             Its size should be assigned to app_path_size. \n
+ *             Internally it reads a link of /proc/{pid}/exe and copies the path to app_path.
+ * @param[in] pid pid of the process that you want to get the executed path
+ * @param[out] app_path the executed file path of the process <br>
+ *                     Callers should allocate memory to this parameter before calling this function.
+ *                     The allocated memory size must be large enough to store the executed file path.
+ *                     The result will include the terminating null byte('\0') at the end of the string.
+ * @param[in] app_path_size allocated memory size of char *app_path
+ * @return 0 on success, -1 if failed. \n
+ *         If the size of app_path is smaller than the result, it will return -1 and \n
+ *         errno will be set as EOVERFLOW.
+ */
+int deviced_get_apppath(pid_t pid, char *app_path, size_t app_path_size);
+
+/* sysconf */
+
+/**
+ * @fn int deviced_conf_set_mempolicy(enum mem_policy mempol)
+ * @brief This API is used to set the policy of the current process when the phone has low available memory.
+ * @param[in] mempol oom adjust value which you want to set
+ * @return 0 on success, -1 if failed.
+ * @see deviced_conf_set_mempolicy_bypid()
+ * @retval -1 operation error
+ * @retval -EBADMSG - dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_conf_set_mempolicy(enum mem_policy mempol);
+
+/**
+ * @fn int deviced_conf_set_mempolicy_bypid(pid_t pid, enum mem_policy mempol)
+ * @brief This API is used to set the policy of the given process when the phone has low available memory.
+ * @param[in] pid process id which you want to set
+ * @param[in] mempol oom adjust value which you want to set
+ * @return 0 on success, -1 if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG - dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_conf_set_mempolicy_bypid(pid_t pid, enum mem_policy mempol);
+
+/**
+ * @fn int deviced_conf_set_permanent(void)
+ * @brief This API is used to set itself as a permanent process.\n
+ *             If the permanent process is dead, system server will relaunch the process automatically.
+ * @return 0 on success, -1 if failed.
+ * @see deviced_conf_set_permanent_bypid()
+ * @par Example
+ * @code
+ *  ...
+ *  ret = deviced_conf_set_permanent();
+ *  if( ret < 0 )
+ *      printf("Fail to set a process as permanent\n");
+ *  ...
+ * @endcode
+ */
+int deviced_conf_set_permanent(void);
+
+/**
+ * @fn int deviced_conf_set_permanent_bypid(pid_t pid)
+ * @brief This API is used to set a given process as permanent.\n
+ *       If the permanent process is dead, system server will relaunch the process automatically.
+ * @param[in] pid proces id
+ * @return 0 on success, -1 if failed.
+ * @see deviced_set_permanent()
+ * @par Example
+ * @code
+ *  ...
+ *  ret = deviced_conf_set_permanent_bypid(pid);
+ *  if( ret < 0 )
+ *      printf("Fail to set a process(%d) as permanent\n",pid);
+ *  ...
+ * @endcode
+ */
+int deviced_conf_set_permanent_bypid(pid_t pid);
+
+/**
+ * @fn int deviced_conf_set_vip(pid_t pid)
+ * @brief This API is used to set a process which has pid as Very Important Process(VIP) .\n
+ *             If the VIP process is dead, restarter program will be run. \n
+ *             Restarter program may kill almost processes and run rc.local scripts again.
+ * @param[in] pid process id to be vip
+ * @return 0 on success, -1 if failed.
+ * @see sysconf_is_vip
+ * @par Example
+ * @code
+ *     ...
+ *     ret = deviced_conf_set_vip(pid);
+ *     if( ret < 0 )
+ *             printf("Fail to set a process(%d) as VIP\n",pid);
+ *     ...
+ * @endcode
+ */
+int deviced_conf_set_vip(pid_t pid);
+
+/**
+ * @fn int deviced_conf_is_vip(pid_t pid)
+ * @brief This API is used to verify that process which has pid is Very Important Process(VIP) or not.
+ * @param[in] pid process id to be vip
+ * @return 1 if given process if vip process, otherwise 0 is returned.
+ * @see deviced_conf_set_vip
+ * @par Example
+ * @code
+ *     ...
+ *     ret = deviced_conf_is_vip(pid);
+ *     if(ret)
+ *             printf("process(%d) is Very Important Process\n",pid);
+ *     ...
+ * @endcode
+ */
+int deviced_conf_is_vip(pid_t pid);
+
+/**
+ * @fn int deviced_set_timezone(char *tzpath_str)
+ * @brief This API sets system timezone.
+ * @param[in] tzpath_str path to timezone definition file
+ * @return 0 on success, negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_set_timezone(char *tzpath_str);
+
+/**
+ * @fn int deviced_call_predef_action(const char *type, int num, ...)
+ * @brief This API calls predefined systemd action.
+ *             Internally it send message through SYSTEM_NOTI_SOCKET_PATH (/tmp/sn) UNIX socket to systemd.
+ * @param[in] type systemd action type name
+ * @param[in] num input parameters count. num cannot exceed SYSTEM_NOTI_MAXARG (16).
+ * @param[in] ... action input parameters. List of the parameters depends on action type.
+ * @return 0 on success, -1 if failed.
+ *         If the action type is not set (is blank) or num > SYSTEM_NOTI_MAXARG it will return -1
+ *         and errno will be set as EINVAL.
+ */
+int deviced_call_predef_action(const char *type, int num, ...);
+
+/**
+ * @fn int deviced_inform_foregrd(void)
+ * @brief This API call notifies that current process is running in foreground.
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_inform_foregrd(void);
+
+/**
+ * @fn int deviced_inform_backgrd(void)
+ * @brief This API call notifies that current process is running in background.
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_inform_backgrd(void);
+
+/**
+ * @fn int deviced_inform_active(pid_t pid)
+ * @brief This API call notifies deviced daemon that given process (pid) is active.
+ * @param[in] pid process pid
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_inform_active(pid_t pid);
+
+/**
+ * @fn int deviced_inform_active(pid_t pid)
+ * @brief This API call notifies deviced daemon that given process (pid) is inactive.
+ * @param[in] pid process pid
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_inform_inactive(pid_t pid);
+
+/**
+ * @fn int deviced_request_poweroff(void)
+ * @brief This API call requests deviced daemon to launch "system poweroff popup".
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_request_poweroff(void);
+
+/**
+ * @fn deviced_request_entersleep(void)
+ * @brief This API call requests deviced daemon to enter system into sleep mode.
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_request_entersleep(void);
+
+/**
+ * @fn int deviced_request_leavesleep(void)
+ * @brief This API calls requests deviced daemon to leave by system "sleep" mode and enter into "normal" mode.
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_request_leavesleep(void);
+
+/**
+ * @fn int deviced_request_reboot(void)
+ * @brief This API call requests deviced daemon to initiate system reboot.
+ * @return 0 on success and negative value if failed.
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_request_reboot(void);
+
+/**
+ * @fn int deviced_request_set_cpu_max_frequency(int val)
+ * @brief This API call requests deviced daemon to set maximum CPU frequency.
+ * @param[in] val maximum CPU frequency to be set.
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG - dbus error (in case of any error on the bus)
+ */
+int deviced_request_set_cpu_max_frequency(int val);
+
+/**
+ * @fn int deviced_request_set_cpu_min_frequency(int val)
+ * @brief This API call requests deviced daemon to set minimum CPU frequency.
+ * @param[in] val minimum CPU frequency to be set
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ */
+int deviced_request_set_cpu_min_frequency(int val);
+
+/**
+ * @fn int deviced_release_cpu_max_frequency(void)
+ * @brief This API call releases limit of maximum CPU frequency set by deviced_request_set_cpu_max_frequency() API.
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ */
+int deviced_release_cpu_max_frequency(void);
+
+/**
+ * @fn int deviced_release_cpu_min_frequency(void)
+ * @brief This API calls releases limit of minimum CPU frequency set by deviced_request_set_cpu_min_frequency() API.
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ */
+int deviced_release_cpu_min_frequency(void);
+
+/**
+ * @fn int deviced_request_set_factory_mode(int val)
+ * @brief This API call requests systemd daemon to enter system into factory mode.
+ * @param[in] val factory mode level.\n
+ *        0 - "off" factory mode\n
+ *        1 - "on" factory mode.
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ * @retval -EINVAL no mandatory parameters
+ * @retval -ESRCH incorrect sender process id
+ */
+int deviced_request_set_factory_mode(int val);
+
+/**
+ * @fn int deviced_request_dump_log(int type)
+ * @brief This API call force dumps all application, modem or application + modem logs.
+ *   - if type is equal AP_DUMP application log dump will be created.
+ *   - if type is equal CP_DUMP modem logs dump  will be created
+ *   - if dump type is equal ALL_DUMP application and modem logs dump  will be created
+ * @param[in] type dump type.
+ * @return 0 or positive value on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ * @see dump_log_type
+ */
+int deviced_request_dump_log(int type);
+
+/**
+ * @fn int deviced_request_delete_dump(char *ticket)
+ * @brief This API call removes all dump data for given ticket from /opt/usr/share/crash/ticket directory.
+ * @param[in] ticket ticket name.
+ * @return 1 on success and negative value if failed.
+ * @retval -1 operation error
+ * @retval -EBADMSG dbus error (in case of any error on the bus)
+ */
+int deviced_request_delete_dump(char *ticket);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif                         /* __DD_DEVICED__ */
diff --git a/src/deviced/dd-display.h b/src/deviced/dd-display.h
new file mode 100644 (file)
index 0000000..5d98391
--- /dev/null
@@ -0,0 +1,620 @@
+/*
+ * 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_DISPLAY_H__
+#define __DD_DISPLAY_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file        dd-display.h
+ * @defgroup    CAPI_SYSTEM_DEVICED_DISPLAY_MODULE Display
+ * @ingroup     CAPI_SYSTEM_DEVICED
+ * @brief       This file provides the API for control of display
+ * @section CAPI_SYSTEM_DEVICED_DISPLAY_MODULE_HEADER Required Header
+ *   \#include <dd-display.h>
+ */
+
+/**
+ * @addtogroup CAPI_SYSTEM_DEVICED_DISPLAY_MODULE
+ * @{
+ */
+
+#include "dd-common.h"
+
+/**
+ * LCD state
+ */
+#define LCD_NORMAL     0x1     /**< NORMAL state */
+#define LCD_DIM                0x2     /**< LCD dimming state */
+#define LCD_OFF                0x4     /**< LCD off state */
+#define SUSPEND                0x8     /**< Sleep state */
+#define POWER_OFF      0x16    /**< Sleep state */
+#define SETALL (LCD_DIM | LCD_OFF | LCD_NORMAL)        /*< select all state - not supported yet */
+
+/**
+ * Parameters for display_lock_state()
+ */
+#define STAY_CUR_STATE 0x1
+#define GOTO_STATE_NOW 0x2
+#define HOLD_KEY_BLOCK 0x4
+#define STANDBY_MODE   0x8
+
+/**
+ * Parameters for display_unlock_state()
+ */
+#define PM_SLEEP_MARGIN        0x0     /**< keep guard time for unlock */
+#define PM_RESET_TIMER 0x1     /**< reset timer for unlock */
+#define PM_KEEP_TIMER  0x2     /**< keep timer for unlock */
+
+/**
+ * @brief enhance - info, mode, scenario, tone, outdoor
+ */
+enum image_enhance_type {
+       ENHANCE_MODE = 0,
+       ENHANCE_SCENARIO,
+       ENHANCE_TONE,
+       ENHANCE_OUTDOOR,
+};
+
+/**
+ * @brief mode - dynamic, standard, natural, movie
+ */
+enum image_enhance_mode {
+       MODE_DYNAMIC = 0,
+       MODE_STANDARD,
+       MODE_NATURAL,
+       MODE_MOVIE,
+};
+
+/**
+ * @brief scenario - ui, gallery, video, vtcall, camera,
+ *     browser, negative, bypass
+ */
+enum image_enhance_scenario {
+       SCENARIO_UI = 0,
+       SCENARIO_GALLERY,
+       SCENARIO_VIDEO,
+       SCENARIO_VTCALL,
+       SCENARIO_CAMERA,
+       SCENARIO_BROWSER,
+       SCENARIO_NEGATIVE,
+       SCENARIO_BYPASS,
+};
+
+/**
+ * @brief tone - normal, warm, cold
+ */
+enum image_enhance_tone {
+       TONE_NORMAL = 0,
+       TONE_WARM,
+       TONE_COLD,
+};
+
+/**
+ * @brief outdoor - off, on
+ */
+enum image_enhance_outdoor {
+       OUTDOOR_OFF = 0,
+       OUTDOOR_ON,
+};
+
+/**
+ * @brief auto tone - off, on
+ */
+enum auto_screen_tone {
+       TONE_OFF = 0,
+       TONE_ON,
+};
+/**
+ * @par Description:
+ * @todo
+ */
+struct blind_color_info {
+    unsigned int RrCr;
+    unsigned int RgCg;
+    unsigned int RbCb;
+    unsigned int GrMr;
+    unsigned int GgMg;
+    unsigned int GbMb;
+    unsigned int BrYr;
+    unsigned int BgYg;
+    unsigned int BbYb;
+};
+
+/**
+ * @brief This API is used to get number of displays on the phone.\n
+ * @details It returns enum value which is the current number on success.\n
+ *     Or a negative value(-1) is returned on failure.
+ * @return 0 on success, -1 if failed
+ * @par Example
+ * @code
+ *  ...
+ *  ret = display_get_count();
+ *  if( ret < 0 )
+ *      printf("Fail to get number of displays\n");
+ *  ...
+ * @endcode
+ */
+int display_get_count(void);
+
+/**
+ * @brief This API is used to get the max brightness of the display.\n
+ * @details It gets the current brightness of the display
+ *     by calling device_get_property() function.\n
+ *     It returns integer value which is the max brightness on success.\n
+ *     Or a negative value(-1) is returned on failure
+ * @return max brightness value on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  int max_brt;
+ *  max_brt = display_get_max_brightness();
+ *  if( max_brt < 0 )
+ *      printf("Fail to get the max brightness of the display.\n");
+ *  else
+ *      printf("Max brightness of the display is %d\n", max_brt);
+ *  ...
+ * @endcode
+ */
+int display_get_max_brightness(void);
+
+/**
+ * @brief This API is used to get the min brightness of the display.\n
+ * @details It gets the current brightness of the display
+ *     by calling device_get_property() function.\n
+ *     It returns integer value which is the min brightness on success.\n
+ *     Or a negative value(-1) is returned on failure
+ * @return min brightness value on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  int min_brt;
+ *  min_brt = display_get_min_brightness();
+ *  if( min_brt < 0 )
+ *      printf("Fail to get the min brightness of the display.\n");
+ *  else
+ *      printf("Min brightness of the display is %d\n", min_brt);
+ *  ...
+ * @endcode
+ */
+int display_get_min_brightness(void);
+
+/**
+ * @brief This API is used to get the current brightness of the display.\n
+ * @details It gets the current brightness of the display
+ *     by calling device_get_property() function.\n
+ *     It returns integer value which is the current brightness on success.\n
+ *     Or a negative value(-1) is returned on failure.
+ * @return current brightness value on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  int cur_brt;
+ *  cur_brt = display_get_brightness();
+ *  if( cur_brt < 0 )
+ *      printf("Fail to get the current brightness of the display.\n");
+ *  else
+ *      printf("Current brightness of the display is %d\n", cur_brt);
+ *  ...
+ * @endcode
+ */
+int display_get_brightness(void);
+
+/**
+ * @brief This API is used to set the current brightness of the display
+ *     and system brightness value in settings.\n
+ * @details It sets the current brightness of the display
+ *     by calling device_set_property() function.\n
+ *     MUST use this API very carefully. \n
+ *     This api is different from display_set_brightness api.\n
+ *     display_set_brightness api will change only device brightness value.\n
+ *     but this api will change device brightness
+ *     as well as system brightness value.\n
+ * @param[in] val brightness value that you want to set
+ * @return 0 on success, negative if failed
+ * @see display_set_brightness()
+ * @par Example
+ * @code
+ *  ...
+ *  if( display_set_brightness_with_setting(6) < 0 )
+ *      printf("Fail to set the current brightness of the display\n");
+ *  else
+ *      printf("The current brightness of the display is set 6\n");
+ *  ...
+ * @endcode
+ */
+int display_set_brightness_with_setting(int val);
+
+/**
+ * @brief This API is used to set the current brightness of the display.\n
+ * @details It sets the current brightness of the display
+ *     by calling device_set_property() function.\n
+ *     MUST use this API very carefully. \n
+ *     you MUST set original brightness by display_release_brightness(),
+ *     after you finish your job using this API.
+ * @param[in] val brightness value that you want to set
+ * @return 0 on success, negative if failed
+ * @see display_get_brightness(), display_release_brightness()
+ * @par Example
+ * @code
+ *  ...
+ *  if( display_set_brightness(6) < 0 )
+ *      printf("Fail to set the current brightness of the display\n");
+ *  else
+ *      printf("The current brightness of the display is set 6\n");
+ *  ...
+ * @endcode
+ */
+int display_set_brightness(int val);
+
+/**
+ * @brief This API is used to release brightness control.\n
+ * @details It sets the current brightness of the display
+ *     by calling device_set_property() function.\n
+ *     MUST call this API after you finished the job
+ *     which need to change the brightness.
+ * @return 0 on success, negative if failed
+ * @see display_set_brightness()
+ * @par Example
+ * @code
+ *  ...
+ *  org_val = display_get_brightness();
+ *  display_set_brightness(1);
+ *  ...
+ *  ret = display_release_brightness();
+ *  if( ret < 0 )
+ *      printf("Fail to release brightness control\n");
+ *  ...
+ * @endcode
+ */
+int display_release_brightness(void);
+
+/**
+ * @brief This API is used to get the current state for acl.\n
+ * @details It gets the current state for acl
+ *     by calling device_get_property() function.\n
+ * @return current status for acl(1 on, 0 off) on success, negative if failed
+ * @see display_set_acl_status()
+ * @par Example
+ * @code
+ *  ...
+ *  int acl_stat;
+ *  acl_stat = display_get_acl_status();
+ *  if( acl_stat < 0 )
+ *      printf("Fail to get the current status for acl.\n");
+ *  else
+ *      printf("Current status for acl is %d\n", cur_brt);
+ *  ...
+ * @endcode
+ */
+int display_get_acl_status(void);
+
+/**
+ * @brief This API is used to set the current status for acl.\n
+ * @details It sets the current status for acl
+ *     by calling device_set_property() function.\n
+ * @param[in] val status for acl(1 on, 0 off) that you want to set
+ * @return 0 on success, negative if failed
+ * @see display_get_acl_status()
+ * @par Example
+ * @code
+ *  ...
+ *  if( display_set_acl_status(0) < 0 )
+ *      printf("Fail to set the current status for acl\n");
+ *  else
+ *      printf("The current status for acl is set 6\n");
+ *  ...
+ * @endcode
+ */
+int display_set_acl_status(int val);
+
+/**
+ * @brief This API is used to get enhance mode supported.\n
+ * @return 1 supported, 0 not supporter, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  ret = display_get_image_enhance_info();
+ *  if( ret < 0 )
+ *      printf("Not support image enhance mode on this device\n");
+ *  ...
+ * @endcode
+ */
+int display_get_image_enhance_info(void);
+
+/**
+ * @brief This API is used to get enhance mode state.\n
+ * @param[in] type enhance mode type
+ * @return enum value of type on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  ret = display_get_image_enhance(ENHANCE_MODE);
+ *  if( ret < 0 )
+ *      printf("Fail to get current image enhance\n");
+ *  ...
+ * @endcode
+ */
+int display_get_image_enhance(int type);
+
+/**
+ * @brief This API is used to set enhance mode state.\n
+ * @param[in] type enhance mode type
+ * @param[in] val enum value of enhance mode type
+ * @return 0 on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if( display_set_image_enhance(ENHANCE_MODE, MODE_DYNAMIC) < 0 )
+ *      printf("Fail to set the image enhance mode\n");
+ *  ...
+ * @endcode
+ */
+int display_set_image_enhance(int type, int val);
+
+/**
+ * @brief This API is used to set frame rate of display.\n
+ * @param[in] val frame rate
+ * @return 0 on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if( display_set_frame_rate() < 0 )
+ *      printf("Fail to set display frame rate\n");
+ *  ...
+ * @endcode
+ * @todo describe range of val
+ */
+int display_set_frame_rate(int val) DEPRECATED;
+
+/**
+ * @brief refresh app - setting, video, camera
+ */
+enum refresh_app {
+       REFRESH_SETTING,
+       REFRESH_VIDEO,
+       REFRESH_CAMERA,
+       REFRESH_WEB,
+};
+
+/**
+ * @brief This API is used to set refresh rate of display.\n
+ * @param[in] app caller application type
+ * @param[in] val refresh rate
+ * @return 0 on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if( display_set_refresh_rate(REFRESH_SETTING, 60) < 0 )
+ *      printf("Fail to set display refresh rate\n");
+ *  ...
+ * @endcode
+ * @todo describe range of val
+ */
+int display_set_refresh_rate(enum refresh_app app, int val);
+
+/**
+ * @brief This API is used to lock a particular display state
+ *     as the current display-state.\n
+ * @details The parameter state specifies the display state which
+ *     you want to lock LCD_NORMAL, LCD_DIM, LCD_OFF. \n
+ *     The second parameter Flag is set if you want to go
+ *     the requested lock state directly.\n
+ *     The third parameter timeout specifies lock-timeout in milliseconds.
+ *     If the value 0 is selected, the display state remains locked
+ *     until display_unlock_state is called.
+ * @param[in] state target power state which you want to lock
+ *     - LCD_NORMAL, LCD_DIM, LCD_OFF
+ * @param[in] flag set if you want to go the lock state directly \n
+ *     GOTO_STATE_NOW - State is changed directly you want to lock.\n
+ *     STAY_CUR_STATE - State is not changed directly and
+ *     phone stay current state until timeout expired.\n
+ *     HOLD_KEY_BLOCK - Hold key is blocked during locking
+ *     LCD_NORMAL or LCD_DIM. \n
+ *     Then LCD state transition to LCD_OFF is blocked. \n
+ *     If this flag is not set, phone state is lcd off
+ *     after pressing hold key. \n
+ *     GOTO_STATE_NOW and STAY_CUR_STATE can't be applied at the same time.
+ * @param[in] timeout lock-timeout in miliseconds. \n
+ *     0 is always lock until calling display_unlock_state
+ * @return 0 on success, negative if failed
+ * @see display_unlock_state(), display_change_state()
+ * @par Example
+ * @code
+ *  ...
+ *  result = pm_lock_state(LCD_NORMAL, GOTO_STATE_NOW, SET_TIMEOUT);
+ *  if( result < 0 )
+ *      printf("[ERROR] return value result =%d, \n",result);
+ *  else
+ *      printf("[SUCCESS]return value result =%d \n",result);
+ *  ...
+ * @endcode
+ */
+int display_lock_state(unsigned int state, unsigned int flag, unsigned int timeout);
+
+/**
+ * @brief This API is used to unlock the display state. \n
+ * @details The parameter state specifies the display
+ *     state which you want to unlock. \n
+ *     Some examples are LCD_NORMAL, LCD_DIM, LCD_OFF.
+ * @param[in] state target display state which you want to unlock
+ * @param[in] flag set timer which is going to the next state after unlocking\n
+ *     PM_SLEEP_MARGIN - If the current status is lcd off,
+ *     deviced reset timer to 1 second.
+ *     If the current status is not lcd off, deviced uses the existing timer.\n
+ *     PM_RESET_TIMER - deviced resets timer.
+ *     (lcd normal : reset timer to predfined value
+ *     which is set in setting module,
+ *     lcd dim : reset timer to 5 seconds, lcd off : reset timer to 1 seconds)\n
+ *     PM_KEEP_TIMER - deviced uses the existing timer
+ *     (if timer is already expired, deviced changes the status) \n
+ * @return 0 on success, negative if failed
+ * @see display_lock_state(), display_change_state()
+ * @par Example
+ * @code
+ *  ...
+ *  result = display_unlock_state(LCD_NORMAL,PM_RESET_TIMER);
+ *  if( result < 0 )
+ *      printf("[ERROR] return value result =%d, \n",result);
+ *  else
+ *      printf("[SUCCESS]return value result =%d \n",result);
+ *  ...
+ * @endcode
+ */
+int display_unlock_state(unsigned int state, unsigned int flag);
+
+/**
+ * @brief This API is used to change display state by force.
+ * @param[in] state display state - LCD_NORMAL, LCD_DIM, LCD_OFF
+ * @return 0 on success, negative if failed.
+ * @see display_lock_state(), display_unlock_state()
+ * @par Example
+ * @code
+ *  ...
+ *  result = display_change_state(LCD_OFF);
+ *  if( result < 0 )
+ *      printf("[ERROR] return value result =%d, \n",result);
+ *  else
+ *      printf("[SUCCESS]return value result =%d \n",result);
+ *  ...
+ * @endcode
+ */
+int display_change_state(unsigned int state);
+
+/**
+ * @brief This API is used to get auto screen tone.\n
+ * @return enum value for current tone on success, negative if failed
+ * @see display_set_auto_screen_tone()
+ * @par Example
+ * @code
+ *  ...
+ *  result = display_get_auto_screen_tone();
+ *  if( result == 0 )
+ *      printf("Display auto screen ton OFF\n");
+ *  else if ( result == 1 )
+ *      printf("Display auto screen ton ON\n");
+ *  ...
+ * @endcode
+ */
+int display_get_auto_screen_tone(void);
+
+/**
+ * @brief This API is used to set auto screen tone.\n
+ * @return 0 on success, negative if failed
+ * @see display_get_auto_screen_tone()
+ * @par Example
+ * @code
+ *  ...
+ *  result = display_set_auto_screen_tone(TONE_OFF);
+ *  if( result < 0 )
+ *      printf("[ERROR] return value result =%d, \n",result);
+ *  else
+ *      printf("[SUCCESS] return value result =%d, \n",result);
+ *  ...
+ * @endcode
+ */
+int display_set_auto_screen_tone(int type);
+
+/**
+ * @brief This API is used to get color blind value.\n
+ * @return blind value on success, negative if failed
+ * @see display_set_color_blind()
+ * @par Example
+ * @code
+ *  ...
+ *  result = display_get_color_blind();
+ *  if( result < 0 )
+ *      printf("[ERROR] return value result =%d, \n",result);
+ *  else
+ *      printf("[SUCCESS] return value result =%d, \n",result);
+ *  ...
+ * @endcode
+ */
+int display_get_color_blind(void);
+
+/**
+ * @brief This API is used to set color blind value.\n
+ * @param[in] enable color blind on/off
+ * @param[in] info blind color info
+ * @return 0 on success, negative if failed
+ * @see display_set_color_blind()
+ * @par Example
+ * @code
+ *  ...
+ *  result = display_set_color_blind(1, info);
+ *  if( result < 0 )
+ *      printf("[ERROR] return value result =%d, \n",result);
+ *  else
+ *      printf("[SUCCESS] return value result =%d, \n",result);
+ *  ...
+ * @endcode
+ * @todo describe blind_color_info
+ */
+int display_set_color_blind(int enable, struct blind_color_info *info);
+
+/**
+ * @brief Gets touch sensitivity mode
+ * @return 0 on success, otherwise negative error value
+ * @see display_set_enhanced_touch()
+ */
+int display_get_enhanced_touch(void);
+
+/**
+ * @brief Sets touch sensitivity mode
+ * @param[in] enable 1 on enable, 0 on disable
+ * @return 0 on success, otherwise negative error value
+ * @see display_get_enhanced_touch()
+ */
+int display_set_enhanced_touch(int enable);
+
+/**
+ * @brief Gets HBM(High Brightness Mode) state
+ * @return 0 or 1 on success, otherwise negative error value
+ * @see display_set_hbm
+ */
+int display_get_hbm(void);
+
+/**
+ * @brief Sets HBM(High Brightness Mode) state
+ * @param[in] enable 1 on enable, 0 on disable
+ * @return 0 on success, otherwise negative error value
+ * @see display_get_hbm()
+ */
+int display_set_hbm(int enable);
+
+/**
+ * @brief Sets HBM(High Brightness Mode) state
+ * @param[in] enable 1 on enable, 0 on disable
+ * @param[in] timeout (second)
+ * @return 0 on success, otherwise negative error value
+ * @see display_get_hbm()
+ */
+int display_enable_hbm(int enable, int timeout);
+
+/**
+ * @} // end of CAPI_SYSTEM_DEVICED_DISPLAY_MODULE
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/deviced/dd-haptic.h b/src/deviced/dd-haptic.h
new file mode 100644 (file)
index 0000000..02b3364
--- /dev/null
@@ -0,0 +1,654 @@
+/*
+ * 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_HAPTIC_H__
+#define __DD_HAPTIC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file        dd-haptic.h
+ * @defgroup    CAPI_SYSTEM_DEVICED_HAPTIC_MODULE Haptic
+ * @ingroup     CAPI_SYSTEM_DEVICED
+ * @brief       This file provides the API for control of haptic
+ * @section CAPI_SYSTEM_DEVICED_HAPTI_MODULE_HEADER Required Header
+ *   \#include <dd-haptic.h>
+ */
+
+/**
+ * @addtogroup CAPI_SYSTEM_DEVICED_HAPTIC_MODULE
+ * @{
+ */
+
+/**
+ * @brief The handle of haptic device
+ */
+typedef void* haptic_device_h;
+
+/**
+ * @brief The handle of haptic effect
+ */
+typedef void* haptic_effect_h;
+
+/**
+ * @brief Enumerations of device id for the Haptic API.
+ * @details We support two motors now.
+ */
+typedef enum {
+       HAPTIC_DEVICE_0 = 0x0,                  /**< 1st motor */
+       HAPTIC_DEVICE_1 = 0x1,                  /**< 2nd motor */
+       HAPTIC_DEVICE_ALL = 0x4,                /**< both of them */
+} haptic_device_e;
+
+/**
+ * @brief Enumerations of priority level for the Haptic API.
+ */
+typedef enum
+{
+       HAPTIC_PRIORITY_MIN = 0,                /**< Minimum effect priority for developers (default) */
+       HAPTIC_PRIORITY_MIDDLE,                 /**< Maximum effect priority for developers */
+       HAPTIC_PRIORITY_HIGH,                   /**< Maximum effect priority for OEMs */
+} haptic_priority_e;
+
+/**
+ * @brief Enumerations of feedback level for the Haptic API.
+ * @details Haptic level means vibration power (intensity).
+ */
+typedef enum
+{
+       HAPTIC_FEEDBACK_0 = 0,                          /**< feedback level 0 */
+       HAPTIC_FEEDBACK_1 = 20,                         /**< feedback level 1 */
+       HAPTIC_FEEDBACK_2 = 40,                         /**< feedback level 2 */
+       HAPTIC_FEEDBACK_3 = 60,                         /**< feedback level 3 */
+       HAPTIC_FEEDBACK_4 = 80,                         /**< feedback level 4 */
+       HAPTIC_FEEDBACK_5 = 100,                        /**< feedback level 5 */
+       HAPTIC_FEEDBACK_AUTO,                           /**< feedback level auto */
+} haptic_feedback_e;
+
+/**
+ * @brief Enumerations of unlimited duration for the Haptic API.
+ */
+typedef enum {
+       HAPTIC_DURATION_UNLIMITED = 0xFFFFFFFF,
+} haptic_duration_e;
+
+/**
+ * @brief Enumerations of iteration count for the Haptic API.
+ */
+typedef enum
+{
+       HAPTIC_ITERATION_ONCE = 1,
+       HAPTIC_ITERATION_INFINITE = 256,
+} haptic_iteration_e;
+
+/**
+ * @brief Enumerations of effect or device state for the Haptic API.
+ */
+typedef enum
+{
+       HAPTIC_STATE_STOP = 0,
+       HAPTIC_STATE_PLAYING,
+} haptic_state_e;
+
+/**
+ * @brief Enumerations of error codes for the Haptic API.
+ */
+typedef enum
+{
+       HAPTIC_ERROR_NONE                 = 0, //TIZEN_ERROR_NONE,                      /**< Successful */
+       HAPTIC_ERROR_INVALID_PARAMETER    = -1, //TIZEN_ERROR_INVALID_PARAMETER,        /**< Invalid parameter */
+       HAPTIC_ERROR_FILE_EXISTS          = -2, //TIZEN_ERROR_FILE_EXISTS,              /**< File exists */
+       HAPTIC_ERROR_NOT_INITIALIZED      = -3, //TIZEN_ERROR_SYSTEM_CLASS | 0x26,      /**< Not initialized */
+       HAPTIC_ERROR_OPERATION_FAILED     = -4, //TIZEN_ERROR_SYSTEM_CLASS | 0x28,      /**< Operation failed */
+       HAPTIC_ERROR_NOT_SUPPORTED_DEVICE = -5, //TIZEN_ERROR_SYSTEM_CLASS | 0x30,      /**< Not supported device */
+} haptic_error_e;
+
+/**
+ * @brief Gets the number of the vibrators.
+ *
+ * @remarks The index HAPTIC_DEVICE_ALL is reserved meaning for all vibrators at a time.
+ *
+ * @param[in] device_number A number of vibrators
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                   Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ */
+int haptic_get_count(int *device_number);
+
+/**
+ * @brief Opens a haptic-vibration device.
+ *
+ * @details Internally, it makes a connection to the vibrator.
+ *
+ * @remarks If this function is not called in advance, other functions will return #HAPTIC_ERROR_NOT_INITIALIZED.
+ * @remarks Haptic API must be closed by haptic_close().
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_close()
+ */
+int haptic_open(haptic_device_e device, haptic_device_h *device_handle);
+
+/**
+ * @brief Closes a haptic-vibration device.
+ *
+ * @details Internally, it disconnects the connection to vibrator.
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_open()
+ */
+int haptic_close(haptic_device_h device_handle);
+
+/**
+ * @brief Vibrates during the specified time with a constant intensity.
+ * @details
+ * This function can be used to start monotonous vibration for specified time.
+ *
+ * @remark
+ * If you don't use th api regarding effect_handle, you can pass in a NULL value to last parameter.\n
+ * And default value of feedback and priority is used.\n
+ * feedback level is reserved for auto chaning to save variable in the settings.\n
+ * priority level uses HAPTIC_PRIORITY_MIN.
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] duration         The play duration in milliseconds
+ * @param[out] effect_handle   Pointer to the variable that will receive a handle to the playing effect
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_vibrate_monotone_with_detail()
+ * @see haptic_vibrate_file()
+ * @see haptic_vibrate_buffer()
+ * @see haptic_get_count()
+ */
+int haptic_vibrate_monotone(haptic_device_h device_handle, int duration, haptic_effect_h *effect_handle);
+
+/**
+ * @brief Vibrates during the specified time with a constant intensity.
+ * @details
+ * This function can be used to start monotonous vibration for specified time.
+ *
+ * @remark
+ * If you don't use th api regarding effect_handle, you can pass in a NULL value to last parameter.
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] duration         The play duration in milliseconds
+ * @param[in] feedback         The amount of the intensity variation
+ * @param[in] priority         The priority from HAPTIC_PRIORITY_MIN to HAPTIC_PRIORITY_HIGH
+ * @param[out] effect_handle   Pointer to the variable that will receive a handle to the playing effect
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_vibrate_monotone()
+ * @see haptic_vibrate_file_with_detail()
+ * @see haptic_vibrate_buffer_with_detail()
+ * @see haptic_get_count()
+ */
+int haptic_vibrate_monotone_with_detail(haptic_device_h device_handle,
+                                                                               int duration,
+                                                                               haptic_feedback_e feedback,
+                                                                               haptic_priority_e priority,
+                                                                               haptic_effect_h *effect_handle);
+
+/**
+ * @brief Vibrates a predefined rhythmic haptic-vibration pattern file.
+ * @details
+ * This function can be used to play a haptic-vibration pattern file.
+ *
+ * @remark
+ * If you don't use th api regarding effect_handle, you can pass in a NULL value to last parameter.\n
+ * And default value of feedback and priority is used.\n
+ * feedback level is reserved for auto chaning to save variable in the settings.\n
+ * priority level uses HAPTIC_PRIORITY_MIN.
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] file_path        Vibration pattern file with path
+ * @param[out] effect_handle   Pointer to the variable that will receive a handle to the playing effect
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_vibrate_file_with_detail()
+ * @see haptic_vibrate_monotone()
+ * @see haptic_vibrate_buffer()
+ * @see haptic_get_count()
+ */
+int haptic_vibrate_file(haptic_device_h device_handle, const char *file_path, haptic_effect_h *effect_handle);
+
+/**
+ * @brief Vibrates a predefined rhythmic haptic-vibration pattern file.
+ * @details
+ * This function can be used to play a haptic-vibration pattern file.
+ *
+ * @remark
+ * If you don't use th api regarding effect_handle, you can pass in a NULL value to last parameter.
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] file_path        Vibration pattern file with path
+ * @param[in] iteration        The number of times to repeat the effect
+ * @param[in] feedback         The amount of the intensity variation
+ * @param[in] priority         The priority from HAPTIC_PRIORITY_MIN to HAPTIC_PRIORITY_HIGH
+ * @param[out] effect_handle   Pointer to the variable that will receive a handle to the playing effect
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_vibrate_file()
+ * @see haptic_vibrate_monotone_with_detail()
+ * @see haptic_vibrate_buffer_with_detail()
+ * @see haptic_get_count()
+ */
+int haptic_vibrate_file_with_detail(haptic_device_h device_handle,
+                                                                       const char *file_path,
+                                                                       haptic_iteration_e iteration,
+                                                                       haptic_feedback_e feedback,
+                                                                       haptic_priority_e priority,
+                                                                       haptic_effect_h *effect_handle);
+
+/**
+ * @brief Vibrates a predefined rhythmic haptic-vibration pattern buffer.
+ * @details
+ * This function can be used to play a haptic-vibration pattern buffer.
+ *
+ * @remark
+ * If you don't use th api regarding effect_handle, you can pass in a NULL value to last parameter.\n
+ * And default value of feedback and priority is used.\n
+ * feedback level is reserved for auto chaning to save variable in the settings.\n
+ * priority level uses HAPTIC_PRIORITY_MIN.
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] vibe_buffer              Pointer to the vibration pattern
+ * @param[out] effect_handle   Pointer to the variable that will receive a handle to the playing effect
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_vibrate_buffer_with_detail()
+ * @see haptic_vibrate_monotone()
+ * @see haptic_vibrate_file()
+ * @see haptic_get_count()
+ */
+int haptic_vibrate_buffer(haptic_device_h device_handle, const unsigned char *vibe_buffer, haptic_effect_h *effect_handle);
+
+/**
+ * @brief Vibrates a predefined rhythmic haptic-vibration pattern buffer.
+ * @details
+ * This function can be used to play a haptic-vibration pattern buffer.
+ *
+ * @remark
+ * If you don't use th api regarding effect_handle, you can pass in a NULL value to last parameter.
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] vibe_buffer      Pointer to the vibration pattern
+ * @param[in] iteration        The number of times to repeat the effect
+ * @param[in] feedback         The amount of the intensity variation
+ * @param[in] priority         The priority from HAPTIC_PRIORITY_MIN to HAPTIC_PRIORITY_HIGH
+ * @param[out] effect_handle   Pointer to the variable that will receive a handle to the playing effect
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_vibrate_buffer()
+ * @see haptic_vibrate_monotone_with_detail()
+ * @see haptic_vibrate_file_with_detail()
+ * @see haptic_get_count()
+ */
+int haptic_vibrate_buffer_with_detail(haptic_device_h device_handle,
+                                                                         const unsigned char *vibe_buffer,
+                                                                         haptic_iteration_e iteration,
+                                                                         haptic_feedback_e feedback,
+                                                                         haptic_priority_e priority,
+                                                                         haptic_effect_h *effect_handle);
+
+/**
+ * @brief Vibrates a predefined rhythmic haptic-vibration pattern buffer.
+ * @details
+ * This function can be used to play a haptic-vibration pattern buffer.
+ *
+ * @remark
+ * If you don't use th api regarding effect_handle, you can pass in a NULL value to last parameter.\n
+ * And default value of feedback and priority is used.\n
+ * feedback level is reserved for auto chaning to save variable in the settings.\n
+ * priority level uses HAPTIC_PRIORITY_MIN.
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] vibe_buffer              Pointer to the vibration pattern
+ * @param[in] size                     Size to the vibration pattern
+ * @param[out] effect_handle   Pointer to the variable that will receive a handle to the playing effect
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_vibrate_buffer_with_detail()
+ * @see haptic_vibrate_monotone()
+ * @see haptic_vibrate_file()
+ * @see haptic_get_count()
+ */
+int haptic_vibrate_buffers(haptic_device_h device_handle,
+                                                       const unsigned char *vibe_buffer,
+                                                       int size,
+                                                       haptic_effect_h *effect_handle);
+
+/**
+ * @brief Vibrates a predefined rhythmic haptic-vibration pattern buffer.
+ * @details
+ * This function can be used to play a haptic-vibration pattern buffer.
+ *
+ * @remark
+ * If you don't use th api regarding effect_handle, you can pass in a NULL value to last parameter.
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] vibe_buffer      Pointer to the vibration pattern
+ * @param[in] size              Size to the vibration pattern
+ * @param[in] iteration        The number of times to repeat the effect
+ * @param[in] feedback         The amount of the intensity variation
+ * @param[in] priority         The priority from HAPTIC_PRIORITY_MIN to HAPTIC_PRIORITY_HIGH
+ * @param[out] effect_handle   Pointer to the variable that will receive a handle to the playing effect
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_vibrate_buffer()
+ * @see haptic_vibrate_monotone_with_detail()
+ * @see haptic_vibrate_file_with_detail()
+ * @see haptic_get_count()
+ */
+int haptic_vibrate_buffers_with_detail(haptic_device_h device_handle,
+                                      const unsigned char *vibe_buffer,
+                                                                         int size,
+                                      haptic_iteration_e iteration,
+                                      haptic_feedback_e feedback,
+                                      haptic_priority_e priority,
+                                      haptic_effect_h *effect_handle);
+
+/**
+ * @brief Stops the current vibration effect which is being played.
+ * @details This function can be used to stop each effect started by haptic_vibrate_xxx().
+ *
+ * @remark
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] effect_handle    The effect handle from haptic_vibrate_xxx()
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_vibrate_buffer()
+ * @see haptic_vibrate_monotone()
+ * @see haptic_vibrate_file()
+ * @see haptic_get_count()
+ * @see haptic_stop_all_effects()
+ */
+int haptic_stop_effect(haptic_device_h device_handle, haptic_effect_h effect_handle);
+
+/**
+ * @brief Stops all vibration effects which are being played.
+ * @details This function can be used to stop all effects started by haptic_vibrate_xxx().
+ *
+ * @remark
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_vibrate_buffer()
+ * @see haptic_vibrate_monotone()
+ * @see haptic_vibrate_file()
+ * @see haptic_get_count()
+ * @see haptic_stop_effect()
+ */
+int haptic_stop_all_effects(haptic_device_h device_handle);
+
+/**
+ * @brief Gets the status of the effect.
+ * @details This function can be used to get the status of the effect wheter the effect are playing or not.
+ *
+ * @remark
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] effect_handle    The effect handle from haptic_vibrate_xxx()
+ * @param[out] state           The pointer to variable that will receive the status of the effect.
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_vibrate_buffer()
+ * @see haptic_vibrate_monotone()
+ * @see haptic_vibrate_file()
+ * @see haptic_get_count()
+ * @see haptic_stop_effect()
+ * @see haptic_stop_all_effects()
+ */
+int haptic_get_effect_state(haptic_device_h device_handle, haptic_effect_h effect_handle, haptic_state_e *state);
+
+/**
+ * @par Description:
+ *      effect element for haptic.
+ */
+typedef struct {
+       int haptic_duration;    /**< Start time of the effect element in millisecond */
+       int haptic_level;       /**< Duration of the effect element in millisecond */
+} haptic_effect_element_s;
+
+/**
+ * @brief Creates an effect buffer.
+ * @details This function can be used to create an effect buffer using effeclt_element variable.
+ *
+ * @remark
+ *
+ * @param[out] vibe_buffer     Pointer to the vibration pattern
+ * @param[in] max_bufsize              The size of the buffer pointed to by vibe_buffer
+ * @param[in] elem_arr                 Pointer to an haptic_effect_element_s structure
+ * @param[in] max_elemcnt              The size fo the buffer pointed to by elem_arr
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_save_effect()
+ */
+int haptic_create_effect(unsigned char *vibe_buffer,
+                                                int max_bufsize,
+                                                haptic_effect_element_s *elem_arr,
+                                                int max_elemcnt);
+
+/**
+ * @brief Save an effect buffer to the file.
+ * @details This function can be used to save an effect buffer to the file using third parameter.
+ *
+ * @remark
+ *
+ * @param[in] vibe_buffer      Pointer to the vibration pattern
+ * @param[in] max_bufsize              The size of the buffer pointed to by vibe_buffer
+ * @param[in] file_path                The pointer to the character buffer containing the path to save
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_FILE_EXISTS           File exists
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_create_effect()
+ */
+int haptic_save_effect(const unsigned char *vibe_buffer,
+                                          int max_bufsize,
+                                          const char *file_path);
+
+/**
+ * @brief Gets a duration time value from file.
+ * @details This function can be used to get a duration time value from the file using second parameter.
+ *
+ * @remark
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] file_path                The pointer to the character buffer containing the path to save
+ * @param[out] duration                The pointer to the duration time value
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_get_buffer_duration()
+ */
+int haptic_get_file_duration(haptic_device_h device_handle, const char *file_path, int *duration);
+
+/**
+ * @brief Gets a duration time value from buffer.
+ * @details This function can be used to get a duration time value from the buffer using second parameter.
+ *
+ * @remark
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] vibe_buffer              Pointer to the vibration pattern buffer
+ * @param[out] duration                The pointer to the duration time value
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_get_file_duration()
+ */
+int haptic_get_buffer_duration(haptic_device_h device_handle, const unsigned char *vibe_buffer, int *duration);
+
+/**
+ * @brief Gets a duration time value from buffer.
+ * @details This function can be used to get a duration time value from the buffer using second parameter.
+ *
+ * @remark
+ *
+ * @param[in] device_handle    The device handle from haptic_open()
+ * @param[in] vibe_buffer              Pointer to the vibration pattern buffer
+ * @param[in] size                     Size to the vibration pattern buffer
+ * @param[out] buffer_duration                 The pointer to the duration time value
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_get_file_duration()
+ */
+int haptic_get_buffers_duration(haptic_device_h device_handle, const unsigned char *vibe_buffer, int size, int *buffer_duration);
+
+/**
+ * @brief Save an effect buffer to the led file.
+ * @details This function can be used to save an effect buffer to the led file which name is third parameter.
+ *
+ * @remark
+ * Third parameter should be compatible with ledplayer file.
+ *
+ * @param[in] vibe_buffer              Pointer to the vibration pattern
+ * @param[in] max_bufsize              The size of the buffer pointed to by vibe_buffer
+ * @param[in] file_path                The pointer to the character buffer containing the path to save
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #HAPTIC_ERROR_NONE                  Successful
+ * @retval #HAPTIC_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval #HAPTIC_ERROR_NOT_INITIALIZED       Not initialized
+ * @retval #HAPTIC_ERROR_FILE_EXISTS           File exists
+ * @retval #HAPTIC_ERROR_OPERATION_FAILED      Operation failed
+ * @retval #HAPTIC_ERROR_NOT_SUPPORTED_DEVICE  Not supported device
+ *
+ * @see haptic_save_effect()
+ */
+int haptic_save_led(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path);
+
+/**
+ * @} end of CAPI_SYSTEM_DEVICED_HAPTIC_MODULE
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/deviced/dd-led.h b/src/deviced/dd-led.h
new file mode 100644 (file)
index 0000000..b00efd6
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * 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_LED_H__
+#define __DD_LED_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+
+/**
+ * @file        dd-led.h
+ * @defgroup    CAPI_SYSTEM_DEVICED_LED_MODULE Led
+ * @ingroup     CAPI_SYSTEM_DEVICED
+ * @brief       This file provides the API for control of led
+ * @section CAPI_SYSTEM_DEVICED_LED_MODULE_HEADER Required Header
+ *   \#include <dd-led.h>
+ */
+
+/**
+ * @addtogroup CAPI_SYSTEM_DEVICED_LED_MODULE
+ * @{
+ */
+
+/**
+ * @par Description
+ * LED mode
+ */
+enum LED_MODE {
+       LED_OFF = 0,
+       LED_LOW_BATTERY,
+       LED_CHARGING,
+       LED_FULLY_CHARGED,
+       LED_CHARGING_ERROR,
+       LED_MISSED_NOTI,
+       LED_VOICE_RECORDING,
+       LED_POWER_OFF,
+       LED_CUSTOM,
+       LED_MODE_MAX,
+};
+
+#define led_set_brightness(val)        \
+               led_set_brightness_with_noti(val, false)
+
+#define led_set_mode(mode, on) \
+               led_set_mode_with_color(mode, on, 0)
+
+/**
+ * @par Description:
+ *  This API is used to get the current brightness of the led.\n
+ *  It gets the current brightness of the led by calling device_get_property() function.\n
+ *  It returns integer value which is the current brightness on success.\n
+ *  Or a negative value(-1) is returned on failure.
+ * @return current brightness value on success, -1 if failed
+ * @see led_set_brightness_with_noti()
+ * @par Example
+ * @code
+ *  ...
+ *  int cur_brt;
+ *  cur_brt = led_get_brightness();
+ *  if( cur_brt < 0 )
+ *      printf("Fail to get the current brightness of the led.\n");
+ *  else
+ *      printf("Current brightness of the led is %d\n", cur_brt);
+ *  ...
+ * @endcode
+ */
+int led_get_brightness(void);
+
+/**
+ * @par Description:
+ *  This API is used to get the max brightness of the led.\n
+ *  It gets the max brightness of the led by calling device_get_property() function.\n
+ *  It returns integer value which is the max brightness on success.\n
+ *  Or a negative value(-1) is returned on failure
+ * @return max brightness value on success, -1 if failed
+ * @par Example
+ * @code
+ *  ...
+ *  int max_brt;
+ *  max_brt = led_get_max_brightness();
+ *  if( max_brt < 0 )
+ *      printf("Fail to get the max brightness of the led.\n");
+ *  ...
+ * @endcode
+ */
+int led_get_max_brightness(void);
+
+/**
+ * @par Description:
+ *  This API is used to set the current brightness of the led.\n
+ *      It sets the current brightness of the led by calling device_set_property() function.\n
+ * @param[in] val brightness value that you want to set
+ * @param[in] enable noti
+ * @return 0 on success, -1 if failed
+ * @see led_get_brightness()
+ * @par Example
+ * @code
+ *  ...
+ *  if( led_set_brightness_with_noti(1, 1) < 0 )
+ *     printf("Fail to set the brightness of the led\n");
+ *  ...
+ * @endcode
+ */
+int led_set_brightness_with_noti(int val, bool enable);
+
+/**
+ * @par Description:
+ *  This API is used to set command of the irled.\n
+ *  It sets the command to control irled by calling device_set_property() function.\n
+ * @param[in] value string that you want to set
+ * @return 0 on success, -1 if failed
+ * @see led_set_brightness_with_noti()
+ * @par Example
+ * @code
+ *  ...
+ *  if( led_set_ir_command(("38000,173,171,24,...,1880") < 0 )
+ *     printf("Fail to set the command of the irled\n");
+ *  ...
+ * @endcode
+ */
+int led_set_ir_command(char *value);
+
+/**
+ * @par Description:
+ *  This API is used to set LED mode with color.\n
+ *  It sets the command to set LED mode by calling device_set_property() function.\n
+ * @param[in] mode LED mode
+ * @param[in] on enable/disable LED
+ * @param[in] color LED color
+ * @return 0 on success, -1 if failed
+ * @see LED_MODE
+ * @par Example
+ * @code
+ *  ...
+ *  if( led_set_mode_with_color(LED_LOW_BATTERY, 1, 0) < 0 )
+ *      printf("Fail to set LED mode with color\n");
+ *  ...
+ * @endcode
+ * @todo describe color
+ */
+int led_set_mode_with_color(int mode, bool on, unsigned int color);
+
+/**
+ * @par Description:
+ *  This API is used to set LED mode with all option such as on/off duty and color.\n
+ *  It sets the command to set LED mode by calling device_set_property() function.\n
+ * @param[in] mode LED mode
+ * @param[in] val enable/disable LED
+ * @param[in] on  duty value (millisecond)
+ * @param[in] off duty value (millisecond)
+ * @param[in] color LED color
+ * @return 0 on success, -1 if failed
+ * @see LED_MODE
+ * @par Example
+ * @code
+ *  ...
+ *  if( led_set_mode_with_property(LED_LOW_BATTERY, true, 500, 5000, 0xFFFF0000) < 0 )
+ *      printf("Fail to set LED mode with color\n");
+ *  ...
+ * @endcode
+ * @todo describe color
+ */
+int led_set_mode_with_property(int mode, bool val, int on, int off, unsigned int color);
+
+/**
+ * @} // end of CAPI_SYSTEM_DEVICED_LED_MODULE
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/deviced/dd-mmc.h b/src/deviced/dd-mmc.h
new file mode 100644 (file)
index 0000000..b387e3e
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * 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
+ * @defgroup    CAPI_SYSTEM_DEVICED_MMC_MODULE MMC
+ * @ingroup     CAPI_SYSTEM_DEVICED
+ * @brief       This file provides the API for control of mmc(sd-card)
+ * @section CAPI_SYSTEM_DEVICED_MMC_MODULE_HEADER Required Header
+ *   \#include <dd-mmc.h>
+ */
+
+/**
+ * @addtogroup CAPI_SYSTEM_DEVICED_MMC_MODULE
+ * @{
+ */
+
+/**
+ * @par Description:
+ *      This API is used to mount mmc.\n
+ * @param[in] mount_point pointer to the character buffer containing the path
+ * @return 0 on success, -1 if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if( mmc_secure_mount(mount_point) < 0 )
+ *      printf("Mount mmc failed\n");
+ *  ...
+ * @endcode
+ */
+int mmc_secure_mount(const char *mount_point);
+
+/**
+ * @par Description:
+ *      This API is used to unmount mmc.\n
+ * @param[in] mount_point pointer to the character buffer containing the path
+ * @return 0 on success, -1 if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if( mmc_secure_unmount(mount_point) < 0 )
+ *      printf("Unmount mmc failed\n");
+ *  ...
+ * @endcode
+ */
+int mmc_secure_unmount(const char *mount_point);
+
+/**
+ * @brief This structure defines the data for receive result of mmc operations(mount/unmount/format)
+ */
+struct mmc_contents {
+       void (*mmc_cb) (int result, void* data);/**< user callback function for receive result of mmc operations */
+       void* user_data;/**< input data for callback function's second-param(data) */
+};
+
+/**
+ * @fn int deviced_request_mount_mmc(struct mmc_contents *mmc_data)
+ * @brief This API is used to mount mmc.\n
+ *             Internally, this API call predefined action API. That is send a notify message. \n
+ *             and when mount operation is finished, cb of deviced_mmc_content struct is called with cb's param1(result). \n
+ *             means of param1 - 0(mount success) and negative value if failed \n
+ *             [mount fail value] \n
+ *             -1 : operation not permmitted \n
+ *             -2 : no such file or directory \n
+ *             -6 : no such device or address \n
+ *             -12 : out of memory \n
+ *             -13 : A component of a path was not searchable \n
+ *             -14 : bad address \n
+ *             -15 : block device is requested \n
+ *             -16 : device or resource busy \n
+ *             -19 : filesystemtype not configured in the kernel \n
+ *             -20 : target, or a prefix of source, is not a directory \n
+ *             -22 : point does not exist \n
+ *             -24 : table of dummy devices is full \n
+ *             -36 : requested name is too long \n
+ *             -40 : Too many links encountered during pathname resolution. \n
+ *                     Or, a move was attempted, while target is a descendant of source \n
+ * @param[in] mmc_data for receive result of mount operation
+ * @return  non-zero on success message sending, -1 if message sending is failed.
+ */
+int deviced_request_mount_mmc(struct mmc_contents *mmc_data);
+
+/**
+ * @fn int deviced_request_unmount_mmc(struct mmc_contents *mmc_data,int option)
+ * @brief This API is used to unmount mmc.\n
+ *             Internally, this API call predefined action API. That is send a notify message. \n
+ *             and when unmount opeation is finished, cb of deviced_mmc_content struct is called with cb's param1(result). \n
+ *             means of param1 - 0(unmount success) and negative value if failed \n
+ *             [unmount fail value] \n
+ *             -1 : operation not permmitted \n
+ *             -2 : no such file or directory \n
+ *             -11 : try again \n
+ *             -12 : out of memory \n
+ *             -14 : bad address \n
+ *             -16 : device or resource busy \n
+ *             -22 : point does not exist \n
+ *             -36 : requested name is too long \n
+ * @param[in] mmc_data for receive result of unmount operation
+ * @param[in] option type of unmount option \n
+ *             0 : Normal unmount \n
+ *                     (if other process still access a sdcard, \n
+ *                      unmount will be failed.) \n
+ *             1 : Force unmount \n
+ *                     (if other process still access a sdcard, \n
+ *                     this process will be received SIGTERM or SIGKILL.)
+ * @return  non-zero on success message sending, -1 if message sending is failed.
+ */
+int deviced_request_unmount_mmc(struct mmc_contents *mmc_data, int option);
+
+/**
+ * @fn int deviced_request_format_mmc(struct mmc_contents *mmc_data)
+ * @brief This API is used to format mmc.\n
+ *             Internally, this API call predefined action API. That is send a notify message. \n
+ *             and when format opeation is finished, cb of deviced_mmc_content struct is called with cb's param1(result). \n
+ *             means of param1 - 0(format success) , -1(format fail)
+ * @param[in] mmc_data for receive result of format operation
+ * @return  non-zero on success message sending, -1 if message sending is failed.
+ */
+int deviced_request_format_mmc(struct mmc_contents *mmc_data);
+
+/**
+ * @fn int deviced_format_mmc(struct mmc_contents *mmc_data, int option)
+ * @brief This API is used to format mmc.\n
+ *             Internally, this API call predefined action API. That is send a notify message. \n
+ *             and when format opeation is finished, cb of deviced_mmc_content struct is called with cb's param1(result). \n
+ *             means of param1 - 0(format success) and negative value if failed \n
+ *             [format fail value] \n
+ *             -22 : Invalid argument(EINVAL) \n
+ * @param[in] mmc_data for receive result of format operation
+ * @param[in] option FMT_NORMAL is 0, FMT_FORCE is 1
+ * @return  non-zero on success message sending, -1 if message sending is failed.
+ */
+int deviced_format_mmc(struct mmc_contents *mmc_data, int option);
+
+/**
+ * @} // end of CAPI_SYSTEM_DEVICED_MMC_MODULE
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/deviced/dd-storage.h b/src/deviced/dd-storage.h
new file mode 100644 (file)
index 0000000..deb3cd8
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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_STORAGE_H__
+#define __DD_STORAGE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file        dd-storage.h
+ * @defgroup    CAPI_SYSTEM_DEVICED_STORAGE_MODULE Storage
+ * @ingroup     CAPI_SYSTEM_DEVICED
+ * @brief       This file provides the API for control of storage
+ * @section CAPI_SYSTEM_DEVICED_STORAGE_MODULE_HEADER Required Header
+ *   \#include <dd-storage.h>
+ */
+
+/**
+ * @addtogroup CAPI_SYSTEM_DEVICED_STORAGE_MODULE
+ * @{
+ */
+
+/**
+ * @par Description
+ * Storage path type
+ */
+enum storage_path_type {
+       STORAGE_DEFAULT = 0,
+       STORAGE_INTERNAL,
+       STORAGE_EXTERNAL,
+       STORAGE_MAX,
+};
+
+/**
+ * @par Description:
+ *  This API is used go get storage path.\n
+ * @param[in] type storage path type
+ * @param[in] path pointer to a buffer where the path is stored
+ * @param[in] size size of buffer
+ * @return 0 on success, -1 if failed
+ * @see storage_path_type
+ * @par Example
+ * @code
+ *  ...
+ *  if ( storage_get_path(STORAGE_INTERNAL, path, 50) < 0 )
+ *          printf("Get storage path failed\n");
+ *  ...
+ * @endcode
+ */
+int storage_get_path(int type, unsigned char *path, int size);
+
+/**
+ * @} // end of CAPI_SYSTEM_DEVICED_STORAGE_MODULE
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/deviced/dd-usbhost.h b/src/deviced/dd-usbhost.h
new file mode 100644 (file)
index 0000000..424469b
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * 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_USBHOST_H__
+#define __DD_USBHOST_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file        dd-usbhost.h
+ * @ingroup     CAPI_SYSTEM_DEVICED
+ * @defgroup    CAPI_SYSTEM_DEVICED_USBHOST_MODULE usbhost
+ * @brief       This file provides the API for usb host operations
+ */
+
+/**
+ * @addtogroup CAPI_SYSTEM_DEVICED_USBHOST_MODULE
+ * @{
+ */
+
+/**
+ * @par Description:
+ *      This API is used to initialize usbhost signal \n
+ * @return 0 on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if (init_usbhost_signal() < 0)
+ *      printf("Failed to initialize usbhost signal\n");
+ *  ...
+ * @endcode
+ */
+int init_usbhost_signal(void);
+
+/**
+ * @par Description:
+ *      This API is used to deinitialize usbhost signal \n
+ * @par Example
+ * @code
+ *  ...
+ *  if (init_usbhost_signal() < 0)
+ *      printf("Failed to initialize usbhost signal\n");
+ *
+ *  // Do something
+ *
+ *  deinit_usbhost_signal();
+ *  ...
+ * @endcode
+ */
+void deinit_usbhost_signal(void);
+
+/**
+ * @par Description:
+ *      This API is used to register usbhost signal \n
+ * @param[in] storage_changed callback function which is called when the usbhost signal is delivered
+ * @param[in] data parameter of storage_changed callback function
+ * @return 0 on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if (init_usbhost_signal() < 0)
+ *      printf("Failed to initialize usbhost signal\n");
+ *
+ *  if (register_usb_storage_change_handler(storage_cb, data) < 0) {
+ *      printf("Failed to register storage signal\n");
+ *      deinit_usbhost_signal();
+ *      return;
+ *  }
+ *
+ *  // Do something
+ *
+ *  if (unregister_usb_storage_change_handler() < 0)
+ *      printf("Failed to unregister storage signal\n");
+ *
+ *  deinit_usbhost_signal();
+ *  ...
+ * @endcode
+ */
+int register_usb_storage_change_handler(
+               void (*storage_changed)(char *type, char *path, int mount, void *),
+               void *data);
+
+/**
+ * @par Description:
+ *      This API is used to unregister usbhost signal \n
+ * @return 0 on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if (init_usbhost_signal() < 0)
+ *      printf("Failed to initialize usbhost signal\n");
+ *
+ *  if (register_usb_storage_change_handler(storage_cb, data) < 0) {
+ *      printf("Failed to register storage signal\n");
+ *      deinit_usbhost_signal();
+ *      return;
+ *  }
+ *
+ *  // Do something
+ *
+ *  if (unregister_usb_storage_change_handler() < 0)
+ *      printf("Failed to unregister storage signal\n");
+ *
+ *  deinit_usbhost_signal();
+ *  ...
+ * @endcode
+ */
+int unregister_usb_storage_change_handler(void);
+
+/**
+ * @par Description:
+ *      This API is used to request usb storage information \n
+ * @return 0 on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if (init_usbhost_signal() < 0)
+ *      printf("Failed to initialize usbhost signal\n");
+ *
+ *  if (register_usb_storage_change_handler(storage_cb, data) < 0) {
+ *      printf("Failed to register storage signal\n");
+ *      deinit_usbhost_signal();
+ *      return;
+ *  }
+ *
+ *  if (request_usb_storage_info() < 0)
+ *      printf("Failed to request all of storage information");
+ *
+ *  // Do someting
+ *
+ *  if (unregister_usb_storage_change_handler() < 0)
+ *      printf("Failed to unregister storage signal\n");
+ *
+ *  deinit_usbhost_signal();
+ *  ...
+ * @endcode
+ */
+int request_usb_storage_info(void);
+
+/**
+ * @par Description:
+ *      This API is used to mount usb storage \n
+ * @param[in] path path to unmount
+ * @return 0 on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if (init_usbhost_signal() < 0)
+ *      printf("Failed to initialize usbhost signal\n");
+ *
+ *  if (register_usb_storage_change_handler(storage_cb, data) < 0) {
+ *      printf("Failed to register storage signal\n");
+ *      deinit_usbhost_signal();
+ *      return;
+ *  }
+ *
+ *  if (mount_usb_storage("/opt/storage/usb/UsbDriveA1") < 0)
+ *      printf("Failed to mount usb storage");
+ *
+ *  // Do something.. Mounting takes some time
+ *
+ *  if (unregister_usb_storage_change_handler() < 0)
+ *      printf("Failed to unregister storage signal\n");
+ *
+ *  deinit_usbhost_signal();
+ *  ...
+ * @endcode
+ */
+int mount_usb_storage(char *path);
+
+/**
+ * @par Description:
+ *      This API is used to unmount usb storage \n
+ * @param[in] path path to mount
+ * @return 0 on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if (init_usbhost_signal() < 0)
+ *      printf("Failed to initialize usbhost signal\n");
+ *
+ *  if (register_usb_storage_change_handler(storage_cb, data) < 0) {
+ *      printf("Failed to register storage signal\n");
+ *      deinit_usbhost_signal();
+ *      return;
+ *  }
+ *
+ *  if (ummount_usb_storage("/opt/storage/usb/UsbDriveA1") < 0)
+ *      printf("Failed to unmount usb storage");
+ *
+ *  // Do something.. Unmounting takes some time
+ *
+ *  if (unregister_usb_storage_change_handler() < 0)
+ *      printf("Failed to unregister storage signal\n");
+ *
+ *  deinit_usbhost_signal();
+ *  ...
+ * @endcode
+ */
+int unmount_usb_storage(char *path);
+
+/**
+ * @par Description:
+ *      This API is used to format usb storage \n
+ * @param[in] path path to format
+ * @return 0 on success, negative if failed
+ * @par Example
+ * @code
+ *  ...
+ *  if (init_usbhost_signal() < 0)
+ *      printf("Failed to initialize usbhost signal\n");
+ *
+ *  if (register_usb_storage_change_handler(storage_cb, data) < 0) {
+ *      printf("Failed to register storage signal\n");
+ *      deinit_usbhost_signal();
+ *      return;
+ *  }
+ *
+ *  if (format_usb_storage("/opt/storage/usb/UsbDriveA1") < 0)
+ *      printf("Failed to unmount usb storage");
+ *
+ *  // Do something.. Formatting takes some time
+ *
+ *  if (unregister_usb_storage_change_handler() < 0)
+ *      printf("Failed to unregister storage signal\n");
+ *
+ *  deinit_usbhost_signal();
+ *  ...
+ * @endcode
+ */
+int format_usb_storage(char *path);
+
+
+/**
+ * @} // end of CAPI_SYSTEM_DEVICED_USBHOST_MODULE
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/deviced/deviced_doc.h b/src/deviced/deviced_doc.h
new file mode 100644 (file)
index 0000000..6a478a3
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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 __TIZEN_SYSTEM_DEVICED_DOC_H__
+#define __TIZEN_SYSTEM_DEVICED_DOC_H__
+
+/**
+ * @defgroup CAPI_SYSTEM_DEVICED deviced
+ * @brief  The deviced APIs provide functions to control devices.
+ * @ingroup CAPI_SYSTEM_FRAMEWORK
+ * @section CAPI_SYSTEM_DEVICED_HEADER Required Header
+ *   \#include <dd-deviced-managed.h>
+ *
+ * @section CAPI_SYSTEM_SYSTEM_DEVICED_OVERVIEW Overview
+ * Provides access to a set of device like battery, display, haptic, LED, etc.
+ * The state of the device is changed or obtained by using APIs provided.
+ *
+ * - battery percentage, full charging state, etc.
+ * - brightness control, enhance mode setting, display lock/unlock, etc.
+ * - haptic play
+ * - service led control
+ * - other devices
+ *
+ */
+
+#endif /* __TIZEN_SYSTEM_DEVICED_DOC_H__ */
diff --git a/src/deviced/haptic-module.h b/src/deviced/haptic-module.h
new file mode 100644 (file)
index 0000000..ba72d32
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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 __HAPTIC_MODULE_H__
+#define __HAPTIC_MODULE_H__
+
+/**
+ * @brief Enumerations of device id for the Haptic Module API.
+ * @details We support two motors now.
+ */
+typedef enum {
+    HAPTIC_MODULE_DEVICE_0 = 0x0,             /**< 1st motor */
+    HAPTIC_MODULE_DEVICE_1 = 0x1,             /**< 2nd motor */
+    HAPTIC_MODULE_DEVICE_ALL = 0x4,           /**< both of them */
+} haptic_module_device;
+
+/**
+ * @brief Enumerations of priority level for the Haptic Module API.
+ */
+typedef enum
+{
+    HAPTIC_MODULE_PRIORITY_MIN = 0,        /**< Minimum effect priority for developers (default) */
+    HAPTIC_MODULE_PRIORITY_MIDDLE,         /**< Maximum effect priority for developers */
+    HAPTIC_MODULE_PRIORITY_HIGH,           /**< Maximum effect priority for OEMs */
+} haptic_module_priority;
+
+/**
+ * @brief Enumerations of feedback level for the Haptic Module API.
+ * @details Haptic level means vibration power (intensity).
+ */
+typedef enum
+{
+    HAPTIC_MODULE_FEEDBACK_MIN = 0,
+    HAPTIC_MODULE_FEEDBACK_MAX = 100,
+} haptic_module_feedback;
+
+/**
+ * @brief Enumerations of iteration count for the Haptic Module API.
+ */
+typedef enum
+{
+    HAPTIC_MODULE_ITERATION_ONCE = 1,
+    HAPTIC_MODULE_ITERATION_INFINITE = 256,
+} haptic_module_iteration;
+
+/**
+ * @brief Enumerations of effect or device state for the Haptic Module API.
+ */
+typedef enum
+{
+    HAPTIC_MODULE_STATE_STOP = 0,
+    HAPTIC_MODULE_STATE_PLAYING,
+} haptic_module_state;
+
+/* Error and Return value codes */
+#define HAPTIC_MODULE_ERROR_NONE                                                        0
+#define HAPTIC_MODULE_NOT_INITIALIZED                                                  -1
+#define HAPTIC_MODULE_ALREADY_INITIALIZED                                              -2
+#define HAPTIC_MODULE_INVALID_ARGUMENT                                                 -3
+#define HAPTIC_MODULE_OPERATION_FAILED                                                 -4
+#define HAPTIC_MODULE_NOT_SUPPORTED                                                            -5
+
+/**
+ * @par Description:
+ *      effect element for haptic module.
+ */
+typedef struct {
+    int haptic_duration;           /**< Start time of the effect element in millisecond */
+    int haptic_level;        /**< Duration of the effect element in millisecond */
+} haptic_module_effect_element;
+
+#endif  /* __HAPTIC_MODULE_H__ */
diff --git a/src/deviced/haptic-plugin-intf.h b/src/deviced/haptic-plugin-intf.h
new file mode 100644 (file)
index 0000000..97351c8
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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 __HAPTIC_PLUGIN_INTF_H__
+#define __HAPTIC_PLUGIN_INTF_H__
+
+#include "haptic-module.h"
+
+struct haptic_plugin_ops {
+       int (*get_device_count) (int*);
+       int (*open_device) (int, int*);
+       int (*close_device) (int);
+       int (*vibrate_monotone) (int, int, int, int, int*);
+       int (*vibrate_buffer) (int, const unsigned char*, int, int, int, int*);
+       int (*stop_device) (int);
+       int (*get_device_state) (int, int*);
+       int (*create_effect) (unsigned char*, int, haptic_module_effect_element*, int);
+       int (*get_buffer_duration) (int, const unsigned char*, int*);
+       int (*convert_binary) (const unsigned char*, int, const char*);
+};
+
+const struct haptic_plugin_ops *get_haptic_plugin_interface();
+
+#endif /* __HAPTIC_PLUGIN_INTF_H__ */
diff --git a/src/display/alpm.c b/src/display/alpm.c
new file mode 100644 (file)
index 0000000..3a0770c
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * 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 <stdbool.h>
+#include <fcntl.h>
+
+#include "util.h"
+#include "core.h"
+#include "display-ops.h"
+#include "weaks.h"
+#include "core/edbus-handler.h"
+
+#define ON             "on"
+#define OFF            "off"
+
+#define SIGNAL_ALPM_ON                 "ALPMOn"
+#define SIGNAL_ALPM_OFF                        "ALPMOff"
+#define CLOCK_START                    "clockstart"
+#define CLOCK_END                      "clockend"
+#define ALPM_MAX_TIME                  30      /* minutes */
+
+static char *alpm_path;
+static int update_count;
+static int alpm_state;
+
+void broadcast_alpm_state(int state)
+{
+       char *signal;
+
+       signal = (state == true ? SIGNAL_ALPM_ON : SIGNAL_ALPM_OFF);
+
+       broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+           signal, NULL, NULL);
+}
+
+int alpm_get_state(void)
+{
+       char state[4];
+       int ret, alpm;
+
+       if (!alpm_path)
+               return -ENODEV;
+
+       ret = sys_get_str(alpm_path, state);
+       if (ret < 0)
+               return ret;
+
+       if (!strncmp(state, ON, strlen(ON)))
+               alpm = true;
+       else if (!strncmp(state, OFF, strlen(OFF)))
+               alpm = false;
+       else
+               alpm = -EINVAL;
+
+       return alpm;
+}
+
+int alpm_set_state(int on)
+{
+       if (!alpm_path)
+               return -ENODEV;
+
+       broadcast_alpm_state(on);
+
+       update_count = 0;
+
+       _D("ALPM is %s", (on ? ON : OFF));
+
+       alpm_state = on;
+
+       return sys_set_str(alpm_path, (on ? ON : OFF));
+}
+
+static void start_clock(void)
+{
+       struct timespec now_time;
+       static struct timespec start_time;
+       int diff_time;
+
+       if (pm_cur_state == S_NORMAL ||
+           pm_cur_state == S_LCDDIM ||
+           alpm_state == false)
+               return;
+
+       _D("lcd on");
+
+       if (update_count == 0)
+               clock_gettime(CLOCK_REALTIME, &start_time);
+
+       update_count++;
+
+       _D("clock update count : %d", update_count);
+
+       clock_gettime(CLOCK_REALTIME, &now_time);
+       diff_time = (now_time.tv_sec - start_time.tv_sec) / 60;
+
+       if (diff_time >= ALPM_MAX_TIME) {
+               _D("Exit ALPM state, LCD off");
+               alpm_set_state(false);
+               backlight_ops.on();
+               backlight_ops.off();
+               return;
+       }
+
+       /* change pmstate in order that apps can know the state */
+       set_setting_pmstate(S_NORMAL);
+       backlight_ops.on();
+
+       sleep(1);
+
+       _D("lcd off");
+       set_setting_pmstate(S_LCDOFF);
+       backlight_ops.off();
+
+       _D("finished!");
+}
+
+static void end_clock(void)
+{
+       if (pm_cur_state == S_NORMAL ||
+           pm_cur_state == S_LCDDIM ||
+           alpm_state == false)
+               return;
+
+       _D("end clock : lcd off");
+}
+
+int set_alpm_screen(char *screen)
+{
+       if (!screen)
+               return -EINVAL;
+
+       if (!alpm_path)
+               return -ENODEV;
+
+       if (!strncmp(screen, CLOCK_START,
+           strlen(CLOCK_START))) {
+               start_clock();
+       } else if (!strncmp(screen, CLOCK_END,
+           strlen(CLOCK_END))) {
+               end_clock();
+       }
+
+       return 0;
+}
+
+static void alpm_init(void *data)
+{
+       int fd;
+
+       alpm_path = getenv("ALPM_NODE");
+
+       /* Check alpm node is valid */
+       fd = open(alpm_path, O_RDONLY);
+       if (fd < 0) {
+               _E("alpm node is invalid");
+               alpm_path = NULL;
+               return;
+       } else {
+               _I("alpm path[%s] is initialized!", alpm_path);
+       }
+       close(fd);
+}
+
+static void alpm_exit(void *data)
+{
+       alpm_set_state(false);
+}
+
+static const struct display_ops display_alpm_ops = {
+       .name     = "alpm",
+       .init     = alpm_init,
+       .exit     = alpm_exit,
+};
+
+DISPLAY_OPS_REGISTER(&display_alpm_ops)
+
diff --git a/src/display/auto-brightness.c b/src/display/auto-brightness.c
new file mode 100644 (file)
index 0000000..45356f4
--- /dev/null
@@ -0,0 +1,686 @@
+/*
+ * 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 <stdbool.h>
+#include <stdio.h>
+#include <math.h>
+#include <limits.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <vconf.h>
+#include <sensor.h>
+#include <Ecore.h>
+
+#include "util.h"
+#include "core.h"
+#include "display-ops.h"
+#include "device-node.h"
+#include "proc/proc-handler.h"
+
+#define DISP_FORCE_SHIFT       12
+#define DISP_FORCE_CMD(prop, force)    (((force) << DISP_FORCE_SHIFT) | prop)
+
+#define SAMPLING_INTERVAL      1       /* 1 sec */
+#define MAX_SAMPLING_COUNT     3
+#define MAX_FAULT              5
+#define DEFAULT_AUTOMATIC_BRT  5
+#define MAX_AUTOMATIC_COUNT    11
+#define AUTOMATIC_DEVIDE_VAL   10
+#define AUTOMATIC_DELAY_TIME   0.5     /* 0.5 sec */
+#define MAX_NORMAL_LUX         10000
+
+#define RADIAN_VALUE           (57.2957)
+#define ROTATION_90            90
+#define WORKING_ANGLE_MIN      0
+#define WORKING_ANGLE_MAX      20
+
+#define ISVALID_AUTOMATIC_INDEX(index) (index >= 0 && index < MAX_AUTOMATIC_COUNT)
+
+static int (*_default_action) (int);
+static Ecore_Timer *alc_timeout_id = 0;
+static Ecore_Timer *update_timeout;
+static int light_handle = -1;
+static int accel_handle = -1;
+static int fault_count = 0;
+static int automatic_brt = DEFAULT_AUTOMATIC_BRT;
+static int min_brightness = PM_MIN_BRIGHTNESS;
+static char *min_brightness_name = 0;
+static int last_autobrightness = 0;
+static int value_table[MAX_AUTOMATIC_COUNT];
+
+static bool update_working_position(void)
+{
+       sensor_data_t data;
+       int ret;
+       float x, y, z, pitch, realg;
+
+       ret = sf_get_data(accel_handle, ACCELEROMETER_BASE_DATA_SET, &data);
+       if (ret < 0) {
+               _E("Fail to get accelerometer data! %d", ret);
+               return true;
+       }
+
+       x = data.values[0];
+       y = data.values[1];
+       z = data.values[2];
+
+       realg = (float)sqrt((x * x) + (y * y) + (z * z));
+       pitch = ROTATION_90 - abs((int) (asin(z / realg) * RADIAN_VALUE));
+
+       _D("accel data [%f, %f, %f] - %f", x, y, z, pitch);
+
+       if (pitch >= WORKING_ANGLE_MIN && pitch <= WORKING_ANGLE_MAX)
+               return true;
+       return false;
+}
+
+static int get_siop_brightness(int value)
+{
+       int cmd, ret, brt;
+
+       cmd = DISP_CMD(PROP_DISPLAY_MAX_BRIGHTNESS, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &brt);
+       if (ret >= 0 && value > brt)
+               return brt;
+
+       return value;
+}
+
+static void alc_set_brightness(int setting, int value, int lux)
+{
+       static int old;
+       int position, cmd, tmp_value = 0;
+
+       cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
+       if (device_get_property(DEVICE_TYPE_DISPLAY, cmd, &tmp_value) < 0) {
+               _E("Fail to get display brightness!");
+               return;
+       }
+
+       if (value < min_brightness)
+               value = min_brightness;
+
+       if (cur_siop_level() != 0)
+               value = get_siop_brightness(value);
+
+       if (tmp_value != value) {
+               if (!setting && min_brightness == PM_MIN_BRIGHTNESS) {
+                       position = update_working_position();
+                       if (!position && (old > lux)) {
+                               _D("It's not working position, "
+                                   "LCD isn't getting dark!");
+                               return;
+                       }
+               }
+               int diff, step;
+
+               diff = value - tmp_value;
+               if (abs(diff) < display_conf.brightness_change_step)
+                       step = (diff > 0 ? 1 : -1);
+               else
+                       step = (int)ceil(diff /
+                           (float)display_conf.brightness_change_step);
+
+               _D("%d", step);
+               while (tmp_value != value) {
+                       if (step == 0) break;
+
+                       tmp_value += step;
+                       if ((step > 0 && tmp_value > value) ||
+                           (step < 0 && tmp_value < value))
+                               tmp_value = value;
+
+                       backlight_ops.set_default_brt(tmp_value);
+                       backlight_ops.update();
+                       last_autobrightness = tmp_value;
+               }
+               _I("load light data:%d lux,auto brt %d,min brightness %d,"
+                   "brightness %d", lux, automatic_brt, min_brightness, value);
+               old = lux;
+       }
+}
+
+static bool check_brightness_changed(int value)
+{
+       int i;
+       static int values[MAX_SAMPLING_COUNT], count = 0;
+
+       if (count >= MAX_SAMPLING_COUNT || count < 0)
+               count = 0;
+
+       values[count++] = value;
+
+       for (i = 0; i < MAX_SAMPLING_COUNT - 1; i++)
+               if (values[i] != values[i+1])
+                       return false;
+       return true;
+}
+
+static void set_brightness_direct(void)
+{
+       int ret, cmd, value;
+       sensor_data_t light_data;
+
+       if (pm_cur_state != S_NORMAL || !get_hallic_open())
+               return;
+
+       /* direct update if it's previous value */
+       if (last_autobrightness > 0) {
+               backlight_ops.set_default_brt(last_autobrightness);
+               backlight_ops.update();
+               return;
+       }
+
+       /* get lux value from light sensor */
+       ret = sf_get_data(light_handle, LIGHT_LUX_DATA_SET, &light_data);
+       if (ret < 0 || (int)light_data.values[0] < 0)
+               return;
+
+       /* get brightness by lux */
+       cmd = DISP_FORCE_CMD(PROP_DISPLAY_BRIGHTNESS_BY_LUX, true);
+       cmd = DISP_CMD(cmd, (int)light_data.values[0]);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, value_table);
+       if (ret < 0)
+               return;
+
+       /* get auto brightness level from value table*/
+       value = (ISVALID_AUTOMATIC_INDEX(automatic_brt) ?
+           value_table[automatic_brt] : value_table[DEFAULT_AUTOMATIC_BRT]);
+
+       /* update brightness actually */
+       backlight_ops.set_default_brt(value);
+       backlight_ops.update();
+       last_autobrightness = value;
+}
+
+static bool check_hbm(int lux)
+{
+       int ret, old_state, new_state;
+
+       ret = device_get_property(DEVICE_TYPE_DISPLAY,
+           PROP_DISPLAY_HBM_CONTROL, &old_state);
+       if (ret < 0) {
+               _E("Failed to get HBM state!");
+               return false;
+       }
+
+       if (old_state)
+               new_state = (lux <= MAX_NORMAL_LUX ? 0 : 1);
+       else
+               new_state = (lux >= display_conf.hbm_lux_threshold ? 1 : 0);
+
+       if (old_state != new_state) {
+               _D("hbm is %s", (new_state ? "on" : "off"));
+               ret = device_set_property(DEVICE_TYPE_DISPLAY,
+                   PROP_DISPLAY_HBM_CONTROL, new_state);
+               if (ret < 0)
+                       _E("Failed to set HBM state!");
+               /*
+                * Brightness is changed directly
+                * when hbm state is changed from on to off
+                */
+               if (!new_state)
+                       set_brightness_direct();
+       }
+
+       return (new_state ? true : false);
+}
+
+static bool alc_update_brt(bool setting)
+{
+       int value = 0;
+       int cal_value = 0;
+       int ret = -1;
+       int cmd;
+       sensor_data_t light_data;
+
+       ret = sf_get_data(light_handle, LIGHT_LUX_DATA_SET, &light_data);
+       if (ret < 0 || (int)light_data.values[0] < 0) {
+               fault_count++;
+       } else {
+               int force = (setting ? 1 : 0);
+               cmd = DISP_FORCE_CMD(PROP_DISPLAY_BRIGHTNESS_BY_LUX, force);
+               cmd = DISP_CMD(cmd, (int)light_data.values[0]);
+               ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, value_table);
+
+               value = (ISVALID_AUTOMATIC_INDEX(automatic_brt) ?
+                   value_table[automatic_brt] : value_table[DEFAULT_AUTOMATIC_BRT]);
+
+               if (ret < 0 || value < PM_MIN_BRIGHTNESS ||
+                   value > PM_MAX_BRIGHTNESS) {
+                       _E("fail to load light data : %d lux, %d",
+                               (int)light_data.values[0], value);
+                       fault_count++;
+               } else {
+                       fault_count = 0;
+
+                       /* Check HBM (High Brightness Mode) */
+                       if (check_hbm((int)light_data.values[0]))
+                               return EINA_TRUE;
+
+                       if (!check_brightness_changed(value) && !setting)
+                               return EINA_TRUE;
+
+                       alc_set_brightness(setting, value, (int)light_data.values[0]);
+               }
+       }
+
+       if ((fault_count > MAX_FAULT) && !(pm_status_flag & PWROFF_FLAG)) {
+               if (alc_timeout_id > 0)
+                       ecore_timer_del(alc_timeout_id);
+               alc_timeout_id = NULL;
+               vconf_set_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT,
+                   SETTING_BRIGHTNESS_AUTOMATIC_OFF);
+               _E("Fault counts is over %d, disable automatic brightness",
+                   MAX_FAULT);
+               return EINA_FALSE;
+       }
+       return EINA_TRUE;
+}
+
+static bool alc_handler(void* data)
+{
+       if (pm_cur_state != S_NORMAL || !get_hallic_open()){
+               if (alc_timeout_id > 0)
+                       ecore_timer_del(alc_timeout_id);
+               alc_timeout_id = NULL;
+               return EINA_FALSE;
+       }
+
+       if (alc_update_brt(false) == EINA_FALSE)
+               return EINA_FALSE;
+
+       if (alc_timeout_id != 0)
+               return EINA_TRUE;
+
+       return EINA_FALSE;
+}
+
+static int alc_action(int timeout)
+{
+       /* sampling timer add */
+       if (alc_timeout_id == 0 && !(pm_status_flag & PWRSV_FLAG)) {
+               display_info.update_auto_brightness(true);
+
+               alc_timeout_id =
+                   ecore_timer_add(display_conf.lightsensor_interval,
+                           (Ecore_Task_Cb)alc_handler, NULL);
+       }
+
+       if (_default_action != NULL)
+               return _default_action(timeout);
+
+       /* unreachable code */
+       return -1;
+}
+
+static int connect_sfsvc(void)
+{
+       int sf_state = -1;
+
+       _I("connect with sensor fw");
+       /* light sensor */
+       light_handle = sf_connect(LIGHT_SENSOR);
+       if (light_handle < 0) {
+               _E("light sensor attach fail");
+               goto error;
+       }
+       sf_state = sf_start(light_handle, 0);
+       if (sf_state < 0) {
+               _E("light sensor attach fail");
+               sf_disconnect(light_handle);
+               light_handle = -1;
+               goto error;
+       }
+       /* accelerometer sensor */
+       accel_handle = sf_connect(ACCELEROMETER_SENSOR);
+       if (accel_handle < 0) {
+               _E("accelerometer sensor attach fail");
+               goto error;
+       }
+       sf_state = sf_start(accel_handle, 0);
+       if (sf_state < 0) {
+               _E("accelerometer sensor attach fail");
+               sf_disconnect(accel_handle);
+               accel_handle = -1;
+               goto error;
+       }
+
+       fault_count = 0;
+       return 0;
+
+error:
+       if (light_handle >= 0) {
+               sf_stop(light_handle);
+               sf_disconnect(light_handle);
+               light_handle = -1;
+       }
+       if (accel_handle >= 0) {
+               sf_stop(accel_handle);
+               sf_disconnect(accel_handle);
+               accel_handle = -1;
+       }
+       return -EIO;
+}
+
+static int disconnect_sfsvc(void)
+{
+       _I("disconnect with sensor fw");
+       /* light sensor*/
+       if(light_handle >= 0) {
+               sf_stop(light_handle);
+               sf_disconnect(light_handle);
+               light_handle = -1;
+       }
+       /* accelerometer sensor*/
+       if(accel_handle >= 0) {
+               sf_stop(accel_handle);
+               sf_disconnect(accel_handle);
+               accel_handle = -1;
+       }
+
+       if (_default_action != NULL) {
+               states[S_NORMAL].action = _default_action;
+               _default_action = NULL;
+       }
+       if (alc_timeout_id > 0) {
+               ecore_timer_del(alc_timeout_id);
+               alc_timeout_id = NULL;
+       }
+
+       return 0;
+}
+
+static inline void set_brtch_state(void)
+{
+       if (pm_status_flag & PWRSV_FLAG) {
+               pm_status_flag |= BRTCH_FLAG;
+               vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, true);
+               _D("brightness changed in low battery,"
+                   "escape dim state (light)");
+       }
+}
+
+static int set_autobrightness_state(int status)
+{
+       int ret = -1;
+       int brt = -1;
+       int default_brt = -1;
+       int max_brt = -1;
+
+       if (status == SETTING_BRIGHTNESS_AUTOMATIC_ON) {
+               if(connect_sfsvc() < 0)
+                       return -1;
+
+               /* escape dim state if it's in low battery.*/
+               set_brtch_state();
+
+               /* change alc action func */
+               if (_default_action == NULL)
+                       _default_action = states[S_NORMAL].action;
+               states[S_NORMAL].action = alc_action;
+
+               set_brightness_direct();
+               alc_timeout_id =
+                   ecore_timer_add(display_conf.lightsensor_interval,
+                           (Ecore_Task_Cb)alc_handler, NULL);
+       } else if (status == SETTING_BRIGHTNESS_AUTOMATIC_PAUSE) {
+               _I("auto brightness paused!");
+               disconnect_sfsvc();
+               backlight_ops.hbm_off();
+       } else {
+               disconnect_sfsvc();
+               backlight_ops.hbm_off();
+               /* escape dim state if it's in low battery.*/
+               set_brtch_state();
+
+               ret = get_setting_brightness(&default_brt);
+               if (ret != 0 || (default_brt < PM_MIN_BRIGHTNESS || default_brt > PM_MAX_BRIGHTNESS)) {
+                       _I("fail to read vconf value for brightness");
+                       brt = PM_DEFAULT_BRIGHTNESS;
+                       if(default_brt < PM_MIN_BRIGHTNESS || default_brt > PM_MAX_BRIGHTNESS)
+                               vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
+                       default_brt = brt;
+               }
+
+               backlight_ops.set_default_brt(default_brt);
+               backlight_ops.update();
+       }
+
+       return 0;
+}
+
+static void set_alc_function(keynode_t *key_nodes, void *data)
+{
+       int status, ret;
+
+       if (key_nodes == NULL) {
+               _E("wrong parameter, key_nodes is null");
+               return;
+       }
+
+       status = vconf_keynode_get_int(key_nodes);
+
+       switch (status) {
+       case SETTING_BRIGHTNESS_AUTOMATIC_OFF:
+       case SETTING_BRIGHTNESS_AUTOMATIC_ON:
+       case SETTING_BRIGHTNESS_AUTOMATIC_PAUSE:
+               ret = set_autobrightness_state(status);
+               _D("set auto brightness : %d", ret);
+               break;
+       default:
+               _E("invalid value! %d", status);
+       }
+}
+
+static bool check_sfsvc(void* data)
+{
+       /* this function will return opposite value for re-callback in fail */
+       int vconf_auto;
+       int sf_state = 0;
+
+       _I("register sfsvc");
+
+       vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &vconf_auto);
+       if (vconf_auto == SETTING_BRIGHTNESS_AUTOMATIC_ON) {
+               if(connect_sfsvc() < 0)
+                       return EINA_TRUE;
+
+               /* change alc action func */
+               if (_default_action == NULL)
+                       _default_action = states[S_NORMAL].action;
+               states[S_NORMAL].action = alc_action;
+               alc_timeout_id =
+                   ecore_timer_add(display_conf.lightsensor_interval,
+                           (Ecore_Task_Cb)alc_handler, NULL);
+               if (alc_timeout_id > 0)
+                       return EINA_FALSE;
+               disconnect_sfsvc();
+               return EINA_TRUE;
+       }
+       _I("change vconf value before registering sfsvc");
+       return EINA_FALSE;
+}
+
+static void set_alc_automatic_brt(keynode_t *key_nodes, void *data)
+{
+       if (key_nodes == NULL) {
+               _E("wrong parameter, key_nodes is null");
+               return;
+       }
+       automatic_brt = vconf_keynode_get_int(key_nodes) / AUTOMATIC_DEVIDE_VAL;
+       _D("automatic brt : %d", automatic_brt);
+
+       alc_update_brt(true);
+}
+
+static Eina_Bool update_handler(void* data)
+{
+       int ret, on;
+
+       update_timeout = NULL;
+
+       if (pm_cur_state != S_NORMAL)
+               return EINA_FALSE;
+
+       if (!get_hallic_open())
+               return EINA_FALSE;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &on);
+       if (ret < 0 || on != SETTING_BRIGHTNESS_AUTOMATIC_ON)
+               return EINA_FALSE;
+
+       _D("auto brightness is working!");
+
+       sf_change_sensor_option(light_handle, 1);
+       alc_update_brt(true);
+       sf_change_sensor_option(light_handle, 0);
+
+       return EINA_FALSE;
+}
+
+static void update_auto_brightness(bool update)
+{
+       if (update_timeout) {
+               ecore_timer_del(update_timeout);
+               update_timeout = NULL;
+       }
+
+       if (update) {
+               update_timeout = ecore_timer_add(AUTOMATIC_DELAY_TIME,
+                   update_handler, NULL);
+       }
+}
+
+static int prepare_lsensor(void *data)
+{
+       int status, ret;
+       int sf_state = 0;
+       int brt = -1;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &status);
+
+       if (ret == 0 && status == SETTING_BRIGHTNESS_AUTOMATIC_ON)
+               set_autobrightness_state(status);
+
+       /* add auto_brt_setting change handler */
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT,
+                                set_alc_function, NULL);
+
+       vconf_get_int(VCONFKEY_SETAPPL_LCD_AUTOMATIC_BRIGHTNESS, &brt);
+       if (brt < PM_MIN_BRIGHTNESS || brt > PM_MAX_BRIGHTNESS) {
+               _E("Failed to get automatic brightness!");
+       } else {
+               automatic_brt = brt / AUTOMATIC_DEVIDE_VAL;
+               _I("automatic brt init success %d", automatic_brt);
+       }
+
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_LCD_AUTOMATIC_BRIGHTNESS,
+                               set_alc_automatic_brt, NULL);
+
+       return 0;
+}
+
+static inline void update_brightness_direct(void)
+{
+       int ret, status;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &status);
+       if (ret == 0 && status == SETTING_BRIGHTNESS_AUTOMATIC_ON)
+               alc_update_brt(true);
+}
+
+static int set_autobrightness_min(int val, char *name)
+{
+       if (!name)
+               return -EINVAL;
+
+       if (val < PM_MIN_BRIGHTNESS || val > PM_MAX_BRIGHTNESS)
+               return -EINVAL;
+
+       min_brightness = val;
+
+       if (min_brightness_name) {
+               free(min_brightness_name);
+               min_brightness_name = 0;
+       }
+       min_brightness_name = strndup(name, strlen(name));
+
+       update_brightness_direct();
+
+       _I("auto brightness min value changed! (%d, %s)",
+           min_brightness, min_brightness_name);
+
+       return 0;
+}
+
+static int reset_autobrightness_min(char *name, enum watch_id id)
+{
+       if (!name)
+               return -EINVAL;
+
+       if (!min_brightness_name)
+               return -EINVAL;
+
+       if (strcmp(name, min_brightness_name))
+               return -EINVAL;
+
+       _I("change to default %d -> %d, %s", min_brightness,
+           PM_MIN_BRIGHTNESS, min_brightness_name);
+       min_brightness = PM_MIN_BRIGHTNESS;
+       if (min_brightness_name) {
+               free(min_brightness_name);
+               min_brightness_name = 0;
+       }
+
+       update_brightness_direct();
+
+       return 0;
+}
+
+static void auto_brightness_init(void *data)
+{
+       display_info.update_auto_brightness = update_auto_brightness;
+       display_info.set_autobrightness_min = set_autobrightness_min;
+       display_info.reset_autobrightness_min = reset_autobrightness_min;
+
+       prepare_lsensor(NULL);
+}
+
+static void auto_brightness_exit(void *data)
+{
+       vconf_ignore_key_changed(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT,
+           set_alc_function);
+
+       vconf_ignore_key_changed(VCONFKEY_SETAPPL_LCD_AUTOMATIC_BRIGHTNESS,
+           set_alc_automatic_brt);
+
+       set_autobrightness_state(SETTING_BRIGHTNESS_AUTOMATIC_OFF);
+}
+
+static const struct display_ops display_autobrightness_ops = {
+       .name     = "auto-brightness",
+       .init     = auto_brightness_init,
+       .exit     = auto_brightness_exit,
+};
+
+DISPLAY_OPS_REGISTER(&display_autobrightness_ops)
+
diff --git a/src/display/brightness.c b/src/display/brightness.c
new file mode 100644 (file)
index 0000000..370de9a
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * 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 <stdlib.h>
+#include <stdbool.h>
+#include <vconf.h>
+#include <Ecore.h>
+
+#include "util.h"
+#include "core.h"
+#include "brightness.h"
+#include "display-ops.h"
+#include "core/common.h"
+#include "core/device-notifier.h"
+#include "core/edbus-handler.h"
+#include "shared/dbus.h"
+
+#define KEY_WAITING_TIME               3       /* 3 seconds */
+
+#define SIGNAL_BRIGHTNESS_READY                "BrightnessReady"
+#define SIGNAL_BRIGHTNESS_CHANGED      "BrightnessChanged"
+
+#define METHOD_BRIGHTNESS              "BrightnessPopupLaunch"
+#define POPUP_TYPE_LAUNCH              "launch"
+#define POPUP_TYPE_TERMINATE           "terminate"
+
+static Ecore_Timer *popup_timer = NULL;
+static int popup_pid = -1;
+static bool brightness_ready = false;
+
+static void broadcast_brightness_changed(int val)
+{
+       char *arr[1];
+       char str[32];
+
+       snprintf(str, sizeof(str), "%d", val);
+       arr[0] = str;
+
+       broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+           SIGNAL_BRIGHTNESS_CHANGED, "i", arr);
+}
+
+static int process_syspopup(char *type)
+{
+       int pid;
+       char *pa[4];
+       pa[0] = "_SYSPOPUP_CONTENT_";
+       pa[1] = "brightness";
+       pa[2] = "_TYPE_";
+       pa[3] = type;
+
+       pid = dbus_method_sync(POPUP_BUS_NAME, POPUP_PATH_SYSTEM,
+           POPUP_INTERFACE_SYSTEM, METHOD_BRIGHTNESS, "ssss", pa);
+
+       if (pid < 0)
+               _E("Failed to syspopup(%d)", pid);
+
+       return pid;
+}
+
+static inline int calculate_brightness(int val, int action)
+{
+       if (action == BRIGHTNESS_UP)
+               val += BRIGHTNESS_CHANGE;
+       else if (action == BRIGHTNESS_DOWN)
+               val -= BRIGHTNESS_CHANGE;
+
+       val = clamp(val, PM_MIN_BRIGHTNESS, PM_MAX_BRIGHTNESS);
+
+       return val;
+}
+
+static void update_brightness(int action)
+{
+       int ret, val, new_val;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, &val);
+       if (ret < 0) {
+               _E("Fail to get brightness!");
+               return;
+       }
+
+       new_val = calculate_brightness(val, action);
+
+       if (new_val == val)
+               return;
+
+       broadcast_brightness_changed(new_val);
+
+       ret = vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, new_val);
+       if (!ret) {
+               backlight_ops.update();
+               _I("brightness is changed! (%d)", new_val);
+       } else {
+               _E("Fail to set brightness!");
+       }
+}
+
+static Eina_Bool key_waiting_expired(void *data)
+{
+       int ret;
+       char name[PATH_MAX];
+
+       popup_timer = NULL;
+       brightness_ready = false;
+
+       get_pname(popup_pid, name);
+       if (!name[0])
+               return EINA_FALSE;
+
+       ret = process_syspopup(POPUP_TYPE_TERMINATE);
+
+       if (ret < 0)
+               _E("Failed to terminate syspopup!(%d:%d)", popup_pid, ret);
+       else
+               _D("syspopup is terminated!(%d:%d)", popup_pid, ret);
+
+       popup_pid = -1;
+
+       return EINA_FALSE;
+}
+
+int control_brightness_key(int action)
+{
+       int ret, val;
+       char name[PATH_MAX];
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &val);
+       if (!ret && val == SETTING_BRIGHTNESS_AUTOMATIC_ON) {
+               vconf_set_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT,
+                   SETTING_BRIGHTNESS_AUTOMATIC_OFF);
+       }
+
+       get_pname(popup_pid, name);
+       if (popup_pid < 0 || !name[0]) {
+               brightness_ready = false;
+               popup_pid = process_syspopup(POPUP_TYPE_LAUNCH);
+
+               if (popup_pid > 0)
+                       _D("popup is launched! (%d)", popup_pid);
+               else
+                       _E("Failed to launch popup! (%d)", popup_pid);
+       }
+
+       if (!brightness_ready)
+               return false;
+
+       if (popup_timer)
+               ecore_timer_reset(popup_timer);
+       else
+               popup_timer = ecore_timer_add(KEY_WAITING_TIME,
+                   key_waiting_expired, NULL);
+
+       update_brightness(action);
+       return false;
+}
+
+static int lcd_changed_cb(void *data)
+{
+       int lcd_state = (int)data;
+
+       if (lcd_state == S_LCDOFF && popup_pid > 0) {
+               if (popup_timer)
+                       ecore_timer_del(popup_timer);
+
+               key_waiting_expired(NULL);
+       }
+       return 0;
+}
+
+static void brightness_ready_handler(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       int ret, state;
+
+       ret = dbus_message_is_signal(msg, DEVICED_INTERFACE_DISPLAY,
+           SIGNAL_BRIGHTNESS_READY);
+       if (!ret) {
+               _E("there is no brightness ready signal");
+               return;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &state,
+           DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               return;
+       }
+
+       if (state) {
+               _D("brightness popup is ready!");
+               brightness_ready = true;
+       } else {
+               _D("brightness popup is not ready! ");
+               brightness_ready = false;
+
+               if (popup_timer)
+                       ecore_timer_del(popup_timer);
+
+               key_waiting_expired(NULL);
+       }
+}
+
+static void brightness_init(void *data)
+{
+       int ret;
+
+       /* register signal handler to get brightness popup state */
+       ret = register_edbus_signal_handler(DEVICED_PATH_DISPLAY,
+                   DEVICED_INTERFACE_DISPLAY, SIGNAL_BRIGHTNESS_READY,
+                   brightness_ready_handler);
+       if (ret < 0)
+               _E("Failed to register signal handler! %d", ret);
+
+       /* register notifier */
+       register_notifier(DEVICE_NOTIFIER_LCD, lcd_changed_cb);
+}
+
+static void brightness_exit(void *data)
+{
+       /* unregister notifier */
+       unregister_notifier(DEVICE_NOTIFIER_LCD, lcd_changed_cb);
+}
+
+static const struct display_ops display_brightness_ops = {
+       .name     = "brightness",
+       .init     = brightness_init,
+       .exit     = brightness_exit,
+};
+
+DISPLAY_OPS_REGISTER(&display_brightness_ops)
+
diff --git a/src/display/brightness.h b/src/display/brightness.h
new file mode 100644 (file)
index 0000000..34125f8
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2011 - 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.
+ */
+
+
+/**
+ * @file       brightness.h
+ * @brief      brightness control about brightness popup or the like
+ */
+#ifndef __BRIGHTNESS_H__
+#define __BRIGHTNESS_H__
+
+#define BRIGHTNESS_UP                  1
+#define BRIGHTNESS_DOWN                        2
+#define BRIGHTNESS_CHANGE              10
+
+int control_brightness_key(int action);
+#endif
+
diff --git a/src/display/core.c b/src/display/core.c
new file mode 100644 (file)
index 0000000..6cfa81a
--- /dev/null
@@ -0,0 +1,2450 @@
+/*
+ * 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.
+ */
+
+
+/**
+ * @file       core.c
+ * @brief      Power manager main loop.
+ *
+ * This file includes Main loop, the FSM, signal processing.
+ */
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <vconf-keys.h>
+#include <Ecore.h>
+
+#include "util.h"
+#include "core.h"
+#include "device-node.h"
+#include "lock-detector.h"
+#include "display-ops.h"
+#include "core/queue.h"
+#include "core/data.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+#include "core/device-handler.h"
+#include "core/udev.h"
+#include "core/list.h"
+#include "core/common.h"
+#include "core/edbus-handler.h"
+#include "core/config-parser.h"
+#include "dd-display.h"
+#include "weaks.h"
+
+#define PM_STATE_LOG_FILE              "/var/log/pm_state.log"
+#define DISPLAY_CONF_FILE              "/etc/deviced/display.conf"
+
+/**
+ * @addtogroup POWER_MANAGER
+ * @{
+ */
+
+#define SET_BRIGHTNESS_IN_BOOTLOADER   "/usr/bin/save_blenv SLP_LCD_BRIGHT"
+#define LOCK_SCREEN_INPUT_TIMEOUT      10000
+#define LOCK_SCREEN_CONTROL_TIMEOUT    5000
+#define DD_LCDOFF_INPUT_TIMEOUT                3000
+
+unsigned int pm_status_flag;
+
+static void (*power_saving_func) (int onoff);
+static enum device_ops_status status = DEVICE_OPS_STATUS_UNINIT;
+
+int pm_cur_state;
+int pm_old_state;
+Ecore_Timer *timeout_src_id;
+static int pre_suspend_flag = false;
+int system_wakeup_flag = false;
+static unsigned int custom_normal_timeout = 0;
+static unsigned int custom_dim_timeout = 0;
+static int custom_holdkey_block = false;
+static int custom_change_pid = -1;
+static char *custom_change_name;
+static int standby_mode = false;
+static int standby_state = false;
+static Eina_List *standby_mode_list = NULL;
+static int (*basic_action) (int);
+static bool hallic_open = true;
+static Ecore_Timer *lock_timeout_id;
+static int lock_screen_timeout = LOCK_SCREEN_INPUT_TIMEOUT;
+static int hdmi_state = 0;
+static int tts_state = false;
+static struct timeval lcdon_tv;
+
+/* default transition, action fuctions */
+static int default_trans(int evt);
+static int default_action(int timeout);
+static int default_check(int next);
+
+struct state states[S_END] = {
+       {S_START, default_trans, default_action, default_check,},
+       {S_NORMAL, default_trans, default_action, default_check,},
+       {S_LCDDIM, default_trans, default_action, default_check,},
+       {S_LCDOFF, default_trans, default_action, default_check,},
+       {S_SLEEP, default_trans, default_action, default_check,}
+};
+
+static const char state_string[5][10] =
+       { "S_START", "S_NORMAL", "S_LCDDIM", "S_LCDOFF", "S_SLEEP" };
+
+static int trans_table[S_END][EVENT_END] = {
+       /* Timeout , Input */
+       {S_START, S_START},     /* S_START */
+       {S_LCDDIM, S_NORMAL},   /* S_NORMAL */
+       {S_LCDOFF, S_NORMAL},   /* S_LCDDIM */
+       {S_SLEEP, S_NORMAL},    /* S_LCDOFF */
+       {S_LCDOFF, S_NORMAL},   /* S_SLEEP */
+};
+
+#define SHIFT_UNLOCK           4
+#define MASK_RESET_TIMEOUT     0x8     /* 1000 */
+#define MASK_MARGIN_TIMEOUT    (0x1 << 8)
+#define SHIFT_CHANGE_STATE     7
+#define CHANGE_STATE_BIT       0xF00   /* 1111 0000 0000 */
+#define SHIFT_LOCK_FLAG        16
+#define SHIFT_CHANGE_TIMEOUT   20
+#define CUSTOM_TIMEOUT_BIT     0x1
+#define CUSTOM_HOLDKEY_BIT     0x2
+#define HOLD_KEY_BLOCK_BIT     0x1
+#define STANDBY_MODE_BIT       0x2
+#define TIMEOUT_NONE           (-1)
+
+#define S_COVER_TIMEOUT                        8000
+#define GET_HOLDKEY_BLOCK_STATE(x) ((x >> SHIFT_LOCK_FLAG) & HOLD_KEY_BLOCK_BIT)
+#define GET_STANDBY_MODE_STATE(x) ((x >> SHIFT_LOCK_FLAG) & STANDBY_MODE_BIT)
+#define MASK32                         0xffffffff
+#define BOOTING_DONE_WATING_TIME       60000   /* 1 minute */
+#define LOCK_TIME_ERROR                        600     /* 600 seconds */
+#define LOCK_TIME_WARNING              60      /* 60 seconds */
+
+#define ACTIVE_ACT "active"
+#define INACTIVE_ACT "inactive"
+#define SIGNAL_LCD_ON "LCDOn"
+#define SIGNAL_LCD_OFF "LCDOff"
+
+#define LOCK_SCREEN_WATING_TIME                0.3     /* 0.3 second */
+#define LONG_PRESS_INTERVAL             2       /* 2 seconds */
+#define SAMPLING_INTERVAL              1       /* 1 sec */
+#define BRIGHTNESS_CHANGE_STEP         10
+#define HBM_LUX_THRESHOLD              32768   /* lux */
+#define LCD_ALWAYS_ON                  0
+#define LCDOFF_TIMEOUT                 500     /* milli second */
+
+#define DIFF_TIMEVAL_MS(a, b) \
+       (((a.tv_sec * 1000000 + a.tv_usec) - \
+       (b.tv_sec * 1000000 + b.tv_usec)) \
+       / 1000)
+
+struct display_config display_conf = {
+       .lock_wait_time         = LOCK_SCREEN_WATING_TIME,
+       .longpress_interval     = LONG_PRESS_INTERVAL,
+       .lightsensor_interval   = SAMPLING_INTERVAL,
+       .lcdoff_timeout         = LCDOFF_TIMEOUT,
+       .brightness_change_step = BRIGHTNESS_CHANGE_STEP,
+       .hbm_lux_threshold      = HBM_LUX_THRESHOLD,
+       .lcd_always_on          = LCD_ALWAYS_ON,
+       .framerate_app          = {0,0,0,0},
+       .control_display        = 0,
+       .powerkey_doublepress   = 0,
+       .alpm_on                = 0,
+};
+
+struct display_function_info display_info = {
+       .update_auto_brightness         = NULL,
+       .set_autobrightness_min         = NULL,
+       .reset_autobrightness_min       = NULL,
+       .face_detection                 = NULL,
+};
+
+typedef struct _pm_lock_node {
+       pid_t pid;
+       Ecore_Timer *timeout_id;
+       time_t time;
+       bool holdkey_block;
+       struct _pm_lock_node *next;
+} PmLockNode;
+
+static PmLockNode *cond_head[S_END];
+
+static void set_process_active(bool flag, pid_t pid)
+{
+       char str[6];
+       char *arr[2];
+       int ret;
+
+       if (pid >= INTERNAL_LOCK_BASE)
+               return;
+
+       sprintf(str, "%d", (int)pid);
+
+       arr[0] = (flag ? ACTIVE_ACT : INACTIVE_ACT);
+       arr[1] = str;
+
+       /* Send dbug to resourced */
+       ret = broadcast_edbus_signal(RESOURCED_PATH_PROCESS,
+           RESOURCED_INTERFACE_PROCESS, RESOURCED_METHOD_ACTIVE, "si", arr);
+       if (ret < 0)
+               _E("Fail to send dbus signal to resourced!!");
+}
+
+int get_standby_state(void)
+{
+       return standby_state;
+}
+
+static inline void set_standby_state(bool state)
+{
+       if (standby_state != state)
+               standby_state = state;
+}
+
+void broadcast_lcd_on(void)
+{
+       broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+           SIGNAL_LCD_ON, NULL, NULL);
+}
+
+void broadcast_lcd_off(void)
+{
+       broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+           SIGNAL_LCD_OFF, NULL, NULL);
+}
+
+void tts_lcd_off(void)
+{
+       int ret;
+
+       ret = dbus_method_sync(POPUP_BUS_NAME, POPUP_PATH_SERVANT,
+           POPUP_IFACE_SERVANT, POPUP_METHOD_SCREENOFF_TTS, NULL, NULL);
+
+       if (ret < 0)
+               _E("Failed to tts(%d)", ret);
+}
+
+inline void lcd_on_procedure(void)
+{
+       broadcast_lcd_on();
+       /* AMOLED Low Power Mode off */
+       if (display_conf.alpm_on == true &&
+           alpm_set_state != NULL) {
+               if (alpm_set_state(false) < 0)
+                       _E("Failed to ALPM off");
+       }
+       backlight_ops.update();
+       backlight_ops.on();
+       touch_ops.screen_on();
+}
+
+inline void lcd_off_procedure(void)
+{
+       if (standby_mode) {
+               _D("standby mode! lcd off logic is skipped");
+               return;
+       }
+       /* AMOLED Low Power Mode on */
+       if (display_conf.alpm_on == true &&
+           alpm_set_state != NULL) {
+               if (alpm_set_state(true) < 0)
+                       _E("Failed to ALPM on!");
+       }
+       broadcast_lcd_off();
+       backlight_ops.off();
+       touch_ops.screen_off();
+
+       if (tts_state)
+               tts_lcd_off();
+}
+
+int low_battery_state(int val)
+{
+       switch (val) {
+       case VCONFKEY_SYSMAN_BAT_POWER_OFF:
+       case VCONFKEY_SYSMAN_BAT_CRITICAL_LOW:
+       case VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF:
+               return true;
+       }
+       return false;
+}
+
+int get_hallic_open(void)
+{
+       return hallic_open;
+}
+
+static int refresh_app_cond()
+{
+       trans_condition = 0;
+
+       if (cond_head[S_LCDDIM] != NULL)
+               trans_condition = trans_condition | MASK_DIM;
+       if (cond_head[S_LCDOFF] != NULL)
+               trans_condition = trans_condition | MASK_OFF;
+       if (cond_head[S_SLEEP] != NULL)
+               trans_condition = trans_condition | MASK_SLP;
+
+       return 0;
+}
+
+static PmLockNode *find_node(enum state_t s_index, pid_t pid)
+{
+       PmLockNode *t = cond_head[s_index];
+
+       while (t != NULL) {
+               if (t->pid == pid)
+                       break;
+               t = t->next;
+       }
+       return t;
+}
+
+static PmLockNode *add_node(enum state_t s_index, pid_t pid, Ecore_Timer *timeout_id,
+               bool holdkey_block)
+{
+       PmLockNode *n;
+       time_t now;
+
+       n = (PmLockNode *) malloc(sizeof(PmLockNode));
+       if (n == NULL) {
+               _E("Not enough memory, add cond. fail");
+               return NULL;
+       }
+
+       time(&now);
+       n->pid = pid;
+       n->timeout_id = timeout_id;
+       n->time = now;
+       n->holdkey_block = holdkey_block;
+       n->next = cond_head[s_index];
+       cond_head[s_index] = n;
+
+       refresh_app_cond();
+       return n;
+}
+
+static int del_node(enum state_t s_index, PmLockNode *n)
+{
+       PmLockNode *t;
+       PmLockNode *prev;
+
+       if (n == NULL)
+               return 0;
+
+       t = cond_head[s_index];
+       prev = NULL;
+       while (t != NULL) {
+               if (t == n) {
+                       if (prev != NULL)
+                               prev->next = t->next;
+                       else
+                               cond_head[s_index] = cond_head[s_index]->next;
+                       /* delete timer */
+                       if (t->timeout_id)
+                               ecore_timer_del(t->timeout_id);
+                       free(t);
+                       break;
+               }
+               prev = t;
+               t = t->next;
+       }
+       refresh_app_cond();
+       return 0;
+}
+
+static void print_node(int next)
+{
+       PmLockNode *n;
+       char buf[30];
+       time_t now;
+       double diff;
+
+       if (next <= S_START || next >= S_END)
+               return;
+
+       time(&now);
+       n = cond_head[next];
+       while (n != NULL) {
+               diff = difftime(now, n->time);
+               ctime_r(&n->time, buf);
+
+               if (diff > LOCK_TIME_ERROR)
+                       _E("over %.0f s, pid: %5d, lock time: %s", diff, n->pid, buf);
+               else if (diff > LOCK_TIME_WARNING)
+                       _I("over %.0f s, pid: %5d, lock time: %s", diff, n->pid, buf);
+               else
+                       _I("pid: %5d, lock time: %s", n->pid, buf);
+
+               n = n->next;
+       }
+}
+
+void get_pname(pid_t pid, char *pname)
+{
+       char buf[PATH_MAX];
+       int cmdline, r;
+
+       if (pid >= INTERNAL_LOCK_BASE)
+               snprintf(buf, PATH_MAX, "/proc/%d/cmdline", getpid());
+       else
+               snprintf(buf, PATH_MAX, "/proc/%d/cmdline", pid);
+
+       cmdline = open(buf, O_RDONLY);
+       if (cmdline < 0) {
+               pname[0] = '\0';
+               _E("%d does not exist now(may be dead without unlock)", pid);
+               return;
+       }
+
+       r = read(cmdline, pname, PATH_MAX);
+       if ((r >= 0) && (r < PATH_MAX))
+               pname[r] = '\0';
+       else
+               pname[0] = '\0';
+
+       close(cmdline);
+}
+
+static Eina_Bool del_dim_cond(void *data)
+{
+       PmLockNode *tmp = NULL;
+       char pname[PATH_MAX];
+       pid_t pid = (pid_t)data;
+
+       _I("delete prohibit dim condition by timeout\n");
+
+       tmp = find_node(S_LCDDIM, pid);
+       del_node(S_LCDDIM, tmp);
+       get_pname(pid, pname);
+       set_unlock_time(pname, S_NORMAL);
+
+       if (!timeout_src_id)
+               states[pm_cur_state].trans(EVENT_TIMEOUT);
+
+       return EINA_FALSE;
+}
+
+static Eina_Bool del_off_cond(void *data)
+{
+       PmLockNode *tmp = NULL;
+       char pname[PATH_MAX];
+       pid_t pid = (pid_t)data;
+
+       _I("delete prohibit off condition by timeout\n");
+
+       tmp = find_node(S_LCDOFF, pid);
+       del_node(S_LCDOFF, tmp);
+       get_pname(pid, pname);
+       set_unlock_time(pname, S_LCDDIM);
+
+       if (!timeout_src_id)
+               states[pm_cur_state].trans(EVENT_TIMEOUT);
+
+       return EINA_FALSE;
+}
+
+static Eina_Bool del_sleep_cond(void *data)
+{
+       PmLockNode *tmp = NULL;
+       char pname[PATH_MAX];
+       pid_t pid = (pid_t)data;
+
+       _I("delete prohibit sleep condition by timeout\n");
+
+       tmp = find_node(S_SLEEP, pid);
+       del_node(S_SLEEP, tmp);
+       get_pname(pid, pname);
+       set_unlock_time(pname, S_LCDOFF);
+
+       if (!timeout_src_id)
+               states[pm_cur_state].trans(EVENT_TIMEOUT);
+
+       set_process_active(EINA_FALSE, (pid_t)data);
+       return EINA_FALSE;
+}
+
+/* timeout handler  */
+Eina_Bool timeout_handler(void *data)
+{
+       _I("Time out state %s\n", state_string[pm_cur_state]);
+
+       if (timeout_src_id) {
+               ecore_timer_del(timeout_src_id);
+               timeout_src_id = NULL;
+       }
+
+       states[pm_cur_state].trans(EVENT_TIMEOUT);
+       return EINA_FALSE;
+}
+
+inline static void reset_timeout(int timeout)
+{
+       if (timeout_src_id != 0) {
+               ecore_timer_del(timeout_src_id);
+               timeout_src_id = NULL;
+       }
+       if (timeout > 0)
+               timeout_src_id = ecore_timer_add(MSEC_TO_SEC(timeout),
+                   (Ecore_Task_Cb)timeout_handler, NULL);
+       else if (timeout == 0)
+               states[pm_cur_state].trans(EVENT_TIMEOUT);
+}
+
+/* get configurations from setting */
+static int get_lcd_timeout_from_settings(void)
+{
+       int i;
+       int val = 0;
+       int ret = -1;
+       char *buf;
+
+       for (i = 0; i < S_END; i++) {
+               switch (states[i].state) {
+               case S_NORMAL:
+                       ret = get_run_timeout(&val);
+                       if (ret != 0) {
+                               buf = getenv("PM_TO_NORMAL");
+                               val = (buf ? atoi(buf) : DEFAULT_NORMAL_TIMEOUT);
+                       }
+                       break;
+               case S_LCDDIM:
+                       get_dim_timeout(&val);
+                       break;
+               case S_LCDOFF:
+                       val = display_conf.lcdoff_timeout;
+                       break;
+               default:
+                       /* This state doesn't need to set time out. */
+                       val = 0;
+                       break;
+               }
+               if (val > 0)
+                       states[i].timeout = val;
+
+               _I("%s state : %d ms timeout", state_string[i],
+                       states[i].timeout);
+       }
+
+       return 0;
+}
+
+static void update_display_time(void)
+{
+       int ret, run_timeout, val;
+
+       /* first priority : s cover */
+       if (!hallic_open) {
+               states[S_NORMAL].timeout = S_COVER_TIMEOUT;
+               _I("S cover closed : timeout is set by normal(%d ms)",
+                   S_COVER_TIMEOUT);
+               return;
+       }
+
+       /* second priority : custom timeout */
+       if (custom_normal_timeout > 0) {
+               states[S_NORMAL].timeout = custom_normal_timeout;
+               states[S_LCDDIM].timeout = custom_dim_timeout;
+               _I("CUSTOM : timeout is set by normal(%d ms), dim(%d ms)",
+                   custom_normal_timeout, custom_dim_timeout);
+               return;
+       }
+
+       /* third priority : lock state */
+       if ((get_lock_screen_state() == VCONFKEY_IDLE_LOCK) &&
+           !get_lock_screen_bg_state()) {
+               if (pm_status_flag & SMAST_FLAG) {
+                       /* smart stay is on, timeout is always 5 seconds. */
+                       states[S_NORMAL].timeout = LOCK_SCREEN_CONTROL_TIMEOUT;
+                       _I("LOCK : timeout is set, smart stay timeout(%d ms)",
+                           LOCK_SCREEN_CONTROL_TIMEOUT);
+               } else {
+                       /* timeout is different according to key or event. */
+                       states[S_NORMAL].timeout = lock_screen_timeout;
+                       _I("LOCK : timeout is set by normal(%d ms)",
+                           lock_screen_timeout);
+               }
+               return;
+       }
+
+       /* default setting */
+       ret = get_run_timeout(&run_timeout);
+       if (ret < 0 || run_timeout <= 0) {
+               _E("Can not get run timeout. set default %d ms",
+                   DEFAULT_NORMAL_TIMEOUT);
+               run_timeout = DEFAULT_NORMAL_TIMEOUT;
+       }
+       states[S_NORMAL].timeout = run_timeout;
+
+       get_dim_timeout(&val);
+       states[S_LCDDIM].timeout = val;
+       
+       _I("Normal: NORMAL timeout is set by %d ms", states[S_NORMAL].timeout);
+       _I("Normal: DIM timeout is set by %d ms", states[S_LCDDIM].timeout);
+}
+
+static void update_display_locktime(int time)
+{
+       lock_screen_timeout = time;
+       update_display_time();
+}
+
+void lcd_on_direct(void)
+{
+       int ret, call_state;
+
+       if (power_ops.get_power_lock_support()
+           && pm_cur_state == S_SLEEP)
+               power_ops.power_lock();
+
+       if (pre_suspend_flag == true) {
+               power_ops.post_resume();
+               pre_suspend_flag = false;
+       }
+#ifdef MICRO_DD
+       _D("lcd is on directly");
+       gettimeofday(&lcdon_tv, NULL);
+       if (hbm_check_timeout != NULL)
+               hbm_check_timeout();
+       lcd_on_procedure();
+       reset_timeout(DD_LCDOFF_INPUT_TIMEOUT);
+#else
+       ret = vconf_get_int(VCONFKEY_CALL_STATE, &call_state);
+       if ((ret >= 0 && call_state != VCONFKEY_CALL_OFF) ||
+           (get_lock_screen_state() == VCONFKEY_IDLE_LOCK)) {
+               _D("LOCK state, lcd is on directly");
+               lcd_on_procedure();
+       }
+       reset_timeout(display_conf.lcdoff_timeout);
+#endif
+       update_display_locktime(LOCK_SCREEN_INPUT_TIMEOUT);
+}
+
+int custom_lcdon(int timeout)
+{
+       struct state *st;
+
+       if (timeout <= 0)
+               return -EINVAL;
+
+       if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
+               lcd_on_direct();
+
+       _I("custom lcd on %d ms", timeout);
+       if (set_custom_lcdon_timeout(timeout) == true)
+               update_display_time();
+
+       /* state transition */
+       pm_old_state = pm_cur_state;
+       pm_cur_state = S_NORMAL;
+       st = &states[pm_cur_state];
+
+       /* enter action */
+       if (st->action) {
+               st->action(st->timeout);
+       }
+
+       return 0;
+}
+
+static int proc_change_state(unsigned int cond, pid_t pid)
+{
+       int next_state = 0;
+       struct state *st;
+       int i;
+
+       for (i = S_NORMAL; i < S_END; i++) {
+               if ((cond >> (SHIFT_CHANGE_STATE + i)) & 0x1) {
+                       next_state = i;
+                       break;
+               }
+       }
+       _I("Change State to %s (%d)", state_string[next_state], pid);
+
+       if (next_state == S_NORMAL) {
+               if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
+                       lcd_on_direct();
+       } else if (next_state == S_LCDOFF) {
+               if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
+                       lcd_off_procedure();
+       }
+
+       if (next_state == S_LCDOFF)
+               if (set_custom_lcdon_timeout(0) == true)
+                       update_display_time();
+
+       switch (next_state) {
+       case S_NORMAL:
+               update_display_locktime(LOCK_SCREEN_CONTROL_TIMEOUT);
+               /* fall through */
+       case S_LCDDIM:
+               /* fall through */
+       case S_LCDOFF:
+               /* state transition */
+               pm_old_state = pm_cur_state;
+               pm_cur_state = next_state;
+               st = &states[pm_cur_state];
+
+               /* pm state is updated to dim because of standby mode */
+               if (standby_mode && (pm_cur_state == S_LCDOFF))
+                       set_setting_pmstate(S_LCDDIM);
+
+               /* enter action */
+               if (st->action) {
+                       st->action(st->timeout);
+               }
+               break;
+       case S_SLEEP:
+               _I("Dangerous requests.");
+               /* at first LCD_OFF and then goto sleep */
+               /* state transition */
+               pm_old_state = pm_cur_state;
+               pm_cur_state = S_LCDOFF;
+               st = &states[pm_cur_state];
+               if (st->action) {
+                       st->action(TIMEOUT_NONE);
+               }
+               delete_condition(S_SLEEP);
+               pm_old_state = pm_cur_state;
+               pm_cur_state = S_SLEEP;
+               st = &states[pm_cur_state];
+               if (st->action) {
+                       st->action(TIMEOUT_NONE);
+               }
+               break;
+
+       default:
+               return -1;
+       }
+
+       return 0;
+}
+
+static int standby_action(int timeout)
+{
+       if (backlight_ops.standby() < 0) {
+               _E("Fail to start standby mode!");
+               return -EIO;
+       }
+       if (CHECK_OPS(keyfilter_ops, backlight_enable))
+               keyfilter_ops->backlight_enable(false);
+       touch_ops.key_off();
+       touch_ops.screen_off();
+
+       set_standby_state(true);
+
+       _I("standby mode (only LCD OFF, But phone is working normal)");
+       reset_timeout(timeout);
+
+       return 0;
+}
+
+static void set_standby_mode(pid_t pid, int enable)
+{
+       Eina_List *l = NULL;
+       Eina_List *l_next = NULL;
+       int *data = 0;
+
+       if (enable) {
+               EINA_LIST_FOREACH(standby_mode_list, l, data)
+                       if (pid == (int) data) {
+                               _E("%d already acquired standby mode", pid);
+                               return;
+                       }
+               EINA_LIST_APPEND(standby_mode_list, (void *)pid);
+               _I("%d acquire standby mode", pid);
+               if (standby_mode)
+                       return;
+               standby_mode = true;
+               basic_action = states[S_LCDOFF].action;
+               states[S_LCDOFF].action = standby_action;
+               trans_table[S_LCDOFF][EVENT_TIMEOUT] = S_LCDOFF;
+               _I("Standby mode is enabled!");
+       } else {
+               if (!standby_mode)
+                       return;
+               EINA_LIST_FOREACH_SAFE(standby_mode_list, l, l_next, data)
+                       if (pid == (int) data) {
+                               standby_mode_list = eina_list_remove_list(
+                                                   standby_mode_list, l);
+                               _I("%d release standby mode", pid);
+                       }
+               if (standby_mode_list != NULL)
+                       return;
+               set_standby_state(false);
+               standby_mode = false;
+               if (basic_action != NULL) {
+                       states[S_LCDOFF].action = basic_action;
+               }
+               trans_table[S_LCDOFF][EVENT_TIMEOUT] = S_SLEEP;
+               proc_change_state(S_NORMAL << (SHIFT_CHANGE_STATE + S_NORMAL),
+                   getpid());
+               _I("Standby mode is disabled!");
+       }
+}
+
+/* update transition condition for application requrements */
+static int proc_condition(PMMsg *data)
+{
+       PmLockNode *tmp = NULL;
+       unsigned int val = data->cond;
+       pid_t pid = data->pid;
+       Ecore_Timer *cond_timeout_id = NULL;
+       bool holdkey_block = 0;
+       int val_timeout;
+
+       if (val == 0)
+               return 0;
+       /* for debug */
+       char pname[PATH_MAX];
+       time_t now;
+
+       get_pname(pid, pname);
+       val_timeout = val >> SHIFT_CHANGE_TIMEOUT;
+       if (val_timeout & (CUSTOM_TIMEOUT_BIT | CUSTOM_HOLDKEY_BIT)) {
+               if (data->timeout == 0 && data->timeout2 == 0) {
+                       _I("LCD timeout changed : default setting");
+                       get_lcd_timeout_from_settings();
+                       if (get_lock_screen_state() == VCONFKEY_IDLE_LOCK) {
+                               _I("LOCK state : setting lock timeout!");
+                               states[S_NORMAL].timeout = lock_screen_timeout;
+                       }
+                       custom_normal_timeout = custom_dim_timeout = 0;
+                       if (!(val_timeout & CUSTOM_HOLDKEY_BIT))
+                               custom_change_pid = -1;
+               } else {
+                       _I("LCD timeout changed : normal(%d s), dim(%d s)",
+                               data->timeout, data->timeout2);
+                       custom_normal_timeout = SEC_TO_MSEC(data->timeout);
+                       states[S_NORMAL].timeout = custom_normal_timeout;
+                       custom_dim_timeout = SEC_TO_MSEC(data->timeout2);
+                       states[S_LCDDIM].timeout = custom_dim_timeout;
+                       custom_change_pid = pid;
+               }
+
+               if (val_timeout & CUSTOM_HOLDKEY_BIT) {
+                       custom_holdkey_block = true;
+                       custom_change_pid = pid;
+                       _I("hold key disabled !");
+               } else {
+                       custom_holdkey_block = false;
+                       _I("hold key enabled !");
+               }
+       }
+
+       if (val & MASK_DIM) {
+               if (data->timeout > 0) {
+                       cond_timeout_id =
+                           ecore_timer_add(MSEC_TO_SEC(data->timeout),
+                                   (Ecore_Task_Cb)del_dim_cond, (void*)pid);
+               }
+               holdkey_block = GET_HOLDKEY_BLOCK_STATE(val);
+               tmp = find_node(S_LCDDIM, pid);
+               if (tmp == NULL) {
+                       add_node(S_LCDDIM, pid, cond_timeout_id, holdkey_block);
+               } else {
+                       if (data->timeout > 0) {
+                               time(&now);
+                               tmp->time = now;
+                       }
+                       if (tmp->timeout_id) {
+                               ecore_timer_del(tmp->timeout_id);
+                               tmp->timeout_id = cond_timeout_id;
+                       }
+                       tmp->holdkey_block = holdkey_block;
+               }
+               /* for debug */
+               _SD("[%s] locked by pid %d - process %s holdkeyblock %d\n",
+                   "S_NORMAL", pid, pname, holdkey_block);
+               set_lock_time(pname, S_NORMAL);
+       }
+       if (val & MASK_OFF) {
+               if (data->timeout > 0) {
+                       cond_timeout_id =
+                           ecore_timer_add(MSEC_TO_SEC(data->timeout),
+                                   (Ecore_Task_Cb)del_off_cond, (void*)pid);
+               }
+               holdkey_block = GET_HOLDKEY_BLOCK_STATE(val);
+               tmp = find_node(S_LCDOFF, pid);
+               if (tmp == NULL) {
+                       add_node(S_LCDOFF, pid, cond_timeout_id, holdkey_block);
+               } else {
+                       if (data->timeout > 0) {
+                               time(&now);
+                               tmp->time = now;
+                       }
+                       if (tmp->timeout_id) {
+                               ecore_timer_del(tmp->timeout_id);
+                               tmp->timeout_id = cond_timeout_id;
+                       }
+                       tmp->holdkey_block = holdkey_block;
+               }
+               /* for debug */
+               _SD("[%s] locked by pid %d - process %s holdkeyblock %d\n",
+                   "S_LCDDIM", pid, pname, holdkey_block);
+               set_lock_time(pname, S_LCDDIM);
+       }
+       if (val & MASK_SLP) {
+               /*
+                * pm-state must be changed to LCDOFF,
+                * to guarantee of LCDOFF-lock
+                * when system resumes from suspend state.
+                */
+               if (pm_cur_state == S_SLEEP)
+                       proc_change_state(S_LCDOFF <<
+                           (SHIFT_CHANGE_STATE + S_LCDOFF), getpid());
+               if (data->timeout > 0) {
+                       cond_timeout_id =
+                           ecore_timer_add(MSEC_TO_SEC(data->timeout),
+                                   (Ecore_Task_Cb)del_sleep_cond, (void*)pid);
+               }
+               if (GET_STANDBY_MODE_STATE(val))
+                       set_standby_mode(pid, true);
+               tmp = find_node(S_SLEEP, pid);
+               if (tmp == NULL) {
+                       add_node(S_SLEEP, pid, cond_timeout_id, 0);
+               } else {
+                       if (data->timeout > 0) {
+                               time(&now);
+                               tmp->time = now;
+                       }
+                       if (tmp->timeout_id) {
+                               ecore_timer_del(tmp->timeout_id);
+                               tmp->timeout_id = cond_timeout_id;
+                       }
+                       tmp->holdkey_block = 0;
+               }
+               set_process_active(EINA_TRUE, pid);
+
+               /* for debug */
+               _SD("[%s] locked by pid %d - process %s\n", "S_LCDOFF", pid,
+                       pname);
+               set_lock_time(pname, S_LCDOFF);
+       }
+
+       /* UNLOCK(GRANT) condition processing */
+       val = val >> SHIFT_UNLOCK;
+       if (val & MASK_DIM) {
+               tmp = find_node(S_LCDDIM, pid);
+               del_node(S_LCDDIM, tmp);
+               _SD("[%s] unlocked by pid %d - process %s\n", "S_NORMAL",
+                       pid, pname);
+               set_unlock_time(pname, S_NORMAL);
+       }
+       if (val & MASK_OFF) {
+               tmp = find_node(S_LCDOFF, pid);
+               del_node(S_LCDOFF, tmp);
+               _SD("[%s] unlocked by pid %d - process %s\n", "S_LCDDIM",
+                       pid, pname);
+               set_unlock_time(pname, S_LCDDIM);
+       }
+       if (val & MASK_SLP) {
+               tmp = find_node(S_SLEEP, pid);
+               del_node(S_SLEEP, tmp);
+               if (standby_mode)
+                       set_standby_mode(pid, false);
+               set_process_active(EINA_FALSE, pid);
+
+               _SD("[%s] unlocked by pid %d - process %s\n", "S_LCDOFF",
+                       pid, pname);
+               set_unlock_time(pname, S_LCDOFF);
+       }
+       val = val >> 8;
+       if (val != 0) {
+               if ((val & 0x1)) {
+                       reset_timeout(states[pm_cur_state].timeout);
+                       _I("reset timeout (%d ms)",
+                           states[pm_cur_state].timeout);
+               }
+       } else {
+               /* guard time for suspend */
+               if (pm_cur_state == S_LCDOFF) {
+                       reset_timeout(states[S_LCDOFF].timeout);
+                       _I("margin timeout (%d ms)",
+                           states[S_LCDOFF].timeout);
+               }
+       }
+
+       if (timeout_src_id == 0)
+               states[pm_cur_state].trans(EVENT_TIMEOUT);
+
+       return 0;
+}
+
+/* If some changed, return 1 */
+int check_processes(enum state_t prohibit_state)
+{
+       PmLockNode *t = cond_head[prohibit_state];
+       PmLockNode *tmp = NULL;
+       int ret = 0;
+
+       while (t != NULL) {
+               if (t->pid < INTERNAL_LOCK_BASE && kill(t->pid, 0) == -1) {
+                       _E("%d process does not exist, delete the REQ"
+                               " - prohibit state %d ",
+                               t->pid, prohibit_state);
+                       if (t->pid == custom_change_pid) {
+                               get_lcd_timeout_from_settings();
+                               custom_normal_timeout = custom_dim_timeout = 0;
+                               custom_change_pid = -1;
+                       }
+                       if (standby_mode)
+                               set_standby_mode(t->pid, false);
+                       tmp = t;
+                       ret = 1;
+               }
+               t = t->next;
+
+               if (tmp != NULL) {
+                       del_node(prohibit_state, tmp);
+                       tmp = NULL;
+               }
+       }
+
+       return ret;
+}
+
+int check_holdkey_block(enum state_t state)
+{
+       PmLockNode *t = cond_head[state];
+       int ret = 0;
+
+       _I("check holdkey block : state of %s", state_string[state]);
+
+       if (custom_holdkey_block == true) {
+               _I("custom hold key blocked by pid(%d)",
+                       custom_change_pid);
+               return 1;
+       }
+
+       while (t != NULL) {
+               if (t->holdkey_block == true) {
+                       ret = 1;
+                       _I("Hold key blocked by pid(%d)!", t->pid);
+                       break;
+               }
+               t = t->next;
+       }
+
+       return ret;
+}
+
+int delete_condition(enum state_t state)
+{
+       PmLockNode *t = cond_head[state];
+       int ret = 0;
+       PmLockNode *tmp = NULL;
+       pid_t pid;
+       char pname[PATH_MAX];
+
+       _I("delete condition : state of %s", state_string[state]);
+
+       while (t != NULL) {
+               if (t->timeout_id > 0) {
+                       ecore_timer_del(t->timeout_id);
+                       t->timeout_id = NULL;
+               }
+               tmp = t;
+               t = t->next;
+               pid = tmp->pid;
+               if (state == S_SLEEP)
+                       set_process_active(EINA_FALSE, pid);
+               _I("delete node of pid(%d)", pid);
+               del_node(state, tmp);
+               get_pname(pid, pname);
+               set_unlock_time(pname, state-1);
+       }
+
+       return 0;
+}
+
+void update_lcdoff_source(int source)
+{
+       if (standby_mode)
+               return;
+
+       switch(source) {
+       case VCONFKEY_PM_LCDOFF_BY_TIMEOUT:
+               _I("LCD OFF by timeout");
+               break;
+       case VCONFKEY_PM_LCDOFF_BY_POWERKEY:
+               _I("LCD OFF by powerkey");
+               break;
+       default:
+               _E("Invalid value(%d)", source);
+               return;
+       }
+       vconf_set_int(VCONFKEY_PM_LCDOFF_SOURCE, source);
+}
+
+#ifdef ENABLE_PM_LOG
+
+typedef struct _pm_history {
+        time_t time;
+        enum pm_log_type log_type;
+        int keycode;
+} pm_history;
+
+static int max_history_count = MAX_LOG_COUNT;
+static pm_history pm_history_log[MAX_LOG_COUNT] = {0,};
+static int history_count = 0;
+
+static const char history_string[PM_LOG_MAX][15] =
+       {"PRESS", "LONG PRESS", "RELEASE", "LCD ON", "LCD ON FAIL",
+       "LCD DIM", "LCD DIM FAIL", "LCD OFF", "LCD OFF FAIL", "SLEEP"};
+
+void pm_history_init()
+{
+       memset(pm_history_log, 0x0, sizeof(pm_history_log));
+       history_count = 0;
+       max_history_count = MAX_LOG_COUNT;
+}
+
+void pm_history_save(enum pm_log_type log_type, int code)
+{
+        time_t now;
+
+        time(&now);
+        pm_history_log[history_count].time = now;
+        pm_history_log[history_count].log_type = log_type;
+        pm_history_log[history_count].keycode = code;
+        history_count++;
+
+        if (history_count >= max_history_count)
+                history_count = 0;
+}
+
+void pm_history_print(int fd, int count)
+{
+       int start_index, index, i;
+       char buf[255];
+       char time_buf[30];
+
+       if (count <= 0 || count > max_history_count)
+               return;
+
+       start_index = (history_count - count + max_history_count)
+                   % max_history_count;
+
+       for (i = 0; i < count; i++) {
+               index = (start_index + i) % max_history_count;
+
+               if (pm_history_log[index].time == 0)
+                       continue;
+
+               if (pm_history_log[index].log_type < PM_LOG_MIN ||
+                   pm_history_log[index].log_type >= PM_LOG_MAX)
+                       continue;
+               ctime_r(&pm_history_log[index].time, time_buf);
+               snprintf(buf, sizeof(buf), "[%3d] %15s %3d %s",
+                       index,
+                       history_string[pm_history_log[index].log_type],
+                       pm_history_log[index].keycode,
+                       time_buf);
+               write(fd, buf, strlen(buf));
+       }
+}
+#endif
+
+/* logging indev_list for debug */
+void print_dev_list(int fd)
+{
+       int i;
+       unsigned int total = 0;
+       indev *tmp;
+
+       total = eina_list_count(indev_list);
+       _I("***** total list : %d *****", total);
+       for (i = 0; i < total; i++) {
+               tmp = (indev*)eina_list_nth(indev_list, i);
+               _I("* %d | path:%s, fd:%d, dev_fd:%d",
+                       i, tmp->dev_path, tmp->fd, tmp->dev_fd);
+               if (fd >= 0) {
+                       char buf[255];
+                       snprintf(buf, sizeof(buf), " %2d| path:%s, fd:%d, dev_fd:%d\n",
+                               i, tmp->dev_path, tmp->fd, tmp->dev_fd);
+                       write(fd, buf, strlen(buf));
+               }
+       }
+       _I("***************************\n");
+}
+
+void print_info(int fd)
+{
+       int s_index = 0;
+       char buf[255];
+       int i = 1, ret;
+       Eina_List *l = NULL;
+       int *data = 0;
+       char pname[PATH_MAX];
+
+       if (fd < 0)
+               return;
+
+       snprintf(buf, sizeof(buf),
+               "\n==========================================="
+               "===========================\n");
+       write(fd, buf, strlen(buf));
+       snprintf(buf, sizeof(buf),"Timeout Info: Run[%dms] Dim[%dms] Off[%dms]\n",
+                states[S_NORMAL].timeout,
+                states[S_LCDDIM].timeout, states[S_LCDOFF].timeout);
+       write(fd, buf, strlen(buf));
+
+       snprintf(buf, sizeof(buf), "Tran. Locked : %s %s %s\n",
+                (trans_condition & MASK_DIM) ? state_string[S_NORMAL] : "-",
+                (trans_condition & MASK_OFF) ? state_string[S_LCDDIM] : "-",
+                (trans_condition & MASK_SLP) ? state_string[S_LCDOFF] : "-");
+       write(fd, buf, strlen(buf));
+
+       snprintf(buf, sizeof(buf), "Current State: %s\n",
+               state_string[pm_cur_state]);
+       write(fd, buf, strlen(buf));
+
+       snprintf(buf, sizeof(buf), "Current Lock Conditions: \n");
+       write(fd, buf, strlen(buf));
+
+       for (s_index = S_NORMAL; s_index < S_END; s_index++) {
+               PmLockNode *t;
+               char time_buf[30];
+               t = cond_head[s_index];
+
+               while (t != NULL) {
+                       get_pname((pid_t)t->pid, pname);
+                       ctime_r(&t->time, time_buf);
+                       snprintf(buf, sizeof(buf),
+                                " %d: [%s] locked by pid %d %s %s",
+                                i++, state_string[s_index - 1], t->pid, pname, time_buf);
+                       write(fd, buf, strlen(buf));
+                       t = t->next;
+               }
+       }
+
+       print_dev_list(fd);
+
+       if (standby_mode) {
+               snprintf(buf, sizeof(buf), "\n\nstandby mode is on\n");
+               write(fd, buf, strlen(buf));
+
+               EINA_LIST_FOREACH(standby_mode_list, l, data) {
+                       get_pname((pid_t)data, pname);
+                       snprintf(buf, sizeof(buf),
+                           "  standby mode acquired by pid %d"
+                           " - process %s\n", data, pname);
+                        write(fd, buf, strlen(buf));
+               }
+       }
+       print_lock_info_list(fd);
+
+#ifdef ENABLE_PM_LOG
+       pm_history_print(fd, 250);
+#endif
+}
+
+void save_display_log(void)
+{
+       int fd;
+       char buf[255];
+       time_t now_time;
+       char time_buf[30];
+
+       _D("internal state is saved!");
+
+       time(&now_time);
+       ctime_r(&now_time, time_buf);
+
+       fd = open(PM_STATE_LOG_FILE, O_CREAT | O_TRUNC | O_WRONLY, 0644);
+       if (fd != -1) {
+               snprintf(buf, sizeof(buf),
+                       "\npm_state_log now-time : %d(s) %s\n\n",
+                       (int)now_time, time_buf);
+               write(fd, buf, strlen(buf));
+
+               snprintf(buf, sizeof(buf), "pm_status_flag: %x\n", pm_status_flag);
+               write(fd, buf, strlen(buf));
+
+               snprintf(buf, sizeof(buf), "screen lock status : %d\n",
+                       get_lock_screen_state());
+               write(fd, buf, strlen(buf));
+
+               print_info(fd);
+               close(fd);
+       }
+
+       fd = open("/dev/console", O_WRONLY);
+       if (fd != -1) {
+               print_info(fd);
+               close(fd);
+       }
+}
+
+/* SIGHUP signal handler
+ * For debug... print info to syslog
+ */
+static void sig_hup(int signo)
+{
+       save_display_log();
+}
+
+static void sig_usr(int signo)
+{
+       pm_status_flag |= VCALL_FLAG;
+}
+
+int check_lcdoff_direct(void)
+{
+       int ret, lock, cradle;
+
+       if (standby_mode)
+               return false;
+
+       lock = get_lock_screen_state();
+       if (lock != VCONFKEY_IDLE_LOCK && hallic_open)
+               return false;
+
+       if (hdmi_state)
+               return false;
+
+       ret = vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle);
+       if (ret >= 0 && cradle == DOCK_SOUND)
+               return false;
+
+       if (pm_old_state != S_NORMAL)
+               return false;
+
+       if (pm_cur_state != S_LCDDIM)
+               return false;
+
+       /*
+        * goto lcd dim state when battery health is bad
+        * and abnormal popup shows
+        */
+       if ((pm_status_flag & DIMSTAY_FLAG) &&
+           (check_abnormal_popup() == HEALTH_BAD))
+               return false;
+
+       _D("Goto LCDOFF direct(%d,%d,%d)", lock, hdmi_state, cradle);
+
+       return true;
+}
+
+int check_lcdoff_lock_state(void)
+{
+       if (cond_head[S_SLEEP] != NULL)
+               return true;
+
+       return false;
+}
+
+/*
+ * default transition function
+ *   1. call check
+ *   2. transition
+ *   3. call enter action function
+ */
+static int default_trans(int evt)
+{
+       struct state *st = &states[pm_cur_state];
+       int next_state;
+
+       next_state = (enum state_t)trans_table[pm_cur_state][evt];
+
+       /* check conditions */
+       while (st->check && !st->check(next_state)) {
+               /* There is a condition. */
+               if (standby_mode) {
+                       _D("standby mode, goto next_state %s",
+                           state_string[next_state]);
+                       break;
+               }
+               _I("%s -> %s : check fail", state_string[pm_cur_state],
+                      state_string[next_state]);
+               if (!check_processes(next_state)) {
+                       /* this is valid condition - the application that sent the condition is running now. */
+                       return -1;
+               }
+       }
+
+       /* smart stay */
+       if (display_info.face_detection &&
+           (pm_status_flag & SMAST_FLAG) && hallic_open) {
+               if (display_info.face_detection(evt, pm_cur_state, next_state))
+                       return 0;
+       }
+
+       /* state transition */
+       pm_old_state = pm_cur_state;
+       pm_cur_state = next_state;
+       st = &states[pm_cur_state];
+
+       /* enter action */
+       if (st->action) {
+               if (pm_cur_state == S_LCDOFF)
+                       update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
+
+               if (pm_cur_state == S_NORMAL || pm_cur_state == S_LCDOFF)
+                       if (set_custom_lcdon_timeout(0) == true)
+                               update_display_time();
+
+               if (check_lcdoff_direct() == true) {
+                       /* enter next state directly */
+                       states[pm_cur_state].trans(EVENT_TIMEOUT);
+               }
+               else {
+                       st->action(st->timeout);
+               }
+       }
+
+       return 0;
+}
+
+static Eina_Bool lcd_on_expired(void *data)
+{
+       int lock_state, ret;
+
+       if (lock_timeout_id)
+               lock_timeout_id = NULL;
+
+       /* check state of lock */
+       ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
+
+       if (ret > 0 && lock_state == VCONFKEY_IDLE_LOCK)
+               return EINA_FALSE;
+
+       if (backlight_ops.get_lcd_power() == PM_LCD_POWER_ON)
+               return EINA_FALSE;
+
+       /* lock screen is not launched yet, but lcd is on */
+       if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
+               lcd_on_procedure();
+
+       return EINA_FALSE;
+}
+
+static inline void stop_lock_timer(void)
+{
+       if (lock_timeout_id) {
+               ecore_timer_del(lock_timeout_id);
+               lock_timeout_id = NULL;
+       }
+}
+
+static void check_lock_screen(void)
+{
+       int lock_setting, lock_state, app_state, ret;
+
+       stop_lock_timer();
+
+       ret = vconf_get_int(VCONFKEY_CALL_STATE, &app_state);
+       if (ret >= 0 && app_state != VCONFKEY_CALL_OFF)
+               goto lcd_on;
+
+       /* check setting of lock screen is enabled. */
+       ret = vconf_get_int(VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT,
+           &lock_setting);
+
+       if (ret < 0 || lock_setting == SETTING_SCREEN_LOCK_TYPE_NONE)
+               goto lcd_on;
+
+       /* check state of lock */
+       ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
+
+       if (ret < 0 || lock_state == VCONFKEY_IDLE_LOCK)
+               goto lcd_on;
+
+       /* Use time to check lock is done. */
+       lock_timeout_id = ecore_timer_add(display_conf.lock_wait_time,
+           (Ecore_Task_Cb)lcd_on_expired, (void*)NULL);
+
+       return;
+
+lcd_on:
+       if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
+               lcd_on_procedure();
+}
+
+/* default enter action function */
+static int default_action(int timeout)
+{
+       int ret;
+       int wakeup_count = -1;
+       char buf[NAME_MAX];
+       char *pkgname = NULL;
+       int i = 0;
+       int lock_state = -1;
+       int app_state = -1;
+       time_t now;
+       double diff;
+       static time_t last_update_time = 0;
+       static int last_timeout = 0;
+       struct timeval now_tv;
+
+       if (status != DEVICE_OPS_STATUS_START) {
+               _E("display is not started!");
+               return -EINVAL;
+       }
+
+       if (pm_cur_state != S_SLEEP) {
+               if (pm_cur_state == S_NORMAL &&
+                   lcdon_tv.tv_sec != 0) {
+                       gettimeofday(&now_tv, NULL);
+                       timeout -= DIFF_TIMEVAL_MS(now_tv, lcdon_tv);
+                       lcdon_tv.tv_sec = 0;
+               }
+               /* set timer with current state timeout */
+               reset_timeout(timeout);
+
+               if (pm_cur_state == S_NORMAL) {
+                       time(&last_update_time);
+                       last_timeout = timeout;
+               } else {
+                       _I("timout set: %s state %d ms",
+                           state_string[pm_cur_state], timeout);
+               }
+       }
+
+       if (pm_cur_state != pm_old_state && pm_cur_state != S_SLEEP) {
+               if (power_ops.get_power_lock_support())
+                       power_ops.power_lock();
+               if (pm_cur_state != S_LCDOFF)
+                       set_setting_pmstate(pm_cur_state);
+               device_notify(DEVICE_NOTIFIER_LCD, (void *)pm_cur_state);
+       }
+
+       if (pm_old_state == S_NORMAL && pm_cur_state != S_NORMAL) {
+               time(&now);
+               diff = difftime(now, last_update_time);
+               _I("S_NORMAL is changed to %s [%d ms, %.0f s]",
+                   state_string[pm_cur_state], last_timeout, diff);
+       }
+
+       switch (pm_cur_state) {
+       case S_NORMAL:
+               /*
+                * normal state : backlight on and restore
+                * the previous brightness
+                */
+               if (pm_old_state == S_LCDOFF || pm_old_state == S_SLEEP) {
+                       if (pre_suspend_flag == true) {
+                               power_ops.post_resume();
+                               pre_suspend_flag = false;
+                       }
+                       check_lock_screen();
+               } else if (pm_old_state == S_LCDDIM)
+                       backlight_ops.update();
+               set_standby_state(false);
+               break;
+
+       case S_LCDDIM:
+               if (pm_old_state == S_NORMAL &&
+                   backlight_ops.get_custom_status())
+                       backlight_ops.save_custom_brightness();
+               /* lcd dim state : dim the brightness */
+               backlight_ops.dim();
+               if (pm_old_state == S_LCDOFF || pm_old_state == S_SLEEP) {
+                       broadcast_lcd_on();
+                       backlight_ops.on();
+                       touch_ops.screen_on();
+                       touch_ops.key_on();
+               }
+               set_standby_state(false);
+               break;
+
+       case S_LCDOFF:
+               if (pm_old_state != S_SLEEP && pm_old_state != S_LCDOFF) {
+                       stop_lock_timer();
+                       /* lcd off state : turn off the backlight */
+                       if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
+                               lcd_off_procedure();
+                       set_setting_pmstate(pm_cur_state);
+
+                       if (pre_suspend_flag == false) {
+                               pre_suspend_flag = true;
+                               power_ops.pre_suspend();
+                       }
+               }
+
+               if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
+                       lcd_off_procedure();
+               break;
+
+       case S_SLEEP:
+               if (pm_old_state != S_SLEEP && pm_old_state != S_LCDOFF)
+                       stop_lock_timer();
+
+               if (backlight_ops.get_lcd_power() != PM_LCD_POWER_OFF)
+                       lcd_off_procedure();
+
+               if (!power_ops.get_power_lock_support()) {
+                       /* sleep state : set system mode to SUSPEND */
+                       if (device_get_property(DEVICE_TYPE_POWER,
+                           PROP_POWER_WAKEUP_COUNT, &wakeup_count) < 0)
+                               _E("wakeup count read error");
+
+                       if (wakeup_count < 0) {
+                               _I("Wakup Event! Can not enter suspend mode.");
+                               goto go_lcd_off;
+                       }
+
+                       if (device_set_property(DEVICE_TYPE_POWER,
+                           PROP_POWER_WAKEUP_COUNT, wakeup_count) < 0) {
+                               _E("wakeup count write error");
+                               goto go_lcd_off;
+                       }
+               }
+               goto go_suspend;
+       }
+
+       return 0;
+
+go_suspend:
+#ifdef ENABLE_PM_LOG
+       pm_history_save(PM_LOG_SLEEP, pm_cur_state);
+#endif
+       if (power_ops.get_power_lock_support()) {
+               if (power_ops.power_unlock() < 0)
+                       _E("power unlock state error!");
+       } else {
+               power_ops.suspend();
+               _I("system wakeup!!");
+               system_wakeup_flag = true;
+               /* Resume !! */
+               if (power_ops.check_wakeup_src() == EVENT_DEVICE)
+                       /* system waked up by devices */
+                       states[pm_cur_state].trans(EVENT_DEVICE);
+               else
+                       /* system waked up by user input */
+                       states[pm_cur_state].trans(EVENT_INPUT);
+       }
+       return 0;
+
+go_lcd_off:
+       if (!power_ops.get_power_lock_support()) {
+               /* Resume !! */
+               states[pm_cur_state].trans(EVENT_DEVICE);
+       }
+       return 0;
+}
+
+/*
+ * default check function
+ *   return
+ *    0 : can't transit, others : transitable
+ */
+static int default_check(int next)
+{
+       int trans_cond = trans_condition & MASK_BIT;
+       int lock_state = -1;
+       int app_state = -1;
+
+       vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
+       if (lock_state==VCONFKEY_IDLE_LOCK && next != S_SLEEP) {
+               while(0) {
+                       vconf_get_int(VCONFKEY_CALL_STATE, &app_state);
+                       if (app_state != VCONFKEY_CALL_OFF)
+                               break;
+                       vconf_get_bool(VCONFKEY_ALARM_RINGING, &app_state);
+                       if (app_state == EINA_TRUE)
+                               break;
+                       _I("default_check:LOCK STATE, it's transitable");
+                       return 1;
+               }
+       }
+
+       switch (next) {
+       case S_LCDDIM:
+               trans_cond = trans_cond & MASK_DIM;
+               break;
+       case S_LCDOFF:
+               trans_cond = trans_cond & MASK_OFF;
+               break;
+       case S_SLEEP:
+               trans_cond = trans_cond & MASK_SLP;
+               break;
+       default:                /* S_NORMAL is exceptional */
+               trans_cond = 0;
+               break;
+       }
+
+       if (trans_cond != 0) {
+               print_node(next);
+               return 0;
+       }
+
+       return 1;               /* transitable */
+}
+
+static void default_saving_mode(int onoff)
+{
+       if (onoff) {
+               pm_status_flag |= PWRSV_FLAG;
+               /* off hbm state, it's power saving mode */
+               if (hbm_get_state != NULL &&
+                   hbm_get_state() == true)
+                       hbm_set_state_with_timeout(false, 0);
+       } else {
+               pm_status_flag &= ~PWRSV_FLAG;
+       }
+       if (pm_cur_state == S_NORMAL)
+               backlight_ops.update();
+}
+
+static int poll_callback(int condition, PMMsg *data)
+{
+       static time_t last_t;
+       time_t now;
+
+       if (status != DEVICE_OPS_STATUS_START) {
+               _E("display logic is not started!");
+               return -ECANCELED;
+       }
+
+       if (condition == INPUT_POLL_EVENT) {
+               if (pm_cur_state == S_LCDOFF || pm_cur_state == S_SLEEP)
+                       _I("Power key input");
+               time(&now);
+               if (last_t != now) {
+                       states[pm_cur_state].trans(EVENT_INPUT);
+                       last_t = now;
+               }
+       } else if (condition == PM_CONTROL_EVENT) {
+               if (data->cond & MASK_BIT
+                       || ((data->cond >> SHIFT_UNLOCK) & MASK_BIT)
+                       || (data->cond >> SHIFT_CHANGE_TIMEOUT))
+                       proc_condition(data);
+
+               if (data->cond & CHANGE_STATE_BIT)
+                       proc_change_state(data->cond, data->pid);
+       }
+
+       return 0;
+}
+
+static int update_setting(int key_idx, int val)
+{
+       char buf[PATH_MAX];
+       int ret = -1;
+       int run_timeout = -1;
+       int power_saving_stat = -1;
+       int power_saving_display_stat = -1;
+
+       switch (key_idx) {
+       case SETTING_TO_NORMAL:
+               ret = get_run_timeout(&run_timeout);
+               if (ret < 0 || run_timeout <= 0) {
+                       _E("Can not get run timeout. set default %.2f ms",
+                           DEFAULT_NORMAL_TIMEOUT);
+                       run_timeout = DEFAULT_NORMAL_TIMEOUT;
+               }
+               states[S_NORMAL].timeout = run_timeout;
+               states[pm_cur_state].trans(EVENT_INPUT);
+               break;
+       case SETTING_HALLIC_OPEN:
+               hallic_open = val;
+               update_display_time();
+               if (pm_cur_state == S_NORMAL || pm_cur_state == S_LCDDIM)
+                       states[pm_cur_state].trans(EVENT_INPUT);
+               else if (pm_cur_state == S_SLEEP && hallic_open)
+                       proc_change_state(S_LCDOFF <<
+                           (SHIFT_CHANGE_STATE + S_LCDOFF), getpid());
+               break;
+       case SETTING_LOW_BATT:
+               if (low_battery_state(val)) {
+                       if (!(pm_status_flag & CHRGR_FLAG))
+                               power_saving_func(true);
+                       pm_status_flag |= LOWBT_FLAG;
+               } else {
+                       if (pm_status_flag & PWRSV_FLAG)
+                               power_saving_func(false);
+                       pm_status_flag &= ~LOWBT_FLAG;
+                       pm_status_flag &= ~BRTCH_FLAG;
+                       vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM,
+                           false);
+               }
+               break;
+       case SETTING_CHARGING:
+               if (val) {
+                       if (pm_status_flag & LOWBT_FLAG) {
+                               power_saving_func(false);
+                               pm_status_flag &= ~LOWBT_FLAG;
+                       }
+                       pm_status_flag |= CHRGR_FLAG;
+               } else {
+                       int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
+                       vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
+                               &bat_state);
+                       if (low_battery_state(bat_state)) {
+                               power_saving_func(true);
+                               pm_status_flag |= LOWBT_FLAG;
+                       }
+                       pm_status_flag &= ~CHRGR_FLAG;
+               }
+               break;
+       case SETTING_BRT_LEVEL:
+               if (pm_status_flag & PWRSV_FLAG) {
+                       pm_status_flag |= BRTCH_FLAG;
+                       vconf_set_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM,
+                           true);
+                       _I("brightness changed in low battery,"
+                               "escape dim state");
+               }
+               backlight_ops.set_default_brt(val);
+               snprintf(buf, sizeof(buf), "%d", val);
+               _D("Brightness set in bl : %d",val);
+               launch_evenif_exist(SET_BRIGHTNESS_IN_BOOTLOADER, buf);
+               break;
+       case SETTING_LOCK_SCREEN:
+               set_lock_screen_state(val);
+               if (val == VCONFKEY_IDLE_UNLOCK) {
+                       if (CHECK_OPS(keyfilter_ops, backlight_enable))
+                               keyfilter_ops->backlight_enable(false);
+               }
+
+               /* LCD on if lock screen show before waiting time */
+               if (pm_cur_state == S_NORMAL &&
+                   val == VCONFKEY_IDLE_LOCK &&
+                   backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
+                       lcd_on_procedure();
+               stop_lock_timer();
+               update_display_time();
+               if (pm_cur_state == S_NORMAL) {
+                       states[pm_cur_state].trans(EVENT_INPUT);
+               }
+               break;
+       case SETTING_LOCK_SCREEN_BG:
+               set_lock_screen_bg_state(val);
+               update_display_time();
+               if (pm_cur_state == S_NORMAL) {
+                       states[pm_cur_state].trans(EVENT_INPUT);
+               }
+               break;
+       case SETTING_POWER_SAVING:
+               if (val == 1)
+                       vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY,
+                                &power_saving_display_stat);
+               if (power_saving_display_stat != 1)
+                       power_saving_display_stat = 0;
+               if (device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_FRAME_RATE,
+                   power_saving_display_stat) < 0) {
+                       _E("Fail to set display frame rate!");
+               }
+               backlight_ops.update();
+               break;
+       case SETTING_POWER_SAVING_DISPLAY:
+               vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS,
+                       &power_saving_stat);
+               if (power_saving_stat == 1) {
+                       if (val == 1)
+                               power_saving_display_stat = 1;
+                       else
+                               power_saving_display_stat = 0;
+                       if (device_set_property(DEVICE_TYPE_DISPLAY,
+                           PROP_DISPLAY_FRAME_RATE, power_saving_display_stat) < 0) {
+                               _E("Fail to set display frame rate!");
+                       }
+                       backlight_ops.update();
+               }
+               break;
+       case SETTING_SMART_STAY:
+               if (!val) {
+                       pm_status_flag &= ~SMAST_FLAG;
+                       _I("Smart Stay Feature off");
+               } else {
+                       pm_status_flag |= SMAST_FLAG;
+                       _I("Smart Stay Feature on");
+               }
+               break;
+       case SETTING_POWEROFF:
+               switch (val) {
+               case VCONFKEY_SYSMAN_POWER_OFF_NONE:
+               case VCONFKEY_SYSMAN_POWER_OFF_POPUP:
+                       pm_status_flag &= ~PWROFF_FLAG;
+                       break;
+               case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
+               case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
+                       pm_status_flag |= PWROFF_FLAG;
+                       break;
+               }
+               break;
+       case SETTING_BOOT_POWER_ON_STATUS:
+               /*
+                * Unlock lcd off after booting is done.
+                * deviced guarantees all booting script is executing.
+                * Last script of booting unlocks this suspend blocking state.
+                */
+               if (val == VCONFKEY_DEVICED_BOOT_POWER_ON_DONE) {
+                       _I("booting done");
+                       pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
+               }
+               break;
+       case SETTING_POWER_CUSTOM_BRIGHTNESS:
+               if (val == VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON)
+                       backlight_ops.set_custom_status(true);
+               else
+                       backlight_ops.set_custom_status(false);
+               break;
+       case SETTING_ACCESSIBILITY_TTS:
+               tts_state = val;
+               _I("TTS is %s", (val ? "ON" : "OFF"));
+               break;
+
+       default:
+               return -1;
+       }
+       return 0;
+}
+
+static void check_seed_status(void)
+{
+       int ret = -1;
+       int tmp = 0;
+       int bat_state = VCONFKEY_SYSMAN_BAT_NORMAL;
+       int max_brt = 0;
+       int brt = 0;
+       int lock_state = -1;
+       int power_saving_stat = -1;
+       int power_saving_display_stat = -1;
+       int smart_stay_on = 0;
+
+       /* Charging check */
+       if ((get_charging_status(&tmp) == 0) && (tmp > 0)) {
+               pm_status_flag |= CHRGR_FLAG;
+       }
+
+       ret = get_setting_brightness(&tmp);
+       if (ret != 0 || (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)) {
+               _I("fail to read vconf value for brightness");
+               brt = PM_DEFAULT_BRIGHTNESS;
+               if (tmp < PM_MIN_BRIGHTNESS || tmp > PM_MAX_BRIGHTNESS)
+                       vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt);
+               tmp = brt;
+       }
+       _I("Set brightness from Setting App. %d", tmp);
+       backlight_ops.set_default_brt(tmp);
+
+       vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat_state);
+       if (low_battery_state(bat_state)) {
+               if (!(pm_status_flag & CHRGR_FLAG)) {
+                       power_saving_func(true);
+                       pm_status_flag |= LOWBT_FLAG;
+               }
+       }
+       backlight_ops.update();
+       backlight_ops.on();
+       touch_ops.screen_on();
+       touch_ops.key_on();
+
+       /* lock screen check */
+       ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
+       set_lock_screen_state(lock_state);
+       if (lock_state == VCONFKEY_IDLE_LOCK) {
+               states[S_NORMAL].timeout = lock_screen_timeout;
+               _I("LCD NORMAL timeout is set by %d ms"
+                       " for lock screen", lock_screen_timeout);
+       }
+
+       /* power saving display stat */
+       vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS,
+           &power_saving_stat);
+       if (power_saving_stat <= 0) {
+               power_saving_display_stat = 0;
+       } else {
+               vconf_get_bool(VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY,
+                   &power_saving_display_stat);
+       }
+       if (power_saving_display_stat < 0) {
+               _E("failed to read power saving display stat!");
+       } else {
+               _I("power saving display stat : %d",
+                   power_saving_display_stat);
+       }
+
+       /* Smart stay status */
+       vconf_get_int(VCONFKEY_SETAPPL_SMARTSCREEN_SMARTSTAY_STATUS, &smart_stay_on);
+       if (!smart_stay_on) {
+               _I("Smart Stay Feature off");
+       } else {
+               _I("Smart Stay Feature on");
+               pm_status_flag |= SMAST_FLAG;
+       }
+
+       /* TTS state */
+       ret = vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &tts_state);
+       if (ret < 0)
+               _E("Failed to get TTS setting! (%d)", ret);
+       _I("TTS is %s", (tts_state ? "ON" : "OFF"));
+
+       return;
+}
+
+enum {
+       INIT_SETTING = 0,
+       INIT_INTERFACE,
+       INIT_POLL,
+       INIT_FIFO,
+       INIT_DBUS,
+       INIT_END
+};
+
+static const char *errMSG[INIT_END] = {
+       [INIT_SETTING] = "setting init error",
+       [INIT_INTERFACE] = "lowlevel interface(sysfs or others) init error",
+       [INIT_POLL] = "input devices poll init error",
+       [INIT_FIFO] = "FIFO poll init error",
+       [INIT_DBUS] = "d-bus init error",
+};
+
+static int input_action(char* input_act, char* input_path)
+{
+       int ret = -EINVAL;
+       Eina_List *list_node = NULL;
+       Eina_List *l = NULL;
+       Eina_List *l_next = NULL;
+       indev *data = NULL;
+       PmLockNode *tmp = NULL;
+
+       if (!strcmp("add", input_act)) {
+               _I("add input path : %s", input_path);
+               ret = init_pm_poll_input(poll_callback, input_path);
+       } else if (!strcmp("remove", input_act)) {
+               EINA_LIST_FOREACH_SAFE(indev_list, l, l_next, data)
+                       if(!strcmp(input_path, data->dev_path)) {
+                               _I("remove %s", input_path);
+                               ecore_main_fd_handler_del(data->dev_fd);
+                               close(data->fd);
+                               free(data->dev_path);
+                               free(data);
+                               indev_list = eina_list_remove_list(indev_list, l);
+                       }
+               ret = 0;
+       } else if (!strcmp("change", input_act)) {
+               if (!strcmp("ESD", input_path)) {
+                       _I("ESD on");
+                       if (pm_cur_state == S_NORMAL) {
+                               backlight_ops.off();
+                               backlight_ops.on();
+                       } else if (pm_cur_state == S_LCDDIM) {
+                               backlight_ops.off();
+                               backlight_ops.dim();
+                       }
+                       ret = 0;
+               }
+       }
+       return ret;
+}
+
+int set_lcd_timeout(int on, int dim, int holdkey_block, char *name)
+{
+       if (on == 0 && dim == 0) {
+               _I("LCD timeout changed : default setting");
+               custom_normal_timeout = custom_dim_timeout = 0;
+       } else if (on < 0 || dim < 0) {
+               _E("fail to set value (%d,%d)", on, dim);
+               return -EINVAL;
+       } else {
+               _I("LCD timeout changed : on(%ds), dim(%ds)", on, dim);
+               custom_normal_timeout = SEC_TO_MSEC(on);
+               custom_dim_timeout = SEC_TO_MSEC(dim);
+       }
+       /* Apply new backlight time */
+       update_display_time();
+
+       if (holdkey_block) {
+               custom_holdkey_block = true;
+               _I("hold key disabled !");
+       } else {
+               custom_holdkey_block = false;
+               _I("hold key enabled !");
+       }
+
+       if (custom_change_name) {
+               free(custom_change_name);
+               custom_change_name = 0;
+       }
+
+       if (custom_normal_timeout == 0 &&
+           custom_dim_timeout == 0 &&
+           !holdkey_block)
+               return 0;
+
+       custom_change_name = strndup(name, strlen(name));
+       if (!custom_change_name) {
+               _E("Malloc falied!");
+               custom_normal_timeout = custom_dim_timeout = 0;
+               custom_holdkey_block = false;
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+int reset_lcd_timeout(char *name, enum watch_id id)
+{
+       if (!name)
+               return -EINVAL;
+
+       if (!custom_change_name)
+               return -EINVAL;
+
+       if (strcmp(name, custom_change_name))
+               return -EINVAL;
+
+       _I("reset lcd timeout %s: set default timeout", name);
+
+       free(custom_change_name);
+       custom_change_name = 0;
+       custom_normal_timeout = custom_dim_timeout = 0;
+       custom_holdkey_block = false;
+
+       update_display_time();
+       if (pm_cur_state == S_NORMAL) {
+               states[pm_cur_state].trans(EVENT_INPUT);
+       }
+
+       return 0;
+}
+
+int get_hdmi_state(void)
+{
+       return hdmi_state;
+}
+
+static int hdmi_changed(void *data)
+{
+       hdmi_state = (int)data;
+
+       return 0;
+}
+
+static int hall_ic_open(void *data)
+{
+       int open = (int)data;
+
+       update_pm_setting(SETTING_HALLIC_OPEN, open);
+
+       return 0;
+}
+
+static int input_device_add(void *data)
+{
+       char *path = (char *)data;
+
+       if (!path)
+               return -EINVAL;
+
+       input_action(UDEV_ADD, path);
+
+       return 0;
+}
+
+static int input_device_remove(void *data)
+{
+       char *path = (char *)data;
+
+       if (!path)
+               return -EINVAL;
+
+       input_action(UDEV_REMOVE, path);
+
+       return 0;
+}
+
+static int booting_done(void *data)
+{
+       static bool done = false;
+
+       if (done)
+               return 0;
+
+       _I("booting done, unlock LCD_OFF");
+       pm_unlock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF, PM_SLEEP_MARGIN);
+       done = true;
+
+       return 0;
+}
+
+static int lcd_esd(void *data)
+{
+       char *path = data;
+
+       if (!path)
+               return -EINVAL;
+
+       input_action(UDEV_CHANGE, path);
+
+       return 0;
+}
+
+static int battery_health_changed(void *data)
+{
+       int health = (int)data;
+
+       if (health == HEALTH_GOOD) {
+               _D("battery health good");
+               pm_status_flag &= ~DIMSTAY_FLAG;
+
+       } else if (health == HEALTH_BAD) {
+               _D("battery health bad");
+               pm_status_flag |= DIMSTAY_FLAG;
+       }
+
+       return 0;
+}
+
+static int display_load_config(struct parse_result *result, void *user_data)
+{
+       struct display_config *c = user_data;
+
+       _D("%s,%s,%s", result->section, result->name, result->value);
+
+       if (!c)
+               return -EINVAL;
+
+       if (!MATCH(result->section, "Display"))
+               return -EINVAL;
+
+       if (MATCH(result->name, "LockScreenWaitingTime")) {
+               SET_CONF(c->lock_wait_time, atof(result->value));
+               _D("lock wait time is %.3f", c->lock_wait_time);
+       } else if (MATCH(result->name, "LongPressInterval")) {
+               SET_CONF(c->longpress_interval, atof(result->value));
+               _D("long press interval is %.3f", c->longpress_interval);
+       } else if (MATCH(result->name, "LightSensorSamplingInterval")) {
+               SET_CONF(c->lightsensor_interval, atof(result->value));
+               _D("lightsensor interval is %.3f", c->lightsensor_interval);
+       } else if (MATCH(result->name, "LCDOffTimeout")) {
+               SET_CONF(c->lcdoff_timeout, atoi(result->value));
+               _D("lcdoff timeout is %d ms", c->lcdoff_timeout);
+       } else if (MATCH(result->name, "BrightnessChangeStep")) {
+               SET_CONF(c->brightness_change_step, atoi(result->value));
+               _D("brightness change step is %d", c->brightness_change_step);
+       } else if (MATCH(result->name, "HBMLuxThreshold")) {
+               SET_CONF(c->hbm_lux_threshold, atoi(result->value));
+               _D("HBM lux threshold is %d", c->hbm_lux_threshold);
+       } else if (MATCH(result->name, "LCDAlwaysOn")) {
+               c->lcd_always_on = (MATCH(result->value, "yes") ? 1 : 0);
+               _D("LCD always on is %d", c->lcd_always_on);
+       } else if (MATCH(result->name, "ChangedFrameRateAllowed")) {
+               if (strstr(result->value, "setting")) {
+                       c->framerate_app[REFRESH_SETTING] = 1;
+                       _D("framerate app is Setting");
+               }
+               if (strstr(result->value, "all")) {
+                       memset(c->framerate_app, 1, sizeof(c->framerate_app));
+                       _D("framerate app is All");
+               }
+       } else if (MATCH(result->name, "ControlDisplay")) {
+               c->control_display = (MATCH(result->value, "yes") ? 1 : 0);
+               _D("ControlDisplay is %d", c->control_display);
+       } else if (MATCH(result->name, "PowerKeyDoublePressSupport")) {
+               c->powerkey_doublepress = (MATCH(result->value, "yes") ? 1 : 0);
+               _D("PowerKeyDoublePressSupport is %d", c->powerkey_doublepress);
+       } else if (MATCH(result->name, "UseALPM")) {
+               c->alpm_on = (MATCH(result->value, "yes") ? 1 : 0);
+               _D("UseALPM is %d", c->alpm_on);
+       }
+
+       return 0;
+}
+
+/**
+ * Power manager Main
+ *
+ */
+static void display_init(void *data)
+{
+       int ret, i;
+       unsigned int flags = (WITHOUT_STARTNOTI | FLAG_X_DPMS);
+       int timeout = 0;
+
+       _I("Start power manager");
+
+       signal(SIGHUP, sig_hup);
+
+       power_saving_func = default_saving_mode;
+       /* noti init for new input device like bt mouse */
+       indev_list = NULL;
+
+       /* load configutation */
+       ret = config_parse(DISPLAY_CONF_FILE, display_load_config, &display_conf);
+       if (ret < 0)
+               _W("Failed to load %s, %s Use default value!",
+                   DISPLAY_CONF_FILE, ret);
+
+       register_notifier(DEVICE_NOTIFIER_HALLIC_OPEN, hall_ic_open);
+       register_notifier(DEVICE_NOTIFIER_INPUT_ADD, input_device_add);
+       register_notifier(DEVICE_NOTIFIER_INPUT_REMOVE, input_device_remove);
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+       register_notifier(DEVICE_NOTIFIER_LCD_ESD, lcd_esd);
+       register_notifier(DEVICE_NOTIFIER_HDMI, hdmi_changed);
+       register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed);
+
+       for (i = INIT_SETTING; i < INIT_END; i++) {
+               switch (i) {
+               case INIT_SETTING:
+                       ret = init_setting(update_setting);
+                       break;
+               case INIT_INTERFACE:
+                       get_lcd_timeout_from_settings();
+                       ret = init_sysfs(flags);
+                       break;
+               case INIT_POLL:
+                       _I("poll init");
+                       ret = init_pm_poll(poll_callback);
+                       break;
+               case INIT_DBUS:
+                       _I("dbus init");
+                       ret = init_pm_dbus();
+                       break;
+               }
+               if (ret != 0) {
+                       _E("%s", errMSG[i]);
+                       break;
+               }
+       }
+
+       if (i == INIT_END) {
+               display_ops_init(NULL);
+#ifdef ENABLE_PM_LOG
+               pm_history_init();
+#endif
+               check_seed_status();
+
+               if (display_conf.lcd_always_on) {
+                       _D("LCD always on!");
+                       trans_table[S_NORMAL][EVENT_TIMEOUT] = S_NORMAL;
+               }
+
+               if (flags & WITHOUT_STARTNOTI) {        /* start without noti */
+                       _I("Start Power managing without noti");
+                       pm_cur_state = S_NORMAL;
+                       set_setting_pmstate(pm_cur_state);
+
+                       timeout = states[S_NORMAL].timeout;
+                       /* check minimun lcd on time */
+                       if (timeout < DEFAULT_NORMAL_TIMEOUT)
+                               timeout = DEFAULT_NORMAL_TIMEOUT;
+
+                       reset_timeout(timeout);
+
+                       /*
+                        * Lock lcd off until booting is done.
+                        * deviced guarantees all booting script is executing.
+                        * Last script of booting unlocks this suspend blocking state.
+                        */
+                       pm_lock_internal(INTERNAL_LOCK_BOOTING, LCD_OFF,
+                           STAY_CUR_STATE, BOOTING_DONE_WATING_TIME);
+               }
+               if (CHECK_OPS(keyfilter_ops, init))
+                       keyfilter_ops->init();
+       }
+       status = DEVICE_OPS_STATUS_START;
+}
+
+static void display_exit(void *data)
+{
+       int i = INIT_END;
+
+       status = DEVICE_OPS_STATUS_STOP;
+
+       /* Set current state to S_NORMAL */
+       pm_cur_state = S_NORMAL;
+       set_setting_pmstate(pm_cur_state);
+       /* timeout is not needed */
+       reset_timeout(0);
+
+       if (CHECK_OPS(keyfilter_ops, exit))
+               keyfilter_ops->exit();
+
+       display_ops_exit(NULL);
+
+       for (i = i - 1; i >= INIT_SETTING; i--) {
+               switch (i) {
+               case INIT_SETTING:
+                       exit_setting();
+                       break;
+               case INIT_INTERFACE:
+                       exit_sysfs();
+                       break;
+               case INIT_POLL:
+                       unregister_notifier(DEVICE_NOTIFIER_HALLIC_OPEN, hall_ic_open);
+                       unregister_notifier(DEVICE_NOTIFIER_INPUT_ADD,
+                           input_device_add);
+                       unregister_notifier(DEVICE_NOTIFIER_INPUT_REMOVE,
+                           input_device_remove);
+                       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
+                           booting_done);
+                       unregister_notifier(DEVICE_NOTIFIER_LCD_ESD, lcd_esd);
+                       unregister_notifier(DEVICE_NOTIFIER_HDMI, hdmi_changed);
+                       unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH,
+                           battery_health_changed);
+
+                       exit_pm_poll();
+                       break;
+               }
+       }
+       free_lock_info_list();
+
+       _I("Stop power manager");
+}
+
+static int display_start(void)
+{
+       if (status == DEVICE_OPS_STATUS_START)
+               return -EALREADY;
+
+       display_init(NULL);
+
+       return 0;
+}
+
+static int display_stop(void)
+{
+       if (status == DEVICE_OPS_STATUS_STOP)
+               return -EALREADY;
+
+       display_exit(NULL);
+
+       return 0;
+}
+
+static int display_status(void)
+{
+       return status;
+}
+
+static const struct device_ops display_device_ops = {
+       .priority = DEVICE_PRIORITY_HIGH,
+       .name     = "display",
+       .init     = display_init,
+       .exit     = display_exit,
+       .start    = display_start,
+       .stop     = display_stop,
+       .status   = display_status,
+};
+
+DEVICE_OPS_REGISTER(&display_device_ops)
+
+/**
+ * @}
+ */
diff --git a/src/display/core.h b/src/display/core.h
new file mode 100644 (file)
index 0000000..c5bf7e1
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2011 - 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.
+ */
+
+
+/**
+ * @file       core.h
+ * @brief       Power manager main loop header file
+ */
+#ifndef __POWER_MANAGER_H__
+#define __POWER_MANAGER_H__
+
+#include "poll.h"
+#include "device-interface.h"
+#include "setting.h"
+
+#define WITHOUT_STARTNOTI      0x1
+#define MASK_BIT 0x7           /* 111 */
+#define MASK_DIM 0x1           /* 001 */
+#define MASK_OFF 0x2           /* 010 */
+#define MASK_SLP 0x4           /* 100 */
+
+#define VCALL_FLAG             0x00000001
+#define LOWBT_FLAG             0x00000100
+#define CHRGR_FLAG             0x00000200
+#define PWRSV_FLAG             0x00000400
+#define SMAST_FLAG             0x00001000
+#define BRTCH_FLAG             0x00002000
+#define PWROFF_FLAG            0x00004000
+#define DIMSTAY_FLAG           0x00008000
+
+#define DEFAULT_NORMAL_TIMEOUT 30000
+#define DEFAULT_DIM_TIMEOUT    5000
+#define DEFAULT_OFF_TIMEOUT    1000
+
+#define MASK32                 0xffffffff
+
+#define CHECK_OPS(d, op) (d != NULL && d->op != NULL)
+
+#ifdef ENABLE_PM_LOG
+#define MAX_LOG_COUNT 250
+
+enum pm_log_type {
+       PM_LOG_MIN = 0,
+       PM_LOG_KEY_PRESS = PM_LOG_MIN,  /* key log */
+       PM_LOG_KEY_LONG_PRESS,
+       PM_LOG_KEY_RELEASE,
+       PM_LOG_LCD_ON,                  /* lcd log */
+       PM_LOG_LCD_ON_FAIL,
+       PM_LOG_LCD_DIM,
+       PM_LOG_LCD_DIM_FAIL,
+       PM_LOG_LCD_OFF,
+       PM_LOG_LCD_OFF_FAIL,
+       PM_LOG_SLEEP,
+       PM_LOG_MAX
+};
+
+void pm_history_save(enum pm_log_type, int);
+#endif
+
+extern unsigned int pm_status_flag;
+
+/*
+ * State enumeration
+ */
+enum state_t {
+       S_START = 0,
+       S_NORMAL,               /*< normal state */
+       S_LCDDIM,               /*< LCD dimming */
+       S_LCDOFF,               /*< LCD off */
+       S_SLEEP,                /*< system suspend */
+       S_END
+};
+
+/*
+ * Global variables
+ *   pm_cur_state   : current state
+ *   states      : state definitions
+ *   trans_table : state transition table
+ */
+int pm_cur_state;
+int pm_old_state;
+
+/*
+ * @brief State structure
+ */
+struct state {
+       enum state_t state;                                     /**< state number */
+       int (*trans) (int evt);         /**< transition function pointer */
+       int (*action) (int timeout);    /**< enter action */
+       int (*check) (int next);        /**< transition check function */
+       int timeout;
+} states[S_END];
+
+/*
+ * @brief Configuration structure
+ */
+struct display_config {
+       double lock_wait_time;
+       double longpress_interval;
+       double lightsensor_interval;
+       int lcdoff_timeout;
+       int brightness_change_step;
+       int hbm_lux_threshold;
+       int lcd_always_on;
+       int framerate_app[4];
+       int control_display;
+       int powerkey_doublepress;
+       int alpm_on;
+};
+
+/*
+ * Global variables
+ *   display_conf : configuration of display
+ */
+extern struct display_config display_conf;
+
+/*
+ * @brief Display Extension features
+ */
+struct display_function_info {
+       void (*update_auto_brightness)(bool);
+       int (*set_autobrightness_min)(int, char *);
+       int (*reset_autobrightness_min)(char *, enum watch_id);
+       int (*face_detection)(int, int, int);
+};
+
+extern struct display_function_info display_info;
+
+struct display_keyfilter_ops {
+       void (*init)(void);
+       void (*exit)(void);
+       int (*check)(int, char[], int);
+       void (*set_powerkey_ignore)(int);
+       int (*powerkey_lcdoff)(void);
+       void (*backlight_enable)(bool);
+};
+
+extern const struct display_keyfilter_ops *keyfilter_ops;
+
+/* If the bit in a condition variable is set,
+ *  we cannot transit the state until clear this bit. */
+int trans_condition;
+pid_t idle_pid;
+int check_processes(enum state_t prohibit_state);
+extern struct state state[S_END];
+int reset_lcd_timeout(char *name, enum watch_id id);
+int check_lcdoff_lock_state(void);
+/**
+ * @}
+ */
+
+#endif
diff --git a/src/display/device-interface.c b/src/display/device-interface.c
new file mode 100644 (file)
index 0000000..fe95194
--- /dev/null
@@ -0,0 +1,637 @@
+/*
+ * 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 <stdlib.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include "core/log.h"
+#include "util.h"
+#include "device-interface.h"
+#include "vconf.h"
+#include "core.h"
+#include "device-node.h"
+#include "weaks.h"
+
+#define TOUCH_ON       1
+#define TOUCH_OFF      0
+
+typedef struct _PMSys PMSys;
+struct _PMSys {
+       int def_brt;
+       int dim_brt;
+
+       int (*sys_power_state) (PMSys *, int);
+       int (*sys_power_lock) (PMSys *, int);
+       int (*sys_get_power_lock_support) (PMSys *);
+       int (*sys_get_lcd_power) (PMSys *);
+       int (*bl_onoff) (PMSys *, int);
+       int (*bl_brt) (PMSys *, int);
+};
+
+static PMSys *pmsys;
+struct _backlight_ops backlight_ops;
+struct _touch_ops touch_ops;
+struct _power_ops power_ops;
+
+static char *touchscreen_node;
+static char *touchkey_node;
+
+#ifdef ENABLE_X_LCD_ONOFF
+#include "x-lcd-on.c"
+static bool x_dpms_enable = false;
+#endif
+
+static int power_lock_support = -1;
+static bool custom_status = false;
+static int custom_brightness = 0;
+static int force_brightness = 0;
+
+static int _bl_onoff(PMSys *p, int on)
+{
+       int cmd;
+
+       cmd = DISP_CMD(PROP_DISPLAY_ONOFF, DEFAULT_DISPLAY);
+       return device_set_property(DEVICE_TYPE_DISPLAY, cmd, on);
+}
+
+static int _bl_brt(PMSys *p, int brightness)
+{
+       int ret = -1;
+       int cmd;
+       int prev;
+
+       if (force_brightness > 0 && brightness != p->dim_brt) {
+               _I("brightness(%d), force brightness(%d)",
+                   brightness, force_brightness);
+               brightness = force_brightness;
+       }
+
+       cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &prev);
+
+       /* Update new brightness to vconf */
+       if (!ret && (brightness != prev)) {
+               vconf_set_int(VCONFKEY_PM_CURRENT_BRIGHTNESS, brightness);
+       }
+
+       /* Update device brightness */
+       ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, brightness);
+
+       _I("set brightness %d, %d", brightness, ret);
+
+       return ret;
+}
+
+static int _sys_power_state(PMSys *p, int state)
+{
+       if (state < POWER_STATE_SUSPEND || state > POWER_STATE_POST_RESUME)
+               return 0;
+       return device_set_property(DEVICE_TYPE_POWER, PROP_POWER_STATE, state);
+}
+
+static int _sys_power_lock(PMSys *p, int state)
+{
+       if (state != POWER_LOCK && state != POWER_UNLOCK)
+               return -1;
+       return device_set_property(DEVICE_TYPE_POWER, PROP_POWER_LOCK, state);
+}
+
+static int _sys_get_power_lock_support(PMSys *p)
+{
+       int value = 0;
+       int ret = -1;
+
+       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_LOCK_SUPPORT,
+           &value);
+
+       if (ret < 0)
+               return -1;
+
+       if (value < 0)
+               return 0;
+
+       return value;
+}
+
+static int _sys_get_lcd_power(PMSys *p)
+{
+       int value = -1;
+       int ret = -1;
+       int cmd;
+
+       cmd = DISP_CMD(PROP_DISPLAY_ONOFF, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &value);
+
+       if (ret < 0 || value < 0)
+               return -1;
+
+       return value;
+}
+
+static void _init_bldev(PMSys *p, unsigned int flags)
+{
+       int ret;
+       //_update_curbrt(p);
+       p->bl_brt = _bl_brt;
+       p->bl_onoff = _bl_onoff;
+#ifdef ENABLE_X_LCD_ONOFF
+       if (flags & FLAG_X_DPMS) {
+               p->bl_onoff = pm_x_set_lcd_backlight;
+               x_dpms_enable = true;
+       }
+#endif
+}
+
+static void _init_pmsys(PMSys *p)
+{
+       char *val;
+
+       val = getenv("PM_SYS_DIMBRT");
+       p->dim_brt = (val ? atoi(val) : 0);
+       p->sys_power_state = _sys_power_state;
+       p->sys_power_lock = _sys_power_lock;
+       p->sys_get_power_lock_support = _sys_get_power_lock_support;
+       p->sys_get_lcd_power = _sys_get_lcd_power;
+}
+
+static void *_system_suspend_cb(void *data)
+{
+       int ret;
+
+       _I("enter system suspend");
+       if (pmsys && pmsys->sys_power_state)
+               ret = pmsys->sys_power_state(pmsys, POWER_STATE_SUSPEND);
+       else
+               ret = -EFAULT;
+
+       if (ret < 0)
+               _E("Failed to system suspend! %d", ret);
+
+       return (void *)ret;
+}
+
+static int system_suspend(void)
+{
+       pthread_t pth;
+       int ret;
+
+       ret = pthread_create(&pth, 0, _system_suspend_cb, (void*)NULL);
+       if (ret < 0) {
+               _E("pthread creation failed!, suspend directly!");
+               _system_suspend_cb((void*)NULL);
+       } else {
+               pthread_join(pth, NULL);
+       }
+
+       return 0;
+}
+
+static int system_pre_suspend(void)
+{
+       _I("enter system pre suspend");
+       if (pmsys && pmsys->sys_power_state)
+               return pmsys->sys_power_state(pmsys, POWER_STATE_PRE_SUSPEND);
+
+       return 0;
+}
+
+static int system_post_resume(void)
+{
+       _I("enter system post resume");
+       if (pmsys && pmsys->sys_power_state)
+               return pmsys->sys_power_state(pmsys, POWER_STATE_POST_RESUME);
+
+       return 0;
+}
+
+static int system_power_lock(void)
+{
+       _I("system power lock");
+       if (pmsys && pmsys->sys_power_lock)
+               return pmsys->sys_power_lock(pmsys, POWER_LOCK);
+
+       return 0;
+}
+
+static int system_power_unlock(void)
+{
+       _I("system power unlock");
+       if (pmsys && pmsys->sys_power_lock)
+               return pmsys->sys_power_lock(pmsys, POWER_UNLOCK);
+
+       return 0;
+}
+
+static int system_get_power_lock_support(void)
+{
+       int value = -1;
+
+       if (power_lock_support == -1) {
+               if (pmsys && pmsys->sys_get_power_lock_support) {
+                       value = pmsys->sys_get_power_lock_support(pmsys);
+                       if (value == 1) {
+                                       _I("system power lock : support");
+                                       power_lock_support = 1;
+                       } else {
+                               _E("system power lock : not support");
+                               power_lock_support = 0;
+                       }
+               } else {
+                       _E("system power lock : read fail");
+                       power_lock_support = 0;
+               }
+       }
+
+       return power_lock_support;
+}
+
+static int get_lcd_power(void)
+{
+       if (pmsys && pmsys->sys_get_lcd_power) {
+               return pmsys->sys_get_lcd_power(pmsys);
+       }
+
+       return -1;
+}
+
+static int backlight_hbm_off(void)
+{
+#ifdef MICRO_DD
+       return -EINVAL;
+#else
+       int ret, state;
+
+       ret = device_get_property(DEVICE_TYPE_DISPLAY,
+           PROP_DISPLAY_HBM_CONTROL, &state);
+       if (ret < 0)
+               return ret;
+
+       if (state) {
+               ret = device_set_property(DEVICE_TYPE_DISPLAY,
+                   PROP_DISPLAY_HBM_CONTROL, 0);
+               if (ret < 0)
+                       return ret;
+               _D("hbm is off!");
+       }
+       return 0;
+#endif
+}
+
+static int touchscreen_on(void)
+{
+       int ret;
+
+       if (!touchscreen_node)
+               return -ENOENT;
+
+       ret = sys_set_int(touchscreen_node, TOUCH_ON);
+       if (ret < 0)
+               _E("Failed to on touch screen!");
+
+       return ret;
+
+}
+
+static int touchscreen_off(void)
+{
+       int ret;
+
+       if (!touchscreen_node)
+               return -ENOENT;
+
+       if (display_conf.alpm_on == true)
+               return -EPERM;
+
+       ret = sys_set_int(touchscreen_node, TOUCH_OFF);
+       if (ret < 0)
+               _E("Failed to off touch screen!");
+
+       return ret;
+}
+
+static int touchkey_on(void)
+{
+       int ret;
+
+       if (!touchkey_node)
+               return -ENOENT;
+
+       ret = sys_set_int(touchkey_node, TOUCH_ON);
+       if (ret < 0)
+               _E("Failed to on touch key!");
+
+       return ret;
+
+}
+
+static int touchkey_off(void)
+{
+       int ret;
+
+       if (!touchkey_node)
+               return -ENOENT;
+
+       ret = sys_set_int(touchkey_node, TOUCH_OFF);
+       if (ret < 0)
+               _E("Failed to off touch key!");
+
+       return ret;
+}
+
+static int backlight_on(void)
+{
+       int ret = -1;
+       int i;
+
+       _D("LCD on");
+
+       if (!pmsys || !pmsys->bl_onoff)
+               return -1;
+
+       for (i = 0; i < PM_LCD_RETRY_CNT; i++) {
+               ret = pmsys->bl_onoff(pmsys, STATUS_ON);
+               if (get_lcd_power() == PM_LCD_POWER_ON) {
+#ifdef ENABLE_PM_LOG
+                       pm_history_save(PM_LOG_LCD_ON, pm_cur_state);
+#endif
+                       break;
+               } else {
+#ifdef ENABLE_PM_LOG
+                       pm_history_save(PM_LOG_LCD_ON_FAIL, pm_cur_state);
+#endif
+#ifdef ENABLE_X_LCD_ONOFF
+                       _E("Failed to LCD on, through xset");
+#else
+                       _E("Failed to LCD on, through OAL");
+#endif
+                       ret = -1;
+               }
+       }
+
+       return ret;
+}
+
+static int backlight_off(void)
+{
+       int ret = -1;
+       int i;
+
+       _D("LCD off");
+
+       if (!pmsys || !pmsys->bl_onoff)
+               return -1;
+
+       for (i = 0; i < PM_LCD_RETRY_CNT; i++) {
+#ifdef ENABLE_X_LCD_ONOFF
+               if (x_dpms_enable == false)
+#endif
+                       usleep(30000);
+               ret = pmsys->bl_onoff(pmsys, STATUS_OFF);
+               if (get_lcd_power() == PM_LCD_POWER_OFF) {
+#ifdef ENABLE_PM_LOG
+                       pm_history_save(PM_LOG_LCD_OFF, pm_cur_state);
+#endif
+                       break;
+               } else {
+#ifdef ENABLE_PM_LOG
+                       pm_history_save(PM_LOG_LCD_OFF_FAIL, pm_cur_state);
+#endif
+#ifdef ENABLE_X_LCD_ONOFF
+                       _E("Failed to LCD off, through xset");
+#else
+                       _E("Failed to LCD off, through OAL");
+#endif
+                       ret = -1;
+               }
+       }
+       return ret;
+}
+
+static int backlight_dim(void)
+{
+       int ret = 0;
+       if (pmsys && pmsys->bl_brt) {
+               ret = pmsys->bl_brt(pmsys, pmsys->dim_brt);
+#ifdef ENABLE_PM_LOG
+               if (!ret)
+                       pm_history_save(PM_LOG_LCD_DIM, pm_cur_state);
+               else
+                       pm_history_save(PM_LOG_LCD_DIM_FAIL, pm_cur_state);
+#endif
+       }
+       return ret;
+}
+
+static int set_custom_status(bool on)
+{
+       custom_status = on;
+       return 0;
+}
+
+static bool get_custom_status(void)
+{
+       return custom_status;
+}
+
+static int save_custom_brightness(void)
+{
+       int cmd, ret, brightness;
+
+       cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &brightness);
+
+       custom_brightness = brightness;
+
+       return ret;
+}
+
+static int custom_backlight_update(void)
+{
+       int ret = 0;
+
+       if (custom_brightness < PM_MIN_BRIGHTNESS ||
+           custom_brightness > PM_MAX_BRIGHTNESS)
+               return -EINVAL;
+
+       if ((pm_status_flag & PWRSV_FLAG) && !(pm_status_flag & BRTCH_FLAG)) {
+               ret = backlight_dim();
+       } else if (pmsys && pmsys->bl_brt) {
+               _I("custom brightness restored! %d", custom_brightness);
+               ret = pmsys->bl_brt(pmsys, custom_brightness);
+       }
+
+       return ret;
+}
+
+static int set_force_brightness(int level)
+{
+       if (level < 0 ||  level > PM_MAX_BRIGHTNESS)
+               return -EINVAL;
+
+       force_brightness = level;
+
+       return 0;
+}
+
+static int backlight_update(void)
+{
+       int ret = 0;
+
+       if (hbm_get_state != NULL && hbm_get_state() == true) {
+               _I("HBM is on, backlight is not updated!");
+               return 0;
+       }
+
+       if (get_custom_status()) {
+               _I("custom brightness mode! brt no updated");
+               return 0;
+       }
+       if ((pm_status_flag & PWRSV_FLAG) && !(pm_status_flag & BRTCH_FLAG)) {
+               ret = backlight_dim();
+       } else if (pmsys && pmsys->bl_brt) {
+               ret = pmsys->bl_brt(pmsys, pmsys->def_brt);
+       }
+       return ret;
+}
+
+static int backlight_standby(void)
+{
+       int ret = -1;
+       if (!pmsys || !pmsys->bl_onoff)
+               return -1;
+
+       if (get_lcd_power() == PM_LCD_POWER_ON) {
+               _I("LCD standby");
+               ret = pmsys->bl_onoff(pmsys, STATUS_STANDBY);
+       }
+
+       return ret;
+}
+
+static int set_default_brt(int level)
+{
+       if (!pmsys)
+               return -EFAULT;
+
+       if (level < PM_MIN_BRIGHTNESS || level > PM_MAX_BRIGHTNESS)
+               level = PM_DEFAULT_BRIGHTNESS;
+       pmsys->def_brt = level;
+
+       return 0;
+}
+
+
+
+static int check_wakeup_src(void)
+{
+       /*  TODO if nedded.
+        * return wackeup source. user input or device interrupts? (EVENT_DEVICE or EVENT_INPUT)
+        */
+       return EVENT_DEVICE;
+}
+
+void _init_ops(void)
+{
+       backlight_ops.off = backlight_off;
+       backlight_ops.dim = backlight_dim;
+       backlight_ops.on = backlight_on;
+       backlight_ops.update = backlight_update;
+       backlight_ops.standby = backlight_standby;
+       backlight_ops.hbm_off = backlight_hbm_off;
+       backlight_ops.set_default_brt = set_default_brt;
+       backlight_ops.get_lcd_power = get_lcd_power;
+       backlight_ops.set_custom_status = set_custom_status;
+       backlight_ops.get_custom_status = get_custom_status;
+       backlight_ops.save_custom_brightness = save_custom_brightness;
+       backlight_ops.custom_update = custom_backlight_update;
+       backlight_ops.set_force_brightness = set_force_brightness;
+
+       touch_ops.screen_on = touchscreen_on;
+       touch_ops.screen_off = touchscreen_off;
+       touch_ops.key_on = touchkey_on;
+       touch_ops.key_off = touchkey_off;
+
+       power_ops.suspend = system_suspend;
+       power_ops.pre_suspend = system_pre_suspend;
+       power_ops.post_resume = system_post_resume;
+       power_ops.power_lock = system_power_lock;
+       power_ops.power_unlock = system_power_unlock;
+       power_ops.get_power_lock_support = system_get_power_lock_support;
+       power_ops.check_wakeup_src = check_wakeup_src;
+}
+
+int init_sysfs(unsigned int flags)
+{
+       int ret;
+
+       pmsys = (PMSys *) malloc(sizeof(PMSys));
+       if (pmsys == NULL) {
+               _E("Not enough memory to alloc PM Sys");
+               return -1;
+       }
+
+       memset(pmsys, 0x0, sizeof(PMSys));
+
+       _init_pmsys(pmsys);
+       _init_bldev(pmsys, flags);
+
+       if (pmsys->bl_onoff == NULL || pmsys->sys_power_state == NULL) {
+               _E("We have no managable resource to reduce the power consumption");
+               return -1;
+       }
+
+       touchscreen_node = getenv("PM_TOUCHSCREEN");
+       _D("touchscreen node : %s", touchscreen_node);
+
+       touchkey_node = getenv("PM_TOUCHKEY");
+       _D("touchkey node : %s", touchkey_node);
+
+       _init_ops();
+
+       return 0;
+}
+
+int exit_sysfs(void)
+{
+       int fd;
+
+       fd = open("/tmp/sem.pixmap_1", O_RDONLY);
+       if (fd == -1) {
+               _E("X server disable");
+               backlight_on();
+       }
+
+       backlight_update();
+       touchscreen_on();
+       touchkey_on();
+
+       free(pmsys);
+       pmsys = NULL;
+       if(fd != -1)
+               close(fd);
+
+       return 0;
+}
diff --git a/src/display/device-interface.h b/src/display/device-interface.h
new file mode 100644 (file)
index 0000000..f50f1da
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2011 - 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.
+ */
+
+
+/**
+ * @file       device-interface.h
+ * @brief      backlight, touch, power devices interface module header
+ */
+#ifndef __DEVICE_INTERFACE_H__
+#define __DEVICE_INTERFACE_H__
+
+#include <stdbool.h>
+
+#define FLAG_X_DPMS            0x2
+
+#define DEFAULT_DISPLAY 0
+
+#define PM_MAX_BRIGHTNESS       100
+#define PM_MIN_BRIGHTNESS       1
+#define PM_DEFAULT_BRIGHTNESS  60
+
+#define PM_LCD_POWER_ON                0
+#define PM_LCD_POWER_OFF       4
+
+#define PM_LCD_RETRY_CNT       3
+#define STATUS_STANDBY         (STATUS_ON + 1)
+
+#define DISP_INDEX_SHIFT       16
+#define DISP_CMD(prop, index)  ((index << DISP_INDEX_SHIFT) | prop)
+
+/*
+ * Event type enumeration
+ */
+enum {
+       EVENT_TIMEOUT = 0,      /*< time out event from timer */
+       EVENT_DEVICE = EVENT_TIMEOUT,   /*< wake up by devices except input devices */
+       EVENT_INPUT,            /*< input event from noti service */
+       EVENT_END,
+};
+
+extern int init_sysfs(unsigned int);
+extern int exit_sysfs(void);
+
+struct _backlight_ops {
+       int (*off)(void);
+       int (*dim)(void);
+       int (*on)(void);
+       int (*update)(void);
+       int (*standby)(void);
+       int (*hbm_off)(void);
+       int (*set_default_brt)(int level);
+       int (*get_lcd_power)(void);
+       int (*set_custom_status)(bool on);
+       bool (*get_custom_status)(void);
+       int (*save_custom_brightness)(void);
+       int (*custom_update)(void);
+       int (*set_force_brightness)(int level);
+};
+
+struct _touch_ops {
+       int (*screen_on)(void);
+       int (*screen_off)(void);
+       int (*key_on)(void);
+       int (*key_off)(void);
+};
+
+struct _power_ops {
+       int (*suspend)(void);
+       int (*pre_suspend)(void);
+       int (*post_resume)(void);
+       int (*power_lock)(void);
+       int (*power_unlock)(void);
+       int (*get_power_lock_support)(void);
+       int (*check_wakeup_src)(void);
+};
+
+extern struct _backlight_ops backlight_ops;
+extern struct _touch_ops touch_ops;
+extern struct _power_ops power_ops;
+
+#endif
+
diff --git a/src/display/display-dbus.c b/src/display/display-dbus.c
new file mode 100644 (file)
index 0000000..e533f51
--- /dev/null
@@ -0,0 +1,1274 @@
+/*
+ * 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.
+ */
+
+
+/**
+ * @file       display-dbus.c
+ * @brief      dbus interface
+ *
+ */
+
+#include <error.h>
+#include <stdbool.h>
+#include <Ecore.h>
+#include <device-node.h>
+
+#include "core/log.h"
+#include "util.h"
+#include "core.h"
+#include "weaks.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "dd-display.h"
+
+#define TELEPHONY_PATH                 "/org/tizen/telephony/SAMSUNG_QMI"
+#define TELEPHONY_INTERFACE_SIM                "org.tizen.telephony.Sim"
+#define SIGNAL_SIM_STATUS              "Status"
+#define SIM_CARD_NOT_PRESENT           (0x01)
+
+#define VCONFKEY_LCD_BRIGHTNESS_INIT "db/private/deviced/lcd_brightness_init"
+
+#define SIGNAL_HOMESCREEN              "HomeScreen"
+#define SIGNAL_EXTREME                 "Extreme"
+#define SIGNAL_NOTEXTREME              "NotExtreme"
+
+#define BLIND_MASK(val)                        ((val) & 0xFFFF)
+#define BLIND_RED(val)                 BLIND_MASK((val) >> 32)
+#define BLIND_GREEN(val)               BLIND_MASK((val) >> 16)
+#define BLIND_BLUE(val)                        BLIND_MASK((val))
+
+#define DISPLAY_DIM_BRIGHTNESS  0
+#define DUMP_MODE_WATING_TIME   600000
+
+static DBusMessage *edbus_start(E_DBus_Object *obj, DBusMessage *msg)
+{
+       static const struct device_ops *display_device_ops;
+
+       if (!display_device_ops) {
+               display_device_ops = find_device("display");
+               if (!display_device_ops)
+                       return dbus_message_new_method_return(msg);
+       }
+
+       display_device_ops->start();
+       return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *edbus_stop(E_DBus_Object *obj, DBusMessage *msg)
+{
+       static const struct device_ops *display_device_ops;
+
+       if (!display_device_ops) {
+               display_device_ops = find_device("display");
+               if (!display_device_ops)
+                       return dbus_message_new_method_return(msg);
+       }
+
+       display_device_ops->stop();
+       return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *edbus_lockstate(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char *state_str;
+       char *option1_str;
+       char *option2_str;
+       int timeout;
+       pid_t pid;
+       int state;
+       int flag;
+       int ret;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &state_str,
+                   DBUS_TYPE_STRING, &option1_str,
+                   DBUS_TYPE_STRING, &option2_str,
+                   DBUS_TYPE_INT32, &timeout, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!state_str || timeout < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (!strcmp(state_str, PM_LCDON_STR))
+               state = LCD_NORMAL;
+       else if (!strcmp(state_str, PM_LCDDIM_STR))
+               state = LCD_DIM;
+       else if (!strcmp(state_str, PM_LCDOFF_STR))
+               state = LCD_OFF;
+       else {
+               _E("%s state is invalid, dbus ignored!", state_str);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!strcmp(option1_str, STAYCURSTATE_STR))
+               flag = STAY_CUR_STATE;
+       else if (!strcmp(option1_str, GOTOSTATENOW_STR))
+               flag = GOTO_STATE_NOW;
+       else {
+               _E("%s option is invalid. set default option!", option1_str);
+               flag = STAY_CUR_STATE;
+       }
+
+       if (!strcmp(option2_str, HOLDKEYBLOCK_STR))
+               flag |= HOLD_KEY_BLOCK;
+       else if (!strcmp(option2_str, STANDBYMODE_STR))
+               flag |= STANDBY_MODE;
+
+       if (check_dimstay(state, flag) == true) {
+               _E("LCD state can not be changed to OFF state now!");
+               flag &= ~GOTO_STATE_NOW;
+               flag |= STAY_CUR_STATE;
+       }
+
+       ret = pm_lock_internal(pid, state, flag, timeout);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *edbus_unlockstate(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char *state_str;
+       char *option_str;
+       pid_t pid;
+       int state;
+       int flag;
+       int ret;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &state_str,
+                   DBUS_TYPE_STRING, &option_str, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!state_str) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (!strcmp(state_str, PM_LCDON_STR))
+               state = LCD_NORMAL;
+       else if (!strcmp(state_str, PM_LCDDIM_STR))
+               state = LCD_DIM;
+       else if (!strcmp(state_str, PM_LCDOFF_STR))
+               state = LCD_OFF;
+       else {
+               _E("%s state is invalid, dbus ignored!", state_str);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!strcmp(option_str, SLEEP_MARGIN_STR))
+               flag = PM_SLEEP_MARGIN;
+       else if (!strcmp(option_str, RESET_TIMER_STR))
+               flag = PM_RESET_TIMER;
+       else if (!strcmp(option_str, KEEP_TIMER_STR))
+               flag = PM_KEEP_TIMER;
+       else {
+               _E("%s option is invalid. set default option!", option_str);
+               flag = PM_RESET_TIMER;
+       }
+
+       ret = pm_unlock_internal(pid, state, flag);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *edbus_changestate(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char *state_str;
+       pid_t pid;
+       int state;
+       int ret;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &state_str, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (!state_str) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (!strcmp(state_str, PM_LCDON_STR))
+               state = LCD_NORMAL;
+       else if (!strcmp(state_str, PM_LCDDIM_STR))
+               state = LCD_DIM;
+       else if (!strcmp(state_str, PM_LCDOFF_STR))
+               state = LCD_OFF;
+       else if (!strcmp(state_str, PM_SUSPEND_STR))
+               state = SUSPEND;
+       else {
+               _E("%s state is invalid, dbus ignored!", state_str);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (check_dimstay(state, GOTO_STATE_NOW) == true) {
+               _E("LCD state can not be changed to OFF state!");
+               ret = -EBUSY;
+               goto out;
+       }
+
+       ret = pm_change_internal(pid, state);
+
+       if (!ret && state == LCD_OFF)
+               update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *edbus_getdisplaycount(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, cnt, ret;
+
+       cmd = DISP_CMD(PROP_DISPLAY_DISPLAY_COUNT, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &cnt);
+       if (ret >= 0)
+               ret = cnt;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_getmaxbrightness(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, brt, ret;
+
+       cmd = DISP_CMD(PROP_DISPLAY_MAX_BRIGHTNESS, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &brt);
+       if (ret >= 0)
+               ret = brt;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_setmaxbrightness(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, brt, ret;
+
+       dbus_message_iter_init(msg, &iter);
+       dbus_message_iter_get_basic(&iter, &brt);
+
+       cmd = DISP_CMD(PROP_DISPLAY_MAX_BRIGHTNESS, DEFAULT_DISPLAY);
+       ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, brt);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_getbrightness(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, brt, ret;
+
+       cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &brt);
+       if (ret >= 0)
+               ret = brt;
+
+       _I("get brightness %d, %d", brt, ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &brt);
+       return reply;
+}
+
+static DBusMessage *edbus_setbrightness(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, brt, powersaver, autobrt, ret;
+
+       dbus_message_iter_init(msg, &iter);
+       dbus_message_iter_get_basic(&iter, &brt);
+
+       if (brt == DISPLAY_DIM_BRIGHTNESS) {
+               _E("application can not set this value(DIM VALUE:%d)", brt);
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &powersaver) != 0) {
+               _E("Failed to get VCONFKEY_SETAPPL_PSMODE value");
+               powersaver = SETTING_PSMODE_NORMAL;
+       }
+
+       if (powersaver == SETTING_PSMODE_WEARABLE) {
+               _D("brightness is changed in powersaver mode!");
+               backlight_ops.set_force_brightness(0);
+       }
+
+       if (vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &autobrt) != 0) {
+               _E("Failed to get VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT value");
+               autobrt = SETTING_BRIGHTNESS_AUTOMATIC_OFF;
+       }
+
+       if (autobrt == SETTING_BRIGHTNESS_AUTOMATIC_ON) {
+               _D("auto_brightness state is ON, can not change the brightness value");
+               ret = 0;
+               goto error;
+       }
+
+       cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
+       ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, brt);
+       if (ret < 0)
+               goto error;
+       if (vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, brt) != 0)
+               _E("Failed to set VCONFKEY_SETAPPL_LCD_BRIGHTNESS value");
+
+       if (vconf_set_int(VCONFKEY_PM_CURRENT_BRIGHTNESS, brt) != 0)
+               _E("Failed to set VCONFKEY_PM_CURRENT_BRIGHTNESS value");
+
+       _I("set brightness %d, %d", brt, ret);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_holdbrightness(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, brt, powersaver, autobrt, ret;
+
+       dbus_message_iter_init(msg, &iter);
+       dbus_message_iter_get_basic(&iter, &brt);
+
+       if (brt == DISPLAY_DIM_BRIGHTNESS) {
+               _E("application can not set this value(DIM VALUE:%d)", brt);
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &powersaver) != 0) {
+               _E("Failed to get VCONFKEY_SETAPPL_PSMODE value");
+               powersaver = SETTING_PSMODE_NORMAL;
+       }
+
+       if (powersaver == SETTING_PSMODE_WEARABLE) {
+               _D("Powersaver mode! brightness can not be changed!");
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &autobrt) != 0) {
+               _E("Failed to get VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT value");
+               autobrt = SETTING_BRIGHTNESS_AUTOMATIC_OFF;
+       }
+
+       vconf_set_int(VCONFKEY_PM_CUSTOM_BRIGHTNESS_STATUS, VCONFKEY_PM_CUSTOM_BRIGHTNESS_ON);
+
+       cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
+       ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, brt);
+       if (ret < 0)
+               goto error;
+
+       if (autobrt == SETTING_BRIGHTNESS_AUTOMATIC_ON) {
+               _D("Auto brightness will be paused");
+               vconf_set_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, SETTING_BRIGHTNESS_AUTOMATIC_PAUSE);
+       }
+
+       if (vconf_set_int(VCONFKEY_PM_CURRENT_BRIGHTNESS, brt) != 0)
+               _E("Failed to set VCONFKEY_PM_CURRENT_BRIGHTNESS value");
+
+       _I("hold brightness %d, %d", brt, ret);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+
+}
+
+static DBusMessage *edbus_releasebrightness(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, bat, charger, changed, setting, brt, autobrt, ret = 0;
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, &bat) != 0) {
+               _E("Failed to get VCONFKEY_SYSMAN_BATTERY_STATUS_LOW value");
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger) != 0) {
+               _E("Failed to get VCONFKEY_SYSMAN_CHARGER_STATUS value");
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (vconf_get_bool(VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM, &changed) != 0) {
+               _E("Failed to get VCONFKEY_PM_BRIGHTNESS_CHANGED_IN_LPM value");
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (vconf_get_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, &setting) != 0) {
+               _E("Failed to get VCONFKEY_SETAPPL_LCD_BRIGHTNESS value");
+               ret = -EPERM;
+               goto error;
+       }
+
+       if (vconf_get_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, &autobrt) != 0) {
+               _E("Failed to get VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT value");
+               ret = -EPERM;
+               goto error;
+       }
+
+       vconf_set_int(VCONFKEY_PM_CUSTOM_BRIGHTNESS_STATUS, VCONFKEY_PM_CUSTOM_BRIGHTNESS_OFF);
+
+       cmd = DISP_CMD(PROP_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &brt);
+       if (ret < 0)
+               brt = ret;
+
+       // check dim state
+       if (low_battery_state(bat) &&
+           charger == VCONFKEY_SYSMAN_CHARGER_DISCONNECTED && !changed) {
+               _D("batt warning low : brightness is not changed!");
+               if (brt != 0) {
+                       device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_BRIGHTNESS, 0);
+               }
+               goto error;
+       }
+
+       if (autobrt == SETTING_BRIGHTNESS_AUTOMATIC_OFF) {
+               if (brt != setting) {
+                       device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_BRIGHTNESS, setting);
+                       if (vconf_set_int(VCONFKEY_PM_CURRENT_BRIGHTNESS, setting) != 0) {
+                               _E("Failed to set VCONFKEY_PM_CURRENT_BRIGHTNESS value");
+                       }
+               }
+       } else if (autobrt == SETTING_BRIGHTNESS_AUTOMATIC_PAUSE) {
+               _D("Auto brightness will be enable");
+               vconf_set_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT, SETTING_BRIGHTNESS_AUTOMATIC_ON);
+       }
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_getaclstatus(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, st, ret;
+
+       cmd = DISP_CMD(PROP_DISPLAY_ACL_CONTROL, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &st);
+       if (ret >= 0)
+               ret = st;
+
+       _I("get acl status %d, %d", st, ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_setaclstatus(E_DBus_Object *ob, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, st, ret;
+
+       dbus_message_iter_init(msg, &iter);
+       dbus_message_iter_get_basic(&iter, &st);
+
+       cmd = DISP_CMD(PROP_DISPLAY_ACL_CONTROL, DEFAULT_DISPLAY);
+       ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, st);
+
+       _I("set acl status %d, %d", st, ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_getautotone(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, tone, ret;
+
+       cmd = DISP_CMD(PROP_DISPLAY_AUTO_SCREEN_TONE, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &tone);
+       if (ret >= 0)
+               ret = tone;
+
+       _I("get auto screen tone %d, %d", tone, ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_setautotone(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, tone, ret;
+
+       dbus_message_iter_init(msg, &iter);
+       dbus_message_iter_get_basic(&iter, &tone);
+
+       cmd = DISP_CMD(PROP_DISPLAY_AUTO_SCREEN_TONE, DEFAULT_DISPLAY);
+       ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, tone);
+
+       _I("set auto screen tone %d, %d", tone, ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_setautotoneforce(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, tone, ret;
+
+       dbus_message_iter_init(msg, &iter);
+       dbus_message_iter_get_basic(&iter, &tone);
+
+       cmd = DISP_CMD(PROP_DISPLAY_AUTO_SCREEN_TONE_FORCE, DEFAULT_DISPLAY);
+       ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, tone);
+
+       _I("set auto screen tone force %d, %d", tone, ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_setrefreshrate(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int app, val, cmd, ret, control;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_INT32, &app,
+                       DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (app < 0 || app >= ARRAY_SIZE(display_conf.framerate_app) || val < 0) {
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (!display_conf.framerate_app[app]) {
+               _I("This case(%d) is not support in this target", app);
+               ret = -EPERM;
+               goto error;
+       }
+
+       control = display_conf.control_display;
+
+       if (control)
+               backlight_ops.off();
+
+       _D("app : %d, value : %d", app, val);
+       cmd = DISP_CMD(PROP_DISPLAY_FRAME_RATE, DEFAULT_DISPLAY);
+       ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, val);
+
+       if (control)
+               backlight_ops.on();
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_getcolorblind(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, val, ret;
+
+       cmd = DISP_CMD(PROP_DISPLAY_IMAGE_ENHANCE_COLOR_BLIND, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &val);
+       if (ret >= 0)
+               ret = val;
+
+       _I("get color blind %d", val);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_setcolorblind(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, val, ret;
+       unsigned int power;
+       uint64_t red, grn, blu;
+       struct color_blind_info info;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &power,
+                       DBUS_TYPE_UINT64, &red, DBUS_TYPE_UINT64, &grn,
+                       DBUS_TYPE_UINT64, &blu, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       info.power = power;
+       info.RrCr = BLIND_RED(red);
+       info.RgCg = BLIND_GREEN(red);
+       info.RbCb = BLIND_BLUE(red);
+       info.GrMr = BLIND_RED(grn);
+       info.GgMg = BLIND_GREEN(grn);
+       info.GbMb = BLIND_BLUE(grn);
+       info.BrYr = BLIND_RED(blu);
+       info.BgYg = BLIND_GREEN(blu);
+       info.BbYb = BLIND_BLUE(blu);
+
+       cmd = DISP_CMD(PROP_DISPLAY_IMAGE_ENHANCE_COLOR_BLIND, DEFAULT_DISPLAY);
+       ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, (int)&info);
+
+       _I("set color blind %d, %hu, %hu, %hu, %hu, %hu, %hu, %hu, %hu, %hu, %d",
+                       info.power, info.RrCr, info.RgCg, info.RbCb, info.GrMr, info.GgMg,
+                       info.GbMb, info.BrYr, info.BgYg, info.BbYb, ret);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_gethbm(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int hbm;
+
+       if (!msg) {
+               _E("msg is empty!");
+               return NULL;
+       }
+
+       /* check weak function symbol */
+       if (!hbm_get_state) {
+               hbm = -ENOSYS;
+               goto error;
+       }
+
+       hbm = hbm_get_state();
+
+       if (hbm < 0)
+               _E("failed to get high brightness mode %d", hbm);
+       else
+               _D("get high brightness mode %d", hbm);
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &hbm);
+       return reply;
+}
+
+static DBusMessage *edbus_sethbm(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int hbm, ret;
+
+       if (!msg) {
+               _E("msg is empty!");
+               return NULL;
+       }
+
+       if (!dbus_message_get_args(msg, NULL,
+                   DBUS_TYPE_INT32, &hbm,
+                   DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       /* check weak function symbol */
+       if (!hbm_set_state) {
+               ret = -ENOSYS;
+               goto error;
+       }
+
+       ret = hbm_set_state(hbm);
+
+       if (ret < 0)
+               _E("failed to set high brightness mode (%d,%d)", ret, hbm);
+       else
+               _I("set high brightness mode (%d,%d)", ret, hbm);
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_sethbm_timeout(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int hbm, timeout, ret;
+
+       if (!msg) {
+               _E("msg is empty!");
+               return NULL;
+       }
+
+       if (!dbus_message_get_args(msg, NULL,
+                   DBUS_TYPE_INT32, &hbm,
+                   DBUS_TYPE_INT32, &timeout, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       /* check weak function symbol */
+       if (!hbm_set_state_with_timeout) {
+               ret = -ENOSYS;
+               goto error;
+       }
+
+       ret = hbm_set_state_with_timeout(hbm, timeout);
+
+       if (ret < 0)
+               _E("failed to set high brightness mode (%d,%d,%d)",
+                   ret, hbm, timeout);
+       else
+               _I("set high brightness mode (%d,%d,%d)",
+                   ret, hbm, timeout);
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_setautobrightnessmin(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+       pid_t pid;
+       const char *sender;
+
+       sender = dbus_message_get_sender(msg);
+        if (!sender) {
+                _E("invalid sender name!");
+                ret = -EINVAL;
+               goto error;
+        }
+       if (!display_info.set_autobrightness_min) {
+               ret = -EIO;
+               goto error;
+       }
+       dbus_message_iter_init(msg, &iter);
+       dbus_message_iter_get_basic(&iter, &val);
+
+       pid = get_edbus_sender_pid(msg);
+       ret = display_info.set_autobrightness_min(val, (char *)sender);
+       if (ret) {
+               _W("fail to set autobrightness min %d, %d by %d", val, ret, pid);
+               goto error;
+       }
+       if (display_info.reset_autobrightness_min) {
+               register_edbus_watch(msg, WATCH_DISPLAY_AUTOBRIGHTNESS_MIN,
+                   display_info.reset_autobrightness_min);
+               _I("set autobrightness min %d by %d", val, pid);
+       }
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *edbus_setlcdtimeout(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int on, dim, holdkey_block, ret;
+       pid_t pid;
+       const char *sender;
+
+       sender = dbus_message_get_sender(msg);
+       if (!sender) {
+               _E("invalid sender name!");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &on,
+                   DBUS_TYPE_INT32, &dim, DBUS_TYPE_INT32, &holdkey_block,
+                   DBUS_TYPE_INVALID);
+
+       pid = get_edbus_sender_pid(msg);
+       ret = set_lcd_timeout(on, dim, holdkey_block, sender);
+       if (ret) {
+               _W("fail to set lcd timeout %d by %d", ret, pid);
+       } else {
+               register_edbus_watch(msg, WATCH_DISPLAY_LCD_TIMEOUT,
+                   reset_lcd_timeout);
+               _I("set lcd timeout on %d, dim %d, holdblock %d by %d",
+                   on, dim, holdkey_block, pid);
+       }
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *edbus_lockscreenbgon(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret = 0;
+       char *on;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &on,
+                   DBUS_TYPE_INVALID);
+
+       if (!ret) {
+               _E("fail to update lcdscreen bg on state %d", ret);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (!strcmp(on, "true"))
+               update_pm_setting(SETTING_LOCK_SCREEN_BG, true);
+       else if (!strcmp(on, "false"))
+               update_pm_setting(SETTING_LOCK_SCREEN_BG, false);
+       else
+               ret = -EINVAL;
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *edbus_dumpmode(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret = 0;
+       char *on;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &on,
+                   DBUS_TYPE_INVALID);
+
+       if (!ret) {
+               _E("fail to get dumpmode state %d", ret);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (!strcmp(on, "on"))
+               pm_lock_internal(INTERNAL_LOCK_DUMPMODE, LCD_OFF,
+                   STAY_CUR_STATE, DUMP_MODE_WATING_TIME);
+       else if (!strcmp(on, "off"))
+               pm_unlock_internal(INTERNAL_LOCK_DUMPMODE, LCD_OFF,
+                   PM_SLEEP_MARGIN);
+       else
+               ret = -EINVAL;
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *edbus_savelog(E_DBus_Object *obj, DBusMessage *msg)
+{
+       save_display_log();
+       return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *edbus_powerkeyignore(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret = 0;
+       int on;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &on,
+                   DBUS_TYPE_INVALID);
+
+       if (!ret) {
+               _E("fail to get powerkey ignore %d", ret);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (CHECK_OPS(keyfilter_ops, set_powerkey_ignore))
+               keyfilter_ops->set_powerkey_ignore(on == 1 ? true : false);
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *edbus_powerkeylcdoff(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       if (CHECK_OPS(keyfilter_ops, powerkey_lcdoff))
+               ret = keyfilter_ops->powerkey_lcdoff();
+       else
+               ret = -ENOSYS;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *edbus_customlcdon(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret = 0;
+       int timeout;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &timeout,
+                   DBUS_TYPE_INVALID);
+
+       if (!ret) {
+               _E("fail to get custom lcd timeout %d", ret);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = custom_lcdon(timeout);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "start",           NULL,  NULL, edbus_start },
+       { "stop",            NULL,  NULL, edbus_stop },
+       { "lockstate",     "sssi",   "i", edbus_lockstate },
+       { "unlockstate",     "ss",   "i", edbus_unlockstate },
+       { "changestate",      "s",   "i", edbus_changestate },
+       { "getbrightness",   NULL,   "i", edbus_getbrightness },        /* deprecated */
+       { "setbrightness",    "i",   "i", edbus_setbrightness },        /* deprecated */
+       { "getautotone",     NULL,   "i", edbus_getautotone },  /* deprecated */
+       { "setautotone",      "i",   "i", edbus_setautotone },  /* deprecated */
+       { "setframerate",    "ii",   "i", edbus_setrefreshrate },       /* deprecated */
+       { "getcolorblind",   NULL,   "i", edbus_getcolorblind },        /* deprecated */
+       { "setcolorblind", "uttt",   "i", edbus_setcolorblind },        /* deprecated */
+       { "setautobrightnessmin", "i", "i", edbus_setautobrightnessmin },
+       { "setlcdtimeout",  "iii",   "i", edbus_setlcdtimeout },
+       { "LockScreenBgOn",   "s",   "i", edbus_lockscreenbgon },
+       { "GetDisplayCount", NULL,   "i", edbus_getdisplaycount },
+       { "GetMaxBrightness",NULL,   "i", edbus_getmaxbrightness },
+       { "SetMaxBrightness", "i",   "i", edbus_setmaxbrightness },
+       { "GetBrightness",   NULL,   "i", edbus_getbrightness },
+       { "SetBrightness",    "i",   "i", edbus_setbrightness },
+       { "HoldBrightness",   "i",   "i", edbus_holdbrightness },
+       { "ReleaseBrightness", NULL, "i", edbus_releasebrightness },
+       { "GetAclStatus",    NULL,   "i", edbus_getaclstatus },
+       { "SetAclStatus",    NULL,   "i", edbus_setaclstatus },
+       { "GetAutoTone",     NULL,   "i", edbus_getautotone },
+       { "SetAutoTone",      "i",   "i", edbus_setautotone },
+       { "SetAutoToneForce", "i",   "i", edbus_setautotoneforce },
+       { "SetRefreshRate",  "ii",   "i", edbus_setrefreshrate },
+       { "GetColorBlind",   NULL,   "i", edbus_getcolorblind },
+       { "SetColorBlind", "uttt",   "i", edbus_setcolorblind },
+       { "GetHBM",          NULL,   "i", edbus_gethbm },
+       { "SetHBM",           "i",   "i", edbus_sethbm },
+       { "SetHBMTimeout"   ,"ii",   "i", edbus_sethbm_timeout },
+       { "Dumpmode",         "s",   "i", edbus_dumpmode },
+       { "SaveLog",         NULL,  NULL, edbus_savelog },
+       { "PowerKeyIgnore",   "i",  NULL, edbus_powerkeyignore },
+       { "PowerKeyLCDOff",  NULL,   "i", edbus_powerkeylcdoff },
+       { "CustomLCDOn",      "i",   "i", edbus_customlcdon },
+       /* Add methods here */
+};
+
+static void sim_signal_handler(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       int ret, val;
+       static int state = false;
+
+       if (state)
+               return;
+
+       ret = dbus_message_is_signal(msg, TELEPHONY_INTERFACE_SIM,
+           SIGNAL_SIM_STATUS);
+       if (!ret) {
+               _E("there is no power off popup signal");
+               return;
+       }
+
+       ret = vconf_get_bool(VCONFKEY_LCD_BRIGHTNESS_INIT, &state);
+       if (ret < 0 || state)
+               return;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val,
+           DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+       }
+
+       if (val != SIM_CARD_NOT_PRESENT) {
+               /* change setting : autobrightness on */
+               state = true;
+               vconf_set_bool(VCONFKEY_LCD_BRIGHTNESS_INIT, state);
+               vconf_set_int(VCONFKEY_SETAPPL_BRIGHTNESS_AUTOMATIC_INT,
+                   SETTING_BRIGHTNESS_AUTOMATIC_ON);
+               vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS,
+                   PM_DEFAULT_BRIGHTNESS);
+               _I("SIM card is inserted at first!");
+       }
+}
+
+static void homescreen_signal_handler(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       int ret;
+       char *screen;
+
+
+       ret = dbus_message_is_signal(msg, DEVICED_INTERFACE_NAME,
+           SIGNAL_HOMESCREEN);
+       if (!ret) {
+               _E("there is no homescreen signal");
+               return;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &screen,
+           DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+       }
+
+       _D("screen : %s", screen);
+
+       if (set_alpm_screen)
+               set_alpm_screen(screen);
+       else
+               _E("alpm screen mode is not supported!");
+}
+
+static void extreme_signal_handler(void *data, DBusMessage *msg)
+{
+       int ret;
+
+       ret = dbus_message_is_signal(msg, POPUP_INTERFACE_LOWBAT,
+           SIGNAL_EXTREME);
+       if (!ret) {
+               _E("there is no extreme signal");
+               return;
+       }
+
+       pm_status_flag &= ~BRTCH_FLAG;
+       if (hbm_get_state != NULL && hbm_get_state() == true)
+               hbm_set_state_with_timeout(false, 0);
+       backlight_ops.update();
+       _D("extreme mode : enter dim state!");
+       if (vconf_set_int(VCONFKEY_PM_KEY_IGNORE, TRUE) != 0)
+               _E("failed to set vconf status");
+}
+
+static void not_extreme_signal_handler(void *data, DBusMessage *msg)
+{
+       int ret;
+
+       ret = dbus_message_is_signal(msg, POPUP_INTERFACE_LOWBAT,
+           SIGNAL_NOTEXTREME);
+       if (!ret) {
+               _E("there is no extreme signal");
+               return;
+       }
+
+       _D("release extreme mode");
+       if (vconf_set_int(VCONFKEY_PM_KEY_IGNORE, FALSE) != 0)
+               _E("failed to set vconf status");
+}
+
+int init_pm_dbus(void)
+{
+       int ret;
+
+       ret = register_edbus_method(DEVICED_PATH_DISPLAY,
+                   edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0) {
+               _E("Failed to register edbus method! %d", ret);
+               return ret;
+       }
+
+       ret = register_edbus_signal_handler(TELEPHONY_PATH,
+                   TELEPHONY_INTERFACE_SIM, SIGNAL_SIM_STATUS,
+                   sim_signal_handler);
+       if (ret < 0 && ret != -EEXIST) {
+               _E("Failed to register signal handler! %d", ret);
+               return ret;
+       }
+
+       ret = register_edbus_signal_handler(DEVICED_OBJECT_PATH,
+                   DEVICED_INTERFACE_NAME, SIGNAL_HOMESCREEN,
+                   homescreen_signal_handler);
+       if (ret < 0 && ret != -EEXIST) {
+               _E("Failed to register signal handler! %d", ret);
+               return ret;
+       }
+
+       ret = register_edbus_signal_handler(POPUP_PATH_LOWBAT,
+                   POPUP_INTERFACE_LOWBAT, SIGNAL_EXTREME,
+                   extreme_signal_handler);
+       if (ret < 0 && ret != -EEXIST) {
+               _E("Failed to register signal handler! %d", ret);
+               return ret;
+       }
+       ret = register_edbus_signal_handler(POPUP_PATH_LOWBAT,
+                   POPUP_INTERFACE_LOWBAT, SIGNAL_NOTEXTREME,
+                   not_extreme_signal_handler);
+       if (ret < 0 && ret != -EEXIST) {
+               _E("Failed to register signal handler! %d", ret);
+               return ret;
+       }
+       return 0;
+}
+
diff --git a/src/display/display-emul.conf b/src/display/display-emul.conf
new file mode 100644 (file)
index 0000000..707b817
--- /dev/null
@@ -0,0 +1,37 @@
+[Display]
+# deviced is pending lcd on until lock screen shows.
+# This is the maximum pending time.
+LockScreenWaitingTime=0.3      #second
+
+# Power-off popup is launched when power key is long pressed.
+# This is duration of pressing power key.
+LongPressInterval=2            #second
+
+# This is polling time of auto brightness.
+LightSensorSamplingInterval=1  #second
+
+# display state is changed to SLEEP state after this time.
+# If this value is large, it causes power consumption problem.
+LCDOffTimeout=500              # milli second
+
+# This is n step of auto brightness.
+# If brightness is change from a to b, brightness's changed n times from a to b.
+BrightnessChangeStep=10
+
+# This is threshold value of light sensor.
+# If lux value is greater than threshold,
+# HBM(High Brightness Mode) is on.
+HBMLuxThreshold=39768
+
+# If this value is yes, LCD is always on except pressing power key.
+# Default value is no, LCD is turned off by lcd timeout.
+LCDAlwaysOn=yes                        # yes or no
+
+# Just below application only allow to change display frame rate.
+# refer to enum refresh_app
+ChangedFrameRateAllowed=all            # all
+ControlDisplay=no              # yes or no
+
+# LCD is not turned off when this value is yes and key double pressed
+PowerKeyDoublePressSupport=yes  # yes or no
+
diff --git a/src/display/display-exynos.conf b/src/display/display-exynos.conf
new file mode 100644 (file)
index 0000000..8924ae9
--- /dev/null
@@ -0,0 +1,40 @@
+[Display]
+# deviced is pending lcd on until lock screen shows.
+# This is the maximum pending time.
+LockScreenWaitingTime=0.3      #second
+
+# Power-off popup is launched when power key is long pressed.
+# This is duration of pressing power key.
+LongPressInterval=2            #second
+
+# This is polling time of auto brightness.
+LightSensorSamplingInterval=1  #second
+
+# display state is changed to SLEEP state after this time.
+# If this value is large, it causes power consumption problem.
+LCDOffTimeout=500              # milli second
+
+# This is n step of auto brightness.
+# If brightness is change from a to b, brightness's changed n times from a to b.
+BrightnessChangeStep=10
+
+# This is threshold value of light sensor.
+# If lux value is greater than threshold,
+# HBM(High Brightness Mode) is on.
+HBMLuxThreshold=39768
+
+# If this value is yes, LCD is always on except pressing power key.
+# Default value is no, LCD is turned off by lcd timeout.
+LCDAlwaysOn=no                 # yes or no
+
+# Just below application only allow to change display frame rate.
+# refer to enum refresh_app
+ChangedFrameRateAllowed=all            # all
+ControlDisplay=no              # yes or no
+
+# LCD is not turned off when this value is yes and key double pressed
+PowerKeyDoublePressSupport=yes  # yes or no
+
+# ALPM(AMOLED Low Power Mode)
+UseALPM=no                     # yes or no
+
diff --git a/src/display/display-msm.conf b/src/display/display-msm.conf
new file mode 100644 (file)
index 0000000..f9d065f
--- /dev/null
@@ -0,0 +1,37 @@
+[Display]
+# deviced is pending lcd on until lock screen shows.
+# This is the maximum pending time.
+LockScreenWaitingTime=0.3      #second
+
+# Power-off popup is launched when power key is long pressed.
+# This is duration of pressing power key.
+LongPressInterval=2            #second
+
+# This is polling time of auto brightness.
+LightSensorSamplingInterval=1  #second
+
+# display state is changed to SLEEP state after this time.
+# If this value is large, it causes power consumption problem.
+LCDOffTimeout=500              # milli second
+
+# This is n step of auto brightness.
+# If brightness is change from a to b, brightness's changed n times from a to b.
+BrightnessChangeStep=10
+
+# This is threshold value of light sensor.
+# If lux value is greater than threshold,
+# HBM(High Brightness Mode) is on.
+HBMLuxThreshold=39768
+
+# If this value is yes, LCD is always on except pressing power key.
+# Default value is no, LCD is turned off by lcd timeout.
+LCDAlwaysOn=no                 # yes or no
+
+# Just below application only allow to change display frame rate.
+# refer to enum refresh_app
+ChangedFrameRateAllowed=setting        # setting
+ControlDisplay=yes             # yes or no
+
+# LCD is not turned off when this value is yes and key double pressed
+PowerKeyDoublePressSupport=no  # yes or no
+
diff --git a/src/display/display-ops.c b/src/display/display-ops.c
new file mode 100644 (file)
index 0000000..172b707
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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 "util.h"
+#include "display-ops.h"
+#include "core/list.h"
+#include "core/common.h"
+
+static dd_list *disp_head;
+
+void add_display(const struct display_ops *disp)
+{
+       DD_LIST_APPEND(disp_head, disp);
+}
+
+void remove_display(const struct display_ops *disp)
+{
+       DD_LIST_REMOVE(disp_head, disp);
+}
+
+const struct display_ops *find_display(const char *name)
+{
+       dd_list *elem;
+       const struct display_ops *disp;
+
+       DD_LIST_FOREACH(disp_head, elem, disp) {
+               if (!strcmp(disp->name, name))
+                       return disp;
+       }
+       return NULL;
+}
+
+void display_ops_init(void *data)
+{
+       dd_list *elem;
+       const struct display_ops *disp;
+
+       DD_LIST_FOREACH(disp_head, elem, disp) {
+               _D("[%s] initialize", disp->name);
+               if (disp->init)
+                       disp->init(data);
+       }
+}
+
+void display_ops_exit(void *data)
+{
+       dd_list *elem;
+       const struct display_ops *disp;
+
+       DD_LIST_FOREACH(disp_head, elem, disp) {
+               _D("[%s] deinitialize", disp->name);
+               if (disp->exit)
+                       disp->exit(data);
+       }
+}
+
diff --git a/src/display/display-ops.h b/src/display/display-ops.h
new file mode 100644 (file)
index 0000000..c11e188
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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 __DISPLAY_OPS_H__
+#define __DISPLAY_OPS_H__
+
+#include <errno.h>
+#include "core/common.h"
+
+struct display_ops {
+       char *name;
+       void (*init) (void *data);
+       void (*exit) (void *data);
+};
+
+void display_ops_init(void *data);
+void display_ops_exit(void *data);
+
+#define DISPLAY_OPS_REGISTER(disp)     \
+static void __CONSTRUCTOR__ module_init(void)  \
+{      \
+       add_display(disp);      \
+}      \
+static void __DESTRUCTOR__ module_exit(void)   \
+{      \
+       remove_display(disp);   \
+}
+
+void add_display(const struct display_ops *disp);
+void remove_display(const struct display_ops *disp);
+const struct display_ops *find_display(const char *name);
+
+#endif
diff --git a/src/display/enhance.c b/src/display/enhance.c
new file mode 100644 (file)
index 0000000..fb7a2e7
--- /dev/null
@@ -0,0 +1,676 @@
+/*
+ * 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 <stdbool.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <device-node.h>
+#include <sys/un.h>
+#include <stdarg.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+#include "core.h"
+#include "core/data.h"
+#include "core/devices.h"
+#include "core/queue.h"
+#include "core/log.h"
+#include "core/common.h"
+#include "proc/proc-handler.h"
+#include "device-interface.h"
+
+#define VCONFKEY_ENHANCE_MODE          "db/private/sysman/enhance_mode"
+#define VCONFKEY_ENHANCE_SCENARIO      "db/private/sysman/enhance_scenario"
+#define VCONFKEY_ENHANCE_TONE          "db/private/sysman/enhance_tone"
+#define VCONFKEY_ENHANCE_OUTDOOR       "db/private/sysman/enhance_outdoor"
+#define VCONFKEY_ENHANCE_PID           "memory/private/sysman/enhance_pid"
+
+#ifndef VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT
+#define VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT   "db/setting/auto_display_adjustment"
+#endif
+
+#define SETTING_NAME   "setting"
+#define CLUSTER_HOME   "cluster-home"
+#define BROWSER_NAME   "browser"
+
+enum lcd_enhance_type{
+       ENHANCE_MODE = 0,
+       ENHANCE_SCENARIO,
+       ENHANCE_TONE,
+       ENHANCE_OUTDOOR,
+       ENHANCE_MAX,
+};
+
+struct enhance_entry_t{
+       int pid;
+       int type[ENHANCE_MAX];
+};
+
+static Eina_List *enhance_ctl_list;
+static struct enhance_entry_t default_enhance;
+
+int get_glove_state(void)
+{
+       int ret, val;
+
+       ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, &val);
+       if (ret < 0) {
+               return ret;
+       }
+       return val;
+}
+
+void switch_glove_key(int val)
+{
+       int ret, exval;
+
+       ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_KEY_GLOVE_MODE, &exval);
+       if (ret < 0 || exval != val) {
+               ret = device_set_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_KEY_GLOVE_MODE, val);
+               if (ret < 0)
+                       _E("fail to set touch key glove mode");
+               else
+                       _D("glove key mode is %s", (val ? "on" : "off"));
+       }
+}
+
+static int check_default_process(int pid, char *default_name)
+{
+       char exe_name[PATH_MAX];
+       if (get_cmdline_name(pid, exe_name, PATH_MAX) != 0) {
+               _E("fail to check cmdline: %d (%s)", pid, default_name);
+               return -EINVAL;
+       }
+       if (strncmp(exe_name, default_name, strlen(default_name)) != 0) {
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static void restore_enhance_status(struct enhance_entry_t *entry)
+{
+       int ret;
+       int scenario;
+       static int pid;
+
+       if (pid == entry->pid)
+               return;
+
+       pid = entry->pid;
+
+       ret = device_get_property(DEVICE_TYPE_DISPLAY,
+               PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO, &scenario);
+       if (ret != 0) {
+               _E("fail to get status");
+               return;
+       }
+       if (entry->type[ENHANCE_SCENARIO] == scenario)
+               goto restore_enhance;
+
+       _D("clear tone and outdoor");
+       device_set_property(DEVICE_TYPE_DISPLAY,
+               PROP_DISPLAY_IMAGE_ENHANCE_TONE, 0);
+       device_set_property(DEVICE_TYPE_DISPLAY,
+               PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR, 0);
+
+restore_enhance:
+       _D("restore [%d:%d:%d:%d]",
+               entry->type[ENHANCE_MODE], entry->type[ENHANCE_SCENARIO],
+               entry->type[ENHANCE_TONE], entry->type[ENHANCE_OUTDOOR]);
+
+       device_set_property(DEVICE_TYPE_DISPLAY,
+               PROP_DISPLAY_IMAGE_ENHANCE_MODE,
+               entry->type[ENHANCE_MODE]);
+       device_set_property(DEVICE_TYPE_DISPLAY,
+               PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO,
+               entry->type[ENHANCE_SCENARIO]);
+       device_set_property(DEVICE_TYPE_DISPLAY,
+               PROP_DISPLAY_IMAGE_ENHANCE_TONE,
+               entry->type[ENHANCE_TONE]);
+       device_set_property(DEVICE_TYPE_DISPLAY,
+               PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR,
+               entry->type[ENHANCE_OUTDOOR]);
+}
+
+static int find_entry_from_enhance_ctl_list(int pid)
+{
+       Eina_List *n;
+       Eina_List *next;
+       struct enhance_entry_t* entry;
+       char exe_name[PATH_MAX];
+
+       EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
+               if (entry != NULL && entry->pid == pid && get_cmdline_name(entry->pid, exe_name, PATH_MAX) == 0) {
+                       _D("find enhance list");
+                       restore_enhance_status(entry);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static void remove_entry_from_enhance_ctl_list(int pid)
+{
+       Eina_List *n;
+       Eina_List *next;
+       struct enhance_entry_t *entry;
+       char exe_name[PATH_MAX];
+
+       if (pid <= 0)
+               return;
+
+       EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
+               if (entry != NULL &&
+                   (get_cmdline_name(entry->pid, exe_name, PATH_MAX) != 0 || (entry->pid == pid))) {
+                       _D("remove enhance list");
+                       enhance_ctl_list = eina_list_remove(enhance_ctl_list, entry);
+                       free(entry);
+               }
+       }
+}
+
+static int check_entry_to_enhance_ctl_list(int pid)
+{
+       int oom_score_adj;
+       if (pid <= 0)
+               return -EINVAL;
+
+       if (get_oom_score_adj(pid, &oom_score_adj) < 0) {
+               _E("fail to get adj value of pid: %d (%d)", pid);
+               return -EINVAL;
+       }
+
+       switch (oom_score_adj) {
+       case OOMADJ_FOREGRD_LOCKED:
+       case OOMADJ_FOREGRD_UNLOCKED:
+               if (!find_entry_from_enhance_ctl_list(pid))
+                       return -EINVAL;
+               return 0;
+       case OOMADJ_BACKGRD_LOCKED:
+       case OOMADJ_BACKGRD_UNLOCKED:
+               remove_entry_from_enhance_ctl_list(pid);
+               return -EINVAL;
+       case OOMADJ_SU:
+               if (check_default_process(pid, CLUSTER_HOME) != 0)
+                       return 0;
+               return -EINVAL;
+       default:
+               return 0;
+       }
+}
+
+static void update_enhance_status(struct enhance_entry_t *entry, int index)
+{
+       char exe_name[PATH_MAX];
+       int type;
+
+       if (index == ENHANCE_MODE)
+               type = PROP_DISPLAY_IMAGE_ENHANCE_MODE;
+       else if (index == ENHANCE_SCENARIO)
+               type = PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO;
+       else if (index == ENHANCE_TONE)
+               type = PROP_DISPLAY_IMAGE_ENHANCE_TONE;
+       else if (index == ENHANCE_OUTDOOR)
+               type = PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR;
+       else {
+               _E("abnormal type is inserted(%d)", index);
+               return;
+       }
+
+       _I("[ENHANCE(%d)] %d", index, entry->type[index]);
+       device_set_property(DEVICE_TYPE_DISPLAY, type, entry->type[index]);
+}
+
+static int change_default_enhance_status(int pid, int index, int val)
+{
+       Eina_List *n, *next;
+       struct enhance_entry_t *entry;
+       char exe_name[PATH_MAX];
+
+       if (check_default_process(pid, SETTING_NAME) != 0)
+               return -EINVAL;
+       default_enhance.pid = pid;
+       default_enhance.type[index] = val;
+       switch (index) {
+       case ENHANCE_MODE:
+               vconf_set_int(VCONFKEY_ENHANCE_MODE, val);
+               EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
+                       if (!entry)
+                               continue;
+                       entry->type[index] = default_enhance.type[index];
+               }
+               break;
+       case ENHANCE_SCENARIO:
+               vconf_set_int(VCONFKEY_ENHANCE_SCENARIO, val);
+               break;
+       case ENHANCE_TONE:
+               vconf_set_int(VCONFKEY_ENHANCE_TONE, val);
+               break;
+       case ENHANCE_OUTDOOR:
+               vconf_set_int(VCONFKEY_ENHANCE_OUTDOOR, val);
+               break;
+       default:
+               _E("input index is abnormal value");
+               return -EINVAL;
+       }
+       update_enhance_status(&default_enhance, index);
+       return 0;
+}
+
+static int add_entry_to_enhance_ctl_list(int pid, int index, int val)
+{
+       int find_node = 0;
+       Eina_List *n, *next;
+       struct enhance_entry_t *entry;
+       struct enhance_entry_t *entry_buf;
+       int oom_score_adj;
+
+       if (pid <= 0)
+               return -EINVAL;
+
+       EINA_LIST_FOREACH_SAFE(enhance_ctl_list, n, next, entry) {
+               if (entry != NULL && entry->pid == pid) {
+                       find_node = 1;
+                       break;
+               }
+       }
+
+       entry_buf = malloc(sizeof(struct enhance_entry_t));
+       if (!entry_buf) {
+               _E("Malloc failed");
+               return -EINVAL;
+       }
+
+       if (find_node) {
+               memcpy(entry_buf, entry, sizeof(struct enhance_entry_t));
+               entry_buf->type[index] = val;
+               remove_entry_from_enhance_ctl_list(pid);
+       } else {
+               memset(entry_buf, 0, sizeof(struct enhance_entry_t));
+               entry_buf->type[ENHANCE_MODE] = default_enhance.type[ENHANCE_MODE];
+               entry_buf->pid = pid;
+               entry_buf->type[index] = val;
+       }
+
+       enhance_ctl_list = eina_list_prepend(enhance_ctl_list, entry_buf);
+       if (!enhance_ctl_list) {
+               _E("eina_list_prepend failed");
+               return -EINVAL;
+       }
+
+       if (get_oom_score_adj(entry_buf->pid, &oom_score_adj) < 0) {
+               _E("fail to get adj value of pid: %d (%d)", pid);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static void enhance_control_pid_cb(keynode_t *in_key, struct main_data *ad)
+{
+       int pid;
+
+       if (vconf_get_int(VCONFKEY_ENHANCE_PID, &pid) != 0)
+               return;
+
+       if (check_entry_to_enhance_ctl_list(pid) == 0)
+               return;
+
+       restore_enhance_status(&default_enhance);
+}
+
+static void enhance_auto_control_cb(keynode_t *in_key, struct main_data *ad)
+{
+       int val;
+
+       if (vconf_get_bool(VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT, &val) != 0) {
+               _E("fail to get %s", VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT);
+               return;
+       }
+
+       _I("set auto adjust screen tone (%d)", val);
+       device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_AUTO_SCREEN_TONE, val);
+       device_set_property(DEVICE_TYPE_DISPLAY,
+               PROP_DISPLAY_IMAGE_ENHANCE_MODE,
+               default_enhance.type[ENHANCE_MODE]);
+}
+
+static void init_colorblind_status(void)
+{
+       struct color_blind_info info;
+       char *str, *it;
+       int val, cnt, cmd, ret, sum;
+       unsigned int color[9];
+
+       /* get the status if colorblind is ON or not */
+       if (vconf_get_bool(VCONFKEY_SETAPPL_COLORBLIND_STATUS_BOOL, &val) != 0)
+               return;
+
+       if (!val) {
+               _D("color blind status is FALSE");
+               return;
+       }
+
+       /* get the value of color blind */
+       str = vconf_get_str(VCONFKEY_SETAPPL_COLORBLIND_LAST_RGBCMY_STR);
+       if (!str)
+               return;
+
+       cnt = strlen(str)/4 - 1;
+       if (cnt != 8)
+               return;
+
+       /* token the color blind value string to integer */
+       sum = 0;
+       for (it = str+cnt*4; cnt >= 0 && it; --cnt, it -= 4) {
+               color[cnt] = strtol(it, NULL, 16);
+               sum += color[cnt];
+               *it = '\0';
+               _D("color[%d] : %d", cnt, color[cnt]);
+       }
+
+       /* ignore colorblind when all of value is invalid */
+       if (!sum)
+               return;
+
+       cnt = 0;
+       info.power = val;
+       info.RrCr = color[cnt++];
+       info.RgCg = color[cnt++];
+       info.RbCb = color[cnt++];
+       info.GrMr = color[cnt++];
+       info.GgMg = color[cnt++];
+       info.GbMb = color[cnt++];
+       info.BrYr = color[cnt++];
+       info.BgYg = color[cnt++];
+       info.BbYb = color[cnt++];
+
+       /* write to the kernel node */
+       cmd = DISP_CMD(PROP_DISPLAY_IMAGE_ENHANCE_COLOR_BLIND, DEFAULT_DISPLAY);
+       ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, (int)&info);
+       if (ret < 0)
+               _E("fail to set color blind value : %d", ret);
+}
+
+static void reset_default_enhance_status(struct enhance_entry_t *entry)
+{
+       _D("reset [%d:%d:%d:%d]",
+               entry->type[ENHANCE_MODE], entry->type[ENHANCE_SCENARIO],
+               entry->type[ENHANCE_TONE], entry->type[ENHANCE_OUTDOOR]);
+
+       device_set_property(DEVICE_TYPE_DISPLAY,
+               PROP_DISPLAY_IMAGE_ENHANCE_MODE,
+               entry->type[ENHANCE_MODE]);
+       device_set_property(DEVICE_TYPE_DISPLAY,
+               PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO,
+               entry->type[ENHANCE_SCENARIO]);
+       device_set_property(DEVICE_TYPE_DISPLAY,
+               PROP_DISPLAY_IMAGE_ENHANCE_TONE,
+               entry->type[ENHANCE_TONE]);
+       device_set_property(DEVICE_TYPE_DISPLAY,
+               PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR,
+               entry->type[ENHANCE_OUTDOOR]);
+}
+
+static void init_default_enhance_status(void)
+{
+       int val;
+
+       memset(&default_enhance, 0, sizeof(struct enhance_entry_t));
+
+       if (vconf_get_bool(VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT, &val) == 0) {
+               _I("set auto adjust screen tone (%d)", val);
+               device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_AUTO_SCREEN_TONE, val);
+       }
+
+       if (vconf_notify_key_changed(VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT,
+               (void *)enhance_auto_control_cb, NULL) < 0) {
+               _E("failed to set : KEY(%s)", VCONFKEY_SETAPPL_LCD_AUTO_DISPLAY_ADJUSTMENT);
+       }
+
+       if (vconf_get_int(VCONFKEY_ENHANCE_MODE, &val) == 0 && val >= 0) {
+               default_enhance.type[ENHANCE_MODE] = val;
+       }
+       if (vconf_get_int(VCONFKEY_ENHANCE_SCENARIO, &val) == 0 && val >= 0) {
+               default_enhance.type[ENHANCE_SCENARIO] = val;
+       }
+       if (vconf_get_int(VCONFKEY_ENHANCE_TONE, &val) == 0 && val >= 0) {
+               default_enhance.type[ENHANCE_TONE] = val;
+       }
+       if (vconf_get_int(VCONFKEY_ENHANCE_OUTDOOR, &val) == 0 && val >= 0) {
+               default_enhance.type[ENHANCE_OUTDOOR] = val;
+       }
+       reset_default_enhance_status(&default_enhance);
+}
+
+int changed_enhance_value(int pid, int prop, int val)
+{
+       int index;
+
+       index = prop - PROP_DISPLAY_IMAGE_ENHANCE_MODE;
+
+       if (change_default_enhance_status(pid, index, val) == 0)
+               return 0;
+       if (add_entry_to_enhance_ctl_list(pid, index, val) == 0)
+               return 0;
+
+       _E("fail to set enhance (p:%d,t:%d,v:%d)", pid, index, val);
+       return -EINVAL;
+}
+
+int set_enhance_pid(int pid)
+{
+       return vconf_set_int(VCONFKEY_ENHANCE_PID, pid);
+}
+
+static DBusMessage *edbus_getenhancesupported(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, val, ret;
+
+       cmd = DISP_CMD(PROP_DISPLAY_IMAGE_ENHANCE_INFO, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &val);
+       if (ret >= 0)
+               ret = val;
+
+       _I("get imange enhance supported %d, %d", val, ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_getimageenhance(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int type, prop, cmd, val, ret;
+
+       dbus_message_iter_init(msg, &iter);
+       dbus_message_iter_get_basic(&iter, &type);
+
+       _I("get image enhance type %d", type);
+
+       switch (type) {
+       case ENHANCE_MODE:
+               prop = PROP_DISPLAY_IMAGE_ENHANCE_MODE;
+               break;
+       case ENHANCE_SCENARIO:
+               prop = PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO;
+               break;
+       case ENHANCE_TONE:
+               prop = PROP_DISPLAY_IMAGE_ENHANCE_TONE;
+               break;
+       case ENHANCE_OUTDOOR:
+               prop = PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR;
+               break;
+       default:
+               ret = -EINVAL;
+               goto error;
+       }
+
+       cmd = DISP_CMD(prop, DEFAULT_DISPLAY);
+       ret = device_get_property(DEVICE_TYPE_DISPLAY, cmd, &val);
+       if (ret >= 0)
+               ret = val;
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_setimageenhance(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int type, prop, cmd, val, ret;
+       pid_t pid;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &type, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       _I("set image enhance type %d, %d", type, val);
+
+       switch (type) {
+       case ENHANCE_MODE:
+               prop = PROP_DISPLAY_IMAGE_ENHANCE_MODE;
+               break;
+       case ENHANCE_SCENARIO:
+               prop = PROP_DISPLAY_IMAGE_ENHANCE_SCENARIO;
+               break;
+       case ENHANCE_TONE:
+               prop = PROP_DISPLAY_IMAGE_ENHANCE_TONE;
+               break;
+       case ENHANCE_OUTDOOR:
+               prop = PROP_DISPLAY_IMAGE_ENHANCE_OUTDOOR;
+               break;
+       default:
+               ret = -EINVAL;
+               goto error;
+       }
+
+       cmd = DISP_CMD(prop, DEFAULT_DISPLAY);
+       ret = device_set_property(DEVICE_TYPE_DISPLAY, cmd, val);
+
+       /* notify to deviced with the purpose of stroing latest enhance value */
+       pid = get_edbus_sender_pid(msg);
+       changed_enhance_value(pid, prop, val);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_getenhancedtouch(E_DBus_Object *obj, DBusMessage *msg)
+{
+       int ret;
+       int val;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+
+       ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, &val);
+       if (ret < 0) {
+               val = -1;
+       }
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &val);
+       return reply;
+}
+
+static DBusMessage *edbus_setenhancedtouch(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, exval, ret;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (!val)
+               ret = device_set_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_KEY_GLOVE_MODE, val);
+       if (ret < 0)
+               _E("fail to off touch key glove mode");
+
+       ret = device_get_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, &exval);
+       if (ret < 0 || exval != val)
+               ret = device_set_property(DEVICE_TYPE_TOUCH, PROP_TOUCH_SCREEN_GLOVE_MODE, val);
+       if (ret < 0) {
+               _E("fail to set touch screen glove mode (%d)", val);
+               goto error;
+       }
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "getimageenhance",  "i",   "i", edbus_getimageenhance },      /* deprecated */
+       { "setimageenhance", "ii",   "i", edbus_setimageenhance },      /* deprecated */
+       { "GetEnhanceSupported", NULL, "i", edbus_getenhancesupported },
+       { "GetImageEnhance",  "i",   "i", edbus_getimageenhance },
+       { "SetImageEnhance", "ii",   "i", edbus_setimageenhance },
+       { "GetEnhancedTouch",    NULL,   "i", edbus_getenhancedtouch },
+       { "SetEnhancedTouch",     "i",   "i", edbus_setenhancedtouch },
+};
+
+static void enhance_init(void *data)
+{
+       int ret;
+
+       ret = register_edbus_method(DEVICED_PATH_DISPLAY,
+                   edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("Failed to register edbus method! %d", ret);
+
+       if (vconf_notify_key_changed(VCONFKEY_ENHANCE_PID,
+               (void *)enhance_control_pid_cb, NULL) < 0) {
+               _E("failed to set : KEY(%s)", VCONFKEY_ENHANCE_PID);
+       }
+
+       init_default_enhance_status();
+       init_colorblind_status();
+}
+
+static const struct device_ops enhance_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "enhance",
+       .init     = enhance_init,
+};
+
+DEVICE_OPS_REGISTER(&enhance_device_ops)
diff --git a/src/display/enhance.h b/src/display/enhance.h
new file mode 100644 (file)
index 0000000..a274cc9
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2000 - 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 __LCD_HANDLER_H__
+#define __LCD_HANDLER_H__
+
+int changed_enhance_value(int pid, int prop, int val);
+
+#ifdef MICRO_DD
+static inline int set_enhance_pid(int pid) {return 0;}
+#else
+int set_enhance_pid(int pid);
+#endif
+
+#endif /* __LCD_HANDLER_H__ */
diff --git a/src/display/hbm.c b/src/display/hbm.c
new file mode 100644 (file)
index 0000000..2251acc
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * 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 <stdbool.h>
+#include <fcntl.h>
+#include <Ecore.h>
+
+#include "util.h"
+#include "core.h"
+#include "display-ops.h"
+#include "core/common.h"
+#include "core/device-notifier.h"
+#include "core/edbus-handler.h"
+
+#define ON             "on"
+#define OFF            "off"
+
+#define SIGNAL_HBM_OFF "HBMOff"
+
+#define DEFAULT_BRIGHTNESS_LEVEL       80
+
+static Ecore_Timer *timer = NULL;
+static struct timespec offtime;
+static char *hbm_path;
+
+static void broadcast_hbm_off(void)
+{
+       broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+           SIGNAL_HBM_OFF, NULL, NULL);
+}
+
+static void hbm_set_offtime(int timeout)
+{
+       struct timespec now;
+
+       if (timeout <= 0) {
+               offtime.tv_sec = 0;
+               return;
+       }
+
+       clock_gettime(CLOCK_REALTIME, &now);
+       offtime.tv_sec = now.tv_sec + timeout;
+}
+
+static Eina_Bool hbm_off_cb(void *data)
+{
+       int ret;
+
+       timer = NULL;
+
+       if (pm_cur_state != S_NORMAL) {
+               _D("hbm timeout! but it's not lcd normal");
+               return EINA_FALSE;
+       }
+       hbm_set_offtime(0);
+
+       ret = sys_set_str(hbm_path, OFF);
+       if (ret < 0)
+               _E("Failed to off hbm");
+
+       vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS,
+           DEFAULT_BRIGHTNESS_LEVEL);
+       backlight_ops.set_default_brt(DEFAULT_BRIGHTNESS_LEVEL);
+       backlight_ops.update();
+       broadcast_hbm_off();
+
+       return EINA_FALSE;
+}
+
+static void hbm_start_timer(int timeout)
+{
+       if (timer) {
+               ecore_timer_del(timer);
+               timer = NULL;
+       }
+       if (!timer) {
+               timer = ecore_timer_add(timeout,
+                   hbm_off_cb, NULL);
+       }
+}
+
+static void hbm_end_timer(void)
+{
+       if (timer) {
+               ecore_timer_del(timer);
+               timer = NULL;
+       }
+}
+
+int hbm_get_state(void)
+{
+       char state[4];
+       int ret, hbm;
+
+       if (!hbm_path)
+               return -ENODEV;
+
+       ret = sys_get_str(hbm_path, state);
+       if (ret < 0)
+               return ret;
+
+       if (!strncmp(state, ON, strlen(ON)))
+               hbm = true;
+       else if (!strncmp(state, OFF, strlen(OFF)))
+               hbm = false;
+       else
+               hbm = -EINVAL;
+
+       return hbm;
+}
+
+int hbm_set_state(int hbm)
+{
+       if (!hbm_path)
+               return -ENODEV;
+
+       return sys_set_str(hbm_path, (hbm ? ON : OFF));
+}
+
+int hbm_set_state_with_timeout(int hbm, int timeout)
+{
+       int ret;
+
+       if (hbm && (timeout <= 0))
+               return -EINVAL;
+
+       ret = hbm_set_state(hbm);
+       if (ret < 0)
+               return ret;
+
+       _D("timeout is %d", timeout);
+
+       if (hbm) {
+               /*
+                * hbm is turned off after timeout.
+                */
+               hbm_set_offtime(timeout);
+               hbm_start_timer(timeout);
+       } else {
+               hbm_set_offtime(0);
+               hbm_end_timer();
+               broadcast_hbm_off();
+       }
+
+       return 0;
+}
+
+void hbm_check_timeout(void)
+{
+       struct timespec now;
+       int ret;
+
+       if (timer) {
+               ecore_timer_del(timer);
+               timer = NULL;
+       }
+
+       if (offtime.tv_sec == 0) {
+               if (hbm_get_state() == true) {
+                       _E("It's invalid state. hbm is off");
+                       hbm_set_state(false);
+               }
+               return;
+       }
+
+       clock_gettime(CLOCK_REALTIME, &now);
+       _D("now %d, offtime %d", now.tv_sec, offtime.tv_sec);
+
+       /* check it's timeout */
+       if (now.tv_sec >= offtime.tv_sec) {
+               hbm_set_offtime(0);
+
+               ret = sys_set_str(hbm_path, OFF);
+               if (ret < 0)
+                       _E("Failed to off hbm");
+               vconf_set_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS,
+                   DEFAULT_BRIGHTNESS_LEVEL);
+               backlight_ops.set_default_brt(DEFAULT_BRIGHTNESS_LEVEL);
+               backlight_ops.update();
+               broadcast_hbm_off();
+       } else {
+               _D("hbm state is restored!");
+               hbm_set_state(true);
+               hbm_start_timer(offtime.tv_sec - now.tv_sec);
+       }
+}
+
+static int lcd_state_changed(void *data)
+{
+       int state = (int)data;
+       int ret;
+
+       switch (state) {
+       case S_NORMAL:
+               /* restore hbm when old state is dim */
+               if (pm_old_state == S_LCDDIM)
+                       hbm_check_timeout();
+               break;
+       case S_LCDDIM:
+               if (hbm_get_state() == true) {
+                       ret = hbm_set_state(false);
+                       if (ret < 0)
+                               _E("Failed to off hbm!");
+               }
+               /* fall through */
+       case S_LCDOFF:
+       case S_SLEEP:
+               hbm_end_timer();
+               break;
+       }
+
+       return 0;
+}
+
+static void hbm_init(void *data)
+{
+       int fd, ret;
+
+       hbm_path = getenv("HBM_NODE");
+
+       /* Check HBM node is valid */
+       fd = open(hbm_path, O_RDONLY);
+       if (fd < 0) {
+               hbm_path = NULL;
+               return;
+       }
+       close(fd);
+
+       /* register notifier */
+       register_notifier(DEVICE_NOTIFIER_LCD, lcd_state_changed);
+}
+
+static void hbm_exit(void *data)
+{
+       /* unregister notifier */
+       unregister_notifier(DEVICE_NOTIFIER_LCD, lcd_state_changed);
+}
+
+static const struct display_ops display_hbm_ops = {
+       .name     = "hbm",
+       .init     = hbm_init,
+       .exit     = hbm_exit,
+};
+
+DISPLAY_OPS_REGISTER(&display_hbm_ops)
+
diff --git a/src/display/key-filter-micro.c b/src/display/key-filter-micro.c
new file mode 100644 (file)
index 0000000..731e9e6
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * 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 <stdlib.h>
+#include <stdbool.h>
+
+#include <vconf.h>
+#include <Ecore.h>
+
+#include "util.h"
+#include "core.h"
+#include "poll.h"
+#include "brightness.h"
+#include "device-node.h"
+#include "core/queue.h"
+#include "core/common.h"
+#include "core/data.h"
+#include "core/device-notifier.h"
+#include "core/edbus-handler.h"
+#include "core/device-handler.h"
+
+#include <linux/input.h>
+
+#define POWEROFF_ACT                   "poweroff"
+
+#define KEY_RELEASED           0
+#define KEY_PRESSED            1
+
+#define NORMAL_POWER(val)              (val == 0)
+#define KEY_TEST_MODE_POWER(val)       (val == 2)
+
+#define SIGNAL_LCDON_BY_POWERKEY "LCDOnByPowerkey"
+
+static Ecore_Timer *longkey_timeout_id;
+static bool ignore_powerkey = false;
+
+static inline int current_state_in_on(void)
+{
+       return (pm_cur_state == S_LCDDIM || pm_cur_state == S_NORMAL);
+}
+
+static void longkey_pressed()
+{
+       int val, ret;
+
+       _I("Power key long pressed!");
+
+       ret = vconf_get_int(VCONFKEY_TESTMODE_POWER_OFF_POPUP, &val);
+       if (ret < 0)
+               return;
+
+       if (NORMAL_POWER(val) || KEY_TEST_MODE_POWER(val))
+               return;
+
+       /*
+        * Poweroff-popup has been launched by app.
+        * deviced only turns off the phone by power key
+        * when power-off popup is disabled for testmode.
+        */
+       _I("power off action!");
+       notify_action(POWEROFF_ACT, 0);
+}
+
+static Eina_Bool longkey_pressed_cb(void *data)
+{
+       longkey_pressed();
+       longkey_timeout_id = NULL;
+
+       return EINA_FALSE;
+}
+
+static inline void check_key_pair(int code, int new, int *old)
+{
+       if (new == *old)
+               _E("key pair is not matched! (%d, %d)", code, new);
+       else
+               *old = new;
+}
+
+static inline void broadcast_lcdon_by_powerkey(void)
+{
+       broadcast_edbus_signal(DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+           SIGNAL_LCDON_BY_POWERKEY, NULL, NULL);
+}
+
+static inline bool switch_on_lcd(void)
+{
+       if (current_state_in_on())
+               return false;
+
+       if (backlight_ops.get_lcd_power() == PM_LCD_POWER_ON)
+               return false;
+
+       broadcast_lcdon_by_powerkey();
+
+       lcd_on_direct();
+
+       return true;
+}
+
+static inline void switch_off_lcd(void)
+{
+       if (!current_state_in_on())
+               return;
+
+       if (backlight_ops.get_lcd_power() == PM_LCD_POWER_OFF)
+               return;
+
+       lcd_off_procedure();
+}
+
+static int process_power_key(struct input_event *pinput)
+{
+       int ignore = true;
+       static int value = KEY_RELEASED;
+
+       switch (pinput->value) {
+       case KEY_RELEASED:
+               check_key_pair(pinput->code, pinput->value, &value);
+               ignore = false;
+
+               if (longkey_timeout_id > 0) {
+                       ecore_timer_del(longkey_timeout_id);
+                       longkey_timeout_id = NULL;
+               }
+               break;
+       case KEY_PRESSED:
+               switch_on_lcd();
+               check_key_pair(pinput->code, pinput->value, &value);
+               _I("power key pressed");
+
+               /* add long key timer */
+               longkey_timeout_id = ecore_timer_add(
+                           display_conf.longpress_interval,
+                           longkey_pressed_cb, NULL);
+               ignore = false;
+               break;
+       }
+       return ignore;
+}
+
+static int check_key(struct input_event *pinput, int fd)
+{
+       int ignore = true;
+
+       switch (pinput->code) {
+       case KEY_POWER:
+               ignore = process_power_key(pinput);
+               break;
+       case KEY_PHONE: /* Flick up key */
+       case KEY_BACK: /* Flick down key */
+       case KEY_VOLUMEUP:
+       case KEY_VOLUMEDOWN:
+       case KEY_CAMERA:
+       case KEY_EXIT:
+       case KEY_CONFIG:
+       case KEY_MEDIA:
+       case KEY_MUTE:
+       case KEY_PLAYPAUSE:
+       case KEY_PLAYCD:
+       case KEY_PAUSECD:
+       case KEY_STOPCD:
+       case KEY_NEXTSONG:
+       case KEY_PREVIOUSSONG:
+       case KEY_REWIND:
+       case KEY_FASTFORWARD:
+               /* These case do not turn on the lcd */
+               if (current_state_in_on())
+                       ignore = false;
+               break;
+       default:
+               ignore = false;
+       }
+#ifdef ENABLE_PM_LOG
+       if (pinput->value == KEY_PRESSED)
+               pm_history_save(PM_LOG_KEY_PRESS, pinput->code);
+       else if (pinput->value == KEY_RELEASED)
+               pm_history_save(PM_LOG_KEY_RELEASE, pinput->code);
+#endif
+       return ignore;
+}
+
+static int check_key_filter(int length, char buf[], int fd)
+{
+       struct input_event *pinput;
+       int ignore = true;
+       int idx = 0;
+       static int old_fd, code, value;
+
+       do {
+               pinput = (struct input_event *)&buf[idx];
+               switch (pinput->type) {
+               case EV_KEY:
+                       if (pinput->code == code && pinput->value == value) {
+                               _E("Same key(%d, %d) is polled [%d,%d]",
+                                   code, value, old_fd, fd);
+                       }
+                       old_fd = fd;
+                       code = pinput->code;
+                       value = pinput->value;
+
+                       ignore = check_key(pinput, fd);
+                       break;
+               case EV_REL:
+                       ignore = false;
+                       break;
+               case EV_ABS:
+                       if (current_state_in_on())
+                               ignore = false;
+                       else if (display_conf.alpm_on == true) {
+                               switch_on_lcd();
+                               ignore = false;
+                       }
+                       if (pm_cur_state == S_LCDDIM &&
+                           backlight_ops.get_custom_status())
+                               backlight_ops.custom_update();
+
+                       break;
+               }
+               idx += sizeof(struct input_event);
+               if (ignore == true && length <= idx)
+                       return 1;
+       } while (length > idx);
+
+       return 0;
+}
+
+static void set_powerkey_ignore(int on)
+{
+       _D("ignore powerkey %d", on);
+       ignore_powerkey = on;
+}
+
+static int powerkey_lcdoff(void)
+{
+       /* Remove non est processes */
+       check_processes(S_LCDOFF);
+       check_processes(S_LCDDIM);
+
+       /* check holdkey block flag in lock node */
+       if (check_holdkey_block(S_LCDOFF) ||
+           check_holdkey_block(S_LCDDIM)) {
+               return -ECANCELED;
+       }
+
+       _I("power key lcdoff");
+       switch_off_lcd();
+       delete_condition(S_LCDOFF);
+       delete_condition(S_LCDDIM);
+       update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_POWERKEY);
+       recv_data.pid = -1;
+       recv_data.cond = 0x400;
+       (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data);
+
+       return 0;
+}
+
+static const struct display_keyfilter_ops micro_keyfilter_ops = {
+       .init                   = NULL,
+       .exit                   = NULL,
+       .check                  = check_key_filter,
+       .set_powerkey_ignore    = set_powerkey_ignore,
+       .powerkey_lcdoff        = powerkey_lcdoff,
+       .backlight_enable       = NULL,
+};
+const struct display_keyfilter_ops *keyfilter_ops = &micro_keyfilter_ops;
+
diff --git a/src/display/key-filter.c b/src/display/key-filter.c
new file mode 100644 (file)
index 0000000..acb6192
--- /dev/null
@@ -0,0 +1,828 @@
+/*
+ * 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 <stdlib.h>
+#include <stdbool.h>
+
+#include <vconf.h>
+#include <Ecore.h>
+
+#include "util.h"
+#include "core.h"
+#include "poll.h"
+#include "brightness.h"
+#include "device-node.h"
+#include "core/queue.h"
+#include "core/common.h"
+#include "core/data.h"
+#include "core/device-notifier.h"
+#include "core/edbus-handler.h"
+#include "core/device-handler.h"
+
+#include <linux/input.h>
+#ifndef KEY_SCREENLOCK
+#define KEY_SCREENLOCK         0x98
+#endif
+#ifndef SW_GLOVE
+#define SW_GLOVE               0x16
+#endif
+
+#define PREDEF_LEAVESLEEP      "leavesleep"
+#define POWEROFF_ACT                   "poweroff"
+#define PWROFF_POPUP_ACT               "pwroff-popup"
+#define USEC_PER_SEC                   1000000
+#define COMBINATION_INTERVAL           0.5     /* 0.5 second */
+#define KEYBACKLIGHT_TIME_90           90      /* 1.5 second */
+#define KEYBACKLIGHT_TIME_360          360     /* 6 second */
+#define KEYBACKLIGHT_TIME_ALWAYS_ON            -1      /* always on */
+#define KEYBACKLIGHT_TIME_ALWAYS_OFF   0       /* always off */
+#define KEYBACKLIGHT_BASE_TIME         60      /* 1min = 60sec */
+#define KEYBACKLIGHT_PRESSED_TIME      15      /*  15 second */
+#define KEY_MAX_DELAY_TIME             700     /* ms */
+
+#define KEY_RELEASED           0
+#define KEY_PRESSED            1
+#define KEY_BEING_PRESSED      2
+
+#define KEY_COMBINATION_STOP           0
+#define KEY_COMBINATION_START          1
+#define KEY_COMBINATION_SCREENCAPTURE  2
+
+#define SIGNAL_CHANGE_HARDKEY          "ChangeHardkey"
+
+#define NORMAL_POWER(val)              (val == 0)
+#define KEY_TEST_MODE_POWER(val)       (val == 2)
+
+#define TOUCH_RELEASE          (-1)
+
+#ifndef VCONFKEY_SETAPPL_TOUCHKEY_LIGHT_DURATION
+#define VCONFKEY_SETAPPL_TOUCHKEY_LIGHT_DURATION VCONFKEY_SETAPPL_PREFIX"/display/touchkey_light_duration"
+#endif
+
+#define GLOVE_MODE     1
+
+int __WEAK__ get_glove_state(void);
+void __WEAK__ switch_glove_key(int val);
+
+static struct timeval pressed_time;
+static Ecore_Timer *longkey_timeout_id = NULL;
+static Ecore_Timer *combination_timeout_id = NULL;
+static Ecore_Timer *hardkey_timeout_id = NULL;
+static int cancel_lcdoff;
+static int key_combination = KEY_COMBINATION_STOP;
+static int volumedown_pressed = false;
+static int hardkey_duration;
+static bool touch_pressed = false;
+static int skip_lcd_off = false;
+static bool powerkey_pressed = false;
+
+static inline int current_state_in_on(void)
+{
+       return (pm_cur_state == S_LCDDIM || pm_cur_state == S_NORMAL);
+}
+
+static inline void restore_custom_brightness(void)
+{
+       if (pm_cur_state == S_LCDDIM &&
+           backlight_ops.get_custom_status())
+               backlight_ops.custom_update();
+}
+
+static void longkey_pressed()
+{
+       int val = 0;
+       int ret;
+       int csc_mode;
+       char *opt;
+       _I("Power key long pressed!");
+       cancel_lcdoff = 1;
+
+       /* change state - LCD on */
+       recv_data.pid = -1;
+       recv_data.cond = 0x100;
+       (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data);
+
+       (*g_pm_callback) (INPUT_POLL_EVENT, NULL);
+
+       ret = vconf_get_int(VCONFKEY_TESTMODE_POWER_OFF_POPUP, &val);
+       if (ret != 0 || NORMAL_POWER(val)) {
+               ret = vconf_get_int(VCONFKEY_CSC_CONFIG_MODE_RUNNING,
+                       &csc_mode);
+               if (ret >= 0 && csc_mode) {
+                       _I("csc config mode! No poweroff-popup!");
+                       return;
+               }
+               opt = PWROFF_POPUP_ACT;
+               goto entry_call;
+       }
+       if (KEY_TEST_MODE_POWER(val)) {
+               _I("skip power off control during factory key test mode");
+               return;
+       }
+       opt = POWEROFF_ACT;
+entry_call:
+       notify_action(opt, 0);
+}
+
+static Eina_Bool longkey_pressed_cb(void *data)
+{
+       longkey_pressed();
+       longkey_timeout_id = NULL;
+
+       return EINA_FALSE;
+}
+
+static Eina_Bool combination_failed_cb(void *data)
+{
+       key_combination = KEY_COMBINATION_STOP;
+       combination_timeout_id = NULL;
+
+       return EINA_FALSE;
+}
+
+static unsigned long timediff_usec(struct timeval t1, struct timeval t2)
+{
+       unsigned long udiff;
+
+       udiff = (t2.tv_sec - t1.tv_sec) * USEC_PER_SEC;
+       udiff += (t2.tv_usec - t1.tv_usec);
+
+       return udiff;
+}
+
+static void stop_key_combination(void)
+{
+       key_combination = KEY_COMBINATION_STOP;
+       if (combination_timeout_id > 0) {
+               g_source_remove(combination_timeout_id);
+               combination_timeout_id = NULL;
+       }
+}
+
+static inline void check_key_pair(int code, int new, int *old)
+{
+       if (new == *old)
+               _E("key pair is not matched! (%d, %d)", code, new);
+       else
+               *old = new;
+}
+
+static inline bool switch_on_lcd(void)
+{
+       if (current_state_in_on())
+               return false;
+
+       if (backlight_ops.get_lcd_power() == PM_LCD_POWER_ON)
+               return false;
+
+       lcd_on_direct();
+
+       return true;
+}
+
+static inline void switch_off_lcd(void)
+{
+       if (!current_state_in_on())
+               return;
+
+       if (backlight_ops.get_lcd_power() == PM_LCD_POWER_OFF)
+               return;
+
+       lcd_off_procedure();
+}
+
+static int process_menu_key(struct input_event *pinput)
+{
+       if (pinput->value == KEY_PRESSED)
+               switch_on_lcd();
+
+       stop_key_combination();
+
+       return false;
+}
+
+static int decide_lcdoff(void)
+{
+       /* It's not needed if it's already LCD off state */
+       if (!current_state_in_on() &&
+           backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
+               return false;
+
+       /*
+        * This flag is set at the moment
+        * that LCD is turned on by power key
+        * LCD has not to turned off in the situation.
+        */
+       if (skip_lcd_off)
+               return false;
+
+       /* LCD is not turned off when powerkey is pressed,not released */
+       if (powerkey_pressed)
+               return false;
+
+       /* LCD-off is blocked at the moment poweroff popup shows */
+       if (cancel_lcdoff)
+               return false;
+
+       /* LCD-off is blocked at the moment volumedown key is pressed */
+       if (volumedown_pressed)
+               return false;
+
+       /* LCD-off is blocked when powerkey and volmedown key are pressed */
+       if (key_combination == KEY_COMBINATION_SCREENCAPTURE)
+               return false;
+
+       return true;
+}
+
+static int lcdoff_powerkey(void)
+{
+       int ignore = true;
+
+       if (decide_lcdoff() == true) {
+               check_processes(S_LCDOFF);
+               check_processes(S_LCDDIM);
+
+               if (!check_holdkey_block(S_LCDOFF) &&
+                   !check_holdkey_block(S_LCDDIM)) {
+                       if (display_info.update_auto_brightness)
+                               display_info.update_auto_brightness(false);
+                       switch_off_lcd();
+                       delete_condition(S_LCDOFF);
+                       delete_condition(S_LCDDIM);
+                       update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_POWERKEY);
+                       recv_data.pid = -1;
+                       recv_data.cond = 0x400;
+                       (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data);
+               }
+       } else {
+               ignore = false;
+       }
+       cancel_lcdoff = 0;
+
+       return ignore;
+}
+
+static int process_power_key(struct input_event *pinput)
+{
+       int ignore = true;
+       static int value = KEY_RELEASED;
+
+       switch (pinput->value) {
+       case KEY_RELEASED:
+               powerkey_pressed = false;
+               check_key_pair(pinput->code, pinput->value, &value);
+
+               if (!display_conf.powerkey_doublepress) {
+                       ignore = lcdoff_powerkey();
+               } else if (skip_lcd_off) {
+                       ignore = false;
+               }
+
+               stop_key_combination();
+               if (longkey_timeout_id > 0) {
+                       ecore_timer_del(longkey_timeout_id);
+                       longkey_timeout_id = NULL;
+               }
+
+               break;
+       case KEY_PRESSED:
+               powerkey_pressed = true;
+               skip_lcd_off = switch_on_lcd();
+               check_key_pair(pinput->code, pinput->value, &value);
+               _I("power key pressed");
+               pressed_time.tv_sec = (pinput->time).tv_sec;
+               pressed_time.tv_usec = (pinput->time).tv_usec;
+               if (key_combination == KEY_COMBINATION_STOP) {
+                       /* add long key timer */
+                       longkey_timeout_id = ecore_timer_add(
+                                   display_conf.longpress_interval,
+                                   (Ecore_Task_Cb)longkey_pressed_cb, NULL);
+                       key_combination = KEY_COMBINATION_START;
+                       combination_timeout_id = ecore_timer_add(
+                                   COMBINATION_INTERVAL,
+                                   (Ecore_Task_Cb)combination_failed_cb, NULL);
+               } else if (key_combination == KEY_COMBINATION_START) {
+                       if (combination_timeout_id > 0) {
+                               ecore_timer_del(combination_timeout_id);
+                               combination_timeout_id = NULL;
+                       }
+                       _I("capture mode");
+                       key_combination = KEY_COMBINATION_SCREENCAPTURE;
+                       skip_lcd_off = true;
+                       ignore = false;
+               }
+               if (skip_lcd_off)
+                       ignore = false;
+               cancel_lcdoff = 0;
+
+               break;
+       case KEY_BEING_PRESSED:
+               if (timediff_usec(pressed_time, pinput->time) >
+                   (display_conf.longpress_interval * USEC_PER_SEC))
+                       longkey_pressed();
+               break;
+       }
+       return ignore;
+}
+
+static int process_volumedown_key(struct input_event *pinput)
+{
+       int ignore = true;
+
+       if (pinput->value == KEY_PRESSED) {
+               if (key_combination == KEY_COMBINATION_STOP) {
+                       key_combination = KEY_COMBINATION_START;
+                       combination_timeout_id = ecore_timer_add(
+                                   COMBINATION_INTERVAL,
+                                   (Ecore_Task_Cb)combination_failed_cb, NULL);
+               } else if (key_combination == KEY_COMBINATION_START) {
+                       if (combination_timeout_id > 0) {
+                               ecore_timer_del(combination_timeout_id);
+                               combination_timeout_id = NULL;
+                       }
+                       if (longkey_timeout_id > 0) {
+                               ecore_timer_del(longkey_timeout_id);
+                               longkey_timeout_id = NULL;
+                       }
+                       _I("capture mode");
+                       key_combination = KEY_COMBINATION_SCREENCAPTURE;
+                       skip_lcd_off = true;
+                       ignore = false;
+               }
+               volumedown_pressed = true;
+       } else if (pinput->value == KEY_RELEASED) {
+               if (key_combination != KEY_COMBINATION_SCREENCAPTURE) {
+                       stop_key_combination();
+                       if (current_state_in_on())
+                               ignore = false;
+               }
+               volumedown_pressed = false;
+       }
+
+       return ignore;
+}
+
+static int process_brightness_key(struct input_event *pinput, int action)
+{
+       if (pinput->value == KEY_RELEASED) {
+               stop_key_combination();
+               return true;
+       }
+
+       if (get_lock_screen_state() == VCONFKEY_IDLE_LOCK)
+               return false;
+
+       /* check weak function symbol */
+       if (!control_brightness_key)
+               return true;
+
+       return control_brightness_key(action);
+}
+
+static int process_screenlock_key(struct input_event *pinput)
+{
+       if (pinput->value != KEY_RELEASED) {
+               stop_key_combination();
+               return true;
+       }
+
+       if (!current_state_in_on())
+               return false;
+
+       check_processes(S_LCDOFF);
+       check_processes(S_LCDDIM);
+
+       if (!check_holdkey_block(S_LCDOFF) && !check_holdkey_block(S_LCDDIM)) {
+               delete_condition(S_LCDOFF);
+               delete_condition(S_LCDDIM);
+               update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_POWERKEY);
+
+               /* LCD off forcly */
+               recv_data.pid = -1;
+               recv_data.cond = 0x400;
+               (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data);
+       }
+
+       return true;
+}
+
+static void turnon_hardkey_backlight(void)
+{
+       int val, ret;
+
+       ret = device_get_property(DEVICE_TYPE_LED, PROP_LED_HARDKEY, &val);
+       if (ret < 0 || !val) {
+               /* key backlight on */
+               ret = device_set_property(DEVICE_TYPE_LED,
+                   PROP_LED_HARDKEY, STATUS_ON);
+               if (ret < 0)
+                       _E("Fail to turn off key backlight!");
+       }
+}
+
+static void turnoff_hardkey_backlight(void)
+{
+       int val, ret;
+
+       ret = device_get_property(DEVICE_TYPE_LED, PROP_LED_HARDKEY, &val);
+       /* check key backlight is already off */
+       if (!ret && !val)
+               return;
+
+       /* key backlight off */
+       ret = device_set_property(DEVICE_TYPE_LED, PROP_LED_HARDKEY, STATUS_OFF);
+       if (ret < 0)
+               _E("Fail to turn off key backlight!");
+}
+
+static Eina_Bool key_backlight_expired(void *data)
+{
+       hardkey_timeout_id = NULL;
+
+       turnoff_hardkey_backlight();
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+static void sound_vibrate_hardkey(void)
+{
+       /* device notify(vibrator) */
+       device_notify(DEVICE_NOTIFIER_TOUCH_HARDKEY, NULL);
+       /* sound(dbus) */
+       broadcast_edbus_signal(DEVICED_PATH_KEY, DEVICED_INTERFACE_KEY,
+                       SIGNAL_CHANGE_HARDKEY, NULL, NULL);
+}
+
+static void process_hardkey_backlight(struct input_event *pinput)
+{
+       float fduration;
+
+       if (pinput->value == KEY_PRESSED) {
+               if (touch_pressed) {
+                       _I("Touch is pressed, then hard key is not working!");
+                       return;
+               }
+               /* Sound & Vibrate only in unlock state */
+               if (get_lock_screen_state() == VCONFKEY_IDLE_UNLOCK
+                   || get_lock_screen_bg_state())
+                       sound_vibrate_hardkey();
+               /* release existing timer */
+               if (hardkey_timeout_id > 0) {
+                       ecore_timer_del(hardkey_timeout_id);
+                       hardkey_timeout_id = NULL;
+               }
+               /* if hardkey option is always off */
+               if (hardkey_duration == KEYBACKLIGHT_TIME_ALWAYS_OFF)
+                       return;
+               /* turn on hardkey backlight */
+               turnon_hardkey_backlight();
+               /* start timer */
+               hardkey_timeout_id = ecore_timer_add(
+                           KEYBACKLIGHT_PRESSED_TIME,
+                           key_backlight_expired, NULL);
+
+       } else if (pinput->value == KEY_RELEASED) {
+               /* if lockscreen is idle lock */
+               if (get_lock_screen_state() == VCONFKEY_IDLE_LOCK) {
+                       _D("Lock state, key backlight is off when phone is unlocked!");
+                       return;
+               }
+               /* release existing timer */
+               if (hardkey_timeout_id > 0) {
+                       ecore_timer_del(hardkey_timeout_id);
+                       hardkey_timeout_id = NULL;
+               }
+               /* if hardkey option is always on or off */
+               if (hardkey_duration == KEYBACKLIGHT_TIME_ALWAYS_ON ||
+                       hardkey_duration == KEYBACKLIGHT_TIME_ALWAYS_OFF)
+                       return;
+               /* start timer */
+               fduration = (float)hardkey_duration / KEYBACKLIGHT_BASE_TIME;
+               hardkey_timeout_id = ecore_timer_add(
+                           fduration,
+                           key_backlight_expired, NULL);
+       }
+}
+
+static int check_key(struct input_event *pinput, int fd)
+{
+       int ignore = true;
+
+       switch (pinput->code) {
+       case KEY_MENU:
+               ignore = process_menu_key(pinput);
+               break;
+       case KEY_POWER:
+               ignore = process_power_key(pinput);
+               break;
+       case KEY_VOLUMEDOWN:
+               ignore = process_volumedown_key(pinput);
+               break;
+       case KEY_BRIGHTNESSDOWN:
+               ignore = process_brightness_key(pinput, BRIGHTNESS_DOWN);
+               break;
+       case KEY_BRIGHTNESSUP:
+               ignore = process_brightness_key(pinput, BRIGHTNESS_UP);
+               break;
+       case KEY_SCREENLOCK:
+               ignore = process_screenlock_key(pinput);
+               break;
+       case KEY_BACK:
+       case KEY_PHONE:
+               stop_key_combination();
+               if (current_state_in_on()) {
+                       process_hardkey_backlight(pinput);
+                       ignore = false;
+               } else if (!check_pre_install(fd)) {
+                       ignore = false;
+               }
+               break;
+       case KEY_VOLUMEUP:
+       case KEY_CAMERA:
+       case KEY_EXIT:
+       case KEY_CONFIG:
+       case KEY_MEDIA:
+       case KEY_MUTE:
+       case KEY_PLAYPAUSE:
+       case KEY_PLAYCD:
+       case KEY_PAUSECD:
+       case KEY_STOPCD:
+       case KEY_NEXTSONG:
+       case KEY_PREVIOUSSONG:
+       case KEY_REWIND:
+       case KEY_FASTFORWARD:
+               stop_key_combination();
+               if (current_state_in_on())
+                       ignore = false;
+               break;
+       case 0x1DB:
+       case 0x1DC:
+       case 0x1DD:
+       case 0x1DE:
+               stop_key_combination();
+               break;
+       default:
+               stop_key_combination();
+               ignore = false;
+       }
+#ifdef ENABLE_PM_LOG
+       if (pinput->value == KEY_PRESSED)
+               pm_history_save(PM_LOG_KEY_PRESS, pinput->code);
+       else if (pinput->value == KEY_RELEASED)
+               pm_history_save(PM_LOG_KEY_RELEASE, pinput->code);
+#endif
+       return ignore;
+}
+
+static inline int check_powerkey_delay(struct input_event *pinput)
+{
+       struct timespec tp;
+       int delay;
+
+       if (pinput->code != KEY_POWER ||
+           pinput->value != KEY_PRESSED)
+               return false;
+
+       if (backlight_ops.get_lcd_power() != PM_LCD_POWER_ON)
+               return false;
+
+       clock_gettime(CLOCK_MONOTONIC, &tp);
+
+       delay = SEC_TO_MSEC(tp.tv_sec) +
+           NSEC_TO_MSEC(tp.tv_nsec) -
+           (SEC_TO_MSEC((pinput->time).tv_sec) +
+           USEC_TO_MSEC((pinput->time).tv_usec));
+
+       if (delay < KEY_MAX_DELAY_TIME)
+               return false;
+
+       return true;
+}
+
+static int check_key_filter(int length, char buf[], int fd)
+{
+       struct input_event *pinput;
+       int ignore = true;
+       int idx = 0;
+       static int old_fd, code, value;
+
+       do {
+               pinput = (struct input_event *)&buf[idx];
+               switch (pinput->type) {
+               case EV_KEY:
+                       if (pinput->code == BTN_TOUCH &&
+                           pinput->value == KEY_RELEASED)
+                               touch_pressed = false;
+                       /*
+                        * The later inputs are going to be ignored when
+                        * powerkey is pressed several times for a short time
+                        */
+                       if (check_powerkey_delay(pinput) == true) {
+                               _D("power key is delayed, then ignored!");
+                               return 0;
+                       }
+                       /*
+                        * Normally, touch press/release events don't occur
+                        * in lcd off state. But touch release events can occur
+                        * in the state abnormally. Then touch events are ignored
+                        * when lcd is off state.
+                        */
+                       if (pinput->code == BTN_TOUCH && !current_state_in_on())
+                               break;
+                       if (get_standby_state() && pinput->code != KEY_POWER) {
+                               _D("standby mode,key ignored except powerkey");
+                               break;
+                       }
+                       if (pinput->code == code && pinput->value == value) {
+                               _E("Same key(%d, %d) is polled [%d,%d]",
+                                   code, value, old_fd, fd);
+                       }
+                       old_fd = fd;
+                       code = pinput->code;
+                       value = pinput->value;
+
+                       ignore = check_key(pinput, fd);
+                       restore_custom_brightness();
+
+                       break;
+               case EV_REL:
+                       if (get_standby_state())
+                               break;
+                       ignore = false;
+                       break;
+               case EV_ABS:
+                       if (get_standby_state())
+                               break;
+                       if (current_state_in_on())
+                               ignore = false;
+                       restore_custom_brightness();
+
+                       touch_pressed =
+                           (pinput->value == TOUCH_RELEASE ? false : true);
+                       break;
+               case EV_SW:
+                       if (!get_glove_state || !switch_glove_key)
+                               break;
+                       if (pinput->code == SW_GLOVE &&
+                           get_glove_state() == GLOVE_MODE) {
+                               switch_glove_key(pinput->value);
+                       }
+                       break;
+               }
+               idx += sizeof(struct input_event);
+               if (ignore == true && length <= idx)
+                       return 1;
+       } while (length > idx);
+
+       return 0;
+}
+
+void key_backlight_enable(bool enable)
+{
+       /* release existing timer */
+       if (hardkey_timeout_id > 0) {
+               ecore_timer_del(hardkey_timeout_id);
+               hardkey_timeout_id = NULL;
+       }
+
+       /* start timer in case of backlight enabled */
+       if (enable) {
+               /* if hardkey option is always off */
+               if (hardkey_duration == KEYBACKLIGHT_TIME_ALWAYS_OFF)
+                       return;
+
+               /* turn on hardkey backlight */
+               turnon_hardkey_backlight();
+
+               /* do not create turnoff timer in case of idle lock state */
+               if (get_lock_screen_state() == VCONFKEY_IDLE_LOCK)
+                       return;
+
+               /* start timer */
+               hardkey_timeout_id = ecore_timer_add(
+                           KEYBACKLIGHT_PRESSED_TIME,
+                               key_backlight_expired, NULL);
+       } else {
+               /* if hardkey option is always on */
+               if (hardkey_duration == KEYBACKLIGHT_TIME_ALWAYS_ON)
+                       return;
+
+               /* turn off hardkey backlight */
+               turnoff_hardkey_backlight();
+       }
+}
+
+static void hardkey_duration_cb(keynode_t *key, void *data)
+{
+       float duration;
+
+       hardkey_duration = vconf_keynode_get_int(key);
+
+       /* release existing timer */
+       if (hardkey_timeout_id > 0) {
+               ecore_timer_del(hardkey_timeout_id);
+               hardkey_timeout_id = NULL;
+       }
+
+       /* if hardkey option is always off */
+       if (hardkey_duration == KEYBACKLIGHT_TIME_ALWAYS_OFF) {
+               /* turn off hardkey backlight */
+               turnoff_hardkey_backlight();
+               return;
+       }
+
+       /* turn on hardkey backlight */
+       turnon_hardkey_backlight();
+
+       /* if hardkey option is always on */
+       if (hardkey_duration == KEYBACKLIGHT_TIME_ALWAYS_ON)
+               return;
+
+       /* start timer */
+       duration = (float)hardkey_duration / KEYBACKLIGHT_BASE_TIME;
+       hardkey_timeout_id = ecore_timer_add(
+                   duration,
+                   key_backlight_expired, NULL);
+}
+
+static int hardkey_lcd_changed_cb(void *data)
+{
+       int lcd_state = (int)data;
+
+       if (lcd_state == S_NORMAL
+           && battery.temp == TEMP_HIGH
+           && hardkey_duration == KEYBACKLIGHT_TIME_ALWAYS_ON) {
+               turnon_hardkey_backlight();
+               return 0;
+       }
+
+       /* when lcd state is dim and battery is over temp,
+          hardkey led should turn off */
+       if (lcd_state == S_LCDDIM && battery.health == HEALTH_BAD) {
+               /* release existing timer */
+               if (hardkey_timeout_id > 0) {
+                       ecore_timer_del(hardkey_timeout_id);
+                       hardkey_timeout_id = NULL;
+               }
+
+               /* turn off hardkey backlight */
+               turnoff_hardkey_backlight();
+       }
+       return 0;
+}
+
+static void keyfilter_init(void)
+{
+       /* get touchkey light duration setting */
+       if (vconf_get_int(VCONFKEY_SETAPPL_TOUCHKEY_LIGHT_DURATION, &hardkey_duration) < 0) {
+               _W("Fail to get VCONFKEY_SETAPPL_TOUCHKEY_LIGHT_DURATION!!");
+               hardkey_duration = KEYBACKLIGHT_TIME_90;
+       }
+
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_TOUCHKEY_LIGHT_DURATION, hardkey_duration_cb, NULL);
+
+       /* register notifier */
+       register_notifier(DEVICE_NOTIFIER_LCD, hardkey_lcd_changed_cb);
+
+       /* update touchkey light duration right now */
+       if (hardkey_duration == KEYBACKLIGHT_TIME_ALWAYS_ON)
+               turnon_hardkey_backlight();
+}
+
+static void keyfilter_exit(void)
+{
+       /* unregister notifier */
+       unregister_notifier(DEVICE_NOTIFIER_LCD, hardkey_lcd_changed_cb);
+
+       vconf_ignore_key_changed(VCONFKEY_SETAPPL_TOUCHKEY_LIGHT_DURATION, hardkey_duration_cb);
+}
+
+static const struct display_keyfilter_ops normal_keyfilter_ops = {
+       .init                   = keyfilter_init,
+       .exit                   = keyfilter_exit,
+       .check                  = check_key_filter,
+       .set_powerkey_ignore    = NULL,
+       .powerkey_lcdoff        = NULL,
+       .backlight_enable       = key_backlight_enable,
+};
+const struct display_keyfilter_ops *keyfilter_ops = &normal_keyfilter_ops;
+
diff --git a/src/display/lock-detector.c b/src/display/lock-detector.c
new file mode 100644 (file)
index 0000000..91c486e
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * 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.
+ */
+
+
+/**
+ * @file       lock-detector.c
+ * @brief
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <Eina.h>
+
+#include "util.h"
+#include "core.h"
+#include "core/list.h"
+
+struct lock_info {
+       unsigned long hash;
+       char *name;
+       int state;
+       int count;
+       long locktime;
+       long unlocktime;
+       long time;
+};
+
+#define LIMIT_COUNT    128
+
+static Eina_List *lock_info_list;
+
+static long get_time(void)
+{
+       struct timeval now;
+       gettimeofday(&now, NULL);
+       return (long)(now.tv_sec * 1000 + now.tv_usec / 1000);
+}
+
+static void shrink_lock_info_list(void)
+{
+       Eina_List *l, *l_prev;
+       struct lock_info *info;
+       unsigned int count;
+
+       count = eina_list_count(lock_info_list);
+       if (count <= LIMIT_COUNT)
+               return;
+       _D("list is shrink : count %d", count);
+
+       EINA_LIST_REVERSE_FOREACH_SAFE(lock_info_list, l, l_prev, info) {
+               if (info->locktime == 0) {
+                       EINA_LIST_REMOVE_LIST(lock_info_list, l);
+                       if (info->name)
+                               free(info->name);
+                       free(info);
+                       count--;
+               }
+               if (count <= (LIMIT_COUNT / 2))
+                       break;
+       }
+}
+
+int set_lock_time(const char *pname, int state)
+{
+       struct lock_info *info;
+       Eina_List *l;
+       unsigned long val;
+
+       if (!pname)
+               return -EINVAL;
+
+       if (state < S_NORMAL || state > S_SLEEP)
+               return -EINVAL;
+
+       val = eina_hash_superfast(pname, strlen(pname));
+
+       EINA_LIST_FOREACH(lock_info_list, l, info)
+               if (info->hash == val && info->state == state) {
+                       info->count += 1;
+                       if (info->locktime == 0)
+                               info->locktime = get_time();
+                       info->unlocktime = 0;
+                       EINA_LIST_PROMOTE_LIST(lock_info_list, l);
+                       eina_list_data_set(l, info);
+                       return 0;
+               }
+
+       info = malloc(sizeof(struct lock_info));
+       if (!info) {
+               _E("Malloc is failed for lock_info!");
+               return -ENOMEM;
+       }
+
+       info->hash = val;
+       info->name = strndup(pname, strlen(pname));
+       info->state = state;
+       info->count = 1;
+       info->locktime = get_time();
+       info->unlocktime = 0;
+       info->time = 0;
+
+       EINA_LIST_APPEND(lock_info_list, info);
+
+       return 0;
+}
+
+int set_unlock_time(const char *pname, int state)
+{
+       bool find = false;
+       long diff;
+       struct lock_info *info;
+       Eina_List *l;
+       unsigned long val;
+
+       if (!pname)
+               return -EINVAL;
+
+       if (state < S_NORMAL || state > S_SLEEP)
+               return -EINVAL;
+
+       val = eina_hash_superfast(pname, strlen(pname));
+
+       EINA_LIST_FOREACH(lock_info_list, l, info)
+               if (info->hash == val && info->state == state) {
+                       EINA_LIST_PROMOTE_LIST(lock_info_list, l);
+                       find = true;
+                       break;
+               }
+
+       if (!find)
+               return -EINVAL;
+
+       if (info->locktime == 0)
+               return -EINVAL;
+
+       /* update time */
+       info->unlocktime = get_time();
+       diff = info->unlocktime - info->locktime;
+       if (diff > 0)
+               info->time += diff;
+       info->locktime = 0;
+
+       eina_list_data_set(l, info);
+
+       if (eina_list_count(lock_info_list) > LIMIT_COUNT)
+               shrink_lock_info_list();
+
+       return 0;
+}
+
+void free_lock_info_list(void)
+{
+       Eina_List *l, *l_next;
+       struct lock_info *info;
+
+       if (!lock_info_list)
+               return;
+
+       EINA_LIST_FOREACH_SAFE(lock_info_list, l, l_next, info) {
+               EINA_LIST_REMOVE(lock_info_list, l);
+               if (info->name)
+                       free(info->name);
+               free(info);
+       }
+       lock_info_list = NULL;
+}
+
+void print_lock_info_list(int fd)
+{
+       struct lock_info *info;
+       Eina_List *l;
+       char buf[255];
+
+       if (!lock_info_list)
+               return;
+
+       snprintf(buf, sizeof(buf),
+           "current time : %u ms\n", get_time());
+       write(fd, buf, strlen(buf));
+
+       snprintf(buf, sizeof(buf),
+           "[%10s %6s] %6s %10s %10s %10s %s\n", "hash", "state",
+           "count", "locktime", "unlocktime", "time", "process name");
+       write(fd, buf, strlen(buf));
+
+       EINA_LIST_FOREACH(lock_info_list, l, info) {
+               long time = 0;
+               if (info->locktime != 0 && info->unlocktime == 0)
+                       time = get_time() - info->locktime;
+               snprintf(buf, sizeof(buf),
+                   "[%10u %6d] %6d %10u %10u %10u %s\n",
+                   info->hash,
+                   info->state,
+                   info->count,
+                   info->locktime,
+                   info->unlocktime,
+                   info->time + time,
+                   info->name);
+               write(fd, buf, strlen(buf));
+       }
+}
+
diff --git a/src/display/lock-detector.h b/src/display/lock-detector.h
new file mode 100644 (file)
index 0000000..681b896
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2011 - 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.
+ */
+
+
+/**
+ * @file       lock-detector.h
+ * @brief
+ *
+ */
+
+#ifndef _LOCK_DETECTOR_H_
+#define _LOCK_DETECTOR_H_
+
+int set_lock_time(const char *pname, int state);
+int set_unlock_time(const char *pname, int state);
+void free_lock_info_list(void);
+void print_lock_info_list(int fd);
+
+#endif //_LOCK_DETECTOR_H_
+
diff --git a/src/display/poll.c b/src/display/poll.c
new file mode 100644 (file)
index 0000000..652df6d
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * 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.
+ */
+
+
+/**
+ * @file       poll.c
+ * @brief       Power Manager poll implementation (input devices & a domain socket file)
+ *
+ * This file includes the input device poll implementation.
+ * Default input devices are /dev/event0 and /dev/event1
+ * User can use "PM_INPUT" for setting another input device poll in an environment file (/etc/profile).
+ * (ex: PM_INPUT=/dev/event0:/dev/event1:/dev/event5 )
+ */
+
+#include <stdio.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <Ecore.h>
+#include <core/devices.h>
+#include <core/device-handler.h>
+#include "util.h"
+#include "core.h"
+#include "poll.h"
+
+#define SHIFT_UNLOCK                    4
+#define SHIFT_UNLOCK_PARAMETER          12
+#define SHIFT_CHANGE_STATE              8
+#define SHIFT_CHANGE_TIMEOUT            20
+#define LOCK_FLAG_SHIFT                 16
+#define __HOLDKEY_BLOCK_BIT              0x1
+#define __STANDBY_MODE_BIT               0x2
+#define HOLDKEY_BLOCK_BIT               (__HOLDKEY_BLOCK_BIT << LOCK_FLAG_SHIFT)
+#define STANDBY_MODE_BIT                (__STANDBY_MODE_BIT << LOCK_FLAG_SHIFT)
+
+#define DEV_PATH_DLM   ":"
+
+PMMsg recv_data;
+int (*g_pm_callback) (int, PMMsg *);
+
+#ifdef ENABLE_KEY_FILTER
+extern int check_key_filter(int length, char buf[], int fd);
+#  define CHECK_KEY_FILTER(a, b, c) \
+       do { \
+               if (CHECK_OPS(keyfilter_ops, check) && \
+                   keyfilter_ops->check(a, b, c) != 0) \
+                       return EINA_TRUE;\
+       } while (0);
+#else
+#  define CHECK_KEY_FILTER(a, b, c)
+#endif
+
+#define DEFAULT_DEV_PATH "/dev/event1:/dev/event0"
+
+static Eina_Bool pm_handler(void *data, Ecore_Fd_Handler *fd_handler)
+{
+       char buf[1024];
+       struct sockaddr_un clientaddr;
+
+       int fd = (int)data;
+       int ret;
+       static const struct device_ops *display_device_ops;
+
+       if (!display_device_ops) {
+               display_device_ops = find_device("display");
+               if (!display_device_ops)
+                       return -ENODEV;
+       }
+
+       if (device_get_status(display_device_ops) != DEVICE_OPS_STATUS_START) {
+               _E("display is not started!");
+               return EINA_FALSE;
+       }
+
+       if (g_pm_callback == NULL) {
+               return EINA_FALSE;
+       }
+
+       ret = read(fd, buf, sizeof(buf));
+       CHECK_KEY_FILTER(ret, buf, fd);
+       (*g_pm_callback) (INPUT_POLL_EVENT, NULL);
+
+       return EINA_TRUE;
+}
+
+int init_pm_poll(int (*pm_callback) (int, PMMsg *))
+{
+       char *dev_paths, *path_tok, *pm_input_env, *save_ptr;
+       int dev_paths_size;
+
+       Ecore_Fd_Handler *fd_handler;
+       int fd = -1;
+       indev *new_dev = NULL;
+
+       g_pm_callback = pm_callback;
+
+       _I("initialize pm poll - input devices(deviced)");
+
+       pm_input_env = getenv("PM_INPUT");
+       if ((pm_input_env != NULL) && (strlen(pm_input_env) < 1024)) {
+               _I("Getting input device path from environment: %s",
+                      pm_input_env);
+               /* Add 2 bytes for following strncat() */
+               dev_paths_size =  strlen(pm_input_env) + 1;
+               dev_paths = (char *)malloc(dev_paths_size);
+               if (!dev_paths) {
+                       _E("Fail to malloc for dev path");
+                       return -ENOMEM;
+               }
+               snprintf(dev_paths, dev_paths_size, "%s", pm_input_env);
+       } else {
+               /* Add 2 bytes for following strncat() */
+               dev_paths_size = strlen(DEFAULT_DEV_PATH) + 1;
+               dev_paths = (char *)malloc(dev_paths_size);
+               if (!dev_paths) {
+                       _E("Fail to malloc for dev path");
+                       return -ENOMEM;
+               }
+               snprintf(dev_paths, dev_paths_size, "%s", DEFAULT_DEV_PATH);
+       }
+
+       /* add the UNIX domain socket file path */
+       strncat(dev_paths, DEV_PATH_DLM, strlen(DEV_PATH_DLM));
+       dev_paths[dev_paths_size - 1] = '\0';
+
+       path_tok = strtok_r(dev_paths, DEV_PATH_DLM, &save_ptr);
+       if (path_tok == NULL) {
+               _E("Device Path Tokeninzing Failed");
+               free(dev_paths);
+               return -1;
+       }
+
+       do {
+               char *path, *new_path;
+               int len;
+
+               fd = open(path_tok, O_RDONLY);
+               path = path_tok;
+               _I("pm_poll input device file: %s, fd: %d", path_tok, fd);
+
+               if (fd == -1) {
+                       _E("Cannot open the file: %s", path_tok);
+                       goto out1;
+               }
+
+               fd_handler = ecore_main_fd_handler_add(fd,
+                                   ECORE_FD_READ|ECORE_FD_ERROR,
+                                   pm_handler, (void *)fd, NULL, NULL);
+               if (fd_handler == NULL) {
+                       _E("Failed ecore_main_handler_add() in init_pm_poll()");
+                       goto out2;
+               }
+
+               new_dev = (indev *)malloc(sizeof(indev));
+
+               if (!new_dev) {
+                       _E("Fail to malloc for new_dev %s", path);
+                       goto out3;
+               }
+
+               memset(new_dev, 0, sizeof(indev));
+
+               len = strlen(path) + 1;
+               new_path = (char*) malloc(len);
+               if (!new_path) {
+                       _E("Fail to malloc for dev_path %s", path);
+                       goto out4;
+               }
+
+               strncpy(new_path, path, len);
+               new_dev->dev_path = new_path;
+               new_dev->fd = fd;
+               new_dev->dev_fd = fd_handler;
+               new_dev->pre_install = true;
+               indev_list = eina_list_append(indev_list, new_dev);
+
+       } while ((path_tok = strtok_r(NULL, DEV_PATH_DLM, &save_ptr)));
+
+       free(dev_paths);
+       return 0;
+
+out4:
+       free(new_dev);
+out3:
+       ecore_main_fd_handler_del(fd_handler);
+out2:
+       close(fd);
+out1:
+       free(dev_paths);
+
+       return -ENOMEM;
+}
+
+int exit_pm_poll(void)
+{
+       Eina_List *l = NULL;
+       Eina_List *l_next = NULL;
+       indev *data = NULL;
+
+       EINA_LIST_FOREACH_SAFE(indev_list, l, l_next, data) {
+               ecore_main_fd_handler_del(data->dev_fd);
+               close(data->fd);
+               free(data->dev_path);
+               free(data);
+               indev_list = eina_list_remove_list(indev_list, l);
+       }
+
+       _I("pm_poll is finished");
+       return 0;
+}
+
+int init_pm_poll_input(int (*pm_callback)(int , PMMsg * ), const char *path)
+{
+       indev *new_dev = NULL;
+       indev *data = NULL;
+       Ecore_Fd_Handler *fd_handler = NULL;
+       Eina_List *l = NULL;
+       Eina_List *l_next = NULL;
+       int fd = -1;
+       char *dev_path = NULL;
+
+       if (!pm_callback || !path) {
+               _E("argument is NULL! (%x,%x)", pm_callback, path);
+               return -1;
+       }
+
+       EINA_LIST_FOREACH_SAFE(indev_list, l, l_next, data)
+               if(!strcmp(path, data->dev_path)) {
+                       _E("%s is already polled!", path);
+                       return -1;
+               }
+
+       _I("initialize pm poll for bt %s", path);
+
+       g_pm_callback = pm_callback;
+
+       fd = open(path, O_RDONLY);
+       if (fd == -1) {
+               _E("Cannot open the file for BT: %s", path);
+               return -1;
+       }
+
+       dev_path = (char*)malloc(strlen(path) + 1);
+       if (!dev_path) {
+               _E("Fail to malloc for dev_path");
+               close(fd);
+               return -1;
+       }
+       strncpy(dev_path, path, strlen(path) +1);
+
+       fd_handler = ecore_main_fd_handler_add(fd,
+                           ECORE_FD_READ|ECORE_FD_ERROR,
+                           pm_handler, (void *)fd, NULL, NULL);
+       if (!fd_handler) {
+               _E("Fail to ecore fd handler add! %s", path);
+               close(fd);
+               free(dev_path);
+               return -1;
+       }
+
+       new_dev = (indev *)malloc(sizeof(indev));
+       if (!new_dev) {
+               _E("Fail to malloc for new_dev %s", path);
+               ecore_main_fd_handler_del(fd_handler);
+               close(fd);
+               free(dev_path);
+               return -1;
+       }
+       new_dev->dev_path = dev_path;
+       new_dev->fd = fd;
+       new_dev->dev_fd = fd_handler;
+       new_dev->pre_install = false;
+
+       _I("pm_poll for BT input device file(path: %s, fd: %d",
+                   new_dev->dev_path, new_dev->fd);
+       indev_list = eina_list_append(indev_list, new_dev);
+
+       return 0;
+}
+
+int check_pre_install(int fd)
+{
+       indev *data = NULL;
+       Eina_List *l = NULL;
+       Eina_List *l_next = NULL;
+
+       EINA_LIST_FOREACH_SAFE(indev_list, l, l_next, data)
+               if(fd == data->fd) {
+                       return data->pre_install;
+               }
+
+       return -ENODEV;
+}
+
+int check_dimstay(int next_state, int flag)
+{
+       if (next_state != LCD_OFF)
+               return false;
+
+       if (!(flag & GOTO_STATE_NOW))
+               return false;
+
+       if (!(pm_status_flag & DIMSTAY_FLAG))
+               return false;
+
+       if (check_abnormal_popup() != HEALTH_BAD)
+               return false;
+
+       return true;
+}
+
+int pm_lock_internal(pid_t pid, int s_bits, int flag, int timeout)
+{
+       if (!g_pm_callback)
+               return -1;
+
+       switch (s_bits) {
+       case LCD_NORMAL:
+       case LCD_DIM:
+       case LCD_OFF:
+               break;
+       default:
+               return -1;
+       }
+       if (flag & GOTO_STATE_NOW)
+               /* if the flag is true, go to the locking state directly */
+               s_bits = s_bits | (s_bits << SHIFT_CHANGE_STATE);
+
+       if (flag & HOLD_KEY_BLOCK)
+               s_bits = s_bits | HOLDKEY_BLOCK_BIT;
+
+       if (flag & STANDBY_MODE)
+               s_bits = s_bits | STANDBY_MODE_BIT;
+
+       recv_data.pid = pid;
+       recv_data.cond = s_bits;
+       recv_data.timeout = timeout;
+
+       (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data);
+
+       return 0;
+}
+
+int pm_unlock_internal(pid_t pid, int s_bits, int flag)
+{
+       if (!g_pm_callback)
+               return -1;
+
+       switch (s_bits) {
+       case LCD_NORMAL:
+       case LCD_DIM:
+       case LCD_OFF:
+               break;
+       default:
+               return -1;
+       }
+
+       s_bits = (s_bits << SHIFT_UNLOCK);
+       s_bits = (s_bits | (flag << SHIFT_UNLOCK_PARAMETER));
+
+       recv_data.pid = pid;
+       recv_data.cond = s_bits;
+
+       (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data);
+
+       return 0;
+}
+
+int pm_change_internal(pid_t pid, int s_bits)
+{
+       if (!g_pm_callback)
+               return -1;
+
+       switch (s_bits) {
+       case LCD_NORMAL:
+       case LCD_DIM:
+       case LCD_OFF:
+       case SUSPEND:
+               break;
+       default:
+               return -1;
+       }
+
+       recv_data.pid = pid;
+       recv_data.cond = s_bits << SHIFT_CHANGE_STATE;
+
+       (*g_pm_callback)(PM_CONTROL_EVENT, &recv_data);
+
+       return 0;
+}
+
diff --git a/src/display/poll.h b/src/display/poll.h
new file mode 100644 (file)
index 0000000..30268d9
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2011 - 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.
+ */
+
+
+/**
+ * @file       poll.h
+ * @brief      Power Manager input device poll implementation
+ *
+ * This file includes the input device poll implementation.
+ * Default input devices are /dev/event0 and /dev/event1
+ * User can use "PM_INPUT_DEV" for setting another input device poll in an environment file (/etc/profile).
+ * (ex: PM_INPUT_DEV=/dev/event0:/dev/event1:/dev/event5 )
+ */
+
+#ifndef __PM_POLL_H__
+#define __PM_POLL_H__
+
+#include <Ecore.h>
+#include "core/edbus-handler.h"
+/**
+ * @addtogroup POWER_MANAGER
+ * @{
+ */
+
+enum {
+       INPUT_POLL_EVENT = -9,
+       SIDEKEY_POLL_EVENT,
+       PWRKEY_POLL_EVENT,
+       PM_CONTROL_EVENT,
+};
+
+enum {
+       INTERNAL_LOCK_BASE = 100000,
+       INTERNAL_LOCK_BATTERY,
+       INTERNAL_LOCK_BOOTING,
+       INTERNAL_LOCK_DUMPMODE,
+       INTERNAL_LOCK_HDMI,
+       INTERNAL_LOCK_ODE,
+       INTERNAL_LOCK_POPUP,
+       INTERNAL_LOCK_SOUNDDOCK,
+       INTERNAL_LOCK_TA,
+       INTERNAL_LOCK_TIME,
+       INTERNAL_LOCK_USB,
+};
+
+#define SIGNAL_NAME_LCD_CONTROL                "lcdcontol"
+
+#define LCD_NORMAL     0x1             /**< NORMAL state */
+#define LCD_DIM                0x2             /**< LCD dimming state */
+#define LCD_OFF                0x4             /**< LCD off state */
+#define SUSPEND                0x8             /**< Suspend state */
+#define POWER_OFF      0x16    /**< Sleep state */
+
+#define STAY_CUR_STATE 0x1
+#define GOTO_STATE_NOW 0x2
+#define HOLD_KEY_BLOCK  0x4
+#define STANDBY_MODE    0x8
+
+#define PM_SLEEP_MARGIN        0x0     /**< keep guard time for unlock */
+#define PM_RESET_TIMER 0x1     /**< reset timer for unlock */
+#define PM_KEEP_TIMER          0x2     /**< keep timer for unlock */
+
+#define PM_LOCK_STR    "lock"
+#define PM_UNLOCK_STR  "unlock"
+#define PM_CHANGE_STR  "change"
+
+#define PM_LCDOFF_STR  "lcdoff"
+#define PM_LCDDIM_STR  "lcddim"
+#define PM_LCDON_STR   "lcdon"
+#define PM_SUSPEND_STR "suspend"
+
+#define STAYCURSTATE_STR "staycurstate"
+#define GOTOSTATENOW_STR "gotostatenow"
+
+#define HOLDKEYBLOCK_STR "holdkeyblock"
+#define STANDBYMODE_STR  "standbymode"
+
+#define SLEEP_MARGIN_STR "sleepmargin"
+#define RESET_TIMER_STR  "resettimer"
+#define KEEP_TIMER_STR   "keeptimer"
+
+typedef struct {
+       pid_t pid;
+       unsigned int cond;
+       unsigned int timeout;
+       unsigned int timeout2;
+} PMMsg;
+
+typedef struct {
+       char *dev_path;
+       int fd;
+       Ecore_Fd_Handler *dev_fd;
+       int pre_install;
+} indev;
+
+Eina_List *indev_list;
+
+PMMsg recv_data;
+int (*g_pm_callback) (int, PMMsg *);
+
+extern int init_pm_poll(int (*pm_callback) (int, PMMsg *));
+extern int exit_pm_poll();
+extern int init_pm_poll_input(int (*pm_callback)(int , PMMsg * ), const char *path);
+
+extern int pm_lock_internal(pid_t pid, int s_bits, int flag, int timeout);
+extern int pm_unlock_internal(pid_t pid, int s_bits, int flag);
+extern int pm_change_internal(pid_t pid, int s_bits);
+
+/**
+ * @}
+ */
+
+#endif                         /*__PM_POLL_H__ */
diff --git a/src/display/setting.c b/src/display/setting.c
new file mode 100644 (file)
index 0000000..2fc1dfd
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * 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 <stdlib.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#include "core.h"
+#include "util.h"
+#include "setting.h"
+
+#define LCD_DIM_RATIO          0.2
+#define LCD_MAX_DIM_TIMEOUT    7000
+
+static const char *setting_keys[SETTING_GET_END] = {
+       [SETTING_TO_NORMAL] = VCONFKEY_SETAPPL_LCD_TIMEOUT_NORMAL,
+       [SETTING_BRT_LEVEL] = VCONFKEY_SETAPPL_LCD_BRIGHTNESS,
+       [SETTING_LOCK_SCREEN] = VCONFKEY_IDLE_LOCK_STATE,
+       [SETTING_POWER_SAVING] = VCONFKEY_SETAPPL_PWRSV_SYSMODE_STATUS,
+       [SETTING_POWER_SAVING_DISPLAY] = VCONFKEY_SETAPPL_PWRSV_CUSTMODE_DISPLAY,
+       [SETTING_SMART_STAY] = VCONFKEY_SETAPPL_SMARTSCREEN_SMARTSTAY_STATUS,
+       [SETTING_BOOT_POWER_ON_STATUS] = VCONFKEY_DEVICED_BOOT_POWER_ON_STATUS,
+       [SETTING_POWER_CUSTOM_BRIGHTNESS] = VCONFKEY_PM_CUSTOM_BRIGHTNESS_STATUS,
+       [SETTING_ACCESSIBILITY_TTS] = VCONFKEY_SETAPPL_ACCESSIBILITY_TTS,
+};
+
+static int lock_screen_state = VCONFKEY_IDLE_UNLOCK;
+static bool lock_screen_bg_state = false;
+static int force_lcdtimeout = 0;
+static int custom_on_timeout = 0;
+static int custom_normal_timeout = 0;
+static int custom_dim_timeout = 0;
+
+int (*update_pm_setting) (int key_idx, int val);
+
+int set_force_lcdtimeout(int timeout)
+{
+       if (timeout < 0)
+               return -EINVAL;
+
+       force_lcdtimeout = timeout;
+
+       return 0;
+}
+
+int get_lock_screen_state(void)
+{
+       return lock_screen_state;
+}
+
+void set_lock_screen_state(int state)
+{
+       switch (state) {
+       case VCONFKEY_IDLE_LOCK:
+       case VCONFKEY_IDLE_UNLOCK:
+               lock_screen_state = state;
+               break;
+       default:
+               lock_screen_state = VCONFKEY_IDLE_UNLOCK;
+       }
+}
+
+int get_lock_screen_bg_state(void)
+{
+       return lock_screen_bg_state;
+}
+
+void set_lock_screen_bg_state(bool state)
+{
+       _I("state is %d", state);
+       lock_screen_bg_state = state;
+}
+
+int get_charging_status(int *val)
+{
+       return vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, val);
+}
+
+int get_lowbatt_status(int *val)
+{
+       return vconf_get_int(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, val);
+}
+
+int get_usb_status(int *val)
+{
+       return vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, val);
+}
+
+int set_setting_pmstate(int val)
+{
+       return vconf_set_int(VCONFKEY_PM_STATE, val);
+}
+
+int get_setting_brightness(int *level)
+{
+       return vconf_get_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, level);
+}
+
+int get_dim_timeout(int *dim_timeout)
+{
+       int vconf_timeout, on_timeout, val, ret;
+
+       if (custom_dim_timeout > 0) {
+               *dim_timeout = custom_dim_timeout;
+               return 0;
+       }
+
+       ret = vconf_get_int(setting_keys[SETTING_TO_NORMAL], &vconf_timeout);
+       if (ret != 0) {
+               _E("Failed ro get setting timeout!");
+               vconf_timeout = DEFAULT_NORMAL_TIMEOUT;
+       }
+
+       if (force_lcdtimeout > 0)
+               on_timeout = SEC_TO_MSEC(force_lcdtimeout);
+       else
+               on_timeout = SEC_TO_MSEC(vconf_timeout);
+
+       val = (double)on_timeout * LCD_DIM_RATIO;
+       if (val > LCD_MAX_DIM_TIMEOUT)
+               val = LCD_MAX_DIM_TIMEOUT;
+
+       *dim_timeout = val;
+
+       return 0;
+}
+
+int get_run_timeout(int *timeout)
+{
+       int dim_timeout = -1;
+       int vconf_timeout = -1;
+       int on_timeout;
+       int ret;
+
+       if (custom_normal_timeout > 0) {
+               *timeout = custom_normal_timeout;
+               return 0;
+       }
+
+       ret = vconf_get_int(setting_keys[SETTING_TO_NORMAL], &vconf_timeout);
+       if (ret != 0) {
+               _E("Failed ro get setting timeout!");
+               vconf_timeout = DEFAULT_NORMAL_TIMEOUT;
+       }
+
+       if (force_lcdtimeout > 0)
+               on_timeout = SEC_TO_MSEC(force_lcdtimeout);
+       else
+               on_timeout = SEC_TO_MSEC(vconf_timeout);
+
+       get_dim_timeout(&dim_timeout);
+
+       if (on_timeout <= 0)
+               ret = -ERANGE;
+       else
+               *timeout = on_timeout - dim_timeout;
+
+       return ret;
+}
+
+int set_custom_lcdon_timeout(int timeout)
+{
+       int changed = (custom_on_timeout == timeout ? false : true);
+
+       custom_on_timeout = timeout;
+
+       if (timeout <= 0) {
+               custom_normal_timeout = 0;
+               custom_dim_timeout = 0;
+               return changed;
+       }
+
+       custom_dim_timeout = (double)timeout * LCD_DIM_RATIO;
+       custom_normal_timeout = timeout - custom_dim_timeout;
+
+       _I("custom normal(%d), dim(%d)", custom_normal_timeout,
+           custom_dim_timeout);
+
+       return changed;
+}
+
+static int setting_cb(keynode_t *key_nodes, void *data)
+{
+       keynode_t *tmp = key_nodes;
+
+       if ((int)data > SETTING_END) {
+               _E("Unknown setting key: %s, idx=%d",
+                      vconf_keynode_get_name(tmp), (int)data);
+               return -1;
+       }
+       if (update_pm_setting != NULL) {
+               switch((int)data) {
+                       case SETTING_POWER_SAVING:
+                       case SETTING_POWER_SAVING_DISPLAY:
+                       case SETTING_ACCESSIBILITY_TTS:
+                               update_pm_setting((int)data, vconf_keynode_get_bool(tmp));
+                               break;
+                       default:
+                               update_pm_setting((int)data, vconf_keynode_get_int(tmp));
+                               break;
+               }
+       }
+
+       return 0;
+}
+
+int init_setting(int (*func) (int key_idx, int val))
+{
+       int i;
+
+       if (func != NULL)
+               update_pm_setting = func;
+
+       for (i = SETTING_BEGIN; i < SETTING_GET_END; i++) {
+               vconf_notify_key_changed(setting_keys[i], (void *)setting_cb,
+                                        (void *)i);
+       }
+
+       return 0;
+}
+
+int exit_setting(void)
+{
+       int i;
+       for (i = SETTING_BEGIN; i < SETTING_GET_END; i++) {
+               vconf_ignore_key_changed(setting_keys[i], (void *)setting_cb);
+       }
+
+       return 0;
+}
+
diff --git a/src/display/setting.h b/src/display/setting.h
new file mode 100644 (file)
index 0000000..7c48397
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2011 - 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.
+ */
+
+
+/*
+ * @file       setting.h
+ * @brief      Power manager setting module header
+ */
+#ifndef __PM_SETTING_H__
+#define __PM_SETTING_H__
+
+#include <vconf.h>
+
+/*
+ * @addtogroup POWER_MANAGER
+ * @{
+ */
+
+enum {
+       SETTING_BEGIN = 0,
+       SETTING_TO_NORMAL = SETTING_BEGIN,
+       SETTING_BRT_LEVEL,
+       SETTING_LOCK_SCREEN,
+       SETTING_POWER_SAVING,
+       SETTING_POWER_SAVING_DISPLAY,
+       SETTING_SMART_STAY,
+       SETTING_BOOT_POWER_ON_STATUS,
+       SETTING_POWER_CUSTOM_BRIGHTNESS,
+       SETTING_ACCESSIBILITY_TTS,
+       SETTING_GET_END,
+       SETTING_PM_STATE = SETTING_GET_END,
+       SETTING_LOW_BATT,
+       SETTING_CHARGING,
+       SETTING_POWEROFF,
+       SETTING_HALLIC_OPEN,
+       SETTING_LOCK_SCREEN_BG,
+       SETTING_END
+};
+
+extern int (*update_pm_setting) (int key_idx, int val);
+
+extern int get_setting_brightness();
+
+/*
+ * @brief setting initialization function
+ *
+ * get the variables if it exists. otherwise, set the default.
+ * and register some callback functions.
+ *
+ * @internal
+ * @param[in] func configuration change callback function
+ * @return 0 : success, -1 : error
+ */
+extern int init_setting(int (*func) (int key_idx, int val));
+
+extern int exit_setting();
+
+/*
+ * get normal state timeout from SLP-setting SLP_SETTING_LCD_TIMEOUT_NORMAL
+ *
+ * @internal
+ * @param[out] timeout timeout variable pointer
+ * @return 0 : success, -1 : error
+ */
+extern int get_run_timeout(int *timeout);
+
+/*
+ * get LCD dim state timeout from environment variable.
+ *
+ * @internal
+ * @param[out] dim_timeout timeout variable pointer
+ * @return 0 : success, negative value : error
+ */
+extern int get_dim_timeout(int *dim_timeout);
+/*
+ * get USB connection status from SLP-setting SLP_SETTING_USB_STATUS
+ *
+ * @internal
+ * @param[out] val usb connection status variable pointer, 0 is disconnected, others is connected.
+ * @return 0 : success, -1 : error
+ */
+extern int get_usb_status(int *val);
+
+/*
+ * set Current power manager state at SLP-setting "memory/pwrmgr/state"
+ *
+ * @internal
+ * @param[in] val current power manager state.
+ * @return 0 : success, -1 : error
+ */
+extern int set_setting_pmstate(int val);
+
+/*
+ * get charging status at SLP-setting "memory/Battery/Charger"
+ *
+ * @internal
+ * @param[in] val charging or not (1 or 0 respectively).
+ * @return 0 : success, -1 : error
+ */
+extern int get_charging_status(int *val);
+
+/*
+ * get current battery low status at SLP-setting "memory/Battery/Status/Low"
+ *
+ * @internal
+ * @param[in] val current low battery status
+ * @return 0 : success, -1 : error
+ */
+extern int get_lowbatt_status(int *val);
+
+/*
+ * @}
+ */
+
+#endif
diff --git a/src/display/smartstay.c b/src/display/smartstay.c
new file mode 100644 (file)
index 0000000..6f9cb32
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * 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 <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+#include "util.h"
+#include "core.h"
+#include "display-ops.h"
+#include "core/common.h"
+#include "core/device-handler.h"
+
+#define SMART_STAY     2
+#define SMART_DETECTION_LIB "/usr/lib/sensor_framework/libsmart_detection.so"
+#define CB_TIMEOUT     3 /* seconds */
+#define OCCUPIED_FAIL  -2
+
+typedef void (*detection_cb)(int result, void *data);
+
+static void *detect_handle = NULL;
+static int (*get_detection)(detection_cb callback, int type, void* user_data1, void* user_data2);
+static bool block_state = EINA_FALSE;
+static bool cb_state = EINA_FALSE;
+static Ecore_Timer *cb_timeout_id = NULL;
+
+static void init_smart_lib(void)
+{
+       detect_handle = dlopen(SMART_DETECTION_LIB, RTLD_LAZY);
+
+       if (!detect_handle) {
+               _E("dlopen error");
+       } else {
+               get_detection = (int (*)(detection_cb, int, void *, void *))
+                   dlsym(detect_handle, "get_smart_detection");
+
+               if (!get_detection) {
+                       _E("dl_sym fail");
+                       dlclose(detect_handle);
+                       detect_handle = NULL;
+               }
+       }
+}
+
+static Eina_Bool check_cb_state(void *data)
+{
+       struct state *st;
+       int next_state;
+       int user_data = (int)(data);
+
+       cb_timeout_id = NULL;
+
+       if (cb_state) {
+               _I("smart detection cb is already working!");
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       if (block_state) {
+               _I("input event occur, smart detection is ignored!");
+               block_state = EINA_FALSE;
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       if (user_data < S_START || user_data > S_LCDOFF) {
+               _E("next state is wrong [%d], set to [%d]",
+                   user_data, S_NORMAL);
+               user_data = S_NORMAL;
+       }
+
+       _I("smart detection cb is failed, goes to [%d]", user_data);
+
+       next_state = user_data;
+       pm_old_state = pm_cur_state;
+       pm_cur_state = next_state;
+
+       st = &states[pm_cur_state];
+       if (st->action)
+               st->action(st->timeout);
+
+       if (pm_cur_state == S_LCDOFF)
+               update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+static void detection_callback(int degree, void *data)
+{
+       struct state *st;
+       int next_state;
+       int user_data = (int)(data);
+
+       cb_state = EINA_TRUE;
+
+       if (block_state) {
+               _I("input event occur, face detection is ignored!");
+               block_state = EINA_FALSE;
+               return;
+       }
+
+       if (!get_hallic_open()) {
+               _I("hallic is closed! Skip detection logic!");
+               return;
+       }
+
+       _I("degree = [%d], user_data = [%d]", degree, user_data);
+
+       switch (degree)
+       {
+       case 270:
+       case 90:
+       case 180:
+       case 0:
+               _I("face detection success, goes to [%d]",
+                   S_NORMAL);
+               pm_old_state = pm_cur_state;
+               pm_cur_state = S_NORMAL;
+               break;
+       case OCCUPIED_FAIL:
+               _I("camera is occupied, stay current state");
+               break;
+       default:
+               if (user_data < S_START || user_data > S_LCDOFF) {
+                       _E("next state is wrong [%d], set to [%d]",
+                           user_data, S_NORMAL);
+                       user_data = S_NORMAL;
+               }
+
+               next_state = user_data;
+
+               pm_old_state = pm_cur_state;
+               pm_cur_state = next_state;
+
+               if (check_lcdoff_direct() == true)
+                       pm_cur_state = S_LCDOFF;
+
+               _I("smart detection is failed, goto [%d]state", pm_cur_state);
+
+               break;
+       }
+
+       st = &states[pm_cur_state];
+       if (st->action)
+               st->action(st->timeout);
+
+       if (pm_cur_state == S_LCDOFF)
+               update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
+}
+
+static int check_face_detection(int evt, int pm_cur_state, int next_state)
+{
+       int lock_state = EINA_FALSE;
+       int state;
+
+       if (cb_timeout_id) {
+               ecore_timer_del(cb_timeout_id);
+               cb_timeout_id = NULL;
+       }
+
+       if (evt == EVENT_INPUT) {
+               block_state = EINA_TRUE;
+               return EINA_FALSE;
+       }
+       block_state = EINA_FALSE;
+
+       if (evt != EVENT_TIMEOUT)
+               return EINA_FALSE;
+
+       if (pm_cur_state != S_NORMAL)
+               return EINA_FALSE;
+
+       if (!get_detection) {
+               init_smart_lib();
+               if (!get_detection) {
+                       _E("%s load failed!", SMART_DETECTION_LIB);
+                       return EINA_FALSE;
+               }
+       }
+
+       state = get_detection(detection_callback, SMART_STAY, NULL, (void*)next_state);
+
+       if (state != 0)
+               _E("get detection FAIL [%d]", state);
+       else
+               _I("get detection success");
+
+       cb_state = EINA_FALSE;
+       cb_timeout_id = ecore_timer_add(CB_TIMEOUT,
+                           (Ecore_Task_Cb)check_cb_state, (void*)next_state);
+       return EINA_TRUE;
+}
+
+static void smartstay_init(void *data)
+{
+       display_info.face_detection = check_face_detection;
+}
+
+static void smartstay_exit(void *data)
+{
+       if (detect_handle) {
+               dlclose(detect_handle);
+               detect_handle = NULL;
+               _D("detect handle is closed!");
+       }
+       get_detection = NULL;
+       display_info.face_detection = NULL;
+}
+
+static const struct display_ops display_smartstay_ops = {
+       .name     = "smartstay",
+       .init     = smartstay_init,
+       .exit     = smartstay_exit,
+};
+
+DISPLAY_OPS_REGISTER(&display_smartstay_ops)
+
diff --git a/src/display/util.h b/src/display/util.h
new file mode 100644 (file)
index 0000000..a55f130
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2011 - 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.
+ */
+
+
+/**
+ * @file       util.h
+ * @brief      Utilities header for Power manager
+ */
+#ifndef __DEF_UTIL_H__
+#define __DEF_UTIL_H__
+
+/**
+ * @addtogroup POWER_MANAGER
+ * @{
+ */
+#ifdef ENABLE_DEVICED_DLOG
+#define ENABLE_DLOG
+#endif
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "POWER_MANAGER"
+#include "shared/log-macro.h"
+
+#define SEC_TO_MSEC(x) ((x)*1000)
+#define MSEC_TO_SEC(x) ((x)/1000)
+
+/**
+ * @}
+ */
+#endif
diff --git a/src/display/weaks.h b/src/display/weaks.h
new file mode 100644 (file)
index 0000000..88c887d
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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 __DISPLAY_WEAKS_H__
+#define __DISPLAY_WEAKS_H__
+
+#include "core/common.h"
+
+/* src/display/hbm.c */
+int __WEAK__ hbm_get_state(void);
+int __WEAK__ hbm_set_state(int);
+int __WEAK__ hbm_set_state_with_timeout(int, int);
+void __WEAK__ hbm_check_timeout(void);
+
+/* src/display/brightness.c */
+int __WEAK__ control_brightness_key(int action);
+
+/* src/display/alpm.c */
+int __WEAK__ alpm_set_state(int);
+int __WEAK__ set_alpm_screen(char *);
+
+#endif
+
diff --git a/src/display/x-lcd-on.c b/src/display/x-lcd-on.c
new file mode 100644 (file)
index 0000000..807b6b3
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  deviced
+ *
+ * Copyright (c) 2011 - 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 __PM_X_LCD_ONOFF_C__
+#define __PM_X_LCD_ONOFF_C__
+
+#include <string.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+#include "core/log.h"
+#include "core/common.h"
+
+#define CMD_ON         "on"
+#define CMD_OFF                "off"
+#define CMD_STANDBY    "standby"
+
+static const char *xset_arg[] = {
+       "/usr/bin/xset",
+       "dpms", "force", NULL, NULL,
+};
+
+static int pm_x_set_lcd_backlight(struct _PMSys *p, int on)
+{
+       pid_t pid;
+       char cmd_line[8];
+       int argc;
+
+       _D("Backlight on=%d", on);
+
+       switch (on) {
+       case STATUS_ON:
+               snprintf(cmd_line, sizeof(cmd_line), "%s", CMD_ON);
+               break;
+       case STATUS_OFF:
+               snprintf(cmd_line, sizeof(cmd_line), "%s", CMD_OFF);
+               break;
+       case STATUS_STANDBY:
+               snprintf(cmd_line, sizeof(cmd_line), "%s", CMD_STANDBY);
+               break;
+       }
+
+       argc = ARRAY_SIZE(xset_arg);
+       xset_arg[argc - 2] = cmd_line;
+       return run_child(argc, xset_arg);
+}
+
+#endif                         /*__PM_X_LCD_ONOFF_C__ */
diff --git a/src/extcon/extcon.c b/src/extcon/extcon.c
new file mode 100644 (file)
index 0000000..5296bd6
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * 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 <device-node.h>
+#include <vconf.h>
+
+#include "core/log.h"
+#include "core/edbus-handler.h"
+#include "core/devices.h"
+
+static DBusMessage *dbus_get_usb_id(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+
+       ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ID, &val);
+       if (ret >= 0)
+               ret = val;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_get_muic_adc_enable(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+
+       ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_MUIC_ADC_ENABLE, &val);
+       if (ret >= 0)
+               ret = val;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_set_muic_adc_enable(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+
+       if (!dbus_message_get_args(msg, NULL,
+                               DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ret = device_set_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_MUIC_ADC_ENABLE, val);
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "GetUsbId",           NULL,    "i", dbus_get_usb_id },
+       { "GetMuicAdcEnable",   NULL,    "i", dbus_get_muic_adc_enable },
+       { "SetMuicAdcEnable",    "i",    "i", dbus_set_muic_adc_enable },
+};
+
+static void extcon_init(void *data)
+{
+       int ret, otg_mode = 0;
+
+       ret = register_edbus_method(DEVICED_PATH_EXTCON, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       if (vconf_get_bool(VCONFKEY_SETAPPL_USB_OTG_MODE, &otg_mode) < 0)
+               _E("failed to get VCONFKEY_SETAPPL_USB_OTG_MODE");
+
+       /* if otg_mode key is on, deviced turns on the otg_mode */
+       if (otg_mode)
+               device_set_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_MUIC_ADC_ENABLE, otg_mode);
+}
+
+static const struct device_ops extcon_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "extcon",
+       .init     = extcon_init,
+};
+
+DEVICE_OPS_REGISTER(&extcon_device_ops)
diff --git a/src/hall/hall-handler.c b/src/hall/hall-handler.c
new file mode 100644 (file)
index 0000000..ef83327
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <vconf.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <assert.h>
+#include <device-node.h>
+#include <Ecore.h>
+
+#include "core/log.h"
+#include "core/data.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+#include "core/edbus-handler.h"
+#include "hall-handler.h"
+
+#define SIGNAL_HALL_STATE      "ChangeState"
+
+static int hall_ic_status = HALL_IC_OPENED;
+
+static int hall_ic_get_status(void)
+{
+       return hall_ic_status;
+}
+
+static void hall_ic_chgdet_cb(struct main_data *ad)
+{
+       int val = -1;
+       int fd, r, ret;
+       char buf[2];
+       char *arr[1];
+       char str_status[32];
+
+       fd = open(HALL_IC_STATUS, O_RDONLY);
+       if (fd == -1) {
+               _E("%s open error: %s", HALL_IC_STATUS, strerror(errno));
+               return;
+       }
+       r = read(fd, buf, 1);
+       close(fd);
+       if (r != 1) {
+               _E("fail to get hall status %d", r);
+               return;
+       }
+
+       buf[1] = '\0';
+
+       hall_ic_status = atoi(buf);
+       _I("cover is opened(%d)", hall_ic_status);
+
+       device_notify(DEVICE_NOTIFIER_HALLIC_OPEN, (void *)hall_ic_status);
+
+       snprintf(str_status, sizeof(str_status), "%d", hall_ic_status);
+       arr[0] = str_status;
+
+       broadcast_edbus_signal(DEVICED_PATH_HALL, DEVICED_INTERFACE_HALL,
+                       SIGNAL_HALL_STATE, "i", arr);
+
+       /* Set touch screen flip mode when cover is closed */
+       ret = device_set_property(DEVICE_TYPE_TOUCH,
+           PROP_TOUCH_SCREEN_FLIP_MODE, (hall_ic_status ? 0 : 1));
+       if (ret < 0)
+               _E("Failed to set touch screen flip mode!");
+
+       /* Set touch key flip mode when cover is closed */
+       ret = device_set_property(DEVICE_TYPE_TOUCH,
+           PROP_TOUCH_KEY_FLIP_MODE, (hall_ic_status ? 0 : 1));
+       if (ret < 0)
+               _E("Failed to set touch key flip mode!");
+
+}
+
+static int hall_action(int argc, char **argv)
+{
+       int i;
+       int pid;
+       int prop;
+
+       if (strncmp(argv[0], HALL_IC_NAME, strlen(HALL_IC_NAME)) == 0)
+               hall_ic_chgdet_cb(NULL);
+       return 0;
+}
+
+static void hall_edbus_signal_handler(void *data, DBusMessage *msg)
+{
+       _D("hall_edbus_signal_handler occurs!!!");
+}
+
+static DBusMessage *edbus_getstatus_cb(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+
+       ret = device_get_property(DEVICE_TYPE_HALL, PROP_HALL_STATUS, &val);
+       if (ret >= 0)
+               ret = val;
+
+       _D("get hall status %d, %d", val, ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "getstatus",       NULL,   "i", edbus_getstatus_cb },
+       /* Add methods here */
+};
+
+static void hall_ic_init(void *data)
+{
+       int ret, val;
+
+       /* init dbus interface */
+       ret = register_edbus_method(DEVICED_PATH_HALL, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       register_action(PREDEF_HALL_IC, hall_action, NULL, NULL);
+
+       register_edbus_signal_handler(DEVICED_PATH_HALL, DEVICED_INTERFACE_HALL,
+                       SIGNAL_HALL_STATE,
+                       hall_edbus_signal_handler);
+
+       if (device_get_property(DEVICE_TYPE_HALL, PROP_HALL_STATUS, &val) >= 0)
+               hall_ic_status = val;
+}
+
+static const struct device_ops hall_device_ops = {
+       .priority       = DEVICE_PRIORITY_NORMAL,
+       .name           = HALL_IC_NAME,
+       .init           = hall_ic_init,
+       .status         = hall_ic_get_status,
+};
+
+DEVICE_OPS_REGISTER(&hall_device_ops)
diff --git a/src/hall/hall-handler.h b/src/hall/hall-handler.h
new file mode 100644 (file)
index 0000000..75760b3
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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 __HALL_HANDLER_H__
+#define __HALL_HANDLER_H__
+
+#define HALL_IC_CLOSED 0
+#define HALL_IC_OPENED 1
+
+#define HALL_IC_SUBSYSTEM "flip"
+#define HALL_IC_NAME "hall_ic"
+#define HALL_IC_PATH "/devices/virtual/"HALL_IC_SUBSYSTEM"/"HALL_IC_NAME
+#define HALL_IC_STATUS "/sys/class/"HALL_IC_SUBSYSTEM"/"HALL_IC_NAME"/cover_status"
+
+#define PREDEF_HALL_IC HALL_IC_NAME
+
+#endif //__HALL_HANDLER_H__
diff --git a/src/haptic/HW_touch_30ms_sharp.ivt b/src/haptic/HW_touch_30ms_sharp.ivt
new file mode 100755 (executable)
index 0000000..97c7978
Binary files /dev/null and b/src/haptic/HW_touch_30ms_sharp.ivt differ
diff --git a/src/haptic/emulator.c b/src/haptic/emulator.c
new file mode 100644 (file)
index 0000000..b6adad9
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * 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 "core/log.h"
+#include "haptic.h"
+
+#define DEFAULT_HAPTIC_HANDLE  0xFFFF
+#define DEFAULT_EFFECT_HANDLE  0xFFFA
+
+/* START: Haptic Module APIs */
+static int get_device_count(int *count)
+{
+       if (count)
+               *count = 1;
+
+       return 0;
+}
+
+static int open_device(int device_index, int *device_handle)
+{
+       if (device_handle)
+               *device_handle = DEFAULT_HAPTIC_HANDLE;
+
+       return 0;
+}
+
+static int close_device(int device_handle)
+{
+       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle)
+{
+       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+               return -EINVAL;
+
+       if (effect_handle)
+               *effect_handle = DEFAULT_EFFECT_HANDLE;
+
+       return 0;
+}
+
+static int vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle)
+{
+       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+               return -EINVAL;
+
+       if (effect_handle)
+               *effect_handle = DEFAULT_EFFECT_HANDLE;
+
+       return 0;
+}
+
+static int stop_device(int device_handle)
+{
+       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int get_device_state(int device_index, int *effect_state)
+{
+       if (effect_state)
+               *effect_state = 0;
+
+       return 0;
+}
+
+static int create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt)
+{
+       _E("Not support feature");
+       return -EACCES;
+}
+
+static int get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration)
+{
+       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+               return -EINVAL;
+
+       _E("Not support feature");
+       return -EACCES;
+}
+
+static int convert_binary(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path)
+{
+       _E("Not support feature");
+       return -EACCES;
+}
+/* END: Haptic Module APIs */
+
+static const struct haptic_plugin_ops default_plugin = {
+       .get_device_count    = get_device_count,
+       .open_device         = open_device,
+       .close_device        = close_device,
+       .vibrate_monotone    = vibrate_monotone,
+       .vibrate_buffer      = vibrate_buffer,
+       .stop_device         = stop_device,
+       .get_device_state    = get_device_state,
+       .create_effect       = create_effect,
+       .get_buffer_duration = get_buffer_duration,
+       .convert_binary      = convert_binary,
+};
+
+static bool is_valid(void)
+{
+#ifdef EMULATOR
+       _I("Support emulator haptic device");
+       return true;
+#else
+       _E("Do not support emulator haptic device");
+       return false;
+#endif
+}
+
+static const struct haptic_plugin_ops *load(void)
+{
+       return &default_plugin;
+}
+
+static const struct haptic_ops emul_ops = {
+       .is_valid = is_valid,
+       .load     = load,
+};
+
+HAPTIC_OPS_REGISTER(&emul_ops)
diff --git a/src/haptic/external.c b/src/haptic/external.c
new file mode 100644 (file)
index 0000000..f0be7f7
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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 <stdbool.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#include "core/log.h"
+#include "haptic.h"
+
+#define HAPTIC_MODULE_PATH                     "/usr/lib/libhaptic-module.so"
+
+/* Haptic Plugin Interface */
+static void *dlopen_handle;
+static const struct haptic_plugin_ops *plugin_intf;
+
+static bool is_valid(void)
+{
+       struct stat buf;
+       const struct haptic_plugin_ops *(*get_haptic_plugin_interface) () = NULL;
+
+       if (stat(HAPTIC_MODULE_PATH, &buf)) {
+               _E("file(%s) is not presents", HAPTIC_MODULE_PATH);
+               goto error;
+       }
+
+       dlopen_handle = dlopen(HAPTIC_MODULE_PATH, RTLD_NOW);
+       if (!dlopen_handle) {
+               _E("dlopen failed: %s", dlerror());
+               goto error;
+       }
+
+       get_haptic_plugin_interface = dlsym(dlopen_handle, "get_haptic_plugin_interface");
+       if (!get_haptic_plugin_interface) {
+               _E("dlsym failed : %s", dlerror());
+               goto error;
+       }
+
+       plugin_intf = get_haptic_plugin_interface();
+       if (!plugin_intf) {
+               _E("get_haptic_plugin_interface() failed");
+               goto error;
+       }
+
+       _I("Support external haptic device");
+       return true;
+
+error:
+       if (dlopen_handle) {
+               dlclose(dlopen_handle);
+               dlopen_handle = NULL;
+       }
+
+       _I("Do not support external haptic device");
+       return false;
+}
+
+static const struct haptic_plugin_ops *load(void)
+{
+       return plugin_intf;
+}
+
+static void release(void)
+{
+       if (dlopen_handle) {
+               dlclose(dlopen_handle);
+               dlopen_handle = NULL;
+       }
+
+       plugin_intf = NULL;
+}
+
+static const struct haptic_ops ext_ops = {
+       .is_valid = is_valid,
+       .load     = load,
+       .release  = release,
+};
+
+HAPTIC_OPS_REGISTER(&ext_ops)
diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c
new file mode 100644 (file)
index 0000000..a211e41
--- /dev/null
@@ -0,0 +1,624 @@
+/*
+ * 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 <stdbool.h>
+#include <dlfcn.h>
+#include <vconf.h>
+
+#include "core/log.h"
+#include "core/list.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+#include "core/device-notifier.h"
+#include "haptic.h"
+
+#ifndef DATADIR
+#define DATADIR                "/usr/share/deviced"
+#endif
+
+/* hardkey vibration variable */
+#define HARDKEY_VIB_RESOURCE           DATADIR"/HW_touch_30ms_sharp.ivt"
+#define HARDKEY_VIB_ITERATION          1
+#define HARDKEY_VIB_FEEDBACK           3
+#define HARDKEY_VIB_PRIORITY           2
+#define HAPTIC_FEEDBACK_STEP           20
+
+/* power on, power off vibration variable */
+#define POWER_ON_VIB_DURATION                  300
+#define POWER_OFF_VIB_DURATION                 300
+#define POWER_VIB_FEEDBACK                     100
+
+#define MAX_EFFECT_BUFFER                      (64*1024)
+
+#define RETRY_CNT                                      3
+
+#define CHECK_VALID_OPS(ops, r)                ((ops) ? true : !(r = -ENODEV))
+
+/* for playing */
+static int g_handle;
+
+/* haptic operation variable */
+static dd_list *h_head;
+static const struct haptic_plugin_ops *h_ops;
+static bool haptic_disabled;
+
+static int haptic_start(void);
+static int haptic_stop(void);
+static int haptic_internal_init(void);
+
+void add_haptic(const struct haptic_ops *ops)
+{
+       DD_LIST_APPEND(h_head, (void*)ops);
+}
+
+void remove_haptic(const struct haptic_ops *ops)
+{
+       DD_LIST_REMOVE(h_head, (void*)ops);
+}
+
+static int haptic_module_load(void)
+{
+       struct haptic_ops *ops;
+       dd_list *elem;
+       int r;
+
+       /* find valid plugin */
+       DD_LIST_FOREACH(h_head, elem, ops) {
+               if (ops->is_valid && ops->is_valid()) {
+                       if (ops->load)
+                               h_ops = ops->load();
+                       break;
+               }
+       }
+
+       if (!CHECK_VALID_OPS(h_ops, r)) {
+               _E("Can't find the valid haptic device");
+               return r;
+       }
+
+       /* solution bug
+          we do not use internal vibration except power off
+          but module does not stop vibrating, although called terminate function */
+       haptic_internal_init();
+
+       return 0;
+}
+
+static DBusMessage *edbus_get_count(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret, val;
+
+       if (!CHECK_VALID_OPS(h_ops, ret))
+               goto exit;
+
+       ret = h_ops->get_device_count(&val);
+       if (ret >= 0)
+               ret = val;
+
+exit:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_open_device(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int index, handle, ret;
+
+       if (!CHECK_VALID_OPS(h_ops, ret))
+               goto exit;
+
+       if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID)) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       ret = h_ops->open_device(index, &handle);
+       if (ret >= 0)
+               ret = handle;
+
+exit:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_close_device(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       unsigned int handle;
+       int ret;
+
+       if (!CHECK_VALID_OPS(h_ops, ret))
+               goto exit;
+
+       if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle, DBUS_TYPE_INVALID)) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       ret = h_ops->close_device(handle);
+
+exit:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_vibrate_monotone(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       unsigned int handle;
+       int duration, level, priority, e_handle, ret;
+
+       if (!CHECK_VALID_OPS(h_ops, ret))
+               goto exit;
+
+       if (haptic_disabled) {
+               ret = -EACCES;
+               goto exit;
+       }
+
+       if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle,
+                               DBUS_TYPE_INT32, &duration,
+                               DBUS_TYPE_INT32, &level,
+                               DBUS_TYPE_INT32, &priority, DBUS_TYPE_INVALID)) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       ret = h_ops->vibrate_monotone(handle, duration, level, priority, &e_handle);
+       if (ret >= 0)
+               ret = e_handle;
+
+exit:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+
+}
+
+static DBusMessage *edbus_vibrate_buffer(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       unsigned int handle;
+       unsigned char *data;
+       int size, iteration, level, priority, e_handle, ret;
+
+       if (!CHECK_VALID_OPS(h_ops, ret))
+               goto exit;
+
+       if (haptic_disabled) {
+               ret = -EACCES;
+               goto exit;
+       }
+
+       if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle,
+                               DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, &size,
+                               DBUS_TYPE_INT32, &iteration,
+                               DBUS_TYPE_INT32, &level,
+                               DBUS_TYPE_INT32, &priority, DBUS_TYPE_INVALID)) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       ret = h_ops->vibrate_buffer(handle, data, iteration, level, priority, &e_handle);
+       if (ret >= 0)
+               ret = e_handle;
+
+exit:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_stop_device(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       unsigned int handle;
+       int ret;
+
+       if (!CHECK_VALID_OPS(h_ops, ret))
+               goto exit;
+
+       if (haptic_disabled) {
+               ret = -EACCES;
+               goto exit;
+       }
+
+       if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle, DBUS_TYPE_INVALID)) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       ret = h_ops->stop_device(handle);
+
+exit:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_get_state(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int index, state, ret;
+
+       if (!CHECK_VALID_OPS(h_ops, ret))
+               goto exit;
+
+       if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &index, DBUS_TYPE_INVALID)) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       ret = h_ops->get_device_state(index, &state);
+       if (ret >= 0)
+               ret = state;
+
+exit:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_create_effect(E_DBus_Object *obj, DBusMessage *msg)
+{
+       static unsigned char data[MAX_EFFECT_BUFFER];
+       static unsigned char *p = data;
+       DBusMessageIter iter, arr;
+       DBusMessage *reply;
+       haptic_module_effect_element *elem_arr;
+       int i, size, cnt, ret, bufsize = sizeof(data);
+
+       if (!CHECK_VALID_OPS(h_ops, ret))
+               goto exit;
+
+       if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &bufsize,
+                               DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &elem_arr, &size,
+                               DBUS_TYPE_INT32, &cnt, DBUS_TYPE_INVALID)) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       if (bufsize > MAX_EFFECT_BUFFER) {
+               ret = -ENOMEM;
+               goto exit;
+       }
+
+       for (i = 0; i < cnt; ++i)
+               _D("[%2d] %d %d", i, elem_arr[i].haptic_duration, elem_arr[i].haptic_level);
+
+       memset(data, 0, MAX_EFFECT_BUFFER);
+       ret = h_ops->create_effect(data, bufsize, elem_arr, cnt);
+
+exit:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &arr);
+       dbus_message_iter_append_fixed_array(&arr, DBUS_TYPE_BYTE, &p, bufsize);
+       dbus_message_iter_close_container(&iter, &arr);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_get_duration(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       unsigned int handle;
+       unsigned char *data;
+       int size, duration, ret;
+
+       if (!CHECK_VALID_OPS(h_ops, ret))
+               goto exit;
+
+       if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &handle,
+                               DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, &size,
+                               DBUS_TYPE_INVALID)) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       ret = h_ops->get_buffer_duration(handle, data, &duration);
+       if (ret >= 0)
+               ret = duration;
+
+exit:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_save_binary(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       unsigned char *data;
+       unsigned char *path;
+       int size, ret;
+
+       if (!CHECK_VALID_OPS(h_ops, ret))
+               goto exit;
+
+       if (!dbus_message_get_args(msg, NULL,
+                               DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, &size,
+                               DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       _D("file path : %s", path);
+       ret = h_ops->convert_binary(data, size, path);
+
+exit:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static unsigned char* convert_file_to_buffer(const char *file_name, int *size)
+{
+       FILE *pf;
+       long file_size;
+       unsigned char *pdata = NULL;
+
+       if (!file_name)
+               return NULL;
+
+       /* Get File Stream Pointer */
+       pf = fopen(file_name, "rb");
+       if (!pf) {
+               _E("fopen failed : %s", strerror(errno));
+               return NULL;
+       }
+
+       if (fseek(pf, 0, SEEK_END))
+               goto error;
+
+       file_size = ftell(pf);
+       if (fseek(pf, 0, SEEK_SET))
+               goto error;
+
+       if (file_size < 0)
+               goto error;
+
+       pdata = (unsigned char*)malloc(file_size);
+       if (!pdata)
+               goto error;
+
+       if (fread(pdata, 1, file_size, pf) != file_size)
+               goto err_free;
+
+       fclose(pf);
+       *size = file_size;
+       return pdata;
+
+err_free:
+       free(pdata);
+
+error:
+       fclose(pf);
+
+       _E("failed to convert file to buffer (%s)", strerror(errno));
+       return NULL;
+}
+
+static int haptic_internal_init(void)
+{
+       int r;
+       if (!CHECK_VALID_OPS(h_ops, r))
+               return r;
+       return h_ops->open_device(HAPTIC_MODULE_DEVICE_ALL, &g_handle);
+}
+
+static int haptic_internal_exit(void)
+{
+       int r;
+       if (!CHECK_VALID_OPS(h_ops, r))
+               return r;
+       return h_ops->close_device(g_handle);
+}
+
+static int haptic_booting_done_cb(void *data)
+{
+       return haptic_module_load();
+}
+
+static int haptic_hardkey_changed_cb(void *data)
+{
+       int size, level, status, e_handle, ret, cnt = RETRY_CNT;
+       unsigned char *buf;
+
+       while (!CHECK_VALID_OPS(h_ops, ret) && cnt--) {
+               haptic_module_load();
+               if (!cnt)
+                       return ret;
+       }
+
+       if (!g_handle)
+               haptic_internal_init();
+
+       if (vconf_get_bool(VCONFKEY_SETAPPL_HAPTIC_FEEDBACK_STATUS_BOOL, &status) < 0) {
+               _E("fail to get VCONFKEY_SETAPPL_HAPTIC_FEEDBACK_STATUS_BOOL");
+               status = 1;
+       }
+
+       /* when turn off haptic feedback option */
+       if (!status)
+               return 0;
+
+       buf = convert_file_to_buffer(HARDKEY_VIB_RESOURCE, &size);
+       if (!buf)
+               return -1;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, &level);
+       if (ret < 0) {
+               _E("fail to get VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT");
+               level = HARDKEY_VIB_FEEDBACK;
+       }
+
+       ret = h_ops->vibrate_buffer(g_handle, buf, HARDKEY_VIB_ITERATION,
+                       level*HAPTIC_FEEDBACK_STEP, HARDKEY_VIB_PRIORITY, &e_handle);
+       if (ret < 0)
+               _E("fail to vibrate buffer : %d", ret);
+
+       free(buf);
+       return ret;
+}
+
+static int haptic_poweroff_cb(void *data)
+{
+       int e_handle, ret, cnt = RETRY_CNT;
+
+       while (!CHECK_VALID_OPS(h_ops, ret) && cnt--) {
+               haptic_module_load();
+               if (!cnt)
+                       return ret;
+       }
+
+       if (!g_handle)
+               haptic_internal_init();
+
+       /* power off vibration */
+       ret = h_ops->vibrate_monotone(g_handle, POWER_OFF_VIB_DURATION,
+                       POWER_VIB_FEEDBACK, HARDKEY_VIB_PRIORITY, &e_handle);
+       if (ret < 0) {
+               _E("fail to vibrate_monotone : %d", ret);
+               return ret;
+       }
+
+       /* sleep for vibration */
+       usleep(POWER_OFF_VIB_DURATION*1000);
+       return 0;
+}
+
+static int haptic_powersaver_cb(void *data)
+{
+       int powersaver_on = (int)data;
+
+       if (powersaver_on)
+               haptic_stop();
+       else
+               haptic_start();
+
+       return 0;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "GetCount",          NULL,   "i", edbus_get_count },
+       { "OpenDevice",         "i",   "i", edbus_open_device },
+       { "CloseDevice",        "u",   "i", edbus_close_device },
+       { "StopDevice",         "u",   "i", edbus_stop_device },
+       { "VibrateMonotone", "uiii",   "i", edbus_vibrate_monotone },
+       { "VibrateBuffer", "uayiii",   "i", edbus_vibrate_buffer },
+       { "GetState",           "i",   "i", edbus_get_state },
+       { "GetDuration",      "uay",   "i", edbus_get_duration },
+       { "CreateEffect",    "iayi", "ayi", edbus_create_effect },
+       { "SaveBinary",       "ays",   "i", edbus_save_binary },
+       /* Add methods here */
+};
+
+static void haptic_init(void *data)
+{
+       int r;
+
+       /* init dbus interface */
+       r = register_edbus_method(DEVICED_PATH_HAPTIC, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (r < 0)
+               _E("fail to init edbus method(%d)", r);
+
+       /* register notifier for below each event */
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, haptic_booting_done_cb);
+       register_notifier(DEVICE_NOTIFIER_TOUCH_HARDKEY, haptic_hardkey_changed_cb);
+       register_notifier(DEVICE_NOTIFIER_POWEROFF_HAPTIC, haptic_poweroff_cb);
+       register_notifier(DEVICE_NOTIFIER_POWERSAVER, haptic_powersaver_cb);
+}
+
+static void haptic_exit(void *data)
+{
+       struct haptic_ops *ops;
+       dd_list *elem;
+       int r;
+
+       /* unregister notifier for below each event */
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, haptic_booting_done_cb);
+       unregister_notifier(DEVICE_NOTIFIER_TOUCH_HARDKEY, haptic_hardkey_changed_cb);
+       unregister_notifier(DEVICE_NOTIFIER_POWEROFF_HAPTIC, haptic_poweroff_cb);
+       unregister_notifier(DEVICE_NOTIFIER_POWERSAVER, haptic_powersaver_cb);
+
+       if (!CHECK_VALID_OPS(h_ops, r))
+               return;
+
+       /* haptic exit for deviced */
+       haptic_internal_exit();
+
+       /* release plugin */
+       DD_LIST_FOREACH(h_head, elem, ops) {
+               if (ops->is_valid && ops->is_valid()) {
+                       if (ops->release)
+                               ops->release();
+                       h_ops = NULL;
+                       break;
+               }
+       }
+}
+
+static int haptic_start(void)
+{
+       _I("start");
+       haptic_disabled = false;
+       return 0;
+}
+
+static int haptic_stop(void)
+{
+       _I("stop");
+       haptic_disabled = true;
+       return 0;
+}
+
+static const struct device_ops haptic_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "haptic",
+       .init     = haptic_init,
+       .exit     = haptic_exit,
+};
+
+DEVICE_OPS_REGISTER(&haptic_device_ops)
diff --git a/src/haptic/haptic.h b/src/haptic/haptic.h
new file mode 100644 (file)
index 0000000..dfda5d3
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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 __HAPTIC_H__
+#define __HAPTIC_H__
+
+#include <stdbool.h>
+#include "core/common.h"
+#include "haptic-plugin-intf.h"
+
+#define HAPTIC_OPS_REGISTER(dev)       \
+static void __CONSTRUCTOR__ module_init(void)  \
+{      \
+       add_haptic(dev);        \
+}      \
+static void __DESTRUCTOR__ module_exit(void)   \
+{      \
+       remove_haptic(dev);     \
+}
+
+struct haptic_ops {
+       bool (*is_valid)(void);
+       const struct haptic_plugin_ops *(*load)(void);
+       void (*release)(void);
+};
+
+void add_haptic(const struct haptic_ops *ops);
+void remove_haptic(const struct haptic_ops *ops);
+
+#endif /* __HAPTIC_H__ */
diff --git a/src/haptic/standard.c b/src/haptic/standard.c
new file mode 100644 (file)
index 0000000..35e0666
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * 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 <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <Ecore.h>
+
+#include "core/log.h"
+#include "haptic.h"
+
+#define DEFAULT_HAPTIC_HANDLE  0xFFFF
+#define MAX_MAGNITUDE                  0xFFFF
+#define PERIODIC_MAX_MAGNITUDE 0x7FFF  /* 0.5 * MAX_MAGNITUDE */
+
+#define DEV_INPUT   "/dev/input"
+#define EVENT          "event"
+
+#define BITS_PER_LONG (sizeof(long) * 8)
+#define OFF(x)  ((x)%BITS_PER_LONG)
+#define BIT(x)  (1UL<<OFF(x))
+#define LONG(x) ((x)/BITS_PER_LONG)
+#define test_bit(bit, array)    ((array[LONG(bit)] >> OFF(bit)) & 1)
+
+static struct ff_effect ff_effect;
+static char ff_path[PATH_MAX];
+static int ff_use_count;
+static int ff_fd;
+static Ecore_Timer *timer;
+
+static int ff_stop(int fd);
+static Eina_Bool timer_cb(void *data)
+{
+       /* stop previous vibration */
+       ff_stop(ff_fd);
+       _I("stop vibration by timer");
+
+       return ECORE_CALLBACK_CANCEL;
+}
+
+static int register_timer(int ms)
+{
+       /* add new timer */
+       timer = ecore_timer_add(ms/1000.f, timer_cb, NULL);
+       if (!timer)
+               return -EPERM;
+
+       return 0;
+}
+
+static int unregister_timer(void)
+{
+       if (timer) {
+               ecore_timer_del(timer);
+               timer = NULL;
+       }
+
+       return 0;
+}
+
+static int ff_find_device(char *path, int size)
+{
+       DIR *dir;
+       struct dirent *dent;
+       char ev_path[PATH_MAX];
+       unsigned long features[1+FF_MAX/sizeof(unsigned long)];
+       int fd, ret;
+
+       dir = opendir(DEV_INPUT);
+       if (!dir)
+               return -errno;
+
+       while ((dent = readdir(dir))) {
+               if (dent->d_type == DT_DIR ||
+                       !strstr(dent->d_name, "event"))
+                       continue;
+
+               snprintf(ev_path, sizeof(ev_path), "%s/%s", DEV_INPUT, dent->d_name);
+
+               fd = open(ev_path, O_RDWR);
+               if (fd < 0)
+                       continue;
+
+               /* get force feedback device */
+               memset(features, 0, sizeof(features));
+               ret = ioctl(fd, EVIOCGBIT(EV_FF, sizeof(features)), features);
+               if (ret == -1) {
+                       close(fd);
+                       continue;
+               }
+
+               if (test_bit(FF_CONSTANT, features))
+                       _D("%s type : constant", ev_path);
+               if (test_bit(FF_PERIODIC, features))
+                       _D("%s type : periodic", ev_path);
+               if (test_bit(FF_SPRING, features))
+                       _D("%s type : spring", ev_path);
+               if (test_bit(FF_FRICTION, features))
+                       _D("%s type : friction", ev_path);
+               if (test_bit(FF_RUMBLE, features))
+                       _D("%s type : rumble", ev_path);
+
+               if (test_bit(FF_PERIODIC, features)) {
+                       memcpy(ff_path, ev_path, strlen(ev_path));
+                       close(fd);
+                       closedir(dir);
+                       return 0;
+               }
+
+               close(fd);
+       }
+
+       closedir(dir);
+       return -1;
+}
+
+static int ff_play(int fd, int length, int level)
+{
+       struct input_event play;
+       int r = 0;
+       double magnitude;
+
+       if (fd < 0)
+               return -EINVAL;
+
+       /* unregister existing timer */
+       unregister_timer();
+
+       magnitude = (double)level/HAPTIC_MODULE_FEEDBACK_MAX;
+       magnitude *= PERIODIC_MAX_MAGNITUDE;
+
+       _I("info : magnitude(%d) length(%d)", (int)magnitude, length);
+
+       /* Set member variables in effect struct */
+       ff_effect.type = FF_PERIODIC;
+       if (!ff_effect.id)
+               ff_effect.id = -1;
+       ff_effect.u.periodic.waveform = FF_SQUARE;
+       ff_effect.u.periodic.period = 0.1*0x100;        /* 0.1 second */
+       ff_effect.u.periodic.magnitude = (int)magnitude;
+       ff_effect.u.periodic.offset = 0;
+       ff_effect.u.periodic.phase = 0;
+       ff_effect.direction = 0x4000;   /* Along X axis */
+       ff_effect.u.periodic.envelope.attack_length = 0;
+       ff_effect.u.periodic.envelope.attack_level = 0;
+       ff_effect.u.periodic.envelope.fade_length = 0;
+       ff_effect.u.periodic.envelope.fade_level = 0;
+       ff_effect.trigger.button = 0;
+       ff_effect.trigger.interval = 0;
+       ff_effect.replay.length = length;
+       ff_effect.replay.delay = 0;
+
+       if (ioctl(fd, EVIOCSFF, &ff_effect) == -1) {
+               /* workaround: if effect is erased, try one more */
+               ff_effect.id = -1;
+               if (ioctl(fd, EVIOCSFF, &ff_effect) == -1)
+                       return -errno;
+       }
+
+       /* Play vibration*/
+       play.type = EV_FF;
+       play.code = ff_effect.id;
+       play.value = 1; /* 1 : PLAY, 0 : STOP */
+
+       if (write(fd, (const void*)&play, sizeof(play)) == -1)
+               return -errno;
+
+       /* register timer */
+       register_timer(length);
+
+       return 0;
+}
+
+static int ff_stop(int fd)
+{
+       struct input_event stop;
+       int r = 0;
+
+       if (fd < 0)
+               return -EINVAL;
+
+       /* Stop vibration */
+       stop.type = EV_FF;
+       stop.code = ff_effect.id;
+       stop.value = 0;
+
+       if (write(fd, (const void*)&stop, sizeof(stop)) == -1)
+               return -errno;
+
+       return 0;
+}
+
+/* START: Haptic Module APIs */
+static int get_device_count(int *count)
+{
+       if (count)
+               *count = 1;
+
+       return 0;
+}
+
+static int open_device(int device_index, int *device_handle)
+{
+       /* open ff driver */
+       if (ff_use_count == 0) {
+               ff_fd = open(ff_path, O_RDWR);
+               if (!ff_fd) {
+                       _E("Failed to open %s : %s", ff_path, strerror(errno));
+                       return -errno;
+               }
+       }
+
+       /* Increase handle count */
+       ff_use_count++;
+
+       if (device_handle)
+               *device_handle = DEFAULT_HAPTIC_HANDLE;
+
+       return 0;
+}
+
+static int close_device(int device_handle)
+{
+       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+               return -EINVAL;
+
+       if (ff_use_count == 0)
+               return -EPERM;
+
+       ff_stop(ff_fd);
+
+       /* Decrease handle count */
+       ff_use_count--;
+
+       /* close ff driver */
+       if (ff_use_count == 0) {
+               /* Initialize effect structure */
+               memset(&ff_effect, 0, sizeof(ff_effect));
+               close(ff_fd);
+               ff_fd = -1;
+       }
+
+       return 0;
+}
+
+static int vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle)
+{
+       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+               return -EINVAL;
+
+       return ff_play(ff_fd, duration, feedback);
+}
+
+static int vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle)
+{
+       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+               return -EINVAL;
+
+       /* temporary code */
+       return ff_play(ff_fd, 300, feedback);
+}
+
+static int stop_device(int device_handle)
+{
+       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+               return -EINVAL;
+
+       return ff_stop(ff_fd);
+}
+
+static int get_device_state(int device_index, int *effect_state)
+{
+       int status;
+
+       if (ff_effect.id != 0)
+               status = 1;
+       else
+               status = 0;
+
+       if (effect_state)
+               *effect_state = status;
+
+       return 0;
+}
+
+static int create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt)
+{
+       _E("Not support feature");
+       return -EACCES;
+}
+
+static int get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration)
+{
+       if (device_handle != DEFAULT_HAPTIC_HANDLE)
+               return -EINVAL;
+
+       _E("Not support feature");
+       return -EACCES;
+}
+
+static int convert_binary(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path)
+{
+       _E("Not support feature");
+       return -EACCES;
+}
+/* END: Haptic Module APIs */
+
+static const struct haptic_plugin_ops default_plugin = {
+       .get_device_count    = get_device_count,
+       .open_device         = open_device,
+       .close_device        = close_device,
+       .vibrate_monotone    = vibrate_monotone,
+       .vibrate_buffer      = vibrate_buffer,
+       .stop_device         = stop_device,
+       .get_device_state    = get_device_state,
+       .create_effect       = create_effect,
+       .get_buffer_duration = get_buffer_duration,
+       .convert_binary      = convert_binary,
+};
+
+static bool is_valid(void)
+{
+       int ret;
+
+       ret = ff_find_device(ff_path, sizeof(ff_path));
+
+       if (ret < 0)
+               return false;
+
+       return true;
+}
+
+static const struct haptic_plugin_ops *load(void)
+{
+       return &default_plugin;
+}
+
+static const struct haptic_ops std_ops = {
+       .is_valid = is_valid,
+       .load     = load,
+};
+
+HAPTIC_OPS_REGISTER(&std_ops)
diff --git a/src/led/ir.c b/src/led/ir.c
new file mode 100644 (file)
index 0000000..86f1767
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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 <device-node.h>
+
+#include "core/log.h"
+#include "core/edbus-handler.h"
+#include "core/devices.h"
+
+static DBusMessage *edbus_set_ir_command(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char *str;
+       int ret;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = device_set_property(DEVICE_TYPE_LED, PROP_LED_IR_COMMAND, (int)str);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "SetIrCommand",      "s",   "i", edbus_set_ir_command },
+       /* Add methods here */
+};
+
+static void ir_init(void *data)
+{
+       int ret;
+
+       /* init dbus interface */
+       ret = register_edbus_method(DEVICED_PATH_LED, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+}
+
+static const struct device_ops irled_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "irled",
+       .init     = ir_init,
+};
+
+DEVICE_OPS_REGISTER(&irled_device_ops)
diff --git a/src/led/led.xml b/src/led/led.xml
new file mode 100644 (file)
index 0000000..9b908df
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<config>
+       <label>led indicator</label>
+       <description>led indicator helps to give notification</description>
+       <led label="off">
+               <priority>0</priority>
+               <data on="0" off="0" color="FF000000"/>
+       </led>
+       <led label="low battery">
+               <priority>2</priority>
+               <data on="500" off="5000" color="FFFF0000"/>
+       </led>
+       <led label="charging">
+               <priority>2</priority>
+               <data on="0" off="0" color="FFFF0000"/>
+       </led>
+       <led label="fully charged">
+               <priority>2</priority>
+               <data on="0" off="0" color="FF00FF00"/>
+       </led>
+       <led label="charging error">
+               <priority>0</priority>
+               <data on="500" off="500" color="FFFF0000"/>
+       </led>
+       <led label="missed noti">
+               <priority>1</priority>
+               <data on="500" off="5000" color="FF0000FF"/>
+       </led>
+       <led label="voice recording">
+               <priority>1</priority>
+               <data on="500" off="500" color="FF0000FF"/>
+       </led>
+       <led label="power off">
+               <priority>0</priority>
+               <data on="0" off="0" color="FF0000FF" wave="on"/>
+       </led>
+       <led label="custom">
+               <priority>1</priority>
+               <data on="500" off="5000" color="FF0000FF"/>
+       </led>
+</config>
diff --git a/src/led/noti.c b/src/led/noti.c
new file mode 100644 (file)
index 0000000..cc17dae
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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 "core/log.h"
+#include "core/edbus-handler.h"
+
+#define METHOD_TORCH_NOTI_ON           "TorchNotiOn"
+#define METHOD_TORCH_NOTI_OFF          "TorchNotiOff"
+
+static int noti_h;
+
+int ongoing_show(void)
+{
+       int ret, ret_val;
+
+       if (noti_h > 0) {
+               _D("already ongoing noti show : handle(%d)", noti_h);
+               return 0;
+       }
+
+       ret_val = dbus_method_sync(POPUP_BUS_NAME,
+                       POPUP_PATH_LED,
+                       POPUP_INTERFACE_LED,
+                       METHOD_TORCH_NOTI_ON,
+                       NULL, NULL);
+
+       noti_h = ret_val;
+       _D("insert noti handle : %d", noti_h);
+       return (ret_val < 0) ? ret_val : 0;
+}
+
+int ongoing_clear(void)
+{
+       char str_h[32];
+       char *arr[1];
+       int ret, ret_val;
+
+       if (noti_h <= 0) {
+               _D("already ongoing noti clear");
+               return 0;
+       }
+
+       snprintf(str_h, sizeof(str_h), "%d", noti_h);
+       arr[0] = str_h;
+
+       ret_val = dbus_method_sync(POPUP_BUS_NAME,
+                       POPUP_PATH_LED,
+                       POPUP_INTERFACE_LED,
+                       METHOD_TORCH_NOTI_OFF,
+                       "i", arr);
+
+       _D("delete noti handle : %d", noti_h);
+       noti_h = 0;
+       return ret_val;
+}
diff --git a/src/led/pattern.c b/src/led/pattern.c
new file mode 100644 (file)
index 0000000..cee8b88
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <errno.h>
+#include <vconf.h>
+#include <device-node.h>
+
+#include "core/log.h"
+
+#define SAMPLE_INTERVAL        50
+#define ITERATION_INFINITE     255
+
+#define PTHREAD_SELF   (pthread_self())
+
+enum led_brt {
+       LED_OFF = 0,
+       LED_ON,
+};
+
+static struct led_pattern {
+       char *buffer;
+       int len;
+       int cnt;
+       int index;
+} pattern;
+
+static pthread_t tid;
+
+static int led_set_brt(enum led_brt brt)
+{
+       int ret, val;
+
+       ret = device_get_property(DEVICE_TYPE_LED, PROP_LED_MAX_BRIGHTNESS, &val);
+       if (ret < 0)
+               return ret;
+
+       if (brt != LED_OFF)
+               brt = val;
+
+       ret = device_set_property(DEVICE_TYPE_LED, PROP_LED_BRIGHTNESS, brt);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static void clean_up(void *arg)
+{
+       struct led_pattern *pt = (struct led_pattern*)arg;
+       int torch_status = 0;
+
+       _D("[%u] Clean up thread", PTHREAD_SELF);
+
+       /* Release memory after use */
+       if (pt->buffer) {
+               free(pt->buffer);
+               pt->buffer = NULL;
+       }
+
+       /* Get assistive light status */
+       if (vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TORCH_LIGHT, &torch_status) < 0)
+               _E("[%u] Failed to get VCONFKEY_SETAPPL_ACCESSIBILITY_TORCH_LIGHT value", PTHREAD_SELF);
+
+       /* Restore assistive light */
+       if (torch_status) {
+               _D("[%u] assistive light turns on", PTHREAD_SELF);
+               led_set_brt(LED_ON);
+       } else  /* For abnormal termination */
+               led_set_brt(LED_OFF);
+
+       tid = 0;
+}
+
+static void* play_cb(void *arg)
+{
+       struct led_pattern *pt = (struct led_pattern*)arg;
+       int val;
+
+       _D("[%u] Start thread", PTHREAD_SELF);
+       pthread_cleanup_push(clean_up, arg);
+
+       if (!pt->buffer)
+               goto error;
+
+       _D("[%u] index(%d), length(%d), repeat count(%d)", PTHREAD_SELF, pt->index, pt->len, pt->cnt);
+
+       /* Play LED accroding to buffer */
+       led_set_brt(LED_OFF);
+       while (pt->cnt) {
+               /* do not reset index to use exisiting value */
+               for ( ; pt->index < pt->len; pt->index++) {
+                       val = (int)(pt->buffer[pt->index] - '0');
+                       /* Verify buffer data */
+                       if (val & 0xFE)
+                               break;
+
+                       led_set_brt(val);
+
+                       /* Sleep time 50*999us = 49.950ms (Vibration unit 50ms) */
+                       usleep(SAMPLE_INTERVAL*999);
+               }
+
+               /* reset index */
+               pt->index = 0;
+
+               /* Decrease count when play with limit */
+               if (pt->cnt != ITERATION_INFINITE)
+                       pt->cnt--;
+       }
+
+       led_set_brt(LED_OFF);
+
+       /* Sleep 500ms before turning on assistive light */
+       usleep(500000);
+
+error:
+       pthread_cleanup_pop(1);
+
+       _D("[%u] End thread", PTHREAD_SELF);
+       pthread_exit((void*)0);
+}
+
+static int create_thread(struct led_pattern *pattern)
+{
+       int ret;
+
+       if (tid) {
+               _E("pthread already created");
+               return -EEXIST;
+       }
+
+       ret = pthread_create(&tid, NULL, play_cb, pattern);
+       if (ret != 0) {
+               _E("fail to create thread : %s", strerror(errno));
+               return -errno;
+       }
+
+       return 0;
+}
+
+static int cancel_thread(void)
+{
+       int ret;
+       void *retval;
+
+       if (!tid) {
+               _D("pthread not initialized");
+               return 0;
+       }
+
+       ret = pthread_cancel(tid);
+       if (ret != 0) {
+               _E("fail to cancel thread(%d) : %s", tid, strerror(errno));
+               return -errno;
+       }
+
+       ret = pthread_join(tid, &retval);
+       if (ret != 0) {
+               _E("fail to join thread(%d) : %s", tid, strerror(errno));
+               return -errno;
+       }
+
+       if (retval == PTHREAD_CANCELED)
+               _D("pthread canceled");
+       else
+               _D("pthread already finished");
+
+       return 0;
+}
+
+static int detach_thread(void)
+{
+       int ret;
+
+       if (!tid) {
+               _D("pthread not initialized");
+               return 0;
+       }
+
+       ret = pthread_detach(tid);
+       if (ret != 0) {
+               _E("fail to detach thread(%d) : %s", tid, strerror(errno));
+               return ret;
+       }
+
+       tid = 0;
+       return 0;
+}
+
+static int load_file(const char *path, char **buffer, int *len)
+{
+       FILE *fp;
+       char *buf = NULL;
+       int l;
+
+       if (!path || !buffer || !len) {
+               _E("invalid argument");
+               return -EINVAL;
+       }
+
+       /* Open file */
+       fp = fopen(path, "rb");
+       if (!fp) {
+               _E("fail to open file(%s) : %s", path, strerror(errno));
+               return -errno;
+       }
+
+       /* Get file length */
+       fseek(fp, 0, SEEK_END);
+       l = ftell(fp);
+       fseek(fp, 0, SEEK_SET);
+
+       if (l < 0)
+               goto error;
+
+       buf = malloc(l*sizeof(char));
+       if (!buf) {
+               _E("fail to allocate memory : %s", strerror(errno));
+               goto error;
+       }
+
+       /* Read file contents into buffer */
+       if (fread(buf, 1, l, fp) < l) {
+               _E("fail to read file data : %s", strerror(errno));
+               goto error;
+       }
+
+       /* Close file */
+       fclose(fp);
+
+       *buffer = buf;
+       *len = l;
+       return 0;
+
+error:
+       /* Close file */
+       fclose(fp);
+
+       /* Free unnecessary memory */
+       free(buf);
+       return -EPERM;
+}
+
+int play_pattern(const char *path, int cnt)
+{
+       int ret;
+
+       /* Check if thread already started */
+       ret = cancel_thread();
+       if (ret < 0) {
+               _E("fail to cancel thread");
+               return ret;
+       }
+
+       /* Load led file to buffer */
+       ret = load_file(path, &(pattern.buffer), &(pattern.len));
+       if (ret < 0) {
+               _E("fail to load file(%s)", path);
+               return ret;
+       }
+
+       /* Set the led data */
+       pattern.cnt = cnt;
+       pattern.index = 0;
+
+       /* Create and Execute thread */
+       ret = create_thread(&pattern);
+       if (ret < 0) {
+               _E("fail to create thread");
+               return ret;
+       }
+
+       return 0;
+}
+
+int stop_pattern(void)
+{
+       int ret;
+
+       ret = cancel_thread();
+       if (ret < 0) {
+               _E("fail to cancel thread");
+               return ret;
+       }
+
+       return 0;
+}
diff --git a/src/led/rgb.c b/src/led/rgb.c
new file mode 100644 (file)
index 0000000..be01dfc
--- /dev/null
@@ -0,0 +1,645 @@
+/*
+ * 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 <assert.h>
+#include <device-node.h>
+#include <Ecore.h>
+#include <vconf.h>
+
+#include "deviced/dd-led.h"
+#include "xml.h"
+#include "core/log.h"
+#include "core/common.h"
+#include "core/edbus-handler.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+#include "core/device-handler.h"
+#include "display/core.h"
+
+#define BOOT_ANIMATION_FINISHED                1
+
+#define LED_VALUE(high, low)           (((high)<<16)|((low)&0xFFFF))
+
+#define BG_COLOR               0x00000000
+#define GET_ALPHA(x)   (((x)>>24) & 0xFF)
+#define GET_RED(x)             (((x)>>16) & 0xFF)
+#define GET_GREEN(x)   (((x)>> 8) & 0xFF)
+#define GET_BLUE(x)            ((x) & 0xFF)
+#define COMBINE_RGB(r,g,b)     ((((r) & 0xFF) << 16) | (((g) & 0xFF) << 8) | ((b) & 0xFF))
+
+#define SET_WAVE_BIT   (0x6 << 24)
+#define DUMPMODE_WAITING_TIME    600000
+
+enum {
+       LED_CUSTOM_DUTY_ON = 1 << 0,    /* this enum doesn't blink on led */
+       LED_CUSTOM_DEFAULT = (LED_CUSTOM_DUTY_ON),
+};
+
+static bool charging_key;
+static bool lowbat_key;
+static bool charging_state;
+static bool lowbat_state;
+static bool full_state;
+static bool badbat_state;
+static bool ovp_state;
+static bool rgb_blocked = false;
+static bool rgb_dumpmode = false;
+static Ecore_Timer *dumpmode_timer = NULL;
+static enum state_t lcd_state = S_NORMAL;
+
+static int led_prop(int mode, int on, int off, unsigned int color)
+{
+       struct led_mode *led;
+
+       if (mode < 0 || mode > LED_MODE_MAX)
+               return -EINVAL;
+
+       led = find_led_data(mode);
+       if (!led) {
+               _E("no find data(%d)", mode);
+               return -EINVAL;
+       }
+
+       switch (mode) {
+       case LED_MISSED_NOTI:
+       case LED_VOICE_RECORDING:
+       case LED_CUSTOM:
+               if (on >= 0)
+                       led->data.on = on;
+               if (off >= 0)
+                       led->data.off = off;
+               if (color)
+                       led->data.color = color;
+               break;
+       default:
+               /* the others couldn't change any property */
+               break;
+       }
+
+       _D("changed mode(%d) : on(%d), off(%d), color(%x)",
+                       mode, led->data.on, led->data.off, led->data.color);
+       return 0;
+}
+
+static int led_mode(int mode, bool enable)
+{
+       struct led_mode *led;
+
+       if (mode < 0 || mode > LED_MODE_MAX)
+               return -EINVAL;
+
+       led = find_led_data(mode);
+       if (!led) {
+               _E("no find data(%d)", mode);
+               return -EINVAL;
+       }
+
+       led->state = enable;
+       return 0;
+}
+
+static int get_led_mode_state(int mode, bool *state)
+{
+       struct led_mode *led;
+
+       if (mode < 0 || mode > LED_MODE_MAX)
+               return -EINVAL;
+
+       led = find_led_data(mode);
+       if (!led) {
+               _E("no find data(%d)", mode);
+               return -EINVAL;
+       }
+
+       if (led->state)
+               *state = true;
+       else
+               *state = false;
+       return 0;
+}
+
+static unsigned int led_blend(unsigned int before)
+{
+       unsigned int alpha, alpha_inv;
+       unsigned char red, grn, blu;
+
+       alpha = GET_ALPHA(before) + 1;
+       alpha_inv = 256 - alpha;
+
+       red = ((alpha * GET_RED(before) + alpha_inv * GET_RED(BG_COLOR)) >> 8);
+       grn = ((alpha * GET_GREEN(before) + alpha_inv * GET_GREEN(BG_COLOR)) >> 8);
+       blu = ((alpha * GET_BLUE(before) + alpha_inv * GET_BLUE(BG_COLOR)) >> 8);
+       return COMBINE_RGB(red, grn, blu);
+}
+
+static int led_mode_to_device(struct led_mode *led)
+{
+       int val, color;
+
+       if (led == NULL)
+               return 0;
+
+       if (rgb_dumpmode)
+               return 0;
+
+       if (rgb_blocked && led->mode != LED_POWER_OFF && led->mode != LED_OFF)
+               return 0;
+
+       val = LED_VALUE(led->data.on, led->data.off);
+       color = led_blend(led->data.color);
+
+       /* if wave status is ON, color should be combined with WAVE_BIT */
+       if (led->data.wave)
+               color |= SET_WAVE_BIT;
+
+       device_set_property(DEVICE_TYPE_LED, PROP_LED_COLOR, color);
+       device_set_property(DEVICE_TYPE_LED, PROP_LED_BLINK, val);
+       return 0;
+}
+
+static int led_display_changed_cb(void *data)
+{
+       struct led_mode *led = NULL;
+       int val;
+
+       /* store last display condition */
+       lcd_state = (enum state_t)data;
+
+       /* charging error state */
+       if (badbat_state)
+               return 0;
+
+       if (lcd_state == S_LCDOFF)
+               led = get_valid_led_data();
+       else if (lcd_state == S_NORMAL || lcd_state == S_LCDDIM)
+               led = find_led_data(LED_OFF);
+
+       return led_mode_to_device(led);
+}
+
+static int led_charging_changed_cb(void *data)
+{
+       int v = (int)data;
+
+       if (v == CHARGER_CHARGING)
+               charging_state = true;
+       else
+               charging_state = false;
+
+       if (charging_key)
+               led_mode(LED_CHARGING, charging_state);
+
+       return 0;
+}
+
+static int led_lowbat_changed_cb(void *data)
+{
+       lowbat_state = (bool)data;
+
+       if (lowbat_key)
+               led_mode(LED_LOW_BATTERY, lowbat_state);
+
+       return 0;
+}
+
+static int led_fullbat_changed_cb(void *data)
+{
+       full_state = (bool)data;
+
+       if (charging_key)
+               led_mode(LED_FULLY_CHARGED, full_state);
+
+       return 0;
+}
+
+static int led_battery_health_changed_cb(void *data)
+{
+       struct led_mode *led;
+       bool cur;
+
+       cur = ((int)data == HEALTH_BAD) ? true : false;
+
+       /* do not enter below scenario in case of same state */
+       if (cur == badbat_state)
+               return 0;
+
+       badbat_state = cur;
+
+       /* set charging error mode */
+       led_mode(LED_CHARGING_ERROR, badbat_state);
+
+       /* update the led state */
+       if (badbat_state) {     /* charging error */
+               led = find_led_data(LED_CHARGING_ERROR);
+               led_mode_to_device(led);
+       } else {
+               led = find_led_data(LED_OFF);
+               led_mode_to_device(led);
+               if (lcd_state == S_LCDOFF)
+                       led_display_changed_cb((void*)S_LCDOFF);
+       }
+
+       return 0;
+}
+
+static int led_battery_ovp_changed_cb(void *data)
+{
+       int cur = (int)data;
+
+       /* do not enter below flow in case of same state */
+       if (cur == ovp_state)
+               return 0;
+
+       ovp_state = cur;
+
+       if (ovp_state == OVP_NORMAL && lcd_state == S_LCDOFF)
+               led_display_changed_cb((void*)S_LCDOFF);
+
+       return 0;
+}
+
+static void led_poweron_changed_cb(keynode_t *key, void *data)
+{
+       int state;
+       struct led_mode *led;
+
+       state = vconf_keynode_get_int(key);
+
+       if (state != BOOT_ANIMATION_FINISHED)
+               return;
+
+       led = find_led_data(LED_OFF);
+       led_mode_to_device(led);
+
+       vconf_ignore_key_changed(VCONFKEY_BOOT_ANIMATION_FINISHED,
+                       led_poweron_changed_cb);
+}
+
+static void led_poweroff_changed_cb(keynode_t *key, void *data)
+{
+       int state;
+       struct led_mode *led;
+
+       state = vconf_keynode_get_int(key);
+
+       if (state == VCONFKEY_SYSMAN_POWER_OFF_NONE ||
+               state == VCONFKEY_SYSMAN_POWER_OFF_POPUP)
+               return;
+
+       led = find_led_data(LED_POWER_OFF);
+       led_mode_to_device(led);
+
+       vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
+                       led_poweroff_changed_cb);
+}
+
+static void led_vconf_charging_cb(keynode_t *key, void *data)
+{
+       charging_key = vconf_keynode_get_bool(key);
+
+       if (charging_key) {
+               led_mode(LED_CHARGING, charging_state);
+               led_mode(LED_FULLY_CHARGED, full_state);
+       } else {
+               led_mode(LED_CHARGING, false);
+               led_mode(LED_FULLY_CHARGED, false);
+       }
+}
+
+static void led_vconf_lowbat_cb(keynode_t *key, void *data)
+{
+       lowbat_key = vconf_keynode_get_bool(key);
+
+       if (lowbat_key)
+               led_mode(LED_LOW_BATTERY, lowbat_state);
+       else
+               led_mode(LED_LOW_BATTERY, false);
+}
+
+static void led_vconf_blocking_cb(keynode_t *key, void *data)
+{
+       rgb_blocked = vconf_keynode_get_bool(key);
+       _I("rgbled blocking mode %s", (rgb_blocked ? "started" : "stopped"));
+}
+
+static DBusMessage *edbus_playcustom(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int cmd, val, ret;
+       int on, off;
+       unsigned int color, flags;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_INT32, &on,
+                       DBUS_TYPE_INT32, &off,
+                       DBUS_TYPE_UINT32, &color,
+                       DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       /* not to play blink, on and off value should be zero */
+       if (!(flags & LED_CUSTOM_DUTY_ON))
+               on = off = 0;
+
+       /* set new value in case of LED_CUSTOM value */
+       ret = led_mode(LED_CUSTOM, true);
+       ret = led_prop(LED_CUSTOM, on, off, color);
+
+       _D("play custom %d, %d, %x, %d", on, off, color, ret);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_stopcustom(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+
+       /* reset default value */
+       ret = led_mode(LED_CUSTOM, false);
+       ret = led_prop(LED_CUSTOM, 500, 5000, 255);
+
+       _D("stop custom %d", ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_set_mode(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       unsigned int color;
+       int mode, val, on, off, ret;
+       struct led_mode *led;
+       bool mode_enabled = false;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_INT32, &mode,
+                       DBUS_TYPE_INT32, &val,
+                       DBUS_TYPE_INT32, &on,
+                       DBUS_TYPE_INT32, &off,
+                       DBUS_TYPE_UINT32, &color, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = get_led_mode_state(mode, &mode_enabled);
+       if (ret) {
+               _I("failed to get led mode state : %d", ret);
+               goto error;
+       }
+
+       ret = led_mode(mode, val);
+       ret = led_prop(mode, on, off, color);
+
+       /* Exception case :
+          in case of display off condition,
+          who requests missed noti event, it should change the device value */
+       if (mode == LED_MISSED_NOTI && lcd_state == S_LCDOFF) {
+               if (!mode_enabled || on == 0) {
+                       /* turn off previous setting */
+                       led = find_led_data(LED_OFF);
+                       led_mode_to_device(led);
+                       /* update the led state */
+                       led_display_changed_cb((void*)S_LCDOFF);
+               }
+       }
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static void set_dumpmode(bool on)
+{
+       struct led_mode *led;
+       int val, color;
+
+       if (on) {
+               val = LED_VALUE(200, 100);
+               color = led_blend(0xFFFF0000);
+               device_set_property(DEVICE_TYPE_LED, PROP_LED_COLOR, color);
+               device_set_property(DEVICE_TYPE_LED, PROP_LED_BLINK, val);
+               rgb_dumpmode = true;
+               _I("dump_mode on");
+       } else {
+               if (dumpmode_timer) {
+                       ecore_timer_del(dumpmode_timer);
+                       dumpmode_timer = NULL;
+               }
+               if (rgb_dumpmode)
+                       rgb_dumpmode = false;
+               else
+                       return;
+               led = find_led_data(LED_OFF);
+               led_mode_to_device(led);
+               _I("dump_mode off");
+       }
+}
+
+static void dumpmode_timer_cb(void *data)
+{
+       set_dumpmode(false);
+}
+
+static DBusMessage *edbus_dump_mode(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret = 0;
+       char *on;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &on,
+                       DBUS_TYPE_INVALID);
+
+       if (!ret) {
+               _E("fail to get dumpmode state %d", ret);
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (!strcmp(on, "on")) {
+               set_dumpmode(true);
+               dumpmode_timer = ecore_timer_add(DUMPMODE_WAITING_TIME,
+                               (Ecore_Task_Cb)dumpmode_timer_cb, NULL);
+       } else if (!strcmp(on, "off")) {
+               set_dumpmode(false);
+       } else
+               ret = -EINVAL;
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *edbus_print_mode(E_DBus_Object *obj, DBusMessage *msg)
+{
+       print_all_data();
+       return dbus_message_new_method_return(msg);
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "playcustom",     "iiuu",  "i",  edbus_playcustom },
+       { "stopcustom",     NULL,    "i",  edbus_stopcustom },
+       { "SetMode",        "iiiiu", "i",  edbus_set_mode },
+       { "PrintMode",      NULL,    NULL, edbus_print_mode },
+       { "Dumpmode",       "s",     "i",  edbus_dump_mode },
+       /* Add methods here */
+};
+
+static void rgb_init(void *data)
+{
+       int ta_connected, boot;
+       int ret;
+       struct led_mode *led;
+
+       /* init dbus interface */
+       ret = register_edbus_method(DEVICED_PATH_LED, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       /* get led mode data from xml */
+       get_led_data();
+
+       /* verify booting or restart */
+       ret = vconf_get_int(VCONFKEY_BOOT_ANIMATION_FINISHED, &boot);
+       if (ret != 0)
+               boot = 0;       /* set booting state */
+
+       /* in case of restart */
+       if (boot)
+               goto next;
+
+       /* when booting, led indicator will be work */
+       led = find_led_data(LED_POWER_OFF);
+       led_mode_to_device(led);
+       vconf_notify_key_changed(VCONFKEY_BOOT_ANIMATION_FINISHED,
+                       led_poweron_changed_cb, NULL);
+
+next:
+       /* register power off callback */
+       vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
+                       led_poweroff_changed_cb, NULL);
+
+       /* register notifier for each event */
+       register_notifier(DEVICE_NOTIFIER_LCD, led_display_changed_cb);
+       register_notifier(DEVICE_NOTIFIER_BATTERY_CHARGING, led_charging_changed_cb);
+       register_notifier(DEVICE_NOTIFIER_LOWBAT, led_lowbat_changed_cb);
+       register_notifier(DEVICE_NOTIFIER_FULLBAT, led_fullbat_changed_cb);
+       register_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, led_battery_health_changed_cb);
+       register_notifier(DEVICE_NOTIFIER_BATTERY_OVP, led_battery_ovp_changed_cb);
+
+       /* initialize vconf value */
+       vconf_get_bool(VCONFKEY_SETAPPL_LED_INDICATOR_CHARGING, (int*)&charging_key);
+       vconf_get_bool(VCONFKEY_SETAPPL_LED_INDICATOR_LOW_BATT, (int*)&lowbat_key);
+
+       /* initialize led indicator blocking value */
+       vconf_get_bool(VCONFKEY_SETAPPL_BLOCKINGMODE_LED_INDICATOR, (int*)&rgb_blocked);
+
+       /* register vconf callback */
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_LED_INDICATOR_CHARGING,
+                       led_vconf_charging_cb, NULL);
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_LED_INDICATOR_LOW_BATT,
+                       led_vconf_lowbat_cb, NULL);
+
+       /* register led indicator blocking vconf callback */
+       vconf_notify_key_changed(VCONFKEY_SETAPPL_BLOCKINGMODE_LED_INDICATOR,
+                       led_vconf_blocking_cb, NULL);
+
+       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_CHARGE_NOW, &ta_connected);
+       if (!ret && ta_connected)
+               led_charging_changed_cb((void*)ta_connected);
+}
+
+static void rgb_exit(void *data)
+{
+       struct led_mode *led;
+
+       /* unregister vconf callback */
+       vconf_ignore_key_changed(VCONFKEY_SETAPPL_LED_INDICATOR_CHARGING,
+                       led_vconf_charging_cb);
+       vconf_ignore_key_changed(VCONFKEY_SETAPPL_LED_INDICATOR_LOW_BATT,
+                       led_vconf_lowbat_cb);
+
+       /* unregister led indicatore blocking vconf callback */
+       vconf_ignore_key_changed(VCONFKEY_SETAPPL_BLOCKINGMODE_LED_INDICATOR,
+                       led_vconf_blocking_cb);
+
+       /* unregister notifier for each event */
+       unregister_notifier(DEVICE_NOTIFIER_LCD, led_display_changed_cb);
+       unregister_notifier(DEVICE_NOTIFIER_BATTERY_CHARGING, led_charging_changed_cb);
+       unregister_notifier(DEVICE_NOTIFIER_LOWBAT, led_lowbat_changed_cb);
+       unregister_notifier(DEVICE_NOTIFIER_FULLBAT, led_fullbat_changed_cb);
+       unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, led_battery_health_changed_cb);
+       unregister_notifier(DEVICE_NOTIFIER_BATTERY_OVP, led_battery_ovp_changed_cb);
+
+       set_dumpmode(false);
+       /* turn off led */
+       led = find_led_data(LED_OFF);
+       led_mode_to_device(led);
+
+       /* release led mode data */
+       release_led_data();
+}
+
+static int rgb_start(void)
+{
+       _I("rgbled device will be started");
+       rgb_blocked = false;
+       return 0;
+}
+
+static int rgb_stop(void)
+{
+       _I("rgbled device will be stopped");
+       rgb_blocked = true;
+       return 0;
+}
+
+static const struct device_ops rgbled_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "rgbled",
+       .init     = rgb_init,
+       .exit     = rgb_exit,
+       .start    = rgb_start,
+       .stop     = rgb_stop,
+};
+
+DEVICE_OPS_REGISTER(&rgbled_device_ops)
diff --git a/src/led/torch.c b/src/led/torch.c
new file mode 100644 (file)
index 0000000..fbd4ece
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * 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 <assert.h>
+#include <vconf.h>
+#include <device-node.h>
+
+#include "core/log.h"
+#include "core/edbus-handler.h"
+#include "core/devices.h"
+#include "torch.h"
+
+static int camera_status;
+
+static DBusMessage *edbus_get_brightness(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+
+       ret = device_get_property(DEVICE_TYPE_LED, PROP_LED_BRIGHTNESS, &val);
+       if (ret >= 0)
+               ret = val;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_get_max_brightness(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+
+       ret = device_get_property(DEVICE_TYPE_LED, PROP_LED_MAX_BRIGHTNESS, &val);
+       if (ret >= 0)
+               ret = val;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_set_brightness(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, enable, ret;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_INT32, &val,
+                       DBUS_TYPE_INT32, &enable, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = device_set_property(DEVICE_TYPE_LED, PROP_LED_BRIGHTNESS, val);
+       if (ret < 0)
+               goto error;
+
+       /* if enable is ON, noti will be show or hide */
+       if (enable) {
+               if (val)
+                       ongoing_show();
+               else
+                       ongoing_clear();
+       }
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_get_camera_brightness(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+
+       ret = device_get_property(DEVICE_TYPE_LED, PROP_LED_FLASH_BRIGHTNESS, &val);
+       if (ret >= 0)
+               ret = val;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_set_camera_brightness(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, enable, ret;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = device_set_property(DEVICE_TYPE_LED, PROP_LED_FLASH_BRIGHTNESS, val);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_play_pattern(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char *path;
+       int cnt, ret;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_STRING, &path,
+                       DBUS_TYPE_INT32, &cnt, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       /* check camera status
+          Do not play led notification during the video recording */
+       if (camera_status == VCONFKEY_CAMERA_STATE_RECORDING) {
+               _D("Camera is recording (status : %d)", camera_status);
+               ret = 0;
+               goto exit;
+       }
+
+       /* TODO: Now we passed led file path from other module.
+                But led file is not a common file structure,
+                        so we should change to be passed vibration pattern path
+                        then it converts to led data internally */
+       ret = play_pattern(path, cnt);
+
+exit:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_stop_pattern(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = stop_pattern();
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static void camera_status_cb(keynode_t *key, void *data)
+{
+       camera_status = vconf_keynode_get_int(key);
+
+       _D("recording status changed!! new status => %d", camera_status);
+
+       if (camera_status != VCONFKEY_CAMERA_STATE_RECORDING)
+               return;
+
+       /* If camera state is recording, stop to play ledplayer */
+       stop_pattern();
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "GetBrightness",    NULL,   "i", edbus_get_brightness },
+       { "GetMaxBrightness", NULL,   "i", edbus_get_max_brightness },
+       { "SetBrightness",    "ii",   "i", edbus_set_brightness },
+       { "GetCameraBrightness",    NULL,   "i", edbus_get_camera_brightness },
+       { "SetCameraBrightness",     "i",   "i", edbus_set_camera_brightness },
+       { "PlayPattern",      "si",   "i", edbus_play_pattern },
+       { "StopPattern",      NULL,   "i", edbus_stop_pattern },
+       /* Add methods here */
+};
+
+static void torch_init(void *data)
+{
+       int ret;
+
+       /* init dbus interface */
+       ret = register_edbus_method(DEVICED_PATH_LED, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       /* Get camera status */
+       if (vconf_get_int(VCONFKEY_CAMERA_STATE, &camera_status) < 0)
+               _E("Failed to get VCONFKEY_CAMERA_STATE value");
+
+       /* add watch for status value */
+       vconf_notify_key_changed(VCONFKEY_CAMERA_STATE, camera_status_cb, NULL);
+}
+
+static void torch_exit(void *data)
+{
+       /* Release vconf callback */
+       vconf_ignore_key_changed(VCONFKEY_CAMERA_STATE, camera_status_cb);
+}
+
+static const struct device_ops torchled_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "torchled",
+       .init     = torch_init,
+       .exit     = torch_exit,
+};
+
+DEVICE_OPS_REGISTER(&torchled_device_ops)
diff --git a/src/led/torch.h b/src/led/torch.h
new file mode 100644 (file)
index 0000000..8a8a8d3
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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 __TORCH_H__
+#define __TORCH_H__
+
+int ongoing_show(void);
+int ongoing_clear(void);
+
+int play_pattern(const char *path, int cnt);
+int stop_pattern(void);
+
+#endif
diff --git a/src/led/xml.c b/src/led/xml.c
new file mode 100644 (file)
index 0000000..66a3b8d
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * 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 <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+#include <libxml/parser.h>
+
+#include "deviced/dd-led.h"
+#include "xml.h"
+#include "core/log.h"
+#include "core/list.h"
+
+#ifndef DATADIR
+#define DATADIR "/usr/share/deviced"
+#endif
+
+#define LED_XML                DATADIR"/led.xml"
+#define LED_STR                "led"
+
+static const char* led_str[] = {
+       [LED_OFF] = "off",
+       [LED_LOW_BATTERY] = "low battery",
+       [LED_CHARGING] = "charging",
+       [LED_FULLY_CHARGED] = "fully charged",
+       [LED_CHARGING_ERROR] = "charging error",
+       [LED_MISSED_NOTI] = "missed noti",
+       [LED_VOICE_RECORDING] = "voice recording",
+       [LED_POWER_OFF] = "power off",
+       [LED_CUSTOM] = "custom",
+};
+
+static dd_list *led_head;
+
+static xmlDocPtr xml_open(const char *xml)
+{
+       xmlDocPtr doc;
+
+       doc = xmlReadFile(xml, NULL, 0);
+       if (doc == NULL) {
+               _E("xmlReadFile fail");
+               return NULL;
+       }
+
+       return doc;
+}
+
+static void xml_close(xmlDocPtr doc)
+{
+       xmlFreeDoc(doc);
+}
+
+static xmlNodePtr xml_find(xmlDocPtr doc, const xmlChar* expr)
+{
+       xmlNodePtr root;
+       xmlNodePtr cur;
+       xmlChar *key;
+
+       assert(doc);
+       assert(expr);
+
+       root = xmlDocGetRootElement(doc);
+       if (root == NULL) {
+               _E("xmlDocGetRootElement fail");
+               return NULL;
+       }
+
+       for (cur = root->children; cur != NULL; cur = cur->next) {
+               if (xmlStrcmp(cur->name, (const xmlChar*)LED_STR))
+                       continue;
+
+               key = xmlGetProp(cur, (const xmlChar*)"label");
+               if (key && !xmlStrcmp(key, expr)) {
+                       _D("%s", key);
+                       xmlFree(key);
+                       return cur;
+               }
+       }
+
+       return NULL;
+}
+
+static struct led_mode *xml_parse(xmlDocPtr doc, xmlNodePtr cur)
+{
+       xmlNodePtr node;
+       xmlNodePtr attr;
+       struct led_mode *led;
+       xmlChar *key;
+       int i = 0;
+
+       assert(doc);
+       assert(cur);
+
+       led = (struct led_mode*)malloc(sizeof(struct led_mode));
+       if (led == NULL) {
+               _E("out of memory");
+               return NULL;
+       }
+
+       for (node = cur->children; node != NULL; node = node->next) {
+               if (node->type != XML_ELEMENT_NODE)
+                       continue;
+
+               if (!xmlStrcmp(node->name, "priority")) {
+                       key = xmlNodeListGetString(doc, node->children, 1);
+                       if (!key)
+                               continue;
+                       led->data.priority = atoi(key);
+                       xmlFree(key);
+               } else if (!xmlStrcmp(node->name, "data")) {
+                       key = xmlGetProp(node, (const xmlChar*)"on");
+                       if (!key)
+                               continue;
+                       led->data.on = atoi(key);
+                       xmlFree(key);
+
+                       key = xmlGetProp(node, (const xmlChar*)"off");
+                       if (!key)
+                               continue;
+                       led->data.off = atoi(key);
+                       xmlFree(key);
+
+                       key = xmlGetProp(node, (const xmlChar*)"color");
+                       if (!key)
+                               continue;
+                       led->data.color = (unsigned int)strtoul(key, NULL, 16);
+                       xmlFree(key);
+
+                       key = xmlGetProp(node, (const xmlChar*)"wave");
+                       if (!key || xmlStrcmp(key, "on"))
+                               led->data.wave = false;
+                       else
+                               led->data.wave = true;
+                       xmlFree(key);
+               }
+       }
+
+       _D("priority : %d, on : %d, off : %d, color : %x, wave : %d",
+                       led->data.priority, led->data.on, led->data.off,
+                       led->data.color, led->data.wave);
+       return led;
+}
+
+int get_led_data(void)
+{
+       xmlDocPtr doc;
+       xmlNodePtr cur;
+       struct led_mode *led;
+       int i;
+       int r;
+
+       doc = xml_open(LED_XML);
+       if (doc == NULL) {
+               _E("xml_open(%s) fail", LED_XML);
+               errno = EPERM;
+               return -1;
+       }
+
+       for (i = 0; i < LED_MODE_MAX; ++i) {
+               cur = xml_find(doc, (const xmlChar*)led_str[i]);
+               if (cur == NULL) {
+                       _E("xml_find(%s) fail", led_str[i]);
+                       break;
+               }
+
+               led = xml_parse(doc, cur);
+               if (led == NULL) {
+                       _E("xml_parse fail");
+                       break;
+               }
+
+               led->mode = i;
+               led->state = 0;
+               DD_LIST_APPEND(led_head, led);
+       }
+
+       xml_close(doc);
+       return 0;
+}
+
+void release_led_data(void)
+{
+       dd_list *l;
+       struct led_mode *node;
+
+       DD_LIST_FOREACH(led_head, l, node) {
+               _D("node name : %d", node->mode);
+               DD_LIST_REMOVE(led_head, node);         
+               free(node);
+       }
+}
+
+struct led_mode *find_led_data(int mode)
+{
+       dd_list *l;
+       struct led_mode *node;
+
+       DD_LIST_FOREACH(led_head, l, node) {
+               if (node->mode == mode)
+                       return node;
+       }
+
+       return NULL;
+}
+
+struct led_mode *get_valid_led_data(void)
+{
+       dd_list *l;
+       struct led_mode *node;
+       struct led_mode *cur = NULL;
+       int pr = 2;
+
+       DD_LIST_FOREACH(led_head, l, node) {
+               if (!node->state)
+                       continue;
+               if (node->data.priority <= pr) {
+                       pr = node->data.priority;
+                       cur = node;
+               }
+       }
+
+       return cur;
+}
+
+void print_all_data(void)
+{
+       dd_list *l;
+       struct led_mode *node;
+
+       _D("Mode State priority   on  off    color wave");
+       DD_LIST_FOREACH(led_head, l, node) {
+               _D("%4d %5d %8d %4d %4d %x %4d",
+                               node->mode, node->state, node->data.priority,
+                               node->data.on, node->data.off, node->data.color, node->data.wave);
+       }
+}
diff --git a/src/led/xml.h b/src/led/xml.h
new file mode 100644 (file)
index 0000000..a85375b
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * deviced
+ *
+ * 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 __XML_H__
+#define __XML_H__
+
+struct led_mode {
+       int mode;
+       int state;
+       struct led_data {
+               int priority;
+               int on;
+               int off;
+               unsigned int color;
+               int wave;
+       } data;
+};
+
+int get_led_data(void);
+void release_led_data(void);
+struct led_mode *find_led_data(int mode);
+struct led_mode *get_valid_led_data(void);
+void print_all_data(void);
+
+#endif
diff --git a/src/libdeviced/CMakeLists.txt b/src/libdeviced/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..fc6a787
--- /dev/null
@@ -0,0 +1,39 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(libdeviced C)
+
+SET(LIBDEVICED_SRCS
+       battery.c
+       control.c
+       display.c
+       haptic.c
+       led.c
+       mmc.c
+       storage.c
+       usbhost.c
+       deviced-conf.c
+       deviced-noti.c
+       deviced-util.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/deviced ${CMAKE_SOURCE_DIR}/src/shared)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(libpkgs REQUIRED
+       vconf
+       dlog
+       dbus-1
+       edbus)
+
+FOREACH(flag ${libpkgs_CFLAGS})
+       SET(EXTRA_LIB_CFLAGS "${EXTRA_LIB_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+# libdeviced
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${LIBDEVICED_SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${libpkgs_LDFLAGS} shared)
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
+# CMake Policy (CMP0002)
+# The logical name of executable and library targes
+# does not have to correspond to the physical file name built.
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES OUTPUT_NAME deviced)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib COMPONENT RuntimeLibraries)
diff --git a/src/libdeviced/battery.c b/src/libdeviced/battery.c
new file mode 100644 (file)
index 0000000..8606ac6
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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 "log.h"
+#include "dbus.h"
+#include "common.h"
+
+#define METHOD_GET_PERCENT             "GetPercent"
+#define METHOD_GET_PERCENT_RAW "GetPercentRaw"
+#define METHOD_IS_FULL                 "IsFull"
+#define METHOD_GET_HEALTH              "GetHealth"
+
+API int battery_get_percent(void)
+{
+       return dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_BATTERY, DEVICED_INTERFACE_BATTERY,
+                       METHOD_GET_PERCENT, NULL, NULL);
+}
+
+API int battery_get_percent_raw(void)
+{
+       return dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_BATTERY, DEVICED_INTERFACE_BATTERY,
+                       METHOD_GET_PERCENT_RAW, NULL, NULL);
+}
+
+API int battery_is_full(void)
+{
+       return dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_BATTERY, DEVICED_INTERFACE_BATTERY,
+                       METHOD_IS_FULL, NULL, NULL);
+}
+
+API int battery_get_health(void)
+{
+       return dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_BATTERY, DEVICED_INTERFACE_BATTERY,
+                       METHOD_GET_HEALTH, NULL, NULL);
+}
diff --git a/src/libdeviced/control.c b/src/libdeviced/control.c
new file mode 100644 (file)
index 0000000..bcea37b
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * 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 "log.h"
+#include "dbus.h"
+#include "common.h"
+#include "dd-control.h"
+
+#define CONTROL_HANDLER_NAME           "control"
+#define CONTROL_GETTER_NAME                    "getcontrol"
+
+static int deviced_control_common(int device, bool enable)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *pa[5];
+       int ret, val;
+       char buf_pid[6];
+       char buf_dev[3];
+       char buf_enable[2];
+
+       snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
+       snprintf(buf_dev, sizeof(buf_dev), "%d", device);
+       snprintf(buf_enable, sizeof(buf_enable), "%d", enable);
+
+       pa[0] = CONTROL_HANDLER_NAME;
+       pa[1] = "3";
+       pa[2] = buf_pid;
+       pa[3] = buf_dev;
+       pa[4] = buf_enable;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       pa[0], "sisss", pa);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _D("%s-%s : %d", DEVICED_INTERFACE_SYSNOTI, pa[0], val);
+       return val;
+}
+
+static int deviced_get_control(int device, void *data)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *pa[4];
+       int ret, val;
+       char buf_pid[6];
+       char buf_dev[3];
+
+       snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
+       snprintf(buf_dev, sizeof(buf_dev), "%d", device);
+
+       pa[0] = CONTROL_GETTER_NAME;
+       pa[1] = "2";
+       pa[2] = buf_pid;
+       pa[3] = buf_dev;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       pa[0], "siss", pa);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _D("%s-%s : %d", DEVICED_INTERFACE_SYSNOTI, pa[0], val);
+       return val;
+}
+
+
+/*
+ * example of control api
+ * API int deviced_display_control(bool enable)
+ * {
+ *     return deviced_control_common(DEVICE_CONTROL_DISPLAY, enable);
+ * }
+ */
+
+API int deviced_mmc_control(bool enable)
+{
+       return deviced_control_common(DEVICE_CONTROL_MMC, enable);
+}
+
+API int deviced_usb_control(bool enable)
+{
+       return deviced_control_common(DEVICE_CONTROL_USBCLIENT, enable);
+}
+
+API int deviced_get_usb_control(void)
+{
+       return deviced_get_control(DEVICE_CONTROL_USBCLIENT, NULL);
+}
+
+API int deviced_rgbled_control(bool enable)
+{
+       return deviced_control_common(DEVICE_CONTROL_RGBLED, enable);
+}
diff --git a/src/libdeviced/deviced-conf.c b/src/libdeviced/deviced-conf.c
new file mode 100755 (executable)
index 0000000..a00e233
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <errno.h>
+
+#include "log.h"
+#include "deviced-priv.h"
+#include "dd-deviced.h"
+#include "dbus.h"
+#include "score-defines.h"
+
+#define PERMANENT_DIR          "/tmp/permanent"
+#define VIP_DIR                        "/tmp/vip"
+
+#define OOMADJ_SET             "oomadj_set"
+#define PROCESS_GROUP_SET      "process_group_set"
+#define PROCESS_VIP            "process_vip"
+#define PROCESS_PERMANENT      "process_permanent"
+
+enum mp_entry_type {
+       MP_VIP,
+       MP_PERMANENT,
+       MP_NONE
+};
+
+int util_oomadj_set(int pid, int oomadj_val)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *pa[4];
+       char buf1[SYSTEM_NOTI_MAXARG];
+       char buf2[SYSTEM_NOTI_MAXARG];
+       int ret, val;
+
+       snprintf(buf1, sizeof(buf1), "%d", pid);
+       snprintf(buf2, sizeof(buf2), "%d", oomadj_val);
+
+       pa[0] = OOMADJ_SET;
+       pa[1] = "2";
+       pa[2] = buf1;
+       pa[3] = buf2;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_PROCESS, DEVICED_INTERFACE_PROCESS,
+                       pa[0], "siss", pa);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _D("%s-%s : %d", DEVICED_INTERFACE_PROCESS, pa[0], val);
+       return val;
+}
+
+static int util_process_group_set(char* name, int pid)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *pa[4];
+       char buf[SYSTEM_NOTI_MAXARG];
+       int ret, val;
+
+       if (strncmp(PROCESS_VIP, name, strlen(name)) != 0 &&
+           strncmp(PROCESS_PERMANENT, name, strlen(name)) != 0) {
+               _E("fail to insert at %s group", name);
+               return -1;
+       }
+
+       snprintf(buf, sizeof(buf), "%d", pid);
+       _D("pid(%d) is inserted at vip", pid);
+
+       pa[0] = PROCESS_GROUP_SET;
+       pa[1] = "2";
+       pa[2] = buf;
+       pa[3] = name;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_PROCESS, DEVICED_INTERFACE_PROCESS,
+                       pa[0], "siss", pa);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _D("%s-%s : %d", DEVICED_INTERFACE_PROCESS, pa[0], val);
+       return val;
+}
+
+API int deviced_conf_set_mempolicy_bypid(int pid, enum mem_policy mempol)
+{
+       if (pid < 1)
+               return -1;
+
+       int oomadj_val = 0;
+
+       switch (mempol) {
+       case OOM_LIKELY:
+               oomadj_val = OOMADJ_BACKGRD_UNLOCKED;
+               break;
+       case OOM_IGNORE:
+               oomadj_val = OOMADJ_SU;
+               break;
+       default:
+               return -1;
+       }
+
+       return util_oomadj_set(pid, oomadj_val);
+}
+
+API int deviced_conf_set_mempolicy(enum mem_policy mempol)
+{
+       return deviced_conf_set_mempolicy_bypid(getpid(), mempol);
+}
+
+static int already_permanent(int pid)
+{
+       char buf[BUFF_MAX];
+
+       snprintf(buf, BUFF_MAX, "%s/%d", PERMANENT_DIR, pid);
+
+       if (access(buf, R_OK) == 0) {
+               _D("already_permanent process : %d", pid);
+               return 1;
+       }
+       return 0;
+}
+
+static int copy_cmdline(int pid)
+{
+       char buf[PATH_MAX];
+       char filepath[PATH_MAX];
+       int fd;
+       int cnt;
+       int r;
+
+       if (access(PERMANENT_DIR, R_OK) < 0) {
+               _D("no predefined matrix dir = %s, so created", PERMANENT_DIR);
+               r = mkdir(PERMANENT_DIR, 0777);
+               if(r < 0) {
+                       _E("permanent directory mkdir is failed");
+                       return -1;
+               }
+       }
+
+       snprintf(filepath, PATH_MAX, "/proc/%d/cmdline", pid);
+
+       fd = open(filepath, O_RDONLY);
+       if (fd == -1) {
+               _E("Failed to open");
+               return -1;
+       }
+
+       cnt = read(fd, buf, PATH_MAX);
+       close(fd);
+
+       if (cnt <= 0) {
+               /* Read /proc/<pid>/cmdline error */
+               _E("Failed to read");
+               return -1;
+       }
+
+       snprintf(filepath, PATH_MAX, "%s/%d", PERMANENT_DIR, pid);
+
+       fd = open(filepath, O_CREAT | O_WRONLY, 0644);
+       if (fd == -1) {
+               _E("Failed to open");
+               return -1;
+       }
+
+       if (write(fd, buf, cnt) == -1) {
+               _E("Failed to write");
+               close(fd);
+               return -1;
+       }
+
+       close(fd);
+       return 0;
+}
+
+API int deviced_conf_set_vip(int pid)
+{
+       char buf[BUFF_MAX];
+       int fd;
+       int r;
+
+       if (pid < 1)
+               return -1;
+
+       if (access(VIP_DIR, R_OK) < 0) {
+               _D("no predefined matrix dir = %s, so created", VIP_DIR);
+               r = mkdir(VIP_DIR, 0777);
+               if(r < 0) {
+                       _E("sysconf_set_vip vip mkdir is failed");
+                       return -1;
+               }
+       }
+
+       snprintf(buf, BUFF_MAX, "%s/%d", VIP_DIR, pid);
+       fd = open(buf, O_CREAT | O_RDWR, 0644);
+       if (fd < 0) {
+               _E("sysconf_set_vip fd open failed");
+               return -1;
+       }
+       close(fd);
+       if (util_process_group_set(PROCESS_VIP, pid) < 0) {
+               _E("set vip failed");
+               return -1;
+       }
+
+       return 0;
+}
+
+API int deviced_conf_is_vip(int pid)
+{
+       if (pid < 1)
+               return -1;
+
+       char buf[BUFF_MAX];
+
+       snprintf(buf, BUFF_MAX, "%s/%d", VIP_DIR, pid);
+
+       if (access(buf, R_OK) == 0)
+               return 1;
+       else
+               return 0;
+}
+
+API int deviced_conf_set_permanent_bypid(int pid)
+{
+       int fd;
+       if (already_permanent(pid))
+               goto MEMPOL_SET;
+
+       if (copy_cmdline(pid) < 0)
+               return -1;
+
+       if (util_process_group_set(PROCESS_PERMANENT, pid) < 0) {
+               _E("set vip failed");
+               return -1;
+       }
+
+ MEMPOL_SET:
+       util_oomadj_set(pid, OOMADJ_SU);
+
+       return 0;
+}
+
+API int deviced_conf_set_permanent()
+{
+       pid_t pid = getpid();
+       return deviced_conf_set_permanent_bypid(pid);
+}
diff --git a/src/libdeviced/deviced-noti.c b/src/libdeviced/deviced-noti.c
new file mode 100755 (executable)
index 0000000..3ae6746
--- /dev/null
@@ -0,0 +1,605 @@
+/*
+ * 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 <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+#include <limits.h>
+
+#include "dd-deviced.h"
+#include "deviced-priv.h"
+#include "log.h"
+#include "dbus.h"
+
+#define PREDEF_PWROFF_POPUP                    "pwroff-popup"
+#define PREDEF_ENTERSLEEP                      "entersleep"
+#define PREDEF_LEAVESLEEP                      "leavesleep"
+#define PREDEF_REBOOT                          "reboot"
+#define PREDEF_BACKGRD                         "backgrd"
+#define PREDEF_FOREGRD                         "foregrd"
+#define PREDEF_ACTIVE                          "active"
+#define PREDEF_INACTIVE                                "inactive"
+#define PREDEF_SET_DATETIME                    "set_datetime"
+#define PREDEF_SET_TIMEZONE                    "set_timezone"
+
+#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_FACTORY_MODE                    "factorymode"
+
+#define PREDEF_DUMP_LOG                        "dump_log"
+#define PREDEF_DELETE_DUMP             "delete_dump"
+#define PREDEF_FLIGHT_MODE             "flightmode"
+#define PREDEF_LED_CMD                 "ledcmd"
+#define PREDEF_LED_BRT                 "ledbrt"
+#define PREDEF_LED_MODE                "ledmode"
+
+#define ALARM_BUS_NAME         "com.samsung.alarm.manager"
+#define ALARM_PATH_NAME                "/com/samsung/alarm/manager"
+#define ALARM_INTERFACE_NAME   ALARM_BUS_NAME
+#define ALARM_SET_TIME_METHOD  "alarm_set_time"
+
+enum deviced_noti_cmd {
+       ADD_deviced_ACTION,
+       CALL_deviced_ACTION
+};
+
+#define SYSTEM_NOTI_SOCKET_PATH "/tmp/sn"
+#define RETRY_READ_COUNT       10
+
+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 > SYSTEM_NOTI_MAXSTR)
+                       len = SYSTEM_NOTI_MAXSTR;
+               write(fd, &len, sizeof(int));
+               ret = write(fd, str, len);
+       }
+       return ret;
+}
+
+static int noti_send(struct sysnoti *msg)
+{
+       int client_len;
+       int client_sockfd;
+       int result;
+       int r;
+       int retry_count = 0;
+       struct sockaddr_un clientaddr;
+       int i;
+
+       client_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (client_sockfd == -1) {
+               _E("socket create failed");
+               return -1;
+       }
+       bzero(&clientaddr, sizeof(clientaddr));
+       clientaddr.sun_family = AF_UNIX;
+       strncpy(clientaddr.sun_path, SYSTEM_NOTI_SOCKET_PATH, sizeof(clientaddr.sun_path) - 1);
+       client_len = sizeof(clientaddr);
+
+       if (connect(client_sockfd, (struct sockaddr *)&clientaddr, client_len) <
+           0) {
+               _E("connect failed");
+               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]);
+
+       while (retry_count < RETRY_READ_COUNT) {
+               r = read(client_sockfd, &result, sizeof(int));
+               if (r < 0) {
+                       if (errno == EINTR) {
+                               _E("Re-read for error(EINTR)");
+                               retry_count++;
+                               continue;
+                       }
+                       _E("Read fail for str length");
+                       result = -1;
+                       break;
+
+               }
+               break;
+       }
+       if (retry_count == RETRY_READ_COUNT) {
+               _E("Read retry failed");
+       }
+
+       close(client_sockfd);
+       return result;
+}
+
+API int deviced_call_predef_action(const char *type, int num, ...)
+{
+       struct sysnoti *msg;
+       int ret;
+       va_list argptr;
+       int i;
+       char *args = NULL;
+
+       if (type == NULL || num > SYSTEM_NOTI_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_deviced_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);
+
+       ret = noti_send(msg);
+       free(msg);
+
+       return ret;
+}
+
+static int dbus_proc_handler(char* type, char *buf)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *pa[3];
+       int ret, val;
+
+       pa[0] = type;
+       pa[1] = "1";
+       pa[2] = buf;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_PROCESS, DEVICED_INTERFACE_PROCESS,
+                       pa[0], "sis", pa);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _D("%s-%s : %d", DEVICED_INTERFACE_PROCESS, pa[0], val);
+       return val;
+}
+
+API int deviced_inform_foregrd(void)
+{
+       char buf[255];
+       snprintf(buf, sizeof(buf), "%d", getpid());
+       return dbus_proc_handler(PREDEF_FOREGRD, buf);
+}
+
+API int deviced_inform_backgrd(void)
+{
+       char buf[255];
+       snprintf(buf, sizeof(buf), "%d", getpid());
+       return dbus_proc_handler(PREDEF_BACKGRD, buf);
+}
+
+API int deviced_inform_active(pid_t pid)
+{
+       char buf[255];
+       snprintf(buf, sizeof(buf), "%d", pid);
+       return dbus_proc_handler(PREDEF_ACTIVE, buf);
+}
+
+API int deviced_inform_inactive(pid_t pid)
+{
+       char buf[255];
+       snprintf(buf, sizeof(buf), "%d", pid);
+       return dbus_proc_handler(PREDEF_INACTIVE, buf);
+}
+
+static int dbus_power_handler(char* type)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *pa[2];
+       int ret, val;
+
+       pa[0] = type;
+       pa[1] = "0";
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER,
+                       pa[0], "si", pa);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _D("%s-%s : %d", DEVICED_INTERFACE_POWER, pa[0], val);
+       return val;
+}
+
+API int deviced_request_poweroff(void)
+{
+       return dbus_power_handler(PREDEF_PWROFF_POPUP);
+}
+
+API int deviced_request_entersleep(void)
+{
+       return dbus_power_handler(PREDEF_ENTERSLEEP);
+}
+
+API int deviced_request_leavesleep(void)
+{
+       return dbus_power_handler(PREDEF_LEAVESLEEP);
+}
+
+API int deviced_request_reboot(void)
+{
+       return dbus_power_handler(PREDEF_REBOOT);
+}
+
+static int dbus_time_handler(char* type, char* buf)
+{
+       DBusError err;
+       DBusMessage *msg;
+       pid_t pid;
+       char name[PATH_MAX];
+       char *pa[3];
+       int ret, val;
+
+       pa[0] = type;
+       pa[1] = "1";
+       pa[2] = buf;
+
+       pid = getpid();
+       ret = deviced_get_cmdline_name(pid, name, sizeof(name));
+       if (ret != 0)
+               snprintf(name, sizeof(name), "%d", pid);
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       pa[0], "sis", pa);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _SI("[%s] %s-%s(%s) : %d", name, DEVICED_INTERFACE_SYSNOTI, pa[0], pa[2], val);
+
+       return val;
+}
+
+static DBusMessage *alarm_set_time_sync_with_reply(time_t timet)
+{
+       DBusConnection *conn;
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       DBusError err;
+       int r;
+
+       conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (!conn) {
+               _E("dbus_bus_get error");
+               return NULL;
+       }
+
+       msg = dbus_message_new_method_call(ALARM_BUS_NAME, ALARM_PATH_NAME, ALARM_INTERFACE_NAME, ALARM_SET_TIME_METHOD);
+       if (!msg) {
+               _E("dbus_message_new_method_call(%s:%s-%s)",
+                       ALARM_PATH_NAME, ALARM_INTERFACE_NAME, ALARM_SET_TIME_METHOD);
+               return NULL;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &timet);
+
+       dbus_error_init(&err);
+
+       reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
+       if (!reply) {
+               _E("dbus_connection_send error(No reply) %s %s:%s-%s",
+                       ALARM_BUS_NAME, ALARM_PATH_NAME, ALARM_INTERFACE_NAME, ALARM_SET_TIME_METHOD);
+       }
+
+       if (dbus_error_is_set(&err)) {
+               _E("dbus_connection_send error(%s:%s) %s %s:%s-%s",
+                       err.name, err.message, ALARM_BUS_NAME, ALARM_PATH_NAME, ALARM_INTERFACE_NAME, ALARM_SET_TIME_METHOD);
+               dbus_error_free(&err);
+               reply = NULL;
+       }
+
+       dbus_message_unref(msg);
+       return reply;
+}
+
+static int alarm_set_time(time_t timet)
+{
+       DBusError err;
+       DBusMessage *msg;
+       pid_t pid;
+       char name[PATH_MAX];
+       int ret, val;
+
+       pid = getpid();
+       ret = deviced_get_cmdline_name(pid, name, sizeof(name));
+       if (ret != 0)
+               snprintf(name, sizeof(name), "%d", pid);
+       _SI("[%s]start %s %ld", name, ALARM_INTERFACE_NAME, timet);
+
+       msg = alarm_set_time_sync_with_reply(timet);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _SI("[%s]end %s %ld, %d", name, ALARM_INTERFACE_NAME, timet, val);
+       return val;
+}
+
+API int deviced_set_datetime(time_t timet)
+{
+       if (timet < 0L)
+               return -1;
+       return alarm_set_time(timet);
+}
+
+API int deviced_set_timezone(char *tzpath_str)
+{
+       if (tzpath_str == NULL)
+               return -1;
+       char buf[255];
+       snprintf(buf, sizeof(buf), "%s", tzpath_str);
+       return dbus_time_handler(PREDEF_SET_TIMEZONE, buf);
+}
+
+static int dbus_cpu_handler(char* type, char* buf_pid, char* buf_freq)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *pa[4];
+       int ret, val;
+
+       pa[0] = type;
+       pa[1] = "2";
+       pa[2] = buf_pid;
+       pa[3] = buf_freq;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       pa[0], "siss", pa);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _D("%s-%s : %d", DEVICED_INTERFACE_SYSNOTI, pa[0], val);
+       return val;
+}
+
+API int deviced_request_set_cpu_max_frequency(int val)
+{
+       char buf_pid[8];
+       char buf_freq[256];
+
+       // to do - need to check new frequncy is valid
+       snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
+       snprintf(buf_freq, sizeof(buf_freq), "%d", val * 1000);
+
+       return dbus_cpu_handler(PREDEF_SET_MAX_FREQUENCY, buf_pid, buf_freq);
+}
+
+API int deviced_request_set_cpu_min_frequency(int val)
+{
+       char buf_pid[8];
+       char buf_freq[256];
+
+       // to do - need to check new frequncy is valid
+       snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
+       snprintf(buf_freq, sizeof(buf_freq), "%d", val * 1000);
+
+       return dbus_cpu_handler(PREDEF_SET_MIN_FREQUENCY, buf_pid, buf_freq);
+}
+
+API int deviced_release_cpu_max_frequency()
+{
+       char buf_pid[8];
+
+       snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
+
+       return dbus_cpu_handler(PREDEF_RELEASE_MAX_FREQUENCY, buf_pid, "2");
+}
+
+API int deviced_release_cpu_min_frequency()
+{
+       char buf_pid[8];
+
+       snprintf(buf_pid, sizeof(buf_pid), "%d", getpid());
+
+       return dbus_cpu_handler(PREDEF_RELEASE_MIN_FREQUENCY, buf_pid, "2");
+}
+
+static int dbus_factory_handler(char* type, char* buf)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *pa[3];
+       int ret, val;
+
+       pa[0] = type;
+       pa[1] = "1";
+       pa[2] = buf;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_SYSNOTI, DEVICED_INTERFACE_SYSNOTI,
+                       pa[0], "sis", pa);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _D("%s-%s : %d", DEVICED_INTERFACE_SYSNOTI, pa[0], val);
+       return val;
+}
+
+API int deviced_request_set_factory_mode(int val)
+{
+       char buf_mode[8];
+       if ( val == 0 || val == 1 ) {
+               snprintf(buf_mode, sizeof(buf_mode), "%d", val);
+               return dbus_factory_handler(PREDEF_FACTORY_MODE, buf_mode);
+       } else {
+               return -1;
+       }
+}
+
+static int dbus_crash_handler(char* type, char* buf)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *pa[3];
+       int ret, val;
+
+       pa[0] = type;
+       pa[1] = "1";
+       pa[2] = buf;
+       msg = dbus_method_sync_with_reply(CRASHD_BUS_NAME,
+                       CRASHD_PATH_CRASH, CRASHD_INTERFACE_CRASH,
+                       pa[0], "sis", pa);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       dbus_error_free(&err);
+
+       _D("%s-%s : %d", CRASHD_INTERFACE_CRASH, pa[0], val);
+       return val;
+}
+
+API int deviced_request_dump_log(int type)
+{
+       char buf_mode[8];
+       if ( type == AP_DUMP || type == CP_DUMP || type == ALL_DUMP) {
+               snprintf(buf_mode, sizeof(buf_mode), "%d", type);
+               return dbus_crash_handler(PREDEF_DUMP_LOG, buf_mode);
+       } else {
+               return -1;
+       }
+}
+
+API int deviced_request_delete_dump(char *ticket)
+{
+       char buf[255];
+       if ( ticket == NULL) {
+               return -1;
+       }
+       snprintf(buf, sizeof(buf), "%s", ticket);
+       return dbus_crash_handler(PREDEF_DELETE_DUMP, buf);
+}
diff --git a/src/libdeviced/deviced-util.c b/src/libdeviced/deviced-util.c
new file mode 100644 (file)
index 0000000..3cb19a6
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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 <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <poll.h>
+
+#include "log.h"
+#include "dd-deviced.h"
+#include "deviced-priv.h"
+
+API int deviced_get_pid(const char *execpath)
+{
+       DIR *dp;
+       struct dirent *dentry;
+       int pid = -1, fd;
+       char buf[BUFF_MAX];
+       char buf2[BUFF_MAX];
+       int ret;
+
+       dp = opendir("/proc");
+       if (!dp) {
+               _E("open /proc");
+               return -1;
+       }
+
+       while ((dentry = readdir(dp)) != NULL) {
+               if (!isdigit(dentry->d_name[0]))
+                       continue;
+
+               pid = atoi(dentry->d_name);
+
+               snprintf(buf, BUFF_MAX, "/proc/%d/cmdline", pid);
+               fd = open(buf, O_RDONLY);
+               if (fd < 0)
+                       continue;
+
+               ret = read(fd, buf2, BUFF_MAX);
+               close(fd);
+
+               if (ret < 0 || ret >=BUFF_MAX)
+                       continue;
+
+               buf2[ret] = '\0';
+
+               if (!strcmp(buf2, execpath)) {
+                       closedir(dp);
+                       return pid;
+               }
+       }
+
+       errno = ESRCH;
+       closedir(dp);
+       return -1;
+}
+
+API int deviced_get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
+{
+       int fd, ret;
+       char buf[PATH_MAX + 1];
+       char *filename;
+
+       snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
+       fd = open(buf, O_RDONLY);
+       if (fd < 0) {
+               errno = ESRCH;
+               return -1;
+       }
+
+       ret = read(fd, buf, PATH_MAX);
+       close(fd);
+       buf[PATH_MAX] = '\0';
+
+       filename = strrchr(buf, '/');
+       if (filename == NULL)
+               filename = buf;
+       else
+               filename = filename + 1;
+
+       if (cmdline_size < strlen(filename) + 1) {
+               errno = EOVERFLOW;
+               return -1;
+       }
+
+       strncpy(cmdline, filename, cmdline_size - 1);
+       cmdline[cmdline_size - 1] = '\0';
+       return 0;
+}
+
+API int deviced_get_apppath(pid_t pid, char *app_path, size_t app_path_size)
+{
+       char buf[PATH_MAX];
+       int ret;
+
+       snprintf(buf, PATH_MAX, "/proc/%d/exe", pid);
+       if (app_path == NULL
+           || (ret = readlink(buf, app_path, app_path_size)) == -1)
+               return -1;
+       if (app_path_size == ret) {
+               app_path[ret - 1] = '\0';
+               errno = EOVERFLOW;
+               return -1;
+       }
+
+       app_path[ret] = '\0';
+       return 0;
+}
diff --git a/src/libdeviced/display.c b/src/libdeviced/display.c
new file mode 100644 (file)
index 0000000..70daf48
--- /dev/null
@@ -0,0 +1,746 @@
+/*
+ * 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 "log.h"
+#include "dbus.h"
+#include "common.h"
+#include "dd-display.h"
+
+#define DISPLAY_MAX_BRIGHTNESS  100
+#define DISPLAY_MIN_BRIGHTNESS  1
+#define DISPLAY_DIM_BRIGHTNESS  0
+
+#define HOLDKEY_BLOCK_BIT              0x1
+#define STANDBY_MODE_BIT               0x2
+
+#define BLIND_MASK(val)                        ((val) & 0xFFFF)
+#define BLIND_COLOR(a,b,c)             ((BLIND_MASK((unsigned long long)(a)) << 32) |   \
+                                                               (BLIND_MASK(b) << 16) | BLIND_MASK(c))
+
+#define METHOD_GET_ENHANCE_SUPPORTED   "GetEnhanceSupported"
+#define METHOD_GET_IMAGE_ENHANCE       "GetImageEnhance"
+#define METHOD_SET_IMAGE_ENHANCE       "SetImageEnhance"
+#define METHOD_SET_REFRESH_RATE                "SetRefreshRate"
+#define METHOD_GET_COLOR_BLIND         "GetColorBlind"
+#define METHOD_SET_COLOR_BLIND         "SetColorBlind"
+#define METHOD_LOCK_STATE              "lockstate"
+#define METHOD_UNLOCK_STATE            "unlockstate"
+#define METHOD_CHANGE_STATE            "changestate"
+#define METHOD_GET_DISPLAY_COUNT       "GetDisplayCount"
+#define METHOD_GET_MAX_BRIGHTNESS      "GetMaxBrightness"
+#define METHOD_GET_BRIGHTNESS  "GetBrightness"
+#define METHOD_SET_BRIGHTNESS  "SetBrightness"
+#define METHOD_HOLD_BRIGHTNESS "HoldBrightness"
+#define METHOD_RELEASE_BRIGHTNESS      "ReleaseBrightness"
+#define METHOD_GET_ACL_STATUS  "GetAclStatus"
+#define METHOD_SET_ACL_STATUS  "SetAclStatus"
+#define METHOD_GET_AUTO_TONE   "GetAutoTone"
+#define METHOD_SET_AUTO_TONE   "SetAutoTone"
+#define METHOD_GET_ENHANCED_TOUCH      "GetEnhancedTouch"
+#define METHOD_SET_ENHANCED_TOUCH      "SetEnhancedTouch"
+#define METHOD_GET_HBM                 "GetHBM"
+#define METHOD_SET_HBM                 "SetHBM"
+#define METHOD_SET_HBM_TIMEOUT         "SetHBMTimeout"
+
+#define STR_LCD_OFF   "lcdoff"
+#define STR_LCD_DIM   "lcddim"
+#define STR_LCD_ON    "lcdon"
+#define STR_SUSPEND   "suspend"
+
+#define STR_STAYCURSTATE "staycurstate"
+#define STR_GOTOSTATENOW "gotostatenow"
+
+#define STR_HOLDKEYBLOCK "holdkeyblock"
+#define STR_STANDBYMODE  "standbymode"
+#define STR_NULL         "NULL"
+
+#define STR_SLEEP_MARGIN "sleepmargin"
+#define STR_RESET_TIMER  "resettimer"
+#define STR_KEEP_TIMER   "keeptimer"
+
+API int display_get_count(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_GET_DISPLAY_COUNT, NULL, NULL);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int display_get_max_brightness(void)
+{
+       int ret;
+
+       ret = dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_GET_MAX_BRIGHTNESS, NULL, NULL);
+       if (ret < 0)
+               return DISPLAY_MAX_BRIGHTNESS;
+
+       _D("get max brightness : %d", ret);
+       return ret;
+}
+
+API int display_get_min_brightness(void)
+{
+       return DISPLAY_MIN_BRIGHTNESS;
+}
+
+API int display_get_brightness(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_GET_BRIGHTNESS, NULL, NULL);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int display_set_brightness_with_setting(int val)
+{
+       char str_val[32];
+       char *arr[1];
+       int ret;
+
+       if (val < 0 || val > 100)
+               return -EINVAL;
+
+       snprintf(str_val, sizeof(str_val), "%d", val);
+       arr[0] = str_val;
+
+       ret = dbus_method_async(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_SET_BRIGHTNESS, "i", arr);
+       if (ret < 0)
+               _E("no message : failed to setting");
+
+       return ret;
+}
+
+API int display_set_brightness(int val)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char str_val[32];
+       char *arr[1];
+       int ret, ret_val;
+
+       snprintf(str_val, sizeof(str_val), "%d", val);
+       arr[0] = str_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_HOLD_BRIGHTNESS, "i", arr);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int display_release_brightness(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_RELEASE_BRIGHTNESS, NULL, NULL);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int display_get_acl_status(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_GET_ACL_STATUS, NULL, NULL);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int display_set_acl_status(int val)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char str_val[32];
+       char *arr[1];
+       int ret, ret_val;
+
+       snprintf(str_val, sizeof(str_val), "%d", val);
+       arr[0] = str_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_SET_ACL_STATUS, "i", arr);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int display_get_auto_screen_tone(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_GET_AUTO_TONE, NULL, NULL);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int display_set_auto_screen_tone(int val)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char str_val[32];
+       char *arr[1];
+       int ret, ret_val;
+
+       snprintf(str_val, sizeof(str_val), "%d", val);
+       arr[0] = str_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_SET_AUTO_TONE, "i", arr);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int display_get_image_enhance_info(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_GET_ENHANCE_SUPPORTED, NULL, NULL);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int display_get_image_enhance(int type)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char str_type[32];
+       char *arr[1];
+       int ret, ret_val;
+
+       snprintf(str_type, sizeof(str_type), "%d", type);
+       arr[0] = str_type;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_GET_IMAGE_ENHANCE, "i", arr);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int display_set_image_enhance(int type, int val)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char str_type[32];
+       char str_val[32];
+       char *arr[2];
+       int ret, ret_val;
+
+       snprintf(str_type, sizeof(str_type), "%d", type);
+       arr[0] = str_type;
+       snprintf(str_val, sizeof(str_val), "%d", val);
+       arr[1] = str_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_SET_IMAGE_ENHANCE, "ii", arr);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int display_set_frame_rate(int val)
+{
+       return display_set_refresh_rate(REFRESH_SETTING, val);
+}
+
+API int display_set_refresh_rate(enum refresh_app app, int val)
+{
+       char str_app[32];
+       char str_val[32];
+       char *arr[2];
+
+       snprintf(str_app, sizeof(str_app), "%d", app);
+       arr[0] = str_app;
+       snprintf(str_val, sizeof(str_val), "%d", val);
+       arr[1] = str_val;
+
+       return dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_SET_REFRESH_RATE, "ii", arr);
+}
+
+API int display_get_color_blind(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_GET_COLOR_BLIND, NULL, NULL);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int display_set_color_blind(int enable, struct blind_color_info *info)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char str_enable[32];
+       char str_red[32];
+       char str_grn[32];
+       char str_blu[32];
+       char *arr[4];
+       int ret, ret_val;
+
+       snprintf(str_enable, sizeof(str_enable), "%d", enable);
+       arr[0] = str_enable;
+       snprintf(str_red, sizeof(str_red), "%llu", BLIND_COLOR(info->RrCr, info->RgCg, info->RbCb));
+       arr[1] = str_red;
+       snprintf(str_grn, sizeof(str_grn), "%llu", BLIND_COLOR(info->GrMr, info->GgMg, info->GbMb));
+       arr[2] = str_grn;
+       snprintf(str_blu, sizeof(str_blu), "%llu", BLIND_COLOR(info->BrYr, info->BgYg, info->BbYb));
+       arr[3] = str_blu;
+
+       _D("red : %s, grn : %s, blu : %s", str_red, str_grn, str_blu);
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_SET_COLOR_BLIND, "uttt", arr);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+static inline char *get_lcd_str(unsigned int val)
+{
+       switch (val) {
+       case LCD_NORMAL:
+               return STR_LCD_ON;
+       case LCD_DIM:
+               return STR_LCD_DIM;
+       case LCD_OFF:
+               return STR_LCD_OFF;
+       case SUSPEND:
+               return STR_SUSPEND;
+       default:
+               return NULL;
+       }
+}
+
+static void display_change_cb(void *data, DBusMessage *msg, DBusError *unused)
+{
+       DBusError err;
+       int ret, val;
+
+       if (!msg)
+               return;
+
+       dbus_error_init(&err);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               return;
+       }
+        _D("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_CHANGE_STATE, val);
+}
+
+API int display_change_state(unsigned int s_bits)
+{
+       char *p, *pa[1];
+       int ret;
+
+       p = get_lcd_str(s_bits);
+       if (!p)
+               return -EINVAL;
+       pa[0] = p;
+
+       ret = dbus_method_async_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_CHANGE_STATE, "s", pa, display_change_cb, -1, NULL);
+       if (ret < 0)
+               _E("no message : failed to change state");
+
+       _D("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_CHANGE_STATE, ret);
+
+       return ret;
+}
+
+static void display_lock_cb(void *data, DBusMessage *msg, DBusError *unused)
+{
+       DBusError err;
+       int ret, val;
+
+       if (!msg)
+               return;
+
+       dbus_error_init(&err);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               return;
+       }
+        _D("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_LOCK_STATE, val);
+}
+
+API int display_lock_state(unsigned int s_bits, unsigned int flag,
+                     unsigned int timeout)
+{
+       char *p, *pa[4];
+       char str_timeout[32];
+       int ret;
+
+       p = get_lcd_str(s_bits);
+       if (!p)
+               return -EINVAL;
+       pa[0] = p;
+
+       if (flag & GOTO_STATE_NOW)
+               /* if the flag is true, go to the locking state directly */
+               p = STR_GOTOSTATENOW;
+       else
+               p = STR_STAYCURSTATE;
+       pa[1] = p;
+
+       if (flag & HOLD_KEY_BLOCK)
+               p = STR_HOLDKEYBLOCK;
+       else if (flag & STANDBY_MODE)
+               p = STR_STANDBYMODE;
+       else
+               p = STR_NULL;
+       pa[2] = p;
+
+       if (timeout < 0)
+               return -EINVAL;
+
+       snprintf(str_timeout, sizeof(str_timeout), "%d", timeout);
+       pa[3] = str_timeout;
+
+       ret = dbus_method_async_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_LOCK_STATE, "sssi", pa, display_lock_cb, -1, NULL);
+       if (ret < 0)
+               _E("no message : failed to lock state");
+
+       _D("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_LOCK_STATE, ret);
+
+       return ret;
+}
+
+static void display_unlock_cb(void *data, DBusMessage *msg, DBusError *unused)
+{
+       DBusError err;
+       int ret, val;
+
+       if (!msg)
+               return;
+
+       dbus_error_init(&err);
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               return;
+       }
+        _D("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_UNLOCK_STATE, val);
+}
+
+API int display_unlock_state(unsigned int s_bits, unsigned int flag)
+{
+       char *p, *pa[2];
+       int ret;
+
+       p = get_lcd_str(s_bits);
+       if (!p)
+               return -EINVAL;
+       pa[0] = p;
+
+       switch (flag) {
+       case PM_SLEEP_MARGIN:
+               p = STR_SLEEP_MARGIN;
+               break;
+       case PM_RESET_TIMER:
+               p = STR_RESET_TIMER;
+               break;
+       case PM_KEEP_TIMER:
+               p = STR_KEEP_TIMER;
+               break;
+       default:
+               return -EINVAL;
+       }
+       pa[1] = p;
+
+       ret = dbus_method_async_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_UNLOCK_STATE, "ss", pa, display_unlock_cb, -1, NULL);
+       if (ret < 0)
+               _E("no message : failed to unlock state");
+
+       _D("%s-%s : %d", DEVICED_INTERFACE_DISPLAY, METHOD_UNLOCK_STATE, ret);
+
+       return ret;
+}
+
+API int display_get_enhanced_touch(void)
+{
+       return dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_GET_ENHANCED_TOUCH, NULL, NULL);
+}
+
+API int display_set_enhanced_touch(int enable)
+{
+       char *arr[1];
+       char str_enable[32];
+
+       snprintf(str_enable, sizeof(str_enable), "%d", enable);
+       arr[0] = str_enable;
+
+       return dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_SET_ENHANCED_TOUCH, "i", arr);
+}
+
+API int display_get_hbm(void)
+{
+       return dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_GET_HBM, NULL, NULL);
+}
+
+API int display_set_hbm(int enable)
+{
+       char *arr[1];
+       char str_enable[2];
+
+       if (enable != 0 && enable != 1)
+               return -EINVAL;
+
+       snprintf(str_enable, sizeof(str_enable), "%d", enable);
+       arr[0] = str_enable;
+
+       return dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_SET_HBM, "i", arr);
+}
+
+API int display_enable_hbm(int enable, int timeout)
+{
+       char *arr[2];
+       char str_enable[2];
+       char str_timeout[32];
+
+       if (enable != 0 && enable != 1)
+               return -EINVAL;
+
+       if (timeout < 0)
+               return -EINVAL;
+
+       snprintf(str_enable, sizeof(str_enable), "%d", enable);
+       arr[0] = str_enable;
+
+       snprintf(str_timeout, sizeof(str_timeout), "%d", timeout);
+       arr[1] = str_timeout;
+
+       return dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY,
+                       METHOD_SET_HBM_TIMEOUT, "ii", arr);
+}
+
diff --git a/src/libdeviced/haptic.c b/src/libdeviced/haptic.c
new file mode 100644 (file)
index 0000000..7940923
--- /dev/null
@@ -0,0 +1,767 @@
+/*
+ * 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 <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include <vconf.h>
+
+#include "log.h"
+#include "dbus.h"
+#include "haptic-plugin-intf.h"
+#include "dd-haptic.h"
+#include "common.h"
+
+#define METHOD_OPEN_DEVICE                     "OpenDevice"
+#define METHOD_CLOSE_DEVICE                    "CloseDevice"
+#define METHOD_STOP_DEVICE                     "StopDevice"
+#define METHOD_VIBRATE_MONOTONE                "VibrateMonotone"
+#define METHOD_VIBRATE_BUFFER          "VibrateBuffer"
+#define METHOD_GET_COUNT                       "GetCount"
+#define METHOD_GET_STATE                       "GetState"
+#define METHOD_GET_DURATION                    "GetDuration"
+#define METHOD_CREATE_EFFECT           "CreateEffect"
+#define METHOD_SAVE_BINARY                     "SaveBinary"
+
+#define TEMP_BUFFER_SIZE                       (64*1024)
+
+/* START of Static Function Section */
+static unsigned char* convert_file_to_buffer(const char *file_name, int *size)
+{
+       FILE *pf;
+       long file_size;
+       unsigned char *pdata = NULL;
+
+       if (!file_name)
+               return NULL;
+
+       /* Get File Stream Pointer */
+       pf = fopen(file_name, "rb");
+       if (!pf) {
+               _E("fopen failed : %s", strerror(errno));
+               return NULL;
+       }
+
+       if (fseek(pf, 0, SEEK_END))
+               goto error;
+
+       file_size = ftell(pf);
+       if (fseek(pf, 0, SEEK_SET))
+               goto error;
+
+       if (file_size < 0)
+               goto error;
+
+       pdata = (unsigned char*)malloc(file_size);
+       if (!pdata)
+               goto error;
+
+       if (fread(pdata, 1, file_size, pf) != file_size)
+               goto err_free;
+
+       fclose(pf);
+       *size = file_size;
+       return pdata;
+
+err_free:
+       free(pdata);
+
+error:
+       fclose(pf);
+
+       _E("failed to convert file to buffer (%s)", strerror(errno));
+       return NULL;
+}
+
+static int save_data(const unsigned char *data, int size, const char *file_path)
+{
+       FILE *file;
+       int fd;
+
+       file = fopen(file_path, "wb+");
+       if (file == NULL) {
+               _E("To open file is failed : %s", strerror(errno));
+               return -1;
+       }
+
+       if (fwrite(data, 1, size, file) != size) {
+               _E("To write file is failed : %s", strerror(errno));
+               fclose(file);
+               return -1;
+       }
+
+       fd = fileno(file);
+       if (fd < 0) {
+               _E("To get file descriptor is failed : %s", strerror(errno));
+               fclose(file);
+               return -1;
+       }
+
+       if (fsync(fd) < 0) {
+               _E("To be synchronized with the disk is failed : %s", strerror(errno));
+               fclose(file);
+               return -1;
+       }
+
+       fclose(file);
+       return 0;
+}
+
+static haptic_feedback_e convert_setting_to_module_level(void)
+{
+       int setting_fb_level;
+
+       if (vconf_get_int(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, &setting_fb_level) < 0) {
+               setting_fb_level = SETTING_VIB_FEEDBACK_LEVEL3;
+       }
+
+       if (setting_fb_level < HAPTIC_FEEDBACK_0 || setting_fb_level > HAPTIC_FEEDBACK_5)
+               return -1;
+
+       switch (setting_fb_level) {
+       case SETTING_VIB_FEEDBACK_LEVEL0 : return HAPTIC_FEEDBACK_0;
+       case SETTING_VIB_FEEDBACK_LEVEL1 : return HAPTIC_FEEDBACK_1;
+       case SETTING_VIB_FEEDBACK_LEVEL2 : return HAPTIC_FEEDBACK_2;
+       case SETTING_VIB_FEEDBACK_LEVEL3 : return HAPTIC_FEEDBACK_3;
+       case SETTING_VIB_FEEDBACK_LEVEL4 : return HAPTIC_FEEDBACK_4;
+       case SETTING_VIB_FEEDBACK_LEVEL5 : return HAPTIC_FEEDBACK_5;
+       default:
+               break;
+       }
+       return -1;
+}
+/* END of Static Function Section */
+
+API int haptic_get_count(int *device_number)
+{
+       int ret;
+
+       /* check if pointer is valid */
+       if (device_number == NULL) {
+               _E("Invalid parameter : device_number(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* request to deviced to get haptic count */
+       ret = dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_HAPTIC, DEVICED_INTERFACE_HAPTIC,
+                       METHOD_GET_COUNT, NULL, NULL);
+       if (ret < 0)
+               return HAPTIC_ERROR_OPERATION_FAILED;
+
+       *device_number = ret;
+       return HAPTIC_ERROR_NONE;
+}
+
+API int haptic_open(haptic_device_e device_index, haptic_device_h *device_handle)
+{
+       char str_index[32];
+       char *arr[1];
+       int ret;
+
+       /* check if index is valid */
+       if (!(device_index == HAPTIC_DEVICE_0 || device_index == HAPTIC_DEVICE_1 ||
+                               device_index == HAPTIC_DEVICE_ALL)) {
+               _E("Invalid parameter : device_index(%d)", device_index);
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* check if pointer is valid */
+       if (device_handle == NULL) {
+               _E("Invalid parameter : device_handle(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       snprintf(str_index, sizeof(str_index), "%d", device_index);
+       arr[0] = str_index;
+
+       /* request to deviced to open haptic device */
+       ret = dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_HAPTIC, DEVICED_INTERFACE_HAPTIC,
+                       METHOD_OPEN_DEVICE, "i", arr);
+       if (ret < 0)
+               return HAPTIC_ERROR_OPERATION_FAILED;
+
+       *device_handle = (haptic_device_h)ret;
+       return HAPTIC_ERROR_NONE;
+}
+
+API int haptic_close(haptic_device_h device_handle)
+{
+       char str_handle[32];
+       char *arr[1];
+       int ret;
+
+       /* check if handle is valid */
+       if (device_handle == NULL) {
+               _E("Invalid parameter : device_handle(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       snprintf(str_handle, sizeof(str_handle), "%u", device_handle);
+       arr[0] = str_handle;
+
+       /* request to deviced to open haptic device */
+       ret = dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_HAPTIC, DEVICED_INTERFACE_HAPTIC,
+                       METHOD_CLOSE_DEVICE, "u", arr);
+       if (ret < 0)
+               return HAPTIC_ERROR_OPERATION_FAILED;
+
+       return HAPTIC_ERROR_NONE;
+}
+
+API int haptic_vibrate_monotone(haptic_device_h device_handle, int duration, haptic_effect_h *effect_handle)
+{
+       return haptic_vibrate_monotone_with_detail(device_handle,
+                                                                                          duration,
+                                                                                          HAPTIC_FEEDBACK_AUTO,
+                                                                                          HAPTIC_PRIORITY_MIN,
+                                                                                          effect_handle);
+}
+
+API int haptic_vibrate_monotone_with_detail(haptic_device_h device_handle,
+                                        int duration,
+                                        haptic_feedback_e feedback,
+                                        haptic_priority_e priority,
+                                        haptic_effect_h *effect_handle)
+{
+       char str_handle[32];
+       char str_duration[32];
+       char str_feedback[32];
+       char str_priority[32];
+       char *arr[4];
+       int ret;
+
+       /* check if handle is valid */
+       if (device_handle == NULL) {
+               _E("Invalid parameter : device_handle(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* check if passed arguments are valid */
+       if (duration < 0 && duration != HAPTIC_DURATION_UNLIMITED) {
+               _E("Invalid parameter : duration(%d)", duration);
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (feedback < HAPTIC_FEEDBACK_0 || feedback > HAPTIC_FEEDBACK_AUTO) {
+               _E("Invalid parameter : feedback(%d)", feedback);
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (priority < HAPTIC_PRIORITY_MIN || priority > HAPTIC_PRIORITY_HIGH) {
+               _E("Invalid parameter : priority(%d)", priority);
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* in case of FEEDBACK_AUTO, should be converted */
+       if (feedback == HAPTIC_FEEDBACK_AUTO)
+               feedback = convert_setting_to_module_level();
+
+       snprintf(str_handle, sizeof(str_handle), "%u", device_handle);
+       arr[0] = str_handle;
+       snprintf(str_duration, sizeof(str_duration), "%d", duration);
+       arr[1] = str_duration;
+       snprintf(str_feedback, sizeof(str_feedback), "%d", feedback);
+       arr[2] = str_feedback;
+       snprintf(str_priority, sizeof(str_priority), "%d", priority);
+       arr[3] = str_priority;
+
+       /* request to deviced to open haptic device */
+       ret = dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_HAPTIC, DEVICED_INTERFACE_HAPTIC,
+                       METHOD_VIBRATE_MONOTONE, "uiii", arr);
+       if (ret < 0)
+               return HAPTIC_ERROR_OPERATION_FAILED;
+
+       if (effect_handle != NULL)
+               *effect_handle = (haptic_effect_h)ret;
+
+       return HAPTIC_ERROR_NONE;
+}
+
+API int haptic_vibrate_file(haptic_device_h device_handle, const char *file_path, haptic_effect_h *effect_handle)
+{
+       char *vibe_buffer;
+       int size, ret;
+
+       vibe_buffer = convert_file_to_buffer(file_path, &size);
+       if (!vibe_buffer) {
+               _E("Convert file to buffer error");
+               return HAPTIC_ERROR_OPERATION_FAILED;
+       }
+
+       ret = haptic_vibrate_buffers_with_detail(device_handle,
+                                                                                       vibe_buffer,
+                                                                                       size,
+                                                                                       HAPTIC_ITERATION_ONCE,
+                                                                                       HAPTIC_FEEDBACK_AUTO,
+                                                                                       HAPTIC_PRIORITY_MIN,
+                                                                                       effect_handle);
+       free(vibe_buffer);
+       return ret;
+}
+
+API int haptic_vibrate_file_with_detail(haptic_device_h device_handle,
+                                    const char *file_path,
+                                    haptic_iteration_e iteration,
+                                    haptic_feedback_e feedback,
+                                    haptic_priority_e priority,
+                                    haptic_effect_h *effect_handle)
+{
+       char *vibe_buffer;
+       int size, ret;
+
+       vibe_buffer = convert_file_to_buffer(file_path, &size);
+       if (!vibe_buffer) {
+               _E("Convert file to buffer error");
+               return HAPTIC_ERROR_OPERATION_FAILED;
+       }
+
+       ret = haptic_vibrate_buffers_with_detail(device_handle,
+                                                                                       vibe_buffer,
+                                                                                       size,
+                                                                                       iteration,
+                                                                                       feedback,
+                                                                                       priority,
+                                                                                       effect_handle);
+       free(vibe_buffer);
+       return ret;
+}
+
+API int haptic_vibrate_buffer(haptic_device_h device_handle, const unsigned char *vibe_buffer, haptic_effect_h *effect_handle)
+{
+       return haptic_vibrate_buffers_with_detail(device_handle,
+                                                                                        vibe_buffer,
+                                                                                        TEMP_BUFFER_SIZE,
+                                                                                        HAPTIC_ITERATION_ONCE,
+                                                                                        HAPTIC_FEEDBACK_AUTO,
+                                                                                        HAPTIC_PRIORITY_MIN,
+                                                                                        effect_handle);
+}
+
+API int haptic_vibrate_buffer_with_detail(haptic_device_h device_handle,
+                                      const unsigned char *vibe_buffer,
+                                      haptic_iteration_e iteration,
+                                      haptic_feedback_e feedback,
+                                      haptic_priority_e priority,
+                                      haptic_effect_h *effect_handle)
+{
+       return haptic_vibrate_buffers_with_detail(device_handle,
+                                                                                        vibe_buffer,
+                                                                                        TEMP_BUFFER_SIZE,
+                                                                                        iteration,
+                                                                                        feedback,
+                                                                                        priority,
+                                                                                        effect_handle);
+}
+
+API int haptic_vibrate_buffers(haptic_device_h device_handle,
+                                                       const unsigned char *vibe_buffer,
+                                                       int size,
+                                                       haptic_effect_h *effect_handle)
+{
+       return haptic_vibrate_buffers_with_detail(device_handle,
+                                                                                        vibe_buffer,
+                                                                                        size,
+                                                                                        HAPTIC_ITERATION_ONCE,
+                                                                                        HAPTIC_FEEDBACK_AUTO,
+                                                                                        HAPTIC_PRIORITY_MIN,
+                                                                                        effect_handle);
+}
+
+API int haptic_vibrate_buffers_with_detail(haptic_device_h device_handle,
+                                      const unsigned char *vibe_buffer,
+                                                                         int size,
+                                      haptic_iteration_e iteration,
+                                      haptic_feedback_e feedback,
+                                      haptic_priority_e priority,
+                                      haptic_effect_h *effect_handle)
+{
+       char str_handle[32];
+       char str_iteration[32];
+       char str_feedback[32];
+       char str_priority[32];
+       char *arr[6];
+       struct dbus_byte bytes;
+       int ret;
+
+       /* check if handle is valid */
+       if (device_handle == NULL) {
+               _E("Invalid parameter : device_handle(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* check if passed arguments are valid */
+       if (vibe_buffer == NULL) {
+               _E("Invalid parameter : vibe_buffer(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (iteration < HAPTIC_ITERATION_ONCE || iteration > HAPTIC_ITERATION_INFINITE) {
+               _E("Invalid parameter : iteration(%d)", iteration);
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (feedback < HAPTIC_FEEDBACK_0 || feedback > HAPTIC_FEEDBACK_AUTO) {
+               _E("Invalid parameter : feedback(%d)", feedback);
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (priority < HAPTIC_PRIORITY_MIN || priority > HAPTIC_PRIORITY_HIGH) {
+               _E("Invalid parameter : priority(%d)", priority);
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* in case of FEEDBACK_AUTO, should be converted */
+       if (feedback == HAPTIC_FEEDBACK_AUTO)
+               feedback = convert_setting_to_module_level();
+
+       snprintf(str_handle, sizeof(str_handle), "%u", device_handle);
+       arr[0] = str_handle;
+       bytes.size = size;
+       bytes.data = vibe_buffer;
+       arr[2] = (char*)&bytes;
+       snprintf(str_iteration, sizeof(str_iteration), "%d", iteration);
+       arr[3] = str_iteration;
+       snprintf(str_feedback, sizeof(str_feedback), "%d", feedback);
+       arr[4] = str_feedback;
+       snprintf(str_priority, sizeof(str_priority), "%d", priority);
+       arr[5] = str_priority;
+
+       /* request to deviced to open haptic device */
+       ret = dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_HAPTIC, DEVICED_INTERFACE_HAPTIC,
+                       METHOD_VIBRATE_BUFFER, "uayiii", arr);
+       if (ret < 0)
+               return HAPTIC_ERROR_OPERATION_FAILED;
+
+       if (effect_handle != NULL)
+               *effect_handle = (haptic_effect_h)ret;
+
+       return HAPTIC_ERROR_NONE;
+}
+
+API int haptic_stop_effect(haptic_device_h device_handle, haptic_effect_h effect_handle)
+{
+       return haptic_stop_all_effects(device_handle);
+}
+
+API int haptic_stop_all_effects(haptic_device_h device_handle)
+{
+       char str_handle[32];
+       char *arr[1];
+       int ret;
+
+       /* check if handle is valid */
+       if (device_handle == NULL) {
+               _E("Invalid parameter : device_handle(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       snprintf(str_handle, sizeof(str_handle), "%u", device_handle);
+       arr[0] = str_handle;
+
+       /* request to deviced to open haptic device */
+       ret = dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_HAPTIC, DEVICED_INTERFACE_HAPTIC,
+                       METHOD_STOP_DEVICE, "u", arr);
+       if (ret < 0)
+               return HAPTIC_ERROR_OPERATION_FAILED;
+
+       return HAPTIC_ERROR_NONE;
+}
+
+API int haptic_get_effect_state(haptic_device_h device_handle, haptic_effect_h effect_handle, haptic_state_e *effect_state)
+{
+       char str_index[32];
+       char *arr[1];
+       int ret;
+
+       /* check if handle is valid */
+       if (device_handle == NULL) {
+               _E("Invalid parameter : device_handle(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* check if pointer is valid */
+       if (effect_state == NULL) {
+               _E("Invalid parameter : effect_state(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       snprintf(str_index, sizeof(str_index), "%d", HAPTIC_DEVICE_0);
+       arr[0] = str_index;
+
+       /* request to deviced to open haptic device */
+       ret = dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_HAPTIC, DEVICED_INTERFACE_HAPTIC,
+                       METHOD_GET_STATE, "i", arr);
+       if (ret < 0)
+               return HAPTIC_ERROR_OPERATION_FAILED;
+
+       *effect_state = (haptic_state_e)ret;
+       return HAPTIC_ERROR_NONE;
+}
+
+API int haptic_create_effect(unsigned char *vibe_buffer,
+                         int max_bufsize,
+                         haptic_effect_element_s *elem_arr,
+                         int max_elemcnt)
+{
+       DBusError err;
+       DBusMessage *msg;
+       dbus_bool_t ret;
+       char str_bufsize[32];
+       char str_elemcnt[32];
+       char *arr[4];
+       char *data;
+       int i, temp, size, ret_val;
+       struct dbus_byte bytes;
+
+       /* check if passed arguments are valid */
+       if (vibe_buffer == NULL) {
+               _E("Invalid parameter : vibe_buffer(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (max_bufsize <= 0) {
+               _E("Invalid parameter : max_bufsize(%d)", max_bufsize);
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (elem_arr == NULL) {
+               _E("Invalid parameter : elem_arr(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (max_elemcnt <= 0) {
+               _E("Invalid parameter : max_elemcnt(%d)", max_elemcnt);
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* convert to proper feedback level in case of auto */
+       for (i = 0; i < max_elemcnt; i++) {
+               if (elem_arr[i].haptic_level == HAPTIC_FEEDBACK_AUTO) {
+                       vconf_get_int(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, &temp);
+                       elem_arr[i].haptic_level = temp*20;
+               }
+       }
+
+       snprintf(str_bufsize, sizeof(str_bufsize), "%d", max_bufsize);
+       arr[0] = str_bufsize;
+       bytes.size = sizeof(haptic_effect_element_s)*max_elemcnt;
+       bytes.data = (unsigned char*)elem_arr;
+       arr[2] = (char*)&bytes;
+       snprintf(str_elemcnt, sizeof(str_elemcnt), "%d", max_elemcnt);
+       arr[3] = str_elemcnt;
+
+       /* request to deviced to open haptic device */
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_HAPTIC, DEVICED_INTERFACE_HAPTIC,
+                       METHOD_CREATE_EFFECT, "iayi", arr);
+       if (!msg)
+               return HAPTIC_ERROR_OPERATION_FAILED;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, &size,
+                       DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               goto err;
+       }
+
+       if (ret_val < 0) {
+               _E("%s-%s failed : %d", DEVICED_INTERFACE_HAPTIC, METHOD_CREATE_EFFECT, ret_val);
+               goto err;
+       }
+
+       if (max_bufsize < size) {
+               _E("max_bufsize(%d) is smaller than effect buffer size(%d)", max_bufsize, size);
+               goto err;
+       }
+
+       memcpy(vibe_buffer, data, max_bufsize);
+       dbus_message_unref(msg);
+       return HAPTIC_ERROR_NONE;
+err:
+       dbus_message_unref(msg);
+       return HAPTIC_ERROR_OPERATION_FAILED;
+}
+
+API int haptic_save_effect(const unsigned char *vibe_buffer,
+                       int max_bufsize,
+                       const char *file_path)
+{
+       struct stat buf;
+       int size, ret;
+
+       /* check if passed arguments are valid */
+       if (vibe_buffer == NULL) {
+               _E("Invalid parameter : vibe_buffer(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (max_bufsize <= 0) {
+               _E("Invalid parameter : max_bufsize(%d)", max_bufsize);
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (file_path == NULL) {
+               _E("Invalid parameter : file_path(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* check if the file already exists */
+       if (!stat(file_path, &buf)) {
+               _E("Already exist : file_path(%s)", file_path);
+               return HAPTIC_ERROR_FILE_EXISTS;
+       }
+
+       _D("file path : %s", file_path);
+       ret = save_data(vibe_buffer, max_bufsize, file_path);
+       if (ret < 0) {
+               _E("fail to save data");
+               return HAPTIC_MODULE_OPERATION_FAILED;
+       }
+
+       return HAPTIC_ERROR_NONE;
+}
+
+API int haptic_get_file_duration(haptic_device_h device_handle, const char *file_path, int *file_duration)
+{
+       char *vibe_buffer;
+       int size, ret;
+
+       vibe_buffer = convert_file_to_buffer(file_path, &size);
+       if (!vibe_buffer) {
+               _E("Convert file to buffer error");
+               return HAPTIC_ERROR_OPERATION_FAILED;
+       }
+
+       ret = haptic_get_buffers_duration(device_handle,
+                                                                        vibe_buffer,
+                                                                        size,
+                                                                        file_duration);
+       free(vibe_buffer);
+       return ret;
+}
+
+API int haptic_get_buffer_duration(haptic_device_h device_handle, const unsigned char *vibe_buffer, int *buffer_duration)
+{
+       return haptic_get_buffers_duration(device_handle,
+                                                                       vibe_buffer,
+                                                                       TEMP_BUFFER_SIZE,
+                                                                       buffer_duration);
+}
+
+API int haptic_get_buffers_duration(haptic_device_h device_handle, const unsigned char *vibe_buffer, int size, int *buffer_duration)
+{
+       char str_handle[32];
+       char *arr[3];
+       struct dbus_byte bytes;
+       int ret;
+
+       /* check if handle is valid */
+       if (device_handle == NULL) {
+               _E("Invalid parameter : device_handle(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (vibe_buffer == NULL) {
+               _E("Invalid parameter : vibe_buffer(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* check if pointer is valid */
+       if (buffer_duration == NULL) {
+               _E("Invalid parameter : buffer_duration(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       snprintf(str_handle, sizeof(str_handle), "%u", device_handle);
+       arr[0] = str_handle;
+       bytes.size = size;
+       bytes.data = vibe_buffer;
+       arr[2] = (char*)&bytes;
+
+       /* request to deviced to open haptic device */
+       ret = dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_HAPTIC, DEVICED_INTERFACE_HAPTIC,
+                       METHOD_GET_DURATION, "uay", arr);
+       if (ret < 0)
+               return HAPTIC_ERROR_OPERATION_FAILED;
+
+       *buffer_duration = ret;
+       return HAPTIC_ERROR_NONE;
+}
+
+API int haptic_save_led(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path)
+{
+       struct stat buf;
+       char str_bufsize[32];
+       char *arr[3];
+       struct dbus_byte bytes;
+       int ret;
+
+       /* check if passed arguments are valid */
+       if (vibe_buffer == NULL) {
+               _E("Invalid parameter : vibe_buffer(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (max_bufsize <= 0) {
+               _E("Invalid parameter : max_bufsize(%d)", max_bufsize);
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (file_path == NULL) {
+               _E("Invalid parameter : file_path(NULL)");
+               return HAPTIC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* check if the file already exists */
+       if (!stat(file_path, &buf)) {
+               _E("Already exist : file_path(%s)", file_path);
+               return HAPTIC_ERROR_FILE_EXISTS;
+       }
+
+       bytes.size = max_bufsize;
+       bytes.data = vibe_buffer;
+       arr[1] = (char*)&bytes;
+       arr[2] = (char*)file_path;
+
+       /* request to deviced to open haptic device */
+       ret = dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_HAPTIC, DEVICED_INTERFACE_HAPTIC,
+                       METHOD_SAVE_BINARY, "ays", arr);
+       if (ret < 0)
+               return HAPTIC_ERROR_OPERATION_FAILED;
+
+       return HAPTIC_ERROR_NONE;
+}
diff --git a/src/libdeviced/led.c b/src/libdeviced/led.c
new file mode 100644 (file)
index 0000000..86c23a7
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * 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 <stdbool.h>
+#include <errno.h>
+
+#include "log.h"
+#include "dbus.h"
+#include "common.h"
+
+#define METHOD_GET_BRIGHTNESS          "GetBrightness"
+#define METHOD_GET_MAX_BRIGHTNESS      "GetMaxBrightness"
+#define METHOD_SET_BRIGHTNESS          "SetBrightness"
+#define METHOD_SET_IR_COMMAND          "SetIrCommand"
+#define METHOD_SET_MODE                                "SetMode"
+
+API int led_get_brightness(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_LED, DEVICED_INTERFACE_LED,
+                       METHOD_GET_BRIGHTNESS, NULL, NULL);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int led_get_max_brightness(void)
+{
+       DBusError err;
+       DBusMessage *msg;
+       int ret, ret_val;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_LED, DEVICED_INTERFACE_LED,
+                       METHOD_GET_MAX_BRIGHTNESS, NULL, NULL);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int led_set_brightness_with_noti(int val, bool enable)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *arr[2];
+       char buf_val[32];
+       char buf_noti[32];
+       int ret, ret_val;
+
+       snprintf(buf_val, sizeof(buf_val), "%d", val);
+       arr[0] = buf_val;
+       snprintf(buf_noti, sizeof(buf_noti), "%d", enable);
+       arr[1] = buf_noti;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_LED, DEVICED_INTERFACE_LED,
+                       METHOD_SET_BRIGHTNESS, "ii", arr);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int led_set_ir_command(char *value)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *arr[1];
+       int ret, ret_val;
+
+       arr[0] = value;
+
+       msg = dbus_method_sync_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_LED, DEVICED_INTERFACE_LED,
+                       METHOD_SET_IR_COMMAND, "s", arr);
+       if (!msg)
+               return -EBADMSG;
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &ret_val, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("no message : [%s:%s]", err.name, err.message);
+               dbus_error_free(&err);
+               ret_val = -EBADMSG;
+       }
+
+       dbus_message_unref(msg);
+       return ret_val;
+}
+
+API int led_set_mode_with_property(int mode, bool val, int on, int off, unsigned int color)
+{
+       DBusError err;
+       DBusMessage *msg;
+       char *arr[5];
+       char buf_mode[32], buf_val[32];
+       char buf_on[32], buf_off[32];
+       char buf_color[32];
+       int ret, ret_val;
+
+       snprintf(buf_mode, sizeof(buf_mode), "%d", mode);
+       arr[0] = buf_mode;
+       snprintf(buf_val, sizeof(buf_val), "%d", val);
+       arr[1] = buf_val;
+       snprintf(buf_on, sizeof(buf_on), "%d", on);
+       arr[2] = buf_on;
+       snprintf(buf_off, sizeof(buf_off), "%d", off);
+       arr[3] = buf_off;
+       snprintf(buf_color, sizeof(buf_color), "%lu", color);
+       arr[4] = buf_color;
+
+       return dbus_method_sync(DEVICED_BUS_NAME,
+                       DEVICED_PATH_LED, DEVICED_INTERFACE_LED,
+                       METHOD_SET_MODE, "iiiiu", arr);
+}
+
+API int led_set_mode_with_color(int mode, bool on, unsigned int color)
+{
+       return led_set_mode_with_property(mode, on, -1, -1, color);
+}
diff --git a/src/libdeviced/mmc.c b/src/libdeviced/mmc.c
new file mode 100644 (file)
index 0000000..73f1a1e
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * 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 "log.h"
+#include "dbus.h"
+#include "common.h"
+#include "dd-mmc.h"
+
+#define METHOD_REQUEST_SECURE_MOUNT            "RequestSecureMount"
+#define METHOD_REQUEST_SECURE_UNMOUNT  "RequestSecureUnmount"
+#define METHOD_REQUEST_MOUNT           "RequestMount"
+#define METHOD_REQUEST_UNMOUNT         "RequestUnmount"
+#define METHOD_REQUEST_FORMAT          "RequestFormat"
+
+#define ODE_MOUNT_STATE 1
+
+API int mmc_secure_mount(const char *mount_point)
+{
+       char *arr[1];
+       arr[0] = (char *)mount_point;
+       return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_MMC,
+                       DEVICED_INTERFACE_MMC, METHOD_REQUEST_SECURE_MOUNT, "s", arr);
+}
+
+API int mmc_secure_unmount(const char *mount_point)
+{
+       char *arr[1];
+       arr[0] = (char *)mount_point;
+       return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_MMC,
+                       DEVICED_INTERFACE_MMC, METHOD_REQUEST_SECURE_UNMOUNT, "s", arr);
+}
+
+static void mount_mmc_cb(void *data, DBusMessage *msg, DBusError *err)
+{
+       struct mmc_contents *mmc_data = (struct mmc_contents*)data;
+       DBusError r_err;
+       int r, mmc_ret;
+
+       _D("mount_mmc_cb called");
+
+       if (!msg) {
+               _E("no message [%s:%s]", err->name, err->message);
+               mmc_ret = -EBADMSG;
+               goto exit;
+       }
+
+       dbus_error_init(&r_err);
+       r = dbus_message_get_args(msg, &r_err, DBUS_TYPE_INT32, &mmc_ret, DBUS_TYPE_INVALID);
+       if (!r) {
+               _E("no message [%s:%s]", r_err.name, r_err.message);
+               dbus_error_free(&r_err);
+               mmc_ret = -EBADMSG;
+               goto exit;
+       }
+
+       _I("Mount State : %d", mmc_ret);
+
+//     if (mmc_ret == ODE_MOUNT_STATE)
+//             return;
+
+exit:
+       (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
+}
+
+API int deviced_request_mount_mmc(struct mmc_contents *mmc_data)
+{
+       void (*mount_cb)(void*, DBusMessage*, DBusError*) = NULL;
+       void *data = NULL;
+
+       if (mmc_data != NULL && mmc_data->mmc_cb != NULL) {
+               mount_cb = mount_mmc_cb;
+               data = mmc_data;
+       }
+
+       return dbus_method_async_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_MMC,
+                       DEVICED_INTERFACE_MMC,
+                       METHOD_REQUEST_MOUNT,
+                       NULL, NULL, mount_cb, -1, data);
+}
+
+static void unmount_mmc_cb(void *data, DBusMessage *msg, DBusError *err)
+{
+       struct mmc_contents *mmc_data = (struct mmc_contents*)data;
+       DBusError r_err;
+       int r, mmc_ret;
+
+       _D("unmount_mmc_cb called");
+
+       if (!msg) {
+               _E("no message [%s:%s]", err->name, err->message);
+               mmc_ret = -EBADMSG;
+               goto exit;
+       }
+
+       dbus_error_init(&r_err);
+       r = dbus_message_get_args(msg, &r_err, DBUS_TYPE_INT32, &mmc_ret, DBUS_TYPE_INVALID);
+       if (!r) {
+               _E("no message [%s:%s]", r_err.name, r_err.message);
+               dbus_error_free(&r_err);
+               mmc_ret = -EBADMSG;
+               goto exit;
+       }
+
+       _I("Unmount State : %d", mmc_ret);
+
+exit:
+       (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
+}
+
+API int deviced_request_unmount_mmc(struct mmc_contents *mmc_data, int option)
+{
+       char *arr[1];
+       char buf_opt[32];
+       void (*unmount_cb)(void*, DBusMessage*, DBusError*) = NULL;
+       void *data = NULL;
+
+       if (option < 0 || option > 1)
+               return -EINVAL;
+
+       if (mmc_data != NULL && mmc_data->mmc_cb != NULL) {
+               unmount_cb = unmount_mmc_cb;
+               data = mmc_data;
+       }
+
+       snprintf(buf_opt, sizeof(buf_opt), "%d", option);
+       arr[0] = buf_opt;
+       return dbus_method_async_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_MMC,
+                       DEVICED_INTERFACE_MMC,
+                       METHOD_REQUEST_UNMOUNT,
+                       "i", arr, unmount_cb, -1, data);
+}
+
+static void format_mmc_cb(void *data, DBusMessage *msg, DBusError *err)
+{
+       struct mmc_contents *mmc_data = (struct mmc_contents*)data;
+       DBusError r_err;
+       int r, mmc_ret;
+
+       _D("format_mmc_cb called");
+
+       if (!msg) {
+               _E("no message [%s:%s]", err->name, err->message);
+               mmc_ret = -EBADMSG;
+               goto exit;
+       }
+
+       dbus_error_init(&r_err);
+       r = dbus_message_get_args(msg, &r_err, DBUS_TYPE_INT32, &mmc_ret, DBUS_TYPE_INVALID);
+       if (!r) {
+               _E("no message [%s:%s]", r_err.name, r_err.message);
+               dbus_error_free(&r_err);
+               mmc_ret = -EBADMSG;
+               goto exit;
+       }
+
+       _I("Format State : %d", mmc_ret);
+
+exit:
+       (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
+}
+
+API int deviced_request_format_mmc(struct mmc_contents *mmc_data)
+{
+       return deviced_format_mmc(mmc_data, 1);
+}
+
+API int deviced_format_mmc(struct mmc_contents *mmc_data, int option)
+{
+       char *arr[1];
+       char buf_opt[32];
+       void (*format_cb)(void*, DBusMessage*, DBusError*) = NULL;
+       void *data = NULL;
+
+       if (option < 0 || option > 1)
+               return -EINVAL;
+
+       if (mmc_data != NULL && mmc_data->mmc_cb != NULL) {
+               format_cb = format_mmc_cb;
+               data = mmc_data;
+       }
+
+       snprintf(buf_opt, sizeof(buf_opt), "%d", option);
+       arr[0] = buf_opt;
+       return dbus_method_async_with_reply(DEVICED_BUS_NAME,
+                       DEVICED_PATH_MMC,
+                       DEVICED_INTERFACE_MMC,
+                       METHOD_REQUEST_FORMAT,
+                       "i", arr, format_cb, -1, data);
+}
diff --git a/src/libdeviced/storage.c b/src/libdeviced/storage.c
new file mode 100644 (file)
index 0000000..bd2552c
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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 <stdbool.h>
+#include <sys/stat.h>
+#include <vconf.h>
+#include <errno.h>
+
+#include "log.h"
+#include "common.h"
+#include "dd-deviced.h"
+#include "dd-storage.h"
+
+#define INT_PATH                               "/opt/media"
+#define EXT_PATH                               "/opt/storage/sdcard"
+#define EXT_PARENT_PATH                        "/opt/storage"
+#define EXT_OPTION1_PATH               "/mnt/mmc"
+
+static bool check_ext_mount(void)
+{
+       struct stat parent, ext;
+
+       if (stat(EXT_PATH, &ext) != 0 || stat(EXT_PARENT_PATH, &parent) != 0)
+               return false;
+
+       if (ext.st_dev == parent.st_dev)
+               return false;
+
+       return true;
+}
+
+API int storage_get_path(int type, unsigned char *path, int size)
+{
+       char *ext_path = EXT_PATH;
+       int option;
+
+       if (type > STORAGE_MAX || path == NULL)
+               return -EINVAL;
+
+       if (vconf_get_int(VCONFKEY_DEVICED_MOUNT_PATH_OPTION, &option) < 0)
+               return -EPERM;
+
+       _D("VCONFKEY_DEVICED_MOUNT_PATH_OPTION1 : %d, option : %d", VCONFKEY_DEVICED_MOUNT_PATH_OPTION1, option);
+       if (option == VCONFKEY_DEVICED_MOUNT_PATH_OPTION1)
+               ext_path = EXT_OPTION1_PATH;
+
+       switch (type) {
+       case STORAGE_DEFAULT:
+               if (check_ext_mount())
+                       snprintf(path, size, "%s", ext_path);
+               else
+                       snprintf(path, size, "");
+               break;
+       case STORAGE_INTERNAL:
+               snprintf(path, size, "%s", INT_PATH);
+               break;
+       case STORAGE_EXTERNAL:
+               snprintf(path, size, "%s", ext_path);
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
diff --git a/src/libdeviced/usbhost.c b/src/libdeviced/usbhost.c
new file mode 100644 (file)
index 0000000..ad5104a
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * 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 <E_DBus.h>
+
+#include "log.h"
+#include "common.h"
+#include "dbus.h"
+
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+
+#define METHOD_REQUEST_STORAGE_INFO_ALL   "StorageInfoAll"
+#define METHOD_REQUEST_STORAGE_MOUNT      "StorageMount"
+#define METHOD_REQUEST_STORAGE_UNMOUNT    "StorageUnmount"
+#define METHOD_REQUEST_STORAGE_FORMAT     "StorageFormat"
+#define SIGNAL_NAME_USB_STORAGE_CHANGED   "usb_storage_changed"
+#define RETRY_MAX 5
+
+struct signal_handler {
+       char *name;
+       E_DBus_Signal_Handler *handler;
+       void (*action)(char *type, char *path, int mount, void *param);
+       void *data;
+};
+
+static struct signal_handler handlers[] = {
+       { SIGNAL_NAME_USB_STORAGE_CHANGED    , NULL, NULL, NULL },
+};
+
+static E_DBus_Connection *conn = NULL;
+
+static int register_edbus_signal_handler(const char *path, const char *interface,
+               const char *name, E_DBus_Signal_Cb cb,
+               void (*action)(char *type, char *path, int mount, void *param),
+               void *data)
+{
+       int i, ret;
+
+       if (!conn) {
+               _E("Use init_usbhost_signal() first to use this function");
+               ret = -1;
+               goto out;
+       }
+
+       for (i = 0 ; i < ARRAY_SIZE(handlers) ; i++) {
+               if (strncmp(handlers[i].name, name, strlen(name)))
+                       continue;
+               break;
+       }
+       if (i >= ARRAY_SIZE(handlers)) {
+               _E("Failed to find \"storage_changed\" signal");
+               ret = -1;
+               goto out;
+       }
+
+       if (handlers[i].handler) {
+               _E("The handler is already registered");
+               ret = -1;
+               goto out;
+       }
+
+       handlers[i].handler = e_dbus_signal_handler_add(conn, NULL, path,
+                                       interface, name, cb, NULL);
+       if (!(handlers[i].handler)) {
+               _E("fail to add edbus handler");
+               ret = -1;
+               goto out;
+       }
+       handlers[i].action = action;
+       handlers[i].data = data;
+
+       return 0;
+
+out:
+       return ret;
+}
+
+static void storage_signal_handler(void *data, DBusMessage *msg)
+{
+       int i;
+       char *type, *path;
+       int mount;
+       DBusError err;
+
+       if (dbus_message_is_signal(msg, DEVICED_INTERFACE_USBHOST, SIGNAL_NAME_USB_STORAGE_CHANGED) == 0) {
+               _E("The signal is not for storage changed");
+               return;
+       }
+
+       dbus_error_init(&err);
+
+       if (dbus_message_get_args(msg, &err,
+                               DBUS_TYPE_STRING, &type,
+                               DBUS_TYPE_STRING, &path,
+                               DBUS_TYPE_INT32, &mount,
+                               DBUS_TYPE_INVALID) == 0) {
+               _E("Failed to get storage info");
+               return;
+       }
+
+       for (i = 0 ; i < ARRAY_SIZE(handlers) ; i++) {
+               if (strcmp(handlers[i].name, SIGNAL_NAME_USB_STORAGE_CHANGED))
+                       continue;
+               break;
+       }
+       if (i >= ARRAY_SIZE(handlers)) {
+               _E("Failed to find \"storage_changed\" signal");
+               return;
+       }
+
+       if (handlers[i].action)
+               handlers[i].action(type, path, mount, handlers[i].data);
+}
+
+API int init_usbhost_signal(void)
+{
+       int retry;
+
+       if (conn)
+               return 0;
+
+       retry = 0;
+       do {
+               if (e_dbus_init() > 0)
+                       break;
+               if (retry >= RETRY_MAX)
+                       return -1;
+       } while (retry++ < RETRY_MAX);
+
+       conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
+       if (!conn) {
+               _E("Failed to get edbus bus");
+               e_dbus_shutdown();
+               return -1;
+       }
+
+       return 0;
+}
+
+API void deinit_usbhost_signal(void)
+{
+       int i;
+
+       if (!conn)
+               return;
+
+       for (i = 0 ; i < ARRAY_SIZE(handlers) ; i++) {
+               if (handlers[i].handler) {
+                       e_dbus_signal_handler_del(conn, handlers[i].handler);
+                       handlers[i].handler = NULL;
+               }
+               handlers[i].action = NULL;
+               handlers[i].data = NULL;
+       }
+
+       e_dbus_connection_close(conn);
+       conn = NULL;
+
+       e_dbus_shutdown();
+}
+
+API int request_usb_storage_info(void)
+{
+       return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_USBHOST,
+                       DEVICED_INTERFACE_USBHOST, METHOD_REQUEST_STORAGE_INFO_ALL, NULL, NULL);
+}
+
+API int register_usb_storage_change_handler(
+               void (*storage_changed)(char *type, char *path, int mount, void *),
+               void *data)
+{
+       if (!storage_changed)
+               return -EINVAL;
+
+       return register_edbus_signal_handler(DEVICED_PATH_USBHOST,
+                       DEVICED_INTERFACE_USBHOST,
+                       SIGNAL_NAME_USB_STORAGE_CHANGED,
+                       storage_signal_handler,
+                       storage_changed,
+                       data);
+}
+
+API int unregister_usb_storage_change_handler(void)
+{
+       int i;
+
+       for (i = 0 ; i < ARRAY_SIZE(handlers) ; i++) {
+               if (strcmp(handlers[i].name, SIGNAL_NAME_USB_STORAGE_CHANGED))
+                       continue;
+               if (handlers[i].handler == NULL)
+                       continue;
+
+               e_dbus_signal_handler_del(conn, handlers[i].handler);
+               handlers[i].handler = NULL;
+               handlers[i].action = NULL;
+               handlers[i].data = NULL;
+               return 0;
+       }
+       return -1;
+}
+
+API int mount_usb_storage(char *path)
+{
+       char *param[1];
+
+       if (!path)
+               return -1;
+
+       param[0] = path;
+       return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_USBHOST,
+                       DEVICED_INTERFACE_USBHOST, METHOD_REQUEST_STORAGE_MOUNT, "s", param);
+}
+
+API int unmount_usb_storage(char *path)
+{
+       char *param[1];
+
+       if (!path)
+               return -1;
+
+       param[0] = path;
+       return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_USBHOST,
+                       DEVICED_INTERFACE_USBHOST, METHOD_REQUEST_STORAGE_UNMOUNT, "s", param);
+}
+
+API int format_usb_storage(char *path)
+{
+       char *param[1];
+
+       if (!path)
+               return -1;
+
+       param[0] = path;
+       return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_USBHOST,
+                       DEVICED_INTERFACE_USBHOST, METHOD_REQUEST_STORAGE_FORMAT, "s", param);
+}
diff --git a/src/mmc/app2ext.c b/src/mmc/app2ext.c
new file mode 100755 (executable)
index 0000000..a1318a6
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * 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 "core/log.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+#include "core/list.h"
+#include "mmc/mmc-handler.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;
+
+       _I("Attempt mount %s app to sdcard", pkgid);
+       r = app2ext_enable(pkgid);
+       if (r < 0)
+               return r;
+
+       _I("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);
+       _I("pkgid_head count : %d", n);
+
+       for (i = 0; i < n; ++i) {
+               str = DD_LIST_NTH(pkgid_head, 0);
+               _I("Attempt unmount %s app from sdcard", str);
+               r = app2ext_disable(str);
+               if (r < 0)
+                       return r;
+               _I("Unmount %s app from sdcard", str);
+               DD_LIST_REMOVE(pkgid_head, str);
+               free(str);
+       }
+
+       return 0;
+}
+
+static DBusMessage *edbus_request_mount_app2ext(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char *pkgid;
+       int ret;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_STRING, &pkgid, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (!mmc_check_mounted(MMC_MOUNT_POINT)) {
+               _I("Do not mounted");
+               ret = -ENODEV;
+               goto error;
+       }
+
+       ret = app2ext_mount(pkgid);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "RequestMountApp2ext",    "s", "i", edbus_request_mount_app2ext },
+};
+
+static void app2ext_init(void *data)
+{
+       int ret;
+
+       app2ext_dl = dlopen(APP2EXT_PLUGIN_PATH, RTLD_LAZY|RTLD_GLOBAL);
+       if (!app2ext_dl) {
+               _E("dlopen error (%s)", dlerror());
+               return;
+       }
+
+       app2ext_enable = dlsym(app2ext_dl, "app2ext_enable_external_pkg");
+       if (!app2ext_enable) {
+               _E("dlsym error (%s)", dlerror());
+               dlclose(app2ext_dl);
+               app2ext_dl = NULL;
+               return;
+       }
+
+       app2ext_disable = dlsym(app2ext_dl, "app2ext_disable_external_pkg");
+       if (!app2ext_disable) {
+               _E("dlsym error (%s)", dlerror());
+               dlclose(app2ext_dl);
+               app2ext_dl = NULL;
+               return;
+       }
+
+       ret = register_edbus_method(DEVICED_PATH_MMC, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+}
+
+static void app2ext_exit(void *data)
+{
+       if(!app2ext_dl)
+               return;
+
+       dlclose(app2ext_dl);
+       app2ext_dl = NULL;
+}
+
+const struct device_ops app2ext_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "app2ext",
+       .init     = app2ext_init,
+       .exit     = app2ext_exit,
+};
+
+DEVICE_OPS_REGISTER(&app2ext_device_ops)
diff --git a/src/mmc/config.c b/src/mmc/config.c
new file mode 100644 (file)
index 0000000..7202f16
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * 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 <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <stdbool.h>
+#include <assert.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/config-parser.h"
+#include "mmc-handler.h"
+#include "config.h"
+
+#define MAX_RATIO_CONF_FILE    "/etc/deviced/mmc.conf"
+#define MAX_RATIO_PATH         "/sys/class/block/mmcblk%d/bdi/max_ratio"
+#define MAX_RATIO_CONFIG_RETRY 5
+#define MAX_RATIO_DURATION             100
+
+static struct mmc_policy_type {
+       int max_ratio;
+} mmc_policy = {
+       .max_ratio = MAX_RATIO_DURATION,
+};
+
+static void mmc_max_ratio(void)
+{
+       char buf[PATH_MAX];
+       FILE *fp;
+       int ret;
+       int num;
+       int retry;
+
+       num = get_block_number();
+       snprintf(buf, PATH_MAX, MAX_RATIO_PATH, num);
+
+       for (retry = MAX_RATIO_CONFIG_RETRY; retry > 0 ; retry--) {
+               ret = sys_set_int(buf, mmc_policy.max_ratio);
+               if (ret == 0)
+                       break;
+       }
+       if (ret < 0)
+               _E("fail path : %s max_ratio: %d ret %d", buf, mmc_policy.max_ratio, ret);
+       else
+               _D("mmc bdi max : %d", mmc_policy.max_ratio);
+}
+
+static int load_config(struct parse_result *result, void *user_data)
+{
+       struct mmc_policy_type *policy = user_data;
+       char *name;
+       char *value;
+
+       _D("%s,%s,%s", result->section, result->name, result->value);
+
+       if (!policy)
+               return -EINVAL;
+
+       if (!MATCH(result->section, "MMC"))
+               return -EINVAL;
+
+       name = result->name;
+       value = result->value;
+       if (MATCH(name, "MaxRatio"))
+               policy->max_ratio = atoi(value);
+
+       return 0;
+}
+
+void mmc_load_config(void)
+{
+       int ret;
+       ret = config_parse(MAX_RATIO_CONF_FILE, load_config, &mmc_policy);
+       if (ret < 0)
+               _E("Failed to load %s, %d Use default value!", MAX_RATIO_CONF_FILE, ret);
+}
+
+void mmc_set_config(enum mmc_config_type type)
+{
+       switch(type) {
+       case MAX_RATIO:
+               mmc_max_ratio();
+       break;
+       }
+}
diff --git a/src/mmc/config.h b/src/mmc/config.h
new file mode 100644 (file)
index 0000000..0397910
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 __MMC_CONFIG_H__
+#define __MMC_CONFIG_H__
+
+#include <stdbool.h>
+
+enum mmc_config_type {
+       MAX_RATIO = 0,
+};
+
+void mmc_set_config(enum mmc_config_type type);
+void mmc_load_config(void);
+#endif /* __MMC_CONFIG_H__ */
diff --git a/src/mmc/cprm.c b/src/mmc/cprm.c
new file mode 100755 (executable)
index 0000000..776b69d
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * 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 <errno.h>
+#include <fcntl.h>
+#include <linux/ioctl.h>
+
+#include "core/log.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "mmc-handler.h"
+#include "core/edbus-handler.h"
+
+#define CPRM_E_BADARG          -2      /* Bad argments */
+#define CPRM_E_FAIL            -1      /* General error */
+#define CPRM_E_SUCCESS         0       /* Success */
+
+#define SETRESP(x)     (x << 11)
+#define R1RESP         SETRESP(1)                      /* R1 response command */
+#define ACMD           0x0400                          /* Is ACMD */
+#define DT             0x8000                          /* With data */
+#define DIR_IN         0x0000                          /* Data transfer read */
+#define DIR_OUT        0x4000                          /* Data transfer write */
+
+#define ACMD18         (18+R1RESP+ACMD+DT+DIR_IN)      /* Secure Read Multi Block */
+#define ACMD25         (25+R1RESP+ACMD+DT+DIR_OUT)     /* Secure Write Multiple Block */
+#define ACMD43         (43+R1RESP+ACMD+DT+DIR_IN)      /* Get MKB */
+#define ACMD44         (44+R1RESP+ACMD+DT+DIR_IN)      /* Get MID */
+#define ACMD45         (45+R1RESP+ACMD+DT+DIR_OUT)     /* Set CER RN1 */
+#define ACMD46         (46+R1RESP+ACMD+DT+DIR_IN)      /* Get CER RN2 */
+#define ACMD47         (47+R1RESP+ACMD+DT+DIR_OUT)     /* Set CER RES2 */
+#define ACMD48         (48+R1RESP+ACMD+DT+DIR_IN)      /* Get CER RES1 */
+
+#define MMC_IOCTL_BASE 0xB3            /* Same as MMC block device major number */
+#define MMC_IOCTL_SET_RETRY_AKE_PROCESS        _IOR(MMC_IOCTL_BASE, 104, int)
+
+struct cprm_request {
+       unsigned int    cmd;
+       unsigned long   arg;
+       unsigned int    *buff;
+       unsigned int    len;
+};
+
+static int cprm_fd;
+
+static DBusMessage *edbus_cprm_init(E_DBus_Object *obj, DBusMessage *msg)
+{
+
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int opt, ret = CPRM_E_SUCCESS;
+       char path[NAME_MAX];
+
+       ret = get_mmc_devpath(path);
+       if (ret < 0) {
+               ret = CPRM_E_SUCCESS;
+               _E("fail to check mmc");
+               if (cprm_fd)
+                       close(cprm_fd);
+               goto out;
+       }
+       _I("devpath :%s", path);
+       cprm_fd = open(path, O_RDWR);
+       if (cprm_fd < 0)
+               _E("fail to open");
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_cprm_terminate(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int opt, ret = CPRM_E_SUCCESS;
+
+       close(cprm_fd);
+       _I("cprm is terminated");
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_cprm_sendcmd(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter, arr;
+       DBusMessage *reply;
+       DBusError err;
+       int ret = CPRM_E_BADARG;
+       int result = CPRM_E_FAIL;
+       int slot;
+       struct cprm_request cprm_req;
+       char *data;
+       char path[NAME_MAX];
+
+       memset(&cprm_req, 0, sizeof(struct cprm_request));
+       ret = get_mmc_devpath(path);
+       if (ret < 0) {
+               _E("fail to check mmc");
+               ret = CPRM_E_FAIL;
+               if (cprm_fd)
+                       close(cprm_fd);
+               goto out;
+       }
+
+       if (cprm_fd <= 0) {
+               _E("fail to init");
+               goto out;
+       }
+
+       dbus_error_init(&err);
+
+       ret = dbus_message_get_args(msg, &err,
+                       DBUS_TYPE_INT32, &slot,
+                       DBUS_TYPE_INT32, &cprm_req.cmd,
+                       DBUS_TYPE_UINT32, &cprm_req.arg,
+                       DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, &cprm_req.len,
+                       DBUS_TYPE_INVALID);
+
+       if (!ret) {
+               _E("there is no message");
+               ret = CPRM_E_BADARG;
+               goto out;
+       }
+
+       if (cprm_req.len <= 0) {
+               _E("fail to check length %d", cprm_req.len);
+               goto out;
+       }
+
+       if ((cprm_req.cmd == ACMD43) || (cprm_req.cmd == ACMD18) || (cprm_req.cmd == ACMD25))
+               ret = ((cprm_req.len % 512) != 0) ? CPRM_E_BADARG : CPRM_E_SUCCESS;
+       else if ((cprm_req.cmd == ACMD44) || (cprm_req.cmd == ACMD45) || (cprm_req.cmd == ACMD46) ||
+           (cprm_req.cmd == ACMD47) || (cprm_req.cmd == ACMD48))
+               ret = (cprm_req.len != 8) ? CPRM_E_BADARG : CPRM_E_SUCCESS;
+       else
+               ret = CPRM_E_BADARG;
+
+       if (ret != CPRM_E_SUCCESS) {
+                       _E("fail to check param cmd %d. Invalid arguments..", (cprm_req.cmd & 0x3f));
+                       goto out;
+       }
+
+       cprm_req.buff = (unsigned int *)data;
+
+       result = ioctl(cprm_fd, cprm_req.cmd, &cprm_req);
+
+       if (result != CPRM_E_SUCCESS) {
+               _E("cprm_drvr_sendcmd: STUB_SENDCMD() return fail! result:%d", result);
+               ret = CPRM_E_FAIL;
+       } else {
+               ret = CPRM_E_SUCCESS;
+       }
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &arr);
+       dbus_message_iter_append_fixed_array(&arr, DBUS_TYPE_BYTE, &data, cprm_req.len);
+       dbus_message_iter_close_container(&iter, &arr);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_cprm_getslotstat(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       unsigned long ret = 0xFFFFFFFF;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_cprm_retry(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret = CPRM_E_BADARG;
+       char path[NAME_MAX];
+
+       ret = get_mmc_devpath(path);
+
+       if (ret < 0) {
+               _E("[cprm_drvr_retry] fail, so close cprm handle");
+               ret = CPRM_E_FAIL;
+               if (cprm_fd)
+                       close(cprm_fd);
+               goto out;
+       }
+
+       ret = ioctl(cprm_fd, MMC_IOCTL_SET_RETRY_AKE_PROCESS, NULL);
+
+       if (ret != CPRM_E_SUCCESS) {
+               _E("fail to retry :%d", ret);
+               ret = CPRM_E_FAIL;
+       } else {
+               ret = CPRM_E_SUCCESS;
+       }
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "CprmInit",           NULL,   "i",    edbus_cprm_init},
+       { "CprmTerminate",      NULL,   "i",    edbus_cprm_terminate},
+       { "CprmSendcmd",        "iiuay","ayi",  edbus_cprm_sendcmd},
+       { "CprmGetslotstat",    NULL,   "u",    edbus_cprm_getslotstat},
+       { "CprmRetry",          NULL,   "i",    edbus_cprm_retry},
+};
+
+static void cprm_init(void *data)
+{
+       int ret;
+
+       ret = register_edbus_method(DEVICED_PATH_MMC, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+}
+
+const struct device_ops cprm_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "cprm",
+       .init     = cprm_init,
+};
+
+DEVICE_OPS_REGISTER(&cprm_device_ops)
diff --git a/src/mmc/ext4.c b/src/mmc/ext4.c
new file mode 100644 (file)
index 0000000..6253dac
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * 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 <stdlib.h>
+#include <limits.h>
+#include <vconf.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/log.h"
+#include "mmc-handler.h"
+
+#define FS_EXT4_NAME   "ext4"
+
+#define FS_EXT4_SMACK_LABEL " /usr/bin/mmc-smack-label"
+
+struct popup_data {
+       char *name;
+       char *key;
+       char *value;
+};
+
+static const char *ext4_arg[] = {
+       "/sbin/mkfs.ext4",
+       NULL, NULL,
+};
+
+static const char *ext4_check_arg[] = {
+       "/sbin/fsck.ext4",
+       "-f", "-y", NULL, NULL,
+};
+
+static struct fs_check ext4_info = {
+       FS_TYPE_EXT4,
+       "ext4",
+       0x438,
+       2,
+       {0x53, 0xef},
+};
+
+static int mmc_popup_pid;
+
+static bool ext4_match(const char *devpath)
+{
+       char buf[4];
+       int fd, r;
+
+       fd = open(devpath, O_RDONLY);
+       if (fd < 0) {
+               _E("failed to open fd(%s) : %s", devpath, strerror(errno));
+               return false;
+       }
+
+       /* check fs type with magic code */
+       r = lseek(fd, ext4_info.offset, SEEK_SET);
+       if (r < 0)
+               goto error;
+
+       r = read(fd, buf, 2);
+       if (r < 0)
+               goto error;
+
+       _D("mmc search magic : 0x%2x, 0x%2x", buf[0],buf[1]);
+       if (memcmp(buf, ext4_info.magic, ext4_info.magic_sz))
+               goto error;
+
+       close(fd);
+       _D("MMC type : %s", ext4_info.name);
+       return true;
+
+error:
+       close(fd);
+       _E("failed to match with ext4(%s)", devpath);
+       return false;
+}
+
+static int ext4_check(const char *devpath)
+{
+       int argc;
+       argc = ARRAY_SIZE(ext4_check_arg);
+       ext4_check_arg[argc - 2] = devpath;
+       return run_child(argc, ext4_check_arg);
+}
+
+static int mmc_check_smack(const char *mount_point)
+{
+       char buf[NAME_MAX] = {0,};
+
+       snprintf(buf, sizeof(buf), "%s", mount_point);
+       launch_evenif_exist(FS_EXT4_SMACK_LABEL, buf);
+
+       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) {
+               _E("will be killed mmc-popup(%d)", mmc_popup_pid);
+               kill(mmc_popup_pid, SIGTERM);
+       }
+       return 0;
+}
+
+static int check_smack_popup(void)
+{
+       int ret = -1;
+       int val = -1;
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+
+       ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &val);
+       if (val == 1 || ret != 0) {
+               if (apps == NULL) {
+                       apps = find_device("apps");
+                       if (apps == NULL)
+                               return 0;
+               }
+               params = malloc(sizeof(struct popup_data));
+               if (params == NULL) {
+                       _E("Malloc failed");
+                       return -1;
+               }
+               params->name = MMC_POPUP_NAME;
+               params->key = MMC_POPUP_APP_KEY;
+               params->value = MMC_POPUP_SMACK_VALUE;
+               apps->init(params);
+               free(params);
+       }
+
+       return 0;
+}
+
+static int ext4_mount(bool smack, const char *devpath, const char *mount_point)
+{
+       int r, retry = RETRY_COUNT;
+
+       do {
+               r = mount(devpath, mount_point, "ext4", 0, NULL);
+               if (!r) {
+                       _D("Mounted mmc card [ext4]");
+                       if (smack) {
+                               check_smack_popup();
+                               mmc_check_smack(mount_point);
+                       }
+                       return 0;
+               }
+               usleep(100000);
+       } while (r < 0 && errno == ENOENT && retry-- > 0);
+
+       return -errno;
+}
+
+static int ext4_format(const char *devpath)
+{
+       int argc;
+       argc = ARRAY_SIZE(ext4_arg);
+       ext4_arg[argc - 2] = devpath;
+       return run_child(argc, ext4_arg);
+}
+
+static const struct mmc_fs_ops ext4_ops = {
+       .type = FS_TYPE_EXT4,
+       .name = "ext4",
+       .match = ext4_match,
+       .check = ext4_check,
+       .mount = ext4_mount,
+       .format = ext4_format,
+};
+
+static void __CONSTRUCTOR__ module_init(void)
+{
+       add_fs(&ext4_ops);
+}
+/*
+static void __DESTRUCTOR__ module_exit(void)
+{
+       remove_fs(&ext4_ops);
+}
+*/
diff --git a/src/mmc/mmc-handler.c b/src/mmc/mmc-handler.c
new file mode 100644 (file)
index 0000000..5493a92
--- /dev/null
@@ -0,0 +1,978 @@
+/*
+ * 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 <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <sys/statvfs.h>
+#include <errno.h>
+#include <vconf.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/statfs.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <assert.h>
+
+#include "core/log.h"
+#include "core/device-handler.h"
+#include "core/device-notifier.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "mmc-handler.h"
+#include "config.h"
+#include "core/edbus-handler.h"
+#include "core/list.h"
+#include "core/config-parser.h"
+
+#define VCONFKEY_INTERNAL_PRIVATE_MMC_ID       "db/private/sysman/mmc_device_id"
+
+#define MMC_PARENT_PATH        "/opt/storage"
+#define MMC_DEV                        "/dev/mmcblk"
+
+#define SMACKFS_MAGIC  0x43415d53
+#define SMACKFS_MNT            "/smack"
+
+#ifndef ST_RDONLY
+#define ST_RDONLY              0x0001
+#endif
+
+#define MMC_32GB_SIZE  61315072
+#define FORMAT_RETRY   3
+#define UNMOUNT_RETRY  5
+
+#define ODE_MOUNT_STATE        1
+
+enum unmount_operation {
+       UNMOUNT_NORMAL = 0,
+       UNMOUNT_FORCE,
+};
+
+enum mmc_operation {
+       MMC_MOUNT = 0,
+       MMC_UNMOUNT,
+       MMC_FORMAT,
+       MMC_END,
+};
+
+static void *mount_start(void *arg);
+static void *unmount_start(void *arg);
+static void *format_start(void *arg);
+
+static const struct mmc_thread_func {
+       enum mmc_operation type;
+       void *(*func) (void*);
+} mmc_func[MMC_END] = {
+       [MMC_MOUNT] = {.type = MMC_MOUNT, .func = mount_start},
+       [MMC_UNMOUNT] = {.type = MMC_UNMOUNT, .func = unmount_start},
+       [MMC_FORMAT] = {.type = MMC_FORMAT, .func = format_start},
+};
+
+struct mmc_data {
+       int option;
+       char *devpath;
+};
+
+struct popup_data {
+       char *name;
+       char *key;
+       char *value;
+};
+
+static dd_list *fs_head;
+static char *mmc_curpath;
+static bool smack = false;
+static bool mmc_disabled = false;
+
+int __WEAK__ app2ext_unmount(void);
+
+static void __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 = true;
+       _I("smackfs check %d", smack);
+}
+
+void add_fs(const struct mmc_fs_ops *fs)
+{
+       DD_LIST_APPEND(fs_head, (void*)fs);
+}
+
+void remove_fs(const struct mmc_fs_ops *fs)
+{
+       DD_LIST_REMOVE(fs_head, (void*)fs);
+}
+
+const struct mmc_fs_ops *find_fs(enum mmc_fs_type type)
+{
+       struct mmc_fs_ops *fs;
+       dd_list *elem;
+
+       DD_LIST_FOREACH(fs_head, elem, fs) {
+               if (fs->type == type)
+                       return fs;
+       }
+       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 void launch_syspopup(char *str)
+{
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+
+       if (apps == NULL) {
+               apps = find_device("apps");
+               if (apps == NULL)
+                       return;
+       }
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return;
+       }
+       params->name = MMC_POPUP_NAME;
+       params->key = POPUP_KEY_CONTENT;
+       params->value = strdup(str);
+       apps->init((void *)params);
+       free(params);
+}
+
+static int get_partition(const char *devpath, char *subpath)
+{
+       char path[NAME_MAX];
+       int i;
+
+       for (i = 1; i < 5; ++i) {
+               snprintf(path, sizeof(path), "%sp%d", devpath, i);
+               if (!access(path, R_OK)) {
+                       strncpy(subpath, path, strlen(path));
+                       return 0;
+               }
+       }
+       return -ENODEV;
+}
+
+static int create_partition(const char *devpath)
+{
+       int r;
+       char data[NAME_MAX];
+
+       snprintf(data, sizeof(data), "\"n\\n\\n\\n\\n\\nw\" | fdisk %s", devpath);
+
+       r = launch_evenif_exist("/usr/bin/printf", data);
+       if (WIFSIGNALED(r) && (WTERMSIG(r) == SIGINT || WTERMSIG(r) == SIGQUIT || WEXITSTATUS(r)))
+               return -1;
+
+       return 0;
+}
+
+static int mmc_check_and_unmount(const char *path)
+{
+       int ret = 0, retry = 0;
+       while (mount_check(path)) {
+               ret = umount(path);
+               if (ret < 0) {
+                       retry++;
+                       if (retry > UNMOUNT_RETRY)
+                               return -errno;
+               }
+       }
+       return ret;
+}
+
+int get_block_number(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) {
+               _E("Can not open directory..");
+               return -1;
+       }
+
+       r = chdir("/sys/block");
+       if (r < 0) {
+               _E("Fail to change the directory..");
+               closedir(dp);
+               return r;
+       }
+
+       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) {
+                                       continue;
+                               }
+                               r = read(fd, buf, 10);
+                               if ((r >= 0) && (r < 10))
+                                       buf[r] = '\0';
+                               else
+                                       _E("%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) {
+                                               _E("Memory Allocation Failed");
+                                               closedir(dp);
+                                               return -1;
+                                       }
+                                       mmcblk_num =
+                                           atoi(str_mmcblk_num);
+
+                                       free(str_mmcblk_num);
+                                       closedir(dp);
+                                       _D("%d", mmcblk_num);
+
+                                       snprintf(buf, 255, "/sys/block/%s/device/cid", dir->d_name);
+
+                                       fd = open(buf, O_RDONLY);
+                                       if (fd == -1) {
+                                               _E("%s open error", buf, strerror(errno));
+                                               return mmcblk_num;
+                                       }
+                                       r = read(fd, buf, 255);
+                                       if ((r >=0) && (r < 255)) {
+                                               buf[r] = '\0';
+                                       } else {
+                                               _E("%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 {
+                                               _E("failed to get pre_mmc_device_id");
+                                       }
+                                       return mmcblk_num;
+                               }
+                       }
+
+               }
+       }
+       closedir(dp);
+       _E("failed to find mmc block number");
+       return -1;
+}
+
+static int find_mmc_node(char devpath[])
+{
+       int num;
+
+       num = get_block_number();
+       if (num < 0)
+               return -ENODEV;
+
+       snprintf(devpath, NAME_MAX, "%s%d", MMC_DEV, num);
+       return 0;
+}
+
+static int get_mmc_size(const char *devpath)
+{
+       int fd, r;
+       unsigned long long ullbytes;
+       unsigned int nbytes;
+
+       fd = open(devpath, O_RDONLY);
+       if (fd < 0) {
+               _E("open error");
+               return -EINVAL;
+       }
+
+       r = ioctl(fd, BLKGETSIZE64, &ullbytes);
+       close(fd);
+
+       if (r < 0) {
+               _E("ioctl BLKGETSIZE64 error");
+               return -EINVAL;
+       }
+
+       nbytes = ullbytes/512;
+       _D("block size(64) : %d", nbytes);
+       return nbytes;
+}
+
+static int 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 mmc_mount(const char *devpath, const char *mount_point)
+{
+       struct mmc_fs_ops *fs;
+       dd_list *elem;
+       char path[NAME_MAX] = {0,};
+       int r;
+
+       /* mmc_disabled set by start/stop func. */
+       if (mmc_disabled)
+               return -EWOULDBLOCK;
+
+       if (!devpath)
+               return -ENODEV;
+
+       /* check partition */
+       r = get_partition(devpath, path);
+       if (!r)
+               devpath = path;
+
+       DD_LIST_FOREACH(fs_head, elem, fs) {
+               if (fs->match(devpath))
+                       break;
+       }
+
+       if (!fs)
+               return -EINVAL;
+
+       _D("devpath : %s", devpath);
+       r = fs->check(devpath);
+       if (r < 0)
+               _E("failt to check devpath : %s", devpath);
+
+       r = fs->mount(smack, devpath, mount_point);
+       if (r < 0)
+               return r;
+
+       r = rw_mount(mount_point);
+       if (r < 0)
+               return -EROFS;
+
+       return 0;
+}
+
+static void *mount_start(void *arg)
+{
+       struct mmc_data *data = (struct mmc_data*)arg;
+       char *devpath;
+       int r;
+
+       devpath = data->devpath;
+
+       assert(devpath);
+
+       /* clear previous filesystem */
+       mmc_check_and_unmount(MMC_MOUNT_POINT);
+
+       /* check mount point */
+       if (access(MMC_MOUNT_POINT, R_OK) != 0) {
+               if (mkdir(MMC_MOUNT_POINT, 0755) < 0) {
+                       r = -errno;
+                       goto error;
+               }
+       }
+
+       /* mount operation */
+       r = mmc_mount(devpath, MMC_MOUNT_POINT);
+       if (r == -EROFS)
+               launch_syspopup("mountrdonly");
+       else if (r < 0)
+               goto error;
+
+       mmc_set_config(MAX_RATIO);
+
+       free(devpath);
+       free(data);
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED);
+       return 0;
+
+error:
+       launch_syspopup("mounterr");
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_FAILED);
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
+
+       free(devpath);
+       free(data);
+       _E("failed to mount device : %s", strerror(-r));
+       return (void *)r;
+}
+
+static int mmc_unmount(int option, const char *mount_point)
+{
+       int r, retry = 0;
+       int kill_op;
+
+       /* try to unmount app2ext */
+       r = app2ext_unmount();
+       if (r < 0)
+               _I("Faild to unmount app2ext : %s", strerror(-r));
+       r = mmc_check_and_unmount(mount_point);
+       if (!r)
+               return r;
+       if (option == UNMOUNT_NORMAL) {
+               _I("Failed to unmount with normal option : %s", strerror(-r));
+               return r;
+       }
+
+       _I("Execute force unmount!");
+       /* Force Unmount Scenario */
+       while (1) {
+               switch (retry++) {
+               case 0:
+                       /* At first, notify to other app who already access sdcard */
+                       _I("Notify to other app who already access sdcard");
+                       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
+                       break;
+               case 1:
+                       /* Second, kill app with SIGTERM */
+                       _I("Kill app with SIGTERM");
+                       terminate_process(MMC_MOUNT_POINT, false);
+                       break;
+               case 2:
+                       /* Last time, kill app with SIGKILL */
+                       _I("Kill app with SIGKILL");
+                       terminate_process(MMC_MOUNT_POINT, true);
+                       break;
+               default:
+                       if (umount2(mount_point, MNT_DETACH) != 0) {
+                               _I("Failed to unmount with lazy option : %s", strerror(errno));
+                               return -errno;
+                       }
+                       return 0;
+               }
+
+               /* it takes some seconds til other app completely clean up */
+               usleep(500*1000);
+
+               /* try to unmount app2ext */
+               r = app2ext_unmount();
+               if (r < 0)
+                       _I("Faild to unmount app2ext : %s", strerror(-r));
+
+               r = mmc_check_and_unmount(mount_point);
+               if (!r)
+                       break;
+       }
+
+       return r;
+}
+
+static void *unmount_start(void *arg)
+{
+       struct mmc_data *data = (struct mmc_data*)arg;
+       int option, r;
+
+       option = data->option;
+
+       assert(option == UNMOUNT_NORMAL || option == UNMOUNT_FORCE);
+
+       r = mmc_unmount(option, MMC_MOUNT_POINT);
+       if (r < 0)
+               goto error;
+
+       free(data);
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED);
+       return 0;
+
+error:
+       free(data);
+       _E("Failed to unmount device : %s", strerror(-r));
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
+       return (void *)r;
+}
+
+static int format(const char *devpath)
+{
+       const struct mmc_fs_ops *fs = NULL;
+       dd_list *elem;
+       char path[NAME_MAX] = {0,};
+       int r, size, retry;
+
+       if (!devpath)
+               return -ENODEV;
+
+       /* check partition */
+       r = get_partition(devpath, path);
+       if (!r) {
+               /* if there is partition, find partition file system */
+               DD_LIST_FOREACH(fs_head, elem, fs) {
+                       if (fs->match(path))
+                               break;
+               }
+       } else {
+               /* if there isn't partition, create partition */
+               create_partition(devpath);
+               r = get_partition(devpath, path);
+               if (r < 0)
+                       memcpy(path, devpath, strlen(devpath));
+       }
+
+       _I("format partition : %s", path);
+
+       if (!fs) {
+               /* find root file system */
+               DD_LIST_FOREACH(fs_head, elem, fs) {
+                       if (fs->match(devpath))
+                               break;
+               }
+       }
+
+       if (!fs) {
+               /* cannot find root and partition file system,
+                  find suitable file system */
+               size = get_mmc_size(path);
+               if (size <= MMC_32GB_SIZE)
+                       fs = find_fs(FS_TYPE_VFAT);
+               else
+                       fs = find_fs(FS_TYPE_EXFAT);
+       }
+
+       if (!fs)
+               return -EINVAL;
+
+       for (retry = FORMAT_RETRY; retry > 0; --retry) {
+               fs->check(devpath);
+               _D("format path : %s", path);
+               r = fs->format(path);
+               if (!r)
+                       break;
+       }
+       return r;
+}
+
+static void *format_start(void *arg)
+{
+       struct mmc_data *data = (struct mmc_data*)arg;
+       char *devpath;
+       int option, r, key = VCONFKEY_SYSMAN_MMC_MOUNTED;
+       bool format_ret = true;
+
+       option = data->option;
+       devpath = data->devpath;
+
+       assert(devpath);
+       assert(option == UNMOUNT_NORMAL || option == UNMOUNT_FORCE);
+
+       _I("Format Start (option:%d)", option);
+       r = mmc_unmount(option, MMC_MOUNT_POINT);
+       if (r < 0)
+               goto release_memory;
+
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS, VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS_NOW);
+       r = format(devpath);
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS, VCONFKEY_SYSMAN_MMC_FORMAT_PROGRESS_NONE);
+       if (r != 0)
+               format_ret = false;
+
+       mount_start(arg);
+       if (!format_ret)
+               goto error;
+       _I("Format Successful");
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, VCONFKEY_SYSMAN_MMC_FORMAT_COMPLETED);
+       return 0;
+
+release_memory:
+       free(devpath);
+       free(data);
+error:
+       _E("Format Failed : %s", strerror(-r));
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_FORMAT, VCONFKEY_SYSMAN_MMC_FORMAT_FAILED);
+       return (void*)r;
+}
+
+static int mmc_make_thread(int type, int option, const char *devpath)
+{
+       pthread_t th;
+       struct mmc_data *pdata;
+       int r;
+
+       if (type < 0 || type >= MMC_END)
+               return -EINVAL;
+
+       pdata = malloc(sizeof(struct mmc_data));
+       if (!pdata) {
+               _E("malloc failed");
+               return -errno;
+       }
+
+       if (option >= 0)
+               pdata->option = option;
+       if (devpath)
+               pdata->devpath = strdup(devpath);
+       r = pthread_create(&th, NULL, mmc_func[type].func, pdata);
+       if (r != 0) {
+               _E("pthread create failed");
+               free(pdata->devpath);
+               free(pdata);
+               return -EPERM;
+       }
+
+       pthread_detach(th);
+       return 0;
+}
+
+static int mmc_inserted(const char *devpath)
+{
+       int r;
+       _I("MMC inserted : %s", devpath);
+       mmc_curpath = strdup(devpath);
+       r = mmc_make_thread(MMC_MOUNT, -1, devpath);
+       if (r < 0)
+               return r;
+       return 0;
+}
+
+static int mmc_removed(void)
+{
+       _I("MMC removed");
+       /* first, try to unmount app2ext */
+       app2ext_unmount();
+       /* unmount */
+       mmc_check_and_unmount((const char *)MMC_MOUNT_POINT);
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_REMOVED);
+       free(mmc_curpath);
+       mmc_curpath = NULL;
+       return 0;
+}
+
+static int mmc_changed_cb(void *data)
+{
+       char *devpath = (char*)data;
+
+       /* if MMC is inserted */
+       if (devpath)
+               return mmc_inserted(devpath);
+       else
+               return mmc_removed();
+}
+
+static int mmc_booting_done(void* data)
+{
+       char devpath[NAME_MAX] = {0,};
+       int r;
+
+       /* check mmc exists */
+       r = find_mmc_node(devpath);
+       if (r < 0)
+               return 0;
+
+       /* if MMC exists */
+       return mmc_inserted(devpath);
+}
+
+static DBusMessage *edbus_request_secure_mount(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char *path;
+       int ret;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path,
+                       DBUS_TYPE_INVALID);
+       if (!ret) {
+               ret = -EBADMSG;
+               goto error;
+       }
+
+       if (!mmc_curpath) {
+               ret = -ENODEV;
+               goto error;
+       }
+
+       /* check mount point */
+       if (access(path, R_OK) != 0) {
+               if (mkdir(path, 0755) < 0) {
+                       ret = -errno;
+                       goto error;
+               }
+       }
+
+       _D("mount path : %s", path);
+       ret = mmc_mount(mmc_curpath, path);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_request_secure_unmount(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char *path;
+       int ret;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path,
+                       DBUS_TYPE_INVALID);
+       if (!ret) {
+               ret = -EBADMSG;
+               goto error;
+       }
+
+       _D("unmount path : %s", path);
+       ret = mmc_unmount(UNMOUNT_NORMAL, path);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_request_mount(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       struct mmc_data *pdata;
+       int ret;
+
+       if (!mmc_curpath) {
+               ret = -ENODEV;
+               goto error;
+       }
+
+       pdata = malloc(sizeof(struct mmc_data));
+       if (!pdata) {
+               _E("malloc failed");
+               ret = -errno;
+               goto error;
+       }
+
+       pdata->devpath = strdup(mmc_curpath);
+       if (!pdata->devpath) {
+               free(pdata);
+               ret = -errno;
+               goto error;
+       }
+
+       ret = (int)mount_start(pdata);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_request_unmount(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int opt, ret;
+       char params[NAME_MAX];
+       struct mmc_data *pdata;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_INT32, &opt, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EBADMSG;
+               goto error;
+       }
+
+       pdata = malloc(sizeof(struct mmc_data));
+       if (!pdata) {
+               _E("malloc failed");
+               ret = -errno;
+               goto error;
+       }
+
+       pdata->option = opt;
+       ret = (int)unmount_start(pdata);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *edbus_request_format(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int opt, ret;
+       struct mmc_data *pdata;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_INT32, &opt, DBUS_TYPE_INVALID);
+       if (!ret) {
+               _I("there is no message");
+               ret = -EBADMSG;
+               goto error;
+       }
+
+       if (!mmc_curpath) {
+               ret = -ENODEV;
+               goto error;
+       }
+
+       pdata = malloc(sizeof(struct mmc_data));
+       if (!pdata) {
+               _E("malloc failed");
+               ret = -errno;
+               goto error;
+       }
+
+       pdata->option = opt;
+       pdata->devpath = strdup(mmc_curpath);
+       if (!pdata->devpath) {
+               free(pdata);
+               ret = -errno;
+               goto error;
+       }
+
+       ret = (int)format_start(pdata);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+int get_mmc_devpath(char devpath[])
+{
+       if (mmc_disabled)
+               return -EWOULDBLOCK;
+       if (!mmc_curpath)
+               return -ENODEV;
+       snprintf(devpath, NAME_MAX, "%s", mmc_curpath);
+       return 0;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "RequestSecureMount",    "s", "i", edbus_request_secure_mount },
+       { "RequestSecureUnmount",  "s", "i", edbus_request_secure_unmount },
+       { "RequestMount",         NULL, "i", edbus_request_mount },
+       { "RequestUnmount",        "i", "i", edbus_request_unmount },
+       { "RequestFormat",         "i", "i", edbus_request_format },
+};
+
+static int mmc_poweroff(void *data)
+{
+       mmc_uevent_stop();
+       return 0;
+}
+
+static void mmc_init(void *data)
+{
+       int ret;
+
+       mmc_load_config();
+       ret = register_edbus_method(DEVICED_PATH_MMC, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       /* register mmc uevent control routine */
+       ret = mmc_uevent_start();
+       if (ret < 0)
+               _E("fail to mmc uevent start");
+
+       /* register notifier if mmc exist or not */
+       register_notifier(DEVICE_NOTIFIER_POWEROFF, mmc_poweroff);
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, mmc_booting_done);
+       register_notifier(DEVICE_NOTIFIER_MMC, mmc_changed_cb);
+}
+
+static void mmc_exit(void *data)
+{
+       /* unregister notifier */
+       unregister_notifier(DEVICE_NOTIFIER_POWEROFF, mmc_poweroff);
+       unregister_notifier(DEVICE_NOTIFIER_MMC, mmc_changed_cb);
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, mmc_booting_done);
+
+       /* unregister mmc uevent control routine */
+       mmc_uevent_stop();
+}
+
+static int mmc_start(void)
+{
+       mmc_disabled = false;
+       _D("start");
+       return 0;
+}
+
+static int mmc_stop(void)
+{
+       mmc_disabled = true;
+       vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_REMOVED);
+       _D("stop");
+       return 0;
+}
+
+const struct device_ops mmc_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "mmc",
+       .init     = mmc_init,
+       .exit     = mmc_exit,
+       .start    = mmc_start,
+       .stop     = mmc_stop,
+};
+
+DEVICE_OPS_REGISTER(&mmc_device_ops)
diff --git a/src/mmc/mmc-handler.h b/src/mmc/mmc-handler.h
new file mode 100644 (file)
index 0000000..d1d9c91
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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 __MMC_HANDLER_H__
+#define __MMC_HANDLER_H__
+
+#include <stdbool.h>
+
+#define SMACKFS_MOUNT_OPT      "smackfsroot=*,smackfsdef=*"
+#define MMC_MOUNT_POINT                "/opt/storage/sdcard"
+
+#define BUF_LEN                20
+#define RETRY_COUNT    10
+
+#define MMC_POPUP_NAME         "mmc-syspopup"
+#define MMC_POPUP_APP_KEY      "_APP_NAME_"
+#define MMC_POPUP_SMACK_VALUE  "checksmack"
+
+enum mmc_fs_type {
+       FS_TYPE_VFAT = 0,
+       FS_TYPE_EXFAT,
+       FS_TYPE_EXT4,
+};
+
+struct mmc_fs_ops {
+       enum mmc_fs_type type;
+       const char *name;
+       bool (*match) (const char *);
+       int (*check) (const char *);
+       int (*mount) (bool, const char *, const char *);
+       int (*format) (const char *);
+};
+
+struct fs_check {
+       int type;
+       char *name;
+       unsigned int offset;
+       unsigned int magic_sz;
+       char magic[4];
+};
+
+void add_fs(const struct mmc_fs_ops *fs);
+void remove_fs(const struct mmc_fs_ops *fs);
+int get_mmc_devpath(char devpath[]);
+bool mmc_check_mounted(const char *mount_point);
+
+int mmc_uevent_start(void);
+int mmc_uevent_stop(void);
+int get_block_number(void);
+#endif /* __MMC_HANDLER_H__ */
diff --git a/src/mmc/mmc.conf b/src/mmc/mmc.conf
new file mode 100644 (file)
index 0000000..55539b9
--- /dev/null
@@ -0,0 +1,3 @@
+[MMC]
+#mmc bdi max ratio
+MaxRatio=10
diff --git a/src/mmc/uevent.c b/src/mmc/uevent.c
new file mode 100644 (file)
index 0000000..873b213
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * 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 <Ecore.h>
+#include "core/udev.h"
+#include "core/device-notifier.h"
+#include "core/log.h"
+
+/* block device */
+#define BLOCK_SUBSYSTEM                "block"
+#define MMC_PATH                       "*/mmcblk[0-9]"
+#define BLOCK_DEVPATH                  "disk"
+
+static struct udev_monitor *mon;
+static struct udev *udev;
+static Ecore_Fd_Handler *ufdh;
+static int ufd;
+
+static Eina_Bool mmc_uevent_cb(void *data, Ecore_Fd_Handler *fd_handler)
+{
+       struct udev_device *dev;
+       const char *subsystem, *devpath, *action, *devnode;
+
+       dev = udev_monitor_receive_device(mon);
+       if (!dev)
+               return EINA_TRUE;
+
+       subsystem = udev_device_get_subsystem(dev);
+       if (strcmp(subsystem, BLOCK_SUBSYSTEM))
+               goto out;
+
+       devpath = udev_device_get_devpath(dev);
+       if (fnmatch(MMC_PATH, devpath, 0))
+               goto out;
+
+       _D("mmc uevent occurs!");
+
+       action = udev_device_get_action(dev);
+       devnode = udev_device_get_devnode(dev);
+       if (!action || !devnode)
+               goto out;
+
+       if (!strcmp(action, UDEV_ADD))
+               device_notify(DEVICE_NOTIFIER_MMC, (void *)devnode);
+       else if (!strcmp(action, UDEV_REMOVE))
+               device_notify(DEVICE_NOTIFIER_MMC, NULL);
+
+out:
+       udev_device_unref(dev);
+       return EINA_TRUE;
+}
+
+int mmc_uevent_start(void)
+{
+       int r;
+
+       if (udev) {
+               _D("uevent control is already started");
+               return -EPERM;
+       }
+
+       udev = udev_new();
+       if (!udev)
+               return -EPERM;
+
+       mon = udev_monitor_new_from_netlink(udev, UDEV);
+       if (!mon)
+               goto stop;
+
+       r = udev_monitor_set_receive_buffer_size(mon, UDEV_MONITOR_SIZE);
+       if (r < 0)
+               goto stop;
+
+       r = udev_monitor_filter_add_match_subsystem_devtype(mon, BLOCK_SUBSYSTEM, NULL);
+       if (r < 0)
+               goto stop;
+
+       r = udev_monitor_filter_update(mon);
+       if (r < 0)
+               _E("error udev_monitor_filter_update");
+
+       ufd = udev_monitor_get_fd(mon);
+       if (ufd < 0)
+               goto stop;
+
+       ufdh = ecore_main_fd_handler_add(ufd, ECORE_FD_READ, mmc_uevent_cb, NULL, NULL, NULL);
+       if (!ufdh)
+               goto stop;
+
+       r = udev_monitor_enable_receiving(mon);
+       if (r < 0)
+               goto stop;
+
+       return 0;
+
+stop:
+       mmc_uevent_stop();
+       return -EPERM;
+}
+
+int mmc_uevent_stop(void)
+{
+       struct udev_device *dev = NULL;
+
+       if (ufdh) {
+               ecore_main_fd_handler_del(ufdh);
+               ufdh = NULL;
+       }
+
+       if (ufd >= 0) {
+               close(ufd);
+               ufd = -1;
+       }
+
+       if (mon) {
+               dev = udev_monitor_receive_device(mon);
+               if (dev) {
+                       udev_device_unref(dev);
+                       dev = NULL;
+               }
+               udev_monitor_unref(mon);
+               mon = NULL;
+       }
+
+       if (udev) {
+               udev_unref(udev);
+               udev = NULL;
+       }
+
+       return 0;
+}
diff --git a/src/mmc/vfat.c b/src/mmc/vfat.c
new file mode 100644 (file)
index 0000000..1cab15d
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * 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 <limits.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include "core/common.h"
+#include "core/log.h"
+#include "mmc-handler.h"
+
+#define FS_VFAT_NAME   "mkdosfs"
+
+#define FS_VFAT_MOUNT_OPT      "uid=5000,gid=5000,dmask=0002,fmask=0002,iocharset=iso8859-1,utf8,shortname=mixed"
+
+static const char *vfat_arg[] = {
+       "/sbin/mkfs.vfat",
+       NULL, NULL,
+};
+
+static const char *vfat_check_arg[] = {
+       "/usr/bin/fsck_msdosfs",
+       "-pf", NULL, NULL,
+};
+
+static struct fs_check vfat_info = {
+       FS_TYPE_VFAT,
+       "vfat",
+       0x1fe,
+       2,
+       {0x55, 0xAA},
+};
+
+static int vfat_check(const char *devpath)
+{
+       int argc, r, pass = 0;
+
+       argc = ARRAY_SIZE(vfat_check_arg);
+       vfat_check_arg[argc - 2] = devpath;
+
+       do {
+               r = run_child(argc, vfat_check_arg);
+
+               switch (r) {
+               case 0:
+                       _I("filesystem check completed OK");
+                       return 0;
+               case 2:
+                       _I("file system check failed (not a FAT filesystem)");
+                       errno = ENODATA;
+                       return -1;
+               case 4:
+                       if (pass++ <= 2) {
+                               _I("filesystem modified - rechecking (pass : %d)", pass);
+                               continue;
+                       }
+                       _I("failing check after rechecks, but file system modified");
+                       return 0;
+               default:
+                       _I("filesystem check failed (unknown exit code %d)", r);
+                       errno = EIO;
+                       return -1;
+               }
+       } while (1);
+
+       return 0;
+}
+
+static bool vfat_match(const char *devpath)
+{
+       int r;
+
+       r = vfat_check(devpath);
+       if (r < 0) {
+               _E("failed to match with vfat(%s)", devpath);
+               return false;
+       }
+
+       _D("MMC type : %s", vfat_info.name);
+       return true;
+}
+
+static int vfat_mount(bool smack, const char *devpath, const char *mount_point)
+{
+       char options[NAME_MAX];
+       int r, retry = RETRY_COUNT;
+
+       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);
+
+       do {
+               r = mount(devpath, mount_point, "vfat", 0, options);
+               if (!r) {
+                       _D("Mounted mmc card [vfat]");
+                       return 0;
+               }
+               _D("mount fail : r = %d, err = %d", r, errno);
+               usleep(100000);
+       } while (r < 0 && errno == ENOENT && retry-- > 0);
+
+       return -errno;
+}
+
+static int vfat_format(const char *devpath)
+{
+       int argc;
+       argc = ARRAY_SIZE(vfat_arg);
+       vfat_arg[argc - 2] = devpath;
+       return run_child(argc, vfat_arg);
+}
+
+static const struct mmc_fs_ops vfat_ops = {
+       .type = FS_TYPE_VFAT,
+       .name = "vfat",
+       .match = vfat_match,
+       .check = vfat_check,
+       .mount = vfat_mount,
+       .format = vfat_format,
+};
+
+static void __CONSTRUCTOR__ module_init(void)
+{
+       add_fs(&vfat_ops);
+}
+/*
+static void __DESTRUCTOR__ module_exit(void)
+{
+       _D("module exit");
+       remove_fs(&vfat_ops);
+}
+*/
diff --git a/src/pmqos/pmqos-plugin.c b/src/pmqos/pmqos-plugin.c
new file mode 100644 (file)
index 0000000..9a720ab
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * 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 <stdbool.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include "core/log.h"
+#include "core/edbus-handler.h"
+#include "core/config-parser.h"
+#include "pmqos.h"
+
+static bool is_supported(const char *value)
+{
+       assert(value);
+
+       if (MATCH(value, "yes"))
+               return true;
+       return false;
+}
+
+static int pmqos_parse_scenario(struct parse_result *result, void *user_data, unsigned int index)
+{
+       struct pmqos_scenario *scenarios = (struct pmqos_scenario*)user_data;
+
+       assert(result);
+       assert(result->section && result->name && result->value);
+
+       /* Parse 'PmqosScenario' section */
+       if (MATCH(result->section, "PmqosScenario")) {
+               if (MATCH(result->name, "scenario_support"))
+                       scenarios->support = is_supported(result->value);
+               else if (MATCH(result->name, "scenario_num")) {
+                       scenarios->num = atoi(result->value);
+                       if (scenarios->num > 0) {
+                               scenarios->list = malloc(sizeof(struct scenario)*scenarios->num);
+                               if (!scenarios->list) {
+                                       _E("failed to allocat memory for scenario");
+                                       return -errno;
+                               }
+                       }
+               }
+       }
+
+       /* Do not support pmqos scenario */
+       if (!scenarios->support)
+               return 0;
+
+       /* Do not have pmqos scenario */
+       if (!scenarios->num)
+               return 0;
+
+       /* No item to parse */
+       if (index > scenarios->num)
+               return 0;
+
+       /* Parse 'Scenario' section */
+       if (MATCH(result->name, "name"))
+               strcpy(scenarios->list[index].name, result->value);
+       else if (MATCH(result->name, "support"))
+               scenarios->list[index].support = is_supported(result->value);
+
+       return 0;
+}
+
+static int pmqos_load_config(struct parse_result *result, void *user_data)
+{
+       struct pmqos_scenario *scenarios = (struct pmqos_scenario*)user_data;
+       char name[NAME_MAX];
+       int ret;
+       static int index;
+
+       if (!result)
+               return 0;
+
+       if (!result->section || !result->name || !result->value)
+               return 0;
+
+       /* Parsing 'PMQOS' section */
+       if (MATCH(result->section, "PMQOS"))
+               goto out;
+
+       /* Parsing 'Pmqos Scenario' section */
+       if (MATCH(result->section, "PmqosScenario")) {
+               ret = pmqos_parse_scenario(result, user_data, -1);
+               if (ret < 0) {
+                       _E("failed to parse [PmqosScenario] section : %d", ret);
+                       return ret;
+               }
+               goto out;
+       }
+
+       /* Parsing 'Scenario' section */
+       for (index = 0; index < scenarios->num; ++index) {
+               snprintf(name, sizeof(name), "Scenario%d", index);
+
+               if (MATCH(result->section, name)) {
+                       ret = pmqos_parse_scenario(result, user_data, index);
+                       if (ret < 0) {
+                               _E("failed to parse [Scenario%d] section : %d", index, ret);
+                               return ret;
+                       }
+                       goto out;
+               }
+       }
+
+out:
+       return 0;
+}
+
+int release_pmqos_table(struct pmqos_scenario *scenarios)
+{
+       if (!scenarios)
+               return -EINVAL;
+
+       if (scenarios->num > 0 && !scenarios->list)
+               free(scenarios->list);
+
+       return 0;
+}
+
+int get_pmqos_table(const char *path, struct pmqos_scenario *scenarios)
+{
+       int ret;
+
+       /* get configuration file */
+       ret = config_parse(path, pmqos_load_config, scenarios);
+       if (ret < 0) {
+               _E("failed to load conficuration file(%s) : %d", path, ret);
+               release_pmqos_table(scenarios);
+               return ret;
+       }
+
+       return 0;
+}
diff --git a/src/pmqos/pmqos.c b/src/pmqos/pmqos.c
new file mode 100644 (file)
index 0000000..51af26d
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ * 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 <stdbool.h>
+#include <limits.h>
+#include <Ecore.h>
+#include <device-node.h>
+
+#include "core/log.h"
+#include "core/edbus-handler.h"
+#include "core/devices.h"
+#include "core/common.h"
+#include "core/list.h"
+#include "core/device-notifier.h"
+#include "pmqos.h"
+
+#define DEFAULT_PMQOS_TIMER            3000
+
+#define PMQOS_CONF_PATH                "/etc/deviced/pmqos.conf"
+
+struct pmqos_cpu {
+       char name[NAME_MAX];
+       Ecore_Timer *timer;
+};
+
+static dd_list *pmqos_head;
+
+int set_cpu_pmqos(const char *name, int val)
+{
+       char scenario[100];
+
+       snprintf(scenario, sizeof(scenario), "%s%s", name, (val ? "Lock" : "Unlock"));
+       _D("Set pm scenario : %s", scenario);
+       device_notify(DEVICE_NOTIFIER_PMQOS, (void *)scenario);
+       return device_set_property(DEVICE_TYPE_CPU, PROP_CPU_PM_SCENARIO, (int)scenario);
+}
+
+static int pmqos_cpu_cancel(const char *name)
+{
+       dd_list *elem;
+       struct pmqos_cpu *cpu;
+
+       /* Find previous request */
+       DD_LIST_FOREACH(pmqos_head, elem, cpu) {
+               if (!strcmp(cpu->name, name))
+                       break;
+       }
+
+       /* In case of already end up request */
+       if(!cpu) {
+               _I("%s request is already canceled", name);
+               return 0;
+       }
+
+       /* Set cpu unlock */
+       set_cpu_pmqos(cpu->name, false);
+
+       /* Delete previous request */
+       DD_LIST_REMOVE(pmqos_head, cpu);
+       ecore_timer_del(cpu->timer);
+       free(cpu);
+
+       return 0;
+}
+
+static Eina_Bool pmqos_cpu_timer(void *data)
+{
+       char *name = (char*)data;
+       int ret;
+
+       _I("%s request will be unlocked", name);
+       ret = pmqos_cpu_cancel(name);
+       if (ret < 0)
+               _E("Can not find %s request", name);
+
+       free(name);
+       return ECORE_CALLBACK_CANCEL;
+}
+
+static int pmqos_cpu_request(const char *name, int val)
+{
+       dd_list *elem;
+       struct pmqos_cpu *cpu;
+       Ecore_Timer *timer;
+       bool locked = false;
+
+       /* Check valid parameter */
+       if (val > DEFAULT_PMQOS_TIMER) {
+               _I("The timer value cannot be higher than default time value(%dms)", DEFAULT_PMQOS_TIMER);
+               val = DEFAULT_PMQOS_TIMER;
+       }
+
+       /* Find previous request */
+       DD_LIST_FOREACH(pmqos_head, elem, cpu) {
+               if (!strcmp(cpu->name, name)) {
+                       ecore_timer_reset(cpu->timer);
+                       locked = true;
+                       break;
+               }
+       }
+
+       /* In case of first request */
+       if (!cpu) {
+               /* Add new timer */
+               timer = ecore_timer_add(val/1000.f, pmqos_cpu_timer, (void*)strdup(name));
+               if (!timer)
+                       return -EPERM;
+
+               cpu = malloc(sizeof(struct pmqos_cpu));
+               if (!cpu) {
+                       ecore_timer_del(timer);
+                       return -ENOMEM;
+               }
+               snprintf(cpu->name, sizeof(cpu->name), "%s", name);
+               cpu->timer = timer;
+               DD_LIST_APPEND(pmqos_head, cpu);
+       }
+
+       /* Set cpu lock */
+       if(!locked) {
+               set_cpu_pmqos(cpu->name, true);
+       }
+
+       return 0;
+}
+
+static int pmqos_powersaving(void *data)
+{
+       return set_cpu_pmqos("PowerSaving", (int)data);
+}
+
+static int pmqos_lowbat(void *data)
+{
+       return set_cpu_pmqos("LowBattery", (int)data);
+}
+
+static int pmqos_emergency(void *data)
+{
+       return set_cpu_pmqos("Emergency", (int)data);
+}
+
+static int pmqos_poweroff(void *data)
+{
+       return set_cpu_pmqos("PowerOff", (int)data);
+}
+
+static DBusMessage *dbus_pmqos_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       const char *member;
+       int val, ret;
+
+       if (!dbus_message_get_args(msg, NULL,
+                               DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (val < 0) {
+               ret = -EINVAL;
+               goto error;
+       }
+
+       member = dbus_message_get_member(msg);
+
+       if (val)
+               ret = pmqos_cpu_request(member, val);
+       else
+               ret = pmqos_cpu_cancel(member);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_wifi_pmqos_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       const char *member;
+       char name[NAME_MAX];
+       int bps, val, ret;
+
+       if (!dbus_message_get_args(msg, NULL,
+                               DBUS_TYPE_INT32, &bps,
+                               DBUS_TYPE_INT32, &val, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       if (bps < 0 || val < 0) {
+               ret = -EINVAL;
+               goto error;
+       }
+
+       member = dbus_message_get_member(msg);
+
+       /* combine bps and member */
+       snprintf(name, sizeof(name), "%s%d", member, bps);
+
+       if (val)
+               ret = pmqos_cpu_request(name, val);
+       else
+               ret = pmqos_cpu_cancel(name);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_getdefaultlocktime(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = DEFAULT_PMQOS_TIMER;
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static int get_methods_from_conf(const char *path, struct edbus_method **edbus_methods)
+{
+       struct edbus_method *methods;
+       struct pmqos_scenario scenarios = {0,};
+       int i, ret;
+
+       /* get pmqos table from conf */
+       ret = get_pmqos_table(path, &scenarios);
+       if (ret < 0) {
+               /* release scenarios memory */
+               release_pmqos_table(&scenarios);
+               return ret;
+       }
+
+       /* if do not support scenario */
+       if (!scenarios.support)
+               return 0;
+
+       /* if do not have scenarios */
+       if (scenarios.num <= 0)
+               return 0;
+
+       /* allocate edbus methods structure */
+       methods = malloc(sizeof(struct edbus_method)*scenarios.num);
+       if (!methods) {
+               _E("failed to allocate methods memory : %s", strerror(errno));
+               /* release scenarios memory */
+               release_pmqos_table(&scenarios);
+               return -errno;
+       }
+
+       /* set edbus_methods structure */
+       for (i = 0; i < scenarios.num; ++i) {
+
+               /* if this scenario does not support */
+               if (!scenarios.list[i].support) {
+                       _I("do not support [%s] scenario", scenarios.list[i].name);
+                       continue;
+               }
+
+               methods[i].member = scenarios.list[i].name;
+               methods[i].signature = "i";
+               methods[i].reply_signature = "i";
+               methods[i].func = dbus_pmqos_handler;
+               _D("support [%s] scenario", scenarios.list[i].name);
+       }
+
+       *edbus_methods = methods;
+       return scenarios.num;
+}
+
+/* Add pmqos name as alphabetically */
+static const struct edbus_method edbus_methods[] = {
+       { "AppLaunch",            "i",    "i", dbus_pmqos_handler },
+       { "BeautyShot",           "i",    "i", dbus_pmqos_handler },
+       { "Browser",              "i",    "i", dbus_pmqos_handler },
+       { "BrowserDash",          "i",    "i", dbus_pmqos_handler },
+       { "BrowserJavaScript",    "i",    "i", dbus_pmqos_handler },
+       { "BrowserLoading",       "i",    "i", dbus_pmqos_handler },
+       { "BrowserScroll",        "i",    "i", dbus_pmqos_handler },
+       { "CallSound",            "i",    "i", dbus_pmqos_handler },
+       { "CameraBurstShot",      "i",    "i", dbus_pmqos_handler },
+       { "CameraCaptureAtRec",   "i",    "i", dbus_pmqos_handler },
+       { "CameraPreview",        "i",    "i", dbus_pmqos_handler },
+       { "CameraSoundAndShot",   "i",    "i", dbus_pmqos_handler },
+       { "Emergency",            "i",    "i", dbus_pmqos_handler },
+       { "GalleryRotation",      "i",    "i", dbus_pmqos_handler },
+       { "GetDefaultLockTime",  NULL,    "i", dbus_getdefaultlocktime },
+       { "GpsSerialCno",         "i",    "i", dbus_pmqos_handler },
+       { "GpuBoost",             "i",    "i", dbus_pmqos_handler },
+       { "GpuWakeup",            "i",    "i", dbus_pmqos_handler },
+       { "ImageViewer",          "i",    "i", dbus_pmqos_handler },
+       { "IMEInput",             "i",    "i", dbus_pmqos_handler },
+       { "LockScreen",           "i",    "i", dbus_pmqos_handler },
+       { "LowBattery",           "i",    "i", dbus_pmqos_handler },
+       { "MtpSendFile",          "i",    "i", dbus_pmqos_handler },
+       { "PowerSaving",          "i",    "i", dbus_pmqos_handler },
+       { "ProcessCrashed",       "i",    "i", dbus_pmqos_handler },
+       { "ReservedMode",         "i",    "i", dbus_pmqos_handler },
+       { "ScreenMirroring",      "i",    "i", dbus_pmqos_handler },
+       { "SmemoZoom",            "i",    "i", dbus_pmqos_handler },
+       { "SVoice",               "i",    "i", dbus_pmqos_handler },
+       { "WebappLaunch",         "i",    "i", dbus_pmqos_handler },
+       { "WifiThroughput",      "ii",    "i", dbus_wifi_pmqos_handler },
+       { "PowerOff",             "i",    "i", dbus_pmqos_handler },
+       { "WebAppDrag",           "i",    "i", dbus_pmqos_handler },
+       { "WebAppFlick",          "i",    "i", dbus_pmqos_handler },
+       { "SensorWakeup",          "i",    "i", dbus_pmqos_handler },
+};
+
+static void pmqos_init(void *data)
+{
+       struct edbus_method *methods = NULL;
+       int ret, size;
+
+       /* register edbus methods */
+       ret = register_edbus_method(DEVICED_PATH_PMQOS, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       /* get methods from config file */
+       size = get_methods_from_conf(PMQOS_CONF_PATH, &methods);
+       if (size < 0)
+               _E("failed to load configuration file(%s)", PMQOS_CONF_PATH);
+
+       /* register edbus methods for pmqos */
+       if (methods) {
+               ret = register_edbus_method(DEVICED_PATH_PMQOS, methods, size);
+               if (ret < 0)
+                       _E("fail to init edbus method from conf(%d)", ret);
+               free(methods);
+       }
+
+       /* register notifier for each event */
+       register_notifier(DEVICE_NOTIFIER_PMQOS_POWERSAVING, pmqos_powersaving);
+       register_notifier(DEVICE_NOTIFIER_PMQOS_LOWBAT, pmqos_lowbat);
+       register_notifier(DEVICE_NOTIFIER_PMQOS_EMERGENCY, pmqos_emergency);
+       register_notifier(DEVICE_NOTIFIER_PMQOS_POWEROFF, pmqos_poweroff);
+}
+
+static void pmqos_exit(void *data)
+{
+       /* unregister notifier for each event */
+       unregister_notifier(DEVICE_NOTIFIER_PMQOS_POWERSAVING, pmqos_powersaving);
+       unregister_notifier(DEVICE_NOTIFIER_PMQOS_LOWBAT, pmqos_lowbat);
+       unregister_notifier(DEVICE_NOTIFIER_PMQOS_EMERGENCY, pmqos_emergency);
+       unregister_notifier(DEVICE_NOTIFIER_PMQOS_POWEROFF, pmqos_poweroff);
+}
+
+static const struct device_ops pmqos_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "pmqos",
+       .init     = pmqos_init,
+       .exit     = pmqos_exit,
+};
+
+DEVICE_OPS_REGISTER(&pmqos_device_ops)
diff --git a/src/pmqos/pmqos.conf b/src/pmqos/pmqos.conf
new file mode 100644 (file)
index 0000000..83025a9
--- /dev/null
@@ -0,0 +1,15 @@
+[PMQOS]
+
+############################
+### Add list of scenario ###
+############################
+[PmqosScenario]
+# set to "yes" scenario_support (Default value is no)
+# set scenario_num to be tested
+scenario_support=no
+scenario_num=0
+
+# describe the scenario section as follows
+#[Scenario0]
+#name=AppLaunch # (dbus method name)
+#support=yes
diff --git a/src/pmqos/pmqos.h b/src/pmqos/pmqos.h
new file mode 100644 (file)
index 0000000..531847c
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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 __PMQOS_H__
+#define __PMQOS_H__
+
+#include <stdbool.h>
+#include <limits.h>
+
+struct pmqos_scenario {
+       struct scenario {
+               char name[NAME_MAX];
+               bool support;
+       } *list;
+       int num;
+       bool support;
+};
+
+int get_pmqos_table(const char *path, struct pmqos_scenario *scenarios);
+int release_pmqos_table(struct pmqos_scenario *scenarios);
+
+#endif /* __PMQOS_H__ */
diff --git a/src/power/power-handler.c b/src/power/power-handler.c
new file mode 100644 (file)
index 0000000..80321e8
--- /dev/null
@@ -0,0 +1,662 @@
+/*
+ * 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 <unistd.h>
+#include <time.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <vconf.h>
+#include <assert.h>
+#include <limits.h>
+#include <vconf.h>
+#include <fcntl.h>
+#include <sys/reboot.h>
+#include <sys/time.h>
+#include <mntent.h>
+#include <sys/mount.h>
+#include <device-node.h>
+#include "dd-deviced.h"
+#include "core/log.h"
+#include "core/launch.h"
+#include "core/queue.h"
+#include "core/device-handler.h"
+#include "core/device-notifier.h"
+#include "core/predefine.h"
+#include "core/data.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "proc/proc-handler.h"
+#include "display/poll.h"
+#include "display/setting.h"
+#include "core/edbus-handler.h"
+#include "display/core.h"
+#include "power-handler.h"
+#include "hall/hall-handler.h"
+
+#define SIGNAL_NAME_POWEROFF_POPUP     "poweroffpopup"
+#define SIGNAL_BOOTING_DONE            "BootingDone"
+
+#define PREDEF_PWROFF_POPUP            "pwroff-popup"
+#define PREDEF_INTERNAL_POWEROFF       "internal_poweroff"
+
+#define POWEROFF_NOTI_NAME             "power_off_start"
+#define POWEROFF_DURATION              2
+#define MAX_RETRY                      2
+
+#define SYSTEMD_STOP_POWER_OFF                         4
+
+#define SIGNAL_POWEROFF_STATE  "ChangeState"
+
+#define POWEROFF_POPUP_NAME    "poweroff-syspopup"
+#define UMOUNT_RW_PATH "/opt/usr"
+
+
+struct popup_data {
+       char *name;
+       char *key;
+};
+
+static struct timeval tv_start_poweroff;
+
+static int power_off = 0;
+static const struct device_ops *telephony;
+static const struct device_ops *hall_ic = NULL;
+static void telephony_init(void)
+{
+       if (telephony)
+               return;
+       telephony = find_device("telephony");
+       _I("telephony (%d)", telephony);
+}
+
+static void telephony_start(void)
+{
+       telephony_init();
+       if (telephony)
+               telephony->start();
+}
+
+static void telephony_stop(void)
+{
+       if (telephony)
+               telephony->stop();
+}
+
+static int telephony_exit(void *data)
+{
+       if (!telephony)
+               return -EINVAL;
+       telephony->exit(data);
+       return 0;
+}
+
+static void poweroff_popup_edbus_signal_handler(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       char *str;
+       int val = 0;
+
+       if (dbus_message_is_signal(msg, DEVICED_INTERFACE_NAME, SIGNAL_NAME_POWEROFF_POPUP) == 0) {
+               _E("there is no power off popup signal");
+               return;
+       }
+
+       dbus_error_init(&err);
+
+       if (dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID) == 0) {
+               _E("there is no message");
+               return;
+       }
+
+       if (strncmp(str, PREDEF_PWROFF_POPUP, strlen(PREDEF_PWROFF_POPUP)) == 0)
+               val = VCONFKEY_SYSMAN_POWER_OFF_POPUP;
+       else if (strncmp(str, PREDEF_POWEROFF, strlen(PREDEF_POWEROFF)) == 0)
+               val = VCONFKEY_SYSMAN_POWER_OFF_DIRECT;
+       else if (strncmp(str, PREDEF_REBOOT, strlen(PREDEF_REBOOT)) == 0)
+               val = VCONFKEY_SYSMAN_POWER_OFF_RESTART;
+       else if (strncmp(str, PREDEF_FOTA_REBOOT, strlen(PREDEF_FOTA_REBOOT)) == 0)
+               val = SYSTEMD_STOP_POWER_RESTART_FOTA;
+       if (val == 0) {
+               _E("not supported message : %s", str);
+               return;
+       }
+       vconf_set_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, val);
+}
+
+static void booting_done_edbus_signal_handler(void *data, DBusMessage *msg)
+{
+       if (!dbus_message_is_signal(msg, DEVICED_INTERFACE_CORE, SIGNAL_BOOTING_DONE)) {
+               _E("there is no bootingdone signal");
+               return;
+       }
+
+       device_notify(DEVICE_NOTIFIER_BOOTING_DONE, (void *)TRUE);
+       telephony_init();
+}
+
+static void poweroff_send_broadcast(int status)
+{
+       static int old = 0;
+       char *arr[1];
+       char str_status[32];
+
+       if (old == status)
+               return;
+
+       _D("broadcast poweroff %d", status);
+
+       old = status;
+       snprintf(str_status, sizeof(str_status), "%d", status);
+       arr[0] = str_status;
+
+       broadcast_edbus_signal(DEVICED_PATH_POWEROFF, DEVICED_INTERFACE_POWEROFF,
+                       SIGNAL_POWEROFF_STATE, "i", arr);
+}
+
+static void poweroff_stop_systemd_service(void)
+{
+       char buf[256];
+       _D("systemd service stop");
+       umount2("/sys/fs/cgroup", MNT_FORCE |MNT_DETACH);
+}
+
+static void poweroff_start_animation(void)
+{
+       char params[128];
+       snprintf(params, sizeof(params), "/usr/bin/boot-animation --stop --clear");
+       launch_app_cmd_with_nice(params, -20);
+       launch_evenif_exist("/usr/bin/sound_server", "--poweroff");
+       device_notify(DEVICE_NOTIFIER_POWEROFF_HAPTIC, NULL);
+}
+
+static void poweroff_control_cb(keynode_t *in_key, struct main_data *ad)
+{
+       int val;
+       int ret;
+       int recovery;
+
+       telephony_start();
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val) != 0)
+               return;
+
+       recovery = val;
+
+       if (val == SYSTEMD_STOP_POWER_OFF ||
+           val == SYSTEMD_STOP_POWER_RESTART ||
+           val == SYSTEMD_STOP_POWER_RESTART_RECOVERY ||
+           val == SYSTEMD_STOP_POWER_RESTART_FOTA) {
+               poweroff_stop_systemd_service();
+               if (val == SYSTEMD_STOP_POWER_OFF)
+                       val = VCONFKEY_SYSMAN_POWER_OFF_DIRECT;
+               else
+                       val = VCONFKEY_SYSMAN_POWER_OFF_RESTART;
+               vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void*)poweroff_control_cb);
+               vconf_set_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, val);
+       }
+
+       if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || val == VCONFKEY_SYSMAN_POWER_OFF_RESTART)
+               poweroff_send_broadcast(val);
+
+       switch (val) {
+       case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
+               device_notify(DEVICE_NOTIFIER_POWEROFF, (void *)val);
+               notify_action(PREDEF_POWEROFF, 0);
+               break;
+       case VCONFKEY_SYSMAN_POWER_OFF_POPUP:
+               notify_action(PREDEF_PWROFF_POPUP, 0);
+               break;
+       case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
+               device_notify(DEVICE_NOTIFIER_POWEROFF, (void *)val);
+               if (recovery == SYSTEMD_STOP_POWER_RESTART_RECOVERY)
+                       notify_action(PREDEF_RECOVERY, 0);
+               else if (recovery == SYSTEMD_STOP_POWER_RESTART_FOTA)
+                       notify_action(PREDEF_FOTA_REBOOT, 0);
+               else
+                       notify_action(PREDEF_REBOOT, 0);
+               break;
+       }
+
+       if (update_pm_setting)
+               update_pm_setting(SETTING_POWEROFF, val);
+}
+
+/* umount usr data partition */
+static void unmount_rw_partition()
+{
+       int retry = 0;
+       sync();
+       if (!mount_check(UMOUNT_RW_PATH))
+               return;
+       while (1) {
+               switch (retry++) {
+               case 0:
+                       /* Second, kill app with SIGTERM */
+                       _I("Kill app with SIGTERM");
+                       terminate_process(UMOUNT_RW_PATH, false);
+                       sleep(3);
+                       break;
+               case 1:
+                       /* Last time, kill app with SIGKILL */
+                       _I("Kill app with SIGKILL");
+                       terminate_process(UMOUNT_RW_PATH, true);
+                       sleep(1);
+                       break;
+               default:
+                       if (umount2(UMOUNT_RW_PATH, 0) != 0) {
+                               _I("Failed to unmount %s", UMOUNT_RW_PATH);
+                               return;
+                       }
+                       _I("%s unmounted successfully", UMOUNT_RW_PATH);
+                       return;
+               }
+               if (umount2(UMOUNT_RW_PATH, 0) == 0) {
+                       _I("%s unmounted successfully", UMOUNT_RW_PATH);
+                       return;
+               }
+       }
+}
+
+static void powerdown(void)
+{
+       static int wait = 0;
+       struct timeval now;
+       int poweroff_duration = POWEROFF_DURATION;
+       int check_duration = 0;
+       char *buf;
+
+       if (power_off == 1) {
+               _E("during power off");
+               return;
+       }
+       telephony_stop();
+       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);
+       check_duration = now.tv_sec - tv_start_poweroff.tv_sec;
+       while (check_duration < poweroff_duration) {
+               if (wait == 0) {
+                       _I("wait poweroff %d %d", check_duration, poweroff_duration);
+                       wait = 1;
+               }
+               usleep(100000);
+               gettimeofday(&now, NULL);
+               check_duration = now.tv_sec - tv_start_poweroff.tv_sec;
+               if (check_duration < 0)
+                       break;
+       }
+       unmount_rw_partition();
+}
+
+static void restart_by_mode(int mode)
+{
+       if (mode == SYSTEMD_STOP_POWER_RESTART_RECOVERY)
+               launch_evenif_exist("/usr/sbin/reboot", "recovery");
+       else if (mode == SYSTEMD_STOP_POWER_RESTART_FOTA)
+               launch_evenif_exist("/usr/sbin/reboot", "fota");
+       else
+               reboot(RB_AUTOBOOT);
+}
+
+int internal_poweroff_def_predefine_action(int argc, char **argv)
+{
+       int ret;
+       const struct device_ops *display_device_ops;
+
+       telephony_start();
+
+       display_device_ops = find_device("display");
+       if (!display_device_ops) {
+               _E("Can't find display_device_ops");
+               return -ENODEV;
+       }
+
+       display_device_ops->exit(NULL);
+       sync();
+
+       gettimeofday(&tv_start_poweroff, NULL);
+
+       ret = telephony_exit(PREDEF_POWEROFF);
+
+       if (ret < 0) {
+               powerdown_ap(NULL);
+               return 0;
+       }
+       return ret;
+}
+
+int do_poweroff(int argc, char **argv)
+{
+       return internal_poweroff_def_predefine_action(argc, argv);
+}
+
+int poweroff_def_predefine_action(int argc, char **argv)
+{
+       int retry_count = 0;
+       poweroff_start_animation();
+       while (retry_count < MAX_RETRY) {
+               if (notify_action(PREDEF_INTERNAL_POWEROFF, 0) < 0) {
+                       _E("failed to request poweroff to deviced");
+                       retry_count++;
+                       continue;
+               }
+               vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void*)poweroff_control_cb);
+               return 0;
+       }
+       return -1;
+}
+
+static int hall_ic_status(void)
+{
+       if (!hall_ic)
+               return HALL_IC_OPENED;
+       return hall_ic->status();
+}
+
+int launching_predefine_action(int argc, char **argv)
+{
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+       int val;
+
+       val = hall_ic_status();
+       if (val == HALL_IC_CLOSED) {
+               _I("cover is closed");
+               return 0;
+       }
+       if (apps == NULL) {
+               apps = find_device("apps");
+               if (apps == NULL)
+                       return 0;
+       }
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return -1;
+       }
+       params->name = POWEROFF_POPUP_NAME;
+       apps->init((void *)params);
+       free(params);
+       return 0;
+}
+
+int restart_def_predefine_action(int argc, char **argv)
+{
+       int ret;
+       int data = 0;
+
+       const struct device_ops *display_device_ops;
+       poweroff_start_animation();
+       telephony_start();
+
+       display_device_ops = find_device("display");
+       if (!display_device_ops) {
+               _E("Can't find display_device_ops");
+               return -ENODEV;
+       }
+
+       pm_change_internal(getpid(), LCD_NORMAL);
+       display_device_ops->exit(NULL);
+       sync();
+
+       gettimeofday(&tv_start_poweroff, NULL);
+
+       if (argc == 1 && argv)
+               data = atoi(argv[0]);
+       if (data == SYSTEMD_STOP_POWER_RESTART_RECOVERY)
+               ret = telephony_exit(PREDEF_RECOVERY);
+       else if (data == SYSTEMD_STOP_POWER_RESTART_FOTA)
+               ret = telephony_exit(PREDEF_FOTA_REBOOT);
+       else
+               ret = telephony_exit(PREDEF_REBOOT);
+
+       if (ret < 0) {
+               restart_ap((void *)data);
+               return 0;
+       }
+       return ret;
+}
+
+int restart_recovery_def_predefine_action(int argc, char **argv)
+{
+       int ret;
+       char *param[1];
+       char status[32];
+
+       snprintf(status, sizeof(status), "%d", SYSTEMD_STOP_POWER_RESTART_RECOVERY);
+       param[0] = status;
+
+       return restart_def_predefine_action(1, param);
+}
+
+int restart_fota_def_predefine_action(int argc, char **argv)
+{
+       int ret;
+       char *param[1];
+       char status[32];
+
+       snprintf(status, sizeof(status), "%d", SYSTEMD_STOP_POWER_RESTART_FOTA);
+       param[0] = status;
+
+       return restart_def_predefine_action(1, param);
+}
+
+int reset_resetkey_disable(char *name, enum watch_id id)
+{
+       _D("force reset power resetkey disable to zero");
+       return device_set_property(DEVICE_TYPE_POWER, PROP_POWER_RESETKEY_DISABLE, 0);
+}
+
+static DBusMessage *edbus_resetkeydisable(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &val,
+                       DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = device_set_property(DEVICE_TYPE_POWER, PROP_POWER_RESETKEY_DISABLE, val);
+       if (ret < 0)
+               goto error;
+
+       if (val)
+               register_edbus_watch(msg, WATCH_POWER_RESETKEY_DISABLE, reset_resetkey_disable);
+       else
+               unregister_edbus_watch(msg, WATCH_POWER_RESETKEY_DISABLE);
+
+       _D("get power resetkey disable %d, %d", val, ret);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static int reset_wakeupkey(char *name, enum watch_id id)
+{
+       _D("force reset wakeupkey to zero");
+       return device_set_property(DEVICE_TYPE_POWER, PROP_POWER_WAKEUP_KEY, 0);
+}
+
+static DBusMessage *edbus_set_wakeup_key(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_INT32, &val,
+                       DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = device_set_property(DEVICE_TYPE_POWER, PROP_POWER_WAKEUP_KEY, val);
+       if (ret < 0)
+               goto error;
+
+       if (val)
+               register_edbus_watch(msg, WATCH_POWER_WAKEUPKEY, reset_wakeupkey);
+       else
+               unregister_edbus_watch(msg, WATCH_POWER_WAKEUPKEY);
+
+       _D("set power wakeup key %d %d", val, ret);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *dbus_power_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       telephony_start();
+
+       if(strncmp(type_str, PREDEF_REBOOT, strlen(PREDEF_REBOOT)) == 0)
+               restart_def_predefine_action(0, NULL);
+       else if(strncmp(type_str, PREDEF_RECOVERY, strlen(PREDEF_RECOVERY)) == 0)
+               restart_recovery_def_predefine_action(0, NULL);
+       else if(strncmp(type_str, PREDEF_PWROFF_POPUP, strlen(PREDEF_PWROFF_POPUP)) == 0)
+               launching_predefine_action(0, NULL);
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+void powerdown_ap(void *data)
+{
+       _I("Power off");
+       powerdown();
+       reboot(RB_POWER_OFF);
+}
+
+void restart_ap(void *data)
+{
+       _I("Restart %d", (int)data);
+       powerdown();
+       restart_by_mode((int)data);
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "setresetkeydisable",   "i",   "i", edbus_resetkeydisable },
+       { "SetWakeupKey", "i", "i", edbus_set_wakeup_key },
+       { PREDEF_REBOOT, "si", "i", dbus_power_handler },
+       { PREDEF_RECOVERY, "si", "i", dbus_power_handler },
+       { PREDEF_PWROFF_POPUP, "si", "i", dbus_power_handler },
+       /* Add methods here */
+};
+
+static void power_init(void *data)
+{
+       int bTelReady = 0;
+       int ret;
+
+       /* init dbus interface */
+       ret = register_edbus_method(DEVICED_PATH_POWER, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       register_action(PREDEF_POWEROFF,
+                                    poweroff_def_predefine_action, NULL, NULL);
+       register_action(PREDEF_PWROFF_POPUP,
+                                    launching_predefine_action, NULL, NULL);
+       register_action(PREDEF_REBOOT,
+                                    restart_def_predefine_action, NULL, NULL);
+       register_action(PREDEF_RECOVERY,
+                                    restart_recovery_def_predefine_action, NULL, NULL);
+       register_action(PREDEF_FOTA_REBOOT,
+                                    restart_fota_def_predefine_action, NULL, NULL);
+
+       register_action(PREDEF_INTERNAL_POWEROFF,
+                                    internal_poweroff_def_predefine_action, NULL, NULL);
+
+       if (vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, (void *)poweroff_control_cb, NULL) < 0) {
+               _E("Vconf notify key chaneged failed: KEY(%s)", VCONFKEY_SYSMAN_POWER_OFF_STATUS);
+       }
+
+       register_edbus_signal_handler(DEVICED_OBJECT_PATH, DEVICED_INTERFACE_NAME,
+                       SIGNAL_NAME_POWEROFF_POPUP,
+                   poweroff_popup_edbus_signal_handler);
+       register_edbus_signal_handler(DEVICED_PATH_CORE,
+                   DEVICED_INTERFACE_CORE,
+                   SIGNAL_BOOTING_DONE,
+                   booting_done_edbus_signal_handler);
+       hall_ic = find_device(HALL_IC_NAME);
+}
+
+static const struct device_ops power_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "power",
+       .init     = power_init,
+};
+
+DEVICE_OPS_REGISTER(&power_device_ops)
diff --git a/src/power/power-handler.h b/src/power/power-handler.h
new file mode 100644 (file)
index 0000000..106bfe5
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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 __POWER_HANDLE_H__
+#define __POWER_HANDLE_H__
+
+#define PREDEF_POWEROFF         "poweroff"
+#define PREDEF_REBOOT           "reboot"
+#define PREDEF_RECOVERY         "reboot-recovery"
+#define PREDEF_FOTA_REBOOT      "fota"
+
+#define SYSTEMD_STOP_POWER_RESTART              5
+#define SYSTEMD_STOP_POWER_RESTART_RECOVERY     6
+#define SYSTEMD_STOP_POWER_RESTART_FOTA         7
+
+#ifndef SYSTEMD_SHUTDOWN
+void restart_ap(void *data);
+void powerdown_ap(void *data);
+#endif
+
+#endif /* __POWER_HANDLE_H__ */
diff --git a/src/power/systemd-power.c b/src/power/systemd-power.c
new file mode 100644 (file)
index 0000000..40a402c
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * 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 <unistd.h>
+#include <time.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <vconf.h>
+#include <assert.h>
+#include <limits.h>
+#include <sys/reboot.h>
+#include <sys/time.h>
+#include <mntent.h>
+#include <sys/mount.h>
+#include <device-node.h>
+#include "core/common.h"
+#include "core/data.h"
+#include "core/device-handler.h"
+#include "core/device-notifier.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+#include "core/launch.h"
+#include "core/log.h"
+#include "core/predefine.h"
+#include "core/queue.h"
+#include "dd-deviced.h"
+#include "display/poll.h"
+#include "display/setting.h"
+#include "hall/hall-handler.h"
+#include "power-handler.h"
+#include "proc/proc-handler.h"
+
+#define SIGNAL_BOOTING_DONE            "BootingDone"
+#define PREDEF_PWROFF_POPUP            "pwroff-popup"
+#define POWEROFF_POPUP_NAME            "poweroff-syspopup"
+#define RECOVERY_POWER_OFF             "reboot recovery"
+
+#define SYSTEMD_STOP_POWER_OFF         4
+#define SYSTEMD_STOP_POWER_RESTART     5
+#define SYSTEMD_STOP_POWER_RESTART_RECOVERY    6
+#define SYSTEMD_CHECK_POWER_OFF                15
+
+struct popup_data {
+       char *name;
+       char *key;
+};
+
+static const struct device_ops *hall_ic = NULL;
+static Ecore_Timer *systemd_poweroff_timer = NULL;
+
+static Eina_Bool systemd_force_shutdown_cb(void *arg)
+{
+       char params[128];
+       if (systemd_poweroff_timer) {
+               ecore_timer_del(systemd_poweroff_timer);
+               systemd_poweroff_timer = NULL;
+       }
+       snprintf(params, sizeof(params), "%s -f", (char*)arg);
+       launch_evenif_exist("/usr/bin/systemctl", params);
+       return EINA_TRUE;
+}
+
+static void start_boot_animation(void)
+{
+       char params[128];
+       snprintf(params, sizeof(params), "--stop --clear");
+       launch_evenif_exist("/usr/bin/boot-animation", params);
+}
+
+static int systemd_shutdown(const char *arg)
+{
+       assert(arg);
+       systemd_poweroff_timer = ecore_timer_add(SYSTEMD_CHECK_POWER_OFF,
+                           systemd_force_shutdown_cb, (void *)arg);
+       start_boot_animation();
+       device_notify(DEVICE_NOTIFIER_POWEROFF_HAPTIC, NULL);
+       return launch_evenif_exist("/usr/bin/systemctl", arg);
+}
+
+int do_poweroff(int argc, char **argv)
+{
+       return vconf_set_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
+                            VCONFKEY_SYSMAN_POWER_OFF_DIRECT);
+}
+
+static void poweroff_control_cb(keynode_t *in_key, struct main_data *ad)
+{
+       int val;
+       int ret;
+
+       if (vconf_get_int(in_key->keyname, &val) != 0)
+               return;
+
+       if (val == SYSTEMD_STOP_POWER_OFF
+           || val == SYSTEMD_STOP_POWER_RESTART
+           || val == SYSTEMD_STOP_POWER_RESTART_RECOVERY) {
+               vconf_ignore_key_changed(in_key->keyname,
+                                        (void*)poweroff_control_cb);
+               vconf_set_int(in_key->keyname, val);
+       }
+
+       device_notify(DEVICE_NOTIFIER_PMQOS_POWEROFF, (void*)1);
+
+       switch (val) {
+       case SYSTEMD_STOP_POWER_OFF:
+       case VCONFKEY_SYSMAN_POWER_OFF_DIRECT:
+               device_notify(DEVICE_NOTIFIER_POWEROFF,
+                             (void *)VCONFKEY_SYSMAN_POWER_OFF_DIRECT);
+               ret = systemd_shutdown(PREDEF_POWEROFF);
+               if (ret < 0)
+                       _E("fail to do (%s)", PREDEF_POWEROFF);
+               break;
+       case SYSTEMD_STOP_POWER_RESTART:
+       case VCONFKEY_SYSMAN_POWER_OFF_RESTART:
+               device_notify(DEVICE_NOTIFIER_POWEROFF,
+                             (void *)VCONFKEY_SYSMAN_POWER_OFF_RESTART);
+               ret = systemd_shutdown(PREDEF_REBOOT);
+               if (ret < 0)
+                       _E("fail to do (%s)", PREDEF_REBOOT);
+               break;
+       case SYSTEMD_STOP_POWER_RESTART_RECOVERY:
+               device_notify(DEVICE_NOTIFIER_POWEROFF,
+                             (void *)VCONFKEY_SYSMAN_POWER_OFF_RESTART);
+               ret = systemd_shutdown(RECOVERY_POWER_OFF);
+               if (ret < 0)
+                       _E("fail to do (%s)", RECOVERY_POWER_OFF);
+               break;
+       case VCONFKEY_SYSMAN_POWER_OFF_POPUP:
+               notify_action(PREDEF_PWROFF_POPUP, 0);
+               break;
+       }
+
+       if (update_pm_setting)
+               update_pm_setting(SETTING_POWEROFF, val);
+}
+
+static void booting_done_edbus_signal_handler(void *data, DBusMessage *msg)
+{
+       if (!dbus_message_is_signal(msg,
+                                   DEVICED_INTERFACE_CORE,
+                                   SIGNAL_BOOTING_DONE)) {
+               _E("there is no bootingdone signal");
+               return;
+       }
+
+       device_notify(DEVICE_NOTIFIER_BOOTING_DONE, (void *)TRUE);
+}
+
+static int hall_ic_status(void)
+{
+       if (!hall_ic)
+               return HALL_IC_OPENED;
+       return hall_ic->status();
+}
+
+int reset_resetkey_disable(char *name, enum watch_id id)
+{
+       _D("force reset power resetkey disable to zero");
+       return device_set_property(DEVICE_TYPE_POWER,
+                                  PROP_POWER_RESETKEY_DISABLE,
+                                  0);
+}
+
+static DBusMessage *edbus_resetkeydisable(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+
+       ret = dbus_message_get_args(msg, NULL, DBUS_TYPE_INT32, &val,
+                                   DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = device_set_property(DEVICE_TYPE_POWER,
+                                 PROP_POWER_RESETKEY_DISABLE,
+                                 val);
+       if (ret < 0)
+               goto error;
+
+       if (val)
+               register_edbus_watch(msg,
+                                    WATCH_POWER_RESETKEY_DISABLE,
+                                    reset_resetkey_disable);
+       else
+               unregister_edbus_watch(msg,
+                                      WATCH_POWER_RESETKEY_DISABLE);
+
+       _D("get power resetkey disable %d, %d", val, ret);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static int reset_wakeupkey(char *name, enum watch_id id)
+{
+       _D("force reset wakeupkey to zero");
+       return device_set_property(DEVICE_TYPE_POWER, PROP_POWER_WAKEUP_KEY, 0);
+}
+
+static DBusMessage *edbus_set_wakeup_key(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int val, ret;
+
+       ret = dbus_message_get_args(msg, NULL,
+                                   DBUS_TYPE_INT32, &val,
+                                   DBUS_TYPE_INVALID);
+       if (!ret) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto error;
+       }
+
+       ret = device_set_property(DEVICE_TYPE_POWER, PROP_POWER_WAKEUP_KEY, val);
+       if (ret < 0)
+               goto error;
+
+       if (val)
+               register_edbus_watch(msg, WATCH_POWER_WAKEUPKEY, reset_wakeupkey);
+       else
+               unregister_edbus_watch(msg, WATCH_POWER_WAKEUPKEY);
+
+       _D("set power wakeup key %d %d", val, ret);
+
+error:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "setresetkeydisable", "i",    "i",    edbus_resetkeydisable   },
+       { "SetWakeupKey",       "i",    "i",    edbus_set_wakeup_key    },
+       /* Add methods here */
+};
+
+int launching_predefine_action(int argc, char **argv)
+{
+       struct popup_data *params;
+       static const struct device_ops *apps = NULL;
+       int val;
+
+       val = hall_ic_status();
+       if (val == HALL_IC_CLOSED) {
+               _I("cover is closed");
+               return 0;
+       }
+       if (apps == NULL) {
+               apps = find_device("apps");
+               if (apps == NULL)
+                       return 0;
+       }
+       params = malloc(sizeof(struct popup_data));
+       if (params == NULL) {
+               _E("Malloc failed");
+               return -1;
+       }
+       params->name = POWEROFF_POPUP_NAME;
+       apps->init((void *)params);
+       free(params);
+       return 0;
+}
+
+static void power_init(void *data)
+{
+       int bTelReady = 0;
+       int ret;
+
+       /* init dbus interface */
+       ret = register_edbus_method(DEVICED_PATH_POWER,
+                                   edbus_methods,
+                                   ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       ret = register_edbus_signal_handler(DEVICED_PATH_CORE,
+                                           DEVICED_INTERFACE_CORE,
+                                           SIGNAL_BOOTING_DONE,
+                                           booting_done_edbus_signal_handler);
+       if (ret < 0)
+               _E("fail to register handler for signal: %s",
+                  SIGNAL_BOOTING_DONE);
+
+       register_action(PREDEF_POWEROFF,
+                       do_poweroff, NULL, NULL);
+       register_action(PREDEF_PWROFF_POPUP,
+                       launching_predefine_action, NULL, NULL);
+
+       ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS,
+                                      (void *)poweroff_control_cb,
+                                      NULL);
+       if (ret < 0)
+               _E("Vconf notify key chaneged failed: KEY(%s)",
+                  VCONFKEY_SYSMAN_POWER_OFF_STATUS);
+       hall_ic = find_device(HALL_IC_NAME);
+}
+
+static const struct device_ops power_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "systemd-power",
+       .init     = power_init,
+};
+
+DEVICE_OPS_REGISTER(&power_device_ops)
diff --git a/src/powersaver/powersaver.c b/src/powersaver/powersaver.c
new file mode 100644 (file)
index 0000000..dae3128
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2014 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 <vconf.h>
+
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+#include "core/log.h"
+#include "display/core.h"
+#include "display/device-interface.h"
+
+static int set_powersaver_mode(int on)
+{
+       int ret;
+       int brightness, timeout;
+
+       _I("powersaver mode %s", (on ? "on" : "off"));
+       device_notify(DEVICE_NOTIFIER_POWERSAVER, (void*)on);
+
+       /* powersaver mode off */
+       if (!on) {
+               backlight_ops.set_force_brightness(0);
+               set_force_lcdtimeout(0);
+               goto update_state;
+       }
+
+       /* powersaver mode on (brightness) */
+       ret = vconf_get_int(VCONFKEY_SETAPPL_EMERGENCY_LCD_BRIGHTNESS_INT,
+           &brightness);
+       if (ret != 0) {
+               _E("Failed to get powersaver brightness!");
+               return ret;
+       }
+       ret = backlight_ops.set_force_brightness(brightness);
+       if (ret < 0) {
+               _E("Failed to set force brightness!");
+               return ret;
+       }
+       _I("force brightness %d", brightness);
+
+       /* powersaver mode on (lcd timeout) */
+       ret = vconf_get_int(VCONFKEY_SETAPPL_EMERGENCY_LCD_TIMEOUT_INT,
+           &timeout);
+       if (ret != 0) {
+               _E("Failed to get powersaver lcd timeout!");
+               return ret;
+       }
+       ret = set_force_lcdtimeout(timeout);
+       if (ret < 0) {
+               _E("Failed to set force timeout!");
+               return ret;
+       }
+       _I("force timeout %d", timeout);
+
+update_state:
+       /* update internal state */
+       if (hbm_get_state())
+               hbm_set_state_with_timeout(false, 0);
+       backlight_ops.update();
+       ret = get_run_timeout(&timeout);
+       if (ret >= 0)
+               states[S_NORMAL].timeout = timeout;
+       states[pm_cur_state].trans(EVENT_INPUT);
+
+       return 0;
+}
+
+static void powersaver_status_changed(keynode_t *key_nodes, void *data)
+{
+       int status, on, ret;
+
+       if (key_nodes == NULL) {
+               _E("wrong parameter, key_nodes is null");
+               return;
+       }
+
+       status = vconf_keynode_get_int(key_nodes);
+       if (status == SETTING_PSMODE_NORMAL)
+               on = false;
+       else if (status == SETTING_PSMODE_WEARABLE)
+               on = true;
+       else
+               return;
+
+       ret = set_powersaver_mode(on);
+       if (ret < 0)
+               _E("Failed to update powersaver state %d", ret);
+}
+
+static int booting_done(void *data)
+{
+       int ret, status;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &status);
+       if (ret != 0) {
+               _E("Failed to vconf get bool!");
+               return -EIO;
+       }
+
+       if (status != SETTING_PSMODE_WEARABLE)
+               return 0;
+
+       _D("powersaver mode on!");
+       ret = set_powersaver_mode(true);
+       if (ret < 0)
+               _E("Failed to update powersaver state %d", ret);
+
+       return ret;
+}
+
+static void powersaver_init(void *data)
+{
+       int ret;
+
+       ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
+           powersaver_status_changed, NULL);
+       if (ret != 0)
+               _E("Failed to vconf_notify_key_changed!");
+
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+}
+
+static void powersaver_exit(void *data)
+{
+       int ret;
+
+       ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
+           powersaver_status_changed);
+       if (ret != 0)
+               _E("Failed to vconf_ignore_key_changed!");
+
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, booting_done);
+}
+
+static const struct device_ops powersaver_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "powersaver",
+       .init     = powersaver_init,
+       .exit     = powersaver_exit,
+};
+
+DEVICE_OPS_REGISTER(&powersaver_device_ops)
diff --git a/src/predefine_act_plugin/CMakeLists.txt b/src/predefine_act_plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..100c04f
--- /dev/null
@@ -0,0 +1,38 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(xxx-predefine C)
+
+SET(SRCS xxx-predefine.c) 
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR "\${prefix}/lib")
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION 1.0)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED sysman)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+MESSAGE("FLAGS: ${CMAKE_C_FLAGS}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"")
+ADD_DEFINITIONS("-DDEBUG")
+IF( $ENV{ARCH} MATCHES "arm" ) 
+       ADD_DEFINITIONS("-DTARGET")
+ENDIF()
+
+SET(CMAKE_LDFLAGS "-Wl,zdefs")
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib COMPONENT RuntimeLibraries)
+
diff --git a/src/predefine_act_plugin/build.sh b/src/predefine_act_plugin/build.sh
new file mode 100755 (executable)
index 0000000..c0cc290
--- /dev/null
@@ -0,0 +1,7 @@
+cd `dirname $0`
+
+. ../../../../../setup.conf || exit 1
+
+. ${TPLDIR}/cmake.tpl
+run
+
diff --git a/src/predefine_act_plugin/xxx-predefine.c b/src/predefine_act_plugin/xxx-predefine.c
new file mode 100644 (file)
index 0000000..507bf09
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  system-server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: DongGi Jang <dg0402.jang@samsung.com>
+ * 
+ * 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/src/proc/cpu-info.c b/src/proc/cpu-info.c
new file mode 100644 (file)
index 0000000..2c8e00e
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * 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 <fcntl.h>
+
+#include "core/log.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+#include "core/common.h"
+
+#define METHOD_GET_REVISION    "GetRevision"
+#define PATH_NAME              "/proc/cpuinfo"
+#define REVISION_NAME  "Revision"
+#define TOK_DELIMITER  ":"
+#define END_DELIMITER  " \n"
+
+#define CONVERT_TYPE   10
+#define REVISION_SIZE  4
+#define FILE_BUFF_MAX  1024
+#define NOT_INITIALIZED        (-1)
+
+static int read_from_file(const char *path, char *buf, size_t size)
+{
+       int fd;
+       size_t count;
+
+       if (!path)
+               return -1;
+
+       fd = open(path, O_RDONLY, 0);
+       if (fd == -1) {
+               _E("Could not open '%s'", path);
+               return -1;
+       }
+
+       count = read(fd, buf, size);
+
+       if (count > 0) {
+               count = (count < size) ? count : size - 1;
+               while (count > 0 && buf[count - 1] == '\n')
+                       count--;
+               buf[count] = '\0';
+       } else {
+               buf[0] = '\0';
+       }
+
+       close(fd);
+
+       return 0;
+}
+
+static int get_revision(char *rev)
+{
+       char buf[FILE_BUFF_MAX];
+       char *tag;
+       char *start, *ptr;
+       long rev_num;
+       const int radix = 16;
+
+       if (rev == NULL) {
+               _E("Invalid argument !\n");
+               return -1;
+       }
+
+       if (read_from_file(PATH_NAME, buf, FILE_BUFF_MAX) < 0) {
+               _E("fail to read %s\n", PATH_NAME);
+               return -1;
+       }
+
+       tag = strstr(buf, REVISION_NAME);
+       if (tag == NULL) {
+               _E("cannot find Hardware in %s\n", PATH_NAME);
+               return -1;
+       }
+
+       start = strstr(tag, TOK_DELIMITER);
+       if (start == NULL) {
+               _E("cannot find Hardware in %s\n", PATH_NAME);
+               return -1;
+       }
+
+       start ++;
+       ptr = strtok(start, END_DELIMITER);
+       ptr += strlen(ptr);
+       ptr -=2;
+
+       memset(rev, 0x00, REVISION_SIZE);
+       rev_num = strtol(ptr, NULL, radix);
+       sprintf(rev, "%d", rev_num);
+
+       return 0;
+}
+
+static DBusMessage *dbus_revision_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char rev[FILE_BUFF_MAX];
+       char *ptr;
+       static int ret = NOT_INITIALIZED;
+
+       if (ret != NOT_INITIALIZED)
+               goto out;
+       ret = get_revision(rev);
+       if (ret == 0)
+               ret = strtol(rev, &ptr, CONVERT_TYPE);
+out:
+       _D("rev : %d", ret);
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { METHOD_GET_REVISION, NULL, "i", dbus_revision_handler },
+};
+
+static void cpu_info_init(void *data)
+{
+       int ret;
+
+       ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+}
+
+static const struct device_ops cpu_info_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "cpu_info",
+       .init     = cpu_info_init,
+};
+
+DEVICE_OPS_REGISTER(&cpu_info_device_ops)
diff --git a/src/proc/pmon-handler.c b/src/proc/pmon-handler.c
new file mode 100644 (file)
index 0000000..98abc37
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * 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 <fcntl.h>
+#include <assert.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <device-node.h>
+
+#include "core/log.h"
+#include "core/launch.h"
+#include "core/data.h"
+#include "core/common.h"
+#include "core/devices.h"
+
+#define PMON_PERMANENT_DIR     "/tmp/permanent"
+
+static Ecore_Fd_Handler *pmon_efd = NULL;
+
+static int __pmon_start(struct 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;
+       int ret;
+       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) {
+               _E("file open error");
+               return NULL;
+       }
+
+       if (fstat(fd, &st) < 0) {
+               _E("fstat error");
+               close(fd);
+               return NULL;
+       }
+       _D("size = %d", (int)st.st_size);
+
+       cmdline = malloc(st.st_size + 1);
+       if (cmdline == NULL) {
+               _E("Not enough memory");
+               close(fd);
+               return NULL;
+       }
+       memset(cmdline, 0, st.st_size + 1);
+
+       ret = read(fd, cmdline, st.st_size);
+       if (ret >= 0 && ret < 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)
+{
+       _D("[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 (is_vip(pid)) {
+               _I("=======================================");
+               _I("[Process MON] VIP process dead.");
+               _I("=======================================");
+       }
+       /* 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) {
+                       _I("[Process MON] %s relaunch", cmdline);
+                       new_pid = 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) {
+                                       _I("no predefined matrix dir = %s, so created", PMON_PERMANENT_DIR);
+                                       r = mkdir(PMON_PERMANENT_DIR, 0777);
+                                       if(r < 0) {
+                                               _E("Make Directory is failed");
+                                               return -1;
+                                       }
+                               }
+
+                               snprintf(filepath, sizeof(filepath), "%s/%d", PMON_PERMANENT_DIR, pid);
+                               fd = open(filepath, O_RDONLY);
+                               if (fd == -1) {
+                                       _E("Failed to open");
+                                       return -1;
+                               }
+                               cnt = read(fd, buf, PATH_MAX);
+                               close(fd);
+
+                               if (cnt <= 0) {
+                                       _E("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) {
+                                       _E("Failed to open");
+                                       return -1;
+                               }
+                               if (write(fd, buf, cnt) == -1) {
+                                       _E("Failed to write");
+                                       close(fd);
+                                       return -1;
+                               }
+                               close(fd);
+                               if ( device_set_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_MP_PNP, new_pid) < 0) {
+                                       _E("Write new pid failed");
+                               }
+                               _I("[Process MON] %d ", new_pid);
+
+                               FILE *fp;
+
+                               _I("[Process MON] OOMADJ_SET : pid %d, new_oomadj %d",
+                                    new_pid, (-17));
+
+                               fp = open_proc_oom_score_adj_file(new_pid, "w");
+                               if (fp == NULL)
+                                       return -1;
+                               fprintf(fp, "%d",0);
+                               fclose(fp);
+
+                               snprintf(old_file, sizeof(old_file), "%s/%d",
+                                        PMON_PERMANENT_DIR, pid);
+                               unlink(old_file);
+                       } else {
+                               _I("[Process MON] failed relaunching");
+                       }
+               }
+       }
+       return 0;
+}
+/*
+static unsigned int pmon_read(int fd)
+{
+       unsigned int pid;
+       read(fd, &pid, sizeof(pid));
+       return pid;
+}
+*/
+
+static Eina_Bool pmon_cb(void *data, Ecore_Fd_Handler * fd_handler)
+{
+       int fd;
+       struct main_data *ad = (struct main_data *)data;
+       int dead_pid;
+       char pid_str[PATH_MAX];
+       int ret;
+
+       if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
+               _E("ecore_main_fd_handler_active_get error , return");
+               goto out;
+       }
+
+       fd = ecore_main_fd_handler_fd_get(fd_handler);
+
+       if (fd < 0) {
+               _E("ecore_main_fd_handler_fd_get error , return");
+               goto out;
+       }
+
+       ret = read(fd, pid_str, PATH_MAX);
+
+       if (ret < 0 || ret >= PATH_MAX) {
+               __pmon_stop(fd);
+               _E("Reading DEAD_PID failed, restart ecore fd");
+               __pmon_start(ad);
+               goto out;
+       }
+
+       pid_str[ret] = '\0';
+       dead_pid = strtoul(pid_str, NULL, 10);
+       print_pmon_state(dead_pid);
+       pmon_process(dead_pid, ad);
+out:
+       return EINA_TRUE;
+}
+
+static int __pmon_start(struct main_data *ad)
+{
+       int pmon_fd = -1;
+       char pmon_dev_node[PATH_MAX];
+       if (device_get_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_NODE,
+               (int *)pmon_dev_node) < 0) {
+               _E("ss_pmon_init get dev node path failed");
+               return -1;
+       }
+
+       pmon_fd = open(pmon_dev_node, O_RDONLY);
+       if (pmon_fd < 0) {
+               _E("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) {
+               _E("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;
+}
+
+static void pmon_init(void *data)
+{
+       struct main_data *ad = (struct main_data*)data;
+       int ret = -1;
+
+       if (pmon_efd) {
+               ecore_main_fd_handler_del(pmon_efd);
+               pmon_efd = NULL;
+       }
+       if (__pmon_start(ad) == -1) {
+               _E("fail pmon control fd init");
+       }
+}
+
+static const struct device_ops pmon_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "pmon",
+       .init     = pmon_init,
+};
+
+DEVICE_OPS_REGISTER(&pmon_device_ops)
diff --git a/src/proc/proc-handler.c b/src/proc/proc-handler.c
new file mode 100644 (file)
index 0000000..7b4c258
--- /dev/null
@@ -0,0 +1,772 @@
+/*
+ * 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 <stdbool.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <device-node.h>
+#include <sys/un.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+#include <fcntl.h>
+
+#include "core/data.h"
+#include "core/queue.h"
+#include "core/log.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/device-notifier.h"
+#include "display/enhance.h"
+#include "proc-handler.h"
+#include "core/edbus-handler.h"
+
+#define LIMITED_PROCESS_OOMADJ 15
+
+#define PROCESS_VIP            "process_vip"
+#define PROCESS_PERMANENT      "process_permanent"
+#define OOMADJ_SET                     "oomadj_set"
+
+#define PREDEF_BACKGRD                 "backgrd"
+#define PREDEF_FOREGRD                 "foregrd"
+#define PREDEF_ACTIVE                  "active"
+#define PREDEF_INACTIVE                        "inactive"
+#define PROCESS_GROUP_SET              "process_group_set"
+
+#define VCONFKEY_INTERNAL_PRIVATE_SIOP_DISABLE "memory/private/sysman/siop_disable"
+
+#define BUFF_MAX       255
+#define SIOP_CTRL_LEVEL_MASK   0xFFFF
+#define SIOP_CTRL_LEVEL(val)   ((val & SIOP_CTRL_LEVEL_MASK) << 16)
+#define SIOP_CTRL_VALUE(s, r)  (s | (r << 4))
+#define SIOP_VALUE(d, val)     ((d) * (val & 0xF))
+#define REAR_VALUE(val)        (val >> 4)
+
+#define SIGNAL_SIOP_CHANGED    "ChangedSiop"
+#define SIGNAL_REAR_CHANGED    "ChangedRear"
+#define SIOP_LEVEL_GET         "GetSiopLevel"
+#define REAR_LEVEL_GET         "GetRearLevel"
+#define SIOP_LEVEL_SET         "SetSiopLevel"
+
+#define SIGNAL_NAME_OOMADJ_SET "OomadjSet"
+
+enum SIOP_DOMAIN_TYPE {
+       SIOP_NEGATIVE = -1,
+       SIOP_POSITIVE = 1,
+};
+
+static int siop = 0;
+static int mode = 0;
+static int siop_domain = SIOP_POSITIVE;
+
+enum siop_scenario {
+       MODE_NONE = 0,
+       MODE_LCD = 1,
+};
+#ifdef NOUSE
+typedef struct _node {
+       pid_t pid;
+       struct _node *next;
+} Node;
+
+static Node *head = NULL;
+
+static Node *find_node(pid_t pid)
+{
+       Node *t = head;
+
+       while (t != NULL) {
+               if (t->pid == pid)
+                       break;
+               t = t->next;
+       }
+       return t;
+}
+
+static Node *add_node(pid_t pid)
+{
+       Node *n;
+
+       n = (Node *) malloc(sizeof(Node));
+       if (n == NULL) {
+               _E("Not enough memory, add cond. fail");
+               return NULL;
+       }
+
+       n->pid = pid;
+       n->next = head;
+       head = n;
+
+       return n;
+}
+
+static int del_node(Node *n)
+{
+       Node *t;
+       Node *prev;
+
+       if (n == NULL)
+               return 0;
+
+       t = head;
+       prev = NULL;
+       while (t != NULL) {
+               if (t == n) {
+                       if (prev != NULL)
+                               prev->next = t->next;
+                       else
+                               head = head->next;
+                       free(t);
+                       break;
+               }
+               prev = t;
+               t = t->next;
+       }
+       return 0;
+}
+#endif
+
+int cur_siop_level(void)
+{
+       return  SIOP_VALUE(siop_domain, siop);
+}
+
+static void siop_level_action(int level)
+{
+       int val = SIOP_CTRL_LEVEL(level);
+       static int old;
+       static int siop_level = 0;
+       static int rear_level = 0;
+       static int initialized = 0;
+       static int domain = 0;
+       char *arr[1];
+       char str_level[32];
+
+       if (initialized && siop == level && mode == old && domain == siop_domain)
+               return;
+       initialized = 1;
+       siop = level;
+       domain = siop_domain;
+       if (siop_domain == SIOP_NEGATIVE)
+               val = 0;
+       old = mode;
+       val |= old;
+
+       device_set_property(DEVICE_TYPE_POWER, PROP_POWER_SIOP_CONTROL, val);
+
+       val = SIOP_VALUE(siop_domain, level);
+       if (siop_level != val) {
+               siop_level = val;
+               snprintf(str_level, sizeof(str_level), "%d", siop_level);
+               arr[0] = str_level;
+               _I("broadcast siop %s", str_level);
+               broadcast_edbus_signal(DEVICED_PATH_PROCESS, DEVICED_INTERFACE_PROCESS,
+                       SIGNAL_SIOP_CHANGED, "i", arr);
+       }
+
+       val = REAR_VALUE(level);
+       if (rear_level != val) {
+               rear_level = val;
+               snprintf(str_level, sizeof(str_level), "%d", rear_level);
+               arr[0] = str_level;
+               _I("broadcast rear %s", str_level);
+               broadcast_edbus_signal(DEVICED_PATH_PROCESS, DEVICED_INTERFACE_PROCESS,
+                       SIGNAL_REAR_CHANGED, "i", arr);
+       }
+       _I("level is d:%d(0x%x) s:%d r:%d", siop_domain, siop, siop_level, rear_level);
+}
+
+static int siop_changed(int argc, char **argv)
+{
+#ifdef MICRO_DD
+       return 0;
+#else
+       int siop_level = 0;
+       int rear_level = 0;
+       int level;
+       int siop_disable;
+       int ret;
+
+       if (argc != 2 || argv[0] == NULL) {
+               _E("fail to check value");
+               return -1;
+       }
+
+       if (argv[0] == NULL)
+               goto out;
+
+       level = atoi(argv[0]);
+       device_set_property(DEVICE_TYPE_DISPLAY, PROP_DISPLAY_ELVSS_CONTROL, level);
+       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_SIOP_LEVEL, &level);
+       if (ret != 0)
+               goto check_rear;
+
+       if (level <= SIOP_NEGATIVE)
+               siop_domain = SIOP_NEGATIVE;
+       else
+               siop_domain = SIOP_POSITIVE;
+       siop_level = siop_domain * level;
+
+check_rear:
+       if (argv[1] == NULL)
+               goto out;
+
+       level = atoi(argv[1]);
+       if (device_get_property(DEVICE_TYPE_POWER, PROP_POWER_REAR_LEVEL, &level) == 0)
+               rear_level = level;
+
+out:
+       level = SIOP_CTRL_VALUE(siop_level, rear_level);
+       siop_level_action(level);
+       return 0;
+#endif
+}
+
+static int siop_mode_lcd(keynode_t *key_nodes, void *data)
+{
+       int pm_state;
+       if (vconf_get_int(VCONFKEY_PM_STATE, &pm_state) != 0)
+               _E("Fail to get vconf value for pm state\n");
+       if (pm_state == VCONFKEY_PM_STATE_LCDOFF)
+               mode = MODE_LCD;
+       else
+               mode = MODE_NONE;
+       siop_level_action(siop);
+       return 0;
+}
+
+static void memcg_move_group(int pid, int oom_score_adj)
+{
+       char buf[100];
+       FILE *f;
+       int ret, size;
+       char exe_name[PATH_MAX];
+
+       if (get_cmdline_name(pid, exe_name, PATH_MAX) != 0) {
+               _E("fail to get process name(%d)", pid);
+               return;
+       }
+
+       _SD("memcg_move_group : %s, pid = %d", exe_name, pid);
+       if (oom_score_adj >= OOMADJ_BACKGRD_LOCKED)
+               sprintf(buf, "/sys/fs/cgroup/memory/background/cgroup.procs");
+       else if (oom_score_adj >= OOMADJ_FOREGRD_LOCKED && oom_score_adj < OOMADJ_BACKGRD_LOCKED)
+               sprintf(buf, "/sys/fs/cgroup/memory/foreground/cgroup.procs");
+       else
+               return;
+
+       f = fopen(buf, "w");
+       if (f == NULL)
+               return;
+       size = sprintf(buf, "%d", pid);
+       if (fwrite(buf, size, 1, f) != 1)
+               _E("fwrite cgroup tasks : %d\n", pid);;
+       fclose(f);
+}
+
+int get_oom_score_adj(int pid, int *oom_score_adj)
+{
+       char buf[PATH_MAX];
+       FILE *fp;
+
+       if (pid < 0)
+               return -1;
+
+       fp = open_proc_oom_score_adj_file(pid, "r");
+       if (fp == NULL)
+               return -1;
+       if (fgets(buf, PATH_MAX, fp) == NULL) {
+               fclose(fp);
+               return -1;
+       }
+
+       *oom_score_adj = atoi(buf);
+       fclose(fp);
+       return 0;
+}
+
+int set_oom_score_adj(pid_t pid, int new_oom_score_adj)
+{
+       FILE *fp;
+       int old_oom_score_adj;
+       char exe_name[PATH_MAX];
+
+       if (get_cmdline_name(pid, exe_name, PATH_MAX) < 0)
+               snprintf(exe_name, sizeof(exe_name), "Unknown (maybe dead)");
+
+       if (get_oom_score_adj(pid, &old_oom_score_adj) < 0)
+               return -1;
+
+       _SI("Process %s, pid %d, old_oom_score_adj %d new_oom_score_adj %d",
+               exe_name, pid, old_oom_score_adj, new_oom_score_adj);
+
+       if (new_oom_score_adj < OOMADJ_SU)
+               new_oom_score_adj = OOMADJ_SU;
+
+       fp = open_proc_oom_score_adj_file(pid, "w");
+       if (fp == NULL)
+               return -1;
+
+       fprintf(fp, "%d", new_oom_score_adj);
+       fclose(fp);
+
+       return 0;
+}
+
+int set_su_oom_score_adj(pid_t pid)
+{
+       return set_oom_score_adj(pid, OOMADJ_SU);
+}
+
+int check_oom_score_adj(int oom_score_adj)
+{
+       if (oom_score_adj != OOMADJ_FOREGRD_LOCKED && oom_score_adj != OOMADJ_FOREGRD_UNLOCKED)
+               return 0;
+       return -1;
+}
+
+int set_oom_score_adj_action(int argc, char **argv)
+{
+       FILE *fp;
+       int pid = -1;
+       int new_oom_score_adj = 0;
+
+       if (argc < 2)
+               return -1;
+       if ((pid = atoi(argv[0])) < 0 || (new_oom_score_adj = atoi(argv[1])) <= -20)
+               return -1;
+
+       _I("OOMADJ_SET : pid %d, new_oom_score_adj %d", pid, new_oom_score_adj);
+
+       fp = open_proc_oom_score_adj_file(pid, "w");
+       if (fp == NULL)
+               return -1;
+       if (new_oom_score_adj < OOMADJ_SU)
+               new_oom_score_adj = OOMADJ_SU;
+       fprintf(fp, "%d", new_oom_score_adj);
+       fclose(fp);
+
+       memcg_move_group(pid, new_oom_score_adj);
+       return 0;
+}
+
+int set_active_action(int argc, char **argv)
+{
+       int pid = -1;
+       int ret = 0;
+       int oom_score_adj = 0;
+
+       if (argc < 1)
+               return -1;
+       if ((pid = atoi(argv[0])) < 0)
+               return -1;
+
+       if (get_oom_score_adj(pid, &oom_score_adj) < 0)
+               return -1;
+
+       switch (oom_score_adj) {
+       case OOMADJ_FOREGRD_LOCKED:
+       case OOMADJ_BACKGRD_LOCKED:
+       case OOMADJ_SU:
+               ret = 0;
+               break;
+       case OOMADJ_FOREGRD_UNLOCKED:
+               ret = set_oom_score_adj((pid_t) pid, OOMADJ_FOREGRD_LOCKED);
+               break;
+       case OOMADJ_BACKGRD_UNLOCKED:
+               ret = set_oom_score_adj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
+               break;
+       case OOMADJ_INIT:
+               ret = set_oom_score_adj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
+               break;
+       default:
+               if(oom_score_adj > OOMADJ_BACKGRD_UNLOCKED) {
+                       ret = set_oom_score_adj((pid_t) pid, OOMADJ_BACKGRD_LOCKED);
+               } else {
+                       _E("Unknown oom_score_adj value (%d) !", oom_score_adj);
+                       ret = -1;
+               }
+               break;
+       }
+       set_enhance_pid(pid);
+       return ret;
+}
+
+int set_inactive_action(int argc, char **argv)
+{
+       int pid = -1;
+       int ret = 0;
+       int oom_score_adj = 0;
+
+       if (argc < 1)
+               return -1;
+       if ((pid = atoi(argv[0])) < 0)
+               return -1;
+
+       if (get_oom_score_adj(pid, &oom_score_adj) < 0)
+               return -1;
+
+       switch (oom_score_adj) {
+       case OOMADJ_FOREGRD_UNLOCKED:
+       case OOMADJ_BACKGRD_UNLOCKED:
+       case OOMADJ_SU:
+               ret = 0;
+               break;
+       case OOMADJ_FOREGRD_LOCKED:
+               ret = set_oom_score_adj((pid_t) pid, OOMADJ_FOREGRD_UNLOCKED);
+               break;
+       case OOMADJ_BACKGRD_LOCKED:
+               ret = set_oom_score_adj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
+               break;
+       case OOMADJ_INIT:
+               ret = set_oom_score_adj((pid_t) pid, OOMADJ_BACKGRD_UNLOCKED);
+               break;
+       default:
+               if(oom_score_adj > OOMADJ_BACKGRD_UNLOCKED) {
+                       ret = 0;
+               } else {
+                       _E("Unknown oom_score_adj value (%d) !", oom_score_adj);
+                       ret = -1;
+               }
+               break;
+
+       }
+       set_enhance_pid(pid);
+       return ret;
+}
+
+int set_process_action(int argc, char **argv)
+{
+       int pid = -1;
+       int ret = 0;
+
+       if (argc < 1)
+               return -1;
+       if ((pid = atoi(argv[0])) < 0)
+               return -1;
+
+       set_enhance_pid(pid);
+       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)
+               _I("%s : pid %d", argv[1], pid);
+       else
+               _E("fail to set %s : pid %d",argv[1], pid);
+       return 0;
+}
+
+void check_siop_disable_process(int pid, char *default_name)
+{
+       int oom_score_adj;
+       char exe_name[PATH_MAX];
+       if (pid <= 0)
+               return;
+
+       if (get_oom_score_adj(pid, &oom_score_adj) < 0) {
+               _E("fail to get adj value of pid: %d (%d)", pid);
+               return;
+       }
+
+       if (get_cmdline_name(pid, exe_name, PATH_MAX) != 0) {
+               _E("fail to check cmdline: %d (%s)", pid, default_name);
+               return;
+       }
+
+       if (strncmp(exe_name, default_name, strlen(default_name)) != 0) {
+               return;
+       }
+
+       switch (oom_score_adj) {
+       case OOMADJ_FOREGRD_LOCKED:
+       case OOMADJ_FOREGRD_UNLOCKED:
+               siop_level_action(0);
+               vconf_set_int(VCONFKEY_INTERNAL_PRIVATE_SIOP_DISABLE, 1);
+               return;
+       case OOMADJ_BACKGRD_LOCKED:
+       case OOMADJ_BACKGRD_UNLOCKED:
+       case OOMADJ_SU:
+               vconf_set_int(VCONFKEY_INTERNAL_PRIVATE_SIOP_DISABLE, 0);
+       }
+       return;
+}
+
+static DBusMessage *dbus_proc_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+       char *argv;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (strncmp(type_str, PREDEF_FOREGRD, strlen(PREDEF_FOREGRD)) == 0)
+               ret = set_process_action(argc, (char **)&argv);
+       else if (strncmp(type_str, PREDEF_BACKGRD, strlen(PREDEF_BACKGRD)) == 0)
+               ret = set_process_action(argc, (char **)&argv);
+       else if (strncmp(type_str, PREDEF_ACTIVE, strlen(PREDEF_ACTIVE)) == 0)
+               ret = set_active_action(argc, (char **)&argv);
+       else if (strncmp(type_str, PREDEF_INACTIVE, strlen(PREDEF_INACTIVE)) == 0)
+               ret = set_inactive_action(argc, (char **)&argv);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *dbus_oom_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+       char *argv[2];
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv[0],
+                   DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (strncmp(type_str, OOMADJ_SET, strlen(OOMADJ_SET)) == 0)
+               ret = set_oom_score_adj_action(argc, (char **)&argv);
+       else if (strncmp(type_str, PROCESS_GROUP_SET, strlen(PROCESS_GROUP_SET)) == 0)
+               ret = set_process_group_action(argc, (char **)&argv);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *dbus_get_siop_level(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int level;
+
+       level = SIOP_VALUE(siop_domain, siop);
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &level);
+       return reply;
+}
+
+static DBusMessage *dbus_get_rear_level(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int level;
+
+       level = REAR_VALUE(siop);
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &level);
+       return reply;
+}
+
+static DBusMessage *dbus_set_siop_level(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+       char *argv[2];
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &argv[0],
+                   DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+       ret = siop_changed(2, (char **)&argv);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static void dbus_proc_oomadj_set_signal_handler(void *data, DBusMessage *msg)
+
+{
+       DBusError err;
+       pid_t pid;
+       int ret = -EINVAL;
+       int argc;
+       char *type_str;
+       char *argv;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               return;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               return;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               return;
+       }
+
+       if (strncmp(type_str, PREDEF_FOREGRD, strlen(PREDEF_FOREGRD)) == 0)
+               ret = set_process_action(argc, (char **)&argv);
+       else if (strncmp(type_str, PREDEF_BACKGRD, strlen(PREDEF_BACKGRD)) == 0)
+               ret = set_process_action(argc, (char **)&argv);
+       else if (strncmp(type_str, PREDEF_ACTIVE, strlen(PREDEF_ACTIVE)) == 0)
+               ret = set_active_action(argc, (char **)&argv);
+       else if (strncmp(type_str, PREDEF_INACTIVE, strlen(PREDEF_INACTIVE)) == 0)
+               ret = set_inactive_action(argc, (char **)&argv);
+
+       if (ret < 0)
+               _E("set_process_action error!");
+}
+
+
+static const struct edbus_method edbus_methods[] = {
+       { PREDEF_FOREGRD, "sis", "i", dbus_proc_handler },
+       { PREDEF_BACKGRD, "sis", "i", dbus_proc_handler },
+       { PREDEF_ACTIVE, "sis", "i", dbus_proc_handler },
+       { PREDEF_INACTIVE, "sis", "i", dbus_proc_handler },
+       { OOMADJ_SET, "siss", "i", dbus_oom_handler },
+       { PROCESS_GROUP_SET, "siss", "i", dbus_oom_handler },
+       { SIOP_LEVEL_GET, NULL, "i", dbus_get_siop_level },
+       { REAR_LEVEL_GET, NULL, "i", dbus_get_rear_level },
+       { SIOP_LEVEL_SET, "ss", "i", dbus_set_siop_level },
+};
+
+static int proc_booting_done(void *data)
+{
+       register_action(SIOP_CHANGED, siop_changed, NULL, NULL);
+       if (vconf_notify_key_changed(VCONFKEY_PM_STATE, (void *)siop_mode_lcd, NULL) < 0)
+               _E("Vconf notify key chaneged failed: KEY(%s)", VCONFKEY_PM_STATE);
+       siop_mode_lcd(NULL, NULL);
+       return 0;
+}
+static void process_init(void *data)
+{
+       int ret;
+
+       register_edbus_signal_handler(DEVICED_PATH_PROCESS, DEVICED_INTERFACE_PROCESS,
+                       SIGNAL_NAME_OOMADJ_SET,
+                   dbus_proc_oomadj_set_signal_handler);
+
+       ret = register_edbus_method(DEVICED_PATH_PROCESS, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       register_action(PREDEF_FOREGRD, set_process_action, NULL, NULL);
+       register_action(PREDEF_BACKGRD, set_process_action, NULL, NULL);
+       register_action(PREDEF_ACTIVE, set_active_action, NULL, NULL);
+       register_action(PREDEF_INACTIVE, set_inactive_action, NULL, NULL);
+       register_action(OOMADJ_SET, set_oom_score_adj_action, NULL, NULL);
+       register_action(PROCESS_GROUP_SET, set_process_group_action, NULL, NULL);
+
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, proc_booting_done);
+}
+
+static const struct device_ops process_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "process",
+       .init     = process_init,
+};
+
+DEVICE_OPS_REGISTER(&process_device_ops)
diff --git a/src/proc/proc-handler.h b/src/proc/proc-handler.h
new file mode 100644 (file)
index 0000000..4a87faf
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2000 - 2011 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 __PROC_HANDLER_H__
+#define __PROC_HANDLER_H__
+
+#include "shared/score-defines.h"
+
+#define SIOP_CHANGED   "siop_level"
+
+int get_oom_score_adj(int pid, int *oom_score_adj);
+int set_oom_score_adj(int pid, int new_oom_score_adj);
+void check_siop_disable_process(int pid, char *default_name);
+int cur_siop_level(void);
+#endif /* __PROC_HANDLER_H__ */
diff --git a/src/restarter/CMakeLists.txt b/src/restarter/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1b0f9bf
--- /dev/null
@@ -0,0 +1,37 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(restart C)
+
+IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_ENGINEER_MODE")
+    OPTION(USE_ENGINEER_MODE "Use Engineer mode" ON)
+ENDIF()
+
+SET(SRCS restart.c)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+IF(USE_ENGINEER_MODE)
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions")
+ELSE()
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer")
+ENDIF()
+
+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/src/restarter/restart.c b/src/restarter/restart.c
new file mode 100644 (file)
index 0000000..550f469
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ *  system-server
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: DongGi Jang <dg0402.jang@samsung.com>
+ * 
+ * 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[])
+{
+       launch_evenif_exist("/etc/rc.d/rc.shutdown", "&");
+        sleep(1);
+        sync();
+       reboot(RB_AUTOBOOT);
+        return 0;
+}
diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..e687346
--- /dev/null
@@ -0,0 +1,7 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+SET(SHARED_SRCS
+       dbus.c
+)
+ADD_LIBRARY(shared STATIC ${SHARED_SRCS})
+SET_TARGET_PROPERTIES(shared PROPERTIES COMPILE_FLAGS "-fPIC")
diff --git a/src/shared/common.h b/src/shared/common.h
new file mode 100644 (file)
index 0000000..5a3ef23
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DD_COMMON_H__
+#define __DD_COMMON_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifndef DEPRECATED
+#define DEPRECATED __attribute__ ((deprecated))
+#endif
+
+#ifndef __CONSTRUCTOR__
+#define __CONSTRUCTOR__ __attribute__ ((constructor))
+#endif
+
+#ifndef __DESTRUCTOR__
+#define __DESTRUCTOR__ __attribute__ ((destructor))
+#endif
+
+#ifdef __cplusplus
+
+}
+#endif
+#endif                         /* __DD_COMMON_H__ */
diff --git a/src/shared/dbus.c b/src/shared/dbus.c
new file mode 100644 (file)
index 0000000..23bedad
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * 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 <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
+
+#include "common.h"
+#include "log.h"
+#include "dbus.h"
+
+/* -1 is a default timeout value, it's converted to 25*1000 internally. */
+#define DBUS_REPLY_TIMEOUT     (-1)
+
+struct pending_call_data {
+       dbus_pending_cb func;
+       void *data;
+};
+
+int append_variant(DBusMessageIter *iter, const char *sig, char *param[])
+{
+       char *ch;
+       int i;
+       int int_type;
+       uint64_t int64_type;
+       DBusMessageIter arr;
+       struct dbus_byte *byte;
+
+       if (!sig || !param)
+               return 0;
+
+       for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) {
+               switch (*ch) {
+               case 'i':
+                       int_type = atoi(param[i]);
+                       dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type);
+                       break;
+               case 'u':
+                       int_type = strtoul(param[i], NULL, 10);
+                       dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type);
+                       break;
+               case 't':
+                       int64_type = atoll(param[i]);
+                       dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type);
+                       break;
+               case 's':
+                       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &param[i]);
+                       break;
+               case 'a':
+                       ++i, ++ch;
+                       switch (*ch) {
+                       case 'y':
+                               dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &arr);
+                               byte = (struct dbus_byte*)param[i];
+                               dbus_message_iter_append_fixed_array(&arr, DBUS_TYPE_BYTE, &(byte->data), byte->size);
+                               dbus_message_iter_close_container(iter, &arr);
+                               break;
+                       default:
+                               break;
+                       }
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+DBusMessage *dbus_method_sync_with_reply(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[])
+{
+       DBusConnection *conn;
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       DBusError err;
+       int r;
+
+       conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (!conn) {
+               _E("dbus_bus_get error");
+               return NULL;
+       }
+
+       msg = dbus_message_new_method_call(dest, path, interface, method);
+       if (!msg) {
+               _E("dbus_message_new_method_call(%s:%s-%s)",
+                       path, interface, method);
+               return NULL;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       r = append_variant(&iter, sig, param);
+       if (r < 0) {
+               _E("append_variant error(%d) %s %s:%s-%s",
+                       r, dest, path, interface, method);
+               dbus_message_unref(msg);
+               return NULL;
+       }
+
+       dbus_error_init(&err);
+
+       reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err);
+       if (!reply) {
+               _E("dbus_connection_send error(No reply) %s %s:%s-%s",
+                       dest, path, interface, method);
+       }
+
+       if (dbus_error_is_set(&err)) {
+               _E("dbus_connection_send error(%s:%s) %s %s:%s-%s",
+                       err.name, err.message, dest, path, interface, method);
+               dbus_error_free(&err);
+               reply = NULL;
+       }
+
+       dbus_message_unref(msg);
+       return reply;
+}
+
+int dbus_method_sync(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[])
+{
+       DBusConnection *conn;
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       DBusError err;
+       int ret, result;
+
+       conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (!conn) {
+               _E("dbus_bus_get error");
+               return -EPERM;
+       }
+
+       msg = dbus_message_new_method_call(dest, path, interface, method);
+       if (!msg) {
+               _E("dbus_message_new_method_call(%s:%s-%s)",
+                       path, interface, method);
+               return -EBADMSG;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       ret = append_variant(&iter, sig, param);
+       if (ret < 0) {
+               _E("append_variant error(%d) %s %s:%s-%s",
+                       ret, dest, path, interface, method);
+               dbus_message_unref(msg);
+               return ret;
+       }
+
+       dbus_error_init(&err);
+
+       reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err);
+       dbus_message_unref(msg);
+       if (!reply) {
+               _E("dbus_connection_send error(%s:%s) %s %s:%s-%s",
+                       err.name, err.message, dest, path, interface, method);
+               dbus_error_free(&err);
+               return -ECOMM;
+       }
+
+       ret = dbus_message_get_args(reply, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
+       dbus_message_unref(reply);
+       if (!ret) {
+               _E("no message : [%s:%s] %s %s:%s-%s",
+                       err.name, err.message, dest, path, interface, method);
+               dbus_error_free(&err);
+               return -ENOMSG;
+       }
+
+       return result;
+}
+
+int dbus_method_async(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[])
+{
+       DBusConnection *conn;
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       int ret;
+
+       conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (!conn) {
+               _E("dbus_bus_get error");
+               return -EPERM;
+       }
+
+       msg = dbus_message_new_method_call(dest, path, interface, method);
+       if (!msg) {
+               _E("dbus_message_new_method_call(%s:%s-%s)",
+                       path, interface, method);
+               return -EBADMSG;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       ret = append_variant(&iter, sig, param);
+       if (ret < 0) {
+               _E("append_variant error(%d) %s %s:%s-%s",
+                       ret, dest, path, interface, method);
+               dbus_message_unref(msg);
+               return ret;
+       }
+
+       ret = dbus_connection_send(conn, msg, NULL);
+       dbus_message_unref(msg);
+       if (ret != TRUE) {
+               _E("dbus_connection_send error(%s %s:%s-%s)",
+                       dest, path, interface, method);
+               return -ECOMM;
+       }
+
+       return 0;
+}
+
+static void cb_pending(DBusPendingCall *pending, void *user_data)
+{
+       DBusMessage *msg;
+       DBusError err;
+       struct pending_call_data *data = user_data;
+       int ret;
+
+       ret = dbus_pending_call_get_completed(pending);
+       if (!ret) {
+               _I("dbus_pending_call_get_completed() fail");
+               dbus_pending_call_unref(pending);
+               return;
+       }
+
+       dbus_error_init(&err);
+       msg = dbus_pending_call_steal_reply(pending);
+       if (!msg) {
+               _E("no message : [%s:%s]", err.name, err.message);
+
+               if (data->func) {
+                       dbus_set_error(&err, "org.tizen.system.deviced.NoReply",
+                                       "There was no reply to this method call");
+                       data->func(data->data, NULL, &err);
+                       dbus_error_free(&err);
+               }
+               return;
+       }
+
+       ret = dbus_set_error_from_message(&err, msg);
+       if (ret) {
+               _E("error msg : [%s:%s]", err.name, err.message);
+
+               if (data->func)
+                       data->func(data->data, NULL, &err);
+               dbus_error_free(&err);
+       } else {
+               if (data->func)
+                       data->func(data->data, msg, &err);
+       }
+
+       dbus_message_unref(msg);
+       dbus_pending_call_unref(pending);
+}
+
+int dbus_method_async_with_reply(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[], dbus_pending_cb cb, int timeout, void *data)
+{
+       DBusConnection *conn;
+       DBusMessage *msg;
+       DBusMessageIter iter;
+       DBusPendingCall *pending = NULL;
+       struct pending_call_data *pdata;
+       int ret;
+
+       conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (!conn) {
+               _E("dbus_bus_get error");
+               return -EPERM;
+       }
+
+       msg = dbus_message_new_method_call(dest, path, interface, method);
+       if (!msg) {
+               _E("dbus_message_new_method_call(%s:%s-%s)",
+                       path, interface, method);
+               return -EBADMSG;
+       }
+
+       dbus_message_iter_init_append(msg, &iter);
+       ret = append_variant(&iter, sig, param);
+       if (ret < 0) {
+               _E("append_variant error(%d)%s %s:%s-%s",
+                       ret, dest, path, interface, method);
+               dbus_message_unref(msg);
+               return ret;
+       }
+
+       ret = dbus_connection_send_with_reply(conn, msg, &pending, timeout);
+       if (!ret) {
+               dbus_message_unref(msg);
+               _E("dbus_connection_send error(%s %s:%s-%s)",
+                       dest, path, interface, method);
+               return -ECOMM;
+       }
+
+       if (cb && pending) {
+               pdata = malloc(sizeof(struct pending_call_data));
+               if (!pdata)
+                       return -ENOMEM;
+
+               pdata->func = cb;
+               pdata->data = data;
+
+               ret = dbus_pending_call_set_notify(pending, cb_pending, pdata, free);
+               if (!ret) {
+                       free(pdata);
+                       dbus_message_unref(msg);
+                       dbus_pending_call_cancel(pending);
+                       return -ECOMM;
+               }
+       }
+
+       return 0;
+}
+
+static void __CONSTRUCTOR__ dbus_init(void)
+{
+       dbus_threads_init_default();
+}
diff --git a/src/shared/dbus.h b/src/shared/dbus.h
new file mode 100644 (file)
index 0000000..1aa4bc9
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * 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 __DBUS_H__
+#define __DBUS_H__
+
+#include <dbus/dbus.h>
+
+/*
+ * Template
+ *
+#define XXX_BUS_NAME                        "org.tizen.system.XXX"
+#define XXX_OBJECT_PATH                     "/Org/Tizen/System/XXX"
+#define XXX_INTERFACE_NAME                  XXX_BUS_NAME
+#define XXX_PATH_YYY                        XXX_OBJECT_PATH"/YYY"
+#define XXX_INTERFACE_YYY                   XXX_INTERFACE_NAME".YYY"
+#define XXX_SIGNAL_ZZZ                      "ZZZ"
+#define XXX_METHOD_ZZZ                      "ZZZ"
+ */
+
+/*
+ * Device daemon
+ */
+#define DEVICED_BUS_NAME                    "org.tizen.system.deviced"
+#define DEVICED_OBJECT_PATH                 "/Org/Tizen/System/DeviceD"
+#define DEVICED_INTERFACE_NAME              DEVICED_BUS_NAME
+/* Core service: get/set device status operations about device */
+#define DEVICED_PATH_CORE                   DEVICED_OBJECT_PATH"/Core"
+#define DEVICED_INTERFACE_CORE              DEVICED_INTERFACE_NAME".core"
+/* Display service: start/stop display(pm), get/set brightness operations about display */
+#define DEVICED_PATH_DISPLAY                DEVICED_OBJECT_PATH"/Display"
+#define DEVICED_INTERFACE_DISPLAY           DEVICED_INTERFACE_NAME".display"
+/* Pass service: start/stop pass operations about pass */
+#define DEVICED_PATH_PASS                   DEVICED_OBJECT_PATH"/Pass"
+#define DEVICED_INTERFACE_PASS              DEVICED_INTERFACE_NAME".pass"
+/* Hall service: get hall status operations about hall */
+#define DEVICED_PATH_HALL                   DEVICED_OBJECT_PATH"/Hall"
+#define DEVICED_INTERFACE_HALL              DEVICED_INTERFACE_NAME".hall"
+/* Power service: set resetkey disable operations about power */
+#define DEVICED_PATH_POWER                  DEVICED_OBJECT_PATH"/Power"
+#define DEVICED_INTERFACE_POWER             DEVICED_INTERFACE_NAME".power"
+/* Storage service: get storage size operatioins about storage */
+#define DEVICED_PATH_STORAGE                DEVICED_OBJECT_PATH"/Storage"
+#define DEVICED_INTERFACE_STORAGE           DEVICED_INTERFACE_NAME".storage"
+/* ODE service: request ode popup result operatioins about storage */
+#define DEVICED_PATH_ODE                    DEVICED_OBJECT_PATH"/Ode"
+#define DEVICED_INTERFACE_ODE               DEVICED_INTERFACE_NAME".ode"
+/* Haptic service: operatioins about haptic */
+#define DEVICED_PATH_HAPTIC                 DEVICED_OBJECT_PATH"/Haptic"
+#define DEVICED_INTERFACE_HAPTIC            DEVICED_INTERFACE_NAME".haptic"
+/* Lowmem service: get critical low status operations about Lowmem */
+#define DEVICED_PATH_LOWMEM                 DEVICED_OBJECT_PATH"/Lowmem"
+#define DEVICED_INTERFACE_LOWMEM            DEVICED_INTERFACE_NAME".lowmem"
+/* Poweroff service: get power off status operations about Poweroff */
+#define DEVICED_PATH_POWEROFF               DEVICED_OBJECT_PATH"/PowerOff"
+#define DEVICED_INTERFACE_POWEROFF          DEVICED_INTERFACE_NAME".PowerOff"
+/* Led service: play/stop led operations about led */
+#define DEVICED_PATH_LED                    DEVICED_OBJECT_PATH"/Led"
+#define DEVICED_INTERFACE_LED               DEVICED_INTERFACE_NAME".Led"
+/* MMC service: mount/unmount/format mmc operations about mmc */
+#define DEVICED_PATH_MMC                    DEVICED_OBJECT_PATH"/Mmc"
+#define DEVICED_INTERFACE_MMC               DEVICED_INTERFACE_NAME".Mmc"
+/* Process service: operations about process */
+#define DEVICED_PATH_PROCESS                DEVICED_OBJECT_PATH"/Process"
+#define DEVICED_INTERFACE_PROCESS           DEVICED_INTERFACE_NAME".Process"
+/* Key service: operations about key */
+#define DEVICED_PATH_KEY                    DEVICED_OBJECT_PATH"/Key"
+#define DEVICED_INTERFACE_KEY               DEVICED_INTERFACE_NAME".Key"
+/* USB client service: change usb connection mode */
+#define DEVICED_PATH_USB                    DEVICED_OBJECT_PATH"/Usb"
+#define DEVICED_INTERFACE_USB               DEVICED_INTERFACE_NAME".Usb"
+/* USB start/stop service: operations about usb start/stop */
+#define DEVICED_PATH_USB_CONTROL            DEVICED_OBJECT_PATH"/UsbControl"
+#define DEVICED_INTERFACE_USB_CONTROL       DEVICED_INTERFACE_NAME".UsbControl"
+/* USB host service: operations about usb start/stop */
+#define DEVICED_PATH_USBHOST                DEVICED_OBJECT_PATH"/Usbhost"
+#define DEVICED_INTERFACE_USBHOST           DEVICED_INTERFACE_NAME".Usbhost"
+/* Cpu service: operations about cpu */
+#define DEVICED_PATH_CPU                    DEVICED_OBJECT_PATH"/Cpu"
+#define DEVICED_INTERFACE_CPU               DEVICED_INTERFACE_NAME".Cpu"
+/* PmQos service: operations about pmqos */
+#define DEVICED_PATH_PMQOS                  DEVICED_OBJECT_PATH"/PmQos"
+#define DEVICED_INTERFACE_PMQOS             DEVICED_INTERFACE_NAME".PmQos"
+/* Sysnoti service */
+#define DEVICED_PATH_SYSNOTI                DEVICED_OBJECT_PATH"/SysNoti"
+#define DEVICED_INTERFACE_SYSNOTI           DEVICED_INTERFACE_NAME".SysNoti"
+/* ExtCon service */
+#define DEVICED_PATH_EXTCON                 DEVICED_OBJECT_PATH"/ExtCon"
+#define DEVICED_INTERFACE_EXTCON            DEVICED_INTERFACE_NAME".ExtCon"
+/* Battery service */
+#define DEVICED_PATH_BATTERY                DEVICED_OBJECT_PATH"/Battery"
+#define DEVICED_INTERFACE_BATTERY           DEVICED_INTERFACE_NAME".Battery"
+/* Time service */
+#define DEVICED_PATH_TIME                DEVICED_OBJECT_PATH"/Time"
+#define DEVICED_INTERFACE_TIME           DEVICED_INTERFACE_NAME".Time"
+/* Board service */
+#define DEVICED_PATH_BOARD                DEVICED_OBJECT_PATH"/Board"
+#define DEVICED_INTERFACE_BOARD           DEVICED_INTERFACE_NAME".Board"
+/* Testmode service */
+#define DEVICED_PATH_TESTMODE               DEVICED_OBJECT_PATH"/Testmode"
+#define DEVICED_INTERFACE_TESTMODE           DEVICED_INTERFACE_NAME".Testmode"
+
+/*
+ * Resource daemon
+ */
+#define RESOURCED_BUS_NAME                  "org.tizen.resourced"
+#define RESOURCED_OBJECT_PATH               "/Org/Tizen/ResourceD"
+#define RESOURCED_INTERFACE_NAME            RESOURCED_BUS_NAME
+
+#define RESOURCED_PATH_PROCESS              RESOURCED_OBJECT_PATH"/Process"
+#define RESOURCED_INTERFACE_PROCESS         RESOURCED_INTERFACE_NAME".process"
+#define RESOURCED_METHOD_ACTIVE             "Active"
+
+/*
+ * Popup launcher
+ */
+#define POPUP_BUS_NAME                      "org.tizen.system.popup"
+#define POPUP_OBJECT_PATH                   "/Org/Tizen/System/Popup"
+#define POPUP_INTERFACE_NAME                POPUP_BUS_NAME
+/* LED */
+#define POPUP_PATH_LED                      POPUP_OBJECT_PATH"/Led"
+#define POPUP_INTERFACE_LED                 POPUP_INTERFACE_NAME".Led"
+/* TICKER */
+#define POPUP_PATH_TICKER                   POPUP_OBJECT_PATH"/Ticker"
+#define POPUP_INTERFACE_TICKER              POPUP_INTERFACE_NAME".Ticker"
+/* Power off */
+#define POPUP_PATH_POWEROFF                 POPUP_OBJECT_PATH"/Poweroff"
+#define POPUP_INTERFACE_POWEROFF            POPUP_INTERFACE_NAME".Poweroff"
+/* Low battery */
+#define POPUP_PATH_LOWBAT                   POPUP_OBJECT_PATH"/Lowbat"
+#define POPUP_INTERFACE_LOWBAT              POPUP_INTERFACE_NAME".Lowbat"
+/* Low memory */
+#define POPUP_PATH_LOWMEM                   POPUP_OBJECT_PATH"/Lowmem"
+#define POPUP_INTERFACE_LOWMEM              POPUP_INTERFACE_NAME".Lowmem"
+/* MMC */
+#define POPUP_PATH_MMC                      POPUP_OBJECT_PATH"/Mmc"
+#define POPUP_INTERFACE_MMC                 POPUP_INTERFACE_NAME".Mmc"
+/* USB */
+#define POPUP_PATH_USB                      POPUP_OBJECT_PATH"/Usb"
+#define POPUP_INTERFACE_USB                 POPUP_INTERFACE_NAME".Usb"
+/* USB otg */
+#define POPUP_PATH_USBOTG                   POPUP_OBJECT_PATH"/Usbotg"
+#define POPUP_INTERFACE_USBOTG              POPUP_INTERFACE_NAME".Usbotg"
+/* USB host */
+#define POPUP_PATH_USBHOST                  POPUP_OBJECT_PATH"/Usbhost"
+#define POPUP_INTERFACE_USBHOST             POPUP_INTERFACE_NAME".Usbhost"
+/* System */
+#define POPUP_PATH_SYSTEM                   POPUP_OBJECT_PATH"/System"
+#define POPUP_INTERFACE_SYSTEM              POPUP_INTERFACE_NAME".System"
+/* Crash */
+#define POPUP_PATH_CRASH                    POPUP_OBJECT_PATH"/Crash"
+#define POPUP_INTERFACE_CRASH               POPUP_INTERFACE_NAME".Crash"
+/* ODE */
+#define POPUP_PATH_ODE                      POPUP_OBJECT_PATH"/Ode"
+#define POPUP_INTERFACE_ODE                 POPUP_INTERFACE_NAME".Ode"
+/* Battery */
+#define POPUP_PATH_BATTERY                  POPUP_OBJECT_PATH"/Battery"
+#define POPUP_INTERFACE_BATTERY             POPUP_INTERFACE_NAME".Battery"
+/* Servant */
+#define POPUP_PATH_SERVANT                  POPUP_OBJECT_PATH"/Servant"
+#define POPUP_IFACE_SERVANT                 POPUP_INTERFACE_NAME".Servant"
+
+#define POPUP_PATH_APP                      POPUP_OBJECT_PATH"/Apps"
+#define POPUP_IFACE_APP                     POPUP_BUS_NAME".Apps"
+
+#define POPUP_METHOD_LAUNCH                 "PopupLaunch"
+#define POPUP_METHOD_TERMINATE              "AppTerminateByPid"
+#define POPUP_KEY_CONTENT                   "_SYSPOPUP_CONTENT_"
+#define POPUP_METHOD_SCREENOFF_TTS          "ScreenOffTts"
+
+/*
+ * Crash daemon
+ */
+#define CRASHD_BUS_NAME                     "org.tizen.system.crashd"
+#define CRASHD_OBJECT_PATH                  "/Org/Tizen/System/CrashD"
+#define CRASHD_INTERFACE_NAME               CRASHD_BUS_NAME
+
+#define CRASHD_PATH_CRASH                   CRASHD_OBJECT_PATH"/Crash"
+#define CRASHD_INTERFACE_CRASH              CRASHD_INTERFACE_NAME".Crash"
+
+struct dbus_byte {
+       const char *data;
+       int size;
+};
+
+int append_variant(DBusMessageIter *iter, const char *sig, char *param[]);
+
+DBusMessage *dbus_method_sync_with_reply(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[]);
+
+int dbus_method_sync(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[]);
+
+int dbus_method_async(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[]);
+
+typedef void (*dbus_pending_cb)(void *data, DBusMessage *msg, DBusError *err);
+
+int dbus_method_async_with_reply(const char *dest, const char *path,
+               const char *interface, const char *method,
+               const char *sig, char *param[], dbus_pending_cb cb, int timeout, void *data);
+#endif
diff --git a/src/shared/deviced-internal.h b/src/shared/deviced-internal.h
new file mode 100644 (file)
index 0000000..b26d67e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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 ___DEVICED_INTERNAL___
+#define ___DEVICED_INTERNAL___
+#include <sys/types.h>
+#include "dd-deviced.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This file will be removed */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif                         /* ___DEVICED_INTERNAL___ */
diff --git a/src/shared/deviced-priv.h b/src/shared/deviced-priv.h
new file mode 100644 (file)
index 0000000..0adb00f
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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 __SYSTEM_PRIVATE__
+#define __SYSTEM_PRIVATE__
+
+#include "common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SYSTEM_NOTI_MAXARG 16
+#define SYSTEM_NOTI_MAXSTR 255
+#define BUFF_MAX 255
+
+struct sysnoti {
+       int pid;
+       int cmd;
+       char *type;
+       char *path;
+       int argc;
+       char *argv[SYSTEM_NOTI_MAXARG];
+};
+
+       int util_launch_app_cmd(const char *cmdline);
+
+#ifdef __cplusplus
+}
+#endif
+#endif                         /* __SYSTEM_PRIVATE__ */
diff --git a/src/shared/list.h b/src/shared/list.h
new file mode 100644 (file)
index 0000000..b05e35f
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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 __LIST_H__
+#define __LIST_H__
+
+#include <glib.h>
+
+#define LIST_ADD(head, data)                            \
+       do {                                                \
+               head = g_list_append(head, data);               \
+       } while(0)
+
+#define LIST_DEL(head, data)                            \
+       do {                                                \
+               head = g_list_remove(head, data);               \
+       } while(0)
+
+#define LIST_FIND(head, node, t, name, data)            \
+       do {                                                \
+               t *tmp;                                         \
+               GList *elem;                                    \
+               for (elem = head; elem; elem = elem->next) {    \
+                       tmp = elem->data;                           \
+                       if (tmp->##name != data)                    \
+                               continue;                               \
+                       node = tmp;                                 \
+               }                                               \
+       } while(0)
+
+#define LIST_FOREACH(head, item)                        \
+               for (item = head; item; item = item->next)
+
+#endif
diff --git a/src/shared/log-macro.h b/src/shared/log-macro.h
new file mode 100644 (file)
index 0000000..407995e
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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_MACRO_H__
+#define __LOG_MACRO_H__
+
+#ifdef ENABLE_DLOG
+#include <dlog.h>
+#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(...)  do { } while (0)
+#define _I(...)  do { } while (0)
+#define _W(...)  do { } while (0)
+#define _E(...)  do { } while (0)
+#define _SD(...)   do { } while (0)
+#define _SI(...)   do { } while (0)
+#define _SW(...)   do { } while (0)
+#define _SE(...)   do { } while (0)
+#endif
+#endif
diff --git a/src/shared/log.h b/src/shared/log.h
new file mode 100644 (file)
index 0000000..29b6c85
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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__
+
+#ifdef ENABLE_LIBDEVICED_DLOG
+#define ENABLE_DLOG
+#endif
+
+#define LOG_TAG "DEVICED"
+#include "shared/log-macro.h"
+
+#endif
diff --git a/src/shared/score-defines.h b/src/shared/score-defines.h
new file mode 100644 (file)
index 0000000..44638e7
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * deviced
+ *
+ * Copyright (c) 2000 - 2011 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 __OOM_H__
+#define __OOM_H__
+
+#define OOMADJ_SU                   (0)
+#define OOMADJ_INIT                 (100)
+#define OOMADJ_FOREGRD_LOCKED       (150)
+#define OOMADJ_FOREGRD_UNLOCKED     (200)
+#define OOMADJ_BACKGRD_LOCKED       (250)
+#define OOMADJ_BACKGRD_UNLOCKED     (300)
+#define OOMADJ_APP_LIMIT            OOMADJ_INIT
+
+#endif /* __OOM_H__ */
diff --git a/src/ta/ta-handler.c b/src/ta/ta-handler.c
new file mode 100644 (file)
index 0000000..e67c9ea
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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 <vconf.h>
+#include <device-node.h>
+
+#include "core/log.h"
+#include "core/data.h"
+#include "core/devices.h"
+#include "display/poll.h"
+#include "core/common.h"
+
+#define RETRY  3
+
+enum ta_connect_status{
+       TA_OFFLINE = 0,
+       TA_ONLINE = 1,
+};
+
+static int __check_insuspend_charging(void)
+{
+       int val, ret;
+
+       ret = device_get_property(DEVICE_TYPE_POWER, PROP_POWER_INSUSPEND_CHARGING_SUPPORT, &val);
+       if (ret != 0)
+               val = 0;
+       if (val == 0)
+               ret = pm_lock_internal(INTERNAL_LOCK_TA, LCD_OFF, STAY_CUR_STATE, 0);
+       else
+               ret = 0;
+       return ret;
+}
+
+static void ta_init(void *data)
+{
+       int val, i = 0;
+       int ret;
+
+       if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_TA_ONLINE, &val) != 0)
+               val = -EINVAL;
+
+       if (val == TA_ONLINE) {
+               vconf_set_int(VCONFKEY_SYSMAN_CHARGER_STATUS,
+                               VCONFKEY_SYSMAN_CHARGER_CONNECTED);
+               while (i < RETRY
+                          && __check_insuspend_charging() == -1) {
+                       i++;
+                       sleep(1);
+               }
+       } else if (val == TA_OFFLINE) {
+               vconf_set_int(VCONFKEY_SYSMAN_CHARGER_STATUS,
+                               VCONFKEY_SYSMAN_CHARGER_DISCONNECTED);
+       }
+}
+
+static const struct device_ops ta_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "ta",
+       .init     = ta_init,
+};
+
+DEVICE_OPS_REGISTER(&ta_device_ops)
diff --git a/src/telephony/telephony.c b/src/telephony/telephony.c
new file mode 100644 (file)
index 0000000..cd28f7e
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * 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 <ITapiModem.h>
+#include <TelPower.h>
+#include <tapi_event.h>
+#include <tapi_common.h>
+#include <TapiCommon.h>
+#include <TapiEvent.h>
+#include <ITapiProductivity.h>
+
+#include <unistd.h>
+#include <assert.h>
+#include <vconf.h>
+
+#include <device-node.h>
+#include "dd-deviced.h"
+#include "core/log.h"
+#include "core/queue.h"
+#include "core/predefine.h"
+#include "core/data.h"
+#include "core/common.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+#include "display/core.h"
+#include "power/power-handler.h"
+
+#define PREDEF_FLIGHT_MODE     "flightmode"
+#define PREDEF_ENTERSLEEP      "entersleep"
+#define PREDEF_LEAVESLEEP      "leavesleep"
+
+#define POWER_RESTART          5
+
+static TapiHandle *tapi_handle = NULL;
+static Ecore_Timer *poweroff_timer_id = NULL;
+static int reboot_opt;
+
+static Eina_Bool telephony_powerdown_ap_internal(void *data)
+{
+       powerdown_ap(data);
+       return EINA_FALSE;
+}
+static void telephony_powerdown_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
+{
+       telephony_powerdown_ap_internal(data);
+}
+
+static void telephony_restart_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
+{
+       restart_ap((void *)reboot_opt);
+}
+
+static Eina_Bool telephony_restart_ap_by_force(void *data)
+{
+       if (poweroff_timer_id) {
+               ecore_timer_del(poweroff_timer_id);
+               poweroff_timer_id = NULL;
+       }
+       restart_ap(data);
+       return EINA_TRUE;
+}
+
+static void powerdown_res_cb(TapiHandle *handle, int result, void *data, void *user_data)
+{
+       _D("poweroff command request : %d",result);
+}
+
+static Eina_Bool telephony_powerdown_ap_by_force(void *data)
+{
+       if (poweroff_timer_id) {
+               ecore_timer_del(poweroff_timer_id);
+               poweroff_timer_id = NULL;
+       }
+       powerdown_ap(data);
+       return EINA_TRUE;
+}
+
+static int telephony_start(void)
+{
+       int ready = 0;
+
+       if (tapi_handle) {
+               _I("already initialized");
+               return 0;
+       }
+       if (vconf_get_bool(VCONFKEY_TELEPHONY_READY,&ready) != 0 || ready != 1) {
+               _E("fail to get %s(%d)", VCONFKEY_TELEPHONY_READY, ready);
+               return -EINVAL;
+       }
+       tapi_handle = tel_init(NULL);
+       if (tapi_handle == NULL) {
+               _E("tapi init error");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int telephony_stop(void)
+{
+       int ret;
+       tel_deregister_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER);
+       ret = tel_deinit(tapi_handle);
+       if (ret != 0) {
+               _E("fail to deinit");
+               return -EINVAL;
+       }
+       tapi_handle = NULL;
+       return 0;
+}
+
+static void telephony_exit(void *data)
+{
+       int ret;
+
+       if (!data) {
+               _E("Option Failed");
+               return;
+       }
+
+       if (!strncmp(data, PREDEF_POWEROFF, strlen(PREDEF_POWEROFF))) {
+               _I("Terminate");
+               ret = tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER,
+                               telephony_powerdown_ap, NULL);
+               if (ret != TAPI_API_SUCCESS) {
+                       _E("tel_register_event is not subscribed. error %d", ret);
+                       telephony_powerdown_ap_by_force(NULL);
+                       return;
+               }
+               ret = tel_process_power_command(tapi_handle, TAPI_PHONE_POWER_OFF,
+                               powerdown_res_cb, NULL);
+               if (ret != TAPI_API_SUCCESS) {
+                       _E("tel_process_power_command() error %d\n", ret);
+                       telephony_powerdown_ap_by_force(NULL);
+                       return;
+               }
+               poweroff_timer_id = ecore_timer_add(15,
+                   telephony_powerdown_ap_internal, NULL);
+               return;
+       }
+
+       if (strncmp(data, PREDEF_REBOOT, strlen(PREDEF_REBOOT)) &&
+           strncmp(data, PREDEF_RECOVERY, strlen(PREDEF_RECOVERY)) &&
+           strncmp(data, PREDEF_FOTA_REBOOT, strlen(PREDEF_FOTA_REBOOT))) {
+               _E("Fail %s", data);
+               return;
+       }
+
+       _I("Option: %s", data);
+        if (!strncmp(data, PREDEF_RECOVERY, strlen(PREDEF_RECOVERY)))
+               reboot_opt = SYSTEMD_STOP_POWER_RESTART_RECOVERY;
+       else if (!strncmp(data, PREDEF_REBOOT, strlen(PREDEF_REBOOT)))
+               reboot_opt = SYSTEMD_STOP_POWER_RESTART;
+       else if (!strncmp(data, PREDEF_FOTA_REBOOT, strlen(PREDEF_FOTA_REBOOT)))
+               reboot_opt = SYSTEMD_STOP_POWER_RESTART_FOTA;
+
+       ret = tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER,
+                       telephony_restart_ap, NULL);
+       if (ret != TAPI_API_SUCCESS) {
+               _E("tel_register_event is not subscribed. error %d", ret);
+               telephony_restart_ap_by_force((void *)POWER_RESTART);
+               return;
+       }
+       ret = tel_process_power_command(tapi_handle, TAPI_PHONE_POWER_OFF,
+                       powerdown_res_cb, NULL);
+       if (ret != TAPI_API_SUCCESS) {
+               _E("tel_process_power_command() error %d", ret);
+               telephony_restart_ap_by_force((void *)reboot_opt);
+               return;
+       }
+       poweroff_timer_id = ecore_timer_add(15,telephony_restart_ap_by_force,
+                                                       (void *)reboot_opt);
+}
+
+static void telephony_flight_mode_on(TapiHandle *handle, int result, void *data, void *user_data)
+{
+       int ret;
+       int bCurFlightMode = 0;
+
+       if (result != TAPI_POWER_FLIGHT_MODE_ENTER) {
+               _E("flight mode enter failed %d", result);
+               return;
+       }
+       _D("enter flight mode result : %d", result);
+       ret = vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &bCurFlightMode);
+       if (ret == 0)
+               _D("Flight Mode is %d", bCurFlightMode);
+       else
+               _E("failed to get vconf key");
+}
+
+static void telephony_flight_mode_off(TapiHandle *handle, int result, void *data, void *user_data)
+{
+       int ret;
+       int bCurFlightMode = 0;
+
+       if (result != TAPI_POWER_FLIGHT_MODE_LEAVE) {
+               _E("flight mode leave failed %d", result);
+               return;
+       }
+       _D("leave flight mode result : %d", result);
+       ret = vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &bCurFlightMode);
+       if (ret == 0)
+               _D("Flight Mode is %d", bCurFlightMode);
+       else
+               _E("failed to get vconf key");
+}
+
+static int telephony_flight_mode(int argc, char **argv)
+{
+       int ret;
+       int mode;
+       int err = TAPI_API_SUCCESS;
+
+       if (argc != 1 || argv[0] == NULL) {
+               _E("FlightMode Set predefine action failed");
+               return -1;
+       }
+       mode = atoi(argv[0]);
+
+       if (tapi_handle == NULL) {
+               ret = telephony_start();
+               if (ret != 0) {
+                       _E("fail to get tapi handle");
+                       return -1;
+               }
+       }
+
+       if (mode == 1) {
+               err = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_LEAVE,
+                               telephony_flight_mode_off, NULL);
+       } else if (mode == 0) {
+               err = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_ENTER,
+                               telephony_flight_mode_on, NULL);
+       }
+       if (err != TAPI_API_SUCCESS)
+               _E("FlightMode tel api action failed %d",err);
+
+       return 0;
+}
+
+static int telephony_enter_sleep(int argc, char **argv)
+{
+       int ret;
+
+       pm_change_internal(getpid(), LCD_NORMAL);
+       sync();
+
+       /* flight mode
+        * TODO - add check, cb, etc...
+        * should be checked wirh telephony part */
+       ret = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_ENTER,
+                       telephony_flight_mode_on, NULL);
+       _I("request for changing into flight mode : %d", ret);
+
+       launch_evenif_exist("/etc/rc.d/rc.entersleep", "");
+       pm_change_internal(getpid(), POWER_OFF);
+
+       return 0;
+}
+
+static int telephony_leave_sleep(int argc, char **argv)
+{
+       int ret;
+
+       pm_change_internal(getpid(), LCD_NORMAL);
+       sync();
+
+       /* flight mode
+        * TODO - add check, cb, etc...
+        * should be checked wirh telephony part */
+       ret = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_LEAVE,
+                       telephony_flight_mode_off, NULL);
+       _I("request for changing into flight mode : %d", ret);
+
+       return 0;
+}
+
+static DBusMessage *flight_mode_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+       char *argv;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       telephony_flight_mode(argc, (char **)&argv);
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static DBusMessage *telephony_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (tapi_handle == NULL) {
+               if (telephony_start() != 0)
+                       _E("fail to get tapi handle");
+       }
+
+       if (!strncmp(type_str, PREDEF_ENTERSLEEP, strlen(PREDEF_ENTERSLEEP)))
+               ret = telephony_enter_sleep(0, NULL);
+       else if (!strncmp(type_str, PREDEF_LEAVESLEEP, strlen(PREDEF_LEAVESLEEP)))
+               ret = telephony_leave_sleep(0, NULL);
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { PREDEF_FLIGHT_MODE, "sis", "i", flight_mode_handler },
+       { PREDEF_ENTERSLEEP, "si", "i", telephony_handler },
+       { PREDEF_LEAVESLEEP, "si", "i", telephony_handler },
+       /* Add methods here */
+};
+
+static void telephony_init(void *data)
+{
+       int ret;
+
+       /* init dbus interface */
+       ret = register_edbus_method(DEVICED_PATH_POWER, edbus_methods,
+                       ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       register_action(PREDEF_FLIGHT_MODE, telephony_flight_mode, NULL, NULL);
+       register_action(PREDEF_ENTERSLEEP, telephony_enter_sleep, NULL, NULL);
+       register_action(PREDEF_LEAVESLEEP, telephony_leave_sleep, NULL, NULL);
+}
+
+static const struct device_ops tel_device_ops = {
+       .priority       = DEVICE_PRIORITY_NORMAL,
+       .name           = "telephony",
+       .init           = telephony_init,
+       .start          = telephony_start,
+       .stop           = telephony_stop,
+       .exit           = telephony_exit,
+};
+
+DEVICE_OPS_REGISTER(&tel_device_ops)
diff --git a/src/testmode/testmode.c b/src/testmode/testmode.c
new file mode 100644 (file)
index 0000000..0c246b9
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 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 <stdbool.h>
+#include <assert.h>
+#include <limits.h>
+#include "core/log.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+#include "core/launch.h"
+
+static DBusMessage *edbus_testmode_launch(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *argv;
+       char param[32];
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+       sprintf(param, "%s", argv);
+       _D("param %s", param);
+
+       launch_evenif_exist("/usr/bin/testmode-env.sh", param);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "Launch", "s",   "i", edbus_testmode_launch },
+       /* Add methods here */
+};
+
+/* battery ops init funcion */
+static void testmode_init(void *data)
+{
+       int ret;
+
+       /* init dbus interface */
+       ret = register_edbus_method(DEVICED_PATH_TESTMODE,
+                       edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+}
+
+/* battery ops exit funcion */
+static void testmode_exit(void *data)
+{
+}
+
+static const struct device_ops battery_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "testmode",
+       .init     = testmode_init,
+       .exit     = testmode_exit,
+};
+
+DEVICE_OPS_REGISTER(&battery_device_ops)
diff --git a/src/ticker/ticker.c b/src/ticker/ticker.c
new file mode 100755 (executable)
index 0000000..89bed50
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * deviced
+ *
+ * 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 <vconf.h>
+#include "core/log.h"
+#include "ticker.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+
+void show_ticker_noti(char *name)
+{
+       int ret, ret_val;
+       char *param[1];
+
+       if (!name)
+               return ;
+
+       param[0] = name;
+
+       ret_val = dbus_method_async(POPUP_BUS_NAME,
+                       POPUP_PATH_TICKER,
+                       POPUP_INTERFACE_TICKER,
+                       "TickerNotiOn", "s", param);
+       return;
+}
+
+void insert_ticker_queue(char *name)
+{
+       /* TODO: Implement queue for ticker noti */
+}
+
+static void ticker_init(void *data)
+{
+       const struct ticker_ops *dev;
+       struct ticker_data *input;
+       static int initialized = 0;
+
+       if (!initialized) {
+               initialized = 1;
+               return;
+       }
+
+       input = (struct ticker_data *)data;
+       if (input == NULL || input->name == NULL)
+               return;
+
+       if (input->type == WITHOUT_QUEUE) {
+               _E("without queue");
+               show_ticker_noti(input->name);
+       } else {
+               _E("with queue");
+               insert_ticker_queue(input->name);
+       }
+}
+
+static const struct device_ops ticker_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "ticker",
+       .init     = ticker_init,
+};
+
+DEVICE_OPS_REGISTER(&ticker_device_ops)
diff --git a/src/ticker/ticker.h b/src/ticker/ticker.h
new file mode 100755 (executable)
index 0000000..3d1b36a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * deviced
+ *
+ * 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 __TICKER_H__
+#define __TICKER_H__
+
+
+#include "core/common.h"
+#include "core/data.h"
+
+enum ticker_type {
+       WITHOUT_QUEUE, /* for usb client */
+       WITH_QUEUE,    /* for other situations */
+};
+
+struct ticker_data {
+       char *name;
+       int type;
+};
+
+#endif /* __TICKER_H__ */
+
diff --git a/src/time/time-handler.c b/src/time/time-handler.c
new file mode 100644 (file)
index 0000000..3eb241b
--- /dev/null
@@ -0,0 +1,382 @@
+/*
+ * 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 <stdbool.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <vconf.h>
+#include <time.h>
+#include <sys/ioctl.h>
+#include <linux/rtc.h>
+#include <fcntl.h>
+#include <sys/timerfd.h>
+
+#include "core/data.h"
+#include "core/queue.h"
+#include "core/log.h"
+#include "core/devices.h"
+#include "display/poll.h"
+#include "display/core.h"
+#include "core/edbus-handler.h"
+#include "core/common.h"
+#include "core/device-notifier.h"
+
+#define PREDEF_SET_DATETIME            "set_datetime"
+#define PREDEF_SET_TIMEZONE            "set_timezone"
+
+#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
+
+#define TIME_CHANGE_SIGNAL     "STimeChanged"
+
+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 Eina_Bool 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;
+       time_t now;
+       struct tm *ts;
+       const char *sympath = default_localtime;
+
+       if (str == NULL)
+               return -1;
+       const char *tzpath = str;
+
+       _D("TZPATH = %s", tzpath);
+
+       if (stat(tzpath, &sts) == -1 && errno == ENOENT) {
+               _E("invalid tzpath(%s)", tzpath);
+               return -EINVAL;
+       }
+
+       /* FIXME for debugging purpose */
+       time(&now);
+       ts = localtime(&now);
+       _D("cur local time is %s", asctime(ts));
+
+       /* unlink current link
+        * eg. rm /opt/etc/localtime */
+       if (stat(sympath, &sts) == -1 && errno == ENOENT) {
+               /* DO NOTHING */
+       } else {
+               ret = unlink(sympath);
+               if (ret < 0) {
+                       _E("unlink error : [%d]%s", ret,
+                                 strerror(errno));
+                       return -1;
+               }
+               _D("unlink success");
+       }
+
+       /* symlink new link
+        * eg. ln -s /usr/share/zoneinfo/Asia/Seoul /opt/etc/localtime */
+       ret = symlink(tzpath, sympath);
+       if (ret < 0) {
+               _E("symlink error : [%d]%s", ret, strerror(errno));
+               return -1;
+       }
+       _D("symlink success");
+
+       tzset();
+
+       /* FIXME for debugging purpose */
+       ts = localtime(&now);
+       _D("new local time is %s", asctime(ts));
+       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;
+
+       _D("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)
+               _E("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_internal(INTERNAL_LOCK_TIME, pm_state, STAY_CUR_STATE, 0);
+       ret = handle_date(argv[0]);
+       pm_unlock_internal(INTERNAL_LOCK_TIME, 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)
+               _E("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_internal(INTERNAL_LOCK_TIME, pm_state, STAY_CUR_STATE, 0);
+       ret = handle_timezone(argv[0]);
+       pm_unlock_internal(INTERNAL_LOCK_TIME, pm_state, STAY_CUR_STATE);
+       return ret;
+}
+
+static void time_changed_broadcast(void)
+{
+       broadcast_edbus_signal(DEVICED_PATH_TIME, DEVICED_INTERFACE_TIME,
+                       TIME_CHANGE_SIGNAL, NULL, NULL);
+}
+
+static int timerfd_check_start(void)
+{
+       int tfd;
+       struct itimerspec tmr;
+
+       if ((tfd = timerfd_create(CLOCK_REALTIME,TFD_NONBLOCK|TFD_CLOEXEC)) == -1) {
+               _E("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) {
+               _E("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) {
+               _E("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 Eina_Bool 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)) {
+               _E("error ecore_main_fd_handler_get()");
+               goto out;
+       }
+
+       if((tfd = ecore_main_fd_handler_fd_get(fd_handler)) == -1) {
+               _E("error ecore_main_fd_handler_fd_get()");
+               goto out;
+       }
+
+       ret = read(tfd,&ticks,sizeof(ticks));
+       if (ret < 0 && errno == ECANCELED) {
+               vconf_set_int(VCONFKEY_SYSMAN_STIME, VCONFKEY_SYSMAN_STIME_CHANGED);
+               time_changed_broadcast();
+               timerfd_check_stop(tfd);
+               _D("NOTIFICATION here");
+               timerfd_check_start();
+       } else {
+               _E("unexpected read (err:%d)", errno);
+       }
+out:
+       return EINA_TRUE;
+}
+
+static DBusMessage *dbus_time_handler(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusError err;
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       pid_t pid;
+       int ret;
+       int argc;
+       char *type_str;
+       char *argv;
+
+       dbus_error_init(&err);
+
+       if (!dbus_message_get_args(msg, &err,
+                   DBUS_TYPE_STRING, &type_str,
+                   DBUS_TYPE_INT32, &argc,
+                   DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
+               _E("there is no message");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (argc < 0) {
+               _E("message is invalid!");
+               ret = -EINVAL;
+               goto out;
+       }
+
+       pid = get_edbus_sender_pid(msg);
+       if (kill(pid, 0) == -1) {
+               _E("%d process does not exist, dbus ignored!", pid);
+               ret = -ESRCH;
+               goto out;
+       }
+
+       if (strncmp(type_str, PREDEF_SET_DATETIME, strlen(PREDEF_SET_DATETIME)) == 0)
+               ret = set_datetime_action(argc, (char **)&argv);
+       else if (strncmp(type_str, PREDEF_SET_TIMEZONE, strlen(PREDEF_SET_TIMEZONE)) == 0)
+               ret = set_timezone_action(argc, (char **)&argv);
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { PREDEF_SET_DATETIME, "sis", "i", dbus_time_handler },
+       { PREDEF_SET_TIMEZONE, "sis", "i", dbus_time_handler },
+
+};
+
+static int time_lcd_changed_cb(void *data)
+{
+       int lcd_state = (int)data;
+       int tfd = -1;
+
+       if (lcd_state < S_LCDOFF)
+               goto restart;
+
+       lcd_state = check_lcdoff_lock_state();
+       if (lcd_state || !tfdh)
+               goto out;
+       tfd = ecore_main_fd_handler_fd_get(tfdh);
+       if (tfd == -1)
+               goto out;
+
+       _D("stop tfd");
+       timerfd_check_stop(tfd);
+       goto out;
+restart:
+       if (tfdh)
+               return 0;
+       _D("restart tfd");
+       timerfd_check_start();
+out:
+       return 0;
+}
+
+static void time_init(void *data)
+{
+       int ret;
+
+       ret = register_edbus_method(DEVICED_PATH_SYSNOTI, edbus_methods, ARRAY_SIZE(edbus_methods));
+       if (ret < 0)
+               _E("fail to init edbus method(%d)", ret);
+
+       register_action(PREDEF_SET_DATETIME, set_datetime_action, NULL, NULL);
+       register_action(PREDEF_SET_TIMEZONE, set_timezone_action, NULL, NULL);
+       if (timerfd_check_start() == -1) {
+               _E("fail system time change detector init");
+       }
+       register_notifier(DEVICE_NOTIFIER_LCD, time_lcd_changed_cb);
+}
+
+static const struct device_ops time_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "time",
+       .init     = time_init,
+};
+
+DEVICE_OPS_REGISTER(&time_device_ops)
diff --git a/src/touch/touch-controller.c b/src/touch/touch-controller.c
new file mode 100644 (file)
index 0000000..b9a453d
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Touch controller
+ *
+ * Copyright (c) 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.
+ */
+
+#include "touch-controller.h"
+#include "core/common.h"
+
+static struct touch_control *touch_control;
+
+/******************************************************
+ *                Touch VCONF interface               *
+ ******************************************************/
+static void touch_vconf_pm_sip_status(keynode_t *key, void* data)
+{
+       int sip_state;
+
+       if (vconf_get_int(VCONFKEY_ISF_INPUT_PANEL_STATE, &sip_state) != 0)
+               return;
+
+       switch (sip_state) {
+       case VCONFKEY_ISF_INPUT_PANEL_STATE_HIDE:
+               /* If SIP is off state, should turn on touch boost feature */
+               touch_boost_enable(touch_control, TOUCH_TYPE_VCONF_SIP, TOUCH_BOOST_ON);
+               break;
+       case VCONFKEY_ISF_INPUT_PANEL_STATE_SHOW:
+               /* If SIP is on state, should turn off touch boost feature */
+               touch_boost_enable(touch_control, TOUCH_TYPE_VCONF_SIP, TOUCH_BOOST_OFF);
+               break;
+       default:
+               _E("Unknow SIP type");
+               return;
+       }
+}
+
+static struct touch_vconf_block vconf_block[] = {
+       {
+               .vconf          = VCONFKEY_ISF_INPUT_PANEL_STATE,
+               .vconf_function = touch_vconf_pm_sip_status,
+       },
+};
+
+static int touch_vconf_stop(void)
+{
+       int i;
+       int ret;
+       int size;
+
+       if (!touch_control) {
+               _E("cannot stop touch_vconf");
+               return -EINVAL;
+       }
+
+       /* Unregister callback function of VCONFKEY */
+       size = ARRAY_SIZE(vconf_block);
+       for (i = 0; i < size; i++) {
+               ret = vconf_ignore_key_changed(vconf_block[i].vconf,
+                                       vconf_block[i].vconf_function);
+               if (ret < 0)
+                       _E("cannot unregister 'vconf function' : %d",
+                                       vconf_block[i].vconf);
+       }
+
+       _I("Stop Touch of VCONF");
+
+       return 0;
+}
+
+static int touch_vconf_start(void)
+{
+       int i;
+       int ret;
+       int size;
+
+       if (!touch_control) {
+               _E("cannot start touch_vconf");
+               return -EINVAL;
+       }
+
+       size = ARRAY_SIZE(vconf_block);
+
+       /* Register callback function of VCONFKEY */
+       for (i = 0; i < size; i++) {
+               ret = vconf_notify_key_changed(vconf_block[i].vconf,
+                                       vconf_block[i].vconf_function,
+                                       (void *)touch_control);
+               if (ret < 0)
+                       _E("cannot register 'vconf function' : %d",
+                                       vconf_block[i].vconf);
+       }
+
+       _I("Start Touch of VCONF");
+
+       return 0;
+}
+
+/******************************************************
+ *             Touch controller interface             *
+ ******************************************************/
+API void touch_controller_start(void)
+{
+       touch_vconf_start();
+
+       /* Add to start() of new touch type */
+}
+
+API void touch_controller_stop(void)
+{
+       touch_vconf_stop();
+
+       /* Add to stop() of new touch type */
+}
+
+API void touch_controller_init(struct touch_control *tc)
+{
+       touch_control = tc;
+}
+
+API void touch_controller_exit(void)
+{
+       touch_control = NULL;
+}
diff --git a/src/touch/touch-controller.h b/src/touch/touch-controller.h
new file mode 100644 (file)
index 0000000..284d8a2
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Touch controller
+ *
+ * Copyright (c) 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 __TOUCH_CONTROLLER__
+#define __TOUCH_CONTROLLER__
+
+#include "touch.h"
+#include "shared/common.h"
+
+/*
+ * struct touch_vconf_block
+ */
+struct touch_vconf_block {
+       char *vconf;
+       void (*vconf_function)(keynode_t *key, void* data);
+};
+
+void touch_controller_init(struct touch_control *);
+void touch_controller_exit(void);
+void touch_controller_start(void);
+void touch_controller_stop(void);
+
+#endif /* __TOUCH_CONTROLLER__ */
diff --git a/src/touch/touch-plugin.c b/src/touch/touch-plugin.c
new file mode 100644 (file)
index 0000000..8900e40
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Touch - Support plugin feature for Touch
+ *
+ * Copyright (c) 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "touch-plugin.h"
+
+#define TOUCH_BOOST_OFF                "/sys/devices/system/cpu/cpu0/cpufreq/touch_boost_off"
+
+/*
+ * Helper function
+ * - Read from sysfs entry
+ * - Write to sysfs entry
+ */
+#define BUFF_MAX 255
+static int sys_read_buf(char *file, char *buf)
+{
+       int fd;
+       int r;
+       int ret = 0;
+
+       fd = open(file, O_RDONLY);
+       if (fd == -1)
+               return -ENOENT;
+
+       r = read(fd, buf, BUFF_MAX);
+       if ((r >= 0) && (r < BUFF_MAX))
+               buf[r] = '\0';
+       else
+               ret = -EIO;
+
+       close(fd);
+
+       return ret;
+}
+
+static int sys_write_buf(char *file, char *buf)
+{
+       int fd;
+       int r;
+       int ret = 0;
+
+       fd = open(file, O_WRONLY);
+       if (fd == -1)
+               return -ENOENT;
+
+       r = write(fd, buf, strlen(buf));
+       if (r < 0)
+               ret = -EIO;
+
+       close(fd);
+
+       return ret;
+}
+
+static int sys_get_int(char *fname, int *val)
+{
+       char buf[BUFF_MAX];
+       int ret = 0;
+
+       if (sys_read_buf(fname, buf) == 0) {
+               *val = atoi(buf);
+       } else {
+               *val = -1;
+               ret = -EIO;
+       }
+
+       return ret;
+}
+
+static int sys_set_int(char *fname, int val)
+{
+       char buf[BUFF_MAX];
+       int ret = 0;
+
+       snprintf(buf, sizeof(buf), "%d", val);
+
+       if (sys_write_buf(fname, buf) != 0)
+               ret = -EIO;
+
+       return ret;
+}
+
+/*
+ * Get/Set touch_boost_off state
+ */
+int get_cpufreq_touch_boost_off(int *touch_boost_off)
+{
+       return sys_get_int(TOUCH_BOOST_OFF, touch_boost_off);
+}
+
+int set_cpufreq_touch_boost_off(int touch_boost_off)
+{
+       return sys_set_int(TOUCH_BOOST_OFF, touch_boost_off);
+}
diff --git a/src/touch/touch-plugin.h b/src/touch/touch-plugin.h
new file mode 100644 (file)
index 0000000..b8e17ad
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Touch - Support plugin feature for Touch
+ *
+ * Copyright (c) 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 __TOUCH_PLUGIN__
+#define __TOUCH_PLUGIN__
+
+int get_cpufreq_touch_boost_off(int *);
+int set_cpufreq_touch_boost_off(int);
+
+#endif /* __TOUCH_PLUGIN__ */
diff --git a/src/touch/touch-util.h b/src/touch/touch-util.h
new file mode 100644 (file)
index 0000000..b53af78
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Touch
+ *
+ * Copyright (c) 2011 - 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 __TOUCH_UTIL_H__
+#define __TOUCh_UTIL_H__
+
+#ifdef ENABLE_DEVICED_DLOG
+#define ENABLE_DLOG
+#endif
+
+#define LOG_TAG "TOUCH"
+#include "shared/log-macro.h"
+
+#endif /* __TOUCH_UTIL_H__ */
diff --git a/src/touch/touch.c b/src/touch/touch.c
new file mode 100644 (file)
index 0000000..bb1ab61
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Touch
+ *
+ * Copyright (c) 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.
+ */
+
+#include <glib.h>
+#include <stdio.h>
+#include <vconf.h>
+
+#include "touch.h"
+#include "touch-controller.h"
+
+#include "core/devices.h"
+#include "core/common.h"
+
+void touch_boost_enable(struct touch_control *touch_control,
+               enum touch_type type, enum touch_boost_state state)
+{
+       if (!touch_control)
+               return;
+
+       switch (state) {
+       case TOUCH_BOOST_ON:
+               touch_control->mask |= (1 << type);
+               break;
+       case TOUCH_BOOST_OFF:
+               touch_control->mask &= ~(1 << type);
+               break;
+       default:
+               _E("Unknow touch boost state");
+               return;
+       }
+
+       /*
+        * Touch should update touch_control->cur_state after updating
+        * touch_control->mask variable because Touch need what some module
+        * turn on/off touch boost feature.
+        */
+       if (touch_control->cur_state == state)
+               return;
+
+       switch (type) {
+       case TOUCH_TYPE_VCONF_SIP:
+               set_cpufreq_touch_boost_off(state);
+               break;
+       default:
+               _E("Unknow touch type");
+               return;
+       }
+
+       touch_control->cur_state = state;
+
+       _I("Touch Boost is %s", state == TOUCH_BOOST_ON ? "ON" : "OFF");
+}
+
+/* Define global variable of struct touch_control */
+static struct touch_control touch_control;
+
+static int touch_stop(void)
+{
+       /* Restore touch boost state as ON state */
+       set_cpufreq_touch_boost_off(TOUCH_BOOST_ON);
+
+       touch_controller_stop();
+
+       _I("Stop Touch");
+
+       return 0;
+}
+
+static int touch_start(void)
+{
+       int i;
+
+       /* Touch Boost is default on state */
+       touch_control.cur_state = TOUCH_BOOST_ON;
+
+       for (i = 0; i < TOUCH_TYPE_MAX; i++)
+               touch_control.mask |= (1 << i);
+
+       touch_controller_start();
+
+       _I("Start Touch");
+
+       return 0;
+}
+
+/*
+ * touch_init - Initialize Touch module
+ */
+static void touch_init(void *data)
+{
+       touch_controller_init(&touch_control);
+}
+
+/*
+ * touch_exit - Exit Touch module
+ */
+static void touch_exit(void *data)
+{
+       touch_controller_exit();
+}
+
+static const struct device_ops touch_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "touch",
+       .init     = touch_init,
+       .exit     = touch_exit,
+       .start    = touch_start,
+       .stop     = touch_stop,
+};
+
+DEVICE_OPS_REGISTER(&touch_device_ops)
diff --git a/src/touch/touch.h b/src/touch/touch.h
new file mode 100644 (file)
index 0000000..e7ab2e6
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Touch
+ *
+ * Copyright (c) 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 __TOUCH__
+#define __TOUCH__
+
+#include <Ecore.h>
+#include <vconf.h>
+#include "touch-util.h"
+
+/* Define touch type */
+enum touch_type {
+       TOUCH_TYPE_VCONF_SIP = 0,
+       TOUCH_TYPE_MAX,
+};
+
+/* Define touch boost state */
+enum touch_boost_state {
+       TOUCH_BOOST_ON = 0,
+       TOUCH_BOOST_OFF = 1,
+};
+
+/*
+ * struct touch_control_block
+ */
+struct touch_control {
+       unsigned int mask;
+       enum touch_boost_state cur_state;
+};
+
+void touch_boost_enable(struct touch_control *,
+               enum touch_type, enum touch_boost_state);
+#endif /* __TOUCH__ */
diff --git a/src/usb/configurations/conf-supported.xml b/src/usb/configurations/conf-supported.xml
new file mode 100644 (file)
index 0000000..306d75e
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<supported>
+       <mode value="0"/>
+       <mode value="1"/>
+       <mode value="2"/>
+       <mode value="3"/>
+       <mode value="4"/>
+       <mode value="5"/>
+       <mode value="6"/>
+       <mode value="8"/>
+</supported>
diff --git a/src/usb/configurations/usb-configurations.xml b/src/usb/configurations/usb-configurations.xml
new file mode 100644 (file)
index 0000000..8f71d22
--- /dev/null
@@ -0,0 +1,328 @@
+<?xml version="1.0" encoding="utf-8"?>
+<usb-config>
+       <config-nodes>
+
+               <driver          value="/sys/class/usb_mode/version"/>
+
+               <usb-drv ver="1.1&#10;">
+                       <disable     value="/sys/class/usb_mode/usb0/enable"/>
+                       <idVendor    value="/sys/class/usb_mode/usb0/idVendor"/>
+                       <idProduct   value="/sys/class/usb_mode/usb0/idProduct"/>
+                       <funcs_fconf value="/sys/class/usb_mode/usb0/funcs_fconf"/>
+                       <funcs_sconf value="/sys/class/usb_mode/usb0/funcs_sconf"/>
+                       <devClass    value="/sys/class/usb_mode/usb0/bDeviceClass"/>
+                       <devSubClass value="/sys/class/usb_mode/usb0/bDeviceSubClass"/>
+                       <devProtocol value="/sys/class/usb_mode/usb0/bDeviceProtocol"/>
+                       <wceis       value="/sys/class/usb_mode/usb0/f_rndis/wceis"/>
+                       <diagClients value="/sys/class/usb_mode/usb0/f_diag/clients"/>
+                       <iProduct    value="/sys/class/usb_mode/usb0/iProduct"/>
+                       <enable      value="/sys/class/usb_mode/usb0/enable"/>
+               </usb-drv>
+
+               <usb-drv ver="1.0&#10;">
+                       <disable     value="/sys/class/usb_mode/usb0/enable"/>
+                       <idVendor    value="/sys/class/usb_mode/usb0/idVendor"/>
+                       <idProduct   value="/sys/class/usb_mode/usb0/idProduct"/>
+                       <functions   value="/sys/class/usb_mode/usb0/functions"/>
+                       <devClass    value="/sys/class/usb_mode/usb0/bDeviceClass"/>
+                       <devSubClass value="/sys/class/usb_mode/usb0/bDeviceSubClass"/>
+                       <devProtocol value="/sys/class/usb_mode/usb0/bDeviceProtocol"/>
+                       <wceis       value="/sys/class/usb_mode/usb0/f_rndis/wceis"/>
+                       <diagClients value="/sys/class/usb_mode/usb0/f_diag/clients"/>
+                       <enable      value="/sys/class/usb_mode/usb0/enable"/>
+               </usb-drv>
+
+       </config-nodes>
+
+       <usb-operations>
+               <action value="set">
+                       <!-- none -->
+                       <mode value="0">
+                       </mode>
+                       <!-- mtp -->
+                       <mode value="1">
+                               <dr-start         value="/usr/bin/start_dr.sh"/>
+                               <mtp-start        value="/usr/bin/mtp-responder"    background="true"/>
+                       </mode>
+                       <!-- mtp,sdb -->
+                       <mode value="2">
+                               <dr-start         value="/usr/bin/start_dr.sh"/>
+                               <mtp-start        value="/usr/bin/mtp-responder"    background="true"/>
+                               <sdbd-start       value="/usr/bin/systemctl start sdbd.service"/>
+                       </mode>
+                       <!-- mtp,sdb,diag -->
+                       <mode value="3">
+                               <dr-start         value="/usr/bin/start_dr.sh"/>
+                               <mtp-start        value="/usr/bin/mtp-responder"    background="true"/>
+                               <sdbd-start       value="/usr/bin/systemctl start sdbd.service"/>
+                       </mode>
+                       <!-- rndis for tethering -->
+                       <mode value="4">
+                               <ip-ethernet-set  value="/sbin/ifconfig usb0 192.168.129.3 up"/>
+                               <network-id       value="/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0"/>
+                       </mode>
+                       <!-- rndis -->
+                       <mode value="5">
+                               <ip-tethering-set value="/sbin/ifconfig usb0 192.168.129.3 up"/>
+                               <network-id       value="/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0"/>
+                               <sshd-start       value="/usr/bin/systemctl start sshd.service"/>
+                       </mode>
+                       <!-- rndis,sdb -->
+                       <mode value="6">
+                               <ip-ethernet-set  value="/sbin/ifconfig usb0 192.168.129.3 up"/>
+                               <network-id       value="/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0"/>
+                               <sshd-start       value="/usr/bin/systemctl start sshd.service"/>
+                               <sdbd-start       value="/usr/bin/systemctl start sdbd.service"/>
+                       </mode>
+                       <!-- rndis,diag -->
+                       <mode value="8">
+                               <ip-tethering-set value="/sbin/ifconfig usb0 192.168.129.3 up"/>
+                               <network-id       value="/sbin/route add -net 192.168.129.0 netmask 255.255.255.0 dev usb0"/>
+                               <sshd-start       value="/usr/bin/systemctl start sshd.service"/>
+                       </mode>
+
+               </action>
+
+               <action value="unset">
+                       <!-- none -->
+                       <mode value="0">
+                       </mode>
+                       <!-- mtp -->
+                       <mode value="1">
+                       </mode>
+                       <!-- mtp,sdb -->
+                       <mode value="2">
+                               <sdbd-stop        value="/usr/bin/systemctl stop sdbd.service"/>
+                       </mode>
+                       <!-- mtp,sdb,diag -->
+                       <mode value="3">
+                               <sdbd-stop        value="/usr/bin/systemctl stop sdbd.service"/>
+                       </mode>
+                       <!-- rndis for tethering -->
+                       <mode value="4">
+                               <ip-unset         value="/sbin/ifconfig usb0 down"/>
+                       </mode>
+                       <!-- rndis -->
+                       <mode value="5">
+                               <sshd-stop        value="/usr/bin/systemctl stop sshd.service"/>
+                               <ip-unset         value="/sbin/ifconfig usb0 down"/>
+                       </mode>
+                       <!-- rndis,sdb -->
+                       <mode value="6">
+                               <sshd-stop        value="/usr/bin/systemctl stop sshd.service"/>
+                               <ip-unset         value="/sbin/ifconfig usb0 down"/>
+                               <sdbd-stop        value="/usr/bin/systemctl stop sdbd.service"/>
+                       </mode>
+                       <!-- rndisi,diag -->
+                       <mode value="8">
+                               <sshd-stop        value="/usr/bin/systemctl stop sshd.service"/>
+                               <ip-unset         value="/sbin/ifconfig usb0 down"/>
+                       </mode>
+
+               </action>
+       </usb-operations>
+
+       <usb-configurations>
+               <usb-drv ver="1.1&#10;">
+                       <!-- none -->
+                       <mode value="0">
+                               <disable     value="0"/>
+                       </mode>
+                       <!-- mtp -->
+                       <mode value="1">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6860"/>
+                               <funcs_fconf value="mtp"/>
+                               <funcs_sconf value="mtp,acm"/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+                       <!-- mtp,sdb -->
+                       <mode value="2">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6860"/>
+                               <funcs_fconf value="mtp"/>
+                               <funcs_sconf value="mtp,acm,sdb"/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+                       <!-- mtp,sdb,diag -->
+                       <mode value="3">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6860"/>
+                               <funcs_fconf value="mtp"/>
+                               <funcs_sconf value="mtp,acm,sdb,diag"/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <diagClients value="diag"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+                       <!-- rndis for tethering -->
+                       <mode value="4">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6863"/>
+                               <funcs_fconf value="rndis"/>
+                               <funcs_sconf value=" "/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <wceis       value="1"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+                       <!-- rndis -->
+                       <mode value="5">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6863"/>
+                               <funcs_fconf value="rndis"/>
+                               <funcs_sconf value=" "/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <wceis       value="1"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+                       <!-- rndis,sdb -->
+                       <mode value="6">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6864"/>
+                               <funcs_fconf value="rndis,sdb"/>
+                               <funcs_sconf value=" "/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+                       <!-- rndis,diag -->
+                       <mode value="8">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6864"/>
+                               <funcs_fconf value="rndis,diag"/>
+                               <funcs_sconf value=" "/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <diagClients value="diag"/>
+                               <wceis       value="0"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+
+               </usb-drv>
+
+               <usb-drv ver="1.0&#10;">
+                       <!-- none -->
+                       <mode value="0">
+                               <disable     value="0"/>
+                       </mode>
+                       <!-- mtp -->
+                       <mode value="1">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6860"/>
+                               <functions   value="mtp,acm"/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+                       <!-- mtp,sdb -->
+                       <mode value="2">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6860"/>
+                               <functions   value="mtp,acm,sdb"/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+                       <!-- mtp,sdb,diag -->
+                       <mode value="3">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6860"/>
+                               <functions   value="mtp,acm,sdb,diag"/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <diagClients value="diag"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+                       <!-- rndis for tethering -->
+                       <mode value="4">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6863"/>
+                               <functions   value="rndis"/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <wceis       value="1"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+                       <!-- rndis -->
+                       <mode value="5">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6863"/>
+                               <functions   value="rndis"/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <wceis       value="1"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+                       <!-- rndis,sdb -->
+                       <mode value="6">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6864"/>
+                               <functions   value="rndis,sdb"/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+                       <!-- rndisi,diag -->
+                       <mode value="8">
+                               <disable     value="0"/>
+                               <idVendor    value="04e8"/>
+                               <idProduct   value="6864"/>
+                               <functions   value="rndis,diag"/>
+                               <devClass    value="239"/>
+                               <devSubClass value="2"/>
+                               <devProtocol value="1"/>
+                               <diagClients value="diag"/>
+                               <wceis       value="0"/>
+                               <iProduct    value="TIZEN"/>
+                               <enable      value="1"/>
+                       </mode>
+
+               </usb-drv>
+
+       </usb-configurations>
+</usb-config>
diff --git a/src/usb/usb-client-control.c b/src/usb/usb-client-control.c
new file mode 100755 (executable)
index 0000000..2c4d36d
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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 <vconf.h>
+#include <stdbool.h>
+#include "usb-client.h"
+#include "core/device-notifier.h"
+
+#define VCONFKEY_USB_CONTROL "db/private/usb/usb_control"
+
+static int usb_control = DEVICE_OPS_STATUS_START;
+
+int control_start(void)
+{
+       if (usb_control == DEVICE_OPS_STATUS_START)
+               return 0;
+
+       usb_control = DEVICE_OPS_STATUS_START;
+       if (vconf_set_int(VCONFKEY_USB_CONTROL, usb_control) != 0)
+               _E("Failed to set vconf");
+
+       if (check_current_usb_state() > 0)
+               act_usb_connected();
+
+       return 0;
+}
+
+int control_stop(void)
+{
+       int cur_mode;
+       if (usb_control == DEVICE_OPS_STATUS_STOP)
+               return 0;
+
+       usb_control = DEVICE_OPS_STATUS_STOP;
+       if (vconf_set_int(VCONFKEY_USB_CONTROL, usb_control) != 0)
+               _E("Failed to set vconf");
+
+       cur_mode = get_current_usb_mode();
+       if (cur_mode <= SET_USB_NONE) {
+               _E("Current usb mode is already none");
+               return 0;
+       }
+
+       unset_client_mode(cur_mode, false);
+
+       launch_syspopup(USB_RESTRICT);
+
+       return 0;
+}
+
+int control_status(void)
+{
+       return usb_control;
+}
+
+static void check_prev_control_status(void)
+{
+       if (vconf_get_int(VCONFKEY_USB_CONTROL, &usb_control) != 0)
+               usb_control = DEVICE_OPS_STATUS_START;
+}
+
+static int usb_client_booting_done(void *data)
+{
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usb_client_booting_done);
+       check_prev_control_status();
+
+       usbclient_init_booting_done();
+
+       if (check_current_usb_state() > 0)
+               act_usb_connected();
+
+       return 0;
+}
+
+void wait_until_booting_done(void)
+{
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usb_client_booting_done);
+       usb_control = DEVICE_OPS_STATUS_STOP;
+}
diff --git a/src/usb/usb-client-dbus.c b/src/usb/usb-client-dbus.c
new file mode 100755 (executable)
index 0000000..4aa0a95
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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 <vconf.h>
+#include "usb-client.h"
+#include "core/edbus-handler.h"
+
+#define CHANGE_USB_MODE "ChangeUsbMode"
+
+static void change_usb_client_mode(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       int mode, debug;
+
+       if (dbus_message_is_signal(msg, DEVICED_INTERFACE_USB, CHANGE_USB_MODE) == 0) {
+               _E("The signal is not for changing usb mode");
+               return;
+       }
+
+       dbus_error_init(&err);
+
+       if (dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &mode, DBUS_TYPE_INVALID) == 0) {
+               _E("FAIL: dbus_message_get_args");
+               goto out;
+       }
+
+       switch (mode){
+       case SET_USB_DEFAULT:
+       case SET_USB_RNDIS:
+       case SET_USB_RNDIS_DIAG:
+               debug = 0;
+               break;
+       case SET_USB_SDB:
+       case SET_USB_SDB_DIAG:
+       case SET_USB_RNDIS_SDB:
+               debug = 1;
+               break;
+       default:
+               _E("(%d) is unknown usb mode", mode);
+               goto out;
+       }
+
+       if (vconf_set_int(VCONFKEY_USB_SEL_MODE, mode) != 0)
+               _E("Failed to set usb mode (%d)", mode);
+
+       if (vconf_set_bool(VCONFKEY_SETAPPL_USB_DEBUG_MODE_BOOL, debug) != 0)
+               _E("Failed to set usb debug toggle (%d)", debug);
+
+out:
+       dbus_error_free(&err);
+       return;
+}
+
+
+int register_usb_client_change_request(void)
+{
+       return register_edbus_signal_handler(DEVICED_PATH_USB,
+                       DEVICED_INTERFACE_USB,
+                       CHANGE_USB_MODE, change_usb_client_mode);
+}
+
diff --git a/src/usb/usb-client-set.c b/src/usb/usb-client-set.c
new file mode 100755 (executable)
index 0000000..5ed9152
--- /dev/null
@@ -0,0 +1,601 @@
+/*
+ * 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 <vconf.h>
+#include <stdbool.h>
+#include "core/log.h"
+#include "core/devices.h"
+#include "core/launch.h"
+#include "usb-client.h"
+
+#define BUF_MAX 256
+
+#define TICKER_TYPE_DEFAULT "usb-client-default"
+#define TICKER_TYPE_SSH     "usb-client-ssh"
+
+#ifdef TIZEN_ENGINEER_MODE
+const static bool eng_mode = true;
+#else
+const static bool eng_mode = false;
+#endif
+
+struct ticker_data {
+       char *name;
+       int type;
+};
+
+static int debug = 0;
+
+static int write_sysfs(char *path, char *value)
+{
+       FILE *fp;
+       int ret;
+
+       if (!path || !value)
+               return -ENOMEM;
+
+       fp = fopen(path, "w");
+       if (!fp) {
+               _E("FAIL: fopen(%s)", path);
+               return -ENOMEM;
+       }
+
+       ret = fwrite(value, sizeof(char), strlen(value), fp);
+       if (ret < strlen(value)) {
+               _E("FAIL: fwrite(%s)", value);
+               ret = -ENOMEM;
+               goto out;
+       }
+
+out:
+       if (fclose(fp) != 0)
+               _E("FAIL: fclose()");
+       return ret;
+}
+
+static int set_configurations_to_sysfs(dd_list *list)
+{
+       dd_list *l;
+       struct xmlConfiguration *conf;
+       int ret;
+
+       if (!list)
+               return -EINVAL;
+
+       DD_LIST_FOREACH(list, l, conf) {
+               if (!(conf->value))
+                       continue;
+
+               ret = write_sysfs(conf->path, conf->value);
+               if (ret < 0) {
+                       _E("FAIL: write_sysfs(%s, %s)", conf->path, conf->value);
+                       return ret;
+               }
+       }
+       return 0;
+}
+
+static void run_operations_for_usb_mode(dd_list *list)
+{
+       dd_list *l;
+       int ret;
+       struct xmlOperation *oper;
+
+       if (!list)
+               return ;
+
+        DD_LIST_FOREACH(list, l, oper) {
+                ret = launch_app_cmd(oper->oper);
+                _I("operation: %s(%d)", oper->oper, ret);
+        }
+}
+
+void unset_client_mode(int mode, bool change)
+{
+       int ret;
+       dd_list *conf_list;
+       dd_list *oper_list;
+
+       if (!change)
+               update_current_usb_mode(SET_USB_NONE);
+
+       if (update_usb_state(VCONFKEY_SYSMAN_USB_DISCONNECTED) < 0)
+               _E("FAIL: update_usb_state(%d)", VCONFKEY_SYSMAN_USB_DISCONNECTED);
+
+       ret = make_configuration_list(SET_USB_NONE);
+       if (ret == 0) {
+               ret = get_configurations_list(&conf_list);
+               if (ret == 0) {
+                       ret = set_configurations_to_sysfs(conf_list);
+                       if (ret < 0)
+                               _E("FAIL: set_configurations_to_sysfs()");
+               }
+       }
+
+       ret = make_operation_list(mode, USB_CON_UNSET);
+       if (ret == 0) {
+               ret = get_operations_list(&oper_list);
+               if (ret == 0)
+                       run_operations_for_usb_mode(oper_list);
+       }
+
+       release_operations_list();
+}
+
+static void launch_ticker_notification(int cur_mode, int sel_mode)
+{
+       struct ticker_data ticker;
+       const struct device_ops *ticker_ops;
+
+       switch(sel_mode) {
+       case SET_USB_DEFAULT:
+       case SET_USB_SDB:
+       case SET_USB_SDB_DIAG:
+               if (cur_mode == SET_USB_DEFAULT
+                               || cur_mode == SET_USB_SDB
+                               || cur_mode == SET_USB_SDB_DIAG)
+                       return;
+
+               ticker.name = TICKER_TYPE_DEFAULT;
+               ticker.type = 0; /* WITHOUT_QUEUE */
+               break;
+       case SET_USB_RNDIS:
+       case SET_USB_RNDIS_DIAG:
+       case SET_USB_RNDIS_SDB:
+               if (cur_mode == SET_USB_RNDIS
+                               || cur_mode == SET_USB_RNDIS_TETHERING
+                               || cur_mode == SET_USB_RNDIS_DIAG
+                               || cur_mode == SET_USB_RNDIS_SDB)
+                       return;
+
+               ticker.name = TICKER_TYPE_SSH;
+               ticker.type = 0; /* WITHOUT_QUEUE */
+               break;
+       case SET_USB_NONE:
+       case SET_USB_RNDIS_TETHERING:
+       default:
+               return;
+       }
+
+       ticker_ops = find_device("ticker");
+
+       if (get_cradle_status() > 0)
+               return;
+
+       if (ticker_ops && ticker_ops->init)
+               ticker_ops->init(&ticker);
+       else
+               _E("cannot find \"ticker\" ops");
+}
+
+static int get_selected_mode_by_debug_mode(int mode)
+{
+       int ret;
+
+       debug = get_debug_mode();
+
+       switch (mode) {
+       case SET_USB_DEFAULT:
+               if (debug == 1) /* debug on */
+                       mode = SET_USB_SDB;
+               break;
+       case SET_USB_SDB:
+       case SET_USB_SDB_DIAG:
+               if (debug == 0) /* debug off */
+                       mode = SET_USB_DEFAULT;
+               break;
+       default:
+               break;
+       }
+
+       return mode;
+}
+
+static bool get_usb_tethering_state(void)
+{
+       int state;
+       int ret;
+
+       if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &state) == 0
+                       && (state & VCONFKEY_MOBILE_HOTSPOT_MODE_USB)) {
+               _I("USB tethering is on");
+               return true;
+       }
+
+       _I("USB tethering is off");
+       return false;
+}
+
+static bool check_usb_tethering(int sel_mode)
+{
+       bool state;
+
+       state = get_usb_tethering_state();
+
+       if (state == false)
+               return state;
+
+       switch (sel_mode) {
+       case SET_USB_RNDIS_TETHERING:
+       case SET_USB_RNDIS:
+               return false;
+       default:
+               break;
+       }
+
+       if (change_selected_usb_mode(SET_USB_RNDIS_TETHERING) != 0) {
+               _E("Failed to set usb selected mode (%d)", SET_USB_RNDIS_TETHERING);
+               return false;
+       }
+
+       return true;
+}
+
+static int turn_on_debug(void)
+{
+       debug = 1;
+       return vconf_set_bool(VCONFKEY_SETAPPL_USB_DEBUG_MODE_BOOL, debug);
+}
+
+static int check_first_eng_mode(int sel_mode)
+{
+       static bool first = true;
+
+       if (!eng_mode || !first)
+               return sel_mode;
+
+       first = false;
+
+       if (sel_mode == SET_USB_DEFAULT) {
+               sel_mode = SET_USB_SDB;
+               if (turn_on_debug() != 0)
+                       _E("Failed to turn on debug toggle");
+       }
+
+       return sel_mode;
+}
+
+static int decide_selected_mode(int sel_mode, int cur_mode)
+{
+       int mode;
+
+       if (check_usb_tethering(sel_mode))
+               return -ECANCELED;
+
+       mode = check_first_eng_mode(sel_mode);
+
+       mode = get_selected_mode_by_debug_mode(mode);
+
+       if (mode == cur_mode) {
+               _I("Selected usb mode (%d) is same with current usb mode (%d)", mode, cur_mode);
+               return -ECANCELED;
+       }
+
+       _I("Selected mode decided is (%d)", mode);
+
+       return mode;
+}
+
+void change_client_setting(int options)
+{
+       int sel_mode;
+       int cur_mode;
+       bool tethering;
+       int ret;
+       char *action;
+       dd_list *conf_list;
+       dd_list *oper_list;
+
+       if (control_status() == DEVICE_OPS_STATUS_STOP) {
+               launch_syspopup(USB_RESTRICT);
+               return;
+       }
+
+       sel_mode = get_selected_usb_mode();
+       cur_mode = get_current_usb_mode();
+
+       sel_mode = decide_selected_mode(sel_mode, cur_mode);
+       if (sel_mode == -ECANCELED)
+               return;
+       else if (sel_mode <= 0) {
+               _E("Failed to get selected mode");
+               return;
+       }
+
+       if (options & SET_CONFIGURATION) {
+               if (cur_mode != SET_USB_NONE) {
+                       unset_client_mode(cur_mode, true);
+               }
+
+               ret = make_configuration_list(sel_mode);
+               if (ret < 0) {
+                       _E("FAIL: make_configuration_list(%d)", sel_mode);
+                       goto out_configuration;
+               }
+
+               ret = get_configurations_list(&conf_list);
+               if (ret < 0) {
+                       _E("failed to get configuration list");
+                       goto out_configuration;
+               }
+
+               ret = set_configurations_to_sysfs(conf_list);
+               if (ret < 0) {
+                       _E("FAIL: set_configurations_to_sysfs()");
+                       goto out_configuration;
+               }
+       }
+
+       if (options & SET_OPERATION) {
+               ret = make_operation_list(sel_mode, USB_CON_SET);
+               if (ret < 0) {
+                       _E("FAIL: make_operation_list()");
+                       goto out_operation;
+               }
+
+               ret = get_operations_list(&oper_list);
+               if (ret < 0) {
+                       _E("failed to get operation list");
+                       goto out_operation;
+               }
+
+               if (update_usb_state(VCONFKEY_SYSMAN_USB_AVAILABLE) < 0)
+                       _E("FAIL: update_usb_state(%d)", VCONFKEY_SYSMAN_USB_AVAILABLE);
+
+               update_current_usb_mode(sel_mode);
+
+               run_operations_for_usb_mode(oper_list);
+       }
+
+       if (options & SET_NOTIFICATION) {
+               launch_ticker_notification(cur_mode, sel_mode);
+       }
+
+       ret = 0;
+
+out_operation:
+       release_operations_list();
+
+out_configuration:
+       if (make_configuration_list(SET_USB_NONE) < 0)
+               _E("Release configurations info error");
+
+       if (ret < 0)
+               launch_syspopup(USB_ERROR);
+
+       return;
+}
+
+void client_mode_changed(keynode_t* key, void *data)
+{
+       int ret;
+
+       if (get_wait_configured())
+               return;
+
+       change_client_setting(SET_CONFIGURATION | SET_OPERATION | SET_NOTIFICATION);
+}
+
+#if 0
+void client_mode_changed(keynode_t* key, void *data)
+{
+       int sel_mode;
+       int cur_mode;
+       int ret;
+       char *action;
+       dd_list *conf_list;
+       dd_list *oper_list;
+
+       if (control_status() == DEVICE_OPS_STATUS_STOP) {
+               launch_syspopup(USB_RESTRICT);
+               return;
+       }
+
+       sel_mode = get_selected_usb_mode();
+       if (sel_mode <= SET_USB_NONE) {
+               _E("Getting selected usb mode error(%d)", sel_mode);
+               return;
+       }
+
+       if (check_usb_tethering()) {
+               _I("Turning on the usb tethering");
+               return;
+       }
+
+       ret = check_debug_mode(sel_mode);
+       if (ret != 0)
+               return;
+
+       sel_mode = check_first_eng_mode(sel_mode);
+
+       cur_mode = get_current_usb_mode();
+       if (cur_mode < SET_USB_NONE) {
+               _E("Getting current usb mode error(%d)", cur_mode);
+               return ;
+       }
+
+       if (cur_mode == sel_mode) {
+               _I("Current usb mode(%d) is same with selected usb mode(%d)", cur_mode, sel_mode);
+               return ;
+       }
+
+       if (cur_mode != SET_USB_NONE) {
+               unset_client_mode(cur_mode);
+       }
+
+       ret = make_configuration_list(sel_mode);
+       if (ret < 0) {
+               _E("FAIL: make_configuration_list(%d)", sel_mode);
+               goto out;
+       }
+
+       ret = make_operation_list(sel_mode, USB_CON_SET);
+       if (ret < 0) {
+               _E("FAIL: make_operation_list()");
+               goto out;
+       }
+
+       ret = get_configurations_list(&conf_list);
+       if (ret < 0) {
+               _E("failed to get configuration list");
+               goto out;
+       }
+
+       ret = get_operations_list(&oper_list);
+       if (ret < 0) {
+               _E("failed to get operation list");
+               goto out;
+       }
+
+       ret = set_configurations_to_sysfs(conf_list);
+       if (ret < 0) {
+               _E("FAIL: set_configurations_to_sysfs()");
+               goto out;
+       }
+
+       update_current_usb_mode(sel_mode);
+
+       run_operations_for_usb_mode(oper_list);
+
+       launch_ticker_notification(cur_mode, sel_mode);
+
+       ret = 0;
+
+out:
+       if (ret < 0)
+               launch_syspopup(USB_ERROR);
+
+       release_operations_list();
+       ret = make_configuration_list(SET_USB_NONE);
+       if (ret < 0)
+               _E("release configurations info error");
+       return;
+}
+#endif
+
+void debug_mode_changed(keynode_t* key, void *data)
+{
+       int new_debug;
+       int cur_mode;
+       int sel_mode;
+
+       if (control_status() == DEVICE_OPS_STATUS_STOP)
+               return;
+
+       new_debug = get_debug_mode();
+       _I("old debug(%d), new debug(%d)", debug, new_debug);
+       if (debug == new_debug)
+               return;
+
+       cur_mode = get_current_usb_mode();
+       _I("cur_mode(%d)", cur_mode);
+
+       switch (cur_mode) {
+       case SET_USB_DEFAULT:
+       case SET_USB_SDB:
+       case SET_USB_SDB_DIAG:
+               if (new_debug == 0)
+                       sel_mode = SET_USB_DEFAULT;
+               else
+                       sel_mode = SET_USB_SDB;
+               break;
+       default:
+               return ;
+       }
+
+       if (change_selected_usb_mode(sel_mode) != 0)
+               _E("FAIL: change_selected_usb_mode(%d)", sel_mode);
+
+       return;
+}
+
+/* USB tethering */
+static int turn_on_usb_tethering(void)
+{
+       int cur_mode;
+       int sel_mode;
+       int ret;
+
+       cur_mode = get_current_usb_mode();
+       sel_mode = get_selected_usb_mode();
+
+       switch (cur_mode) {
+       case SET_USB_RNDIS:
+       case SET_USB_RNDIS_TETHERING:
+               return 0;
+       default:
+               break;
+       }
+
+       switch (sel_mode) {
+       case SET_USB_RNDIS:
+       case SET_USB_RNDIS_TETHERING:
+               break;
+       default:
+               sel_mode = SET_USB_RNDIS_TETHERING;
+               break;
+       }
+
+       ret = change_selected_usb_mode(sel_mode);
+       if (ret != 0)
+               _E("FAIL: change_selected_usb_mode(%d)", sel_mode);
+
+       return ret;
+}
+
+static int turn_off_usb_tethering(void)
+{
+       int cur_mode;
+       int sel_mode;
+       int ret;
+
+       cur_mode = get_current_usb_mode();
+
+       switch(cur_mode) {
+       case SET_USB_RNDIS:
+       case SET_USB_RNDIS_TETHERING:
+               sel_mode = get_default_mode();
+               ret = change_selected_usb_mode(sel_mode);
+               if (ret != 0)
+                       _E("FAIL: change_selected_usb_mode(%d)", sel_mode);
+               return ret;
+
+       default:
+               return 0;
+       }
+}
+
+void tethering_status_changed(keynode_t* key, void *data)
+{
+       bool usb_tethering;
+       int ret;
+
+       if (control_status() == DEVICE_OPS_STATUS_STOP)
+               return;
+
+       usb_tethering = get_usb_tethering_state();
+       if (usb_tethering)
+               ret = turn_on_usb_tethering();
+       else
+               ret = turn_off_usb_tethering();
+
+       if (ret != 0)
+               _E("Failed to change tethering mode");
+
+       return;
+}
diff --git a/src/usb/usb-client-xml.c b/src/usb/usb-client-xml.c
new file mode 100755 (executable)
index 0000000..49d27a7
--- /dev/null
@@ -0,0 +1,919 @@
+/*
+ * 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 <vconf.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <libxml/parser.h>
+#include "core/log.h"
+#include "core/list.h"
+#include "usb-client.h"
+
+#define BUF_MAX 256
+
+#define DEFAULT_IPRODUCT_NAME "TIZEN"
+
+#define CONF_PATH                "/usr/share/deviced/usb-configurations"
+#define SUPPORTED_CONF_PATH      CONF_PATH"/conf-supported.xml"
+#define USB_CONFIGURATIONS_PATH  CONF_PATH"/usb-configurations.xml"
+
+#define USB_CON_SET             "set"
+#define USB_CON_UNSET           "unset"
+
+#define NODE_NAME_TEXT          "text"
+#define NODE_NAME_COMMENT       "comment"
+#define NODE_NAME_CONFIG_NODES  "config-nodes"
+#define NODE_NAME_CONFIG_files  "config-files"
+#define NODE_NAME_USB_CONFIG    "usb-config"
+#define NODE_NAME_CONF_FILE     "conf-file"
+#define NODE_NAME_USB_CONFS     "usb-configurations"
+#define NODE_NAME_USB_OPERS     "usb-operations"
+#define NODE_NAME_DRIVER        "driver"
+#define NODE_NAME_USB_DRV       "usb-drv"
+#define NODE_NAME_MODE          "mode"
+#define NODE_NAME_ACTION        "action"
+#define NODE_NAME_IPRODUCT      "iProduct"
+#define ATTR_VALUE              "value"
+#define ATTR_VERSION            "ver"
+#define ATTR_BACKGROUND         "background"
+
+static dd_list *supported_list;  /* Supported Configurations */
+static dd_list *oper_list;       /* Operations for USB mode */
+static dd_list *conf_list;       /* Configurations for usb mode */
+static char *driver;             /* usb driver version (ex. 1.0, 1.1, none, ... ) */
+
+int get_operations_list(dd_list **list)
+{
+       if (!list)
+               return -EINVAL;
+
+       *list = oper_list;
+       return 0;
+}
+
+int get_configurations_list(dd_list **list)
+{
+       if (!list)
+               return -EINVAL;
+
+       *list = conf_list;
+       return 0;
+}
+
+#ifdef USB_DEBUG
+static void show_supported_confs_list(void)
+{
+       int i;
+       dd_list *l;
+       struct xmlSupported *sp;
+       void *mode;
+
+       if (!supported_list) {
+               _D("Supported Confs list is empty");
+               return;
+       }
+
+       _D("********************************");
+       _D("** Supported Confs list");
+       _D("********************************");
+
+       DD_LIST_FOREACH(supported_list, l, sp) {
+               _D("** Mode      : %d", sp->mode);
+               _D("********************************");
+       }
+}
+
+static void show_operation_list(void)
+{
+       int i;
+       dd_list *l;
+       struct xmlOperation *oper;
+
+       _D("********************************");
+       _D("** Operation list");
+       _D("********************************");
+       if (!oper_list) {
+               _D("Operation list is empty");
+               _D("********************************");
+               return;
+       }
+
+       i = 0;
+       DD_LIST_FOREACH(oper_list, l, oper) {
+               _D("** Number    : %d", i++);
+               _D("** Name      : %s", oper->name);
+               _D("** Operation : %s", oper->oper);
+               _D("** Background: %d", oper->background);
+               _D("********************************");
+       }
+}
+
+static void show_configuration_list(void)
+{
+       int i;
+       dd_list *l;
+       struct xmlConfiguration *conf;
+
+       if (!conf_list) {
+               _D("Configuration list is empty");
+               return;
+       }
+
+       _D("********************************");
+       _D("** Configuration list");
+       _D("********************************");
+
+       i = 0;
+       DD_LIST_FOREACH(conf_list, l, conf) {
+               _D("** Number: %d", i++);
+               _D("** Name  : %s", conf->name);
+               _D("** Path  : %s", conf->path);
+               _D("** Value : %s", conf->value);
+               _D("********************************");
+       }
+}
+#else
+#define show_supported_confs_list() do {} while(0)
+#define show_operation_list() do {} while(0)
+#define show_configuration_list() do {} while(0)
+#endif
+
+static xmlDocPtr xml_open(const char *xml)
+{
+       if (!xml)
+               return NULL;
+
+       return xmlReadFile(xml, NULL, 0);
+}
+
+static void xml_close(xmlDocPtr doc)
+{
+       xmlFreeDoc(doc);
+}
+
+static bool skip_node(xmlNodePtr node)
+{
+       if (!node)
+               return true;
+
+       if (!xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_TEXT))
+               return true;
+       if (!xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_COMMENT))
+               return true;
+
+       return false;
+}
+
+static int get_xml_property(xmlNodePtr node, char *property, char *value, int len)
+{
+       xmlChar *xmlprop;
+
+       xmlprop = xmlGetProp(node, (const xmlChar *)property);
+       if (!xmlprop)
+               return -ENOMEM;
+
+       snprintf(value, len, "%s", (char *)xmlprop);
+       xmlFree(xmlprop);
+
+       return 0;
+}
+
+static bool is_usb_mode_supported(int usb_mode)
+{
+       dd_list *l;
+       struct xmlSupported *sp;
+
+       DD_LIST_FOREACH(supported_list, l, sp) {
+               if (sp->mode == usb_mode)
+                       return true;
+       }
+
+       return false;
+}
+
+static int get_iproduct_name(char *name, int size)
+{
+       if (!name)
+               return -EINVAL;
+
+       /* TODO: Product name should be set using device model
+        * ex) TIZEN_SM-Z9005 */
+
+       snprintf(name, size, "%s", DEFAULT_IPRODUCT_NAME);
+       return 0;
+}
+
+static int get_driver_version(xmlNodePtr root)
+{
+       int ret;
+       xmlNodePtr node;
+       FILE *fp;
+       char buf[BUF_MAX];
+       char path[BUF_MAX];
+
+       if (!root)
+               return -EINVAL;
+
+       for (node = root->children ; node ; node = node->next) {
+               if (skip_node(node))
+                       continue;
+
+               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_DRIVER))
+                       continue;
+
+               ret = get_xml_property(node, ATTR_VALUE, path, sizeof(path));
+               if (ret < 0) {
+                       _E("Failed to get property(%d)", ret);
+                       return ret;
+               }
+
+               if (access(path, F_OK) != 0) {
+                       /* TODO: If the path does not exist,
+                        * usb gadgets are not from Galaxy, but from Linux Kernel */
+                       driver = NULL;
+                       return 0;
+               }
+
+               fp = fopen(path, "r");
+               if (!fp) {
+                       _E("fopen() failed(%s)", path);
+                       return -ENOMEM;
+               }
+
+               if (!fgets(buf, sizeof(buf), fp)) {
+                       _E("fgets() failed");
+                       fclose(fp);
+                       return -ENOMEM;
+               }
+
+               fclose(fp);
+
+               driver = strdup(buf);
+               break;
+       }
+       return 0;
+}
+
+/* Getting sysfs nodes to set usb configurations */
+static int add_conf_nodes_to_list(xmlNodePtr root)
+{
+       int ret;
+       xmlNodePtr node;
+       struct xmlConfiguration *conf;
+       char path[BUF_MAX];
+
+       if (!root)
+               return -EINVAL;
+
+       for (node = root->children ; node ; node = node->next) {
+               if (skip_node(node))
+                       continue;
+
+               ret = get_xml_property(node, ATTR_VALUE, path, sizeof(path));
+               if (ret < 0) {
+                       _E("Failed to get property(%d)", ret);
+                       return ret;
+               }
+
+               conf = (struct xmlConfiguration *)malloc(sizeof(struct xmlConfiguration));
+               if (!conf) {
+                       _E("malloc() failed");
+                       return -ENOMEM;
+               }
+
+               conf->name = strdup((const char *)(node->name));
+               conf->path = strdup(path);
+               conf->value = NULL;
+
+               if (!(conf->name) || !(conf->path)) {
+                       _E("strdup() failed");
+                       if (conf->name)
+                               free(conf->name);
+                       if (conf->path)
+                               free(conf->path);
+                       free(conf);
+                       continue;
+               }
+
+               DD_LIST_APPEND(conf_list, conf);
+       }
+
+       return 0;
+}
+
+static int get_configuration_nodes(xmlNodePtr root)
+{
+       int ret;
+       xmlNodePtr node;
+       char ver[BUF_MAX];
+
+       if (!root)
+               return -EINVAL;
+
+       for (node = root->children ; node ; node = node->next) {
+               if (skip_node(node))
+                       continue;
+
+               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_USB_DRV))
+                       continue;
+
+               ret = get_xml_property(node, ATTR_VERSION, ver, sizeof(ver));
+               if (ret < 0) {
+                       _E("Failed to get property(%d)", ret);
+                       return ret;
+               }
+
+               if (strncmp(ver, driver, strlen(ver)))
+                       continue;
+
+               return add_conf_nodes_to_list(node);
+       }
+
+       return -ENOMEM;
+}
+
+int make_empty_configuration_list(void)
+{
+       int ret;
+       xmlDocPtr doc;
+       xmlNodePtr root;
+       xmlNodePtr node;
+
+       doc = xml_open(USB_CONFIGURATIONS_PATH);
+       if (!doc) {
+               _E("fail to open xml file (%s)", USB_CONFIGURATIONS_PATH);
+               return -ENOMEM;
+       }
+
+       root = xmlDocGetRootElement(doc);
+       if (!root) {
+               _E("FAIL: xmlDocGetRootElement()");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       for (node = root->children ; node ; node = node->next) {
+               if (skip_node(node))
+                       continue;
+
+               if (!xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_CONFIG_NODES)) {
+                       ret = get_driver_version(node);
+                       if (ret < 0) {
+                               _E("Failed to get usb driver version");
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+
+                       ret = get_configuration_nodes(node);
+                       if (ret < 0) {
+                               _E("Failed to get conf nodes");
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+
+                       show_configuration_list();
+                       break;
+               }
+       }
+
+       ret = 0;
+
+out:
+       xml_close(doc);
+       return ret;
+}
+
+static int add_configurations_to_list(xmlNodePtr root)
+{
+       int ret;
+       dd_list *l;
+       struct xmlConfiguration *conf;
+       xmlNodePtr node;
+       char buf[BUF_MAX];
+       char value[BUF_MAX];
+
+       if (!root)
+               return -EINVAL;
+
+       DD_LIST_FOREACH(conf_list, l, conf) {
+               if (conf->value) {
+                       free(conf->value);
+                       conf->value = NULL;
+               }
+
+               if (!strncmp(conf->name, NODE_NAME_IPRODUCT, strlen(NODE_NAME_IPRODUCT))) {
+                       ret = get_iproduct_name(buf, sizeof(buf));
+                       if (ret == 0)
+                               conf->value = strdup(buf);
+                       continue;
+               }
+
+               for (node = root->children ; node ; node = node->next) {
+                       if (skip_node(node))
+                               continue;
+
+                       if (xmlStrcmp((const xmlChar *)conf->name, node->name))
+                               continue;
+
+                       ret = get_xml_property(node, ATTR_VALUE, value, sizeof(value));
+                       if (ret < 0) {
+                               _E("Failed to get property(%d)", ret);
+                               return ret;
+                       }
+
+                       conf->value = strdup(value);
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static int get_configurations_by_usb_mode(xmlNodePtr root, int mode)
+{
+       xmlNodePtr node;
+       char cMode[BUF_MAX];
+       int iMode, ret;
+
+       if (!root)
+               return -EINVAL;
+
+       for (node = root->children ; node ; node = node->next) {
+               if (skip_node(node))
+                       continue;
+
+               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_MODE))
+                       continue;
+
+               ret = get_xml_property(node, ATTR_VALUE, cMode, sizeof(cMode));
+               if (ret < 0) {
+                       _E("Failed to get property(%d)", ret);
+                       return ret;
+               }
+
+               iMode = atoi(cMode);
+               if (mode != iMode)
+                       continue;
+
+               return add_configurations_to_list(node);
+       }
+       return -EINVAL;
+}
+
+static int get_configurations_by_version(xmlNodePtr root, int mode)
+{
+       xmlNodePtr node;
+       char ver[BUF_MAX];
+       int ret;
+
+       if (!root)
+               return -EINVAL;
+
+       for (node = root->children ; node ; node = node->next) {
+               if (skip_node(node))
+                       continue;
+
+               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_USB_DRV))
+                       continue;
+
+               ret = get_xml_property(node, ATTR_VERSION, ver, sizeof(ver));
+               if (ret < 0) {
+                       _E("Failed to get property(%d)", ret);
+                       return ret;
+               }
+
+               if (strncmp(ver, driver, strlen(ver)))
+                       continue;
+
+               return get_configurations_by_usb_mode(node, mode);
+       }
+
+       return -EINVAL;
+}
+
+static int get_configurations_info(xmlNodePtr root, int mode)
+{
+       xmlNodePtr node;
+
+       if (!root)
+               return -EINVAL;
+
+       for (node = root->children ; node ; node = node->next) {
+               if (skip_node(node))
+                       continue;
+
+               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_USB_CONFS))
+                       continue;
+
+               return get_configurations_by_version(node, mode);
+       }
+
+       return -EINVAL;
+}
+
+int make_configuration_list(int usb_mode)
+{
+       int ret;
+       xmlDocPtr doc;
+       xmlNodePtr root;
+       xmlNodePtr node;
+
+       if (!is_usb_mode_supported(usb_mode)) {
+               _E("USB mode (%d) is not supported", usb_mode);
+               return -EINVAL;
+       }
+
+       doc = xml_open(USB_CONFIGURATIONS_PATH);
+       if (!doc) {
+               _E("fail to open xml file (%s)", USB_CONFIGURATIONS_PATH);
+               return -ENOMEM;
+       }
+
+       root = xmlDocGetRootElement(doc);
+       if (!root) {
+               _E("FAIL: xmlDocGetRootElement()");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = get_configurations_info(root, usb_mode);
+       if (ret < 0) {
+               _E("Failed to get operations for usb mode(%d)", usb_mode);
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       show_configuration_list();
+       ret = 0;
+
+out:
+       xml_close(doc);
+       return ret;
+}
+
+
+void release_configuration_list(void)
+{
+       dd_list *l;
+       struct xmlConfiguration *conf;
+
+       if (!conf_list)
+               return;
+
+       DD_LIST_FOREACH(conf_list, l, conf) {
+               if (conf->name)
+                       free(conf->name);
+               if (conf->path)
+                       free(conf->path);
+               if (conf->value)
+                       free(conf->value);
+               if (conf)
+                       free(conf);
+       }
+
+       DD_LIST_FREE_LIST(conf_list);
+       conf_list = NULL;
+}
+
+/* Getting configurations supported */
+static int get_supported_confs(xmlNodePtr root)
+{
+       int ret;
+       xmlNodePtr node;
+       char cMode[BUF_MAX];
+       int iMode;
+       struct xmlSupported *sp;
+
+       if (!root)
+               return -EINVAL;
+
+       for (node = root->children ; node ; node = node->next) {
+               if (skip_node(node))
+                       continue;
+
+               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_MODE))
+                       continue;
+
+               ret = get_xml_property(node, ATTR_VALUE, cMode, sizeof(cMode));
+               if (ret < 0) {
+                       _E("Failed to get property(%d)", ret);
+                       return ret;
+               }
+
+               iMode = atoi(cMode);
+
+               sp = (struct xmlSupported *)malloc(sizeof(struct xmlSupported));
+               if (!sp) {
+                       _E("malloc() failed");
+                       return -ENOMEM;
+               }
+
+               sp->mode = iMode;
+
+               DD_LIST_APPEND(supported_list, sp);
+       }
+
+       return 0;
+}
+
+int make_supported_confs_list(void)
+{
+       int ret;
+       xmlDocPtr doc;
+       xmlNodePtr root;
+       xmlNodePtr node;
+
+       doc = xml_open(SUPPORTED_CONF_PATH);
+       if (!doc) {
+               _E("fail to open xml file (%s)", SUPPORTED_CONF_PATH);
+               return -ENOMEM;
+       }
+
+       root = xmlDocGetRootElement(doc);
+       if (!root) {
+               _E("FAIL: xmlDocGetRootElement()");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = get_supported_confs(root);
+       if (ret < 0) {
+               _E("Failed to get supported confs");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       show_supported_confs_list();
+       ret = 0;
+
+out:
+       xml_close(doc);
+       return ret;
+}
+
+void release_supported_confs_list(void)
+{
+       struct xmlSupported *sp;
+       dd_list *l;
+
+       if (!supported_list)
+               return;
+
+       DD_LIST_FOREACH(supported_list, l, sp) {
+               free(sp);
+       }
+
+       DD_LIST_FREE_LIST(supported_list);
+       supported_list = NULL;
+}
+
+/* Getting operations for each usb mode */
+static int get_operations_info(xmlNodePtr node, struct xmlOperation **oper)
+{
+       int ret;
+       char background[BUF_MAX];
+       char operation[BUF_MAX];
+
+       if (!node || !oper)
+               return -EINVAL;
+
+       ret = get_xml_property(node, ATTR_VALUE, operation, sizeof(operation));
+       if (ret < 0) {
+               _E("Failed to get property(%d)", ret);
+               return ret;
+       }
+
+       *oper = (struct xmlOperation *)malloc(sizeof(struct xmlOperation));
+       if (!(*oper)) {
+               _E("malloc() failed");
+               return -ENOMEM;
+       }
+
+       (*oper)->name = strdup((const char *)(node->name));
+       (*oper)->oper = strdup(operation);
+
+       if (!((*oper)->name) || !((*oper)->oper)) {
+               if ((*oper)->name)
+                       free((*oper)->name);
+               if ((*oper)->oper)
+                       free((*oper)->oper);
+               if (*oper) {
+                       free(*oper);
+                       *oper = NULL;
+               }
+               return -ENOMEM;
+       }
+
+       ret = get_xml_property(node, ATTR_BACKGROUND, background, sizeof(background));
+       if (ret < 0) {
+               (*oper)->background = false;
+               return 0;
+       }
+
+       if (strncmp(background, "true", strlen(background)))
+               (*oper)->background = false;
+       else
+               (*oper)->background = true;
+
+       return 0;
+}
+
+static int add_operations_to_list(xmlNodePtr root)
+{
+       int ret;
+       xmlNodePtr node;
+       struct xmlOperation *oper;
+
+       if (!root)
+               return -EINVAL;
+
+       for (node = root->children ; node ; node = node->next) {
+               if (skip_node(node))
+                       continue;
+
+               ret = get_operations_info(node, &oper);
+               if (ret < 0 || !oper) {
+                       _E("Failed to get operations info");
+                       return -ENOMEM;
+               }
+
+               DD_LIST_APPEND(oper_list, oper);
+       }
+
+       return 0;
+}
+
+static int get_operations_by_usb_mode(xmlNodePtr root, int usb_mode)
+{
+       int ret;
+       xmlNodePtr node;
+       char cMode[BUF_MAX];
+       int iMode;
+
+       if (!root)
+               return -EINVAL;
+
+       for (node = root->children ; node ; node = node->next) {
+               if (skip_node(node))
+                       continue;
+
+               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_MODE))
+                       continue;
+
+               ret = get_xml_property(node, ATTR_VALUE, cMode, sizeof(cMode));
+               if (ret < 0) {
+                       _E("Failed to get property(%d)", ret);
+                       return ret;
+               }
+
+               iMode = atoi(cMode);
+
+               if (usb_mode != iMode)
+                       continue;
+
+               ret = add_operations_to_list(node);
+               if (ret < 0) {
+                       _E("Failed to add operations to list ");
+                       return -ENOMEM;
+               }
+               break;
+       }
+
+       return 0;
+}
+
+static int get_operations_by_action(xmlNodePtr root, int usb_mode, char *action)
+{
+       int ret;
+       xmlNodePtr node;
+       char act[BUF_MAX];
+
+       if (!root || !action)
+               return -EINVAL;
+
+       for (node = root->children ; node ; node = node->next) {
+               if (skip_node(node))
+                       continue;
+
+               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_ACTION))
+                       continue;
+
+               ret = get_xml_property(node, ATTR_VALUE, act, sizeof(act));
+               if (ret < 0) {
+                       _E("Failed to get property(%d)", ret);
+                       return ret;
+               }
+
+               if (strncmp(act, action, strlen(act)))
+                       continue;
+
+               ret = get_operations_by_usb_mode(node, usb_mode);
+               if (ret < 0) {
+                       _E("Failed to get operations for usb_mode (%d)", usb_mode);
+                       return -ENOMEM;
+               }
+               break;
+       }
+
+       return 0;
+}
+
+static int get_usb_operations(xmlNodePtr root, int usb_mode, char *action)
+{
+       xmlNodePtr node;
+
+       if (!root || !action)
+               return -EINVAL;
+
+       for (node = root->children ; node ; node = node->next) {
+               if (skip_node(node))
+                       continue;
+
+               if (xmlStrcmp(node->name, (const xmlChar *)NODE_NAME_USB_OPERS))
+                       continue;
+
+               return get_operations_by_action(node, usb_mode, action);
+       }
+
+       return -ENOMEM;
+}
+
+int make_operation_list(int usb_mode, char *action)
+{
+       int ret;
+       xmlDocPtr doc;
+       xmlNodePtr root;
+       xmlNodePtr node;
+       char conf_file_path[BUF_MAX];
+
+       if (!action)
+               return -EINVAL;
+
+       if (!is_usb_mode_supported(usb_mode)) {
+               _E("USB mode (%d) is not supported", usb_mode);
+               return -EINVAL;
+       }
+
+       doc = xml_open(USB_CONFIGURATIONS_PATH);
+       if (!doc) {
+               _E("fail to open xml file (%s)", USB_CONFIGURATIONS_PATH);
+               return -ENOMEM;
+       }
+
+       root = xmlDocGetRootElement(doc);
+       if (!root) {
+               _E("FAIL: xmlDocGetRootElement()");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = get_usb_operations(root, usb_mode, action);
+       if (ret < 0) {
+               _E("Failed to get operations info(%d, %s)", usb_mode, action);
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       show_operation_list();
+       ret = 0;
+
+out:
+       xml_close(doc);
+       return ret;
+}
+
+void release_operations_list(void)
+{
+       dd_list *l;
+       struct xmlOperation *oper;
+
+       if (!oper_list)
+               return;
+
+       DD_LIST_FOREACH(oper_list, l, oper) {
+               if (oper->name)
+                       free(oper->name);
+               if (oper->oper)
+                       free(oper->oper);
+               if (oper)
+                       free(oper);
+       }
+
+       DD_LIST_FREE_LIST(oper_list);
+       oper_list = NULL;
+}
diff --git a/src/usb/usb-client.c b/src/usb/usb-client.c
new file mode 100755 (executable)
index 0000000..5df9f42
--- /dev/null
@@ -0,0 +1,502 @@
+/*
+ * 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 <stdbool.h>
+#include "usb-client.h"
+#include "core/device-handler.h"
+#include "core/edbus-handler.h"
+
+#define USB_POPUP_NAME "usb-syspopup"
+
+#ifndef VCONFKEY_USB_CONFIGURATION_ENABLED
+#define VCONFKEY_USB_CONFIGURATION_ENABLED "memory/private/usb/conf_enabled"
+#endif
+
+struct popup_data {
+       char *name;
+       char *key;
+       char *value;
+};
+
+enum usb_enabled {
+       USB_CONF_DISABLED,
+       USB_CONF_ENABLED,
+};
+
+static bool client_mode = false;
+static char *driver_version = NULL;
+static bool wait_configured = false;
+
+void launch_syspopup(char *str)
+{
+       struct popup_data params;
+       static const struct device_ops *apps = NULL;
+
+       if (apps == NULL) {
+               apps = find_device("apps");
+               if (apps == NULL)
+                       return;
+       }
+
+       params.name = USB_POPUP_NAME;
+       params.key = POPUP_KEY_CONTENT;
+       params.value = str;
+
+       if (apps->init)
+               apps->init(&params);
+}
+
+bool get_wait_configured(void)
+{
+       return wait_configured;
+}
+
+int get_debug_mode(void)
+{
+       int debug;
+       if (vconf_get_bool(VCONFKEY_SETAPPL_USB_DEBUG_MODE_BOOL, &debug) != 0)
+               return 1; /* 0 means debug mode is on */
+
+       return debug;
+}
+
+int get_default_mode(void)
+{
+       if (get_debug_mode() == 0)
+               return SET_USB_DEFAULT;
+
+       return SET_USB_SDB;
+}
+
+int update_usb_state(int state)
+{
+       return vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS, state);
+}
+
+int update_current_usb_mode(int mode)
+{
+       /*************************************************/
+       /* TODO: This legacy vconf key should be removed */
+       /* The legacy vconf key is used by mtp and OSP   */
+       int legacy;
+
+       switch(mode) {
+       case SET_USB_DEFAULT:
+       case SET_USB_SDB:
+       case SET_USB_SDB_DIAG:
+               legacy = SETTING_USB_SAMSUNG_KIES;
+               break;
+       case SET_USB_RNDIS:
+       case SET_USB_RNDIS_DIAG:
+       case SET_USB_RNDIS_SDB:
+               legacy = SETTING_USB_DEBUG_MODE;
+               break;
+       case SET_USB_RNDIS_TETHERING:
+               legacy = SETTING_USB_TETHERING_MODE;
+               break;
+       case SET_USB_NONE:
+       default:
+               legacy = SETTING_USB_NONE_MODE;
+               break;
+       }
+
+       if (vconf_set_int(VCONFKEY_SETAPPL_USB_MODE_INT, legacy) != 0)
+               _E("Failed to set legacy vconf key for current usb mode");
+       /****************************************************/
+
+       return vconf_set_int(VCONFKEY_USB_CUR_MODE, mode);
+}
+
+int check_current_usb_state(void)
+{
+       int ret;
+       int state;
+
+       ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &state);
+       if (ret != 0)
+               return -ENOMEM;
+
+       return state;
+}
+
+int get_current_usb_mode(void)
+{
+       int ret;
+       int mode;
+
+       ret = vconf_get_int(VCONFKEY_USB_CUR_MODE, &mode);
+       if (ret != 0)
+               return -ENOMEM;
+
+       return mode;
+}
+
+int get_selected_usb_mode(void)
+{
+       int ret;
+       int mode;
+
+       ret = vconf_get_int(VCONFKEY_USB_SEL_MODE, &mode);
+       if (ret != 0)
+               return -ENOMEM;
+
+       return mode;
+}
+
+int change_selected_usb_mode(int mode)
+{
+       if (mode <= SET_USB_NONE)
+               return -EINVAL;
+       return vconf_set_int(VCONFKEY_USB_SEL_MODE, mode);
+}
+
+static int notify_vconf_keys(void)
+{
+       int ret;
+
+       ret = vconf_notify_key_changed(
+                       VCONFKEY_USB_SEL_MODE,
+                       client_mode_changed, NULL);
+       if (ret != 0) {
+               _E("FAIL: vconf_notify_key_changed()");
+               return ret;
+       }
+
+       ret = vconf_notify_key_changed(
+                       VCONFKEY_SETAPPL_USB_DEBUG_MODE_BOOL,
+                       debug_mode_changed, NULL);
+       if (ret != 0)
+               _E("FAIL: vconf_notify_key_changed()");
+
+       ret = vconf_notify_key_changed(
+                       VCONFKEY_MOBILE_HOTSPOT_MODE,
+                       tethering_status_changed, NULL);
+       if (ret != 0)
+               _E("FAIL: vconf_notify_key_changed()");
+
+       return 0;
+}
+
+static int ignore_vconf_keys(void)
+{
+       int ret;
+
+       ret = vconf_ignore_key_changed(
+                       VCONFKEY_USB_SEL_MODE,
+                       client_mode_changed);
+       if (ret != 0) {
+               _E("FAIL: vconf_ignore_key_changed()");
+               return ret;
+       }
+
+       ret = vconf_ignore_key_changed(
+                       VCONFKEY_SETAPPL_USB_DEBUG_MODE_BOOL,
+                       debug_mode_changed);
+       if (ret != 0)
+               _E("FAIL: vconf_ignore_key_changed()");
+
+       ret = vconf_ignore_key_changed(
+                       VCONFKEY_MOBILE_HOTSPOT_MODE,
+                       tethering_status_changed);
+       if (ret != 0)
+               _E("FAIL: vconf_ignore_key_changed()");
+
+       return 0;
+}
+
+
+static int register_client_handlers(void)
+{
+       int ret;
+
+       ret = notify_vconf_keys();
+       if (ret < 0)
+               return ret;
+
+       /* TODO: register other handler (ex. dbus, ... ) */
+
+       return 0;
+}
+
+static int unregister_client_handlers(void)
+{
+       int ret;
+
+       ret = ignore_vconf_keys();
+       if (ret < 0)
+               return ret;
+
+       /* TODO: unregister other handler (ex. dbus, ... ) */
+
+       return 0;
+}
+
+static int init_client_values(void)
+{
+       int ret;
+
+       ret = make_empty_configuration_list();
+       if (ret < 0)
+               _E("Failed to get information of usb configurations");
+
+       ret = make_supported_confs_list();
+       if (ret < 0)
+               _E("Failed to get information of usb configuration files");
+
+       return 0;
+}
+
+static void deinit_client_values(void)
+{
+       int sel_mode;
+
+       sel_mode = get_selected_usb_mode();
+       switch (sel_mode) {
+       case SET_USB_RNDIS_TETHERING:
+       case SET_USB_RNDIS_DIAG:
+               if (change_selected_usb_mode(get_default_mode()) != 0)
+                       _E("Failed to set selected usb mode");
+               break;
+       default:
+               break;
+       }
+
+       release_supported_confs_list();
+       release_configuration_list();
+}
+
+static int init_client(void)
+{
+       int ret;
+
+       client_mode = true;
+
+       ret = register_client_handlers();
+       if (ret < 0)
+               return ret;
+
+       ret = init_client_values();
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int deinit_client(void)
+{
+       int ret;
+
+       client_mode = false;
+
+       ret = unregister_client_handlers();
+       if (ret < 0)
+               _E("FAIL: unregister_client_handlers()");
+
+       deinit_client_values();
+
+       return 0;
+}
+
+#ifdef MICRO_DD
+void act_usb_connected(void)
+{
+       wait_configured = false;
+
+       if (vconf_set_int(VCONFKEY_USB_CONFIGURATION_ENABLED, USB_CONF_ENABLED) != 0)
+               _E("Failed to set vconf key (%s)", VCONFKEY_USB_CONFIGURATION_ENABLED);
+
+       if (init_client() < 0)
+               _E("FAIL: init_client()");
+
+       change_client_setting(SET_CONFIGURATION | SET_OPERATION | SET_NOTIFICATION);
+
+       pm_lock_internal(getpid(), LCD_OFF, STAY_CUR_STATE, 0);
+}
+#else
+void act_usb_connected(void)
+{
+       wait_configured = true;
+
+       if (vconf_set_int(VCONFKEY_USB_CONFIGURATION_ENABLED, USB_CONF_ENABLED) != 0)
+               _E("Failed to set vconf key (%s)", VCONFKEY_USB_CONFIGURATION_ENABLED);
+
+       if (init_client() < 0)
+               _E("FAIL: init_client()");
+
+       change_client_setting(SET_CONFIGURATION);
+
+       pm_lock_internal(getpid(), LCD_OFF, STAY_CUR_STATE, 0);
+}
+#endif
+
+static void act_usb_disconnected(void)
+{
+       int cur_mode;
+
+       wait_configured = false;
+
+       if (vconf_set_int(VCONFKEY_USB_CONFIGURATION_ENABLED, USB_CONF_DISABLED) != 0)
+               _E("Failed to set vconf key (%s)", VCONFKEY_USB_CONFIGURATION_ENABLED);
+
+       pm_unlock_internal(getpid(), LCD_OFF, STAY_CUR_STATE);
+
+       cur_mode = get_current_usb_mode();
+       if (cur_mode > SET_USB_NONE)
+               unset_client_mode(cur_mode, false);
+
+       if (deinit_client() < 0)
+               _E("FAIL: deinit_client()");
+
+       if (update_usb_state(VCONFKEY_SYSMAN_USB_DISCONNECTED) < 0)
+               _E("FAIL: update_usb_state(%d)", VCONFKEY_SYSMAN_USB_DISCONNECTED);
+}
+
+static void subsystem_switch_changed (struct udev_device *dev)
+{
+       const char *name = NULL;
+       const char *state = NULL;
+       int ret;
+       int cur_mode;
+
+       name = udev_device_get_property_value(dev, UDEV_PROP_KEY_SWITCH_NAME);
+       if (!name)
+               return;
+
+       if (strncmp(name, UDEV_PROP_VALUE_USB_CABLE, strlen(UDEV_PROP_VALUE_USB_CABLE)))
+               return;
+
+       state = udev_device_get_property_value(dev, UDEV_PROP_KEY_SWITCH_STATE);
+       if (!state)
+               return;
+
+       /* USB cable disconnected */
+       if (!strncmp(state, UDEV_PROP_VALUE_DISCON, strlen(UDEV_PROP_VALUE_DISCON))) {
+               _I("USB cable is disconnected");
+               act_usb_disconnected();
+               return;
+       }
+
+       /* USB cable connected */
+       if (!strncmp(state, UDEV_PROP_VALUE_CON, strlen(UDEV_PROP_VALUE_CON))) {
+               _I("USB cable is connected");
+               act_usb_connected();
+               return;
+       }
+}
+
+static void subsystem_platform_changed (struct udev_device *dev)
+{
+       const char *chgdet = NULL;
+       int state;
+       int ret;
+
+       chgdet = udev_device_get_property_value(dev, UDEV_PROP_KEY_CHGDET);
+       if (!chgdet)
+               return;
+
+       if (strncmp(chgdet, UDEV_PROP_VALUE_USB, strlen(UDEV_PROP_VALUE_USB)))
+               return;
+
+       if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &state) != 0
+                       || (state != 0 && state != 1)) {
+               _E("cannot get the usb cable connection status");
+               state = get_usb_state_direct();
+       }
+
+       /* USB cable disconnected */
+       if (state == 0) {
+               _I("USB cable is disconnected");
+               act_usb_disconnected();
+               return;
+       }
+
+       /* USB cable connected */
+       if (state == 1) {
+               _I("USB cable is connected");
+               act_usb_connected();
+               return;
+       }
+
+       _E("USB state is unknown(%d)", state);
+}
+
+static void subsystem_usbmode_changed (struct udev_device *dev)
+{
+       const char *state = NULL;
+
+       if (!wait_configured)
+               return;
+
+       wait_configured = false;
+
+       state = udev_device_get_property_value(dev, UDEV_PROP_KEY_USB_STATE);
+       if (!state)
+               return ;
+
+       if (strncmp(state, UDEV_PROP_VALUE_CONFIGURED, strlen(state)))
+               return;
+
+       _I("Real USB cable is connected");
+       change_client_setting(SET_OPERATION | SET_NOTIFICATION);
+}
+
+const static struct uevent_handler uhs[] = {
+       { SWITCH_SUBSYSTEM     ,     subsystem_switch_changed     ,    NULL    },
+       { USBMODE_SUBSYSTEM    ,     subsystem_usbmode_changed    ,    NULL    },
+       { PLATFORM_SUBSYSTEM   ,     subsystem_platform_changed   ,    NULL    },
+};
+
+void usbclient_init_booting_done(void)
+{
+       int ret, i;
+
+       for (i = 0 ; i < ARRAY_SIZE(uhs) ; i++) {
+               ret = register_kernel_uevent_control(&uhs[i]);
+               if (ret < 0)
+                       _E("FAIL: reg_uevent_control()");
+       }
+
+       if (register_usb_client_change_request() < 0)
+               _E("Failed to register the request to change usb mode");
+}
+
+static void usbclient_init(void *data)
+{
+       wait_until_booting_done();
+}
+
+static void usbclient_exit(void *data)
+{
+       int i;
+
+       for (i = 0 ; i < ARRAY_SIZE(uhs) ; i++) {
+               unregister_kernel_uevent_control(&uhs[i]);
+       }
+}
+
+static const struct device_ops usbclient_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "usbclient",
+       .init     = usbclient_init,
+       .exit     = usbclient_exit,
+       .start    = control_start,
+       .stop     = control_stop,
+       .status   = control_status,
+};
+
+DEVICE_OPS_REGISTER(&usbclient_device_ops)
diff --git a/src/usb/usb-client.h b/src/usb/usb-client.h
new file mode 100755 (executable)
index 0000000..674afe1
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * 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 __USB_CLIENT_H__
+#define __USB_CLIENT_H__
+
+#include <stdbool.h>
+#include <device-node.h>
+
+#include "core/log.h"
+#include "core/devices.h"
+#include "display/poll.h"
+#include "core/udev.h"
+#include "core/common.h"
+#include "core/list.h"
+#include "apps/apps.h"
+#include "usb-common.h"
+
+/* Switch uevent */
+#define UDEV_PROP_KEY_SWITCH_NAME  "SWITCH_NAME"
+#define UDEV_PROP_VALUE_USB_CABLE  "usb_cable"
+
+#define UDEV_PROP_KEY_SWITCH_STATE "SWITCH_STATE"
+#define UDEV_PROP_VALUE_DISCON     "0"
+#define UDEV_PROP_VALUE_CON        "1"
+
+/* usb_mode uevnet */
+#define USBMODE_SUBSYSTEM          "usb_mode"
+#define UDEV_PROP_KEY_USB_STATE    "USB_STATE"
+#define UDEV_PROP_VALUE_CONFIGURED "CONFIGURED"
+
+/* Platform uevent */
+#define UDEV_PROP_KEY_CHGDET       "CHGDET"
+#define UDEV_PROP_VALUE_USB        "usb"
+
+#define USB_CON_SET    "set"
+#define USB_CON_UNSET  "unset"
+
+#define USB_RESTRICT  "restrict"
+#define USB_ERROR     "error"
+
+//#define USB_DEBUG
+
+enum usbclient_setting_option {
+       SET_CONFIGURATION = 0x0001,
+       SET_OPERATION     = 0x0010,
+       SET_NOTIFICATION  = 0x0100,
+};
+
+struct xmlSupported {
+       int mode;
+};
+
+struct xmlOperation {
+       char *name;
+       char *oper;
+       bool background;
+};
+
+struct xmlConfiguration {
+       char *name;
+       char *path;
+       char *value;
+};
+
+/* XML */
+int make_empty_configuration_list(void);
+int make_configuration_list(int usb_mode);
+void release_configuration_list(void);
+int make_supported_confs_list(void);
+void release_supported_confs_list(void);
+int make_operation_list(int usb_mode, char *action);
+void release_operations_list(void);
+
+int get_operations_list(dd_list **list);
+int get_configurations_list(dd_list **list);
+
+/* vconf callbacks */
+void client_mode_changed(keynode_t* key, void *data);
+void prev_client_mode_changed(keynode_t* key, void *data);
+void debug_mode_changed(keynode_t* key, void *data);
+void tethering_status_changed(keynode_t* key, void *data);
+
+/* Check usb state */
+int get_default_mode(void);
+int check_current_usb_state(void);
+int get_current_usb_mode(void);
+int get_selected_usb_mode(void);
+int get_debug_mode(void);
+int change_selected_usb_mode(int mode);
+int update_current_usb_mode(int mode);
+int update_usb_state(int state);
+
+/* Unset usb mode */
+void unset_client_mode(int mode, bool change);
+
+/* USB control */
+int control_start(void);
+int control_stop(void);
+int control_status(void);
+void wait_until_booting_done(void);
+void usbclient_init_booting_done(void);
+void act_usb_connected(void);
+
+/* USB syspopup */
+void launch_syspopup(char *str);
+
+/* Change usb mode */
+void change_client_setting(int options);
+bool get_wait_configured(void);
+
+#endif /* __USB_CLIENT_H__ */
diff --git a/src/usb/usb-common.c b/src/usb/usb-common.c
new file mode 100755 (executable)
index 0000000..fd9d241
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 "usb-common.h"
+
+int get_cradle_status(void)
+{
+       int cradle;
+
+       /* If cradle == 0, cradle is not connected.
+        * And if cradle > 0, cradle is connected. */
+       if (vconf_get_int(VCONFKEY_SYSMAN_CRADLE_STATUS, &cradle) != 0)
+               return 0;
+
+       return cradle;
+}
diff --git a/src/usb/usb-common.h b/src/usb/usb-common.h
new file mode 100755 (executable)
index 0000000..c411632
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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 __USB_COMMON_H__
+#define __USB_COMMON_H__
+
+#include <vconf.h>
+
+int get_cradle_status(void);
+
+#endif /* __USB_COMMON_H__ */
diff --git a/src/usb/usb-handler.c b/src/usb/usb-handler.c
new file mode 100755 (executable)
index 0000000..2c913aa
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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 <vconf.h>
+#include <device-node.h>
+
+#include "core/log.h"
+#include "core/launch.h"
+#include "core/data.h"
+#include "core/devices.h"
+#include "core/edbus-handler.h"
+#include "display/poll.h"
+#include "core/common.h"
+
+#define USBCON_EXEC_PATH       PREFIX"/bin/usb-server"
+#define RETRY                  3
+
+#define SIGNAL_USB_CONTROL "UsbControl"
+
+static int usb_control = DEVICE_OPS_STATUS_START;
+
+static void usb_init(void *data)
+{
+       int val, i = 0, pid;
+
+       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_internal(getpid(), LCD_OFF, STAY_CUR_STATE, 0) == -1) {
+                               i++;
+                               sleep(1);
+                       }
+                       pid = launch_if_noexist(USBCON_EXEC_PATH, NULL);
+                       if (pid < 0) {
+                               _E("usb appl launching failed\n");
+                               return;
+                       }
+               }
+               else if (val==0)
+                       vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS,VCONFKEY_SYSMAN_USB_DISCONNECTED);
+       }
+}
+
+static int usb_set_control(int control)
+{
+       char buf[2];
+       char *arr[1];
+
+       if (usb_control == control)
+               return 0;
+
+       usb_control = control;
+       _D("USB control: %d", usb_control);
+
+       snprintf(buf, sizeof(buf), "%d", usb_control);
+       arr[0] = buf;
+
+       broadcast_edbus_signal(DEVICED_PATH_USB_CONTROL,
+                       DEVICED_INTERFACE_USB_CONTROL,
+                       SIGNAL_USB_CONTROL, "i", arr);
+
+       return 0;
+}
+
+static int usb_start(void)
+{
+       return usb_set_control(DEVICE_OPS_STATUS_START);
+}
+
+static int usb_stop(void)
+{
+       return usb_set_control(DEVICE_OPS_STATUS_STOP);
+}
+
+static int usb_status(void)
+{
+       return usb_control;
+}
+
+static const struct device_ops usb_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "usb",
+       .init     = usb_init,
+       .start    = usb_start,
+       .stop     = usb_stop,
+       .status   = usb_status,
+};
+
+DEVICE_OPS_REGISTER(&usb_device_ops)
diff --git a/src/usb/usb-host-camera.c b/src/usb/usb-host-camera.c
new file mode 100755 (executable)
index 0000000..6a28953
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * 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 "usb-host.h"
+#include "core/device-notifier.h"
+
+#define UDEV_PROP_GPHOTO2_DRIVER   "GPHOTO2_DRIVER"
+#define UDEV_PROP_ACTION           "ACTION"
+#define UDEV_PROP_DEVNAME          "DEVNAME"
+#define UDEV_PROP_MODEL      "ID_MODEL"
+#define UDEV_PROP_MODEL_ID   "ID_MODEL_ID"
+#define UDEV_PROP_VENDOR     "ID_VENDOR"
+#define UDEV_PROP_VENDOR_ID  "ID_VENDOR_ID"
+
+/* Popup */
+#define USBOTG_SYSPOPUP        "usbotg-syspopup"
+#define METHOD_CAMERA          "CameraPopupLaunch"
+#define PARAM_CAMERA_ADD       "camera_add"
+#define PARAM_CAMERA_REMOVE    "camera_remove"
+
+static void camera_device_added (struct udev_device *dev)
+{
+       const char *driver = NULL;
+       const char *name = NULL;
+       const char *model = NULL;
+       const char *model_id = NULL;
+       const char *vendor = NULL;
+       const char *vendor_id = NULL;
+       char v_vendor[BUF_MAX];
+       char v_model[BUF_MAX];
+       int dev_type;
+
+       if (!dev)
+               return;
+
+       driver = udev_device_get_property_value(dev, UDEV_PROP_GPHOTO2_DRIVER);
+       if (!driver)
+               return;
+
+       dev_type = USBHOST_CAMERA;
+
+       name = udev_device_get_property_value(dev, UDEV_PROP_DEVNAME);
+       if (!name) {
+               _E("cannot get device name");
+               return;
+       }
+
+       vendor = udev_device_get_property_value(dev, UDEV_PROP_VENDOR);
+       vendor_id = udev_device_get_property_value(dev, UDEV_PROP_VENDOR_ID);
+       if (vendor && vendor_id
+                       && !strncmp(vendor, vendor_id, strlen(vendor)))
+               memset(v_vendor, 0, sizeof(v_vendor));
+       else {
+               if (verify_vendor_name(vendor, v_vendor, sizeof(v_vendor)) < 0)
+                       memset(v_vendor, 0, sizeof(v_vendor));
+       }
+
+       model = udev_device_get_property_value(dev, UDEV_PROP_MODEL);
+       model_id = udev_device_get_property_value(dev, UDEV_PROP_MODEL_ID);
+       if (model && model_id
+                       && !strncmp(model, model_id, strlen(model)))
+               memset(v_model, 0, sizeof(v_model));
+       else {
+               if (verify_model_name(model, v_vendor, v_model, sizeof(v_vendor)) < 0)
+                       memset(v_model, 0, sizeof(v_model));
+       }
+
+
+       if (add_usb_device_to_list(dev_type, name, v_model, v_vendor) < 0) {
+               _E("Failed to add device to dev_list");
+               return;
+       }
+
+       launch_ticker_notification(TICKER_NAME_CAMERA_CONNECTED);
+
+       launch_host_syspopup(USBOTG_SYSPOPUP, METHOD_CAMERA,
+                       POPUP_KEY_CONTENT, PARAM_CAMERA_ADD,
+                       NULL, NULL);
+
+       send_msg_camera_added();
+}
+
+static void camera_device_removed (struct udev_device *dev)
+{
+       const char *name = NULL;
+
+       if (!dev)
+               return;
+
+       name= udev_device_get_property_value(dev, UDEV_PROP_DEVNAME);
+       if (!name) {
+               return;
+       }
+
+       if (remove_usb_device_from_list(name, USBHOST_CAMERA) < 0) {
+               return;
+       }
+
+       launch_ticker_notification(TICKER_NAME_DEVICE_DISCONNECTED);
+
+       launch_host_syspopup(USBOTG_SYSPOPUP, METHOD_CAMERA,
+                       POPUP_KEY_CONTENT, PARAM_CAMERA_REMOVE,
+                       NULL, NULL);
+
+       send_msg_camera_removed();
+}
+
+static void subsystem_usb_changed (struct udev_device *dev)
+{
+       const char *action = NULL;
+       if (!dev)
+               return;
+
+       if (!is_host_uevent_enabled())
+               return;
+
+       action = udev_device_get_property_value(dev, UDEV_PROP_ACTION);
+       if (!action)
+               return;
+
+       if (!strncmp(action, "add", strlen("add"))) {
+               camera_device_added(dev);
+               return;
+       }
+
+       if (!strncmp(action, "remove", strlen("remove"))) {
+               camera_device_removed(dev);
+               return;
+       }
+}
+
+const static struct uevent_handler uhs_camera[] = {
+       { USB_SUBSYSTEM       ,     subsystem_usb_changed       ,    NULL    },
+};
+
+static int usbhost_camera_init_booting_done(void *data)
+{
+       int ret, i;
+
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_camera_init_booting_done);
+
+       for (i = 0 ; i < ARRAY_SIZE(uhs_camera) ; i++) {
+               ret = register_uevent_control(&uhs_camera[i]);
+               if (ret < 0)
+                       _E("FAIL: reg_uevent_control()");
+       }
+
+       return 0;
+}
+
+static void usbhost_camera_init(void *data)
+{
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_camera_init_booting_done);
+}
+
+static void usbhost_camera_exit(void *data)
+{
+       int i;
+
+       for (i = 0 ; i < ARRAY_SIZE(uhs_camera) ; i++) {
+               unregister_uevent_control(&uhs_camera[i]);
+       }
+}
+
+static const struct device_ops usbhost_device_camera_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "usbhost_camera",
+       .init     = usbhost_camera_init,
+       .exit     = usbhost_camera_exit,
+};
+
+DEVICE_OPS_REGISTER(&usbhost_device_camera_ops)
diff --git a/src/usb/usb-host-dbus.c b/src/usb/usb-host-dbus.c
new file mode 100755 (executable)
index 0000000..5f00d46
--- /dev/null
@@ -0,0 +1,759 @@
+/*
+ * 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 "usb-host.h"
+#include "core/edbus-handler.h"
+
+#define RETRY_MAX 5
+
+#define BUS_NAME_PREFIX           "org.tizen.usb"
+#define OBJECT_PATH_PREFIX        "/Org/Tizen/Usb"
+
+/* Notice for usb storage mount/unmount success */
+#define STORAGE_BUS_NAME           BUS_NAME_PREFIX".storage"
+#define STORAGE_OBJECT_PATH        OBJECT_PATH_PREFIX"/Storage"
+#define STORAGE_INTERFACE_NAME     STORAGE_BUS_NAME
+
+/* Notice for device changed */
+#define HOST_BUS_NAME              BUS_NAME_PREFIX".host"
+#define HOST_OBJECT_PATH           OBJECT_PATH_PREFIX"/Host"
+#define HOST_INTERFACE_NAME        HOST_BUS_NAME
+#define HOST_MOUSE_SIGNAL          "usbmouse"
+#define HOST_KEYBOARD_SIGNAL       "usbkeyboard"
+#define HOST_STORAGE_SIGNAL        "usbstorage"
+#define HOST_CAMERA_SIGNAL         "usbcamera"
+#define HOST_ADDED                 "added"
+#define HOST_REMOVED               "removed"
+
+/* Notification */
+#define POPUP_BUS_NAME             "org.tizen.system.popup"
+#define POPUP_OBJECT_PATH          "/Org/Tizen/System/Popup"
+#define POPUP_INTERFACE_NAME       POPUP_BUS_NAME
+
+#define POPUP_PATH_USBHOST         POPUP_OBJECT_PATH"/Usbhost"
+#define POPUP_INTERFACE_USBHOST        POPUP_INTERFACE_NAME".Usbhost"
+
+#define METHOD_STORAGE_NOTI_ON     "UsbStorageNotiOn"
+#define METHOD_STORAGE_RO_NOTI_ON  "UsbStorageRoNotiOn"
+#define METHOD_STORAGE_NOTI_OFF    "UsbStorageNotiOff"
+#define METHOD_DEVICE_NOTI_ON      "UsbDeviceNotiOn"
+#define METHOD_DEVICE_NOTI_UPDATE  "UsbDeviceNotiUpdate"
+#define METHOD_DEVICE_NOTI_OFF     "UsbDeviceNotiOff"
+
+/* Unmount */
+#define SIGNAL_NAME_UNMOUNT        "unmount_storage"
+
+/* Send device info to host-devices app */
+#define SIGNAL_NAME_DEVICE_ALL     "host_device_all"
+#define SIGNAL_NAME_DEVICE_ADDED   "host_device_add"
+#define SIGNAL_NAME_DEVICE_REMOVED "host_device_remove"
+
+/* USB storage update signal */
+#define SIGNAL_NAME_USB_STORAGE_CHANGED    "usb_storage_changed"
+#define STORAGE_ADDED                      "storage_added"
+#define STORAGE_REMOVED                    "storage_removed"
+#define STORAGE_UPDATED                    "storage_updated"
+
+
+struct noti_keyword {
+       int type;
+       char *key;
+};
+
+static struct noti_keyword noti_key[] = {
+       { USBHOST_KEYBOARD   , "keyboard" },
+       { USBHOST_MOUSE      , "mouse"    },
+       { USBHOST_CAMERA     , "camera"   },
+       { USBHOST_PRINTER    , "printer"  },
+       { USBHOST_UNKNOWN    , "unknown"  },
+};
+
+static int noti_id = 0;
+
+void send_msg_storage_added(bool mount)
+{
+       char *param[1];
+
+       param[0] = HOST_ADDED;
+
+       if (mount) {
+               if (broadcast_edbus_signal(STORAGE_OBJECT_PATH,
+                               STORAGE_INTERFACE_NAME,
+                               HOST_STORAGE_SIGNAL,
+                               "s", param) < 0)
+                       _E("Failed to send dbus signal");
+       } else {
+               if (broadcast_edbus_signal(HOST_OBJECT_PATH,
+                               HOST_INTERFACE_NAME,
+                               HOST_STORAGE_SIGNAL,
+                               "s", param) < 0)
+                       _E("Failed to send dbus signal");
+       }
+}
+
+void send_msg_storage_removed(bool mount)
+{
+       char *param[1];
+
+       param[0] = HOST_REMOVED;
+
+       if (mount) {
+               if (broadcast_edbus_signal(STORAGE_OBJECT_PATH,
+                               STORAGE_INTERFACE_NAME,
+                               HOST_STORAGE_SIGNAL,
+                               "s", param) < 0)
+                       _E("Failed to send dbus signal");
+       } else {
+               if (broadcast_edbus_signal(HOST_OBJECT_PATH,
+                               HOST_INTERFACE_NAME,
+                               HOST_STORAGE_SIGNAL,
+                               "s", param) < 0)
+                       _E("Failed to send dbus signal");
+       }
+}
+
+static void send_msg_device_changed(char *signal, char* action)
+{
+       char *param[1];
+
+       param[0] = action;
+
+       if (broadcast_edbus_signal(HOST_OBJECT_PATH,
+                       HOST_INTERFACE_NAME,
+                       signal,
+                       "s", param) < 0)
+               _E("Failed to send dbus signal");
+}
+
+void send_msg_keyboard_added(void)
+{
+       send_msg_device_changed(HOST_KEYBOARD_SIGNAL, HOST_ADDED);
+}
+
+void send_msg_keyboard_removed(void)
+{
+       send_msg_device_changed(HOST_KEYBOARD_SIGNAL, HOST_REMOVED);
+}
+
+void send_msg_mouse_added(void)
+{
+       send_msg_device_changed(HOST_MOUSE_SIGNAL, HOST_ADDED);
+}
+
+void send_msg_mouse_removed(void)
+{
+       send_msg_device_changed(HOST_MOUSE_SIGNAL, HOST_REMOVED);
+}
+
+void send_msg_camera_added(void)
+{
+       send_msg_device_changed(HOST_CAMERA_SIGNAL, HOST_ADDED);
+}
+
+void send_msg_camera_removed(void)
+{
+       send_msg_device_changed(HOST_CAMERA_SIGNAL, HOST_REMOVED);
+}
+
+int activate_storage_notification(char *path, int mount_type)
+{
+       char devpath[BUF_MAX];
+       char *arr[1];
+       int ret, i;
+       char *method;
+
+       if (!path)
+               return -EINVAL;
+
+       switch (mount_type) {
+       case STORAGE_MOUNT_RW:
+               method = METHOD_STORAGE_NOTI_ON;
+               break;
+       case STORAGE_MOUNT_RO:
+               method = METHOD_STORAGE_RO_NOTI_ON;
+               break;
+       default:
+               _E("Unknown mount type(%d)", mount_type);
+               return -EINVAL;
+       }
+
+       snprintf(devpath, sizeof(devpath), "%s", path);
+       arr[0] = devpath;
+
+       i = 0;
+       do {
+               ret = dbus_method_sync(POPUP_BUS_NAME,
+                               POPUP_PATH_USBHOST,
+                               POPUP_INTERFACE_USBHOST,
+                               METHOD_STORAGE_NOTI_ON,
+                               "s", arr);
+               if (ret < 0)
+                       _E("Retry to activate notification (path: %s, ret: %d, retry: %d)", path, ret, i);
+               else
+                       break;
+       } while (i++ < RETRY_MAX);
+
+       return ret;
+}
+
+int deactivate_storage_notification(int id)
+{
+       char devpath[BUF_MAX];
+       char *arr[1];
+       int ret, i;
+
+       if (id <= 0)
+               return -EINVAL;
+
+       snprintf(devpath, sizeof(devpath), "%d", id);
+       arr[0] = devpath;
+
+       i = 0;
+       do {
+               ret = dbus_method_sync(POPUP_BUS_NAME,
+                               POPUP_PATH_USBHOST,
+                               POPUP_INTERFACE_USBHOST,
+                               METHOD_STORAGE_NOTI_OFF,
+                               "i", arr);
+               if (ret < 0)
+                       _E("Retry to deactivate notification (ret: %d, retry: %d)", ret, i);
+               else
+                       break;
+       } while (i++ < RETRY_MAX);
+
+       return ret;
+}
+
+static void unmount_signal_handler(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       char *path;
+       struct usb_device dev;
+       int ret;
+
+       if (dbus_message_is_signal(msg, DEVICED_INTERFACE_USBHOST, SIGNAL_NAME_UNMOUNT) == 0) {
+               _E("The signal is not for unmounting storage");
+               return;
+       }
+
+       dbus_error_init(&err);
+
+       if (dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID) == 0) {
+               _E("FAIL: dbus_message_get_args");
+               return;
+       }
+
+       snprintf(dev.mntpath, sizeof(dev.mntpath), "%s", path);
+       if (is_storage_mounted(path)) {
+               if (add_job(STORAGE_UNMOUNT, &dev, true) < 0)
+                       _E("Failed to add job(%d, %s)", STORAGE_UNMOUNT, path);
+       } else {
+               _E("Failed to unmount since the storage (%s) is not mounted", path);
+       }
+}
+
+int register_unmount_signal_handler(void)
+{
+       return register_edbus_signal_handler(DEVICED_PATH_USBHOST,
+                       DEVICED_INTERFACE_USBHOST,
+                       SIGNAL_NAME_UNMOUNT, unmount_signal_handler);
+}
+
+static int get_product_name(struct usb_device *dev, char *product, int len)
+{
+       int v_len, m_len;
+       if (!dev || !product || len <= 0)
+               return -EINVAL;
+
+       v_len = strlen(dev->vendor);
+       m_len = strlen(dev->model);
+
+       if (v_len > 0 && m_len > 0)
+               snprintf(product, len, "%s %s", dev->vendor, dev->model);
+       else if (v_len > 0)
+               snprintf(product, len, "%s", dev->vendor);
+       else if (m_len > 0)
+               snprintf(product, len, "%s", dev->model);
+       else
+               memset(product, 0, len);
+
+       return 0;
+}
+
+static int launch_device_notification(int type, char *product)
+{
+       char *noti_type = NULL;
+       int i;
+       char devpath[BUF_MAX];
+       char *arr[2];
+       int ret, ret_val;
+
+       for (i = 0; i < ARRAY_SIZE(noti_key) ; i++) {
+               if (noti_key[i].type == type) {
+                       noti_type = noti_key[i].key;
+                       break;
+               }
+       }
+       if (!noti_type)
+               return -EINVAL;
+
+       arr[0] = noti_type;
+       arr[1] = product;
+
+       i = 0;
+       do {
+               ret = dbus_method_sync(POPUP_BUS_NAME,
+                               POPUP_PATH_USBHOST,
+                               POPUP_INTERFACE_USBHOST,
+                               METHOD_DEVICE_NOTI_ON,
+                               "ss", arr);
+               if (ret < 0)
+                       _E("Retry to activate notification (product: %s, ret: %d, retry: %d)", product, ret, i);
+               else
+                       break;
+       } while (i++ < RETRY_MAX);
+
+       return ret;
+}
+
+static int remove_device_notification(void)
+{
+       char *arr[1];
+       int ret, ret_val, i;
+       char id[8];
+
+       snprintf(id, sizeof(id), "%d", noti_id);
+       arr[0] = id;
+
+       i = 0;
+       do {
+               ret = dbus_method_sync(POPUP_BUS_NAME,
+                               POPUP_PATH_USBHOST,
+                               POPUP_INTERFACE_USBHOST,
+                               METHOD_DEVICE_NOTI_OFF,
+                               "i", arr);
+               if (ret < 0)
+                       _E("Retry to deactivate notification (ret: %d, retry: %d)", ret, i);
+               else
+                       break;
+       } while (i++ < RETRY_MAX);
+
+       return ret;
+}
+
+static int update_device_notification(int devlen, int type, char *product)
+{
+       char *noti_type = NULL;
+       int i, ret;
+       char devpath[BUF_MAX];
+       char *arr[4];
+       char id[8];
+       char len[4];
+
+       if (noti_id <= 0)
+               return -EINVAL;
+
+       for (i = 0; i < ARRAY_SIZE(noti_key) ; i++) {
+               if (noti_key[i].type == type) {
+                       noti_type = noti_key[i].key;
+                       break;
+               }
+       }
+       if (!noti_type)
+               return -EINVAL;
+
+       snprintf(id, sizeof(id), "%d", noti_id);
+       snprintf(len, sizeof(len), "%d", devlen);
+       arr[0] = id;
+       arr[1] = len;
+       arr[2] = noti_type;
+       arr[3] = product;
+
+       i = 0;
+       do {
+               ret = dbus_method_sync(POPUP_BUS_NAME,
+                               POPUP_PATH_USBHOST,
+                               POPUP_INTERFACE_USBHOST,
+                               METHOD_DEVICE_NOTI_UPDATE,
+                               "isss", arr);
+               if (ret < 0)
+                       _E("Retry to update notification (ret: %d, retry: %d)", ret, i);
+               else
+                       break;
+       } while (i++ < RETRY_MAX);
+
+       return ret;
+}
+
+int activate_device_notification(struct usb_device *dev, int len)
+{
+       char product[BUF_MAX];
+       int ret;
+
+       if (!dev)
+               return -EINVAL;
+
+       ret = get_product_name(dev, product, sizeof(product));
+       if (ret < 0) {
+               _E("cannot get product name to show");
+               return ret;
+       }
+
+       if (len > 0) {
+               return update_device_notification(len + 1, dev->type, product);
+       } else {
+               noti_id= launch_device_notification(dev->type, product);
+               if (noti_id < 0)
+                       return noti_id;
+               else
+                       return 0;
+       }
+}
+
+int deactivate_device_notification(struct usb_device *dev, int len)
+{
+       char product[BUF_MAX];
+       int ret;
+
+       if (len <= 0) {
+               ret = remove_device_notification();
+               noti_id = 0;
+               if (ret < 0)
+                       _E("Faile to remove notification");
+               return ret;
+       }
+
+       ret = get_product_name(dev, product, sizeof(product));
+       if (ret < 0) {
+               _E("cannot get product name to show");
+               return ret;
+       }
+
+       return update_device_notification(len, dev->type, product);
+}
+
+static int send_device_changed_info(struct usb_device *dev, char *signal)
+{
+       char *param[3];
+       char v_vendor[BUF_MAX];
+       char v_model[BUF_MAX];
+       int i;
+       char *noti_type;
+
+       int ret;
+
+       if (!dev | !signal)
+               return -EINVAL;
+
+       ret = verify_vendor_name(dev->vendor, v_vendor, sizeof(v_vendor));
+       if (ret < 0)
+               return ret;
+       ret = verify_model_name(dev->model, v_vendor, v_model, sizeof(v_model));
+       if (ret < 0)
+               return ret;
+
+       noti_type = NULL;
+       for (i = 0; i < ARRAY_SIZE(noti_key) ; i++) {
+               if (noti_key[i].type == dev->type) {
+                       noti_type = noti_key[i].key;
+                       break;
+               }
+       }
+       if (!noti_type)
+               return -EINVAL;
+
+       param[0] = noti_type;
+       param[1] = v_vendor;
+       param[2] = v_model;
+
+       ret = broadcast_edbus_signal(DEVICED_PATH_USBHOST,
+                       DEVICED_INTERFACE_USBHOST,
+                       signal,
+                       "sss", param);
+       return ret;
+}
+
+int send_device_added_info(struct usb_device *dev)
+{
+       return send_device_changed_info(dev, SIGNAL_NAME_DEVICE_ADDED);
+}
+
+int send_device_removed_info(struct usb_device *dev)
+{
+       return send_device_changed_info(dev, SIGNAL_NAME_DEVICE_REMOVED);
+}
+
+static int send_all_device_info(void)
+{
+       dd_list *l;
+       dd_list *dev_list;
+       struct usb_device *dev;
+
+       dev_list = get_device_list();
+       if (!dev_list) {
+               _E("cannot get device list()");
+               return -ENOMEM;
+       }
+
+       _I("device list length: %d", DD_LIST_LENGTH(dev_list));
+
+       DD_LIST_FOREACH(dev_list, l, dev) {
+               if (send_device_added_info(dev) < 0)
+                       _E("Failed to send device info");
+       }
+
+       return 0;
+}
+
+static void host_device_all_signal_handler(void *data, DBusMessage *msg)
+{
+       DBusError err;
+       char *str;
+       char *path;
+
+       _I("All device info are requested");
+
+       if (dbus_message_is_signal(msg, DEVICED_INTERFACE_USBHOST, SIGNAL_NAME_DEVICE_ALL) == 0) {
+               _E("The signal is not for unmounting storage");
+               return;
+       }
+
+       if (send_all_device_info() < 0)
+               _E("Failed to send device info");
+}
+
+int register_device_all_signal_handler(void)
+{
+       return register_edbus_signal_handler(DEVICED_PATH_USBHOST,
+                       DEVICED_INTERFACE_USBHOST,
+                       SIGNAL_NAME_DEVICE_ALL, host_device_all_signal_handler);
+}
+
+int send_storage_changed_info(struct usb_device *dev, char *type)
+{
+       char *param[3];
+       char mounted[2];
+
+       if (!dev | !type)
+               return -EINVAL;
+
+       param[0] = type;
+       param[1] = dev->mntpath;
+       snprintf(mounted, sizeof(mounted), "%d", dev->is_mounted);
+       param[2] = mounted;
+
+       return broadcast_edbus_signal(DEVICED_PATH_USBHOST,
+                       DEVICED_INTERFACE_USBHOST,
+                       SIGNAL_NAME_USB_STORAGE_CHANGED,
+                       "ssi", param);
+}
+
+static int send_all_storage_info(void)
+{
+       dd_list *storage_list, *l;
+       struct usb_device *dev;
+
+       storage_list = get_storage_list();
+       if (!storage_list)
+               return 0;
+
+       DD_LIST_FOREACH (storage_list, l, dev) {
+               if (send_storage_changed_info(dev, STORAGE_UPDATED) < 0)
+                       _E("Failed to send storage info (%s, %s)", dev->name, dev->mntpath);
+       }
+       return 0;
+}
+
+static DBusMessage *send_storage_info_all(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = send_all_storage_info();
+
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *send_storage_mount(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char *path;
+       int ret;
+       struct usb_device dev;
+
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_STRING, &path,
+                       DBUS_TYPE_INVALID);
+       if (ret == 0) {
+               _E("Failed to get path information");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       snprintf(dev.mntpath, sizeof(dev.mntpath), "%s", path);
+       if (!is_storage_mounted(path)) {
+               ret = add_job(STORAGE_MOUNT, &dev, true);
+               if (ret < 0)
+                       _E("Failed to add job(%d, %s)", STORAGE_MOUNT, path);
+       } else {
+               _E("Failed to mount since the storage (%s) is already mounted", path);
+       }
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *send_storage_unmount(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char *path;
+       int ret;
+       struct usb_device dev;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_STRING, &path,
+                       DBUS_TYPE_INVALID);
+       if (ret == 0) {
+               _E("Failed to get path information");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       snprintf(dev.mntpath, sizeof(dev.mntpath), "%s", path);
+       if (is_storage_mounted(path)) {
+               ret = add_job(STORAGE_UNMOUNT, &dev, true);
+               if (ret < 0)
+                       _E("Failed to add job(%d, %s)", STORAGE_UNMOUNT, path);
+       } else {
+               _E("Failed to unmount since the storage (%s) is not mounted", path);
+               ret = -ECANCELED;
+       }
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *send_storage_format(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       char *path;
+       int ret;
+       struct usb_device dev;
+
+       ret = dbus_message_get_args(msg, NULL,
+                       DBUS_TYPE_STRING, &path,
+                       DBUS_TYPE_INVALID);
+       if (ret == 0) {
+               _E("Failed to get path information");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       snprintf(dev.mntpath, sizeof(dev.mntpath), "%s", path);
+       ret = add_job(STORAGE_FORMAT, &dev, true);
+       if (ret < 0)
+               _E("Failed to add job(%d, %s)", STORAGE_FORMAT, path);
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static int is_device_connected(int type)
+{
+       int ret;
+       dd_list *device_list, *l;
+       struct usb_device *dev;
+
+       ret = DEVICE_DISCONNECTED;
+
+       device_list = get_device_list();
+       if (!device_list) {
+               _E("Device list is empty");
+               return ret;
+       }
+
+       DD_LIST_FOREACH(device_list, l, dev) {
+               if (dev->type == type) {
+                       ret = DEVICE_CONNECTED;
+                       break;
+               }
+       }
+       _I("Device (%d) state is (%d)", type, ret);
+       return ret;
+}
+
+static DBusMessage *send_keyboard_state(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = is_device_connected(USBHOST_KEYBOARD);
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static DBusMessage *send_mouse_state(E_DBus_Object *obj, DBusMessage *msg)
+{
+       DBusMessageIter iter;
+       DBusMessage *reply;
+       int ret;
+
+       ret = is_device_connected(USBHOST_MOUSE);
+
+out:
+       reply = dbus_message_new_method_return(msg);
+       dbus_message_iter_init_append(reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+       return reply;
+}
+
+static const struct edbus_method edbus_methods[] = {
+       { "StorageInfoAll"  ,  NULL, "i" ,  send_storage_info_all },
+       { "StorageMount"    ,   "s", "i" ,  send_storage_mount    },
+       { "StorageUnmount"  ,   "s", "i" ,  send_storage_unmount  },
+       { "StorageFormat"   ,   "s", "i" ,  send_storage_format   },
+       { "GetKeyboardState",  NULL, "i" ,  send_keyboard_state   },
+       { "GetMouseState"   ,  NULL, "i" ,  send_mouse_state      },
+};
+
+int register_usbhost_dbus_methods(void)
+{
+       return register_edbus_method(DEVICED_PATH_USBHOST, edbus_methods, ARRAY_SIZE(edbus_methods));
+}
diff --git a/src/usb/usb-host-hid.c b/src/usb/usb-host-hid.c
new file mode 100755 (executable)
index 0000000..7749274
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * 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 "usb-host.h"
+#include "core/device-notifier.h"
+#include <string.h>
+
+#define UDEV_PROP_DEVLINKS   "DEVLINKS"
+#define UDEV_PROP_PATH       "ID_PATH"
+#define UDEV_PROP_KEYBOARD   "ID_INPUT_KEYBOARD"
+#define UDEV_PROP_MOUSE      "ID_INPUT_MOUSE"
+#define UDEV_PROP_MODEL      "ID_MODEL"
+#define UDEV_PROP_MODEL_ID   "ID_MODEL_ID"
+#define UDEV_PROP_VENDOR     "ID_VENDOR"
+#define UDEV_PROP_VENDOR_ID  "ID_VENDOR_ID"
+
+static bool check_same_hid(const char *name)
+{
+       dd_list *dev_list, *l;
+       struct usb_device *dev;
+       char head[BUF_MAX];
+       char *term;
+
+       if (!name)
+               return false;
+
+       dev_list = get_device_list();
+       if (!dev_list)
+               return false;
+
+       snprintf(head, sizeof(head), "%s", name);
+       term = strrchr(head, ':');
+       if (!term)
+               return false;
+       *term = '\0';
+       _I("hid name head:(%s)", head);
+
+       DD_LIST_FOREACH(dev_list, l, dev) {
+               if (strstr(dev->name, head))
+                       return true;
+       }
+
+       return false;
+}
+
+static void hid_device_added (struct udev_device *dev)
+{
+       const char *path = NULL;
+       const char *type = NULL;
+       const char *model = NULL;
+       const char *model_id = NULL;
+       const char *vendor = NULL;
+       const char *vendor_id = NULL;
+       char v_vendor[BUF_MAX];
+       char v_model[BUF_MAX];
+       int dev_type;
+
+       if (!dev)
+               return;
+
+       if (udev_device_get_property_value(dev, UDEV_PROP_DEVLINKS))
+               return;
+
+       path = udev_device_get_property_value(dev, UDEV_PROP_PATH);
+       if (!path) {
+               _E("cannot get device path");
+               return;
+       }
+
+       if (check_same_hid(path)) {
+               _E("Same device is already connected");
+               return;
+       }
+
+       type = udev_device_get_property_value(dev, UDEV_PROP_KEYBOARD);
+       if (type)
+               dev_type = USBHOST_KEYBOARD;
+       else {
+               type = udev_device_get_property_value(dev, UDEV_PROP_MOUSE);
+               if (type)
+                       dev_type = USBHOST_MOUSE;
+       }
+       if (!type) {
+               _E("cannot get device type");
+               return;
+       }
+
+       vendor = udev_device_get_property_value(dev, UDEV_PROP_VENDOR);
+       vendor_id = udev_device_get_property_value(dev, UDEV_PROP_VENDOR_ID);
+       if (vendor && vendor_id
+                       && !strncmp(vendor, vendor_id, strlen(vendor)))
+               memset(v_vendor, 0, sizeof(v_vendor));
+       else {
+               if (verify_vendor_name(vendor, v_vendor, sizeof(v_vendor)) < 0)
+                       memset(v_vendor, 0, sizeof(v_vendor));
+       }
+
+       model = udev_device_get_property_value(dev, UDEV_PROP_MODEL);
+       model_id = udev_device_get_property_value(dev, UDEV_PROP_MODEL_ID);
+       if (model && model_id
+                       && !strncmp(model, model_id, strlen(model)))
+               memset(v_model, 0, sizeof(v_model));
+       else {
+               if (verify_model_name(model, v_vendor, v_model, sizeof(v_vendor)) < 0)
+                       memset(v_model, 0, sizeof(v_model));
+       }
+
+       if (add_usb_device_to_list(dev_type, path, v_model, v_vendor) < 0) {
+               _E("Failed to add device to dev_list");
+               return;
+       }
+
+       if (dev_type == USBHOST_KEYBOARD) {
+               launch_ticker_notification(TICKER_NAME_KEYBOARD_CONNECTED);
+               send_msg_keyboard_added();
+       } else if (dev_type == USBHOST_MOUSE) {
+               launch_ticker_notification(TICKER_NAME_MOUSE_CONNECTED);
+               send_msg_mouse_added();
+       }
+}
+
+static void hid_device_removed (struct udev_device *dev)
+{
+       const char *path = NULL;
+       const char *type = NULL;
+       int dev_type;
+
+       if (!dev)
+               return;
+
+       if (udev_device_get_property_value(dev, UDEV_PROP_DEVLINKS))
+               return;
+
+       type = udev_device_get_property_value(dev, UDEV_PROP_KEYBOARD);
+       if (type)
+               dev_type = USBHOST_KEYBOARD;
+       else {
+               type = udev_device_get_property_value(dev, UDEV_PROP_MOUSE);
+               if (type)
+                       dev_type = USBHOST_MOUSE;
+               else
+                       return;
+       }
+
+       path = udev_device_get_property_value(dev, UDEV_PROP_PATH);
+       if (!path) {
+               _E("cannot get device path");
+               return;
+       }
+
+       if (remove_usb_device_from_list(path, dev_type) < 0) {
+               _E("Failed to remove device from dev_list");
+               return;
+       }
+
+       launch_ticker_notification(TICKER_NAME_DEVICE_DISCONNECTED);
+
+       if (dev_type == USBHOST_KEYBOARD)
+               send_msg_keyboard_removed();
+       else if (dev_type == USBHOST_MOUSE)
+               send_msg_mouse_removed();
+}
+
+static void subsystem_input_changed (struct udev_device *dev)
+{
+       const char *action = NULL;
+       if (!dev)
+               return;
+
+       if (!is_host_uevent_enabled())
+               return;
+
+       action = udev_device_get_property_value(dev, "ACTION");
+       if (!action)
+               return;
+
+       if (!strncmp(action, "add", strlen("add"))) {
+               hid_device_added(dev);
+               return;
+       }
+
+       if (!strncmp(action, "remove", strlen("remove"))) {
+               hid_device_removed(dev);
+               return;
+       }
+}
+
+const static struct uevent_handler uhs_hid[] = {
+       { INPUT_SUBSYSTEM       ,     subsystem_input_changed       ,    NULL    },
+};
+
+static int usbhost_hid_init_booting_done(void *data)
+{
+       int ret, i;
+
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_hid_init_booting_done);
+
+       for (i = 0 ; i < ARRAY_SIZE(uhs_hid) ; i++) {
+               ret = register_uevent_control(&uhs_hid[i]);
+               if (ret < 0)
+                       _E("FAIL: reg_uevent_control()");
+       }
+
+       return 0;
+}
+
+static void usbhost_hid_init(void *data)
+{
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_hid_init_booting_done);
+}
+
+static void usbhost_hid_exit(void *data)
+{
+       int i;
+
+       for (i = 0 ; i < ARRAY_SIZE(uhs_hid) ; i++) {
+               unregister_uevent_control(&uhs_hid[i]);
+       }
+}
+
+static const struct device_ops usbhost_device_hid_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "usbhost_hid",
+       .init     = usbhost_hid_init,
+       .exit     = usbhost_hid_exit,
+};
+
+DEVICE_OPS_REGISTER(&usbhost_device_hid_ops)
diff --git a/src/usb/usb-host-naming.c b/src/usb/usb-host-naming.c
new file mode 100755 (executable)
index 0000000..a92cb3f
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include "usb-host.h"
+#include <string.h>
+
+#define VENDOR_HP_1         "Hewlett-Packard"
+#define VENDOR_HP_2         "Hewlett Packard"
+#define VENDOR_HP_3         "HP"
+#define VENDOR_SAMSUNG      "Samsung"
+
+static void remove_underbar(char *name)
+{
+       int i;
+       char *temp = name;
+
+       if (!temp)
+               return;
+
+       for (i = 0 ; i < strlen(name); temp++, i++) {
+               if (*temp == '_')
+                       *temp = ' ';
+       }
+}
+
+static void remove_non_alphabet(char *name)
+{
+       int i;
+       char *pos, *temp;
+
+       if (!name)
+               return;
+
+       pos = name + strlen(name) - 1;
+
+       for (i = strlen(name); i > 0 ; i--, pos--) {
+               if ((*pos >= 48 && *pos <= 57)          /* number */
+                               || (*pos >= 65 && *pos <= 90)   /* uppercase letter */
+                               || (*pos >= 97 && *pos <= 122)  /* lowercase letter */
+                               || *pos == '-'                 /* hyphen  */
+                               || *pos == ' ')                /* white space */
+                       continue;
+
+               temp = pos;
+               while (*temp != '\0') {
+                       *temp = *(temp + 1);
+                       temp++;
+               }
+       }
+}
+
+static void change_to_short(char *name, int len)
+{
+       if (strcasestr(name, VENDOR_HP_1)) {
+               snprintf(name, len, "%s", VENDOR_HP_3);
+               return;
+       }
+
+       if (strcasestr(name, VENDOR_HP_2)) {
+               snprintf(name, len, "%s", VENDOR_HP_3);
+               return;
+       }
+
+       if (strcasestr(name, VENDOR_HP_3)) {
+               snprintf(name, len, "%s", VENDOR_HP_3);
+               return;
+       }
+
+       if (strcasestr(name, VENDOR_SAMSUNG)) {
+               snprintf(name, len, "%s", VENDOR_SAMSUNG);
+               return;
+       }
+}
+
+static void remove_vendor(char *model, char *vendor)
+{
+       char *pos, *temp;
+       int i;
+
+       pos = strcasestr(model, vendor);
+       if (!pos)
+               return;
+
+       temp = pos + strlen(vendor);
+
+       while(*pos != '\0') {
+               *pos = *temp;
+               pos++;
+               temp++;
+       }
+}
+
+int verify_vendor_name(const char *vendor, char *buf, int len)
+{
+       char name[BUF_MAX];
+
+       if (!vendor || !buf || len <= 0)
+               return -EINVAL;
+
+       snprintf(name, sizeof(name), "%s", vendor);
+
+       remove_underbar(name);
+
+       remove_non_alphabet(name);
+
+       change_to_short(name, strlen(name));
+
+       snprintf(buf, len, "%s", name);
+       return 0;
+}
+
+int verify_model_name(const char *model, char *vendor, char *buf, int len)
+{
+       char name[BUF_MAX];
+
+       if (!model || !vendor || !buf || len <= 0)
+               return -EINVAL;
+
+       snprintf(name, sizeof(name), "%s", model);
+
+       remove_underbar(name);
+
+       remove_non_alphabet(name);
+
+       change_to_short(name, strlen(name));
+
+       remove_vendor(name, vendor);
+
+       snprintf(buf, len, "%s", name);
+       return 0;
+}
diff --git a/src/usb/usb-host-printer.c b/src/usb/usb-host-printer.c
new file mode 100755 (executable)
index 0000000..d1a1124
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * 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 "usb-host.h"
+#include "core/device-notifier.h"
+
+#define UDEV_PROP_ACTION           "ACTION"
+#define UDEV_PROP_SYSTEMD_WANTS    "SYSTEMD_WANTS"
+#define UDEV_PROP_DEVPATH          "DEVPATH"
+#define UDEV_PROP_MODEL      "ID_MODEL"
+#define UDEV_PROP_MODEL_ID   "ID_MODEL_ID"
+#define UDEV_PROP_VENDOR     "ID_VENDOR"
+#define UDEV_PROP_VENDOR_ID  "ID_VENDOR_ID"
+
+static void printer_device_added (struct udev_device *dev)
+{
+       const char *printer = NULL;
+       const char *path = NULL;
+       const char *model = NULL;
+       const char *model_id = NULL;
+       const char *vendor = NULL;
+       const char *vendor_id = NULL;
+       char v_vendor[BUF_MAX];
+       char v_model[BUF_MAX];
+       char *temp;
+       int dev_type;
+
+       if (!dev)
+               return;
+
+       printer = udev_device_get_property_value(dev, UDEV_PROP_SYSTEMD_WANTS);
+       if (!printer)
+               return;
+
+       if (!strstr(printer, "printer"))
+               return;
+
+       path = udev_device_get_property_value(dev, UDEV_PROP_DEVPATH);
+       if (!path)
+               return;
+
+       temp = strrchr(path, '/');
+       if (!temp)
+               return;
+
+       if (strstr(temp, "lp"))
+               return;
+
+       dev_type = USBHOST_PRINTER;
+
+       vendor = udev_device_get_property_value(dev, UDEV_PROP_VENDOR);
+       vendor_id = udev_device_get_property_value(dev, UDEV_PROP_VENDOR_ID);
+       if (vendor && vendor_id
+                       && !strncmp(vendor, vendor_id, strlen(vendor)))
+               memset(v_vendor, 0, sizeof(v_vendor));
+       else {
+               if (verify_vendor_name(vendor, v_vendor, sizeof(v_vendor)) < 0)
+                       memset(v_vendor, 0, sizeof(v_vendor));
+       }
+
+       model = udev_device_get_property_value(dev, UDEV_PROP_MODEL);
+       model_id = udev_device_get_property_value(dev, UDEV_PROP_MODEL_ID);
+       if (model && model_id
+                       && !strncmp(model, model_id, strlen(model)))
+               memset(v_model, 0, sizeof(v_model));
+       else {
+               if (verify_model_name(model, v_vendor, v_model, sizeof(v_vendor)) < 0)
+                       memset(v_model, 0, sizeof(v_model));
+       }
+
+       if (add_usb_device_to_list(dev_type, path, v_model, v_vendor) < 0) {
+               _E("Failed to add device to dev_list");
+               return;
+       }
+
+       launch_ticker_notification(TICKER_NAME_PRINTER_CONNECTED);
+}
+
+static void printer_device_removed (struct udev_device *dev)
+{
+       const char *path = NULL;
+       const char *printer = NULL;
+
+       if (!dev)
+               return;
+
+       printer = udev_device_get_property_value(dev, UDEV_PROP_SYSTEMD_WANTS);
+       if (!printer)
+               return;
+       if (!strstr(printer, "printer"))
+               return;
+
+       path = udev_device_get_property_value(dev, UDEV_PROP_DEVPATH);
+       if (!path)
+               return;
+
+       if (remove_usb_device_from_list(path, USBHOST_PRINTER) < 0)
+               return;
+
+       launch_ticker_notification(TICKER_NAME_DEVICE_DISCONNECTED);
+}
+
+static void subsystem_usb_changed (struct udev_device *dev)
+{
+       const char *action = NULL;
+       if (!dev)
+               return;
+
+       if (!is_host_uevent_enabled())
+               return;
+
+       action = udev_device_get_property_value(dev, UDEV_PROP_ACTION);
+       if (!action)
+               return;
+
+       if (!strncmp(action, "add", strlen("add"))) {
+               printer_device_added(dev);
+               return;
+       }
+
+       if (!strncmp(action, "remove", strlen("remove"))) {
+               printer_device_removed(dev);
+               return;
+       }
+}
+
+const static struct uevent_handler uhs_printer[] = {
+       { USB_SUBSYSTEM       ,     subsystem_usb_changed       ,    NULL    },
+};
+
+static int usbhost_printer_init_booting_done(void *data)
+{
+       int ret, i;
+
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_printer_init_booting_done);
+
+       for (i = 0 ; i < ARRAY_SIZE(uhs_printer) ; i++) {
+               ret = register_uevent_control(&uhs_printer[i]);
+               if (ret < 0)
+                       _E("FAIL: reg_uevent_control()");
+       }
+
+       return 0;
+}
+
+static void usbhost_printer_init(void *data)
+{
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_printer_init_booting_done);
+}
+
+static void usbhost_printer_exit(void *data)
+{
+       int i;
+
+       for (i = 0 ; i < ARRAY_SIZE(uhs_printer) ; i++) {
+               unregister_uevent_control(&uhs_printer[i]);
+       }
+}
+
+static const struct device_ops usbhost_device_printer_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "usbhost_printer",
+       .init     = usbhost_printer_init,
+       .exit     = usbhost_printer_exit,
+};
+
+DEVICE_OPS_REGISTER(&usbhost_device_printer_ops)
diff --git a/src/usb/usb-host-storage-vfat.c b/src/usb/usb-host-storage-vfat.c
new file mode 100644 (file)
index 0000000..cc2bf78
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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 <fcntl.h>
+#include <string.h>
+#include <sys/mount.h>
+
+#include "core/common.h"
+#include "usb-host.h"
+
+#define VFAT_MOUNT_OPT "uid=5000,gid=5000,dmask=0002,fmask=0002,iocharset=iso8859-1,utf8,shortname=mixed"
+#define SMACK_MOUNT_OPT "smackfsroot=*,smackfsdef=*"
+
+static const char *vfat_check_arg[] = {
+       "/usr/bin/fsck_msdosfs",
+       "-pf", NULL, NULL,
+};
+
+static const char *vfat_arg[] = {
+       "/sbin/mkfs.vfat",
+       NULL, NULL,
+};
+
+static int vfat_check(const char *devname)
+{
+       int argc;
+       argc = ARRAY_SIZE(vfat_check_arg);
+       vfat_check_arg[argc - 2] = devname;
+       return run_child(argc, vfat_check_arg);
+}
+
+static void get_mount_options(bool smack, char *options, int len)
+{
+       if (smack)
+               snprintf(options, len, "%s,%s", VFAT_MOUNT_OPT, SMACK_MOUNT_OPT);
+       else
+               snprintf(options, len, "%s", VFAT_MOUNT_OPT);
+}
+
+static int vfat_mount(bool smack, const char *devpath, const char *mount_point)
+{
+       char options[NAME_MAX];
+       get_mount_options(smack, options, sizeof(options));
+       return mount(devpath, mount_point, "vfat", 0, options);
+}
+
+static int vfat_mount_rdonly(bool smack, const char *devpath, const char *mount_point)
+{
+       char options[NAME_MAX];
+       get_mount_options(smack, options, sizeof(options));
+       return mount(devpath, mount_point, "vfat", MS_RDONLY, options);
+}
+
+static int vfat_format(const char *path)
+{
+       int argc;
+       argc = ARRAY_SIZE(vfat_arg);
+       vfat_arg[argc - 2] = path;
+       return run_child(argc, vfat_arg);
+}
+
+static const struct storage_fs_ops vfat_ops = {
+       .name         = "vfat",
+       .check        = vfat_check,
+       .mount        = vfat_mount,
+       .mount_rdonly = vfat_mount_rdonly,
+       .format       = vfat_format,
+};
+
+static void __CONSTRUCTOR__ vfat_init(void)
+{
+       register_fs(&vfat_ops);
+}
diff --git a/src/usb/usb-host-storage.c b/src/usb/usb-host-storage.c
new file mode 100755 (executable)
index 0000000..d51c0cd
--- /dev/null
@@ -0,0 +1,1279 @@
+/*
+ * 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 "usb-host.h"
+#include "core/device-notifier.h"
+#include <sys/mount.h>
+#include <sys/statfs.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+
+#define MOUNT_POINT     "/opt/storage/usb"
+#define FS_TMPFS        "tmpfs"
+#define SMACKFS_MNT        "/smack"
+#define SMACKFS_MAGIC  0x43415d53
+#define SIZE_32GB       61315072
+
+#define BLOCK_DEVICE_PATH         "/sys/block"
+#define BLOCK_DEVICE_POLLING_TIME "events_poll_msecs"
+#define POLLING_TIME_ABNORMAL     200
+#define POLLING_TIME_NORMAL       500
+
+#define RETRY_MAX 5
+
+#define SYSTEM_SYSPOPUP         "system-syspopup"
+#define METHOD_STORAGE_WARNING  "UsbotgWarningPopupLaunch"
+#define METHOD_WATCHDOG         "WatchdogPopupLaunch"
+#define METHOD_RECOVERY         "RecoveryPopupLaunch"
+#define PARAM_MOUNTFAIL         "usbotg_mount_failed"
+#define PARAM_REMOVED_UNSAFE    "usbotg_removed_unsafe"
+
+#define USBOTG_SYSPOPUP         "usbotg-syspopup"
+#define METHOD_STORAGE_MOUNT    "StoragePopupLaunch"
+#define METHOD_CAMERA           "CameraPopupLaunch"
+#define METHOD_STORAGE_UNMOUNT  "StorageUnmountPopupLaunch"
+#define PARAM_STORAGE_ADD       "storage_add"
+#define PARAM_STORAGE_REMOVE    "storage_remove"
+#define POPUP_KEY_DEVICE_PATH   "_DEVICE_PATH_"
+
+static int parts_num = 0;
+static bool mount_flag = false;
+static bool path_init = false;
+
+static bool smack = false;
+static dd_list *fs_list = NULL;
+
+static int pipe_out[2];
+
+struct job_data {
+       int type;
+       bool safe;
+       struct usb_device dev;
+};
+
+static dd_list *storage_job = NULL;
+static Ecore_Fd_Handler *pipe_handler;
+
+static void __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 = true;
+       _I("smackfs check %d", smack);
+}
+
+void register_fs(const struct storage_fs_ops *ops)
+{
+       if (!ops)
+               return;
+       DD_LIST_APPEND(fs_list, ops);
+}
+
+void unregister_fs(const struct storage_fs_ops *ops)
+{
+       if (!ops)
+               return;
+       DD_LIST_REMOVE(fs_list, ops);
+}
+
+static struct storage_fs_ops *get_fs_ops(char *name)
+{
+       dd_list *l;
+       struct storage_fs_ops *ops;
+
+       if (!name)
+               return NULL;
+
+       DD_LIST_FOREACH(fs_list, l, ops) {
+               if (!strncmp(ops->name, name, strlen(name)))
+                       return ops;
+       }
+       return NULL;
+}
+
+static int get_storage_size(char *name)
+{
+       int fd, ret;
+       uint64_t size;
+
+       if (!name)
+               return -EINVAL;
+
+       if (access(name, F_OK) != 0)
+               return -EINVAL;
+
+       fd = open(name, O_RDONLY);
+       if (fd < 0) {
+               _E("Failed to open (%s) with errno(%d)", name, errno);
+               return -errno;
+       }
+
+       if (ioctl(fd, BLKGETSIZE64, &size) < 0) {
+               _E("Failed to get size of (%s), errno(%d)", name, errno);
+               size = -errno;
+       }
+
+       close(fd);
+       return size;
+}
+
+static int get_block_device_name(const char *devname, char *block, int len)
+{
+       char *name;
+
+       name = strstr(devname, "sd");
+       if (!name) {
+               _E("Cannot get the device name");
+               return -ENOMEM;
+       }
+
+       snprintf(block, len, "%s", name);
+       name = block;
+       while (*name) {
+               if (*name >= 48 && *name <= 57) {
+                       *name = '\0';
+                       break;
+               }
+               name = name + 1;
+       }
+       _I("Block device name: (%s)", block);
+
+       return 0;
+}
+static int get_block_size(const char *devname)
+{
+       char block[32];
+       char block_size[BUF_MAX];
+       char size[32];
+       FILE *fp;
+       int ret;
+
+       ret = get_block_device_name(devname, block, sizeof(block));
+       if (ret < 0) {
+               _E("Failed to get block device name(%s)", devname);
+               return ret;
+       }
+
+       snprintf(block_size, sizeof(block_size), "%s/%s/size", BLOCK_DEVICE_PATH, block);
+
+       fp = fopen(block_size, "r");
+       if (!fp) {
+               _E("Failed to open block device size node");
+               return -ENOMEM;
+       }
+
+       ret = fread(size, 1, sizeof(size), fp);
+       fclose(fp);
+       if (ret <= 0) {
+               _E("Cannot read size of block device(%d)", ret);
+               return -ENOMEM;
+       }
+
+       return atoi(size);
+}
+
+static int set_block_polling_time(char *devname, int time)
+{
+       FILE *fp;
+       char block[32];
+       char ptime[32];
+       char tpath[BUF_MAX];
+       int ret;
+
+       ret = get_block_device_name(devname, block, sizeof(block));
+       if (ret < 0) {
+               _E("Failed to get block device name(%s)", devname);
+               return ret;
+       }
+
+       snprintf(ptime, sizeof(ptime), "%d", time);
+       snprintf(tpath, sizeof(tpath), "%s/%s/%s",
+                       BLOCK_DEVICE_PATH, block, BLOCK_DEVICE_POLLING_TIME);
+       fp = fopen(tpath, "w");
+       if (!fp) {
+               _E("Failed to open file (%s)", tpath);
+               return -ENOMEM;
+       }
+
+       ret = fwrite(ptime, 1, strlen(ptime), fp);
+       fclose(fp);
+       if (ret <= 0) {
+               _E("Failed to write (%s) to file (%s)", ptime, tpath);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static int check_changed_storage(struct udev_device *dev)
+{
+       const char *devname;
+       int size;
+
+       if (!dev)
+               return -EINVAL;
+
+       devname = udev_device_get_property_value(dev, "DEVNAME");
+       if (!devname) {
+               _E("Failed to get device name");
+               return -EINVAL;
+       }
+
+       return get_block_size(devname);
+}
+
+static bool check_storage_exists(struct udev_device *dev)
+{
+       const char *devname;
+       char mntpath[BUF_MAX];
+       bool same;
+       int ret;
+
+       if (!dev)
+               return false;
+
+       devname = udev_device_get_property_value(dev, "DEVNAME");
+       if (!devname) {
+               _E("Failed to get device name");
+               return false;
+       }
+
+       ret = get_mount_path(devname, mntpath, sizeof(mntpath));
+       if (ret < 0) {
+               _E("Cannot get mount path");
+               return false;
+       }
+
+       same = check_same_mntpath(mntpath);
+       if (!same)
+               set_block_polling_time((char *)devname, POLLING_TIME_ABNORMAL);
+       return same;
+}
+
+static int mount_path_init(void)
+{
+       int ret, retry;
+
+       if (path_init)
+               return 0;
+
+       if (access(MOUNT_POINT, F_OK) < 0) {
+               ret = mkdir(MOUNT_POINT, 0755);
+               if (ret < 0) {
+                       _E("Failed to make directory to mount usb storage");
+                       return ret;
+               }
+       }
+
+       retry = 0;
+       do {
+               ret = mount(FS_TMPFS, MOUNT_POINT, FS_TMPFS, 0, "");
+               if (ret == 0)
+                       break;
+       } while (retry ++ < RETRY_MAX);
+
+       if (ret < 0) {
+               _E("Failed to mount tmpfs to mount point(%s)", MOUNT_POINT);
+               goto out;
+       }
+
+       ret = chmod(MOUNT_POINT, 0755);
+       if (ret < 0) {
+               _E("Failed to change permission(%d)", MOUNT_POINT);
+               goto out_unmount;
+       }
+
+       path_init = true;
+       return 0;
+
+out_unmount:
+       if (umount2(MOUNT_POINT, MNT_DETACH) < 0)
+               _E("Failed to unmount tmpfs(%s)", MOUNT_POINT);
+out:
+       if (rmdir(MOUNT_POINT) < 0)
+               _E("Failed to remove directory(%s)", MOUNT_POINT);
+
+       return ret;
+}
+
+static void mount_path_deinit(void)
+{
+       int ret, retry, len;
+       dd_list *storage_list, *l;
+       struct usb_device *dev;
+
+       storage_list = get_storage_list();
+       DD_LIST_FOREACH(storage_list, l, dev) {
+               if (dev->is_mounted == true)
+                       return;
+       }
+
+       path_init = false;
+
+       if (access(MOUNT_POINT, F_OK) < 0)
+               return;
+
+       if (umount2(MOUNT_POINT, MNT_DETACH) < 0)
+               _E("Failed to unmount tmpfs(%s)", MOUNT_POINT);
+
+       if (rmdir(MOUNT_POINT) < 0)
+               _E("Failed to remove directory(%s)", MOUNT_POINT);
+
+       return;
+}
+
+static void add_partition_number(int num)
+{
+       if (num <= 0)
+               return;
+
+       if (parts_num >= 0) {
+               parts_num += num;
+               return;
+       }
+
+       parts_num = num;
+}
+
+static void launch_mount_popup_by_flag(bool success, char *path)
+{
+       if (parts_num > 0)
+               parts_num--;
+       else
+               parts_num = 0;
+
+       if (success)
+               mount_flag = true;
+
+       if (parts_num != 0)
+               return;
+
+       if (mount_flag)
+               mount_flag = false;
+       else
+               launch_host_syspopup(SYSTEM_SYSPOPUP, METHOD_STORAGE_WARNING,
+                               POPUP_KEY_CONTENT, PARAM_MOUNTFAIL, NULL, NULL);
+}
+
+int get_mount_path(const char *name, char *path, int len)
+{
+       char *dev;
+       char buf[BUF_MAX];
+
+       if (!name || !path || len <= 0)
+               return -EINVAL;
+
+       dev = strstr(name, "/sd");
+       if (!dev)
+               return -ENOMEM;
+
+       dev = dev + 3;
+
+       snprintf(buf, sizeof(buf), "%s", dev);
+       if (*buf >= 97 && *buf <= 122)
+               *buf = *buf - 32;
+
+       snprintf(path, len, "%s/UsbDrive%s", MOUNT_POINT, buf);
+
+       return 0;
+}
+
+int get_devname_by_path(char *path, char *name, int len)
+{
+       char *dev;
+       char buf[BUF_MAX];
+
+       if (!path || !name || len <= 0)
+               return -EINVAL;
+
+       dev = strstr(path, "UsbDrive");
+       if (!dev)
+               return -EINVAL;
+
+       dev = dev + 8;
+
+       snprintf(buf, sizeof(buf), "%s", dev);
+       if (*buf >= 65 && *buf <= 90)
+               *buf = *buf + 32;
+
+       snprintf(name, len, "/dev/sd%s", buf);
+
+       return 0;
+}
+
+
+static int find_app_accessing_storage(char *path)
+{
+       const char *argv[7] = {"/sbin/fuser", "-m", "-S", NULL, NULL, NULL};
+       int argc;
+
+       if (!path)
+               return -EINVAL;
+
+       argv[5] = path;
+
+       argc = ARRAY_SIZE(argv);
+
+       return run_child(argc, argv);
+}
+
+static int mount_storage(const char *fstype, const char *devname, char *path)
+{
+       dd_list *l;
+       struct storage_fs_ops *ops;
+       int ret, retry;
+
+       if (!fstype || !devname || !path)
+               return -EINVAL;
+
+       ret = mount_path_init();
+       if (ret < 0) {
+               _E("Failed to init mount path");
+               return ret;
+       }
+
+       DD_LIST_FOREACH(fs_list, l, ops) {
+               if (strncmp(ops->name, fstype, strlen(fstype)))
+                       continue;
+
+               ret = mkdir(path, 0755);
+               if (ret < 0) {
+                       if (errno != EEXIST) {
+                               _E("Failed to make mount path(%s)", path);
+                               return -errno;
+                       }
+               }
+
+               if (ops->check) {
+                       ret = ops->check(devname);
+                       if (ret < 0) {
+                               _E("Failed to check device file system(%s, %s)", fstype, devname);
+                               goto out;
+                       }
+               }
+
+               if (!(ops->mount)) {
+                       _E("Cannot mount device");
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               retry = 0;
+               do {
+                       ret = ops->mount(smack, devname, path);
+                       if (ret == 0 || errno == EROFS)
+                               break;
+               } while (retry++ < RETRY_MAX);
+
+               if (ret == 0)
+                       return ret;
+
+               if (errno == EROFS && ops->mount_rdonly) {
+                       _I("Read only file system is connected");
+                       retry = 0;
+                       do {
+                               ret = ops->mount_rdonly(smack, devname, path);
+                               if (ret == 0) {
+                                       ret = EROFS;
+                                       break;
+                               }
+                       } while (retry++ < RETRY_MAX);
+               }
+
+               if (ret < 0) {
+                       _E("Failed to mount usb storage (devname: %s, ret: %d, errno: %d)", devname, ret, errno);
+                       goto out;
+               }
+
+               return ret;
+       }
+
+       _E("Not supported file system");
+       ret = -ENOTSUP;
+out:
+       if (access(path, F_OK) == 0) {
+               if (rmdir(path) < 0)
+                       _E("Failed to remove dir(%s)", path);
+       }
+       return ret;
+}
+
+static int unmount_storage(char *path)
+{
+       int ret;
+
+       if (!path)
+               return -EINVAL;
+
+       ret = access(path, F_OK);
+       if (ret < 0) {
+               _E("The mount path (%s) does not exist", path);
+               return ret;
+       }
+
+       ret = umount2(path, MNT_DETACH);
+       if (ret < 0) {
+               _E("Failed to unmount storage (%s), errno(%d)", path, errno);
+               goto out;
+       }
+
+       ret = rmdir(path);
+       if (ret < 0) {
+               _E("Failed to remove mount path(%d), errno(%d)", path, errno);
+               goto out;
+       }
+
+       return 0;
+
+out:
+       if (find_app_accessing_storage(path) < 0)
+               _E("Failed to find apps accessing the storage(%d)", path);
+
+       return ret;
+}
+
+int mount_usb_storage(const char *name)
+{
+       dd_list *storage_list, *l;
+       struct usb_device *dev;
+       bool found;
+       int ret, mount_type;
+
+       storage_list = get_storage_list();
+       if (!storage_list) {
+               _E("Storage list is NULL");
+               return -ENOMEM;
+       }
+
+       found = false;
+       DD_LIST_FOREACH(storage_list, l, dev) {
+               if (strncmp(dev->name, name, strlen(name)))
+                       continue;
+               found = true;
+               break;
+       }
+       if (!found) {
+               _E("Cannot find storage whose name is (%s)", name);
+               return -EINVAL;
+       }
+
+       if (dev->is_mounted == true) {
+               _E("(%s) is already mounted", dev->name);
+               return -ECANCELED;
+       }
+
+       ret = mount_storage(dev->fs, dev->name, dev->mntpath);
+       if (ret < 0) {
+               _E("Failed to mount usb storage(%s, %s, %s): %d", dev->fs, dev->name, dev->mntpath, ret);
+               launch_mount_popup_by_flag(false, dev->mntpath);
+               return ret;
+       }
+
+       if (ret == EROFS)
+               mount_type = STORAGE_MOUNT_RO;
+       else
+               mount_type = STORAGE_MOUNT_RW;
+
+       dev->noti_id = activate_storage_notification(dev->mntpath, mount_type);
+       dev->is_mounted = true;
+
+       return ret;
+}
+
+static int format_usb_storage(const char *path)
+{
+       int ret, i;
+       char name[BUF_MAX];
+       dd_list *storage_list, *l;
+       struct usb_device *dev;
+       struct storage_fs_ops *fs_ops;
+       bool found;
+
+       if (!path)
+               return -EINVAL;
+
+       storage_list = get_storage_list();
+       if (!storage_list) {
+               _E("Storage list is NULL");
+               return -ENOMEM;
+       }
+
+       found = false;
+       DD_LIST_FOREACH(storage_list, l, dev) {
+               if (strncmp(dev->mntpath, path, strlen(path)))
+                       continue;
+               found = true;
+               break;
+       }
+       if (!found) {
+               _I("Cannot find storage whose name is (%s)", name);
+               return -ENOENT;
+       }
+
+       if (dev->is_mounted == true) {
+               ret = unmount_storage(dev->mntpath);
+               if (ret < 0) {
+                       _E("Failed to unmount storage(%s): %d", dev->mntpath, ret);
+                       return ret;
+               }
+               dev->is_mounted = false;
+               dev->noti_id = deactivate_storage_notification(dev->noti_id);
+       }
+
+       fs_ops = get_fs_ops(dev->fs);
+       if (!fs_ops) {
+               if (get_storage_size(dev->name) <= SIZE_32GB)
+                       fs_ops = get_fs_ops("vfat");
+               else
+                       fs_ops = get_fs_ops("exfat");
+               if (!fs_ops) {
+                       _E("Cannot get file system to format");
+                       return -EINVAL;
+               }
+       }
+
+       ret = -1;
+       if (fs_ops->format) {
+               i = 0;
+               do {
+                       ret = fs_ops->format(dev->name);
+                       if (ret < 0) {
+                               _E("Failed to format (%s, %d).. retry(%d)", dev->name, ret, i);
+                               continue;
+                       }
+                       break;
+               } while (i++ < RETRY_MAX);
+       }
+       if (ret < 0) {
+               _E("Falied to format (%s, %d)", dev->name, ret);
+               return ret;
+       }
+
+       ret = mount_usb_storage(dev->name);
+       if (ret < 0) {
+               _E("Falied to mount storage(%s): %d", dev->mntpath, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int unmount_usb_storage(const char *path, bool safe)
+{
+       int ret;
+       char name[BUF_MAX];
+       dd_list *storage_list, *l;
+       struct usb_device *dev;
+       bool found;
+
+       if (!path)
+               return -EINVAL;
+
+       storage_list = get_storage_list();
+       if (!storage_list) {
+               _E("Storage list is NULL");
+               return -ENOMEM;
+       }
+
+       found = false;
+       DD_LIST_FOREACH(storage_list, l, dev) {
+               if (strncmp(dev->mntpath, path, strlen(path)))
+                       continue;
+               found = true;
+               break;
+       }
+       if (!found) {
+               _I("Cannot find storage whose name is (%s)", name);
+               mount_path_deinit();
+               return -ENOENT;
+       }
+
+       if (dev->is_mounted == false) {
+               _I("(%s) is already unmounted", dev->name);
+               mount_path_deinit();
+               return -ENOENT;
+       }
+
+       ret = unmount_storage(dev->mntpath);
+       if (ret < 0) {
+               _E("Failed to unmount storage(%s): %d", dev->mntpath, ret);
+               return ret;
+       }
+
+       dev->is_mounted = false;
+       dev->noti_id = deactivate_storage_notification(dev->noti_id);
+       mount_path_deinit();
+
+       return 0;
+}
+
+static void storage_device_added (struct udev_device *dev)
+{
+       const char *nparts;
+       const char *fstype;
+       const char *devname;
+       const char *vendor;
+       const char *model;
+       char mountpath[BUF_MAX];
+       int num, ret;
+       bool mounted;
+       int noti_id;
+       struct usb_device usb_dev;
+
+       if (!dev)
+               return;
+
+       nparts = udev_device_get_property_value(dev, "NPARTS");
+       if (nparts) {
+               num = atoi(nparts);
+               if (num > 0) {
+                       add_partition_number(num);
+                       return;
+               }
+       }
+
+       fstype = udev_device_get_property_value(dev, "ID_FS_TYPE");
+       if (!fstype) {
+               _E("Failed to get file system type");
+               return;
+       }
+
+       devname = udev_device_get_property_value(dev, "DEVNAME");
+       if (!devname) {
+               _E("Failed to get device name");
+               return;
+       }
+
+       model = udev_device_get_property_value(dev, "ID_MODEL");
+       if (!model)
+               _E("Failed to get model information");
+
+       vendor = udev_device_get_property_value(dev, "ID_VENDOR");
+       if (!vendor)
+               _E("Failed to get vendor information");
+
+       snprintf(usb_dev.name, sizeof(usb_dev.name), "%s", devname);
+       snprintf(usb_dev.fs, sizeof(usb_dev.fs), "%s", fstype);
+       snprintf(usb_dev.model, sizeof(usb_dev.model), "%s", model);
+       snprintf(usb_dev.vendor, sizeof(usb_dev.vendor), "%s", vendor);
+       ret = get_mount_path(devname, usb_dev.mntpath, sizeof(usb_dev.mntpath));
+       if (ret < 0) {
+               _E("Failed to get mount path(%d, %s)", ret, usb_dev.name);
+               return ;
+       }
+
+       set_block_polling_time(usb_dev.name, POLLING_TIME_NORMAL);
+
+       ret = add_job(STORAGE_ADD, &usb_dev, true);
+       if (ret < 0) {
+               _E("Failed to add job (%d, %s, %d)", STORAGE_ADD, usb_dev.name, ret);
+               return ;
+       }
+
+       ret = add_job(STORAGE_MOUNT, &usb_dev, true);
+       if (ret < 0)
+               _E("Falied to mount storage (%d, %s, %d)", STORAGE_MOUNT, usb_dev.name, ret);
+}
+
+static void storage_device_removed (struct udev_device *dev)
+{
+       const char *devname = NULL;
+       const char *nparts = NULL;
+       char mountpath[BUF_MAX];
+       int ret;
+       struct usb_device usb_dev;
+       dd_list *storage_list, *l;
+
+       if (!dev)
+               return;
+
+       nparts = udev_device_get_property_value(dev, "NPARTS");
+       if (nparts) {
+               ret = atoi(nparts);
+               if (ret > 0)
+                       return;
+               if (ret == 0) {
+                       if (!udev_device_get_property_value(dev, "ID_FS_TYPE")
+                                       && !udev_device_get_property_value(dev, "DISK_MEDIA_CHANGE")) {
+                               return;
+                       }
+               }
+       }
+
+       devname = udev_device_get_property_value(dev, "DEVNAME");
+       if (!devname) {
+               _E("cannot get device name");
+               return;
+       }
+
+       snprintf(usb_dev.name, sizeof(usb_dev.name), "%s", devname);
+       ret = get_mount_path(devname, usb_dev.mntpath, sizeof(usb_dev.mntpath));
+       if (ret < 0) {
+               _E("Failed to get mount path(%d, %s)", ret, usb_dev.name);
+               return ;
+       }
+
+       ret = add_job(STORAGE_UNMOUNT, &usb_dev, false);
+       if (ret < 0) {
+               _E("Failed to add job (%d, %s, %d)", STORAGE_UNMOUNT, usb_dev.name, ret);
+               return ;
+       }
+
+       ret = add_job(STORAGE_REMOVE, &usb_dev, true);
+       if (ret < 0)
+               _E("Falied to mount storage (%d, %s, %d)", STORAGE_REMOVE, usb_dev.name, ret);
+}
+
+static void *start_job(void *data)
+{
+       int result;
+       struct job_data *job;
+       struct usb_device *dev;
+
+       if (DD_LIST_LENGTH(storage_job) <= 0) {
+               _E("storage job list is NULL");
+               result = -1;
+               goto out;
+       }
+
+       job = DD_LIST_NTH(storage_job, 0);
+       if (!job) {
+               _E("cannot get 0th job");
+               result = -1;
+               goto out;
+       }
+
+       dev = &(job->dev);
+       if (!dev) {
+               _E("job->dev == NULL");
+               result = -1;
+               goto out;
+       }
+
+       switch (job->type) {
+       case STORAGE_ADD:
+               if (check_same_mntpath(dev->mntpath))
+                       result = -1;
+               else
+                       result = add_usb_storage_to_list(dev->name, dev->vendor, dev->model, dev->fs);
+               break;
+
+       case STORAGE_REMOVE:
+               if (check_same_mntpath(dev->mntpath))
+                       result = remove_usb_storage_from_list(dev->name);
+               else
+                       result = -1;
+               break;
+
+       case STORAGE_MOUNT:
+               if (is_storage_mounted(dev->mntpath))
+                       result = -1;
+               else
+                       result = mount_usb_storage(dev->name);
+               break;
+
+       case STORAGE_UNMOUNT:
+               if (is_storage_mounted(dev->mntpath))
+                       result = unmount_usb_storage(dev->mntpath, job->safe);
+               else
+                       result = -1;
+               break;
+
+       case STORAGE_FORMAT:
+               if (check_same_mntpath(dev->mntpath))
+                       result = format_usb_storage(dev->mntpath);
+               else
+                       result = -1;
+               break;
+
+       default:
+               _E("Unknown job type (%d)", job->type);
+               result = -1;
+               break;
+       }
+
+       _I("Job(%d, %s) is done: (%d)", job->type, dev->mntpath, result);
+
+out:
+       write(pipe_out[1], &result, sizeof(int));
+       return NULL;
+}
+
+static int trigger_job(void)
+{
+       pthread_t th;
+       int ret;
+
+       if (DD_LIST_LENGTH(storage_job) <= 0) {
+               return 0;
+       }
+
+       ret = pthread_create(&th, NULL, start_job, NULL);
+       if (ret < 0) {
+               _E("Failed to create pthread");
+               return ret;
+       }
+       pthread_detach(th);
+
+       return 0;
+}
+
+int add_job(int type, struct usb_device *dev, bool safe)
+{
+       struct job_data *job;
+       struct usb_device *usb_dev;
+       int len;
+
+       len = DD_LIST_LENGTH(storage_job);
+
+       job = (struct job_data *)malloc(sizeof(struct job_data));
+       if (!job) {
+               _E("malloc() failed");
+               return -ENOMEM;
+       }
+
+       job->type = type;
+       job->safe = safe;
+       snprintf((job->dev).name, sizeof((job->dev).name), "%s", dev->name);
+       snprintf((job->dev).mntpath, sizeof((job->dev).mntpath), "%s", dev->mntpath);
+       snprintf((job->dev).vendor, sizeof((job->dev).vendor), "%s", dev->vendor);
+       snprintf((job->dev).model, sizeof((job->dev).model), "%s", dev->model);
+       snprintf((job->dev).fs, sizeof((job->dev).fs), "%s", dev->fs);
+
+       DD_LIST_APPEND(storage_job, job);
+
+       _I("ADD Job(%d, %s, %d)", job->type, (job->dev).name, job->safe);
+
+       if (len > 0)
+               return 0;
+
+       if (trigger_job() < 0)
+               _E("Failed to trigger job");
+
+
+       return 0;
+}
+
+static bool check_to_skip_unmount_error(struct usb_device *dev)
+{
+       dd_list *l;
+       struct job_data *job;
+       int i;
+
+       if (!storage_job || DD_LIST_LENGTH(storage_job) <= 0)
+               return false;
+       if (!dev)
+               return false;
+
+       i = 0;
+       DD_LIST_FOREACH(storage_job, l, job) {
+               if (i++ == 0)
+                       continue;
+               if (strncmp((job->dev).mntpath, dev->mntpath, strlen((job->dev).mntpath)))
+                       continue;
+
+               if (job->type == STORAGE_MOUNT)
+                       return true;
+       }
+
+       return false;
+}
+
+static int send_storage_notification(struct job_data *job, int result)
+{
+       char *noti_type;
+
+       if (!job)
+               return -EINVAL;
+
+       if (result < 0 && job->type != STORAGE_FORMAT)
+               return -EINVAL;
+
+       switch (job->type) {
+       case STORAGE_ADD:
+               (job->dev).is_mounted = false;
+               if (send_storage_changed_info(&(job->dev), "storage_unmount") < 0)
+                       _E("Failed to send signal");
+               break;
+
+       case STORAGE_REMOVE:
+               (job->dev).is_mounted = false;
+               if (send_storage_changed_info(&(job->dev), "storage_remove") < 0)
+                       _E("Failed to send signal");
+               break;
+
+       case STORAGE_FORMAT:
+               if (result < 0) {
+                       (job->dev).is_mounted = false;
+                       send_msg_storage_removed(true);
+                       if (send_storage_changed_info(&(job->dev), "storage_unmount") < 0)
+                               _E("Failed to send signal");
+                       break;
+               }
+               /* if result >= 0, the notifications are same with storage mount */
+
+       case STORAGE_MOUNT:
+               if (result == EROFS)
+                       noti_type = TICKER_NAME_STORAGE_RO_CONNECTED;
+               else
+                       noti_type = TICKER_NAME_STORAGE_CONNECTED;
+
+               (job->dev).is_mounted = true;
+               launch_mount_popup_by_flag(true, (job->dev).mntpath);
+               launch_ticker_notification(noti_type);
+               send_msg_storage_added(true);
+               if (send_storage_changed_info(&(job->dev), "storage_mount") < 0)
+                       _E("Failed to send signal");
+               launch_host_syspopup(USBOTG_SYSPOPUP, METHOD_STORAGE_MOUNT,
+                               POPUP_KEY_CONTENT, PARAM_STORAGE_ADD,
+                               POPUP_KEY_DEVICE_PATH, (job->dev).mntpath);
+               break;
+
+       case STORAGE_UNMOUNT:
+               (job->dev).is_mounted = false;
+               _I("Safe: (%d)", job->safe ? 1 : 0);
+               if (job->safe)
+                       launch_ticker_notification(TICKER_NAME_STORAGE_DISCONNECTED_SAFE);
+               else {
+                       if (!check_to_skip_unmount_error(&(job->dev)))
+                               launch_host_syspopup(SYSTEM_SYSPOPUP, METHOD_STORAGE_WARNING,
+                                               POPUP_KEY_CONTENT, PARAM_REMOVED_UNSAFE, NULL, NULL);
+               }
+               send_msg_storage_removed(true);
+               if (send_storage_changed_info(&(job->dev), "storage_unmount") < 0)
+                       _E("Failed to send signal");
+               launch_host_syspopup(USBOTG_SYSPOPUP, METHOD_STORAGE_MOUNT,
+                               POPUP_KEY_CONTENT, PARAM_STORAGE_REMOVE,
+                               POPUP_KEY_DEVICE_PATH, (job->dev).mntpath);
+
+               break;
+
+       default:
+               _E("Invalid job type(%d)", job->type);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void remove_job(int result)
+{
+       struct job_data *job;
+
+       if (!storage_job || DD_LIST_LENGTH(storage_job) <= 0) {
+               return ;
+       }
+
+       job = DD_LIST_NTH(storage_job, 0);
+       if (!job) {
+               _E("Failed to get job from the storage_job list");
+               return;
+       }
+
+       if (send_storage_notification(job, result) < 0)
+               _E("Failed to send notification");
+
+       _I("Remove Job(%d, %s)", job->type, (job->dev).name);
+
+       DD_LIST_REMOVE(storage_job, job);
+       free(job);
+
+       if (DD_LIST_LENGTH(storage_job) <= 0) {
+               _I("REMOVE storage_job FULL");
+               DD_LIST_FREE_LIST(storage_job);
+               storage_job = NULL;
+               return ;
+       }
+
+       if (trigger_job() < 0)
+               _E("Failed to trigger job");
+
+}
+
+static Eina_Bool job_done(void *data, Ecore_Fd_Handler *fd_handler)
+{
+       int result;
+       int ret, retry;
+
+       update_usbhost_state();
+
+       if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
+               _E("ecore_main_fd_handler_active_get error , return");
+               return EINA_TRUE;
+       }
+
+       retry = 0;
+       do {
+               ret = read(pipe_out[0], &result, sizeof(int));
+               if (ret >= 0)
+                       break;
+               if (errno != EINTR)
+                       goto out;
+       } while (retry++ < RETRY_MAX);
+
+
+       if (result < 0) {
+               /*Error handling*/
+               _E("Job of thread failed (%d)", result);
+       }
+
+out:
+       remove_job(result);
+
+       return EINA_TRUE;
+}
+
+static void subsystem_block_changed (struct udev_device *dev)
+{
+       const char *action = NULL;
+       const char *bus = NULL;
+       int size;
+
+       if (!dev)
+               return;
+
+       if (!is_host_uevent_enabled())
+               return;
+
+       /* Check whether or not the block device is usb device */
+       bus = udev_device_get_property_value(dev, "ID_BUS");
+       if (!bus)
+               return;
+       if (strncmp(bus, "usb", strlen(bus)))
+               return;
+
+
+       action = udev_device_get_property_value(dev, "ACTION");
+       if (!action)
+               return;
+
+       if (!strncmp(action, "add", strlen("add"))) {
+               send_msg_storage_added(false);
+               storage_device_added(dev);
+               return;
+       }
+
+       if (!strncmp(action, "remove", strlen("remove"))) {
+               send_msg_storage_removed(false);
+               storage_device_removed(dev);
+               return;
+       }
+
+       if (!strncmp(action, "change", strlen("change"))) {
+               size = check_changed_storage(dev);
+               _I("block size(%d)", size);
+               if (size > 0) {
+                       send_msg_storage_added(false);
+                       storage_device_added(dev);
+               } else {
+                       if (check_storage_exists(dev)) {
+                               send_msg_storage_removed(false);
+                               storage_device_removed(dev);
+                       }
+               }
+               return;
+       }
+}
+
+static int pipe_start(void)
+{
+       int ret;
+
+       ret = pipe(pipe_out);
+       if (ret < 0) {
+               _E("Failed to make pipe(%d)", ret);
+               return ret;
+       }
+
+       pipe_handler = ecore_main_fd_handler_add(pipe_out[0], ECORE_FD_READ,
+                       job_done, NULL, NULL, NULL);
+       if (!pipe_handler) {
+               _E("Failed to register pipe handler");
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static void pipe_stop(void)
+{
+       if (pipe_handler) {
+               ecore_main_fd_handler_del(pipe_handler);
+               pipe_handler = NULL;
+       }
+
+       if (pipe_out[0] >= 0)
+               close(pipe_out[0]);
+       if (pipe_out[1] >= 0)
+               close(pipe_out[1]);
+}
+
+const static struct uevent_handler uhs_storage[] = {
+       { BLOCK_SUBSYSTEM       ,     subsystem_block_changed       ,    NULL    },
+};
+
+static int usbhost_storage_init_booting_done(void *data)
+{
+       int ret, i;
+
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_storage_init_booting_done);
+
+       for (i = 0 ; i < ARRAY_SIZE(uhs_storage) ; i++) {
+               ret = register_uevent_control(&uhs_storage[i]);
+               if (ret < 0)
+                       _E("FAIL: reg_uevent_control()");
+       }
+
+       ret = pipe_start();
+       if (ret < 0)
+               _E("Failed to make pipe(%d)", ret);
+
+       return 0;
+}
+
+static void usbhost_storage_init(void *data)
+{
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_storage_init_booting_done);
+}
+
+static void usbhost_storage_exit(void *data)
+{
+       int i, ret;
+
+       for (i = 0 ; i < ARRAY_SIZE(uhs_storage) ; i++) {
+               unregister_uevent_control(&uhs_storage[i]);
+       }
+
+       pipe_stop();
+}
+
+static const struct device_ops usbhost_device_storage_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "usbhost_storage",
+       .init     = usbhost_storage_init,
+       .exit     = usbhost_storage_exit,
+};
+
+DEVICE_OPS_REGISTER(&usbhost_device_storage_ops)
diff --git a/src/usb/usb-host.c b/src/usb/usb-host.c
new file mode 100755 (executable)
index 0000000..80c9cf6
--- /dev/null
@@ -0,0 +1,437 @@
+/*
+ * 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 "usb-host.h"
+#include "core/device-notifier.h"
+
+static dd_list *storage_list;
+static dd_list *device_list;
+
+static int noti_id = 0;
+
+struct ticker_data {
+       char *name;
+       int type;
+};
+
+struct popup_data {
+       char *name;
+       char *method;
+       char *key1;
+       char *value1;
+       char *key2;
+       char *value2;
+};
+
+/* Do not handle usb host uevents if host_uevent_enable is false
+ * host_uevent_enable is set to true when usb host connector is connected first*/
+static bool host_uevent_enabled = false;
+
+bool is_host_uevent_enabled(void)
+{
+       return host_uevent_enabled;
+}
+
+int get_storage_list_length(void)
+{
+       return DD_LIST_LENGTH(storage_list);
+}
+
+dd_list *get_storage_list(void)
+{
+       return storage_list;
+}
+
+dd_list *get_device_list(void)
+{
+       return device_list;
+}
+
+void launch_ticker_notification(char *name)
+{
+       struct ticker_data ticker;
+       const struct device_ops *ticker_ops;
+
+       if (!name) {
+               _E("ticker noti name is NULL");
+               return;
+       }
+
+       ticker.name = name;
+       ticker.type = 0; /* WITHOUT_QUEUE */
+
+       ticker_ops = find_device("ticker");
+
+       if (ticker_ops && ticker_ops->init)
+               ticker_ops->init(&ticker);
+       else
+               _E("cannot find \"ticker\" ops");
+}
+
+void launch_host_syspopup(char *name, char *method,
+               char *key1, char *value1,
+               char *key2, char *value2)
+{
+       struct popup_data params;
+       static const struct device_ops *apps = NULL;
+
+       if (!name || !method)
+               return;
+
+       if (apps == NULL) {
+               apps = find_device("apps");
+               if (apps == NULL)
+                       return;
+       }
+
+       params.name = name;
+       params.method = method;
+       params.key1 = key1;
+       params.value1 = value1;
+       params.key2 = key2;
+       params.value2 = value2;
+
+       if (apps->init)
+               apps->init(&params);
+}
+
+static int get_number_of_mounted_storages(void)
+{
+       int num;
+       dd_list *l;
+       struct usb_device *dev;
+
+       if (!storage_list || DD_LIST_LENGTH(storage_list) == 0)
+               return 0;
+
+       num = 0;
+       DD_LIST_FOREACH(storage_list, l, dev) {
+               if (dev && dev->is_mounted)
+                       num++;
+       }
+
+       return num;
+}
+
+void update_usbhost_state(void)
+{
+       int prev, curr;
+
+       if (vconf_get_int(VCONFKEY_SYSMAN_USB_HOST_STATUS, &prev) != 0)
+               prev = -1;
+
+       if (get_number_of_mounted_storages() == 0
+                       && (!device_list || DD_LIST_LENGTH(device_list) == 0))
+               curr = VCONFKEY_SYSMAN_USB_HOST_DISCONNECTED;
+       else
+               curr = VCONFKEY_SYSMAN_USB_HOST_CONNECTED;
+
+       if (prev == curr)
+               return;
+
+       if (vconf_set_int(VCONFKEY_SYSMAN_USB_HOST_STATUS, curr) != 0)
+               _E("Failed to set vconf key");
+}
+
+bool check_same_mntpath(const char *mntpath)
+{
+       dd_list *l;
+       struct usb_device *dev;
+
+       DD_LIST_FOREACH(storage_list, l, dev) {
+               if (!strncmp(dev->mntpath, mntpath, strlen(dev->mntpath)))
+                       return true;
+       }
+       return false;
+}
+
+bool is_storage_mounted(const char *mntpath)
+{
+       dd_list *l;
+       struct usb_device *dev;
+
+       DD_LIST_FOREACH(storage_list, l, dev) {
+               if (!strncmp(dev->mntpath, mntpath, strlen(dev->mntpath)))
+                       break;
+       }
+       if (l && dev)
+               return dev->is_mounted;
+       return false;
+}
+
+static int add_usb_host_device_to_list(int type,
+               const char *name,
+               const char *vendor,
+               const char *model,
+               const char *fstype,
+               char *path)
+{
+       struct usb_device *dev;
+       int id;
+
+       if (!name || type < 0)
+               return -EINVAL;
+
+       if (type == USBHOST_STORAGE && !path)
+               return -EINVAL;
+
+       dev = (struct usb_device *)malloc(sizeof(struct usb_device));
+       if (!dev) {
+               _E("Failed to assign memory");
+               return -ENOMEM;
+       }
+
+       dev->type = type;
+       dev->is_mounted = false;
+       dev->noti_id = 0;
+       snprintf(dev->name, sizeof(dev->name), "%s", name);
+       snprintf(dev->mntpath, sizeof(dev->mntpath), "%s", path);
+
+       if (model)
+               snprintf(dev->model, sizeof(dev->model), "%s", model);
+       else
+               memset(dev->model, 0, sizeof(dev->model));
+
+       if (vendor)
+               snprintf(dev->vendor, sizeof(dev->vendor), "%s", vendor);
+       else
+               memset(dev->vendor, 0, sizeof(dev->vendor));
+
+       if (fstype)
+               snprintf(dev->fs, sizeof(dev->fs), "%s", fstype);
+       else
+               memset(dev->fs, 0, sizeof(dev->fs));
+
+       if (type == USBHOST_STORAGE) {
+               if (!check_same_mntpath(path))
+                       DD_LIST_APPEND(storage_list, dev);
+               else
+                       free(dev);
+       } else {
+               dev->noti_id = activate_device_notification(dev, DD_LIST_LENGTH(device_list));
+               DD_LIST_APPEND(device_list, dev);
+               if (send_device_added_info(dev) < 0)
+                       _E("Failed to send device info");
+       }
+
+       return 0;
+}
+
+int add_usb_storage_to_list(const char *name,
+               const char *vendor,
+               const char *model,
+               const char *fstype)
+{
+       char path[BUF_MAX];
+       int ret;
+
+       if (!name)
+               return -EINVAL;
+
+       ret = get_mount_path(name, path, sizeof(path));
+       if (ret < 0) {
+               _E("Failed to get mount path");
+               return ret;
+       }
+
+       ret = add_usb_host_device_to_list(USBHOST_STORAGE,
+                       name, vendor, model, fstype, path);
+
+       update_usbhost_state();
+
+       return ret;
+}
+
+int add_usb_device_to_list(int type,
+               const char *name,
+               const char *vendor,
+               const char *model)
+{
+       int ret;
+
+       ret = add_usb_host_device_to_list(type,
+                       name, vendor, model, NULL, NULL);
+
+       update_usbhost_state();
+
+       return ret;
+}
+
+int remove_usb_storage_from_list(const char *name)
+{
+       dd_list *l;
+       struct usb_device *dev;
+       bool found;
+
+       if (!name)
+               return -EINVAL;
+
+       found = false;
+       DD_LIST_FOREACH(storage_list, l, dev) {
+               if (strncmp(dev->name, name, strlen(name)))
+                       continue;
+
+               found = true;
+               break;
+       }
+       if (!found) {
+               return -EINVAL;
+       }
+
+       DD_LIST_REMOVE(storage_list, dev);
+       free(dev);
+
+       update_usbhost_state();
+
+       return 0;
+}
+
+int remove_usb_device_from_list(const char *name, int type)
+{
+       dd_list *l;
+       struct usb_device *dev;
+       bool found;
+       int len;
+
+       if (!name)
+               return -EINVAL;
+
+       found = false;
+       DD_LIST_FOREACH(device_list, l, dev) {
+               if (type == USBHOST_PRINTER) {
+                       if (!strstr(name, dev->name))
+                               continue;
+               } else {
+                       if (strncmp(dev->name, name, strlen(name)))
+                               continue;
+               }
+
+               found = true;
+               break;
+       }
+       if (!found) {
+               return -EINVAL;
+       }
+
+       if (send_device_removed_info(dev) < 0)
+               _E("Failed to send device info");
+
+       DD_LIST_REMOVE(device_list, dev);
+       free(dev);
+
+       len = DD_LIST_LENGTH(device_list);
+       if (len <= 0)
+               dev = NULL;
+       else
+               dev = DD_LIST_NTH(device_list, 0); /* First element */
+
+       if (deactivate_device_notification(dev, len))
+               _E("Failed to remove notification");
+
+       update_usbhost_state();
+
+       return 0;
+}
+
+static void subsystem_host_changed (struct udev_device *dev)
+{
+       const char *state = NULL;
+       int ret;
+       static int cradle;
+
+       state = udev_device_get_property_value(dev, UDEV_PROP_KEY_STATE);
+       if (!state)
+               return;
+
+       if (!strncmp(state, UDEV_PROP_VALUE_ADD, strlen(UDEV_PROP_VALUE_ADD))) {
+               _I("USB host connector is added");
+
+               if (!host_uevent_enabled)
+                       host_uevent_enabled = true;
+
+               cradle = get_cradle_status();
+               if (cradle == 0) {
+                       launch_ticker_notification(TICKER_NAME_CONNECTOR_CONNECTED);
+               }
+
+               return;
+       }
+
+       if (!strncmp(state, UDEV_PROP_VALUE_REMOVE, strlen(UDEV_PROP_VALUE_REMOVE))) {
+               _I("USB host connector is removed");
+
+               if (cradle == 0) {
+                       launch_ticker_notification(TICKER_NAME_CONNECTOR_DISCONNECTED);
+               } else {
+                       cradle = 0;
+               }
+
+               return;
+       }
+}
+
+const static struct uevent_handler uhs[] = {
+       { HOST_SUBSYSTEM       ,     subsystem_host_changed       ,    NULL    },
+};
+
+static int usbhost_init_booting_done(void *data)
+{
+       int ret, i;
+
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_init_booting_done);
+
+       for (i = 0 ; i < ARRAY_SIZE(uhs) ; i++) {
+               ret = register_uevent_control(&uhs[i]);
+               if (ret < 0)
+                       _E("FAIL: reg_uevent_control()");
+       }
+
+       if (register_unmount_signal_handler() < 0)
+               _E("Failed to register handler for unmount signal");
+
+       if (register_device_all_signal_handler() < 0)
+               _E("Failed to register handler for device info");
+
+       if (register_usbhost_dbus_methods() < 0)
+               _E("Failed to register dbus handler for usbhost");
+
+       return 0;
+}
+
+static void usbhost_init(void *data)
+{
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE, usbhost_init_booting_done);
+}
+
+static void usbhost_exit(void *data)
+{
+       int i;
+
+       for (i = 0 ; i < ARRAY_SIZE(uhs) ; i++) {
+               unregister_uevent_control(&uhs[i]);
+       }
+}
+
+static const struct device_ops usbhost_device_ops = {
+       .priority = DEVICE_PRIORITY_NORMAL,
+       .name     = "usbhost",
+       .init     = usbhost_init,
+       .exit     = usbhost_exit,
+};
+
+DEVICE_OPS_REGISTER(&usbhost_device_ops)
diff --git a/src/usb/usb-host.h b/src/usb/usb-host.h
new file mode 100755 (executable)
index 0000000..a89d9b8
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * 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 __USB_HOST_H__
+#define __USB_HOST_H__
+
+#include <stdbool.h>
+#include "core/udev.h"
+#include "core/log.h"
+#include "core/devices.h"
+#include "display/poll.h"
+#include "core/udev.h"
+#include "core/common.h"
+#include "core/list.h"
+#include "usb-common.h"
+
+#define BLOCK_SUBSYSTEM           "block"
+#define INPUT_SUBSYSTEM           "input"
+#define USB_SUBSYSTEM             "usb"
+
+#define UDEV_PROP_KEY_STATE       "STATE"
+#define UDEV_PROP_VALUE_ADD       "ADD"
+#define UDEV_PROP_VALUE_REMOVE    "REMOVE"
+
+#define TICKER_NAME_CONNECTOR_CONNECTED         "connector-connected"
+#define TICKER_NAME_CONNECTOR_DISCONNECTED      "connector-disconnected"
+#define TICKER_NAME_STORAGE_CONNECTED           "storage-connected"
+#define TICKER_NAME_STORAGE_RO_CONNECTED        "storage-ro-connected"
+#define TICKER_NAME_STORAGE_DISCONNECTED_SAFE   "storage-disconnected-safe"
+#define TICKER_NAME_STORAGE_DISCONNECTED_UNSAFE "storage-disconnected-unsafe"
+#define TICKER_NAME_KEYBOARD_CONNECTED          "keyboard-connected"
+#define TICKER_NAME_MOUSE_CONNECTED             "mouse-connected"
+#define TICKER_NAME_CAMERA_CONNECTED            "camera-connected"
+#define TICKER_NAME_PRINTER_CONNECTED           "printer-connected"
+#define TICKER_NAME_DEVICE_DISCONNECTED         "device-disconnected"
+
+#define BUF_MAX 256
+#define RETRY_MAX 5
+
+enum action_type {
+       STORAGE_ADD,
+       STORAGE_REMOVE,
+       STORAGE_MOUNT,
+       STORAGE_UNMOUNT,
+       STORAGE_FORMAT,
+};
+
+struct pipe_data {
+       int type;
+       int result;
+       void *data;
+};
+
+struct usb_device {
+       int type;
+       char name[BUF_MAX];
+       char mntpath[BUF_MAX];
+       char vendor[BUF_MAX];
+       char model[BUF_MAX];
+       char fs[BUF_MAX];
+       bool is_mounted;
+       int noti_id;
+};
+
+struct storage_fs_ops {
+       char *name;
+       int (*check)(const char *devname);
+       int (*mount)(bool smack, const char *devname, const char *mount_point);
+       int (*mount_rdonly)(bool smack, const char *devname, const char *mount_point);
+       int (*format)(const char *path);
+};
+
+enum usb_host_type {
+       USBHOST_KEYBOARD,
+       USBHOST_MOUSE,
+       USBHOST_STORAGE,
+       USBHOST_CAMERA,
+       USBHOST_PRINTER,
+       USBHOST_UNKNOWN,
+       /* add type of usb host */
+       USBHOST_TYPE_MAX,
+};
+
+enum mount_type {
+       STORAGE_MOUNT_RW,
+       STORAGE_MOUNT_RO,
+};
+
+enum device_state {
+       DEVICE_DISCONNECTED = 0,
+       DEVICE_CONNECTED = 1,
+};
+
+void launch_ticker_notification(char *name);
+bool is_host_uevent_enabled(void);
+dd_list *get_device_list(void);
+dd_list *get_storage_list(void);
+int get_mount_path(const char *name, char *path, int len);
+int get_devname_by_path(char *path, char *name, int len);
+bool check_same_mntpath(const char *mntpath);
+bool is_storage_mounted(const char *mntpath);
+void update_usbhost_state(void);
+
+void register_fs(const struct storage_fs_ops *ops);
+void unregister_fs(const struct storage_fs_ops *ops);
+
+int get_storage_list_length(void);
+
+/* Add/Remove usb storage to list */
+int add_usb_storage_to_list(const char *name,
+               const char *vendor,
+               const char *model,
+               const char *fstype);
+int remove_usb_storage_from_list(const char *name);
+
+/* Add/Remove usb device to list */
+int add_usb_device_to_list(int type,
+               const char *name,
+               const char *vendor,
+               const char *model);
+int remove_usb_device_from_list(const char *name, int type);
+
+/* Mount/Unmount usb storge */
+int mount_usb_storage(const char *name);
+int unmount_usb_storage(const char *path, bool safe);
+
+void launch_host_syspopup(char *name, char *method,
+               char *key1, char *value1, char *key2, char *value2);
+
+/* Thread Job */
+int add_job(int type, struct usb_device *dev, bool safe);
+
+/* Device changed signal */
+void send_msg_storage_added(bool mount);
+void send_msg_storage_removed(bool mount);
+void send_msg_keyboard_added(void);
+void send_msg_keyboard_removed(void);
+void send_msg_mouse_added(void);
+void send_msg_mouse_removed(void);
+void send_msg_camera_added(void);
+void send_msg_camera_removed(void);
+
+/* Ongoing notification */
+int activate_storage_notification(char *path, int mount_type);
+int deactivate_storage_notification(int id);
+int activate_device_notification(struct usb_device *dev, int len);
+int deactivate_device_notification(struct usb_device *dev, int len);
+
+/* Unmount signal handler */
+int register_unmount_signal_handler(void);
+int unmount_storage_by_dbus_signal(char *path);
+
+/* device info signal handler */
+int register_device_all_signal_handler(void);
+int send_device_added_info(struct usb_device *dev);
+int send_device_removed_info(struct usb_device *dev);
+int register_usbhost_dbus_methods(void);
+int send_storage_changed_info(struct usb_device *dev, char *type);
+
+/* Vendor, model name */
+int verify_vendor_name(const char *vendor, char *buf, int len);
+int verify_model_name(const char *model, char *vendor, char *buf, int len);
+
+#endif /* __USB_HOST_H__ */
diff --git a/test/_export_env.sh b/test/_export_env.sh
new file mode 100755 (executable)
index 0000000..72a11ec
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+. ./config
+export TET_INSTALL_PATH=$TET_INSTALL_HOST_PATH # tetware root path
+export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target # tetware target path
+export PATH=$TET_TARGET_PATH/bin:$PATH
+export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH
+export TET_ROOT=$TET_TARGET_PATH
diff --git a/test/_export_target_env.sh b/test/_export_target_env.sh
new file mode 100755 (executable)
index 0000000..5ddaa53
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/sh
+. ./config
+export TET_INSTALL_PATH=$TET_INSTALL_TARGET_PATH # path to path
+export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target
+export PATH=$TET_TARGET_PATH/bin:$PATH
+export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH
+export TET_ROOT=$TET_TARGET_PATH
diff --git a/test/build.sh b/test/build.sh
new file mode 100755 (executable)
index 0000000..d58c039
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+. ./_export_env.sh                              # setting environment variables
+
+export TET_SUITE_ROOT=`pwd`
+FILE_NAME_EXTENSION=`date +%s`
+
+RESULT_DIR=results
+HTML_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.html
+JOURNAL_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.journal
+
+mkdir -p $RESULT_DIR
+
+tcc -c -p ./
+tcc -b -j $JOURNAL_RESULT -p ./
+grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT
diff --git a/test/clean.sh b/test/clean.sh
new file mode 100755 (executable)
index 0000000..29743e0
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+. ./_export_env.sh                              # setting environment variables
+
+export TET_SUITE_ROOT=`pwd`
+RESULT_DIR=results
+
+tcc -c -p ./                                # executing tcc, with clean option (-c)
+rm -r $RESULT_DIR
+rm -r tet_tmp_dir
+rm testcase/tet_captured
diff --git a/test/config b/test/config
new file mode 100644 (file)
index 0000000..457c529
--- /dev/null
@@ -0,0 +1,3 @@
+PKG_NAME=deviced
+TET_INSTALL_HOST_PATH=/var/tmp/dts_fw/TETware
+TET_INSTALL_TARGET_PATH=/opt/home/TETware
diff --git a/test/execute.sh b/test/execute.sh
new file mode 100755 (executable)
index 0000000..a4f6095
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+. ./_export_target_env.sh                    # setting environment variables
+
+export TET_SUITE_ROOT=`pwd`
+FILE_NAME_EXTENSION=`date +%s`
+
+RESULT_DIR=results
+HTML_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.html
+JOURNAL_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.journal
+
+mkdir -p $RESULT_DIR
+
+tcc -e -j $JOURNAL_RESULT -p ./
+grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT
diff --git a/test/push.sh b/test/push.sh
new file mode 100755 (executable)
index 0000000..2bbab27
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+. ./config
+
+TC_PATH=/opt/home/$PKG_NAME
+
+echo $TC_PATH
+
+sdb root on
+sdb shell "mkdir -p $TC_PATH"
+sdb push . $TC_PATH
diff --git a/test/testcase/Makefile b/test/testcase/Makefile
new file mode 100644 (file)
index 0000000..db70570
--- /dev/null
@@ -0,0 +1,28 @@
+CC = gcc
+
+C_FILES = $(shell ls *.c)
+
+PKGS = deviced
+
+#TET_ROOT = /home/idkiller/work/tetware/TETware/tetware-target
+
+LDFLAGS += $(TET_ROOT)/lib/tet3/tcm_s.o
+LDFLAGS += -L$(TET_ROOT)/lib/tet3 -ltcm_s
+LDFLAGS += -L$(TET_ROOT)/lib/tet3 -lapi_s
+LDFLAGS += `pkg-config --libs $(PKGS)`
+
+CFLAGS += `pkg-config --cflags $(PKGS)`
+CFLAGS += -I.
+CFLAGS += -I$(TET_ROOT)/inc/tet3
+CFLAGS += -Wall
+
+#TARGETS = $(C_FILES:%.c=tc-%)
+TCS := $(shell ls -1 *.c | cut -d. -f1)
+
+all: $(TCS)
+
+%: %.c
+       $(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
+
+clean:
+       rm -f $(TCS)
diff --git a/test/testcase/tslist b/test/testcase/tslist
new file mode 100644 (file)
index 0000000..cc10762
--- /dev/null
@@ -0,0 +1,10 @@
+/testcase/utc_system_deviced_battery
+/testcase/utc_system_deviced_control
+/testcase/utc_system_deviced_deviced
+/testcase/utc_system_deviced_deviced_managed
+/testcase/utc_system_deviced_display
+/testcase/utc_system_deviced_haptic
+/testcase/utc_system_deviced_led
+/testcase/utc_system_deviced_mmc
+/testcase/utc_system_deviced_storage
+
diff --git a/test/testcase/utc_system_deviced_battery.c b/test/testcase/utc_system_deviced_battery.c
new file mode 100644 (file)
index 0000000..83eea6a
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of SAMSUNG
+ * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
+ * this software is owned by Samsung and you shall not disclose such
+ * Confidential Information and shall use it only in accordance with the terms
+ * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
+ * make no representations or warranties about the suitability of the software,
+ * either express or implied, including but not limited to the implied
+ * warranties of merchantability, fitness for a particular purpose, or
+ * non-infringement. SAMSUNG shall not be liable for any damages suffered by
+ * licensee arising out of or related to this software.
+ *
+ */
+#include <tet_api.h>
+#include <dd-battery.h>
+
+#define API_NAME_BATTERY_GET_PERCENT "battery_get_percent"
+#define API_NAME_BATTERY_GET_PERCENT_RAW "battery_get_percent_raw"
+#define API_NAME_BATTERY_IS_FULL "battery_is_full"
+#define API_NAME_BATTERY_GET_HEALTH "battery_get_health"
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+
+static void utc_system_deviced_battery_get_percent_p(void);
+static void utc_system_deviced_battery_get_percent_raw_p(void);
+static void utc_system_deviced_battery_is_full_p(void);
+static void utc_system_deviced_battery_get_health_p(void);
+
+enum {
+       POSITIVE_TC_IDX = 0x01,
+       NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+       { utc_system_deviced_battery_get_percent_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_battery_get_percent_raw_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_battery_is_full_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_battery_get_health_p, POSITIVE_TC_IDX },
+       { NULL, 0 },
+};
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of battery_get_percent()
+ */
+static void utc_system_deviced_battery_get_percent_p(void)
+{
+       int ret;
+
+       ret = battery_get_percent();
+       dts_check_ge(API_NAME_BATTERY_GET_PERCENT, ret, 0);
+}
+
+/**
+ * @brief Positive test case of battery_get_percent_raw()
+ */
+static void utc_system_deviced_battery_get_percent_raw_p(void)
+{
+       int ret;
+
+       ret = battery_get_percent_raw();
+       dts_check_ge(API_NAME_BATTERY_GET_PERCENT_RAW, ret, 0);
+}
+
+/**
+ * @brief Positive test case of battery_is_full()
+ */
+static void utc_system_deviced_battery_is_full_p(void)
+{
+       int ret;
+
+       ret = battery_is_full();
+       dts_check_ge(API_NAME_BATTERY_IS_FULL, ret, 0);
+}
+
+/**
+ * @brief Positive test case of battery_get_health()
+ */
+static void utc_system_deviced_battery_get_health_p(void)
+{
+       int ret;
+
+       ret = battery_get_health();
+       dts_check_ge(API_NAME_BATTERY_GET_HEALTH, ret, 0);
+}
diff --git a/test/testcase/utc_system_deviced_control.c b/test/testcase/utc_system_deviced_control.c
new file mode 100644 (file)
index 0000000..ab12ade
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of SAMSUNG
+ * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
+ * this software is owned by Samsung and you shall not disclose such
+ * Confidential Information and shall use it only in accordance with the terms
+ * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
+ * make no representations or warranties about the suitability of the software,
+ * either express or implied, including but not limited to the implied
+ * warranties of merchantability, fitness for a particular purpose, or
+ * non-infringement. SAMSUNG shall not be liable for any damages suffered by
+ * licensee arising out of or related to this software.
+ *
+ */
+#include <tet_api.h>
+#include <dd-control.h>
+
+#define API_NAME_DEVICED_MMC_CONTROL "deviced_mmc_control"
+#define API_NAME_DEVICED_USB_CONTROL "deviced_usb_control"
+#define API_NAME_DEVICED_GET_USB_CONTROL "deviced_get_usb_control"
+#define API_NAME_DEVICED_RGBLED_CONTROL "deviced_rgbled_control"
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+
+static void utc_system_deviced_deviced_mmc_control_p_1(void);
+static void utc_system_deviced_deviced_mmc_control_p_2(void);
+static void utc_system_deviced_deviced_usb_control_p_1(void);
+static void utc_system_deviced_deviced_usb_control_p_2(void);
+static void utc_system_deviced_deviced_get_usb_control_p(void);
+static void utc_system_deviced_deviced_rgbled_control_p_1(void);
+static void utc_system_deviced_deviced_rgbled_control_p_2(void);
+static void utc_system_deviced_deviced_rgbled_control_n(void);
+
+enum {
+       POSITIVE_TC_IDX = 0x01,
+       NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+       { utc_system_deviced_deviced_mmc_control_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_mmc_control_p_2, POSITIVE_TC_IDX },
+//     { utc_system_deviced_deviced_usb_control_p_1, POSITIVE_TC_IDX },
+//     { utc_system_deviced_deviced_usb_control_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_get_usb_control_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_rgbled_control_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_rgbled_control_p_2, POSITIVE_TC_IDX },
+       { NULL, 0 },
+};
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of deviced_mmc_control()
+ */
+static void utc_system_deviced_deviced_mmc_control_p_1(void)
+{
+       int ret;
+
+       ret = deviced_mmc_control(false);
+       dts_check_eq(API_NAME_DEVICED_MMC_CONTROL, ret, 0, "Disable MMC");
+}
+
+/**
+ * @brief Positive test case of deviced_mmc_control()
+ */
+static void utc_system_deviced_deviced_mmc_control_p_2(void)
+{
+       int ret;
+
+       ret = deviced_mmc_control(true);
+       dts_check_eq(API_NAME_DEVICED_MMC_CONTROL, ret, 0, "Enable MMC");
+}
+
+/**
+ * @brief Positive test case of deviced_usb_control()
+ */
+static void utc_system_deviced_deviced_usb_control_p_1(void)
+{
+       int ret;
+
+       ret = deviced_usb_control(false);
+       dts_check_eq(API_NAME_DEVICED_USB_CONTROL, ret, 0, "Disable USB");
+}
+
+/**
+ * @brief Positive test case of deviced_usb_control()
+ */
+static void utc_system_deviced_deviced_usb_control_p_2(void)
+{
+       int ret;
+
+       ret = deviced_usb_control(true);
+       dts_check_eq(API_NAME_DEVICED_USB_CONTROL, ret, 0, "Enable USB");
+}
+
+/**
+ * @brief Positive test case of deviced_get_usb_control()
+ */
+static void utc_system_deviced_deviced_get_usb_control_p(void)
+{
+       int ret;
+
+       ret = deviced_get_usb_control();
+       dts_check_ge(API_NAME_DEVICED_GET_USB_CONTROL, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_rgbled_control()
+ */
+static void utc_system_deviced_deviced_rgbled_control_p_1(void)
+{
+       int ret;
+
+       ret = deviced_rgbled_control(false);
+       dts_check_eq(API_NAME_DEVICED_RGBLED_CONTROL, ret, 0, "Disable RGB led");
+}
+
+/**
+ * @brief Positive test case of deviced_rgbled_control()
+ */
+static void utc_system_deviced_deviced_rgbled_control_p_2(void)
+{
+       int ret;
+
+       ret = deviced_rgbled_control(true);
+       dts_check_eq(API_NAME_DEVICED_USB_CONTROL, ret, 0, "Enable RGB led");
+}
diff --git a/test/testcase/utc_system_deviced_deviced.c b/test/testcase/utc_system_deviced_deviced.c
new file mode 100644 (file)
index 0000000..6782bbf
--- /dev/null
@@ -0,0 +1,714 @@
+/*
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of SAMSUNG
+ * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
+ * this software is owned by Samsung and you shall not disclose such
+ * Confidential Information and shall use it only in accordance with the terms
+ * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
+ * make no representations or warranties about the suitability of the software,
+ * either express or implied, including but not limited to the implied
+ * warranties of merchantability, fitness for a particular purpose, or
+ * non-infringement. SAMSUNG shall not be liable for any damages suffered by
+ * licensee arising out of or related to this software.
+ *
+ */
+#include <tet_api.h>
+#include <dd-deviced.h>
+
+#define API_NAME_DEVICED_GET_CMDLINE_NAME "deviced_get_cmdline_name"
+#define API_NAME_DEVICED_GET_APPPATH "deviced_get_apppath"
+#define API_NAME_DEVICED_CONF_SET_MEMPOLICY "deviced_conf_set_mempolicy"
+#define API_NAME_DEVICED_CONF_SET_MEMPOLICY_BYPID "deviced_conf_set_mempolicy_bypid"
+#define API_NAME_DEVICED_CONF_SET_PERMANENT "deviced_conf_set_permanent"
+#define API_NAME_DEVICED_CONF_SET_PERMANENT_BYPID "deviced_conf_set_permanent_bypid"
+#define API_NAME_DEVICED_CONF_SET_VIP "deviced_conf_set_vip"
+#define API_NAME_DEVICED_CONF_IS_VIP "deviced_conf_is_vip"
+#define API_NAME_DEVICED_SET_TIMEZONE "deviced_set_timezone"
+#define API_NAME_DEVICED_INFORM_FOREGRD "deviced_inform_foregrd"
+#define API_NAME_DEVICED_INFORM_BACKGRD "deviced_inform_backgrd"
+#define API_NAME_DEVICED_INFORM_ACTIVE "deviced_inform_active"
+#define API_NAME_DEVICED_INFORM_INACTIVE "deviced_inform_active"
+#define API_NAME_DEVICED_REQUEST_POWEROFF "deviced_request_poweroff"
+#define API_NAME_DEVICED_REQUEST_ENTERSLEEP "deviced_request_entersleep"
+#define API_NAME_DEVICED_REQUEST_LEAVESLEEP "deviced_request_leavesleep"
+#define API_NAME_DEVICED_REQUEST_REBOOT "deviced_request_reboot"
+#define API_NAME_DEVICED_REQUEST_SET_CPU_MAX_FREQUENCY "deviced_request_set_cpu_max_frequency"
+#define API_NAME_DEVICED_REQUEST_SET_CPU_MIN_FREQUENCY "deviced_request_set_cpu_min_frequency"
+#define API_NAME_DEVICED_RELEASE_CPU_MAX_FREQUENCY "deviced_release_cpu_max_frequency"
+#define API_NAME_DEVICED_RELEASE_CPU_MIN_FREQUENCY "deviced_release_cpu_min_frequency"
+#define API_NAME_DEVICED_REQUEST_SET_FACTORY_MODE "deviced_request_set_factory_mode"
+#define API_NAME_DEVICED_REQUEST_DUMP_LOG "deviced_request_dump_log"
+#define API_NAME_DEVICED_REQUEST_DELETE_DUMP "deviced_request_delete_dump"
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+
+static void utc_system_deviced_deviced_get_cmdline_name_p(void);
+static void utc_system_deviced_deviced_get_cmdline_name_n_1(void);
+static void utc_system_deviced_deviced_get_cmdline_name_n_2(void);
+static void utc_system_deviced_deviced_get_cmdline_name_n_3(void);
+static void utc_system_deviced_deviced_get_apppath_p(void);
+static void utc_system_deviced_deviced_get_apppath_n_1(void);
+static void utc_system_deviced_deviced_get_apppath_n_2(void);
+static void utc_system_deviced_deviced_get_apppath_n_3(void);
+static void utc_system_deviced_deviced_conf_set_mempolicy_p(void);
+static void utc_system_deviced_deviced_conf_set_mempolicy_n(void);
+static void utc_system_deviced_deviced_conf_set_mempolicy_bypid_p(void);
+static void utc_system_deviced_deviced_conf_set_mempolicy_bypid_n_1(void);
+static void utc_system_deviced_deviced_conf_set_mempolicy_bypid_n_2(void);
+static void utc_system_deviced_deviced_conf_set_permanent_p(void);
+static void utc_system_deviced_deviced_conf_set_permanent_bypid_p(void);
+static void utc_system_deviced_deviced_conf_set_permanent_bypid_n(void);
+static void utc_system_deviced_deviced_conf_set_vip_p(void);
+static void utc_system_deviced_deviced_conf_set_vip_n(void);
+static void utc_system_deviced_deviced_conf_is_vip_p(void);
+static void utc_system_deviced_deviced_conf_is_vip_n(void);
+static void utc_system_deviced_deviced_set_timezone_p(void);
+static void utc_system_deviced_deviced_set_timezone_n(void);
+static void utc_system_deviced_deviced_inform_foregrd_p(void);
+static void utc_system_deviced_deviced_inform_backgrd_p(void);
+static void utc_system_deviced_deviced_inform_active_p(void);
+static void utc_system_deviced_deviced_inform_active_n(void);
+static void utc_system_deviced_deviced_inform_inactive_p(void);
+static void utc_system_deviced_deviced_inform_inactive_n(void);
+static void utc_system_deviced_deviced_request_poweroff_p(void);
+static void utc_system_deviced_deviced_request_entersleep_p(void);
+static void utc_system_deviced_deviced_request_leavesleep_p(void);
+static void utc_system_deviced_deviced_request_reboot_p(void);
+static void utc_system_deviced_deviced_request_set_cpu_max_frequency_p(void);
+static void utc_system_deviced_deviced_request_set_cpu_max_frequency_n(void);
+static void utc_system_deviced_deviced_request_set_cpu_min_frequency_p(void);
+static void utc_system_deviced_deviced_request_set_cpu_min_frequency_n(void);
+static void utc_system_deviced_deviced_release_cpu_max_frequency_p(void);
+static void utc_system_deviced_deviced_release_cpu_min_frequency_p(void);
+static void utc_system_deviced_deviced_request_set_factory_mode_p_1(void);
+static void utc_system_deviced_deviced_request_set_factory_mode_p_2(void);
+static void utc_system_deviced_deviced_request_set_factory_mode_n(void);
+static void utc_system_deviced_deviced_request_dump_log_p_1(void);
+static void utc_system_deviced_deviced_request_dump_log_p_2(void);
+static void utc_system_deviced_deviced_request_dump_log_n(void);
+static void utc_system_deviced_deviced_request_delete_dump_p(void);
+static void utc_system_deviced_deviced_request_delete_dump_n(void);
+
+enum {
+       POSITIVE_TC_IDX = 0x01,
+       NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+       { utc_system_deviced_deviced_get_cmdline_name_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_get_cmdline_name_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_get_cmdline_name_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_get_cmdline_name_n_3, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_get_apppath_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_get_apppath_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_get_apppath_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_get_apppath_n_3, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_conf_set_mempolicy_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_conf_set_mempolicy_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_conf_set_mempolicy_bypid_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_conf_set_mempolicy_bypid_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_conf_set_mempolicy_bypid_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_conf_set_permanent_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_conf_set_permanent_bypid_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_conf_set_permanent_bypid_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_conf_set_vip_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_conf_set_vip_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_conf_is_vip_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_conf_is_vip_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_set_timezone_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_set_timezone_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_inform_foregrd_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_inform_backgrd_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_inform_active_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_inform_active_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_inform_inactive_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_inform_inactive_n, NEGATIVE_TC_IDX },
+//     { utc_system_deviced_deviced_request_poweroff_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_entersleep_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_leavesleep_p, POSITIVE_TC_IDX },
+//     { utc_system_deviced_deviced_request_reboot_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_set_cpu_max_frequency_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_set_cpu_max_frequency_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_set_cpu_min_frequency_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_set_cpu_min_frequency_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_release_cpu_max_frequency_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_release_cpu_min_frequency_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_set_factory_mode_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_set_factory_mode_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_set_factory_mode_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_dump_log_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_dump_log_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_dump_log_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_delete_dump_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_delete_dump_n, NEGATIVE_TC_IDX },
+       { NULL, 0 },
+};
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of deviced_get_cmdline_name()
+ */
+static void utc_system_deviced_deviced_get_cmdline_name_p(void)
+{
+       pid_t pid;
+       char str[1024];
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_get_cmdline_name(pid, str, sizeof(str));
+       dts_check_eq(API_NAME_DEVICED_GET_CMDLINE_NAME, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_get_cmdline_name()
+ */
+static void utc_system_deviced_deviced_get_cmdline_name_n_1(void)
+{
+       char str[1024];
+       int ret;
+
+       ret = deviced_get_cmdline_name(-1, str, sizeof(str));
+       dts_check_ne(API_NAME_DEVICED_GET_CMDLINE_NAME, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_get_cmdline_name()
+ */
+static void utc_system_deviced_deviced_get_cmdline_name_n_2(void)
+{
+       pid_t pid;
+       char str[1024];
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_get_cmdline_name(pid, NULL, sizeof(str));
+       dts_check_ne(API_NAME_DEVICED_GET_CMDLINE_NAME, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_get_cmdline_name()
+ */
+static void utc_system_deviced_deviced_get_cmdline_name_n_3(void)
+{
+       pid_t pid;
+       char str[1024];
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_get_cmdline_name(pid, str, -1);
+       dts_check_ne(API_NAME_DEVICED_GET_CMDLINE_NAME, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_get_apppath()
+ */
+static void utc_system_deviced_deviced_get_apppath_p(void)
+{
+       pid_t pid;
+       char str[1024];
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_get_apppath(pid, str, sizeof(str));
+       dts_check_eq(API_NAME_DEVICED_GET_APPPATH, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_get_apppath()
+ */
+static void utc_system_deviced_deviced_get_apppath_n_1(void)
+{
+       char str[1024];
+       int ret;
+
+       ret = deviced_get_apppath(-1, str, sizeof(str));
+       dts_check_ne(API_NAME_DEVICED_GET_APPPATH, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_get_apppath()
+ */
+static void utc_system_deviced_deviced_get_apppath_n_2(void)
+{
+       pid_t pid;
+       char str[1024];
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_get_apppath(pid, NULL, sizeof(str));
+       dts_check_ne(API_NAME_DEVICED_GET_APPPATH, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_get_apppath()
+ */
+static void utc_system_deviced_deviced_get_apppath_n_3(void)
+{
+       pid_t pid;
+       char str[1024];
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_get_apppath(pid, str, -1);
+       dts_check_ne(API_NAME_DEVICED_GET_APPPATH, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_conf_set_mempolicy()
+ */
+static void utc_system_deviced_deviced_conf_set_mempolicy_p(void)
+{
+       int ret;
+
+       ret = deviced_conf_set_mempolicy(OOM_LIKELY);
+       dts_check_eq(API_NAME_DEVICED_CONF_SET_MEMPOLICY, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_conf_set_mempolicy()
+ */
+static void utc_system_deviced_deviced_conf_set_mempolicy_n(void)
+{
+       int ret;
+
+       ret = deviced_conf_set_mempolicy(-1);
+       dts_check_ne(API_NAME_DEVICED_CONF_SET_MEMPOLICY, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_conf_set_mempolicy_bypid()
+ */
+static void utc_system_deviced_deviced_conf_set_mempolicy_bypid_p(void)
+{
+       pid_t pid;
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_conf_set_mempolicy_bypid(pid, OOM_LIKELY);
+       dts_check_eq(API_NAME_DEVICED_CONF_SET_MEMPOLICY_BYPID, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_conf_set_mempolicy_bypid()
+ */
+static void utc_system_deviced_deviced_conf_set_mempolicy_bypid_n_1(void)
+{
+       int ret;
+
+       ret = deviced_conf_set_mempolicy_bypid(-1, OOM_LIKELY);
+       dts_check_ne(API_NAME_DEVICED_CONF_SET_MEMPOLICY_BYPID, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_conf_set_mempolicy_bypid()
+ */
+static void utc_system_deviced_deviced_conf_set_mempolicy_bypid_n_2(void)
+{
+       pid_t pid;
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_conf_set_mempolicy_bypid(pid, -1);
+       dts_check_ne(API_NAME_DEVICED_CONF_SET_MEMPOLICY_BYPID, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_conf_set_permanent()
+ */
+static void utc_system_deviced_deviced_conf_set_permanent_p(void)
+{
+       int ret;
+
+       ret = deviced_conf_set_permanent();
+       dts_check_eq(API_NAME_DEVICED_CONF_SET_PERMANENT, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_conf_set_permanent_bypid()
+ */
+static void utc_system_deviced_deviced_conf_set_permanent_bypid_p(void)
+{
+       pid_t pid;
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_conf_set_permanent_bypid(pid);
+       dts_check_eq(API_NAME_DEVICED_CONF_SET_PERMANENT_BYPID, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_conf_set_permanent_bypid()
+ */
+static void utc_system_deviced_deviced_conf_set_permanent_bypid_n(void)
+{
+       int ret;
+
+       ret = deviced_conf_set_permanent_bypid(-1);
+       dts_check_ne(API_NAME_DEVICED_CONF_SET_PERMANENT_BYPID, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_conf_set_vip()
+ */
+static void utc_system_deviced_deviced_conf_set_vip_p(void)
+{
+       pid_t pid;
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_conf_set_vip(pid);
+       dts_check_eq(API_NAME_DEVICED_CONF_SET_VIP, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_conf_set_vip()
+ */
+static void utc_system_deviced_deviced_conf_set_vip_n(void)
+{
+       int ret;
+
+       ret = deviced_conf_set_vip(-1);
+       dts_check_ne(API_NAME_DEVICED_CONF_SET_VIP, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_conf_is_vip()
+ */
+static void utc_system_deviced_deviced_conf_is_vip_p(void)
+{
+       pid_t pid;
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_conf_is_vip(pid);
+       dts_check_ge(API_NAME_DEVICED_CONF_IS_VIP, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_conf_is_vip()
+ */
+static void utc_system_deviced_deviced_conf_is_vip_n(void)
+{
+       int ret;
+
+       ret = deviced_conf_is_vip(-1);
+       dts_check_lt(API_NAME_DEVICED_CONF_IS_VIP, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_set_timezone()
+ */
+static void utc_system_deviced_deviced_set_timezone_p(void)
+{
+       int ret;
+
+       ret = deviced_set_timezone("/usr/share/zoneinfo/Asia/Seoul");
+       dts_check_eq(API_NAME_DEVICED_SET_TIMEZONE, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_set_timezone()
+ */
+static void utc_system_deviced_deviced_set_timezone_n(void)
+{
+       int ret;
+
+       ret = deviced_set_timezone(NULL);
+       dts_check_ne(API_NAME_DEVICED_SET_TIMEZONE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_inform_foregrd()
+ */
+static void utc_system_deviced_deviced_inform_foregrd_p(void)
+{
+       int ret;
+
+       ret = deviced_inform_foregrd();
+       dts_check_eq(API_NAME_DEVICED_INFORM_FOREGRD, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_inform_backgrd()
+ */
+static void utc_system_deviced_deviced_inform_backgrd_p(void)
+{
+       int ret;
+
+       ret = deviced_inform_backgrd();
+       dts_check_eq(API_NAME_DEVICED_INFORM_BACKGRD, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_inform_active()
+ */
+static void utc_system_deviced_deviced_inform_active_p(void)
+{
+       pid_t pid;
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_inform_active(pid);
+       dts_check_eq(API_NAME_DEVICED_INFORM_ACTIVE, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_inform_active()
+ */
+static void utc_system_deviced_deviced_inform_active_n(void)
+{
+       int ret;
+
+       ret = deviced_inform_active(-1);
+       dts_check_ne(API_NAME_DEVICED_INFORM_ACTIVE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_inform_inactive()
+ */
+static void utc_system_deviced_deviced_inform_inactive_p(void)
+{
+       pid_t pid;
+       int ret;
+
+       pid = getpid();
+
+       ret = deviced_inform_inactive(pid);
+       dts_check_eq(API_NAME_DEVICED_INFORM_INACTIVE, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_inform_inactive()
+ */
+static void utc_system_deviced_deviced_inform_inactive_n(void)
+{
+       int ret;
+
+       ret = deviced_inform_inactive(-1);
+       dts_check_ne(API_NAME_DEVICED_INFORM_INACTIVE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_request_poweroff()
+ */
+static void utc_system_deviced_deviced_request_poweroff_p(void)
+{
+       int ret;
+
+       ret = deviced_request_poweroff();
+       dts_check_eq(API_NAME_DEVICED_REQUEST_POWEROFF, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_request_entersleep()
+ */
+static void utc_system_deviced_deviced_request_entersleep_p(void)
+{
+       int ret;
+
+       ret = deviced_request_entersleep();
+       dts_check_eq(API_NAME_DEVICED_REQUEST_ENTERSLEEP, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_request_leavesleep()
+ */
+static void utc_system_deviced_deviced_request_leavesleep_p(void)
+{
+       int ret;
+
+       ret = deviced_request_leavesleep();
+       dts_check_eq(API_NAME_DEVICED_REQUEST_LEAVESLEEP, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_request_reboot()
+ */
+static void utc_system_deviced_deviced_request_reboot_p(void)
+{
+       int ret;
+
+       ret = deviced_request_reboot();
+       dts_check_eq(API_NAME_DEVICED_REQUEST_REBOOT, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_request_set_cpu_max_frequency()
+ */
+static void utc_system_deviced_deviced_request_set_cpu_max_frequency_p(void)
+{
+       int ret;
+
+       ret = deviced_request_set_cpu_max_frequency(60);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_SET_CPU_MAX_FREQUENCY, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_request_set_cpu_max_frequency()
+ */
+static void utc_system_deviced_deviced_request_set_cpu_max_frequency_n(void)
+{
+       int ret;
+
+       ret = deviced_request_set_cpu_max_frequency(-1);
+       dts_check_ne(API_NAME_DEVICED_REQUEST_SET_CPU_MAX_FREQUENCY, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_request_set_cpu_min_frequency()
+ */
+static void utc_system_deviced_deviced_request_set_cpu_min_frequency_p(void)
+{
+       int ret;
+
+       ret = deviced_request_set_cpu_min_frequency(60);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_SET_CPU_MIN_FREQUENCY, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_request_set_cpu_min_frequency()
+ */
+static void utc_system_deviced_deviced_request_set_cpu_min_frequency_n(void)
+{
+       int ret;
+
+       ret = deviced_request_set_cpu_min_frequency(-1);
+       dts_check_ne(API_NAME_DEVICED_REQUEST_SET_CPU_MIN_FREQUENCY, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_release_cpu_max_frequency()
+ */
+static void utc_system_deviced_deviced_release_cpu_max_frequency_p(void)
+{
+       int ret;
+
+       ret = deviced_release_cpu_max_frequency();
+       dts_check_eq(API_NAME_DEVICED_RELEASE_CPU_MAX_FREQUENCY, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_release_cpu_min_frequency()
+ */
+static void utc_system_deviced_deviced_release_cpu_min_frequency_p(void)
+{
+       int ret;
+
+       ret = deviced_release_cpu_min_frequency();
+       dts_check_eq(API_NAME_DEVICED_RELEASE_CPU_MIN_FREQUENCY, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_request_set_factory_mode()
+ */
+static void utc_system_deviced_deviced_request_set_factory_mode_p_1(void)
+{
+       int ret;
+
+       ret = deviced_request_set_factory_mode(1);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_SET_FACTORY_MODE, ret, 1, "Enable factory mode");
+}
+
+/**
+ * @brief Positive test case of deviced_request_set_factory_mode()
+ */
+static void utc_system_deviced_deviced_request_set_factory_mode_p_2(void)
+{
+       int ret;
+
+       ret = deviced_request_set_factory_mode(0);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_SET_FACTORY_MODE, ret, 0, "Disable factory mode");
+}
+
+/**
+ * @brief Negative test case of deviced_request_set_factory_mode()
+ */
+static void utc_system_deviced_deviced_request_set_factory_mode_n(void)
+{
+       int ret;
+
+       ret = deviced_request_set_factory_mode(-1);
+       dts_check_ne(API_NAME_DEVICED_REQUEST_SET_FACTORY_MODE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_request_dump_log()
+ */
+static void utc_system_deviced_deviced_request_dump_log_p_1(void)
+{
+       int ret;
+
+       ret = deviced_request_dump_log(AP_DUMP);
+       dts_check_ge(API_NAME_DEVICED_REQUEST_DUMP_LOG, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_request_dump_log()
+ */
+static void utc_system_deviced_deviced_request_dump_log_p_2(void)
+{
+       int ret;
+
+       ret = deviced_request_dump_log(CP_DUMP);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_DUMP_LOG, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_request_dump_log()
+ */
+static void utc_system_deviced_deviced_request_dump_log_n(void)
+{
+       int ret;
+
+       ret = deviced_request_dump_log(-1);
+       dts_check_ne(API_NAME_DEVICED_REQUEST_DUMP_LOG, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_request_delete_dump()
+ */
+static void utc_system_deviced_deviced_request_delete_dump_p(void)
+{
+       int ret;
+
+       ret = deviced_request_delete_dump("");
+       dts_check_eq(API_NAME_DEVICED_REQUEST_DELETE_DUMP, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_request_delete_dump()
+ */
+static void utc_system_deviced_deviced_request_delete_dump_n(void)
+{
+       int ret;
+
+       ret = deviced_request_delete_dump(NULL);
+       dts_check_ne(API_NAME_DEVICED_REQUEST_DELETE_DUMP, ret, 0);
+}
diff --git a/test/testcase/utc_system_deviced_deviced_managed.c b/test/testcase/utc_system_deviced_deviced_managed.c
new file mode 100644 (file)
index 0000000..78ac62f
--- /dev/null
@@ -0,0 +1,422 @@
+/*
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of SAMSUNG
+ * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
+ * this software is owned by Samsung and you shall not disclose such
+ * Confidential Information and shall use it only in accordance with the terms
+ * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
+ * make no representations or warranties about the suitability of the software,
+ * either express or implied, including but not limited to the implied
+ * warranties of merchantability, fitness for a particular purpose, or
+ * non-infringement. SAMSUNG shall not be liable for any damages suffered by
+ * licensee arising out of or related to this software.
+ *
+ */
+#include <tet_api.h>
+#include <stdbool.h>
+#include <dd-deviced-managed.h>
+
+#define API_NAME_DEVICED_GET_PID "deviced_get_pid"
+#define API_NAME_DEVICED_SET_DATETIME "deviced_set_datetime"
+#define API_NAME_DEVICED_REQUEST_MOUNT_MMC "deviced_request_mount_mmc"
+#define API_NAME_DEVICED_REQUEST_UNMOUNT_MMC "deviced_request_unmount_mmc"
+#define API_NAME_DEVICED_REQUEST_FORMAT_MMC "deviced_request_format_mmc"
+#define API_NAME_DEVICED_FORMAT_MMC "deviced_format_mmc"
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+
+static void utc_system_deviced_deviced_get_pid_p(void);
+static void utc_system_deviced_deviced_get_pid_n(void);
+static void utc_system_deviced_deviced_set_datetime_n(void);
+static void utc_system_deviced_deviced_set_datetime_p(void);
+static void utc_system_deviced_deviced_request_mount_mmc_p_1(void);
+static void utc_system_deviced_deviced_request_mount_mmc_p_2(void);
+static void utc_system_deviced_deviced_request_mount_mmc_p_3(void);
+static void utc_system_deviced_deviced_request_unmount_mmc_p_1(void);
+static void utc_system_deviced_deviced_request_unmount_mmc_p_2(void);
+static void utc_system_deviced_deviced_request_unmount_mmc_p_3(void);
+static void utc_system_deviced_deviced_request_unmount_mmc_p_4(void);
+static void utc_system_deviced_deviced_request_unmount_mmc_n(void);
+static void utc_system_deviced_deviced_request_format_mmc_p_1(void);
+static void utc_system_deviced_deviced_request_format_mmc_p_2(void);
+static void utc_system_deviced_deviced_request_format_mmc_p_3(void);
+static void utc_system_deviced_deviced_format_mmc_p_1(void);
+static void utc_system_deviced_deviced_format_mmc_p_2(void);
+static void utc_system_deviced_deviced_format_mmc_p_3(void);
+static void utc_system_deviced_deviced_format_mmc_p_4(void);
+static void utc_system_deviced_deviced_format_mmc_n(void);
+
+enum {
+       POSITIVE_TC_IDX = 0x01,
+       NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+       /* The following TCs are for root application */
+//     { utc_system_deviced_deviced_get_pid_p, POSITIVE_TC_IDX },
+//     { utc_system_deviced_deviced_get_pid_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_set_datetime_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_set_datetime_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_mount_mmc_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_mount_mmc_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_mount_mmc_p_3, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_unmount_mmc_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_unmount_mmc_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_unmount_mmc_p_3, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_unmount_mmc_p_4, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_unmount_mmc_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_format_mmc_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_format_mmc_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_request_format_mmc_p_3, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_format_mmc_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_format_mmc_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_format_mmc_p_3, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_format_mmc_p_4, POSITIVE_TC_IDX },
+       { utc_system_deviced_deviced_format_mmc_n, NEGATIVE_TC_IDX },
+       { NULL, 0 },
+};
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of deviced_get_pid()
+ */
+static void utc_system_deviced_deviced_get_pid_p(void)
+{
+       int ret;
+
+       ret = deviced_get_pid("/usb/bin/deviced");
+       dts_check_ge(API_NAME_DEVICED_GET_PID, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_get_pid()
+ */
+static void utc_system_deviced_deviced_get_pid_n(void)
+{
+       int ret;
+
+       ret = deviced_get_pid(NULL);
+       dts_check_lt(API_NAME_DEVICED_GET_PID, ret, 0);
+}
+
+/**
+ * @brief Negative test case of deviced_set_datetime()
+ */
+static void utc_system_deviced_deviced_set_datetime_n(void)
+{
+       int ret;
+
+       ret = deviced_set_datetime(-1);
+       dts_check_lt(API_NAME_DEVICED_SET_DATETIME, ret, 0);
+}
+
+/**
+ * @brief Positive test case of deviced_set_datetime()
+ */
+static void utc_system_deviced_deviced_set_datetime_p(void)
+{
+       int ret;
+       time_t now;
+
+       localtime(&now);
+
+       ret = deviced_set_datetime(now);
+       dts_check_ge(API_NAME_DEVICED_SET_DATETIME, ret, 0);
+}
+
+static void mount_cb(int result, void *data)
+{
+       dts_message(API_NAME_DEVICED_REQUEST_MOUNT_MMC,
+                       "mount callback result : %d", result);
+}
+
+/**
+ * @brief Positive test case of deviced_request_mount_mmc()
+ */
+static void utc_system_deviced_deviced_request_mount_mmc_p_1(void)
+{
+       int ret;
+       struct mmc_contents data = {.mmc_cb = mount_cb, .user_data = NULL};
+
+       dts_message(API_NAME_DEVICED_REQUEST_MOUNT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_request_mount_mmc(&data);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_MOUNT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Positive test case of deviced_request_mount_mmc()
+ */
+static void utc_system_deviced_deviced_request_mount_mmc_p_2(void)
+{
+       int ret;
+       struct mmc_contents data = {.mmc_cb = NULL, .user_data = NULL};
+
+       dts_message(API_NAME_DEVICED_REQUEST_MOUNT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_request_mount_mmc(&data);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_MOUNT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Positive test case of deviced_request_mount_mmc()
+ */
+static void utc_system_deviced_deviced_request_mount_mmc_p_3(void)
+{
+       int ret;
+
+       dts_message(API_NAME_DEVICED_REQUEST_MOUNT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_request_mount_mmc(NULL);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_MOUNT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+static void unmount_cb(int result, void *data)
+{
+       dts_message(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC,
+                       "unmount callback result : %d", result);
+}
+
+/**
+ * @brief Positive test case of deviced_request_unmount_mmc()
+ */
+static void utc_system_deviced_deviced_request_unmount_mmc_p_1(void)
+{
+       int ret;
+       struct mmc_contents data = {.mmc_cb = unmount_cb, .user_data = NULL};
+
+       dts_message(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_request_unmount_mmc(&data, 0);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Positive test case of deviced_request_unmount_mmc()
+ */
+static void utc_system_deviced_deviced_request_unmount_mmc_p_2(void)
+{
+       int ret;
+       struct mmc_contents data = {.mmc_cb = unmount_cb, .user_data = NULL};
+
+       dts_message(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_request_unmount_mmc(&data, 1);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Positive test case of deviced_request_unmount_mmc()
+ */
+static void utc_system_deviced_deviced_request_unmount_mmc_p_3(void)
+{
+       int ret;
+       struct mmc_contents data = {.mmc_cb = NULL, .user_data = NULL};
+
+       dts_message(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_request_unmount_mmc(&data, 1);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Positive test case of deviced_request_unmount_mmc()
+ */
+static void utc_system_deviced_deviced_request_unmount_mmc_p_4(void)
+{
+       int ret;
+
+       dts_message(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_request_unmount_mmc(NULL, 0);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Negative test case of deviced_request_unmount_mmc()
+ */
+static void utc_system_deviced_deviced_request_unmount_mmc_n(void)
+{
+       int ret;
+       struct mmc_contents data = {.mmc_cb = unmount_cb, .user_data = NULL};
+
+       dts_message(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_request_unmount_mmc(&data, -1);
+       dts_check_ne(API_NAME_DEVICED_REQUEST_UNMOUNT_MMC, ret, 0);
+}
+
+static void format_cb(int result, void *data)
+{
+       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
+                       "format callback result : %d", result);
+}
+
+/**
+ * @brief Positive test case of deviced_request_format_mmc()
+ */
+static void utc_system_deviced_deviced_request_format_mmc_p_1(void)
+{
+       int ret;
+       struct mmc_contents data = {.mmc_cb = format_cb, .user_data = NULL};
+
+       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_request_format_mmc(&data);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_FORMAT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Positive test case of deviced_request_format_mmc()
+ */
+static void utc_system_deviced_deviced_request_format_mmc_p_2(void)
+{
+       int ret;
+       struct mmc_contents data = {.mmc_cb = NULL, .user_data = NULL};
+
+       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_request_format_mmc(&data);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_FORMAT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Positive test case of deviced_request_format_mmc()
+ */
+static void utc_system_deviced_deviced_request_format_mmc_p_3(void)
+{
+       int ret;
+
+       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_request_format_mmc(NULL);
+       dts_check_eq(API_NAME_DEVICED_REQUEST_FORMAT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Positive test case of deviced_format_mmc()
+ */
+static void utc_system_deviced_deviced_format_mmc_p_1(void)
+{
+       int ret;
+       struct mmc_contents data = {.mmc_cb = format_cb, .user_data = NULL};
+
+       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_format_mmc(&data, 0);
+       dts_check_eq(API_NAME_DEVICED_FORMAT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Positive test case of deviced_format_mmc()
+ */
+static void utc_system_deviced_deviced_format_mmc_p_2(void)
+{
+       int ret;
+       struct mmc_contents data = {.mmc_cb = format_cb, .user_data = NULL};
+
+       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_format_mmc(&data, 1);
+       dts_check_eq(API_NAME_DEVICED_FORMAT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Positive test case of deviced_format_mmc()
+ */
+static void utc_system_deviced_deviced_format_mmc_p_3(void)
+{
+       int ret;
+       struct mmc_contents data = {.mmc_cb = NULL, .user_data = NULL};
+
+       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_format_mmc(&data, 1);
+       dts_check_eq(API_NAME_DEVICED_FORMAT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Positive test case of deviced_format_mmc()
+ */
+static void utc_system_deviced_deviced_format_mmc_p_4(void)
+{
+       int ret;
+
+       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_format_mmc(NULL, 0);
+       dts_check_eq(API_NAME_DEVICED_FORMAT_MMC, ret, 0);
+
+       sleep(1);
+}
+
+/**
+ * @brief Negative test case of deviced_format_mmc()
+ */
+static void utc_system_deviced_deviced_format_mmc_n(void)
+{
+       int ret;
+       struct mmc_contents data = {.mmc_cb = format_cb, .user_data = NULL};
+
+       dts_message(API_NAME_DEVICED_REQUEST_FORMAT_MMC,
+                       "This testcase is only valid when mmc is inserted");
+
+       ret = deviced_format_mmc(&data, -1);
+       dts_check_ne(API_NAME_DEVICED_FORMAT_MMC, ret, 0);
+}
diff --git a/test/testcase/utc_system_deviced_display.c b/test/testcase/utc_system_deviced_display.c
new file mode 100644 (file)
index 0000000..812b4bd
--- /dev/null
@@ -0,0 +1,649 @@
+/*
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of SAMSUNG
+ * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
+ * this software is owned by Samsung and you shall not disclose such
+ * Confidential Information and shall use it only in accordance with the terms
+ * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
+ * make no representations or warranties about the suitability of the software,
+ * either express or implied, including but not limited to the implied
+ * warranties of merchantability, fitness for a particular purpose, or
+ * non-infringement. SAMSUNG shall not be liable for any damages suffered by
+ * licensee arising out of or related to this software.
+ *
+ */
+#include <tet_api.h>
+#include <stdbool.h>
+#include <dd-display.h>
+
+#define API_NAME_DISPLAY_GET_COUNT "display_get_count"
+#define API_NAME_DISPLAY_GET_MAX_BRIGHTNESS "display_get_max_brightness"
+#define API_NAME_DISPLAY_GET_MIN_BRIGHTNESS "display_get_min_brightness"
+#define API_NAME_DISPLAY_GET_BRIGHTNESS "display_get_brightness"
+#define API_NAME_DISPLAY_SET_BRIGHTNESS_WITH_SETTING "display_set_brightness_with_setting"
+#define API_NAME_DISPLAY_SET_BRIGHTNESS "display_set_brightness"
+#define API_NAME_DISPLAY_RELEASE_BRIGHTNESS "display_release_brightness"
+#define API_NAME_DISPLAY_GET_ACL_STATUS "display_get_acl_status"
+#define API_NAME_DISPLAY_SET_ACL_STATUS "display_set_acl_status"
+#define API_NAME_DISPLAY_GET_IMAGE_ENHANCE_INFO "display_get_enhance_info"
+#define API_NAME_DISPLAY_GET_IMAGE_ENHANCE "display_get_image_enhance"
+#define API_NAME_DISPLAY_SET_IMAGE_ENHANCE "display_set_image_enhance"
+#define API_NAME_DISPLAY_SET_REFRESH_RATE "display_set_refresh_rate"
+#define API_NAME_DISPLAY_LOCK_STATE "display_lock_state"
+#define API_NAME_DISPLAY_UNLOCK_STATE "display_unlock_state"
+#define API_NAME_DISPLAY_CHANGE_STATE "display_change_state"
+#define API_NAME_DISPLAY_GET_AUTO_SCREEN_TONE "display_get_auto_screen_tone"
+#define API_NAME_DISPLAY_SET_AUTO_SCREEN_TONE "display_Set_auto_screen_tone"
+#define API_NAME_DISPLAY_GET_COLOR_BLIND "display_get_color_blind"
+#define API_NAME_DISPLAY_SET_COLOR_BLIND "display_set_color_blind"
+#define API_NAME_DISPLAY_GET_ENHANCED_TOUCH "display_get_enhanced_touch"
+#define API_NAME_DISPLAY_SET_ENHANCED_TOUCH "display_set_enhanced_touch"
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+
+static void utc_system_deviced_display_get_count_p(void);
+static void utc_system_deviced_display_get_max_brightness_p(void);
+static void utc_system_deviced_display_get_min_brightness_p(void);
+static void utc_system_deviced_display_get_brightness_p(void);
+static void utc_system_deviced_display_set_brightness_with_setting_p(void);
+static void utc_system_deviced_display_set_brightness_with_setting_n(void);
+static void utc_system_deviced_display_set_brightness_p(void);
+static void utc_system_deviced_display_set_brightness_n(void);
+static void utc_system_deviced_display_release_brightness_p(void);
+static void utc_system_deviced_display_get_acl_status_p(void);
+static void utc_system_deviced_display_set_acl_status_p_1(void);
+static void utc_system_deviced_display_set_acl_status_p_2(void);
+static void utc_system_deviced_display_set_acl_status_n(void);
+static void utc_system_deviced_display_get_image_enhance_info_p(void);
+static void utc_system_deviced_display_get_image_enhance_p(void);
+static void utc_system_deviced_display_get_image_enhance_n(void);
+static void utc_system_deviced_display_set_image_enhance_p(void);
+static void utc_system_deviced_display_set_image_enhance_n_1(void);
+static void utc_system_deviced_display_set_image_enhance_n_2(void);
+static void utc_system_deviced_display_set_refresh_rate_p(void);
+static void utc_system_deviced_display_set_refresh_rate_n_1(void);
+static void utc_system_deviced_display_set_refresh_rate_n_2(void);
+static void utc_system_deviced_display_lock_state_p(void);
+static void utc_system_deviced_display_lock_state_n_1(void);
+static void utc_system_deviced_display_lock_state_n_2(void);
+static void utc_system_deviced_display_lock_state_n_3(void);
+static void utc_system_deviced_display_unlock_state_p(void);
+static void utc_system_deviced_display_unlock_state_n_1(void);
+static void utc_system_deviced_display_unlock_state_n_2(void);
+static void utc_system_deviced_display_change_state_p(void);
+static void utc_system_deviced_display_change_state_n(void);
+static void utc_system_deviced_display_get_auto_screen_tone_p(void);
+static void utc_system_deviced_display_set_auto_screen_tone_p_1(void);
+static void utc_system_deviced_display_set_auto_screen_tone_p_2(void);
+static void utc_system_deviced_display_set_auto_screen_tone_n(void);
+static void utc_system_deviced_display_get_color_blind_p(void);
+static void utc_system_deviced_display_set_color_blind_p_1(void);
+static void utc_system_deviced_display_set_color_blind_p_2(void);
+static void utc_system_deviced_display_set_color_blind_n_1(void);
+static void utc_system_deviced_display_set_color_blind_n_2(void);
+static void utc_system_deviced_display_get_enhanced_touch_p(void);
+static void utc_system_deviced_display_set_enhanced_touch_p_1(void);
+static void utc_system_deviced_display_set_enhanced_touch_p_2(void);
+static void utc_system_deviced_display_set_enhanced_touch_n(void);
+
+enum {
+       POSITIVE_TC_IDX = 0x01,
+       NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+       { utc_system_deviced_display_get_count_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_get_max_brightness_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_get_min_brightness_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_get_brightness_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_brightness_with_setting_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_brightness_with_setting_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_set_brightness_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_brightness_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_release_brightness_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_get_acl_status_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_acl_status_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_acl_status_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_acl_status_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_get_image_enhance_info_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_get_image_enhance_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_get_image_enhance_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_set_image_enhance_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_image_enhance_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_set_image_enhance_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_set_refresh_rate_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_refresh_rate_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_set_refresh_rate_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_lock_state_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_lock_state_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_lock_state_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_lock_state_n_3, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_unlock_state_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_unlock_state_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_unlock_state_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_change_state_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_change_state_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_get_auto_screen_tone_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_auto_screen_tone_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_auto_screen_tone_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_auto_screen_tone_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_get_color_blind_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_color_blind_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_color_blind_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_color_blind_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_set_color_blind_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_display_get_enhanced_touch_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_enhanced_touch_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_enhanced_touch_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_display_set_enhanced_touch_n, NEGATIVE_TC_IDX },
+       { NULL, 0 },
+};
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of display_get_count()
+ */
+static void utc_system_deviced_display_get_count_p(void)
+{
+       int ret;
+
+       ret = display_get_count();
+       dts_check_ge(API_NAME_DISPLAY_GET_COUNT, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_get_max_brightness()
+ */
+static void utc_system_deviced_display_get_max_brightness_p(void)
+{
+       int ret;
+
+       ret = display_get_max_brightness();
+       dts_check_ge(API_NAME_DISPLAY_GET_MAX_BRIGHTNESS, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_get_min_brightness()
+ */
+static void utc_system_deviced_display_get_min_brightness_p(void)
+{
+       int ret;
+
+       ret = display_get_min_brightness();
+       dts_check_ge(API_NAME_DISPLAY_GET_MIN_BRIGHTNESS, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_get_brightness()
+ */
+static void utc_system_deviced_display_get_brightness_p(void)
+{
+       int ret;
+
+       ret = display_get_brightness();
+       dts_check_ge(API_NAME_DISPLAY_GET_BRIGHTNESS, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_set_brightness_with_setting()
+ */
+static void utc_system_deviced_display_set_brightness_with_setting_p(void)
+{
+       int ret;
+
+       ret = display_set_brightness_with_setting(100);
+       dts_check_eq(API_NAME_DISPLAY_SET_BRIGHTNESS_WITH_SETTING, ret, 0);
+}
+
+/**
+ * @brief Negative test case of display_set_brightness_with_setting()
+ */
+static void utc_system_deviced_display_set_brightness_with_setting_n(void)
+{
+       int ret;
+
+       ret = display_set_brightness_with_setting(-1);
+       dts_check_ne(API_NAME_DISPLAY_SET_BRIGHTNESS_WITH_SETTING, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_set_brightness()
+ */
+static void utc_system_deviced_display_set_brightness_p(void)
+{
+       int ret;
+
+       ret = display_set_brightness(50);
+       dts_check_eq(API_NAME_DISPLAY_SET_BRIGHTNESS, ret, 0);
+}
+
+/**
+ * @brief Negative test case of display_set_brightness()
+ */
+static void utc_system_deviced_display_set_brightness_n(void)
+{
+       int ret;
+
+       ret = display_set_brightness(-1);
+       dts_check_ne(API_NAME_DISPLAY_SET_BRIGHTNESS, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_release_brightness()
+ */
+static void utc_system_deviced_display_release_brightness_p(void)
+{
+       int ret;
+
+       ret = display_release_brightness();
+       dts_check_eq(API_NAME_DISPLAY_RELEASE_BRIGHTNESS, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_get_acl_status()
+ */
+static void utc_system_deviced_display_get_acl_status_p(void)
+{
+       int ret;
+
+       ret = display_get_acl_status();
+       dts_check_ge(API_NAME_DISPLAY_GET_ACL_STATUS, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_set_acl_status()
+ */
+static void utc_system_deviced_display_set_acl_status_p_1(void)
+{
+       int ret;
+
+       ret = display_set_acl_status(1);
+       dts_check_eq(API_NAME_DISPLAY_SET_ACL_STATUS, ret, 0, "Enable acl");
+}
+
+/**
+ * @brief Positive test case of display_set_acl_status()
+ */
+static void utc_system_deviced_display_set_acl_status_p_2(void)
+{
+       int ret;
+
+       ret = display_set_acl_status(0);
+       dts_check_eq(API_NAME_DISPLAY_SET_ACL_STATUS, ret, 0, "Disable acl");
+}
+
+/**
+ * @brief Negative test case of display_set_acl_status()
+ */
+static void utc_system_deviced_display_set_acl_status_n(void)
+{
+       int ret;
+
+       ret = display_set_acl_status(-1);
+       dts_check_ne(API_NAME_DISPLAY_SET_ACL_STATUS, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_get_image_enhance_info()
+ */
+static void utc_system_deviced_display_get_image_enhance_info_p(void)
+{
+       int ret;
+
+       ret = display_get_image_enhance_info();
+       dts_check_ge(API_NAME_DISPLAY_GET_IMAGE_ENHANCE_INFO, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_get_image_enhance()
+ */
+static void utc_system_deviced_display_get_image_enhance_p(void)
+{
+       int i, ret;
+
+       for (i = ENHANCE_MODE; i <= ENHANCE_OUTDOOR; ++i) {
+               ret = display_get_image_enhance(i);
+               dts_check_ge(API_NAME_DISPLAY_GET_IMAGE_ENHANCE, ret, 0, "enhance type : %d", i);
+       }
+}
+
+/**
+ * @brief Negative test case of display_get_image_enhance()
+ */
+static void utc_system_deviced_display_get_image_enhance_n(void)
+{
+       int ret;
+
+       ret = display_get_image_enhance(-1);
+       dts_check_ne(API_NAME_DISPLAY_GET_IMAGE_ENHANCE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_set_image_enhance()
+ */
+static void utc_system_deviced_display_set_image_enhance_p(void)
+{
+       int i, ret;
+
+       for (i = ENHANCE_MODE; i <= ENHANCE_OUTDOOR; ++i) {
+               ret = display_set_image_enhance(i, 0);
+               dts_check_eq(API_NAME_DISPLAY_SET_IMAGE_ENHANCE, ret, 0, "enhance type : %d", i);
+       }
+}
+
+/**
+ * @brief Negative test case of display_set_image_enhance()
+ */
+static void utc_system_deviced_display_set_image_enhance_n_1(void)
+{
+       int ret;
+
+       ret = display_set_image_enhance(-1, 0);
+       dts_check_ne(API_NAME_DISPLAY_SET_IMAGE_ENHANCE, ret, 0);
+}
+
+/**
+ * @brief Negative test case of display_set_image_enhance()
+ */
+static void utc_system_deviced_display_set_image_enhance_n_2(void)
+{
+       int ret;
+
+       ret = display_set_image_enhance(0, -1);
+       dts_check_ne(API_NAME_DISPLAY_SET_IMAGE_ENHANCE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_set_refresh_rate()
+ */
+static void utc_system_deviced_display_set_refresh_rate_p(void)
+{
+       int i, ret;
+
+       for (i = REFRESH_SETTING; i <= REFRESH_WEB; ++i) {
+               ret = display_set_refresh_rate(i, 60);
+               dts_check_eq(API_NAME_DISPLAY_SET_REFRESH_RATE, ret, 0, "refresh type : %d", i);
+       }
+}
+
+/**
+ * @brief Negative test case of display_set_refresh_rate()
+ */
+static void utc_system_deviced_display_set_refresh_rate_n_1(void)
+{
+       int ret;
+
+       ret = display_set_refresh_rate(-1, 60);
+       dts_check_ne(API_NAME_DISPLAY_SET_REFRESH_RATE, ret, 0);
+}
+
+/**
+ * @brief Negative test case of display_set_refresh_rate()
+ */
+static void utc_system_deviced_display_set_refresh_rate_n_2(void)
+{
+       int ret;
+
+       ret = display_set_refresh_rate(0, -1);
+       dts_check_ne(API_NAME_DISPLAY_SET_REFRESH_RATE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_lock_state()
+ */
+static void utc_system_deviced_display_lock_state_p(void)
+{
+       int ret;
+
+       ret = display_lock_state(LCD_NORMAL, GOTO_STATE_NOW, 0);
+       dts_check_eq(API_NAME_DISPLAY_LOCK_STATE, ret, 0);
+}
+
+/**
+ * @brief Negative test case of display_lock_state()
+ */
+static void utc_system_deviced_display_lock_state_n_1(void)
+{
+       int ret;
+
+       ret = display_lock_state(-1, GOTO_STATE_NOW, 0);
+       dts_check_ne(API_NAME_DISPLAY_LOCK_STATE, ret, 0);
+}
+
+/**
+ * @brief Negative test case of display_lock_state()
+ */
+static void utc_system_deviced_display_lock_state_n_2(void)
+{
+       int ret;
+
+       ret = display_lock_state(LCD_NORMAL, -1, 0);
+       dts_check_ne(API_NAME_DISPLAY_LOCK_STATE, ret, 0);
+}
+
+/**
+ * @brief Negative test case of display_lock_state()
+ */
+static void utc_system_deviced_display_lock_state_n_3(void)
+{
+       int ret;
+
+       ret = display_lock_state(LCD_NORMAL, GOTO_STATE_NOW, -1);
+       dts_check_ne(API_NAME_DISPLAY_LOCK_STATE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_unlock_state()
+ */
+static void utc_system_deviced_display_unlock_state_p(void)
+{
+       int ret;
+
+       ret = display_unlock_state(LCD_NORMAL, PM_RESET_TIMER);
+       dts_check_eq(API_NAME_DISPLAY_UNLOCK_STATE, ret, 0);
+}
+
+/**
+ * @brief Negative test case of display_unlock_state()
+ */
+static void utc_system_deviced_display_unlock_state_n_1(void)
+{
+       int ret;
+
+       ret = display_unlock_state(-1, PM_RESET_TIMER);
+       dts_check_ne(API_NAME_DISPLAY_UNLOCK_STATE, ret, 0);
+}
+
+/**
+ * @brief Negative test case of display_unlock_state()
+ */
+static void utc_system_deviced_display_unlock_state_n_2(void)
+{
+       int ret;
+
+       ret = display_unlock_state(LCD_NORMAL, -1);
+       dts_check_ne(API_NAME_DISPLAY_UNLOCK_STATE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_change_state()
+ */
+static void utc_system_deviced_display_change_state_p(void)
+{
+       int ret;
+
+       ret = display_change_state(LCD_NORMAL);
+       dts_check_eq(API_NAME_DISPLAY_CHANGE_STATE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_change_state()
+ */
+static void utc_system_deviced_display_change_state_n(void)
+{
+       int ret;
+
+       ret = display_change_state(-1);
+       dts_check_ne(API_NAME_DISPLAY_CHANGE_STATE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_get_auto_screen_tone()
+ */
+static void utc_system_deviced_display_get_auto_screen_tone_p(void)
+{
+       int ret;
+
+       ret = display_get_auto_screen_tone();
+       dts_check_ge(API_NAME_DISPLAY_GET_AUTO_SCREEN_TONE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_set_auto_screen_tone()
+ */
+static void utc_system_deviced_display_set_auto_screen_tone_p_1(void)
+{
+       int ret;
+
+       ret = display_set_auto_screen_tone(TONE_ON);
+       dts_check_eq(API_NAME_DISPLAY_SET_AUTO_SCREEN_TONE, ret, 0, "Enable auto screen tone");
+}
+
+/**
+ * @brief Positive test case of display_set_auto_screen_tone()
+ */
+static void utc_system_deviced_display_set_auto_screen_tone_p_2(void)
+{
+       int ret;
+
+       ret = display_set_auto_screen_tone(TONE_OFF);
+       dts_check_eq(API_NAME_DISPLAY_SET_AUTO_SCREEN_TONE, ret, 0, "Disable auto screen tone");
+}
+
+/**
+ * @brief Negative test case of display_set_auto_screen_tone()
+ */
+static void utc_system_deviced_display_set_auto_screen_tone_n(void)
+{
+       int ret;
+
+       ret = display_set_auto_screen_tone(-1);
+       dts_check_ne(API_NAME_DISPLAY_SET_AUTO_SCREEN_TONE, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_get_color_blind()
+ */
+static void utc_system_deviced_display_get_color_blind_p(void)
+{
+       int ret;
+
+       ret = display_get_color_blind();
+       dts_check_ge(API_NAME_DISPLAY_GET_COLOR_BLIND, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_set_color_blind()
+ */
+static void utc_system_deviced_display_set_color_blind_p_1(void)
+{
+       int ret;
+       struct blind_color_info info = {0,};
+
+       ret = display_set_color_blind(true, &info);
+       dts_check_eq(API_NAME_DISPLAY_SET_COLOR_BLIND, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_set_color_blind()
+ */
+static void utc_system_deviced_display_set_color_blind_p_2(void)
+{
+       int ret;
+       struct blind_color_info info = {0,};
+
+       ret = display_set_color_blind(false, &info);
+       dts_check_eq(API_NAME_DISPLAY_SET_COLOR_BLIND, ret, 0);
+}
+
+/**
+ * @brief Negative test case of display_set_color_blind()
+ */
+static void utc_system_deviced_display_set_color_blind_n_1(void)
+{
+       int ret;
+       struct blind_color_info info = {0,};
+
+       ret = display_set_color_blind(-1, &info);
+       dts_check_ne(API_NAME_DISPLAY_SET_COLOR_BLIND, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_set_color_blind()
+ */
+static void utc_system_deviced_display_set_color_blind_n_2(void)
+{
+       int ret;
+
+       ret = display_set_color_blind(true, NULL);
+       dts_check_ne(API_NAME_DISPLAY_SET_COLOR_BLIND, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_get_enhanced_touch()
+ */
+static void utc_system_deviced_display_get_enhanced_touch_p(void)
+{
+       int ret;
+
+       ret = display_get_enhanced_touch();
+       dts_check_ge(API_NAME_DISPLAY_GET_ENHANCED_TOUCH, ret, 0);
+}
+
+/**
+ * @brief Positive test case of display_set_enhanced_touch()
+ */
+static void utc_system_deviced_display_set_enhanced_touch_p_1(void)
+{
+       int ret;
+
+       ret = display_set_enhanced_touch(true);
+       dts_check_eq(API_NAME_DISPLAY_SET_ENHANCED_TOUCH, ret, 0, "Enable enhanced touch");
+}
+
+/**
+ * @brief Positive test case of display_set_enhanced_touch()
+ */
+static void utc_system_deviced_display_set_enhanced_touch_p_2(void)
+{
+       int ret;
+
+       ret = display_set_enhanced_touch(false);
+       dts_check_eq(API_NAME_DISPLAY_SET_ENHANCED_TOUCH, ret, 0, "Disable enhanced touch");
+}
+
+/**
+ * @brief Negative test case of display_set_enhanced_touch()
+ */
+static void utc_system_deviced_display_set_enhanced_touch_n(void)
+{
+       int ret;
+
+       ret = display_set_enhanced_touch(-1);
+       dts_check_ne(API_NAME_DISPLAY_SET_ENHANCED_TOUCH, ret, 0);
+}
diff --git a/test/testcase/utc_system_deviced_haptic.c b/test/testcase/utc_system_deviced_haptic.c
new file mode 100644 (file)
index 0000000..d32283e
--- /dev/null
@@ -0,0 +1,984 @@
+/*
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of SAMSUNG
+ * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
+ * this software is owned by Samsung and you shall not disclose such
+ * Confidential Information and shall use it only in accordance with the terms
+ * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
+ * make no representations or warranties about the suitability of the software,
+ * either express or implied, including but not limited to the implied
+ * warranties of merchantability, fitness for a particular purpose, or
+ * non-infringement. SAMSUNG shall not be liable for any damages suffered by
+ * licensee arising out of or related to this software.
+ *
+ */
+#include <tet_api.h>
+#include <dd-haptic.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#define API_NAME_HAPTIC_STARTUP "haptic_startup"
+#define API_NAME_HAPTIC_GET_COUNT "haptic_get_count"
+#define API_NAME_HAPTIC_OPEN "haptic_open"
+#define API_NAME_HAPTIC_CLOSE "haptic_close"
+#define API_NAME_HAPTIC_VIBRATE_MONOTONE "haptic_vibrate_monotone"
+#define API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL "haptic_vibrate_monotone_with_detail"
+#define API_NAME_HAPTIC_VIBRATE_FILE "haptic_vibrate_file"
+#define API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL "haptic_vibrate_file_with_detail"
+#define API_NAME_HAPTIC_VIBRATE_BUFFERS "haptic_vibrate_buffers"
+#define API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL "haptic_vibrate_buffers_with_detail"
+#define API_NAME_HAPTIC_STOP_ALL_EFFECTS "haptic_stop_all_effects"
+#define API_NAME_HAPTIC_GET_EFFECT_STATE "haptic_get_effect_state"
+#define API_NAME_HAPTIC_CREATE_EFFECT "haptic_create_effect"
+#define API_NAME_HAPTIC_SAVE_EFFECT "haptic_save_effect"
+#define API_NAME_HAPTIC_GET_FILE_DURATION "haptic_get_file_duration"
+#define API_NAME_HAPTIC_GET_BUFFER_DURATION "haptic_get_buffer_duration"
+#define API_NAME_HAPTIC_SAVE_LED "haptic_save_led"
+
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+
+static void utc_system_deviced_haptic_get_count_p(void);
+static void utc_system_deviced_haptic_get_count_n(void);
+static void utc_system_deviced_haptic_open_p(void);
+static void utc_system_deviced_haptic_open_n_1(void);
+static void utc_system_deviced_haptic_open_n_2(void);
+static void utc_system_deviced_haptic_close_p(void);
+static void utc_system_deviced_haptic_close_n(void);
+static void utc_system_deviced_haptic_vibrate_monotone_p_1(void);
+static void utc_system_deviced_haptic_vibrate_monotone_p_2(void);
+static void utc_system_deviced_haptic_vibrate_monotone_n_1(void);
+static void utc_system_deviced_haptic_vibrate_monotone_n_2(void);
+static void utc_system_deviced_haptic_vibrate_monotone_with_detail_p_1(void);
+static void utc_system_deviced_haptic_vibrate_monotone_with_detail_p_2(void);
+static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_1(void);
+static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_2(void);
+static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_3(void);
+static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_4(void);
+static void utc_system_deviced_haptic_vibrate_file_p_1(void);
+static void utc_system_deviced_haptic_vibrate_file_p_2(void);
+static void utc_system_deviced_haptic_vibrate_file_n_1(void);
+static void utc_system_deviced_haptic_vibrate_file_n_2(void);
+static void utc_system_deviced_haptic_vibrate_file_with_detail_p_1(void);
+static void utc_system_deviced_haptic_vibrate_file_with_detail_p_2(void);
+static void utc_system_deviced_haptic_vibrate_file_with_detail_n_1(void);
+static void utc_system_deviced_haptic_vibrate_file_with_detail_n_2(void);
+static void utc_system_deviced_haptic_vibrate_file_with_detail_n_3(void);
+static void utc_system_deviced_haptic_vibrate_file_with_detail_n_4(void);
+static void utc_system_deviced_haptic_vibrate_file_with_detail_n_5(void);
+static void utc_system_deviced_haptic_vibrate_buffers_p_1(void);
+static void utc_system_deviced_haptic_vibrate_buffers_p_2(void);
+static void utc_system_deviced_haptic_vibrate_buffers_n_1(void);
+static void utc_system_deviced_haptic_vibrate_buffers_n_2(void);
+static void utc_system_deviced_haptic_vibrate_buffers_n_3(void);
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_p_1(void);
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_p_2(void);
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_1(void);
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_2(void);
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_3(void);
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_4(void);
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_5(void);
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_6(void);
+static void utc_system_deviced_haptic_stop_all_effects_p(void);
+static void utc_system_deviced_haptic_stop_all_effects_n(void);
+static void utc_system_deviced_haptic_get_effect_state_p(void);
+static void utc_system_deviced_haptic_get_effect_state_n_1(void);
+static void utc_system_deviced_haptic_get_effect_state_n_2(void);
+static void utc_system_deviced_haptic_create_effect_p(void);
+static void utc_system_deviced_haptic_create_effect_n_1(void);
+static void utc_system_deviced_haptic_create_effect_n_2(void);
+static void utc_system_deviced_haptic_create_effect_n_3(void);
+static void utc_system_deviced_haptic_create_effect_n_4(void);
+static void utc_system_deviced_haptic_save_effect_p(void);
+static void utc_system_deviced_haptic_save_effect_n_1(void);
+static void utc_system_deviced_haptic_save_effect_n_2(void);
+static void utc_system_deviced_haptic_save_effect_n_3(void);
+static void utc_system_deviced_haptic_get_file_duration_p(void);
+static void utc_system_deviced_haptic_get_file_duration_n_1(void);
+static void utc_system_deviced_haptic_get_file_duration_n_2(void);
+static void utc_system_deviced_haptic_get_file_duration_n_3(void);
+static void utc_system_deviced_haptic_get_buffer_duration_p(void);
+static void utc_system_deviced_haptic_get_buffer_duration_n_1(void);
+static void utc_system_deviced_haptic_get_buffer_duration_n_2(void);
+static void utc_system_deviced_haptic_get_buffer_duration_n_3(void);
+static void utc_system_deviced_haptic_save_led_p(void);
+static void utc_system_deviced_haptic_save_led_n_1(void);
+static void utc_system_deviced_haptic_save_led_n_2(void);
+static void utc_system_deviced_haptic_save_led_n_3(void);
+
+enum {
+       POSITIVE_TC_IDX = 0x01,
+       NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+       { utc_system_deviced_haptic_get_count_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_get_count_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_open_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_open_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_open_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_create_effect_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_create_effect_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_create_effect_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_create_effect_n_3, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_create_effect_n_4, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_save_effect_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_save_effect_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_save_effect_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_save_effect_n_3, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_monotone_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_monotone_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_monotone_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_monotone_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_monotone_with_detail_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_monotone_with_detail_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_monotone_with_detail_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_monotone_with_detail_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_monotone_with_detail_n_3, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_monotone_with_detail_n_4, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_file_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_file_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_file_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_file_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_file_with_detail_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_file_with_detail_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_file_with_detail_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_file_with_detail_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_file_with_detail_n_3, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_file_with_detail_n_4, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_file_with_detail_n_5, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_n_3, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_with_detail_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_with_detail_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_with_detail_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_with_detail_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_with_detail_n_3, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_with_detail_n_4, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_with_detail_n_5, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_vibrate_buffers_with_detail_n_6, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_stop_all_effects_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_stop_all_effects_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_get_effect_state_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_get_effect_state_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_get_effect_state_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_get_file_duration_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_get_file_duration_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_get_file_duration_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_get_file_duration_n_3, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_get_buffer_duration_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_get_buffer_duration_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_get_buffer_duration_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_get_buffer_duration_n_3, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_save_led_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_save_led_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_save_led_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_save_led_n_3, NEGATIVE_TC_IDX },
+       { utc_system_deviced_haptic_close_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_haptic_close_n, NEGATIVE_TC_IDX },
+       { NULL, 0 },
+};
+
+#define DEVICED_FILE_PATH "/opt/usr/share/deviced"
+#define HAPTIC_FILE_PATH DEVICED_FILE_PATH"/test.ivt"
+#define BINARY_FILE_PATH DEVICED_FILE_PATH"/test.led"
+
+static haptic_device_h haptic_h;
+static unsigned char haptic_buffer[1024];
+static int haptic_buf_size = 1024;
+
+static void startup(void)
+{
+       int ret;
+
+       ret = mkdir(DEVICED_FILE_PATH, 0777);
+       if (ret < 0)
+               dts_message(API_NAME_HAPTIC_STARTUP,
+                               "fail to make direcotry(%s) : %s",
+                               DEVICED_FILE_PATH, strerror(errno));
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of haptic_get_count()
+ */
+static void utc_system_deviced_haptic_get_count_p(void)
+{
+       int val, ret;
+
+       ret = haptic_get_count(&val);
+       dts_check_eq(API_NAME_HAPTIC_GET_COUNT, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_get_count()
+ */
+static void utc_system_deviced_haptic_get_count_n(void)
+{
+       int ret;
+
+       ret = haptic_get_count(NULL);
+       dts_check_ne(API_NAME_HAPTIC_GET_COUNT, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_open()
+ */
+static void utc_system_deviced_haptic_open_p(void)
+{
+       int ret;
+
+       ret = haptic_open(HAPTIC_DEVICE_ALL, &haptic_h);
+       dts_check_eq(API_NAME_HAPTIC_OPEN, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_open()
+ */
+static void utc_system_deviced_haptic_open_n_1(void)
+{
+       int ret;
+
+       ret = haptic_open(-1, &haptic_h);
+       dts_check_ne(API_NAME_HAPTIC_OPEN, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_open()
+ */
+static void utc_system_deviced_haptic_open_n_2(void)
+{
+       int ret;
+
+       ret = haptic_open(HAPTIC_DEVICE_ALL, NULL);
+       dts_check_ne(API_NAME_HAPTIC_OPEN, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_close()
+ */
+static void utc_system_deviced_haptic_close_p(void)
+{
+       int ret;
+
+       ret = haptic_close(haptic_h);
+       dts_check_eq(API_NAME_HAPTIC_CLOSE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_close()
+ */
+static void utc_system_deviced_haptic_close_n(void)
+{
+       int ret;
+
+       ret = haptic_close((haptic_device_h)-1);
+       dts_check_ne(API_NAME_HAPTIC_CLOSE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_vibrate_monotone()
+ */
+static void utc_system_deviced_haptic_vibrate_monotone_p_1(void)
+{
+       haptic_effect_h eh;
+       int ret;
+
+       ret = haptic_vibrate_monotone(haptic_h, 1000, &eh);
+       dts_check_eq(API_NAME_HAPTIC_VIBRATE_MONOTONE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_vibrate_monotone()
+ */
+static void utc_system_deviced_haptic_vibrate_monotone_p_2(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_monotone(haptic_h, 1000, NULL);
+       dts_check_eq(API_NAME_HAPTIC_VIBRATE_MONOTONE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_monotone()
+ */
+static void utc_system_deviced_haptic_vibrate_monotone_n_1(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_monotone((haptic_device_h)-1, 1000, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_MONOTONE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_monotone()
+ */
+static void utc_system_deviced_haptic_vibrate_monotone_n_2(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_monotone(haptic_h, -1, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_MONOTONE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_vibrate_monotone_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_monotone_with_detail_p_1(void)
+{
+       haptic_effect_h eh;
+       int ret;
+
+       ret = haptic_vibrate_monotone_with_detail(haptic_h, 1000,
+                       HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, &eh);
+       dts_check_eq(API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_vibrate_monotone_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_monotone_with_detail_p_2(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_monotone_with_detail(haptic_h, 1000,
+                       HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_eq(API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_monotone_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_1(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_monotone_with_detail((haptic_device_h)-1, 1000,
+                       HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_monotone_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_2(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_monotone_with_detail(haptic_h, -1,
+                       HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_monotone_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_3(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_monotone_with_detail(haptic_h, 1000,
+                       -1, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_monotone_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_monotone_with_detail_n_4(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_monotone_with_detail(haptic_h, 1000,
+                       HAPTIC_FEEDBACK_5, -1, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_MONOTONE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_vibrate_file()
+ */
+static void utc_system_deviced_haptic_vibrate_file_p_1(void)
+{
+       haptic_effect_h eh;
+       int ret;
+
+       ret = haptic_vibrate_file(haptic_h, HAPTIC_FILE_PATH, &eh);
+       dts_check_eq(API_NAME_HAPTIC_VIBRATE_FILE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_vibrate_file()
+ */
+static void utc_system_deviced_haptic_vibrate_file_p_2(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_file(haptic_h, HAPTIC_FILE_PATH, NULL);
+       dts_check_eq(API_NAME_HAPTIC_VIBRATE_FILE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_file()
+ */
+static void utc_system_deviced_haptic_vibrate_file_n_1(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_file((haptic_device_h)-1, HAPTIC_FILE_PATH, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_file()
+ */
+static void utc_system_deviced_haptic_vibrate_file_n_2(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_file(haptic_h, NULL, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_vibrate_file_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_file_with_detail_p_1(void)
+{
+       haptic_effect_h eh;
+       int ret;
+
+       ret = haptic_vibrate_file_with_detail(haptic_h, HAPTIC_FILE_PATH,
+                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, &eh);
+       dts_check_eq(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_vibrate_file_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_file_with_detail_p_2(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_file_with_detail(haptic_h, HAPTIC_FILE_PATH,
+                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_eq(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_file_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_file_with_detail_n_1(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_file_with_detail((haptic_device_h)-1, HAPTIC_FILE_PATH,
+                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_file_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_file_with_detail_n_2(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_file_with_detail(haptic_h, NULL,
+                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_file_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_file_with_detail_n_3(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_file_with_detail(haptic_h, HAPTIC_FILE_PATH,
+                       -1, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_file_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_file_with_detail_n_4(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_file_with_detail(haptic_h, HAPTIC_FILE_PATH,
+                       HAPTIC_ITERATION_ONCE, -1, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_file_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_file_with_detail_n_5(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_file_with_detail(haptic_h, HAPTIC_FILE_PATH,
+                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, -1, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_FILE_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_vibrate_buffers()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_p_1(void)
+{
+       haptic_effect_h eh;
+       int ret;
+
+       ret = haptic_vibrate_buffers(haptic_h, haptic_buffer, haptic_buf_size, &eh);
+       dts_check_eq(API_NAME_HAPTIC_VIBRATE_BUFFERS, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_vibrate_buffers()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_p_2(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_buffers(haptic_h, haptic_buffer, haptic_buf_size, NULL);
+       dts_check_eq(API_NAME_HAPTIC_VIBRATE_BUFFERS, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_buffers()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_n_1(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_buffers((haptic_device_h)-1, haptic_buffer, haptic_buf_size, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_buffers()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_n_2(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_buffers(haptic_h, NULL, haptic_buf_size, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_buffers()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_n_3(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_buffers(haptic_h, haptic_buffer, -1, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_vibrate_buffers_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_p_1(void)
+{
+       haptic_effect_h eh;
+       int ret;
+
+       ret = haptic_vibrate_buffers_with_detail(haptic_h, haptic_buffer, haptic_buf_size,
+                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, &eh);
+       dts_check_eq(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_vibrate_buffers_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_p_2(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_buffers_with_detail(haptic_h, haptic_buffer, haptic_buf_size,
+                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_eq(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_buffers_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_1(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_buffers_with_detail((haptic_device_h)-1, haptic_buffer, haptic_buf_size,
+                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_buffers_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_2(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_buffers_with_detail(haptic_h, NULL, haptic_buf_size,
+                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_buffers_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_3(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_buffers_with_detail(haptic_h, haptic_buffer, -1,
+                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_buffers_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_4(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_buffers_with_detail(haptic_h, haptic_buffer, haptic_buf_size,
+                       -1, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_buffers_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_5(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_buffers_with_detail(haptic_h, haptic_buffer, haptic_buf_size,
+                       HAPTIC_ITERATION_ONCE, -1, HAPTIC_PRIORITY_MIN, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_vibrate_buffers_with_detail()
+ */
+static void utc_system_deviced_haptic_vibrate_buffers_with_detail_n_6(void)
+{
+       int ret;
+
+       ret = haptic_vibrate_buffers_with_detail(haptic_h, haptic_buffer, haptic_buf_size,
+                       HAPTIC_ITERATION_ONCE, HAPTIC_FEEDBACK_5, -1, NULL);
+       dts_check_ne(API_NAME_HAPTIC_VIBRATE_BUFFERS_WITH_DETAIL, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_stop_all_effects()
+ */
+static void utc_system_deviced_haptic_stop_all_effects_p(void)
+{
+       int ret;
+
+       ret = haptic_stop_all_effects(haptic_h);
+       dts_check_eq(API_NAME_HAPTIC_STOP_ALL_EFFECTS, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_stop_all_effects()
+ */
+static void utc_system_deviced_haptic_stop_all_effects_n(void)
+{
+       int ret;
+
+       ret = haptic_stop_all_effects((haptic_device_h)-1);
+       dts_check_ne(API_NAME_HAPTIC_STOP_ALL_EFFECTS, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_get_effect_state()
+ */
+static void utc_system_deviced_haptic_get_effect_state_p(void)
+{
+       haptic_state_e val;
+       int ret;
+
+       ret = haptic_get_effect_state(haptic_h, (haptic_effect_h)0, &val);
+       dts_check_eq(API_NAME_HAPTIC_GET_EFFECT_STATE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_get_effect_state()
+ */
+static void utc_system_deviced_haptic_get_effect_state_n_1(void)
+{
+       haptic_state_e val;
+       int ret;
+
+       ret = haptic_get_effect_state((haptic_device_h)NULL, (haptic_effect_h)0, &val);
+       dts_check_ne(API_NAME_HAPTIC_GET_EFFECT_STATE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_get_effect_state()
+ */
+static void utc_system_deviced_haptic_get_effect_state_n_2(void)
+{
+       int ret;
+
+       ret = haptic_get_effect_state(haptic_h, 0, NULL);
+       dts_check_ne(API_NAME_HAPTIC_GET_EFFECT_STATE, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_create_effect()
+ */
+static void utc_system_deviced_haptic_create_effect_p(void)
+{
+       int ret;
+       haptic_effect_element_s elem[3] = { {1000, 100}, {500, 0}, {500, 100} };
+
+       ret = haptic_create_effect(haptic_buffer, haptic_buf_size, elem, 3);
+       dts_check_eq(API_NAME_HAPTIC_CREATE_EFFECT, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_create_effect()
+ */
+static void utc_system_deviced_haptic_create_effect_n_1(void)
+{
+       int ret;
+       haptic_effect_element_s elem[3] = { {1000, 100}, {500, 0}, {500, 100} };
+
+       ret = haptic_create_effect(NULL, haptic_buf_size, elem, 3);
+       dts_check_ne(API_NAME_HAPTIC_CREATE_EFFECT, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_create_effect()
+ */
+static void utc_system_deviced_haptic_create_effect_n_2(void)
+{
+       int ret;
+       haptic_effect_element_s elem[3] = { {1000, 100}, {500, 0}, {500, 100} };
+
+       ret = haptic_create_effect(haptic_buffer, -1, elem, 3);
+       dts_check_ne(API_NAME_HAPTIC_CREATE_EFFECT, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_create_effect()
+ */
+static void utc_system_deviced_haptic_create_effect_n_3(void)
+{
+       int ret;
+
+       ret = haptic_create_effect(haptic_buffer, haptic_buf_size, NULL, 3);
+       dts_check_ne(API_NAME_HAPTIC_CREATE_EFFECT, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_create_effect()
+ */
+static void utc_system_deviced_haptic_create_effect_n_4(void)
+{
+       int ret;
+       haptic_effect_element_s elem[3] = { {1000, 100}, {500, 0}, {500, 100} };
+
+       ret = haptic_create_effect(haptic_buffer, haptic_buf_size, elem, -1);
+       dts_check_ne(API_NAME_HAPTIC_CREATE_EFFECT, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_save_effect()
+ */
+static void utc_system_deviced_haptic_save_effect_p(void)
+{
+       int ret;
+
+       ret = haptic_save_effect(haptic_buffer, haptic_buf_size, HAPTIC_FILE_PATH);
+       dts_check_eq(API_NAME_HAPTIC_SAVE_EFFECT, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_save_effect()
+ */
+static void utc_system_deviced_haptic_save_effect_n_1(void)
+{
+       int ret;
+
+       ret = haptic_save_effect(NULL, haptic_buf_size, HAPTIC_FILE_PATH);
+       dts_check_ne(API_NAME_HAPTIC_SAVE_EFFECT, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_save_effect()
+ */
+static void utc_system_deviced_haptic_save_effect_n_2(void)
+{
+       int ret;
+
+       ret = haptic_save_effect(haptic_buffer, -1, HAPTIC_FILE_PATH);
+       dts_check_ne(API_NAME_HAPTIC_SAVE_EFFECT, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_save_effect()
+ */
+static void utc_system_deviced_haptic_save_effect_n_3(void)
+{
+       int ret;
+
+       ret = haptic_save_effect(haptic_buffer, haptic_buf_size, NULL);
+       dts_check_ne(API_NAME_HAPTIC_SAVE_EFFECT, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_get_file_duration()
+ */
+static void utc_system_deviced_haptic_get_file_duration_p(void)
+{
+       int val, ret;
+
+       ret = haptic_get_file_duration(haptic_h, HAPTIC_FILE_PATH, &val);
+       dts_check_eq(API_NAME_HAPTIC_GET_FILE_DURATION, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_get_file_duration()
+ */
+static void utc_system_deviced_haptic_get_file_duration_n_1(void)
+{
+       int val, ret;
+
+       ret = haptic_get_file_duration((haptic_device_h)-1, HAPTIC_FILE_PATH, &val);
+       dts_check_ne(API_NAME_HAPTIC_GET_FILE_DURATION, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_get_file_duration()
+ */
+static void utc_system_deviced_haptic_get_file_duration_n_2(void)
+{
+       int val, ret;
+
+       ret = haptic_get_file_duration(haptic_h, NULL, &val);
+       dts_check_ne(API_NAME_HAPTIC_GET_FILE_DURATION, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_get_file_duration()
+ */
+static void utc_system_deviced_haptic_get_file_duration_n_3(void)
+{
+       int ret;
+
+       ret = haptic_get_file_duration(haptic_h, HAPTIC_FILE_PATH, NULL);
+       dts_check_ne(API_NAME_HAPTIC_GET_FILE_DURATION, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_get_buffer_duration()
+ */
+static void utc_system_deviced_haptic_get_buffer_duration_p(void)
+{
+       int val, ret;
+
+       ret = haptic_get_buffer_duration(haptic_h, haptic_buffer, &val);
+       dts_check_eq(API_NAME_HAPTIC_GET_BUFFER_DURATION, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_get_buffer_duration()
+ */
+static void utc_system_deviced_haptic_get_buffer_duration_n_1(void)
+{
+       int val, ret;
+
+       ret = haptic_get_buffer_duration((haptic_device_h)-1, haptic_buffer, &val);
+       dts_check_ne(API_NAME_HAPTIC_GET_BUFFER_DURATION, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_get_buffer_duration()
+ */
+static void utc_system_deviced_haptic_get_buffer_duration_n_2(void)
+{
+       int val, ret;
+
+       ret = haptic_get_buffer_duration(haptic_h, NULL, &val);
+       dts_check_ne(API_NAME_HAPTIC_GET_BUFFER_DURATION, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_get_buffer_duration()
+ */
+static void utc_system_deviced_haptic_get_buffer_duration_n_3(void)
+{
+       int ret;
+
+       ret = haptic_get_buffer_duration(haptic_h, haptic_buffer, NULL);
+       dts_check_ne(API_NAME_HAPTIC_GET_BUFFER_DURATION, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Positive test case of haptic_save_led()
+ */
+static void utc_system_deviced_haptic_save_led_p(void)
+{
+       int ret;
+
+       ret = haptic_save_led(haptic_buffer, haptic_buf_size, BINARY_FILE_PATH);
+       dts_check_eq(API_NAME_HAPTIC_SAVE_LED, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_save_led()
+ */
+static void utc_system_deviced_haptic_save_led_n_1(void)
+{
+       int ret;
+
+       ret = haptic_save_led(NULL, haptic_buf_size, BINARY_FILE_PATH);
+       dts_check_ne(API_NAME_HAPTIC_SAVE_LED, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_save_led()
+ */
+static void utc_system_deviced_haptic_save_led_n_2(void)
+{
+       int ret;
+
+       ret = haptic_save_led(haptic_buffer, -1, BINARY_FILE_PATH);
+       dts_check_ne(API_NAME_HAPTIC_SAVE_LED, ret, HAPTIC_ERROR_NONE);
+}
+
+/**
+ * @brief Negative test case of haptic_save_led()
+ */
+static void utc_system_deviced_haptic_save_led_n_3(void)
+{
+       int ret;
+
+       ret = haptic_save_led(haptic_buffer, haptic_buf_size, NULL);
+       dts_check_ne(API_NAME_HAPTIC_SAVE_LED, ret, HAPTIC_ERROR_NONE);
+}
diff --git a/test/testcase/utc_system_deviced_led.c b/test/testcase/utc_system_deviced_led.c
new file mode 100644 (file)
index 0000000..0bb512f
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of SAMSUNG
+ * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
+ * this software is owned by Samsung and you shall not disclose such
+ * Confidential Information and shall use it only in accordance with the terms
+ * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
+ * make no representations or warranties about the suitability of the software,
+ * either express or implied, including but not limited to the implied
+ * warranties of merchantability, fitness for a particular purpose, or
+ * non-infringement. SAMSUNG shall not be liable for any damages suffered by
+ * licensee arising out of or related to this software.
+ *
+ */
+#include <tet_api.h>
+#include <dd-led.h>
+
+#define API_NAME_LED_GET_BRIGHTNESS "led_get_brightness"
+#define API_NAME_LED_GET_MAX_BRIGHTNESS "led_get_max_brightness"
+#define API_NAME_LED_SET_BRIGHTNESS_WITH_NOTI "led_set_brightness_with_noti"
+#define API_NAME_LED_SET_IR_COMMAND "led_set_ir_command"
+#define API_NAME_LED_SET_MODE_WITH_COLOR "led_set_mode_with_color"
+#define API_NAME_LED_SET_MODE_WITH_PROPERTY "led_set_mode_with_property"
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+
+static void utc_system_deviced_led_get_brightness_p(void);
+static void utc_system_deviced_led_get_max_brightness_p(void);
+static void utc_system_deviced_led_set_brightness_with_noti_p_1(void);
+static void utc_system_deviced_led_set_brightness_with_noti_p_2(void);
+static void utc_system_deviced_led_set_brightness_with_noti_n(void);
+static void utc_system_deviced_led_set_ir_command_p(void);
+static void utc_system_deviced_led_set_ir_command_n(void);
+static void utc_system_deviced_led_set_mode_with_color_p_1(void);
+static void utc_system_deviced_led_set_mode_with_color_p_2(void);
+static void utc_system_deviced_led_set_mode_with_color_n(void);
+static void utc_system_deviced_led_set_mode_with_property_p_1(void);
+static void utc_system_deviced_led_set_mode_with_property_p_2(void);
+static void utc_system_deviced_led_set_mode_with_property_p_3(void);
+static void utc_system_deviced_led_set_mode_with_property_p_4(void);
+static void utc_system_deviced_led_set_mode_with_property_n(void);
+
+enum {
+       POSITIVE_TC_IDX = 0x01,
+       NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+       { utc_system_deviced_led_get_brightness_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_led_get_max_brightness_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_led_set_brightness_with_noti_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_led_set_brightness_with_noti_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_led_set_brightness_with_noti_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_led_set_ir_command_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_led_set_ir_command_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_led_set_mode_with_color_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_led_set_mode_with_color_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_led_set_mode_with_color_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_led_set_mode_with_property_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_led_set_mode_with_property_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_led_set_mode_with_property_p_3, POSITIVE_TC_IDX },
+       { utc_system_deviced_led_set_mode_with_property_p_4, POSITIVE_TC_IDX },
+       { utc_system_deviced_led_set_mode_with_property_n, NEGATIVE_TC_IDX },
+       { NULL, 0 },
+};
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of led_get_brightness()
+ */
+static void utc_system_deviced_led_get_brightness_p(void)
+{
+       int ret;
+
+       ret = led_get_brightness();
+       dts_check_ge(API_NAME_LED_GET_BRIGHTNESS, ret, 0);
+}
+
+/**
+ * @brief Positive test case of led_get_max_brightness()
+ */
+static void utc_system_deviced_led_get_max_brightness_p(void)
+{
+       int ret;
+
+       ret = led_get_max_brightness();
+       dts_check_ge(API_NAME_LED_GET_MAX_BRIGHTNESS, ret, 0);
+}
+
+/**
+ * @brief Positive test case of led_set_brightness_with_noti()
+ */
+static void utc_system_deviced_led_set_brightness_with_noti_p_1(void)
+{
+       int max, ret;
+
+       max = led_get_max_brightness();
+
+       ret = led_set_brightness_with_noti(max, true);
+       dts_check_eq(API_NAME_LED_SET_BRIGHTNESS_WITH_NOTI, ret, 0, "Turn on torchled");
+}
+
+/**
+ * @brief Positive test case of led_set_brightness_with_noti()
+ */
+static void utc_system_deviced_led_set_brightness_with_noti_p_2(void)
+{
+       int ret;
+
+       ret = led_set_brightness_with_noti(0, true);
+       dts_check_eq(API_NAME_LED_SET_BRIGHTNESS_WITH_NOTI, ret, 0, "Turn off torchled");
+}
+
+/**
+ * @brief Negative test case of led_set_brightness_with_noti()
+ */
+static void utc_system_deviced_led_set_brightness_with_noti_n(void)
+{
+       int ret;
+
+       ret = led_set_brightness_with_noti(-1, true);
+       dts_check_ne(API_NAME_LED_SET_BRIGHTNESS_WITH_NOTI, ret, 0);
+}
+
+/**
+ * @brief Positive test case of led_set_ir_command()
+ */
+static void utc_system_deviced_led_set_ir_command_p(void)
+{
+       int ret;
+
+       ret = led_set_ir_command("38000,173,171,24,1880");
+       dts_check_eq(API_NAME_LED_SET_IR_COMMAND, ret, 0);
+}
+
+/**
+ * @brief Negative test case of led_set_ir_command()
+ */
+static void utc_system_deviced_led_set_ir_command_n(void)
+{
+       int ret;
+
+       ret = led_set_ir_command(NULL);
+       dts_check_ne(API_NAME_LED_SET_IR_COMMAND, ret, 0);
+}
+
+/**
+ * @brief Positive test case of led_set_mode_with_color()
+ */
+static void utc_system_deviced_led_set_mode_with_color_p_1(void)
+{
+       int ret;
+
+       ret = led_set_mode_with_color(LED_MISSED_NOTI, true, 0xffff00ff);
+       dts_check_eq(API_NAME_LED_SET_MODE_WITH_COLOR, ret, 0);
+}
+
+/**
+ * @brief Positive test case of led_set_mode_with_color()
+ */
+static void utc_system_deviced_led_set_mode_with_color_p_2(void)
+{
+       int ret;
+
+       ret = led_set_mode_with_color(LED_MISSED_NOTI, false, 0xffff00ff);
+       dts_check_eq(API_NAME_LED_SET_MODE_WITH_COLOR, ret, 0);
+}
+
+/**
+ * @brief Negative test case of led_set_mode_with_color()
+ */
+static void utc_system_deviced_led_set_mode_with_color_n(void)
+{
+       int ret;
+
+       ret = led_set_mode_with_color(-1, true, 0xffff00ff);
+       dts_check_ne(API_NAME_LED_SET_MODE_WITH_COLOR, ret, 0);
+}
+
+/**
+ * @brief Positive test case of led_set_mode_with_property()
+ */
+static void utc_system_deviced_led_set_mode_with_property_p_1(void)
+{
+       int ret;
+
+       ret = led_set_mode_with_property(LED_MISSED_NOTI, true, 500, 500, 0xffff00ff);
+       dts_check_eq(API_NAME_LED_SET_MODE_WITH_PROPERTY, ret, 0);
+}
+
+/**
+ * @brief Positive test case of led_set_mode_with_property()
+ */
+static void utc_system_deviced_led_set_mode_with_property_p_2(void)
+{
+       int ret;
+
+       ret = led_set_mode_with_property(LED_MISSED_NOTI, false, 500, 500, 0xffff00ff);
+       dts_check_eq(API_NAME_LED_SET_MODE_WITH_PROPERTY, ret, 0);
+}
+
+/**
+ * @brief Positive test case of led_set_mode_with_property()
+ */
+static void utc_system_deviced_led_set_mode_with_property_p_3(void)
+{
+       int ret;
+
+       ret = led_set_mode_with_property(LED_MISSED_NOTI, true, -1, 500, 0xffff00ff);
+       dts_check_eq(API_NAME_LED_SET_MODE_WITH_PROPERTY, ret, 0);
+}
+
+/**
+ * @brief Positive test case of led_set_mode_with_property()
+ */
+static void utc_system_deviced_led_set_mode_with_property_p_4(void)
+{
+       int ret;
+
+       ret = led_set_mode_with_property(LED_MISSED_NOTI, true, 500, -1, 0xffff00ff);
+       dts_check_eq(API_NAME_LED_SET_MODE_WITH_PROPERTY, ret, 0);
+}
+
+/**
+ * @brief Negative test case of led_set_mode_with_property()
+ */
+static void utc_system_deviced_led_set_mode_with_property_n(void)
+{
+       int ret;
+
+       ret = led_set_mode_with_property(-1, true, 500, 500, 0xffff00ff);
+       dts_check_ne(API_NAME_LED_SET_MODE_WITH_PROPERTY, ret, 0);
+}
diff --git a/test/testcase/utc_system_deviced_mmc.c b/test/testcase/utc_system_deviced_mmc.c
new file mode 100644 (file)
index 0000000..8a326b9
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of SAMSUNG
+ * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
+ * this software is owned by Samsung and you shall not disclose such
+ * Confidential Information and shall use it only in accordance with the terms
+ * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
+ * make no representations or warranties about the suitability of the software,
+ * either express or implied, including but not limited to the implied
+ * warranties of merchantability, fitness for a particular purpose, or
+ * non-infringement. SAMSUNG shall not be liable for any damages suffered by
+ * licensee arising out of or related to this software.
+ *
+ */
+#include <tet_api.h>
+#include <dd-mmc.h>
+
+#define API_NAME_MMC_SECURE_MOUNT "mmc_secure_mount"
+#define API_NAME_MMC_SECURE_UNMOUNT "mmc_secure_unmount"
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+
+static void utc_system_deviced_mmc_secure_mount_p(void);
+static void utc_system_deviced_mmc_secure_mount_n(void);
+static void utc_system_deviced_mmc_secure_unmount_p(void);
+static void utc_system_deviced_mmc_secure_unmount_n(void);
+
+enum {
+       POSITIVE_TC_IDX = 0x01,
+       NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+       { utc_system_deviced_mmc_secure_mount_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_mmc_secure_mount_n, NEGATIVE_TC_IDX },
+       { utc_system_deviced_mmc_secure_unmount_p, POSITIVE_TC_IDX },
+       { utc_system_deviced_mmc_secure_unmount_n, NEGATIVE_TC_IDX },
+       { NULL, 0 },
+};
+
+#define SECURE_MOUNT_POINT "/opt/storage/secure"
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of mmc_secure_mount()
+ */
+static void utc_system_deviced_mmc_secure_mount_p(void)
+{
+       int ret;
+
+       dts_message("This testcase is only valid when mmc is inserted");
+
+       ret = mmc_secure_mount(SECURE_MOUNT_POINT);
+       dts_check_eq(API_NAME_MMC_SECURE_MOUNT, ret, 0);
+}
+
+/**
+ * @brief Negative test case of mmc_secure_mount()
+ */
+static void utc_system_deviced_mmc_secure_mount_n(void)
+{
+       int ret;
+
+       dts_message("This testcase is only valid when mmc is inserted");
+
+       ret = mmc_secure_mount(NULL);
+       dts_check_ne(API_NAME_MMC_SECURE_MOUNT, ret, 0);
+}
+
+/**
+ * @brief Positive test case of mmc_secure_unmount()
+ */
+static void utc_system_deviced_mmc_secure_unmount_p(void)
+{
+       int ret;
+
+       ret = mmc_secure_unmount(SECURE_MOUNT_POINT);
+       dts_check_eq(API_NAME_MMC_SECURE_UNMOUNT, ret, 0);
+}
+
+/**
+ * @brief Negative test case of mmc_secure_unmount()
+ */
+static void utc_system_deviced_mmc_secure_unmount_n(void)
+{
+       int ret;
+
+       ret = mmc_secure_unmount(NULL);
+       dts_check_ne(API_NAME_MMC_SECURE_UNMOUNT, ret, 0);
+}
diff --git a/test/testcase/utc_system_deviced_storage.c b/test/testcase/utc_system_deviced_storage.c
new file mode 100644 (file)
index 0000000..3eab765
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of SAMSUNG
+ * ELECTRONICS ("Confidential Information"). You agree and acknowledge that
+ * this software is owned by Samsung and you shall not disclose such
+ * Confidential Information and shall use it only in accordance with the terms
+ * of the license agreement you entered into with SAMSUNG ELECTRONICS. SAMSUNG
+ * make no representations or warranties about the suitability of the software,
+ * either express or implied, including but not limited to the implied
+ * warranties of merchantability, fitness for a particular purpose, or
+ * non-infringement. SAMSUNG shall not be liable for any damages suffered by
+ * licensee arising out of or related to this software.
+ *
+ */
+#include <tet_api.h>
+#include <dd-storage.h>
+
+#define API_NAME_STORAGE_GET_PATH "storage_get_path"
+
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+
+static void utc_system_deviced_storage_get_path_p_1(void);
+static void utc_system_deviced_storage_get_path_p_2(void);
+static void utc_system_deviced_storage_get_path_p_3(void);
+static void utc_system_deviced_storage_get_path_n_1(void);
+static void utc_system_deviced_storage_get_path_n_2(void);
+static void utc_system_deviced_storage_get_path_n_3(void);
+
+enum {
+       POSITIVE_TC_IDX = 0x01,
+       NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+       { utc_system_deviced_storage_get_path_p_1, POSITIVE_TC_IDX },
+       { utc_system_deviced_storage_get_path_p_2, POSITIVE_TC_IDX },
+       { utc_system_deviced_storage_get_path_p_3, POSITIVE_TC_IDX },
+       { utc_system_deviced_storage_get_path_n_1, NEGATIVE_TC_IDX },
+       { utc_system_deviced_storage_get_path_n_2, NEGATIVE_TC_IDX },
+       { utc_system_deviced_storage_get_path_n_3, NEGATIVE_TC_IDX },
+       { NULL, 0 },
+};
+
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of storage_get_path()
+ */
+static void utc_system_deviced_storage_get_path_p_1(void)
+{
+       char path[40];
+       int ret;
+
+       ret = storage_get_path(STORAGE_DEFAULT, path, sizeof(path));
+       dts_check_eq(API_NAME_STORAGE_GET_PATH, ret, 0, "Default storage");
+}
+
+/**
+ * @brief Positive test case of storage_get_path()
+ */
+static void utc_system_deviced_storage_get_path_p_2(void)
+{
+       char path[40];
+       int ret;
+
+       ret = storage_get_path(STORAGE_INTERNAL, path, sizeof(path));
+       dts_check_eq(API_NAME_STORAGE_GET_PATH, ret, 0, "Internal storage");
+}
+
+/**
+ * @brief Positive test case of storage_get_path()
+ */
+static void utc_system_deviced_storage_get_path_p_3(void)
+{
+       char path[40];
+       int ret;
+
+       ret = storage_get_path(STORAGE_EXTERNAL, path, sizeof(path));
+       dts_check_eq(API_NAME_STORAGE_GET_PATH, ret, 0, "External storage");
+}
+
+/**
+ * @brief Negative test case of storage_get_path()
+ */
+static void utc_system_deviced_storage_get_path_n_1(void)
+{
+       char path[40];
+       int ret;
+
+       ret = storage_get_path(-1, path, sizeof(path));
+       dts_check_ne(API_NAME_STORAGE_GET_PATH, ret, 0);
+}
+
+/**
+ * @brief Negative test case of storage_get_path()
+ */
+static void utc_system_deviced_storage_get_path_n_2(void)
+{
+       char path[40];
+       int ret;
+
+       ret = storage_get_path(STORAGE_DEFAULT, NULL, sizeof(path));
+       dts_check_ne(API_NAME_STORAGE_GET_PATH, ret, 0);
+}
+
+/**
+ * @brief Negative test case of storage_get_path()
+ */
+static void utc_system_deviced_storage_get_path_n_3(void)
+{
+       char path[40];
+       int ret;
+
+       ret = storage_get_path(STORAGE_DEFAULT, path, -1);
+       dts_check_ne(API_NAME_STORAGE_GET_PATH, ret, 0);
+}
diff --git a/test/tet_scen b/test/tet_scen
new file mode 100644 (file)
index 0000000..03f029a
--- /dev/null
@@ -0,0 +1,7 @@
+all
+       ^TEST
+##### Scenarios for TEST #####
+
+# Test scenario
+TEST
+       :include:/testcase/tslist
diff --git a/test/tetbuild.cfg b/test/tetbuild.cfg
new file mode 100644 (file)
index 0000000..f7eda55
--- /dev/null
@@ -0,0 +1,5 @@
+TET_OUTPUT_CAPTURE=True # capture option for build operation checking
+TET_BUILD_TOOL=make # build with using make command
+TET_BUILD_FILE=-f Makefile # execution file (Makefile) for build
+TET_API_COMPLIANT=True # use TET API in Test Case ?
+TET_PASS_TC_NAME=True # report passed TC name in Journal file?
diff --git a/test/tetclean.cfg b/test/tetclean.cfg
new file mode 100644 (file)
index 0000000..02d7030
--- /dev/null
@@ -0,0 +1,5 @@
+TET_OUTPUT_CAPTURE=True # capture option
+TET_CLEAN_TOOL= make clean # clean tool
+TET_CLEAN_FILE= Makefile # file for clean
+TET_API_COMPLIANT=True # TET API useage 
+TET_PASS_TC_NAME=True # showing name , passed TC
diff --git a/test/tetexec.cfg b/test/tetexec.cfg
new file mode 100644 (file)
index 0000000..ef3e452
--- /dev/null
@@ -0,0 +1,5 @@
+TET_OUTPUT_CAPTURE=True # capturing execution or not
+TET_EXEC_TOOL=  # ex) exec : execution tool set up/ Optional
+TET_EXEC_FILE=   # ex) exectool : execution file/ Optional
+TET_API_COMPLIANT=True # Test case or Tool usesTET API?
+TET_PASS_TC_NAME=True # showing Passed TC name ?