--- /dev/null
+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>
--- /dev/null
+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)
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+# 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}
--- /dev/null
+# 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
--- /dev/null
+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 *
+
--- /dev/null
+[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
--- /dev/null
+[Unit]
+Description=Device Control Start %I
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/devicectl %I start
--- /dev/null
+[Unit]
+Description=Device Control Stop %I
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/devicectl %I stop
--- /dev/null
+[Unit]
+Description=prepare device daemon
+DefaultDependencies=no
+Before=deviced.service
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/deviced-pre.sh
--- /dev/null
+<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>
--- /dev/null
+# 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
--- /dev/null
+[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
--- /dev/null
+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
--- /dev/null
+<manifest>
+<request>
+ <domain name="_"/>
+</request>
+</manifest>
--- /dev/null
+<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>
--- /dev/null
+<manifest>
+ <define>
+ <domain name="liblogd"/>
+ </define>
+ <request>
+ <domain name="liblogd"/>
+ </request>
+ <assign>
+ <filesystem path="/usr/lib/liblogd.so" label="_" exec_label="none"/>
+ </assign>
+</manifest>
--- /dev/null
+[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
--- /dev/null
+[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
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
--- /dev/null
+#--------------------------------------
+# 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
+
--- /dev/null
+#!/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
--- /dev/null
+#!/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
+
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+ADD_SUBDIRECTORY(shared)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
+
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
+
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+[LOWBAT]
+#low battery level
+Normal=100
+Warning=15
+Critical=5
+PowerOff=3
+RealOff=0
--- /dev/null
+[LOWBAT]
+#low battery level
+Normal=100
+Warning=15
+Critical=5
+PowerOff=3
+RealOff=0
--- /dev/null
+/*
+ * 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)
+
--- /dev/null
+/*
+ * 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)
--- /dev/null
+[LOWBAT]
+#low battery level
+Normal=100
+Warning=15
+Critical=5
+PowerOff=1
+RealOff=0
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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, ¶m);
+ 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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(¬ifier_device_ops)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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;
+}
+
+
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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(¬i_device_ops)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+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)
+
--- /dev/null
+/*
+ * 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);
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
+
--- /dev/null
+/*
+ * 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)
+
--- /dev/null
+/*
+ * 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)
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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)
+
+/**
+ * @}
+ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+[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
+
--- /dev/null
+[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
+
--- /dev/null
+[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
+
--- /dev/null
+/*
+ * 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);
+ }
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
+
--- /dev/null
+/*
+ * 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 = µ_keyfilter_ops;
+
--- /dev/null
+/*
+ * 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;
+
--- /dev/null
+/*
+ * 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));
+ }
+}
+
--- /dev/null
+/*
+ * 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_
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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)
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+<?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>
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+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)
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+}
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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);
+}
+*/
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+[MMC]
+#mmc bdi max ratio
+MaxRatio=10
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+}
+*/
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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)
--- /dev/null
+[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
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+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)
+
--- /dev/null
+cd `dirname $0`
+
+. ../../../../../setup.conf || exit 1
+
+. ${TPLDIR}/cmake.tpl
+run
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+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)
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+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")
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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, ¶m[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();
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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___ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
+
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+<?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>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<usb-config>
+ <config-nodes>
+
+ <driver value="/sys/class/usb_mode/version"/>
+
+ <usb-drv ver="1.1 ">
+ <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 ">
+ <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 ">
+ <!-- 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 ">
+ <!-- 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>
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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);
+}
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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(¶ms);
+}
+
+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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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));
+}
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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(¶ms);
+}
+
+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)
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+PKG_NAME=deviced
+TET_INSTALL_HOST_PATH=/var/tmp/dts_fw/TETware
+TET_INSTALL_TARGET_PATH=/opt/home/TETware
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+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)
--- /dev/null
+/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
+
--- /dev/null
+/*
+ *
+ * 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);
+}
--- /dev/null
+/*
+ *
+ * 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");
+}
--- /dev/null
+/*
+ *
+ * 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);
+}
--- /dev/null
+/*
+ *
+ * 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);
+}
--- /dev/null
+/*
+ *
+ * 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);
+}
--- /dev/null
+/*
+ *
+ * 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);
+}
--- /dev/null
+/*
+ *
+ * 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);
+}
--- /dev/null
+/*
+ *
+ * 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);
+}
--- /dev/null
+/*
+ *
+ * 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);
+}
--- /dev/null
+all
+ ^TEST
+##### Scenarios for TEST #####
+
+# Test scenario
+TEST
+ :include:/testcase/tslist
--- /dev/null
+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?
--- /dev/null
+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
--- /dev/null
+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 ?