From 2bc00c9396ff8ec55a0d6586fc93d2ae36ab64d8 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Mon, 25 Oct 2021 19:59:13 +0900 Subject: [PATCH 01/16] shared: add test for libdeviced-common-private This test runs automatically at build time. If the test fails, build will fail. In addition to adding the test, collect existing usb-host-test under src/tests directory. Change-Id: Id825b5747c0e9144d390687bf7d0bf9293075b72 Signed-off-by: Youngjae Cho --- CMakeLists.txt | 19 ++--- packaging/deviced.spec | 1 + src/auto-test/CMakeLists.txt | 6 +- src/shared/CMakeLists.txt | 12 +++ src/shared/device-notifier.c | 1 + src/{core => shared}/execute.c | 0 src/shared/log.h | 4 + src/shared/plugin.c | 4 +- src/tests/shared/CMakeLists.txt | 37 +++++++++ src/tests/shared/test-bitmap.c | 95 ++++++++++++++++++++++ src/tests/shared/test-device-notifier.c | 66 +++++++++++++++ src/tests/shared/test-main.c | 24 ++++++ src/tests/shared/test-main.h | 19 +++++ src/tests/shared/test-mock.c | 20 +++++ src/tests/shared/test-mock.h | 11 +++ src/tests/shared/test-plugin.c | 65 +++++++++++++++ .../usb-host-ffs-test-daemon/CMakeLists.txt | 0 .../usb-host-ffs-test-daemon/descs_gen.c | 0 .../usb-host-ffs-test-daemon.c | 0 src/{ => tests}/usb-host-test/test_gadget.gs | 0 src/{ => tests}/usb-host-test/usb-host-test.c | 0 21 files changed, 371 insertions(+), 13 deletions(-) create mode 100644 src/shared/CMakeLists.txt rename src/{core => shared}/execute.c (100%) create mode 100644 src/tests/shared/CMakeLists.txt create mode 100644 src/tests/shared/test-bitmap.c create mode 100644 src/tests/shared/test-device-notifier.c create mode 100644 src/tests/shared/test-main.c create mode 100644 src/tests/shared/test-main.h create mode 100644 src/tests/shared/test-mock.c create mode 100644 src/tests/shared/test-mock.h create mode 100644 src/tests/shared/test-plugin.c rename src/{ => tests}/usb-host-ffs-test-daemon/CMakeLists.txt (100%) rename src/{ => tests}/usb-host-ffs-test-daemon/descs_gen.c (100%) rename src/{ => tests}/usb-host-ffs-test-daemon/usb-host-ffs-test-daemon.c (100%) rename src/{ => tests}/usb-host-test/test_gadget.gs (100%) rename src/{ => tests}/usb-host-test/usb-host-test.c (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index a75ab28..be87671 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,6 @@ SET(SRCS src/core/delayed-init-notifier.c src/core/devices.c src/core/event-handler.c - src/core/execute.c src/core/log.c src/core/main.c src/core/sig-handler.c @@ -144,9 +143,9 @@ IF(TIZEN_FEATURE_CPU_MODULE STREQUAL on) ENDIF() IF(TIZEN_FEATURE_USBHOST_TEST STREQUAL on) - ADD_SOURCE(src/usb-host-test USB_HOST_TEST_SRCS) + ADD_SOURCE(src/tests/usb-host-test USB_HOST_TEST_SRCS) SET(SRCS ${SRCS} ${USB_HOST_TEST_SRCS}) - INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/usb-host-test/test_gadget.gs + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/tests/usb-host-test/test_gadget.gs DESTINATION /etc/deviced/usb-host-test/) ENDIF() @@ -239,10 +238,7 @@ ENDIF() ADD_DEFINITIONS("-DDEBUG") # Build libdeviced-common-private.so -FILE(GLOB SHARED_SRC "src/shared/*.c") -ADD_LIBRARY(deviced-common-private SHARED ${SHARED_SRC}) -TARGET_LINK_LIBRARIES(deviced-common-private ${REQUIRED_PKGS_LDFLAGS}) -INSTALL(TARGETS deviced-common-private DESTINATION ${CMAKE_INSTALL_LIBDIR}) +ADD_SUBDIRECTORY(src/shared) ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) SET(deviced_LDFLAGS ${REQUIRED_PKGS_LDFLAGS}) @@ -250,7 +246,7 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${REQUIRED_PKGS_LDFLAGS} "-lrt -ldl -lm" d INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) IF(POWER_MODULE STREQUAL on) - ADD_EXECUTABLE(deviced-shutdown src/power-shutdown/shutdown.c src/shared/common.c src/core/execute.c) + ADD_EXECUTABLE(deviced-shutdown src/power-shutdown/shutdown.c src/shared/common.c src/shared/execute.c) SET(deviced-shutdown_LDFLAGS ${REQUIRED_PKGS_LDFLAGS}) TARGET_LINK_LIBRARIES(deviced-shutdown ${REQUIRED_PKGS_LDFLAGS} "-lrt -ldl -lm" deviced-common-private) INSTALL(TARGETS deviced-shutdown DESTINATION /usr/lib/systemd) @@ -265,7 +261,7 @@ IF(POWER_MODULE STREQUAL on) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/systemd/deviced-request-shutdown-exit.conf DESTINATION /usr/lib/systemd/system/systemd-exit.service.d) - ADD_EXECUTABLE(deviced-request-shutdown src/power-command/command.c src/shared/common.c src/core/execute.c) + ADD_EXECUTABLE(deviced-request-shutdown src/power-command/command.c src/shared/common.c src/shared/execute.c) SET(deviced-request-shutdown_LDFLAGS ${REQUIRED_PKGS_LDFLAGS}) TARGET_LINK_LIBRARIES(deviced-request-shutdown ${REQUIRED_PKGS_LDFLAGS} "-lrt -ldl -lm" deviced-common-private) INSTALL(TARGETS deviced-request-shutdown DESTINATION /usr/sbin) @@ -328,7 +324,7 @@ ADD_SUBDIRECTORY(src/libdeviced) ADD_SUBDIRECTORY(src/tools/devicectl) ADD_SUBDIRECTORY(src/tools/partition-switch) IF(TIZEN_FEATURE_USBHOST_TEST STREQUAL on) - ADD_SUBDIRECTORY(src/usb-host-ffs-test-daemon) + ADD_SUBDIRECTORY(src/tests/usb-host-ffs-test-daemon) ENDIF() ADD_SUBDIRECTORY(src/auto-test) @@ -351,3 +347,6 @@ INSTALL_CONF(conf mobile-display) INSTALL_CONF(conf wearable-display) INSTALL_CONF(conf tv-display) INSTALL_CONF(conf iot-headed-display) + +# Tests +ADD_SUBDIRECTORY(src/tests/shared) diff --git a/packaging/deviced.spec b/packaging/deviced.spec index 4b3a7c1..cb13612 100644 --- a/packaging/deviced.spec +++ b/packaging/deviced.spec @@ -41,6 +41,7 @@ BuildRequires: pkgconfig(tizen-extension-client) BuildRequires: pkgconfig(tizen-dpms-client) BuildRequires: pkgconfig(zlib) BuildRequires: pkgconfig(argos_watchdog) +BuildRequires: pkgconfig(cmocka) Requires: %{name}-tools = %{version}-%{release} %{?systemd_requires} diff --git a/src/auto-test/CMakeLists.txt b/src/auto-test/CMakeLists.txt index e75088c..91db6fd 100644 --- a/src/auto-test/CMakeLists.txt +++ b/src/auto-test/CMakeLists.txt @@ -31,7 +31,11 @@ SET(SRCS INCLUDE(FindPkgConfig) pkg_check_modules(pkgs REQUIRED - capi-system-device) + capi-system-device + vconf + udev + hal-api-common + hal-api-device) FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/src/shared/CMakeLists.txt b/src/shared/CMakeLists.txt new file mode 100644 index 0000000..44ad940 --- /dev/null +++ b/src/shared/CMakeLists.txt @@ -0,0 +1,12 @@ +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(SHARED_REQUIRED_PKGS REQUIRED + libsyscommon + dlog + bundle + capi-system-info + eventsystem) + +FILE(GLOB SHARED_SRCS "*.c") +ADD_LIBRARY(deviced-common-private SHARED ${SHARED_SRCS}) +TARGET_LINK_LIBRARIES(deviced-common-private ${SHARED_REQUIRED_PKGS_LDFLAGS}) +INSTALL(TARGETS deviced-common-private DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/src/shared/device-notifier.c b/src/shared/device-notifier.c index b755d37..08044f1 100644 --- a/src/shared/device-notifier.c +++ b/src/shared/device-notifier.c @@ -17,6 +17,7 @@ */ +#include #include "log.h" #include "device-notifier.h" #include "shared/common.h" diff --git a/src/core/execute.c b/src/shared/execute.c similarity index 100% rename from src/core/execute.c rename to src/shared/execute.c diff --git a/src/shared/log.h b/src/shared/log.h index 29b6c85..27681f2 100644 --- a/src/shared/log.h +++ b/src/shared/log.h @@ -24,6 +24,10 @@ #define ENABLE_DLOG #endif +#if defined(ENABLE_TEST) && defined(ENABLE_DLOG) +#undef ENABLE_DLOG +#endif + #define LOG_TAG "DEVICED" #include "shared/log-macro.h" diff --git a/src/shared/plugin.c b/src/shared/plugin.c index fc9b17b..d74f981 100644 --- a/src/shared/plugin.c +++ b/src/shared/plugin.c @@ -90,7 +90,7 @@ int unload_plugin(void *h) return dlclose(h); } -void load_plugins() +void load_plugins(void) { DIR *dir; void *handle = NULL; @@ -123,7 +123,7 @@ void load_plugins() return; } -void unload_plugins() +void unload_plugins(void) { GList *plugin = plgn_list; void *handle = NULL; diff --git a/src/tests/shared/CMakeLists.txt b/src/tests/shared/CMakeLists.txt new file mode 100644 index 0000000..5cd27ed --- /dev/null +++ b/src/tests/shared/CMakeLists.txt @@ -0,0 +1,37 @@ +SET(${CMAKE_C_FLAGS} $ENV{CFLAGS}) + +ADD_DEFINITIONS("-DENABLE_TEST") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) + +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(ORIG_REQUIRED_PKGS REQUIRED + libsyscommon + bundle + capi-system-info + eventsystem) + +SET(WRAP_FLAGS "-Wl,--wrap=dlopen") +SET(WRAP_FLAGS "${WRAP_FLAGS} -Wl,--wrap=access") + +FILE(GLOB ORIG_SRCS "${CMAKE_SOURCE_DIR}/src/shared/*.c") +ADD_LIBRARY(test-shared SHARED ${ORIG_SRCS}) +SET_TARGET_PROPERTIES(test-shared PROPERTIES LINK_FLAGS ${WRAP_FLAGS}) +TARGET_LINK_LIBRARIES(test-shared ${ORIG_REQUIRED_PKGS_LDFLAGS}) + +PKG_CHECK_MODULES(TEST_REQUIRED_PKGS REQUIRED cmocka) + +LIST(APPEND TEST_DRIVERS test-bitmap.c) +LIST(APPEND TEST_DRIVERS test-device-notifier.c) +LIST(APPEND TEST_DRIVERS test-plugin.c) + +ADD_EXECUTABLE(test-main test-main.c test-mock.c ${TEST_DRIVERS}) +ADD_DEPENDENCIES(test-main test-shared) +SET_TARGET_PROPERTIES(test-main PROPERTIES COMPILE_FLAGS "-rdynamic -Wno-unused-variable") +SET_TARGET_PROPERTIES(test-main PROPERTIES LINK_FLAGS "-Wl,--rpath=${CMAKE_CURRENT_SOURCE_DIR}") +TARGET_LINK_LIBRARIES(test-main test-shared dl ${TEST_REQUIRED_PKGS_LDFLAGS}) + +REMOVE_DEFINITIONS("-DENABLE_TEST") + +ADD_CUSTOM_TARGET(run-test ALL "./test-main") +ADD_DEPENDENCIES(run-test test-main) diff --git a/src/tests/shared/test-bitmap.c b/src/tests/shared/test-bitmap.c new file mode 100644 index 0000000..23e5644 --- /dev/null +++ b/src/tests/shared/test-bitmap.c @@ -0,0 +1,95 @@ +#include + +#include "test-main.h" + +static void test_init_bitmap_p(void **state) +{ + struct dd_bitmap *bm; + + bm = init_bitmap(10); + assert_non_null(bm); + + deinit_bitmap(bm); +} + +static void test_init_bitmap_n(void **state) +{ + struct dd_bitmap *bm = NULL; + + bm = init_bitmap(0); + assert_null(bm); +} + +static void test_test_bit(void **state) +{ + struct dd_bitmap *bm; + const int bmsize = 37; + bool bit; + int i, nbit; + + bm = init_bitmap(bmsize); + assert_non_null(bm); + + for (i = 0; i < bmsize; ++i) { + bit = test_bit(bm, i); + assert_false(bit); + } + + /* count bit by setting one by one */ + for (i = 0; i < bmsize; ++i) { + set_bit(bm, i); + nbit = count_set_bit(bm); + assert_int_equal(nbit, i + 1); + } + + /* test the marginal bit */ + bit = test_bit(bm, 0); + assert_true(bit); + bit = test_bit(bm, bmsize - 1); + assert_true(bit); + bit = test_bit(bm, bmsize); + assert_false(bit); + + + /* count bit by clearing one by one */ + for (i = 0; i < bmsize; ++i) { + clear_bit(bm, i); + nbit = count_set_bit(bm); + assert_int_equal(nbit, bmsize - i - 1); + } + + deinit_bitmap(bm); +} + +static void test_all_bit(void **state) +{ + struct dd_bitmap *bm; + const int bmsize = 37; + int nbit; + + bm = init_bitmap(bmsize); + assert_non_null(bm); + + set_all_bits(bm); + nbit = count_set_bit(bm); + assert_int_equal(nbit, bmsize); + + clear_all_bits(bm); + nbit = count_set_bit(bm); + assert_int_equal(nbit, 0); + + deinit_bitmap(bm); +} + +static int run_bitmap_test(void) +{ + static const struct CMUnitTest testsuite[] = { + cmocka_unit_test(test_init_bitmap_p), + cmocka_unit_test(test_init_bitmap_n), + cmocka_unit_test(test_test_bit), + cmocka_unit_test(test_all_bit), + }; + + return cmocka_run_group_tests(testsuite, NULL, NULL); +} +ADD_TEST_FUNCTION(run_bitmap_test) diff --git a/src/tests/shared/test-device-notifier.c b/src/tests/shared/test-device-notifier.c new file mode 100644 index 0000000..bc86513 --- /dev/null +++ b/src/tests/shared/test-device-notifier.c @@ -0,0 +1,66 @@ +#include +#include +#include + +#include "test-main.h" + +static int notified; + +static int notify_callback(void *data) +{ + notified = (int)(intptr_t) data; + + return 0; +} + +static void test_device_notify_n(void **state) +{ + int retval; + + retval = register_notifier(DEVICE_NOTIFIER_MAX, NULL); + assert_int_equal(retval, -EINVAL); +} + +static void test_device_notify_p(void **state) +{ + int retval; + + notified = 999; + + retval = register_notifier(DEVICE_NOTIFIER_LCD, notify_callback); + assert_int_equal(retval, 0); + + for (int i = 3; i < 8; ++i) { + device_notify(DEVICE_NOTIFIER_LCD, (void *)(intptr_t) i); + assert_int_equal(notified, i); + } +} + +static void test_device_notify_once_p(void **state) +{ + int retval; + int value = 721; + + notified = 999; + + retval = register_notifier(DEVICE_NOTIFIER_LCD_OFF, notify_callback); + assert_int_equal(retval, 0); + + device_notify_once(DEVICE_NOTIFIER_LCD_OFF, (void *)(intptr_t) value); + assert_int_equal(notified, value); + + device_notify(DEVICE_NOTIFIER_LCD_OFF, (void *)(intptr_t) (value - 1)); + assert_int_equal(notified, value); +} + +static int run_device_notifier_test(void) +{ + static const struct CMUnitTest testsuite[] = { + cmocka_unit_test(test_device_notify_n), + cmocka_unit_test(test_device_notify_p), + cmocka_unit_test(test_device_notify_once_p), + }; + + return cmocka_run_group_tests(testsuite, NULL, NULL); +} +ADD_TEST_FUNCTION(run_device_notifier_test) diff --git a/src/tests/shared/test-main.c b/src/tests/shared/test-main.c new file mode 100644 index 0000000..cb6b11a --- /dev/null +++ b/src/tests/shared/test-main.c @@ -0,0 +1,24 @@ +#include +#include + +#include "test-main.h" + +static GList *tests; + + +void __add_test_function(test_function f) +{ + SYS_G_LIST_APPEND(tests, f); +} + +int main(int argc, char *argv[]) +{ + GList *elem; + test_function run; + int failed = 0; + + SYS_G_LIST_FOREACH(tests, elem, run) + failed += run(); + + return failed; +} diff --git a/src/tests/shared/test-main.h b/src/tests/shared/test-main.h new file mode 100644 index 0000000..dc28c6f --- /dev/null +++ b/src/tests/shared/test-main.h @@ -0,0 +1,19 @@ +#ifndef __TEST_MAIN_H__ +#define __TEST_MAIN_H__ + +#include +#include +#include +#include + +typedef int (*test_function)(void); +void __add_test_function(test_function f); + +#define ADD_TEST_FUNCTION(f) \ +__attribute__((constructor)) \ +static void add_test_function(void) \ +{ \ + __add_test_function(f); \ +} + +#endif //__TEST_MAIN_H__ diff --git a/src/tests/shared/test-mock.c b/src/tests/shared/test-mock.c new file mode 100644 index 0000000..63ea2cd --- /dev/null +++ b/src/tests/shared/test-mock.c @@ -0,0 +1,20 @@ +#include + +#include "test-main.h" +#include "test-mock.h" + +int __wrap_access(const char *pathname, int mode) +{ + return mock_type(int); +} + +void *__wrap_dlopen(const char *filename, int flags) +{ + void *ret; + + ret = mock_ptr_type(void *); + if (ret == NULL) + return ret; + + return ret; +} diff --git a/src/tests/shared/test-mock.h b/src/tests/shared/test-mock.h new file mode 100644 index 0000000..6841770 --- /dev/null +++ b/src/tests/shared/test-mock.h @@ -0,0 +1,11 @@ +#ifndef __TEST_MOCK_H__ +#define __TEST_MOCK_H__ + +#include + +#include "test-main.h" + +int __wrap_access(const char *pathname, int mode); +void *__wrap_dlopen(const char *filename, int flags); + +#endif //__TEST_MOCK_H__ diff --git a/src/tests/shared/test-plugin.c b/src/tests/shared/test-plugin.c new file mode 100644 index 0000000..69c879a --- /dev/null +++ b/src/tests/shared/test-plugin.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include + +#include "test-main.h" +#include "test-mock.h" + +static void test_load_plugin_n1(void **state) +{ + int retval; + + retval = load_plugin("", NULL); + assert_int_equal(retval, -EINVAL); +} + +static void test_load_plugin_n2(void **state) +{ + int retval; + void *handle; + + /* not existing .so */ + will_return(__wrap_access, -1); + + retval = load_plugin("display.so", &handle); + assert_int_equal(retval, -ENODEV); +} + +static void test_load_plugin_n3(void **state) +{ + int retval; + void *handle; + + will_return(__wrap_access, 0); + will_return(__wrap_dlopen, NULL); + + retval = load_plugin("something.so", &handle); + assert_int_equal(retval, -ENOENT); +} + +static void test_load_plugin_p(void **state) +{ + int retval; + void *handle; + + will_return(__wrap_access, 0); + will_return(__wrap_dlopen, (void *)(intptr_t) 0x123); + + retval = load_plugin("something.so", &handle); + assert_int_equal(retval, 0); + assert_ptr_equal(handle, 0x123); +} + +static int run_plugin_test(void) +{ + static const struct CMUnitTest testsuite[] = { + cmocka_unit_test(test_load_plugin_n1), + cmocka_unit_test(test_load_plugin_n2), + cmocka_unit_test(test_load_plugin_n3), + cmocka_unit_test(test_load_plugin_p), + }; + + return cmocka_run_group_tests(testsuite, NULL, NULL); +} +ADD_TEST_FUNCTION(run_plugin_test) diff --git a/src/usb-host-ffs-test-daemon/CMakeLists.txt b/src/tests/usb-host-ffs-test-daemon/CMakeLists.txt similarity index 100% rename from src/usb-host-ffs-test-daemon/CMakeLists.txt rename to src/tests/usb-host-ffs-test-daemon/CMakeLists.txt diff --git a/src/usb-host-ffs-test-daemon/descs_gen.c b/src/tests/usb-host-ffs-test-daemon/descs_gen.c similarity index 100% rename from src/usb-host-ffs-test-daemon/descs_gen.c rename to src/tests/usb-host-ffs-test-daemon/descs_gen.c diff --git a/src/usb-host-ffs-test-daemon/usb-host-ffs-test-daemon.c b/src/tests/usb-host-ffs-test-daemon/usb-host-ffs-test-daemon.c similarity index 100% rename from src/usb-host-ffs-test-daemon/usb-host-ffs-test-daemon.c rename to src/tests/usb-host-ffs-test-daemon/usb-host-ffs-test-daemon.c diff --git a/src/usb-host-test/test_gadget.gs b/src/tests/usb-host-test/test_gadget.gs similarity index 100% rename from src/usb-host-test/test_gadget.gs rename to src/tests/usb-host-test/test_gadget.gs diff --git a/src/usb-host-test/usb-host-test.c b/src/tests/usb-host-test/usb-host-test.c similarity index 100% rename from src/usb-host-test/usb-host-test.c rename to src/tests/usb-host-test/usb-host-test.c -- 2.7.4 From 3fb87fc42a70b0fb475234befc77b29536ff3196 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Tue, 26 Oct 2021 10:36:25 +0900 Subject: [PATCH 02/16] tests: move tests to the topmost directory Change-Id: I96af0cd9a652d2f5d1ed5467d73e57de8c63850e Signed-off-by: Youngjae Cho --- CMakeLists.txt | 10 +++++----- {src => tests}/auto-test/CMakeLists.txt | 2 +- {src => tests}/auto-test/auto-test.conf | 0 {src => tests}/auto-test/battery-monitor-test.c | 0 {src => tests}/auto-test/battery.c | 0 {src => tests}/auto-test/boot.c | 0 {src => tests}/auto-test/brightness.c | 0 {src => tests}/auto-test/config.c | 0 {src => tests}/auto-test/config.h | 0 {src => tests}/auto-test/display.c | 0 {src => tests}/auto-test/extcon.c | 0 {src => tests}/auto-test/ir.c | 0 {src => tests}/auto-test/led.c | 0 {src => tests}/auto-test/main.c | 0 {src => tests}/auto-test/pmqos.c | 0 {src => tests}/auto-test/power.c | 0 {src => tests}/auto-test/proc.c | 0 {src => tests}/auto-test/result.c | 0 {src => tests}/auto-test/test.c | 0 {src => tests}/auto-test/test.h | 0 {src => tests}/auto-test/test_dbus_interface.c | 0 {src => tests}/auto-test/test_dbus_interface.h | 0 {src => tests}/auto-test/time.c | 0 {src => tests}/auto-test/touchscreen.c | 0 {src => tests}/auto-test/udev.c | 0 .../deviced-common-private-test}/CMakeLists.txt | 1 + .../shared => tests/deviced-common-private-test}/test-bitmap.c | 0 .../deviced-common-private-test}/test-device-notifier.c | 0 .../shared => tests/deviced-common-private-test}/test-main.c | 0 .../shared => tests/deviced-common-private-test}/test-main.h | 0 .../shared => tests/deviced-common-private-test}/test-mock.c | 0 .../shared => tests/deviced-common-private-test}/test-mock.h | 0 .../shared => tests/deviced-common-private-test}/test-plugin.c | 0 {src/tests => tests}/usb-host-ffs-test-daemon/CMakeLists.txt | 0 {src/tests => tests}/usb-host-ffs-test-daemon/descs_gen.c | 0 .../usb-host-ffs-test-daemon/usb-host-ffs-test-daemon.c | 0 {src/tests => tests}/usb-host-test/test_gadget.gs | 0 {src/tests => tests}/usb-host-test/usb-host-test.c | 0 38 files changed, 7 insertions(+), 6 deletions(-) rename {src => tests}/auto-test/CMakeLists.txt (95%) rename {src => tests}/auto-test/auto-test.conf (100%) rename {src => tests}/auto-test/battery-monitor-test.c (100%) rename {src => tests}/auto-test/battery.c (100%) rename {src => tests}/auto-test/boot.c (100%) rename {src => tests}/auto-test/brightness.c (100%) rename {src => tests}/auto-test/config.c (100%) rename {src => tests}/auto-test/config.h (100%) rename {src => tests}/auto-test/display.c (100%) rename {src => tests}/auto-test/extcon.c (100%) rename {src => tests}/auto-test/ir.c (100%) rename {src => tests}/auto-test/led.c (100%) rename {src => tests}/auto-test/main.c (100%) rename {src => tests}/auto-test/pmqos.c (100%) rename {src => tests}/auto-test/power.c (100%) rename {src => tests}/auto-test/proc.c (100%) rename {src => tests}/auto-test/result.c (100%) rename {src => tests}/auto-test/test.c (100%) rename {src => tests}/auto-test/test.h (100%) rename {src => tests}/auto-test/test_dbus_interface.c (100%) rename {src => tests}/auto-test/test_dbus_interface.h (100%) rename {src => tests}/auto-test/time.c (100%) rename {src => tests}/auto-test/touchscreen.c (100%) rename {src => tests}/auto-test/udev.c (100%) rename {src/tests/shared => tests/deviced-common-private-test}/CMakeLists.txt (96%) rename {src/tests/shared => tests/deviced-common-private-test}/test-bitmap.c (100%) rename {src/tests/shared => tests/deviced-common-private-test}/test-device-notifier.c (100%) rename {src/tests/shared => tests/deviced-common-private-test}/test-main.c (100%) rename {src/tests/shared => tests/deviced-common-private-test}/test-main.h (100%) rename {src/tests/shared => tests/deviced-common-private-test}/test-mock.c (100%) rename {src/tests/shared => tests/deviced-common-private-test}/test-mock.h (100%) rename {src/tests/shared => tests/deviced-common-private-test}/test-plugin.c (100%) rename {src/tests => tests}/usb-host-ffs-test-daemon/CMakeLists.txt (100%) rename {src/tests => tests}/usb-host-ffs-test-daemon/descs_gen.c (100%) rename {src/tests => tests}/usb-host-ffs-test-daemon/usb-host-ffs-test-daemon.c (100%) rename {src/tests => tests}/usb-host-test/test_gadget.gs (100%) rename {src/tests => tests}/usb-host-test/usb-host-test.c (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index be87671..926fcbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,9 +143,9 @@ IF(TIZEN_FEATURE_CPU_MODULE STREQUAL on) ENDIF() IF(TIZEN_FEATURE_USBHOST_TEST STREQUAL on) - ADD_SOURCE(src/tests/usb-host-test USB_HOST_TEST_SRCS) + ADD_SOURCE(tests/usb-host-test USB_HOST_TEST_SRCS) SET(SRCS ${SRCS} ${USB_HOST_TEST_SRCS}) - INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/tests/usb-host-test/test_gadget.gs + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/tests/usb-host-test/test_gadget.gs DESTINATION /etc/deviced/usb-host-test/) ENDIF() @@ -324,10 +324,9 @@ ADD_SUBDIRECTORY(src/libdeviced) ADD_SUBDIRECTORY(src/tools/devicectl) ADD_SUBDIRECTORY(src/tools/partition-switch) IF(TIZEN_FEATURE_USBHOST_TEST STREQUAL on) - ADD_SUBDIRECTORY(src/tests/usb-host-ffs-test-daemon) + ADD_SUBDIRECTORY(tests/usb-host-ffs-test-daemon) ENDIF() -ADD_SUBDIRECTORY(src/auto-test) # Plugins ADD_SOURCE(src/display DISPLAY_SRCS) @@ -349,4 +348,5 @@ INSTALL_CONF(conf tv-display) INSTALL_CONF(conf iot-headed-display) # Tests -ADD_SUBDIRECTORY(src/tests/shared) +ADD_SUBDIRECTORY(tests/deviced-common-private-test) +ADD_SUBDIRECTORY(tests/auto-test) diff --git a/src/auto-test/CMakeLists.txt b/tests/auto-test/CMakeLists.txt similarity index 95% rename from src/auto-test/CMakeLists.txt rename to tests/auto-test/CMakeLists.txt index 91db6fd..341c366 100644 --- a/src/auto-test/CMakeLists.txt +++ b/tests/auto-test/CMakeLists.txt @@ -1,7 +1,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(deviced-auto-test C) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src) IF("$ENV{CFLAGS}" MATCHES "-DTIZEN_ENGINEER_MODE") OPTION(USE_ENGINEER_MODE "Use Engineer mode" ON) diff --git a/src/auto-test/auto-test.conf b/tests/auto-test/auto-test.conf similarity index 100% rename from src/auto-test/auto-test.conf rename to tests/auto-test/auto-test.conf diff --git a/src/auto-test/battery-monitor-test.c b/tests/auto-test/battery-monitor-test.c similarity index 100% rename from src/auto-test/battery-monitor-test.c rename to tests/auto-test/battery-monitor-test.c diff --git a/src/auto-test/battery.c b/tests/auto-test/battery.c similarity index 100% rename from src/auto-test/battery.c rename to tests/auto-test/battery.c diff --git a/src/auto-test/boot.c b/tests/auto-test/boot.c similarity index 100% rename from src/auto-test/boot.c rename to tests/auto-test/boot.c diff --git a/src/auto-test/brightness.c b/tests/auto-test/brightness.c similarity index 100% rename from src/auto-test/brightness.c rename to tests/auto-test/brightness.c diff --git a/src/auto-test/config.c b/tests/auto-test/config.c similarity index 100% rename from src/auto-test/config.c rename to tests/auto-test/config.c diff --git a/src/auto-test/config.h b/tests/auto-test/config.h similarity index 100% rename from src/auto-test/config.h rename to tests/auto-test/config.h diff --git a/src/auto-test/display.c b/tests/auto-test/display.c similarity index 100% rename from src/auto-test/display.c rename to tests/auto-test/display.c diff --git a/src/auto-test/extcon.c b/tests/auto-test/extcon.c similarity index 100% rename from src/auto-test/extcon.c rename to tests/auto-test/extcon.c diff --git a/src/auto-test/ir.c b/tests/auto-test/ir.c similarity index 100% rename from src/auto-test/ir.c rename to tests/auto-test/ir.c diff --git a/src/auto-test/led.c b/tests/auto-test/led.c similarity index 100% rename from src/auto-test/led.c rename to tests/auto-test/led.c diff --git a/src/auto-test/main.c b/tests/auto-test/main.c similarity index 100% rename from src/auto-test/main.c rename to tests/auto-test/main.c diff --git a/src/auto-test/pmqos.c b/tests/auto-test/pmqos.c similarity index 100% rename from src/auto-test/pmqos.c rename to tests/auto-test/pmqos.c diff --git a/src/auto-test/power.c b/tests/auto-test/power.c similarity index 100% rename from src/auto-test/power.c rename to tests/auto-test/power.c diff --git a/src/auto-test/proc.c b/tests/auto-test/proc.c similarity index 100% rename from src/auto-test/proc.c rename to tests/auto-test/proc.c diff --git a/src/auto-test/result.c b/tests/auto-test/result.c similarity index 100% rename from src/auto-test/result.c rename to tests/auto-test/result.c diff --git a/src/auto-test/test.c b/tests/auto-test/test.c similarity index 100% rename from src/auto-test/test.c rename to tests/auto-test/test.c diff --git a/src/auto-test/test.h b/tests/auto-test/test.h similarity index 100% rename from src/auto-test/test.h rename to tests/auto-test/test.h diff --git a/src/auto-test/test_dbus_interface.c b/tests/auto-test/test_dbus_interface.c similarity index 100% rename from src/auto-test/test_dbus_interface.c rename to tests/auto-test/test_dbus_interface.c diff --git a/src/auto-test/test_dbus_interface.h b/tests/auto-test/test_dbus_interface.h similarity index 100% rename from src/auto-test/test_dbus_interface.h rename to tests/auto-test/test_dbus_interface.h diff --git a/src/auto-test/time.c b/tests/auto-test/time.c similarity index 100% rename from src/auto-test/time.c rename to tests/auto-test/time.c diff --git a/src/auto-test/touchscreen.c b/tests/auto-test/touchscreen.c similarity index 100% rename from src/auto-test/touchscreen.c rename to tests/auto-test/touchscreen.c diff --git a/src/auto-test/udev.c b/tests/auto-test/udev.c similarity index 100% rename from src/auto-test/udev.c rename to tests/auto-test/udev.c diff --git a/src/tests/shared/CMakeLists.txt b/tests/deviced-common-private-test/CMakeLists.txt similarity index 96% rename from src/tests/shared/CMakeLists.txt rename to tests/deviced-common-private-test/CMakeLists.txt index 5cd27ed..7c3323d 100644 --- a/src/tests/shared/CMakeLists.txt +++ b/tests/deviced-common-private-test/CMakeLists.txt @@ -1,3 +1,4 @@ +# test for libdeviced-common-private.so SET(${CMAKE_C_FLAGS} $ENV{CFLAGS}) ADD_DEFINITIONS("-DENABLE_TEST") diff --git a/src/tests/shared/test-bitmap.c b/tests/deviced-common-private-test/test-bitmap.c similarity index 100% rename from src/tests/shared/test-bitmap.c rename to tests/deviced-common-private-test/test-bitmap.c diff --git a/src/tests/shared/test-device-notifier.c b/tests/deviced-common-private-test/test-device-notifier.c similarity index 100% rename from src/tests/shared/test-device-notifier.c rename to tests/deviced-common-private-test/test-device-notifier.c diff --git a/src/tests/shared/test-main.c b/tests/deviced-common-private-test/test-main.c similarity index 100% rename from src/tests/shared/test-main.c rename to tests/deviced-common-private-test/test-main.c diff --git a/src/tests/shared/test-main.h b/tests/deviced-common-private-test/test-main.h similarity index 100% rename from src/tests/shared/test-main.h rename to tests/deviced-common-private-test/test-main.h diff --git a/src/tests/shared/test-mock.c b/tests/deviced-common-private-test/test-mock.c similarity index 100% rename from src/tests/shared/test-mock.c rename to tests/deviced-common-private-test/test-mock.c diff --git a/src/tests/shared/test-mock.h b/tests/deviced-common-private-test/test-mock.h similarity index 100% rename from src/tests/shared/test-mock.h rename to tests/deviced-common-private-test/test-mock.h diff --git a/src/tests/shared/test-plugin.c b/tests/deviced-common-private-test/test-plugin.c similarity index 100% rename from src/tests/shared/test-plugin.c rename to tests/deviced-common-private-test/test-plugin.c diff --git a/src/tests/usb-host-ffs-test-daemon/CMakeLists.txt b/tests/usb-host-ffs-test-daemon/CMakeLists.txt similarity index 100% rename from src/tests/usb-host-ffs-test-daemon/CMakeLists.txt rename to tests/usb-host-ffs-test-daemon/CMakeLists.txt diff --git a/src/tests/usb-host-ffs-test-daemon/descs_gen.c b/tests/usb-host-ffs-test-daemon/descs_gen.c similarity index 100% rename from src/tests/usb-host-ffs-test-daemon/descs_gen.c rename to tests/usb-host-ffs-test-daemon/descs_gen.c diff --git a/src/tests/usb-host-ffs-test-daemon/usb-host-ffs-test-daemon.c b/tests/usb-host-ffs-test-daemon/usb-host-ffs-test-daemon.c similarity index 100% rename from src/tests/usb-host-ffs-test-daemon/usb-host-ffs-test-daemon.c rename to tests/usb-host-ffs-test-daemon/usb-host-ffs-test-daemon.c diff --git a/src/tests/usb-host-test/test_gadget.gs b/tests/usb-host-test/test_gadget.gs similarity index 100% rename from src/tests/usb-host-test/test_gadget.gs rename to tests/usb-host-test/test_gadget.gs diff --git a/src/tests/usb-host-test/usb-host-test.c b/tests/usb-host-test/usb-host-test.c similarity index 100% rename from src/tests/usb-host-test/usb-host-test.c rename to tests/usb-host-test/usb-host-test.c -- 2.7.4 From 34132c4276782ae16d6d1ebe491d5a0976ad6f24 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Mon, 1 Nov 2021 10:21:53 +0900 Subject: [PATCH 03/16] Remove unnecessaries from iot-headless plugin package Change-Id: I89bf3db908b078c1609284e1c650cda7a02ead4a Signed-off-by: Youngjae Cho --- packaging/deviced.spec | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packaging/deviced.spec b/packaging/deviced.spec index cb13612..3c80351 100644 --- a/packaging/deviced.spec +++ b/packaging/deviced.spec @@ -255,9 +255,7 @@ mkdir -p %{_libdir}/deviced mv %{_libdir}/iot-headed-display.so %{_libdir}/deviced/display.so %post plugin-profile-iot-headless -mv %{_sysconfdir}/deviced/iot-headless-display.conf %{_sysconfdir}/deviced/display.conf mkdir -p %{_libdir}/deviced -mv %{_libdir}/iot-headed-display.so %{_libdir}/deviced/display.so mv %{_libdir}/iot-headless-input-handler.so %{_libdir}/deviced/input-handler.so mv %{_libdir}/iot-headless-power.so %{_libdir}/deviced/power.so @@ -377,8 +375,6 @@ mv %{_libdir}/iot-headless-power.so %{_libdir}/deviced/power.so %manifest deviced.manifest %license LICENSE.Apache-2.0 %defattr(-,root,root,-) -%config %{_sysconfdir}/deviced/iot-headed-display.conf -%{_libdir}/iot-headed-display.so %{_libdir}/iot-headless-input-handler.so %{_libdir}/iot-headless-power.so %{_unitdir}/rndis.service -- 2.7.4 From b6fc94e23753ed3e4b5d16ece7bebfc06d71e292 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Mon, 1 Nov 2021 15:31:39 +0900 Subject: [PATCH 04/16] input: make input module initialize plugin input-handler Change-Id: Ia72cd8f207b782da369e4161e1bd9269045e19e6 Signed-off-by: Youngjae Cho --- CMakeLists.txt | 2 +- plugins/iot-headed/display/core.c | 5 +-- plugins/iot-headless/input/input-handler.c | 55 +++++++++++------------------- plugins/mobile/display/core.c | 5 +-- plugins/tv/display/core.c | 5 +-- plugins/wearable/display/core.c | 5 +-- src/display/display-input.c | 35 ++++++++----------- src/display/poll.h | 3 -- src/input/input.c | 38 ++++++++++++--------- src/shared/common.c | 1 - src/shared/devices.c | 11 ++++++ src/shared/devices.h | 1 + src/shared/plugin.c | 2 -- src/tzip/tzip-utility.c | 1 - src/tzip/tzip.c | 1 - src/usbhost/usb-host.c | 2 -- 16 files changed, 74 insertions(+), 98 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 926fcbc..15d8125 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -205,7 +205,7 @@ FOREACH(flag ${REQUIRED_PKGS_CFLAGS}) ENDFOREACH(flag) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE -rdynamic") -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions -D_GNU_SOURCE") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") SET(CMAKE_EXE_LINKER_FLAGS "-pie") diff --git a/plugins/iot-headed/display/core.c b/plugins/iot-headed/display/core.c index a91533b..c772d9e 100644 --- a/plugins/iot-headed/display/core.c +++ b/plugins/iot-headed/display/core.c @@ -2042,9 +2042,7 @@ static int display_probe(void *data) static int input_init_handler(void) { if (!display_conf.input_support) - return 0; - - g_idle_add(display_input_init, NULL); + remove_device_by_devname("input"); return 0; } @@ -2256,7 +2254,6 @@ static void display_exit(void *data) unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed); unregister_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed); - display_input_exit(); break; } } diff --git a/plugins/iot-headless/input/input-handler.c b/plugins/iot-headless/input/input-handler.c index bb2bb43..ae25482 100644 --- a/plugins/iot-headless/input/input-handler.c +++ b/plugins/iot-headless/input/input-handler.c @@ -20,6 +20,7 @@ #include #include +#include "shared/common.h" #include "shared/devices.h" #include "shared/log.h" @@ -28,6 +29,7 @@ #define LONGPRESS_INTERVAL 10000 /* milisecond */ +static int longpress_interval = LONGPRESS_INTERVAL; static guint longpress_timer_id; static gboolean longpressed_cb(void *data) @@ -55,7 +57,7 @@ static void start_longpress_timer(void) longpress_timer_id = 0; } - longpress_timer_id = g_timeout_add(LONGPRESS_INTERVAL, longpressed_cb, NULL); + longpress_timer_id = g_timeout_add(longpress_interval, longpressed_cb, NULL); } static void stop_longpress_timer(void) @@ -66,14 +68,19 @@ static void stop_longpress_timer(void) } } -/* poweroff if power button is pressed longer than LONGPRESS_INTERVAL */ -static void input_event_handler(struct libinput_event *e) +static int input_handler_execute(void *data) { + struct libinput_event *e; struct libinput_event_keyboard *ek; int keycode, keyvalue; + if (!data) + return 0; + + e = (struct libinput_event *) data; + if (libinput_event_get_type(e) != LIBINPUT_EVENT_KEYBOARD_KEY) - return; + return 0; ek = libinput_event_get_keyboard_event(e); keycode = libinput_event_keyboard_get_key(ek); @@ -87,42 +94,20 @@ static void input_event_handler(struct libinput_event *e) else if (keyvalue == KEYVALUE_RELEASE) stop_longpress_timer(); } -} -static void input_event_handler_init(void *data) -{ - const struct device_ops *input_device; - - input_device = find_device("input"); - if (check_default(input_device)) { - _E("There is no input device"); - return; - } - - if (input_device->init) { - _D("[%s] Initialization.", input_device->name); - input_device->init(input_event_handler); - } + return 0; } -static void input_event_handler_exit(void *data) +static void input_handler_init(void *data) { - const struct device_ops *input_device; - - input_device = find_device("input"); - if (check_default(input_device)) { - _E("There is no input device"); - return; - } - - if (input_device->exit) - input_device->exit(NULL); + // TODO: parse system config, which set holding time of short/long key } -static const struct device_ops input_event_handler_device_ops = { - DECLARE_NAME_LEN("input-event-handler"), - .init = input_event_handler_init, - .exit = input_event_handler_exit, +static const struct device_ops input_handler_device_ops = { + DECLARE_NAME_LEN("input-handler"), + .init = input_handler_init, + .execute = input_handler_execute, + .disable_auto_init = true, }; -DEVICE_OPS_REGISTER(&input_event_handler_device_ops); +DEVICE_OPS_REGISTER(&input_handler_device_ops) diff --git a/plugins/mobile/display/core.c b/plugins/mobile/display/core.c index 3d11cbd..6b3aad8 100644 --- a/plugins/mobile/display/core.c +++ b/plugins/mobile/display/core.c @@ -2048,9 +2048,7 @@ static int display_probe(void *data) static int input_init_handler(void) { if (!display_conf.input_support) - return 0; - - g_idle_add(display_input_init, NULL); + remove_device_by_devname("input"); return 0; } @@ -2262,7 +2260,6 @@ static void display_exit(void *data) unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed); unregister_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed); - display_input_exit(); break; } } diff --git a/plugins/tv/display/core.c b/plugins/tv/display/core.c index 86807aa..3f9357d 100644 --- a/plugins/tv/display/core.c +++ b/plugins/tv/display/core.c @@ -2039,9 +2039,7 @@ static int display_probe(void *data) static int input_init_handler(void) { if (!display_conf.input_support) - return 0; - - g_idle_add(display_input_init, NULL); + remove_device_by_devname("input"); return 0; } @@ -2253,7 +2251,6 @@ static void display_exit(void *data) unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed); unregister_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed); - display_input_exit(); break; } } diff --git a/plugins/wearable/display/core.c b/plugins/wearable/display/core.c index 5acaa70..2ff8cf6 100644 --- a/plugins/wearable/display/core.c +++ b/plugins/wearable/display/core.c @@ -2331,9 +2331,7 @@ static int display_probe(void *data) static int input_init_handler(void) { if (!display_conf.input_support) - return 0; - - g_idle_add(display_input_init, NULL); + remove_device_by_devname("input"); return 0; } @@ -2584,7 +2582,6 @@ static void display_exit(void *data) unregister_notifier(DEVICE_NOTIFIER_BATTERY_HEALTH, battery_health_changed); unregister_notifier(DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, display_brightness_changed); - display_input_exit(); break; } } diff --git a/src/display/display-input.c b/src/display/display-input.c index 0e1d4c6..05fcde6 100644 --- a/src/display/display-input.c +++ b/src/display/display-input.c @@ -30,7 +30,7 @@ #define SEAT_NAME "seat0" -static void process_event(struct libinput_event *ev) +static void process_input(struct libinput_event *ev) { static const struct device_ops *display_device_ops; struct input_event input; @@ -105,30 +105,25 @@ static void process_event(struct libinput_event *ev) poll_callback(INPUT_POLL_EVENT, NULL); } -gboolean display_input_init(gpointer data) +static int input_handler_execute(void *data) { - static const struct device_ops *input_device; - - input_device = find_device("input"); - if (check_default(input_device)) - return G_SOURCE_REMOVE; + if (!data) + return 0; - _D("[%s] Initialization.", input_device->name); - if (input_device->init) - input_device->init(process_event); + process_input(data); - return G_SOURCE_REMOVE; + return 0; } -int display_input_exit(void) +static void input_handler_init(void *data) { - static const struct device_ops *input_device; - - input_device = find_device("input"); - if (check_default(input_device)) - return 0; +} - input_device->exit(NULL); +static const struct device_ops input_handler_device_ops = { + DECLARE_NAME_LEN("input-handler"), + .init = input_handler_init, + .execute = input_handler_execute, + .disable_auto_init = true, +}; - return 0; -} +DEVICE_OPS_REGISTER(&input_handler_device_ops) diff --git a/src/display/poll.h b/src/display/poll.h index 096316d..aed0736 100644 --- a/src/display/poll.h +++ b/src/display/poll.h @@ -143,9 +143,6 @@ enum cond_flags_e { #define RESET_TIMER_STR "resettimer" #define KEEP_TIMER_STR "keeptimer" -gboolean display_input_init(gpointer data); -int display_input_exit(void); - /** * @} */ diff --git a/src/input/input.c b/src/input/input.c index 76c82b9..f39e7b8 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "shared/devices.h" #include "shared/log.h" @@ -38,21 +39,23 @@ static struct udev *udev; static struct libinput *li; static guint efd; -static void (*input_event_handler) (struct libinput_event *); +static const struct device_ops *input_handler; -static gboolean input_handler(gint fd, GIOCondition cond, void *data) +static gboolean input_callback(gint fd, GIOCondition cond, void *data) { struct libinput_event *ev; - struct libinput *input = (struct libinput *)data; + struct libinput *input = (struct libinput *) data; - if (!input || !input_event_handler) + if (!input_handler) + return G_SOURCE_REMOVE; + + if (!input) return G_SOURCE_CONTINUE; libinput_dispatch(input); while ((ev = libinput_get_event(input))) { - input_event_handler(ev); - + input_handler->execute(ev); libinput_event_destroy(ev); libinput_dispatch(input); } @@ -93,13 +96,15 @@ static void input_init(void *data) int ret; int fd; - if (!data) { - _E("there is no handler for input event"); + /* load plugin input handler */ + input_handler = find_device("input-handler"); + if (check_default(input_handler) || input_handler->execute == NULL) { + input_handler = NULL; return; } - /* registering input event handler */ - input_event_handler = data; + if (input_handler->init) + input_handler->init(NULL); udev = udev_new(); if (!udev) { @@ -125,9 +130,9 @@ static void input_init(void *data) return; } - /* add to poll handler */ + /* add poll callback */ efd = g_unix_fd_add(fd, G_IO_IN, - input_handler, + input_callback, (void *)((intptr_t)li)); if (!efd) { _E("fail to g_unix_fd_add"); @@ -150,16 +155,17 @@ static void input_exit(void *data) if (udev) udev_unref(udev); - input_event_handler = NULL; + if (input_handler && input_handler->exit) + input_handler->exit(NULL); + + input_handler = NULL; } -/* input module parse and transfer - * input event to input event handler */ static const struct device_ops input_device_ops = { DECLARE_NAME_LEN("input"), .init = input_init, .exit = input_exit, - .disable_auto_init = true, + .priority = -1, /* initialize at last */ }; DEVICE_OPS_REGISTER(&input_device_ops) diff --git a/src/shared/common.c b/src/shared/common.c index af6e980..c7f4bb0 100644 --- a/src/shared/common.c +++ b/src/shared/common.c @@ -16,7 +16,6 @@ * limitations under the License. */ -#define _GNU_SOURCE #include #include #include diff --git a/src/shared/devices.c b/src/shared/devices.c index 950c1d7..f3884a1 100644 --- a/src/shared/devices.c +++ b/src/shared/devices.c @@ -39,6 +39,17 @@ void remove_device(const struct device_ops *dev) SYS_G_LIST_REMOVE(dev_head, dev); } +void remove_device_by_devname(const char *devname) +{ + const struct device_ops *dev = find_device(devname); + + if (check_default(dev)) + return; + + _D("remove device=%s", devname); + remove_device(dev); +} + const struct device_ops *find_device(const char *name) { GList *elem; diff --git a/src/shared/devices.h b/src/shared/devices.h index d42c490..b0feb6a 100644 --- a/src/shared/devices.h +++ b/src/shared/devices.h @@ -132,6 +132,7 @@ static void __DESTRUCTOR__ module_exit(void) \ extern GList *dev_head; void add_device(const struct device_ops *dev); void remove_device(const struct device_ops *dev); +void remove_device_by_devname(const char *devname); const struct device_ops *find_device(const char *name); int check_default(const struct device_ops *dev); diff --git a/src/shared/plugin.c b/src/shared/plugin.c index d74f981..db8725c 100644 --- a/src/shared/plugin.c +++ b/src/shared/plugin.c @@ -16,8 +16,6 @@ * limitations under the License. */ -#define _GNU_SOURCE - #include #include #include diff --git a/src/tzip/tzip-utility.c b/src/tzip/tzip-utility.c index 8e749e3..671163e 100644 --- a/src/tzip/tzip-utility.c +++ b/src/tzip/tzip-utility.c @@ -16,7 +16,6 @@ * limitations under the License. */ -#define _GNU_SOURCE #include #include #include diff --git a/src/tzip/tzip.c b/src/tzip/tzip.c index 9ae85dd..d99ed56 100644 --- a/src/tzip/tzip.c +++ b/src/tzip/tzip.c @@ -18,7 +18,6 @@ #define FUSE_USE_VERSION 26 -#define _GNU_SOURCE #include #include #include diff --git a/src/usbhost/usb-host.c b/src/usbhost/usb-host.c index 1af7c9c..9155fb5 100644 --- a/src/usbhost/usb-host.c +++ b/src/usbhost/usb-host.c @@ -15,8 +15,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define _GNU_SOURCE - #include #include #include -- 2.7.4 From 31cb94dd663b45e3d905e31b20a97bc145d9d769 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Fri, 22 Oct 2021 16:32:21 +0900 Subject: [PATCH 05/16] input: support powerkey shortpress for iot-headless Change-Id: I0451471b0b17746e30e159c7ac5e0e7395fd39e1 Signed-off-by: Youngjae Cho --- plugins/iot-headless/input/input-handler.c | 41 +++++++++++++++++++++++++++--- src/shared/device-notifier.h | 1 + 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/plugins/iot-headless/input/input-handler.c b/plugins/iot-headless/input/input-handler.c index ae25482..69b619e 100644 --- a/plugins/iot-headless/input/input-handler.c +++ b/plugins/iot-headless/input/input-handler.c @@ -22,16 +22,27 @@ #include "shared/common.h" #include "shared/devices.h" +#include "shared/device-notifier.h" #include "shared/log.h" #define KEYVALUE_PRESS 1 #define KEYVALUE_RELEASE 0 #define LONGPRESS_INTERVAL 10000 /* milisecond */ +#define SHORTPRESS_INTERVAL 3000 /* milisecond */ static int longpress_interval = LONGPRESS_INTERVAL; +static int shortpress_interval = SHORTPRESS_INTERVAL; +static guint shortpress_timer_id; static guint longpress_timer_id; +static gboolean shortpressed_cb(void *data) +{ + shortpress_timer_id = 0; + + return G_SOURCE_REMOVE; +} + static gboolean longpressed_cb(void *data) { const struct device_ops *power_device; @@ -43,13 +54,23 @@ static gboolean longpressed_cb(void *data) return G_SOURCE_REMOVE; if (power_device->execute) { - _D("powerkey long pressed, start poweroff sequence"); + _D("powerkey long pressed"); power_device->execute("poweroff"); } return G_SOURCE_REMOVE; } +static void start_shortpress_timer(void) +{ + if (shortpress_timer_id) { + g_source_remove(shortpress_timer_id); + shortpress_timer_id = 0; + } + + shortpress_timer_id = g_timeout_add(shortpress_interval, shortpressed_cb, NULL); +} + static void start_longpress_timer(void) { if (longpress_timer_id) { @@ -60,6 +81,17 @@ static void start_longpress_timer(void) longpress_timer_id = g_timeout_add(longpress_interval, longpressed_cb, NULL); } +static void stop_shortpress_timer(void) +{ + if (shortpress_timer_id) { + g_source_remove(shortpress_timer_id); + shortpress_timer_id = 0; + } else { + _D("powerkey short pressed"); + device_notify(DEVICE_NOTIFIER_KEY_SHORTPRESS, (void *)(intptr_t) KEY_POWER); + } +} + static void stop_longpress_timer(void) { if (longpress_timer_id) { @@ -89,10 +121,13 @@ static int input_handler_execute(void *data) _D("key input: code=%d, value=%d", keycode, keyvalue); if (keycode == KEY_POWER) { - if (keyvalue == KEYVALUE_PRESS) + if (keyvalue == KEYVALUE_PRESS) { + start_shortpress_timer(); start_longpress_timer(); - else if (keyvalue == KEYVALUE_RELEASE) + } else if (keyvalue == KEYVALUE_RELEASE) { + stop_shortpress_timer(); stop_longpress_timer(); + } } return 0; diff --git a/src/shared/device-notifier.h b/src/shared/device-notifier.h index ba597b1..72d2ed8 100644 --- a/src/shared/device-notifier.h +++ b/src/shared/device-notifier.h @@ -61,6 +61,7 @@ enum device_notifier_type { DEVICE_NOTIFIER_ULTRAPOWERSAVING, DEVICE_NOTIFIER_EXTCON_COUNT, DEVICE_NOTIFIER_REQUEST_WAKE_LOCK, + DEVICE_NOTIFIER_KEY_SHORTPRESS, /* hold down a key for a short duration */ DEVICE_NOTIFIER_REQUEST_WAKE_UNLOCK, DEVICE_NOTIFIER_MAX, }; -- 2.7.4 From f82e72f176de869c60e67edcd9797f0462cca1bb Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Thu, 4 Nov 2021 15:52:52 +0900 Subject: [PATCH 06/16] extcon: initialize on calling extcon_enable_device() Change-Id: Id128ded4a79fc63172cd35aeb00fa940c5c00709 Signed-off-by: Youngjae Cho --- src/extcon/extcon.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/extcon/extcon.c b/src/extcon/extcon.c index 3af9f94..8a93315 100644 --- a/src/extcon/extcon.c +++ b/src/extcon/extcon.c @@ -149,6 +149,9 @@ int extcon_enable_device(const char *name) struct extcon_ops *dev; int ret; + if (!delayed_init_done(NULL)) + extcon_deferred_init(); + dev = find_extcon(name); if (!dev) return -ENODEV; -- 2.7.4 From d0586f4c5ed166a3338ae42a35f041200e9c97e4 Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Mon, 8 Nov 2021 15:33:37 +0900 Subject: [PATCH 07/16] extcon: rename enable to initialized Change-Id: I9febfb6a57267bd42812c165d52de29aaa7dd3d2 --- src/extcon/extcon.c | 24 ++++++++++++------------ src/extcon/extcon.h | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/extcon/extcon.c b/src/extcon/extcon.c index 8a93315..564fe88 100644 --- a/src/extcon/extcon.c +++ b/src/extcon/extcon.c @@ -80,7 +80,7 @@ int extcon_get_status(const char *name) if (!dev) return -ENOENT; - if (!dev->enabled) + if (!dev->initialized) return -ENODEV; return dev->status; @@ -120,7 +120,7 @@ static int extcon_update(const char *name, const char *index, const char *value) dev->status = status; - if (dev->enabled == false && strncmp(name, "USB", strlen("USB")) == 0) { + if (dev->initialized == false && strncmp(name, "USB", strlen("USB")) == 0) { if (status > 0) { snprintf(buf, BUF_MAX, "usb-client"); ret_dbus = gdbus_call_sync_with_reply_int(DEVICEMANAGER_BUS_NAME, @@ -156,13 +156,13 @@ int extcon_enable_device(const char *name) if (!dev) return -ENODEV; - if (dev->enabled) { - _I("Extcon(%s) already enabled.", name); + if (dev->initialized) { + _I("Extcon(%s) already initialized.", name); return 0; } dev->init(NULL); - dev->enabled = true; + dev->initialized = true; if (strncmp(name, "USB", strlen("USB")) == 0) { ret = extcon_update("USB", NULL, "0"); @@ -173,7 +173,7 @@ int extcon_enable_device(const char *name) if (ret != 0) _E("Failed to connect USB."); } - _I("Extcon(%s) enabled.", name); + _I("Extcon(%s) initialized.", name); return 0; } @@ -197,15 +197,15 @@ int extcon_disable_device(const char *name) if (ret_dbus < 0) _E("Failed to launch USB restricted popup: %d", ret_dbus); - if (!dev->enabled) { - _I("Extcon(%s) already disabled.", name); + if (!dev->initialized) { + _I("Extcon(%s) already deinitialized.", name); return 0; } dev->exit(NULL); - dev->enabled = false; + dev->initialized = false; - _I("Extcon(%s) disabled.", name); + _I("Extcon(%s) deinitialized.", name); return 0; } @@ -500,7 +500,7 @@ static void extcon_deferred_init(void) _I("Extcon(%s) init.", dev->name); if (dev->init) dev->init(NULL); - dev->enabled = true; + dev->initialized = true; } event_handler_state_changed((void *)&state); @@ -553,7 +553,7 @@ static void extcon_exit(void *data) _I("Extcon(%s) deinit.", dev->name); if (dev->exit) dev->exit(data); - dev->enabled = false; + dev->initialized = false; } extcon_dev_available = false; } diff --git a/src/extcon/extcon.h b/src/extcon/extcon.h index e4a4826..4747d0c 100644 --- a/src/extcon/extcon.h +++ b/src/extcon/extcon.h @@ -40,7 +40,7 @@ struct extcon_ops { const char *name; int status; - int enabled; + int initialized; void (*init)(void *data); void (*exit)(void *data); int (*update)(const char *index, int status); -- 2.7.4 From 3f4b02133108d755f3171c005619159975d4bf8c Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Mon, 8 Nov 2021 14:53:42 +0900 Subject: [PATCH 08/16] extcon: check condition variable for extcon init and deinit Change-Id: Ib7956980d1d82991d866666c82ac5fb39a9885ed --- src/extcon/extcon.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/extcon/extcon.c b/src/extcon/extcon.c index 564fe88..5e163de 100644 --- a/src/extcon/extcon.c +++ b/src/extcon/extcon.c @@ -497,7 +497,12 @@ static void extcon_deferred_init(void) /* initialize extcon devices */ SYS_G_LIST_FOREACH(extcon_list, l, dev) { - _I("Extcon(%s) init.", dev->name); + if (dev->initialized) { + _I("Extcon(%s) is already initialized.", dev->name); + continue; + } else + _I("Extcon(%s) init.", dev->name); + if (dev->init) dev->init(NULL); dev->initialized = true; @@ -550,7 +555,12 @@ static void extcon_exit(void *data) /* deinitialize extcon devices */ SYS_G_LIST_FOREACH(extcon_list, l, dev) { - _I("Extcon(%s) deinit.", dev->name); + if (!dev->initialized) { + _I("Extcon(%s) is already deinitialized.", dev->name); + continue; + } else + _I("Extcon(%s) deinit.", dev->name); + if (dev->exit) dev->exit(data); dev->initialized = false; -- 2.7.4 From cac27690fbc9ea12c4febfe6fe322cc88db5d9f2 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Fri, 22 Oct 2021 16:02:10 +0900 Subject: [PATCH 09/16] power: support autosleep for iot-headless Change-Id: Ia0ff76a4fa301708939abf197f0abaa92aad5c10 Signed-off-by: Youngjae Cho --- plugins/iot-headless/power/power-control.c | 59 ++++++++++++++++++++++++++---- src/power/power-control.c | 19 ++++++++++ src/shared/device-notifier.h | 8 +++- 3 files changed, 77 insertions(+), 9 deletions(-) diff --git a/plugins/iot-headless/power/power-control.c b/plugins/iot-headless/power/power-control.c index f7b477c..eda7caf 100644 --- a/plugins/iot-headless/power/power-control.c +++ b/plugins/iot-headless/power/power-control.c @@ -18,6 +18,8 @@ #include #include +#include +#include #include #include #include @@ -29,7 +31,7 @@ #include "shared/device-notifier.h" #ifndef PROCESS_CHECK_TIMEOUT -#define PROCESS_CHECK_TIMEOUT 3600000 /* milisecond, 1 hour */ +#define PROCESS_CHECK_TIMEOUT 600000 /* milisecond, 10 minute */ #endif static GList *lock_list; @@ -53,9 +55,23 @@ static void print_lock_node(void) node->pid, node->comm, node->locktime, node->timeout); } +/* check the lock_list is empty. + * if it is, then request wake unlock */ +static void try_wake_unlock(void) +{ + if (SYS_G_LIST_LENGTH(lock_list) == 0) + device_notify(DEVICE_NOTIFIER_REQUEST_WAKE_UNLOCK, NULL); + else + print_lock_node(); +} + +static void try_wake_lock(void) +{ + device_notify(DEVICE_NOTIFIER_REQUEST_WAKE_LOCK, NULL); +} + /* remove given node from lock list. - * if list is empty after removing the lock, - * automatically release powerlock */ + * after removing the node, request wake unlock if possible */ static void remove_lock_node(struct lock_node *node) { if (!node) @@ -69,10 +85,7 @@ static void remove_lock_node(struct lock_node *node) SYS_G_LIST_REMOVE(lock_list, node); free(node); - if (SYS_G_LIST_LENGTH(lock_list) == 0) - device_notify(DEVICE_NOTIFIER_REQUEST_WAKE_UNLOCK, NULL); - else - print_lock_node(); + try_wake_unlock(); } static gboolean lock_expired_cb(void *data) @@ -174,7 +187,7 @@ static GVariant *dbus_power_lock_cpu(GDBusConnection *conn, } _D("pid=%d(%s) request CPU lock for %dms", pid, node->comm, timeout); - device_notify(DEVICE_NOTIFIER_REQUEST_WAKE_LOCK, NULL); + try_wake_lock(); if (timeout > 0) node->timer_id = g_timeout_add(timeout, lock_expired_cb, node); @@ -228,6 +241,31 @@ static const dbus_interface_u dbus_interface = { .nr_methods = ARRAY_SIZE(dbus_methods), }; +/* toggle sleep_enabled on powerkey short press */ +static int powerkey_short_pressed_cb(void *data) +{ + int keycode; + static int sleep_enabled = 0; /* initial sleep state: disabled */ + + if (!data) + return 0; + + keycode = (int)(intptr_t) data; + if (keycode != KEY_POWER) + return 0; + + sleep_enabled ^= 1; /* toggle status */ + if (sleep_enabled) { + device_notify(DEVICE_NOTIFIER_REQUEST_ENABLE_AUTOSLEEP, NULL); + _D("Sleep enabled"); + } else { + device_notify(DEVICE_NOTIFIER_REQUEST_DISABLE_AUTOSLEEP, NULL); + _D("Sleep disabled"); + } + + return 0; +} + static void power_control_init(void *data) { int retval; @@ -235,6 +273,11 @@ static void power_control_init(void *data) retval = gdbus_add_object(NULL, DEVICED_PATH_POWER, &dbus_interface); if (retval < 0) _E("Failed to init dbus method."); + + /* initial sleep state: disabled */ + device_notify(DEVICE_NOTIFIER_REQUEST_DISABLE_AUTOSLEEP, NULL); + + register_notifier(DEVICE_NOTIFIER_KEY_SHORTPRESS, powerkey_short_pressed_cb); } static const struct device_ops power_control_plugin_device_ops = { diff --git a/src/power/power-control.c b/src/power/power-control.c index 749c4e5..3482a60 100644 --- a/src/power/power-control.c +++ b/src/power/power-control.c @@ -213,6 +213,12 @@ int pm_enable_autosleep(void) return sys_set_str(POWER_AUTOSLEEP_PATH, "mem"); } +int pm_disable_autosleep(void) +{ + _I("System autosleep disabled."); + return sys_set_str(POWER_AUTOSLEEP_PATH, "off"); +} + int pm_power_lock(void) { _I("system power lock"); @@ -292,6 +298,17 @@ int set_wakeup_count(int cnt) return 0; } +static int __pm_enable_autosleep(void *data) +{ + return pm_enable_autosleep(); +} + +static int __pm_disable_autosleep(void *data) +{ + + return pm_disable_autosleep(); +} + static int __pm_power_lock(void *data) { if (mainlock_status == POWER_UNLOCK) @@ -318,6 +335,8 @@ static void power_control_init(void *data) /* if there is plugin of power-control, * register notifier for the plugin module */ + register_notifier(DEVICE_NOTIFIER_REQUEST_ENABLE_AUTOSLEEP, __pm_enable_autosleep); + register_notifier(DEVICE_NOTIFIER_REQUEST_DISABLE_AUTOSLEEP, __pm_disable_autosleep); register_notifier(DEVICE_NOTIFIER_REQUEST_WAKE_LOCK, __pm_power_lock); register_notifier(DEVICE_NOTIFIER_REQUEST_WAKE_UNLOCK, __pm_power_unlock); diff --git a/src/shared/device-notifier.h b/src/shared/device-notifier.h index 72d2ed8..7269d57 100644 --- a/src/shared/device-notifier.h +++ b/src/shared/device-notifier.h @@ -60,8 +60,14 @@ enum device_notifier_type { DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, DEVICE_NOTIFIER_ULTRAPOWERSAVING, DEVICE_NOTIFIER_EXTCON_COUNT, - DEVICE_NOTIFIER_REQUEST_WAKE_LOCK, DEVICE_NOTIFIER_KEY_SHORTPRESS, /* hold down a key for a short duration */ + DEVICE_NOTIFIER_KEY_LONGPRESS, /* hold down a key for a long duration */ + + /* Purpose of calling methods of different modules + * Use prefix DEVICE_NOTIFIER_REQUEST */ + DEVICE_NOTIFIER_REQUEST_ENABLE_AUTOSLEEP, + DEVICE_NOTIFIER_REQUEST_DISABLE_AUTOSLEEP, + DEVICE_NOTIFIER_REQUEST_WAKE_LOCK, DEVICE_NOTIFIER_REQUEST_WAKE_UNLOCK, DEVICE_NOTIFIER_MAX, }; -- 2.7.4 From dc22cdecd827613305c9103854d0a0ad6f29735b Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Fri, 12 Nov 2021 14:53:00 +0900 Subject: [PATCH 10/16] battery: invalidate battery vconf when battery disconnected Change-Id: I4afad3783088c1cb1a7a8ef63b9535907b0a20ad Signed-off-by: Youngjae Cho --- src/battery/power-supply.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/battery/power-supply.c b/src/battery/power-supply.c index d00b2b4..12f263a 100644 --- a/src/battery/power-supply.c +++ b/src/battery/power-supply.c @@ -968,6 +968,27 @@ static int battery_state(struct battery_info *info) return 1; } +static void battery_invalidate_vconf(int value) +{ + int retval; + const char *vconf[] = { + VCONFKEY_SYSMAN_BATTERY_CAPACITY, + VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, + VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, + VCONFKEY_SYSMAN_BATTERY_LEVEL_STATUS, + }; + + _D("Invalidate battery vconfs to %d", value); + + for (int i = 0; i < ARRAY_SIZE(vconf); ++i) { + retval = vconf_set_int(vconf[i], value); + if (retval == 0) + _D("Set vconf %s to %d", vconf[i], value); + else + _E("Failed to set %s to %d, %d", vconf[i], value, retval); + } +} + static void battery_changed(struct battery_info *info, void *data) { int ret_val; @@ -1029,8 +1050,12 @@ static void battery_changed(struct battery_info *info, void *data) battery.present = PRESENT_NORMAL; } - process_power_supply(&battery.capacity); - + if (battery.present) { + process_power_supply(&battery.capacity); + } else { + _D("Battery disconnected"); + battery_invalidate_vconf(-ENODEV); + } } static void power_supply_status_init(void) @@ -1074,11 +1099,20 @@ static void power_supply_timer_start(void) static void power_supply_timer_stop(void) { + int retval; + if (power_timer == 0) return; _I("Stop battery init timer during booting."); g_source_remove(power_timer); power_timer = 0; + + /* check battery has been initialized until booting done */ + retval = hal_device_battery_get_current_state(battery_changed, NULL); + if (retval < 0) { + _E("Failed to initialize battery state"); + battery_invalidate_vconf(retval); + } } static GVariant *dbus_get_charger_status(GDBusConnection *conn, -- 2.7.4 From cd286a14d37fd6ff8ad5aabedc29982b8578b5c0 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Wed, 17 Nov 2021 10:17:14 +0900 Subject: [PATCH 11/16] power: move sleep configuration to power Change-Id: I5d6d7054149134bdea68f85802414e7783f8265d Signed-off-by: Youngjae Cho --- conf/power.conf | 3 +++ plugins/iot-headed/display/core.c | 5 ++--- plugins/mobile/display/core.c | 5 ++--- plugins/tv/display/core.c | 5 ++--- plugins/wearable/display/core.c | 5 ++--- src/display/core.h | 1 - src/display/display.c | 3 --- src/power/power-control.c | 24 ++++++++++++++++++++++++ src/power/power-control.h | 2 ++ 9 files changed, 37 insertions(+), 16 deletions(-) diff --git a/conf/power.conf b/conf/power.conf index 7a753c2..52abf4a 100644 --- a/conf/power.conf +++ b/conf/power.conf @@ -4,3 +4,6 @@ Option=download Option=wdownload Option=debug Option=silent + +[Sleep] +TimeoutSleepSupport=yes diff --git a/plugins/iot-headed/display/core.c b/plugins/iot-headed/display/core.c index c772d9e..71376ad 100644 --- a/plugins/iot-headed/display/core.c +++ b/plugins/iot-headed/display/core.c @@ -200,7 +200,6 @@ static struct display_config display_conf = { .aod_enter_level = 40, .aod_tsp = true, .touch_wakeup = false, - .sleep_support = true, .display_on_usb_conn_changed = true, }; @@ -603,7 +602,7 @@ void reset_timeout(int timeout) return; if ((get_pm_cur_state() == S_LCDOFF) - && (is_emulator() == true || display_conf.sleep_support == false)) + && (is_emulator() == true || timeout_sleep_support == false)) return; _I("Reset timeout(%d ms).", timeout); @@ -1355,7 +1354,7 @@ static int default_trans(int evt) states[get_pm_cur_state()].trans(EVENT_TIMEOUT); } else { if ((get_pm_cur_state() == S_SLEEP) - && (is_emulator() == true || display_conf.sleep_support == false)) + && (is_emulator() == true || timeout_sleep_support == false)) return 0; st->action(st->timeout); diff --git a/plugins/mobile/display/core.c b/plugins/mobile/display/core.c index 6b3aad8..7180885 100644 --- a/plugins/mobile/display/core.c +++ b/plugins/mobile/display/core.c @@ -202,7 +202,6 @@ static struct display_config display_conf = { .aod_enter_level = 40, .aod_tsp = true, .touch_wakeup = false, - .sleep_support = true, .display_on_usb_conn_changed = true, }; @@ -610,7 +609,7 @@ void reset_timeout(int timeout) return; if ((get_pm_cur_state() == S_LCDOFF) - && (is_emulator() == true || display_conf.sleep_support == false)) + && (is_emulator() == true || timeout_sleep_support == false)) return; _I("Reset timeout(%d ms).", timeout); @@ -1365,7 +1364,7 @@ static int default_trans(int evt) states[get_pm_cur_state()].trans(EVENT_TIMEOUT); } else { if ((get_pm_cur_state() == S_SLEEP) - && (is_emulator() == true || display_conf.sleep_support == false)) + && (is_emulator() == true || timeout_sleep_support == false)) return 0; st->action(st->timeout); diff --git a/plugins/tv/display/core.c b/plugins/tv/display/core.c index 3f9357d..33b3775 100644 --- a/plugins/tv/display/core.c +++ b/plugins/tv/display/core.c @@ -200,7 +200,6 @@ static struct display_config display_conf = { .aod_enter_level = 40, .aod_tsp = true, .touch_wakeup = false, - .sleep_support = true, .display_on_usb_conn_changed = true, }; @@ -603,7 +602,7 @@ void reset_timeout(int timeout) return; if ((get_pm_cur_state() == S_LCDOFF) - && (is_emulator() == true || display_conf.sleep_support == false)) + && (is_emulator() == true || timeout_sleep_support == false)) return; _I("Reset timeout(%d ms) pm_cur_state(%d).", timeout, get_pm_cur_state()); @@ -1355,7 +1354,7 @@ static int default_trans(int evt) states[get_pm_cur_state()].trans(EVENT_TIMEOUT); } else { if ((get_pm_cur_state() == S_SLEEP) - && (is_emulator() == true || display_conf.sleep_support == false)) + && (is_emulator() == true || timeout_sleep_support == false)) return 0; st->action(st->timeout); diff --git a/plugins/wearable/display/core.c b/plugins/wearable/display/core.c index 2ff8cf6..bd6349c 100644 --- a/plugins/wearable/display/core.c +++ b/plugins/wearable/display/core.c @@ -222,7 +222,6 @@ static struct display_config display_conf = { .aod_enter_level = 40, .aod_tsp = true, .touch_wakeup = false, - .sleep_support = true, .display_on_usb_conn_changed = true, }; @@ -818,7 +817,7 @@ void reset_timeout(int timeout) return; if ((get_pm_cur_state() == S_LCDOFF) - && (is_emulator() == true || display_conf.sleep_support == false)) + && (is_emulator() == true || timeout_sleep_support == false)) return; _I("Reset timeout(%d ms).", timeout); @@ -1619,7 +1618,7 @@ static int default_trans(int evt) states[get_pm_cur_state()].trans(EVENT_TIMEOUT); } else { if ((get_pm_cur_state() == S_SLEEP) - && (is_emulator() == true || display_conf.sleep_support == false)) + && (is_emulator() == true || timeout_sleep_support == false)) return 0; st->action(st->timeout); diff --git a/src/display/core.h b/src/display/core.h index e001f65..816e00b 100644 --- a/src/display/core.h +++ b/src/display/core.h @@ -138,7 +138,6 @@ struct display_config { bool timeout_enable; bool input_support; bool touch_wakeup; - bool sleep_support; bool display_on_usb_conn_changed; }; diff --git a/src/display/display.c b/src/display/display.c index 033240e..7eea0ed 100644 --- a/src/display/display.c +++ b/src/display/display.c @@ -152,9 +152,6 @@ int display_load_config(struct parse_result *result, void *user_data) } else if (MATCH(result->name, "AODTSP")) { c->aod_tsp = (MATCH(result->value, "yes") ? true : false); _D("TSP control at is %d at aod", c->aod_tsp); - } else if (MATCH(result->name, "SleepSupport")) { - c->sleep_support = (MATCH(result->value, "yes") ? true : false); - _D("SleepSupport is %d", c->sleep_support); } else if (MATCH(result->name, "DisplayOnUsbConnChanged")) { c->display_on_usb_conn_changed = (MATCH(result->value, "yes") ? true : false); } diff --git a/src/power/power-control.c b/src/power/power-control.c index 3482a60..c44d2de 100644 --- a/src/power/power-control.c +++ b/src/power/power-control.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "core/log.h" #include "shared/devices.h" @@ -42,6 +43,8 @@ #include "power/boot.h" #include "power-control.h" +#define POWER_CONF_FILE "/etc/deviced/power.conf" + static int mainlock_status = POWER_UNLOCK; static int vital_service; static bool vital_sleep; @@ -64,6 +67,8 @@ static const char history_string[PM_LOG_MAX][15] = { "LCD DIM", "LCD DIM FAIL", "LCD OFF", "LCD OFF COMPL", "LCD OFF FAIL", "LCD FAIL", "SLEEP"}; +bool timeout_sleep_support = false; + void pm_history_init() { memset(pm_history_log, 0x0, sizeof(pm_history_log)); @@ -325,9 +330,28 @@ static int __pm_power_unlock(void *data) return 0; } +static int load_sleep_config(struct parse_result *result, void *user_data) +{ + if (!MATCH(result->section, "Sleep")) + return 0; + + if (MATCH(result->name, "TimeoutSleepSupport") && MATCH(result->value, "yes")) { + timeout_sleep_support = true; + _D("timeout_sleep_support=%d", timeout_sleep_support); + } + + return 0; +} + static void power_control_init(void *data) { const struct device_ops *plugin_device_ops; + int retval; + + retval = config_parse(POWER_CONF_FILE, load_sleep_config, NULL); + if (retval < 0) + _E("Failed to load sleep config: %d", retval); + plugin_device_ops = find_device("power-control-plugin"); if (check_default(plugin_device_ops)) diff --git a/src/power/power-control.h b/src/power/power-control.h index 61d4f53..e4d1a18 100644 --- a/src/power/power-control.h +++ b/src/power/power-control.h @@ -47,6 +47,8 @@ enum vital_state { VITAL_EXIT, }; +extern bool timeout_sleep_support; + #ifdef ENABLE_PM_LOG void pm_history_init(void); void pm_history_save(enum pm_log_type log_type, int code); -- 2.7.4 From 376fcf9e188b7d517bac2ddcceb96d799a2ce607 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Wed, 17 Nov 2021 18:08:32 +0900 Subject: [PATCH 12/16] power: emit signal before sleep on iot-headless path : /Org/Tizen/System/DeviceD/Power interface : org.tizen.system.deviced.Power name : "sleep" parameter : "(tt)" uint64, current time in milisecond uint64, sleep id Change-Id: I1664898bf3f475125ad8bb3cafbd8a2c45948841 Signed-off-by: Youngjae Cho --- plugins/iot-headless/power/power-control.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/iot-headless/power/power-control.c b/plugins/iot-headless/power/power-control.c index eda7caf..7e20ca5 100644 --- a/plugins/iot-headless/power/power-control.c +++ b/plugins/iot-headless/power/power-control.c @@ -245,7 +245,12 @@ static const dbus_interface_u dbus_interface = { static int powerkey_short_pressed_cb(void *data) { int keycode; + int retval; + guint64 current_time_ms = 0; + struct timespec ts; + static int sleep_enabled = 0; /* initial sleep state: disabled */ + static guint64 sleep_id = 0; /* increased by 1 on enabling sleep */ if (!data) return 0; @@ -256,11 +261,16 @@ static int powerkey_short_pressed_cb(void *data) sleep_enabled ^= 1; /* toggle status */ if (sleep_enabled) { + retval = clock_gettime(CLOCK_REALTIME, &ts); + if (retval == 0) + current_time_ms = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); + + ++sleep_id; + gdbus_signal_emit(NULL, DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER, + "sleep", g_variant_new("(tt)", current_time_ms, sleep_id)); device_notify(DEVICE_NOTIFIER_REQUEST_ENABLE_AUTOSLEEP, NULL); - _D("Sleep enabled"); } else { device_notify(DEVICE_NOTIFIER_REQUEST_DISABLE_AUTOSLEEP, NULL); - _D("Sleep disabled"); } return 0; -- 2.7.4 From 7f05f3dbf3e696670679efd0fbde24bca23cb9e7 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Thu, 18 Nov 2021 18:07:03 +0900 Subject: [PATCH 13/16] input: acquire temporal lock on pressing key To process shortkey/longkey during autosleep is enabled, it must be prevented to re-enter sleep right after the device is woken up by key press. Therefore, hold wakelock temporarily during key pressed. Change-Id: I9d4f282fcae0beeec9edb97e463f4b0eef2bfacb Signed-off-by: Youngjae Cho --- plugins/iot-headless/input/input-handler.c | 6 ++++ plugins/iot-headless/power/power-control.c | 56 ++++++++++++++++++++++++++++++ src/shared/device-notifier.h | 2 ++ 3 files changed, 64 insertions(+) diff --git a/plugins/iot-headless/input/input-handler.c b/plugins/iot-headless/input/input-handler.c index 69b619e..2c293d0 100644 --- a/plugins/iot-headless/input/input-handler.c +++ b/plugins/iot-headless/input/input-handler.c @@ -31,8 +31,10 @@ #define LONGPRESS_INTERVAL 10000 /* milisecond */ #define SHORTPRESS_INTERVAL 3000 /* milisecond */ +/* milisecond */ static int longpress_interval = LONGPRESS_INTERVAL; static int shortpress_interval = SHORTPRESS_INTERVAL; + static guint shortpress_timer_id; static guint longpress_timer_id; @@ -54,6 +56,8 @@ static gboolean longpressed_cb(void *data) return G_SOURCE_REMOVE; if (power_device->execute) { + /* disable autosleep */ + device_notify(DEVICE_NOTIFIER_REQUEST_DISABLE_AUTOSLEEP, NULL); _D("powerkey long pressed"); power_device->execute("poweroff"); } @@ -122,11 +126,13 @@ static int input_handler_execute(void *data) if (keycode == KEY_POWER) { if (keyvalue == KEYVALUE_PRESS) { + device_notify(DEVICE_NOTIFIER_KEY_PRESS, (void *)(intptr_t) KEY_POWER); start_shortpress_timer(); start_longpress_timer(); } else if (keyvalue == KEYVALUE_RELEASE) { stop_shortpress_timer(); stop_longpress_timer(); + device_notify(DEVICE_NOTIFIER_KEY_RELEASE, (void *)(intptr_t) KEY_POWER); } } diff --git a/plugins/iot-headless/power/power-control.c b/plugins/iot-headless/power/power-control.c index 7e20ca5..5be4ad8 100644 --- a/plugins/iot-headless/power/power-control.c +++ b/plugins/iot-headless/power/power-control.c @@ -34,6 +34,12 @@ #define PROCESS_CHECK_TIMEOUT 600000 /* milisecond, 10 minute */ #endif +#define KEYPRESS_LOCK_TIMEOUT 4000 /* milisecond */ + +/* temporal wakelock of powerkey input */ +#define KEY_PRESSED_TEMPORAL_LOCK "templock" +#define TEMPORAL_LOCK_WAKE_MARGIN 1000 /* milisecond */ + static GList *lock_list; struct lock_node { @@ -44,6 +50,54 @@ struct lock_node { char locktime[64]; }; +static guint keypress_temporal_timer_id; + +static gboolean temporal_lock_expired_cb(void *data) +{ + sys_set_str("/sys/power/wake_unlock", KEY_PRESSED_TEMPORAL_LOCK); + keypress_temporal_timer_id = 0; + + return G_SOURCE_REMOVE; +} + +static int acquire_temporal_lock(void *data) +{ + int keycode = (int)(intptr_t) data; + + if (keycode != KEY_POWER) + return 0; + + if (keypress_temporal_timer_id) { + g_source_remove(keypress_temporal_timer_id); + keypress_temporal_timer_id = 0; + } + + sys_set_str("/sys/power/wake_lock", KEY_PRESSED_TEMPORAL_LOCK); + keypress_temporal_timer_id = g_timeout_add(KEYPRESS_LOCK_TIMEOUT + TEMPORAL_LOCK_WAKE_MARGIN, + temporal_lock_expired_cb, NULL); + + return 0; +} + +static int release_temporal_lock(void * data) +{ + int keycode = (int)(intptr_t) data; + + if (keycode != KEY_POWER) + return 0; + + if (keypress_temporal_timer_id) { + g_source_remove(keypress_temporal_timer_id); + keypress_temporal_timer_id = 0; + } + + /* shorten timeout */ + keypress_temporal_timer_id = g_timeout_add(TEMPORAL_LOCK_WAKE_MARGIN, + temporal_lock_expired_cb, NULL); + + return 0; +} + static void print_lock_node(void) { GList *elem; @@ -287,6 +341,8 @@ static void power_control_init(void *data) /* initial sleep state: disabled */ device_notify(DEVICE_NOTIFIER_REQUEST_DISABLE_AUTOSLEEP, NULL); + register_notifier(DEVICE_NOTIFIER_KEY_PRESS, acquire_temporal_lock); + register_notifier(DEVICE_NOTIFIER_KEY_RELEASE, release_temporal_lock); register_notifier(DEVICE_NOTIFIER_KEY_SHORTPRESS, powerkey_short_pressed_cb); } diff --git a/src/shared/device-notifier.h b/src/shared/device-notifier.h index 7269d57..77c1b73 100644 --- a/src/shared/device-notifier.h +++ b/src/shared/device-notifier.h @@ -60,6 +60,8 @@ enum device_notifier_type { DEVICE_NOTIFIER_DISPLAY_BRIGHTNESS, DEVICE_NOTIFIER_ULTRAPOWERSAVING, DEVICE_NOTIFIER_EXTCON_COUNT, + DEVICE_NOTIFIER_KEY_PRESS, + DEVICE_NOTIFIER_KEY_RELEASE, DEVICE_NOTIFIER_KEY_SHORTPRESS, /* hold down a key for a short duration */ DEVICE_NOTIFIER_KEY_LONGPRESS, /* hold down a key for a long duration */ -- 2.7.4 From 07c98b983e0ab3e075039455fbe75ff9b1536cbe Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Fri, 19 Nov 2021 12:01:32 +0900 Subject: [PATCH 14/16] input: change shortkey/longkey interval Change-Id: I466c591b754c906fe9b77854e4fca43b4f78ac26 Signed-off-by: Youngjae Cho --- plugins/iot-headless/input/input-handler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/iot-headless/input/input-handler.c b/plugins/iot-headless/input/input-handler.c index 2c293d0..a70755d 100644 --- a/plugins/iot-headless/input/input-handler.c +++ b/plugins/iot-headless/input/input-handler.c @@ -28,8 +28,8 @@ #define KEYVALUE_PRESS 1 #define KEYVALUE_RELEASE 0 -#define LONGPRESS_INTERVAL 10000 /* milisecond */ -#define SHORTPRESS_INTERVAL 3000 /* milisecond */ +#define LONGPRESS_INTERVAL 4000 /* milisecond */ +#define SHORTPRESS_INTERVAL 2000 /* milisecond */ /* milisecond */ static int longpress_interval = LONGPRESS_INTERVAL; -- 2.7.4 From af5412b3c231055715696b304214849c48b2341b Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Wed, 17 Nov 2021 16:44:55 +0900 Subject: [PATCH 15/16] power: introduce sleep-wait for iot-headless Sleep-wait defers wake unlock if somebody wants to defer sleep for a short duration. For example, system might want to notify user that it is going to sleep by alarming sound. To play sound, system must hold running state for a moment. One who wants to defer sleep must request sleep-wait. On receiving signal that sleep is requested, it processes todo list before going to sleep. And after finishing the job, it must confirm that it is OK to go into sleep. For now, deviced waits maximum of 5 seconds, and after this timeout, wake unlock even someone hasn't confirmed the sleep-wait. Sleep-wait offers dbus methods. 1. Adding sleep-wait for deferring sleep path : /Org/Tizen/System/DeviceD/Power interface : org.tizen.system.deviced.Power member : AddSleepWait parameter : no parameter return : "(i)", 0 on success, negative on error. 2. Removing sleep-wait path : /Org/Tizen/System/DeviceD/Power interface : org.tizen.system.deviced.Power member : RemoveSleepWait parameter : no parameter return : no return 3. Confirming sleep-wait, which notifies deviced that it is OK to go into sleep. path : /Org/Tizen/System/DeviceD/Power interface : org.tizen.system.deviced.Power member : ConfirmSleepWait parameter : "(i)", sleep id to confirm return : "(i)", 0 on success, negative on error. Change-Id: I58860ab7633c3863cc3ee06befc49b0e152934fe Signed-off-by: Youngjae Cho --- plugins/iot-headless/power/power-control.c | 75 ++++++++- plugins/iot-headless/power/sleep-wait.c | 255 +++++++++++++++++++++++++++++ plugins/iot-headless/power/sleep-wait.h | 12 ++ src/display/display-dbus.c | 35 ---- src/shared/common.c | 36 ++++ src/shared/common.h | 1 + 6 files changed, 375 insertions(+), 39 deletions(-) create mode 100644 plugins/iot-headless/power/sleep-wait.c create mode 100644 plugins/iot-headless/power/sleep-wait.h diff --git a/plugins/iot-headless/power/power-control.c b/plugins/iot-headless/power/power-control.c index 5be4ad8..0a72e95 100644 --- a/plugins/iot-headless/power/power-control.c +++ b/plugins/iot-headless/power/power-control.c @@ -30,6 +30,8 @@ #include "shared/log.h" #include "shared/device-notifier.h" +#include "sleep-wait.h" + #ifndef PROCESS_CHECK_TIMEOUT #define PROCESS_CHECK_TIMEOUT 600000 /* milisecond, 10 minute */ #endif @@ -282,9 +284,73 @@ out: return g_variant_new("(i)", ret); } +static GVariant *dbus_power_add_sleep_wait(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) +{ + int ret = 0; + pid_t pid; + + pid = gdbus_connection_get_sender_pid(conn, sender); + if (pid == -1 || kill(pid, 0) == -1) { + _E("%d process does not exist, dbus ignored.", pid); + ret = -ESRCH; + goto out; + } + + ret = add_sleep_wait(pid); + +out: + return g_variant_new("(i)", ret); +} + +static GVariant *dbus_power_remove_sleep_wait(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) +{ + pid_t pid; + + pid = gdbus_connection_get_sender_pid(conn, sender); + if (pid == -1 || kill(pid, 0) == -1) { + _E("%d process does not exist, dbus ignored.", pid); + goto out; + } + + remove_sleep_wait(pid); + +out: + return gdbus_new_g_variant_tuple(); +} + +static GVariant *dbus_power_confirm_sleep_wait(GDBusConnection *conn, + const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, + GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) +{ + int ret = 0; + pid_t pid; + int sleep_id; + + pid = gdbus_connection_get_sender_pid(conn, sender); + if (pid == -1 || kill(pid, 0) == -1) { + _E("%d process does not exist, dbus ignored.", pid); + ret = -ESRCH; + goto out; + } + + g_variant_get(param, "(i)", &sleep_id); + + ret = confirm_sleep_wait(pid, sleep_id); + +out: + return g_variant_new("(i)", ret); +} + static const dbus_method_s dbus_methods[] = { - { "LockCpu", "i", "i", dbus_power_lock_cpu }, - { "UnlockCpu", NULL, "i", dbus_power_unlock_cpu }, + { "LockCpu", "i", "i", dbus_power_lock_cpu }, + { "UnlockCpu", NULL, "i", dbus_power_unlock_cpu }, + { "AddSleepWait", NULL, "i", dbus_power_add_sleep_wait }, + { "RemoveSleepWait", NULL, NULL, dbus_power_remove_sleep_wait }, + { "ConfirmSleepWait", "i", "i", dbus_power_confirm_sleep_wait }, /* Add methods here */ }; @@ -315,16 +381,17 @@ static int powerkey_short_pressed_cb(void *data) sleep_enabled ^= 1; /* toggle status */ if (sleep_enabled) { + ++sleep_id; retval = clock_gettime(CLOCK_REALTIME, &ts); if (retval == 0) current_time_ms = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); - ++sleep_id; gdbus_signal_emit(NULL, DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER, "sleep", g_variant_new("(tt)", current_time_ms, sleep_id)); - device_notify(DEVICE_NOTIFIER_REQUEST_ENABLE_AUTOSLEEP, NULL); + start_sleep_wait(sleep_id); } else { device_notify(DEVICE_NOTIFIER_REQUEST_DISABLE_AUTOSLEEP, NULL); + stop_sleep_wait(); } return 0; diff --git a/plugins/iot-headless/power/sleep-wait.c b/plugins/iot-headless/power/sleep-wait.c new file mode 100644 index 0000000..d6c1d48 --- /dev/null +++ b/plugins/iot-headless/power/sleep-wait.c @@ -0,0 +1,255 @@ +#include +#include + +#include "shared/log.h" +#include "shared/device-notifier.h" +#include "shared/common.h" + +#include "sleep-wait.h" + +#define MAX_WAIT_SECOND 5 /* second */ + +struct sleep_wait { + pid_t pid; + char comm[128]; + // int timeout; + // int timer_id; +}; + +/* inactive: This list contains sleep waits added by AddSleepWait dbus method. + * active: All entries of inactive list are moved to this list when sleep is requested. + * Each one moves to inactive list on receiving ConfirmWait dbus method. + * Sleep will be triggered when it becomes empty. */ +static GList *inactive; +static GList *active; + +static int max_wait_timer; +static int current_sleep_id; + +static void switch_active_list(void) +{ + GList *tmp; + int n; + + n = g_list_length(active); + if (n != 0) + _W("Sleep wait remains in active list, %d", n); + + tmp = inactive; + inactive = active; + active = tmp; +} + +static void request_wake_unlock(void) +{ + device_notify(DEVICE_NOTIFIER_REQUEST_ENABLE_AUTOSLEEP, NULL); + device_notify(DEVICE_NOTIFIER_REQUEST_WAKE_UNLOCK, NULL); +} + +static gboolean max_wait_expired_cb(void *data) +{ + struct sleep_wait *sw; + GList *elem, *elem_next; + + max_wait_timer = 0; + + /* force confirmation */ + if (g_list_length(active) != 0) { + SYS_G_LIST_FOREACH_SAFE(active, elem, elem_next, sw) { + if (kill(sw->pid, 0) != 0) { + _D("Remove not existing sleep wait of pid=%d(%s)", sw->pid, sw->comm); + active = g_list_remove(active, sw); + free(sw); + } else { /* move to inactive manually */ + _W("pid=%d(%s) hasn't comfirmed sleep wait", sw->pid, sw->comm); + active = g_list_remove(active, sw); + inactive = g_list_append(inactive, sw); + } + } + } + + _D("Force wake unlock"); + request_wake_unlock(); + + return G_SOURCE_REMOVE; +} + +/* It returns + * 0 if sleep_wait is found in inactive list, + * -EBUSY if sleep_wait is found in active list, + * -ESRCH if sleep_wait is not found in both list */ +static int find_sleep_wait(pid_t pid, struct sleep_wait **sw) +{ + struct sleep_wait *ret = NULL; + GList *elem; + + if (!sw) + return -EINVAL; + + SYS_G_LIST_FOREACH(inactive, elem, ret) { + if (ret->pid == pid) { + *sw = ret; + return 0; + } + } + + SYS_G_LIST_FOREACH(active, elem, ret) { + if (ret->pid == pid) { + *sw = ret; + return -EBUSY; + } + } + + *sw = NULL; + return -ESRCH; +} + +int add_sleep_wait(pid_t pid) +{ + struct sleep_wait *sw; + int ret; + + ret = find_sleep_wait(pid, &sw); + if (ret == -ESRCH) { /* new node */ + sw = calloc(1, sizeof(struct sleep_wait)); + if (!sw) + return -ENOMEM; + + sw->pid = pid; + get_command(pid, sw->comm, sizeof(sw->comm)); + inactive = g_list_append(inactive, sw); + + _D("pid=%d(%s) is added to sleep wait list", sw->pid, sw->comm); + } else if (ret == 0 || ret == -EBUSY) { + _D("pid=%d(%s) has already been added to sleep wait list", sw->pid, sw->comm); + } + + return ret; +} + +void remove_sleep_wait(pid_t pid) +{ + struct sleep_wait *sw = NULL; + int retval; + + retval = find_sleep_wait(pid, &sw); + if (retval == -ESRCH) + return; + + if (sw) { + _D("pid=%d(%s) requested removing sleep wait", sw->pid, sw->comm); + + /* remove from where it is contained */ + active = g_list_remove(active, sw); + inactive = g_list_remove(inactive, sw); + + free(sw); + + /* wake unlock when active becomes empty by this operation + * during waiting sleep confirmations */ + if (max_wait_timer != 0 && g_list_length(active) == 0) { + g_source_remove(max_wait_timer); + max_wait_timer = 0; + + _D("All sleep waits have been confirmed, wake unlock"); + request_wake_unlock(); + } + } +} + +int confirm_sleep_wait(pid_t pid, int id) +{ + struct sleep_wait *sw; + int ret = 0; + + ret = find_sleep_wait(pid, &sw); + if (ret == -ESRCH) { + _E("pid=%d hasn't been added to sleep wait list", pid); + return ret; + } + + /* Multiple confirmation or + * confirm request after MAX_WAIT_SECOND */ + if (ret == 0) { + _D("pid=%d(%s) sleep wait has already been confirmed", sw->pid, sw->comm); + return 0; + } + + if (id != current_sleep_id) { + _E("Confirm mismatches sleep_id, current=%d, confirm=%d", current_sleep_id, id); + return -EINVAL; + } + + /* Move sw from active to inactive list. + * Wake unlock if active becomes empty. */ + if (ret == -EBUSY) { + active = g_list_remove(active, sw); + inactive = g_list_append(inactive, sw); + _D("pid=%d(%s) confirmed sleep wait", sw->pid, sw->comm); + + if (g_list_length(active) == 0) { + /* remove max_wait_timer and wake unlock immediately */ + if (max_wait_timer) { + g_source_remove(max_wait_timer); + max_wait_timer = 0; + } + + _D("All sleep waits have been confirmed, wake unlock"); + request_wake_unlock(); + } + + return 0; + } + + /* fail */ + _E("Failed to confirm sleep wait, %d", ret); + + return ret; +} + +void start_sleep_wait(int id) +{ + if (max_wait_timer) { + _E("Already sleep waiting"); + return; + } + + switch_active_list(); + + /* no need to defer sleep. wake unlock */ + if (g_list_length(active) == 0) { + request_wake_unlock(); + return; + } + + current_sleep_id = id; + + _D("Sleep wait is triggered, maximum wait timeout=%ds", MAX_WAIT_SECOND); + max_wait_timer = g_timeout_add_seconds(MAX_WAIT_SECOND, max_wait_expired_cb, NULL); +} + +void stop_sleep_wait(void) +{ + struct sleep_wait *sw; + GList *elem, *elem_next; + + if (max_wait_timer == 0) + return; + + /* cancel sleep wait */ + g_source_remove(max_wait_timer); + max_wait_timer = 0; + + _D("Wake locked during sleep wait, cancel all sleep waits"); + + SYS_G_LIST_FOREACH_SAFE(active, elem, elem_next, sw) { + if (kill(sw->pid, 0) != 0) { + _D("Remove not existing sleep wait of %d(%s)", sw->pid, sw->comm); + active = g_list_remove(active, sw); + free(sw); + } else { /* move to inactive manually */ + active = g_list_remove(active, sw); + inactive = g_list_append(inactive, sw); + } + } +} diff --git a/plugins/iot-headless/power/sleep-wait.h b/plugins/iot-headless/power/sleep-wait.h new file mode 100644 index 0000000..e7ca51e --- /dev/null +++ b/plugins/iot-headless/power/sleep-wait.h @@ -0,0 +1,12 @@ +#ifndef __SLEEP_WAIT_H__ +#define __SLEEP_WAIT_H__ + +#include + +int add_sleep_wait(pid_t pid); +void remove_sleep_wait(pid_t pid); +int confirm_sleep_wait(pid_t pid, int id); +void start_sleep_wait(int id); +void stop_sleep_wait(void); + +#endif //__SLEEP_WAIT_H__ diff --git a/src/display/display-dbus.c b/src/display/display-dbus.c index d6d6e53..a6a5909 100644 --- a/src/display/display-dbus.c +++ b/src/display/display-dbus.c @@ -993,41 +993,6 @@ struct pmlock_expired_s { static GList *expired_req_list; -static int get_command(pid_t pid, char *comm, size_t len) -{ - FILE *fp; - char path[PATH_MAX]; - char name[NAME_MAX]; - char *tmp; - int ret; - - snprintf(path, sizeof(path), "/proc/%d/comm", pid); - - fp = fopen(path, "r"); - if (!fp) { - _E("Failed to open file %s, errno:%d", path, errno); - return -errno; - } - - ret = fread(name, 1, sizeof(name) - 1, fp); - name[ret] = '\0'; - fclose(fp); - - tmp = name; - while (*tmp != '\0') { - if (*tmp == '\n' || - *tmp == '\r') { - *tmp = '\0'; - break; - } - tmp++; - } - - snprintf(comm, len, "%s", name); - - return 0; -} - static GVariant *dbus_locktimeout_expired(GDBusConnection *conn, const gchar *sender, const gchar *path, const gchar *iface, const gchar *name, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data) diff --git a/src/shared/common.c b/src/shared/common.c index c7f4bb0..f52fa6f 100644 --- a/src/shared/common.c +++ b/src/shared/common.c @@ -531,3 +531,39 @@ int do_copy_force(const char *src, const char *dst) return do_copy_internal(src, dst, 0644, true); } + +int get_command(pid_t pid, char *comm, size_t len) +{ + FILE *fp; + char path[PATH_MAX]; + char name[NAME_MAX]; + char *tmp; + int ret; + + snprintf(path, sizeof(path), "/proc/%d/comm", pid); + + fp = fopen(path, "r"); + if (!fp) { + _E("Failed to open file %s, errno:%d", path, errno); + return -errno; + } + + ret = fread(name, 1, sizeof(name) - 1, fp); + name[ret] = '\0'; + fclose(fp); + + tmp = name; + while (*tmp != '\0') { + if (*tmp == '\n' || + *tmp == '\r') { + *tmp = '\0'; + break; + } + tmp++; + } + + snprintf(comm, len, "%s", name); + + return 0; +} + diff --git a/src/shared/common.h b/src/shared/common.h index a912486..1d2cdb0 100644 --- a/src/shared/common.h +++ b/src/shared/common.h @@ -209,6 +209,7 @@ int do_mkdir(const char *path, mode_t mode); int do_copy_force(const char *src, const char *dst); void watchdog_notify(void); int print_open_files(const char *mount_point); +int get_command(pid_t pid, char *comm, size_t len); #ifdef __cplusplus } -- 2.7.4 From 89a98020d5a89cd8a9f0289fd8be81883f635208 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Fri, 19 Nov 2021 17:46:56 +0900 Subject: [PATCH 16/16] power: emit signal on wakeup path : /Org/Tizen/System/DeviceD/Power interface : org.tizen.system.deviced.Power signame : wakeup parameter : "(ii)" uint64: current time in milisecond uitn64: wakeup reason (refer device API) Change-Id: I8078b056b8f22e86c545ceb291959fbe62bc6869 Signed-off-by: Youngjae Cho --- plugins/iot-headless/power/power-control.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/iot-headless/power/power-control.c b/plugins/iot-headless/power/power-control.c index 0a72e95..157e406 100644 --- a/plugins/iot-headless/power/power-control.c +++ b/plugins/iot-headless/power/power-control.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "shared/devices.h" #include "shared/log.h" @@ -379,12 +380,13 @@ static int powerkey_short_pressed_cb(void *data) if (keycode != KEY_POWER) return 0; + retval = clock_gettime(CLOCK_REALTIME, &ts); + if (retval == 0) + current_time_ms = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); + sleep_enabled ^= 1; /* toggle status */ if (sleep_enabled) { ++sleep_id; - retval = clock_gettime(CLOCK_REALTIME, &ts); - if (retval == 0) - current_time_ms = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); gdbus_signal_emit(NULL, DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER, "sleep", g_variant_new("(tt)", current_time_ms, sleep_id)); @@ -392,6 +394,8 @@ static int powerkey_short_pressed_cb(void *data) } else { device_notify(DEVICE_NOTIFIER_REQUEST_DISABLE_AUTOSLEEP, NULL); stop_sleep_wait(); + gdbus_signal_emit(NULL, DEVICED_PATH_POWER, DEVICED_INTERFACE_POWER, + "wakeup", g_variant_new("(tt)", current_time_ms, DEVICE_SIG_WAKEUP_SHORTKEY)); } return 0; -- 2.7.4