Refactor app-core 12/247812/87
authorJunghoon Park <jh9216.park@samsung.com>
Tue, 17 Nov 2020 06:07:17 +0000 (15:07 +0900)
committerChanggyu Choi <changyu.choi@samsung.com>
Mon, 10 Jan 2022 04:48:45 +0000 (13:48 +0900)
- Redesigned by c++

Change-Id: I7659cab20ca2599c74640f2e7fe84b609166c113
Signed-off-by: Junghoon Park <jh9216.park@samsung.com>
Signed-off-by: jh9216.park <jh9216.park@samsung.com>
126 files changed:
AUTHORS [deleted file]
CMakeLists.txt
TC/build.sh [deleted file]
TC/execute.sh [deleted file]
TC/tet_code [deleted file]
TC/tet_scen [deleted file]
TC/tetbuild.cfg [deleted file]
TC/tetclean.cfg [deleted file]
TC/tetexec.cfg [deleted file]
TC/unit/Makefile [deleted file]
TC/unit/tc_gen.sh [deleted file]
TC/unit/tslist [deleted file]
TC/unit/utc_ApplicationFW_appcore_efl_main_func.c [deleted file]
TC/unit/utc_ApplicationFW_appcore_exit_func.c [deleted file]
TC/unit/utc_ApplicationFW_appcore_get_rotation_state_func.c [deleted file]
TC/unit/utc_ApplicationFW_appcore_init_func.c [deleted file]
TC/unit/utc_ApplicationFW_appcore_measure_start_func.c [deleted file]
TC/unit/utc_ApplicationFW_appcore_measure_time_from_func.c [deleted file]
TC/unit/utc_ApplicationFW_appcore_measure_time_func.c [deleted file]
TC/unit/utc_ApplicationFW_appcore_set_event_callback_func.c [deleted file]
TC/unit/utc_ApplicationFW_appcore_set_i18n_func.c [deleted file]
TC/unit/utc_ApplicationFW_appcore_set_rotation_cb_func.c [deleted file]
TC/unit/utc_ApplicationFW_appcore_unset_rotation_cb_func.c [deleted file]
TC/unit/utc_MODULE_API_func.c.in [deleted file]
cmake/Modules/ApplyPkgConfig.cmake [new file with mode: 0644]
legacy/CMakeLists.txt [new file with mode: 0644]
legacy/appcore-common.pc.in [moved from appcore-common.pc.in with 100% similarity]
legacy/appcore-efl.pc.in [moved from appcore-efl.pc.in with 100% similarity]
legacy/appcore-multiwindow.pc.in [moved from appcore-multiwindow.pc.in with 100% similarity]
legacy/appcore-ui.pc.in [moved from appcore-ui.pc.in with 100% similarity]
legacy/include/appcore-common.h [moved from include/appcore-common.h with 100% similarity]
legacy/include/appcore-efl.h [moved from include/appcore-efl.h with 100% similarity]
legacy/include/appcore-internal.h [moved from include/appcore-internal.h with 100% similarity]
legacy/include/appcore_base.h [moved from include/appcore_base.h with 100% similarity]
legacy/include/appcore_base_control.h [moved from include/appcore_base_control.h with 100% similarity]
legacy/include/appcore_efl_base.h [moved from include/appcore_efl_base.h with 100% similarity]
legacy/include/appcore_multiwindow_base.h [moved from include/appcore_multiwindow_base.h with 100% similarity]
legacy/include/appcore_ui_base.h [moved from include/appcore_ui_base.h with 100% similarity]
legacy/include/appcore_ui_plugin.h [moved from include/appcore_ui_plugin.h with 100% similarity]
legacy/include/appcore_watchdog.h [moved from include/appcore_watchdog.h with 100% similarity]
legacy/src/base/appcore_base.c [moved from src/base/appcore_base.c with 100% similarity]
legacy/src/base/appcore_base_control.c [moved from src/base/appcore_base_control.c with 100% similarity]
legacy/src/base/appcore_base_private.h [moved from src/base/appcore_base_private.h with 100% similarity]
legacy/src/efl_base/appcore_efl_base.c [moved from src/efl_base/appcore_efl_base.c with 100% similarity]
legacy/src/efl_base/appcore_efl_base_private.h [moved from src/efl_base/appcore_efl_base_private.h with 100% similarity]
legacy/src/legacy/appcore-efl.c [moved from src/legacy/appcore-efl.c with 100% similarity]
legacy/src/legacy/appcore-i18n.c [moved from src/legacy/appcore-i18n.c with 100% similarity]
legacy/src/legacy/appcore-measure.c [moved from src/legacy/appcore-measure.c with 100% similarity]
legacy/src/legacy/appcore-rotation.c [moved from src/legacy/appcore-rotation.c with 100% similarity]
legacy/src/legacy/appcore.c [moved from src/legacy/appcore.c with 100% similarity]
legacy/src/multiwindow_base/appcore_multiwindow_base.c [moved from src/multiwindow_base/appcore_multiwindow_base.c with 100% similarity]
legacy/src/multiwindow_base/appcore_multiwindow_base_class.c [moved from src/multiwindow_base/appcore_multiwindow_base_class.c with 100% similarity]
legacy/src/multiwindow_base/appcore_multiwindow_base_instance.c [moved from src/multiwindow_base/appcore_multiwindow_base_instance.c with 100% similarity]
legacy/src/multiwindow_base/appcore_multiwindow_base_private.h [moved from src/multiwindow_base/appcore_multiwindow_base_private.h with 100% similarity]
legacy/src/multiwindow_base/appcore_multiwindow_base_window.c [moved from src/multiwindow_base/appcore_multiwindow_base_window.c with 100% similarity]
legacy/src/ui_base/appcore_ui_base.c [moved from src/ui_base/appcore_ui_base.c with 100% similarity]
legacy/src/ui_base/appcore_ui_base_private.h [moved from src/ui_base/appcore_ui_base_private.h with 100% similarity]
legacy/src/ui_base/appcore_ui_plugin.c [moved from src/ui_base/appcore_ui_plugin.c with 100% similarity]
legacy/src/watchdog/appcore_watchdog.c [moved from src/watchdog/appcore_watchdog.c with 100% similarity]
legacy/src/watchdog/appcore_watchdog_private.h [moved from src/watchdog/appcore_watchdog_private.h with 100% similarity]
packaging/app-core.spec
tizen-cpp/CMakeLists.txt [new file with mode: 0644]
tizen-cpp/app-core-cpp/CMakeLists.txt [new file with mode: 0644]
tizen-cpp/app-core-cpp/app-core-cpp.pc.in [new file with mode: 0644]
tizen-cpp/app-core-cpp/app_core_base.cc [new file with mode: 0644]
tizen-cpp/app-core-cpp/app_core_base.hh [new file with mode: 0644]
tizen-cpp/app-core-cpp/interface_app_core.hh [new file with mode: 0644]
tizen-cpp/app-core-cpp/interface_app_core_ui.hh [new file with mode: 0644]
tizen-cpp/app-core-cpp/interface_main_loop.hh [new file with mode: 0644]
tizen-cpp/app-core-cpp/interface_window.hh [new file with mode: 0644]
tizen-cpp/app-core-efl-cpp/CMakeLists.txt [new file with mode: 0644]
tizen-cpp/app-core-efl-cpp/app-core-efl-cpp.pc.in [new file with mode: 0644]
tizen-cpp/app-core-efl-cpp/app_core_efl_base.cc [new file with mode: 0644]
tizen-cpp/app-core-efl-cpp/app_core_efl_base.hh [new file with mode: 0644]
tizen-cpp/app-core-efl-cpp/voice_elm_private.cc [new file with mode: 0644]
tizen-cpp/app-core-efl-cpp/voice_elm_private.hh [new file with mode: 0644]
tizen-cpp/app-core-multi-window-cpp/CMakeLists.txt [new file with mode: 0644]
tizen-cpp/app-core-multi-window-cpp/app-core-multi-window-cpp.pc.in [new file with mode: 0644]
tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.cc [new file with mode: 0644]
tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.hh [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/CMakeLists.txt [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/app-core-ui-cpp.pc.in [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/app_core_ui_base.hh [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/app_core_ui_base_legacy.cc [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/app_core_ui_delegator_private.cc [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/app_core_ui_delegator_private.hh [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/app_core_ui_plugin_private.cc [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/app_core_ui_plugin_private.hh [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/appcore_ui_base.h [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/wayland_handler_private.cc [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/wayland_handler_private.hh [new file with mode: 0644]
tizen-cpp/common/ecore_handler.cc [new file with mode: 0644]
tizen-cpp/common/ecore_handler.hh [new file with mode: 0644]
tizen-cpp/common/log_private.hh [new file with mode: 0644]
unittests/CMakeLists.txt [new file with mode: 0644]
unittests/app_core_base_test.cc [new file with mode: 0644]
unittests/app_core_efl_base_test.cc [new file with mode: 0644]
unittests/app_core_multi_window_base_test.cc [new file with mode: 0644]
unittests/main.cc [new file with mode: 0644]
unittests/mock/app_core_base_mock.h [new file with mode: 0644]
unittests/mock/app_core_efl_base_mock.h [new file with mode: 0644]
unittests/mock/app_core_multi_window_base_context_mock.h [new file with mode: 0644]
unittests/mock/app_core_multi_window_base_mock.h [new file with mode: 0644]
unittests/mock/aul_mock.cc [new file with mode: 0644]
unittests/mock/aul_mock.h [new file with mode: 0644]
unittests/mock/dbus_mock.cc [new file with mode: 0644]
unittests/mock/dbus_mock.h [new file with mode: 0644]
unittests/mock/dl_mock.cc [new file with mode: 0644]
unittests/mock/dl_mock.h [new file with mode: 0644]
unittests/mock/ecore_mock.cc [new file with mode: 0644]
unittests/mock/ecore_mock.h [new file with mode: 0644]
unittests/mock/ecore_wl2_mock.cc [new file with mode: 0644]
unittests/mock/ecore_wl2_mock.h [new file with mode: 0644]
unittests/mock/elm_mock.cc [new file with mode: 0644]
unittests/mock/elm_mock.h [new file with mode: 0644]
unittests/mock/mock_hook.h [new file with mode: 0644]
unittests/mock/module_mock.h [new file with mode: 0644]
unittests/mock/sensor_mock.cc [new file with mode: 0644]
unittests/mock/sensor_mock.h [new file with mode: 0644]
unittests/mock/test_fixture.cc [new file with mode: 0644]
unittests/mock/test_fixture.h [new file with mode: 0644]
unittests/mock/vconf_mock.cc [new file with mode: 0644]
unittests/mock/vconf_mock.h [new file with mode: 0644]
unittests/mock/wayland_mock.cc [new file with mode: 0644]
unittests/mock/wayland_mock.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644 (file)
index 064881e..0000000
--- a/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-Jayoun Lee <airjany@samsung.com>
-Sewook Park <sewook7.park@samsung.com>
-Jaeho Lee <jaeho81.lee@samsung.com>
index 038b35e..e491eaf 100644 (file)
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(appcore C)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
 
+PROJECT(appcore)
+
+SET(CMAKE_SKIP_BUILD_RPATH true)
 SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 SET(EXEC_PREFIX "\${prefix}")
 SET(LIBDIR ${LIB_INSTALL_DIR})
 SET(INCLUDEDIR "\${prefix}/include")
 SET(VERSION ${FULLVER})
 
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+#Target
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
 
-ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+SET(TARGET_APP_CORE_CPP "app-core-cpp")
+SET(TARGET_APP_CORE_UI_CPP "app-core-ui-cpp")
+SET(TARGET_APP_CORE_EFL_CPP "app-core-efl-cpp")
+SET(TARGET_APP_CORE_MULTI_WINDOW_CPP "app-core-multi-window-cpp")
 
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs -pie" )
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -Wall")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,--as-needed")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-
-SET(CMAKE_SKIP_BUILD_RPATH TRUE)
-
-#################################################################
-# Build appcore-common Library
-# ------------------------------
-SET(APPCORE_COMMON "appcore-common")
-SET(SRCS_common
-       src/legacy/appcore.c
-       src/legacy/appcore-measure.c
-       src/legacy/appcore-rotation.c
-       src/legacy/appcore-i18n.c
-       src/base/appcore_base.c
-       src/base/appcore_base_control.c
-       src/watchdog/appcore_watchdog.c)
-
-SET(HEADERS_common
-       appcore-common.h
-       appcore_base.h
-       appcore_watchdog.h
-       appcore_base_control.h)
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -Wall -Werror")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} ")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} ")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
 
 INCLUDE(FindPkgConfig)
-SET(APPCORE_PKG_CHECK_MODULES "gio-2.0 vconf sensor aul dlog capi-system-info")
-
-pkg_check_modules(pkg_common REQUIRED ${APPCORE_PKG_CHECK_MODULES})
-
-FOREACH(flag ${pkg_common_CFLAGS})
-       SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} ${flag}")
-ENDFOREACH(flag)
-
-ADD_LIBRARY(${APPCORE_COMMON} SHARED ${SRCS_common})
-SET_TARGET_PROPERTIES(${APPCORE_COMMON} PROPERTIES SOVERSION ${MAJORVER})
-SET_TARGET_PROPERTIES(${APPCORE_COMMON} PROPERTIES VERSION ${FULLVER})
-SET_TARGET_PROPERTIES(${APPCORE_COMMON} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_common})
-TARGET_LINK_LIBRARIES(${APPCORE_COMMON} ${pkg_common_LDFLAGS} "-ldl")
-
-CONFIGURE_FILE(${APPCORE_COMMON}.pc.in ${APPCORE_COMMON}.pc @ONLY)
-
-INSTALL(TARGETS ${APPCORE_COMMON} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPCORE_COMMON}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
-FOREACH(hfile ${HEADERS_common})
-       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${hfile} DESTINATION include/appcore)
-ENDFOREACH(hfile)
-
-#################################################################
-# Build appcore-ui Library
-# ------------------------------
-SET(APPCORE_UI "appcore-ui")
-SET(SRCS_ui src/ui_base/appcore_ui_base.c src/ui_base/appcore_ui_plugin.c)
-SET(HEADERS_ui appcore_ui_base.h)
-
-INCLUDE(FindPkgConfig)
-SET(APPCORE_UI_PKG_CHECK_MODULES "dlog ecore gobject-2.0 glib-2.0 aul bundle pkgmgr-info ttrace ecore-wl2 tizen-extension-client wayland-client")
-
-pkg_check_modules(pkg_ui REQUIRED ${APPCORE_UI_PKG_CHECK_MODULES})
-
-FOREACH(flag ${pkg_ui_CFLAGS})
-       SET(EXTRA_CFLAGS_ui "${EXTRA_CFLAGS_ui} ${flag}")
-ENDFOREACH(flag)
-
-ADD_LIBRARY(${APPCORE_UI} SHARED ${SRCS_ui})
-SET_TARGET_PROPERTIES(${APPCORE_UI} PROPERTIES SOVERSION ${MAJORVER})
-SET_TARGET_PROPERTIES(${APPCORE_UI} PROPERTIES VERSION ${FULLVER})
-SET_TARGET_PROPERTIES(${APPCORE_UI} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_ui})
-TARGET_LINK_LIBRARIES(${APPCORE_UI} ${pkg_ui_LDFLAGS} ${APPCORE_COMMON})
-
-CONFIGURE_FILE(${APPCORE_UI}.pc.in ${APPCORE_UI}.pc @ONLY)
-
-INSTALL(TARGETS ${APPCORE_UI} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPCORE_UI}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
-FOREACH(hfile ${HEADERS_ui})
-       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${hfile} DESTINATION include/appcore)
-ENDFOREACH(hfile)
-
-#################################################################
-# Build appcore-efl Library
-# ------------------------------
-SET(APPCORE_EFL "appcore-efl")
-SET(SRCS_efl src/legacy/appcore-efl.c src/efl_base/appcore_efl_base.c)
-SET(HEADERS_efl appcore-efl.h appcore_efl_base.h)
-
-INCLUDE(FindPkgConfig)
-SET(APPCORE_PKG_CHECK_MODULES2 "elementary dlog aul bundle ttrace")
-
-pkg_check_modules(pkg_efl REQUIRED ${APPCORE_PKG_CHECK_MODULES2})
-
-FOREACH(flag ${pkg_efl_CFLAGS})
-       SET(EXTRA_CFLAGS_efl "${EXTRA_CFLAGS_efl} ${flag}")
-ENDFOREACH(flag)
-
-ADD_LIBRARY(${APPCORE_EFL} SHARED ${SRCS_efl})
-SET_TARGET_PROPERTIES(${APPCORE_EFL} PROPERTIES SOVERSION ${MAJORVER})
-SET_TARGET_PROPERTIES(${APPCORE_EFL} PROPERTIES VERSION ${FULLVER})
-SET_TARGET_PROPERTIES(${APPCORE_EFL} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_efl})
-TARGET_LINK_LIBRARIES(${APPCORE_EFL} ${pkg_efl_LDFLAGS} ${APPCORE_UI})
-
-CONFIGURE_FILE(${APPCORE_EFL}.pc.in ${APPCORE_EFL}.pc @ONLY)
-
-INSTALL(TARGETS ${APPCORE_EFL} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPCORE_EFL}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
-FOREACH(hfile ${HEADERS_efl})
-       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${hfile} DESTINATION include/appcore)
-ENDFOREACH(hfile)
-
-#################################################################
-# Build appcore-multiwindow Library
-# ------------------------------
-SET(APPCORE_MULTIWINDOW "appcore-multiwindow")
-SET(SRCS_mw src/multiwindow_base/appcore_multiwindow_base.c
-       src/multiwindow_base/appcore_multiwindow_base_class.c
-       src/multiwindow_base/appcore_multiwindow_base_instance.c
-       src/multiwindow_base/appcore_multiwindow_base_window.c
-       )
-SET(HEADERS_mw appcore_multiwindow_base.h)
-
-INCLUDE(FindPkgConfig)
-SET(APPCORE_MULTIWINDOW_PKG_CHECK_MODULES "dlog ecore gobject-2.0 glib-2.0 aul ecore-wl2")
-
-pkg_check_modules(pkg_mw REQUIRED ${APPCORE_MULTIWINDOW_PKG_CHECK_MODULES})
-
-FOREACH(flag ${pkg_mw_CFLAGS})
-       SET(EXTRA_CFLAGS_mw "${EXTRA_CFLAGS_mw} ${flag}")
-ENDFOREACH(flag)
-
-ADD_LIBRARY(${APPCORE_MULTIWINDOW} SHARED ${SRCS_mw})
-SET_TARGET_PROPERTIES(${APPCORE_MULTIWINDOW} PROPERTIES SOVERSION ${MAJORVER})
-SET_TARGET_PROPERTIES(${APPCORE_MULTIWINDOW} PROPERTIES VERSION ${FULLVER})
-SET_TARGET_PROPERTIES(${APPCORE_MULTIWINDOW} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_mw})
-TARGET_LINK_LIBRARIES(${APPCORE_MULTIWINDOW} ${pkg_mw_LDFLAGS} ${APPCORE_COMMON})
-
-CONFIGURE_FILE(${APPCORE_MULTIWINDOW}.pc.in ${APPCORE_MULTIWINDOW}.pc @ONLY)
-
-INSTALL(TARGETS ${APPCORE_MULTIWINDOW} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPCORE_MULTIWINDOW}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
-FOREACH(hfile ${HEADERS_mw})
-       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${hfile} DESTINATION include/appcore)
-ENDFOREACH(hfile)
+INCLUDE(ApplyPkgConfig)
+
+PKG_CHECK_MODULES(AUL_DEPS REQUIRED aul)
+PKG_CHECK_MODULES(BUNDLE_DEPS REQUIRED bundle)
+PKG_CHECK_MODULES(CAPI_SYSTEM_INFO_DEPS REQUIRED capi-system-info)
+PKG_CHECK_MODULES(DLOG_DEPS REQUIRED dlog)
+PKG_CHECK_MODULES(ECORE_DEPS REQUIRED ecore)
+PKG_CHECK_MODULES(ECORE_WL2_DEPS REQUIRED ecore-wl2)
+PKG_CHECK_MODULES(ELEMENTARY_DEPS REQUIRED elementary)
+PKG_CHECK_MODULES(GIO_2_DEPS REQUIRED gio-2.0)
+PKG_CHECK_MODULES(GLIB_2_DEPS REQUIRED glib-2.0)
+PKG_CHECK_MODULES(GMOCK_DEPS REQUIRED gmock)
+PKG_CHECK_MODULES(GOBJECT_2_DEPS REQUIRED gobject-2.0)
+PKG_CHECK_MODULES(PKGMGR_INFO_DEPS REQUIRED pkgmgr-info)
+PKG_CHECK_MODULES(SENSOR_DEPS REQUIRED sensor)
+PKG_CHECK_MODULES(TIZEN_EXTENSION_CLIENT_DEPS REQUIRED tizen-extension-client)
+PKG_CHECK_MODULES(TTRACE_DEPS REQUIRED ttrace)
+PKG_CHECK_MODULES(VCONF_DEPS REQUIRED vconf)
+PKG_CHECK_MODULES(WAYLAND_CLIENT_DEPS REQUIRED wayland-client)
+PKG_CHECK_MODULES(WAYLAND_TBM_CLIENT_DEPS REQUIRED wayland-tbm-client)
+
+ADD_SUBDIRECTORY(legacy)
+ADD_SUBDIRECTORY(tizen-cpp)
+
+IF(NOT DEFINED MINIMUM_BUILD)
+ENABLE_TESTING()
+SET(APP_CORE_UNITTESTS app-core_unittests)
+ADD_TEST(NAME ${APP_CORE_UNITTESTS} COMMAND ${APP_CORE_UNITTESTS}
+        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/unittests)
+ADD_SUBDIRECTORY(unittests)
+ENDIF(NOT DEFINED MINIMUM_BUILD)
diff --git a/TC/build.sh b/TC/build.sh
deleted file mode 100755 (executable)
index 98ebeff..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-
-export TET_INSTALL_PATH=/scratchbox/tetware  # local tetware 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
-
-export TET_SUITE_ROOT=`pwd`
-FILE_NAME_EXTENSION=`date +%s`
-
-RESULT_DIR=results
-HTML_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.html
-JOURNAL_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.journal
-
-mkdir -p $RESULT_DIR
-
-tcc -c -p ./
-tcc -b -j $JOURNAL_RESULT -p ./
-grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT
diff --git a/TC/execute.sh b/TC/execute.sh
deleted file mode 100755 (executable)
index 2d9df79..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-#export TET_INSTALL_PATH=/mnt/nfs/tetware
-export TET_INSTALL_PATH=/scratchbox/tetware
-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
-
-export TET_SUITE_ROOT=`pwd`
-FILE_NAME_EXTENSION=`date +%s`
-
-RESULT_DIR=results
-HTML_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.html
-JOURNAL_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.journal
-
-mkdir -p $RESULT_DIR
-
-tcc -e -j $JOURNAL_RESULT -p ./
-grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT
diff --git a/TC/tet_code b/TC/tet_code
deleted file mode 100644 (file)
index a2cf6c1..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# TET reserved codes
-0 "PASS"
-1 "FAIL"
-2 "UNRESOLVED"
-3 "NOTINUSE"
-4 "UNSUPPORTED"
-5 "UNTESTED"
-6 "UNINITIATED"
-7 "NORESULT"
-
-# Test suite additional codes
-33 "INSPECT"
diff --git a/TC/tet_scen b/TC/tet_scen
deleted file mode 100644 (file)
index 43cbc9b..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-all
-       ^TEST
-##### Scenarios for TEST #####
-
-# Test scenario
-TEST
-       :include:/unit/tslist
diff --git a/TC/tetbuild.cfg b/TC/tetbuild.cfg
deleted file mode 100644 (file)
index 6192c78..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-TET_OUTPUT_CAPTURE=False
-TET_BUILD_TOOL=make
-TET_PASS_TC_NAME=True
diff --git a/TC/tetclean.cfg b/TC/tetclean.cfg
deleted file mode 100644 (file)
index c66eda4..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-TET_OUTPUT_CAPTURE=False
-TET_CLEAN_TOOL=make clean
diff --git a/TC/tetexec.cfg b/TC/tetexec.cfg
deleted file mode 100644 (file)
index 0d9d39a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-TET_OUTPUT_CAPTURE=False
diff --git a/TC/unit/Makefile b/TC/unit/Makefile
deleted file mode 100644 (file)
index f967994..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-CC ?= gcc
-
-TARGETS =  \
-         utc_ApplicationFW_appcore_efl_main_func \
-         utc_ApplicationFW_appcore_init_func \
-         utc_ApplicationFW_appcore_exit_func \
-         utc_ApplicationFW_appcore_set_rotation_cb_func \
-         utc_ApplicationFW_appcore_unset_rotation_cb_func \
-         utc_ApplicationFW_appcore_get_rotation_state_func \
-         utc_ApplicationFW_appcore_set_i18n_func \
-         utc_ApplicationFW_appcore_measure_start_func \
-         utc_ApplicationFW_appcore_measure_time_func \
-         utc_ApplicationFW_appcore_measure_time_from_func \
-         utc_ApplicationFW_appcore_set_event_callback_func
-
-PKGS = appcore-efl
-
-LDFLAGS = `pkg-config --libs $(PKGS)`
-LDFLAGS += $(TET_ROOT)/lib/tet3/tcm_s.o
-LDFLAGS += -L$(TET_ROOT)/lib/tet3 -ltcm_s
-LDFLAGS += -L$(TET_ROOT)/lib/tet3 -lapi_s
-
-CFLAGS = -I. `pkg-config --cflags $(PKGS)`
-CFLAGS += -I$(TET_ROOT)/inc/tet3
-CFLAGS += -Wall
-
-all: $(TARGETS)
-
-$(TARGETS): %: %.c
-       $(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
-
-clean:
-       rm -f $(TARGETS)
diff --git a/TC/unit/tc_gen.sh b/TC/unit/tc_gen.sh
deleted file mode 100755 (executable)
index 54f482d..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-TMPSTR=$0
-SCRIPT=${TMPSTR##*/}
-
-if [ $# -lt 2 ]; then
-       echo "Usage) $SCRIPT module_name api_name"
-       exit 1
-fi
-
-MODULE=$1
-API=$2
-TEMPLATE=utc_MODULE_API_func.c.in
-TESTCASE=utc_${MODULE}_${API}_func
-
-sed -e '
-       s^@API@^'"$API"'^g
-       s^@MODULE@^'"$MODULE"'^g
-       ' $TEMPLATE > $TESTCASE.c
-
-if [ ! -e "$TESTCASE.c" ]; then
-       echo "Failed"
-       exit 1
-fi
-echo "Testcase file is $TESTCASE.c"
-echo "Done"
-echo "please put \"$TESTCASE\" as Target in Makefile"
-echo "please put \"/unit/$TESTCASE\" in tslist"
diff --git a/TC/unit/tslist b/TC/unit/tslist
deleted file mode 100644 (file)
index 91c8d1a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/unit/utc_ApplicationFW_appcore_efl_main_func
-/unit/utc_ApplicationFW_appcore_init_func
-/unit/utc_ApplicationFW_appcore_exit_func
-/unit/utc_ApplicationFW_appcore_set_rotation_cb_func
-/unit/utc_ApplicationFW_appcore_unset_rotation_cb_func
-/unit/utc_ApplicationFW_appcore_get_rotation_state_func
-/unit/utc_ApplicationFW_appcore_set_i18n_func
-/unit/utc_ApplicationFW_appcore_measure_start_func
-/unit/utc_ApplicationFW_appcore_measure_time_func
-/unit/utc_ApplicationFW_appcore_measure_time_from_func
-/unit/utc_ApplicationFW_appcore_set_event_callback_func
diff --git a/TC/unit/utc_ApplicationFW_appcore_efl_main_func.c b/TC/unit/utc_ApplicationFW_appcore_efl_main_func.c
deleted file mode 100644 (file)
index eacd09e..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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 <tet_api.h>
-#include <Elementary.h>
-#include <appcore-efl.h>
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-static void utc_ApplicationFW_appcore_efl_main_func_01(void);
-static void utc_ApplicationFW_appcore_efl_main_func_02(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_ApplicationFW_appcore_efl_main_func_01, POSITIVE_TC_IDX },
-       { utc_ApplicationFW_appcore_efl_main_func_02, NEGATIVE_TC_IDX },
-       { NULL, 0},
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-static int app_reset(bundle *b, void *data)
-{
-       elm_exit();
-       return 0;
-}
-
-/**
- * @brief Positive test case of appcore_efl_main()
- */
-static void utc_ApplicationFW_appcore_efl_main_func_01(void)
-{
-       int r = 0;
-       int argc = 1;
-       char *_argv[] = {
-               "Testcase",
-               NULL,
-       };
-       char **argv;
-       struct appcore_ops ops = {
-               .reset = app_reset,
-       };
-
-       argv = _argv;
-       r = appcore_efl_main("Testcase", &argc, &argv, &ops);
-       printf("Return %d\n", r);
-       if (r) {
-               tet_infoline("appcore_efl_main() failed in positive test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-       tet_result(TET_PASS);
-}
-
-/**
- * @brief Negative test case of ug_init appcore_efl_main()
- */
-static void utc_ApplicationFW_appcore_efl_main_func_02(void)
-{
-       int r = 0;
-       int argc = 1;
-       char *_argv[] = {
-               "Testcase",
-               NULL,
-       };
-       char **argv;
-       struct appcore_ops ops = {
-               .reset = app_reset,
-       };
-
-       argv = _argv;
-       r = appcore_efl_main("Testcase", &argc, &argv, NULL);
-       if (!r) {
-               tet_infoline("appcore_efl_main() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       r = appcore_efl_main(NULL, &argc, &argv, &ops);
-       if (!r) {
-               tet_infoline("appcore_efl_main() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       r = appcore_efl_main("Testcase", NULL, &argv, &ops);
-       if (!r) {
-               tet_infoline("appcore_efl_main() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       r = appcore_efl_main("Testcase", &argc, NULL, &ops);
-       if (!r) {
-               tet_infoline("appcore_efl_main() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       tet_result(TET_PASS);
-}
diff --git a/TC/unit/utc_ApplicationFW_appcore_exit_func.c b/TC/unit/utc_ApplicationFW_appcore_exit_func.c
deleted file mode 100644 (file)
index b74e9a6..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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 <tet_api.h>
-#include <appcore-common.h>
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-static void utc_ApplicationFW_appcore_exit_func_01(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_ApplicationFW_appcore_exit_func_01, POSITIVE_TC_IDX },
-       { NULL, 0},
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of appcore_exit()
- */
-static void utc_ApplicationFW_appcore_exit_func_01(void)
-{
-       appcore_exit();
-       tet_result(TET_PASS);
-}
-
diff --git a/TC/unit/utc_ApplicationFW_appcore_get_rotation_state_func.c b/TC/unit/utc_ApplicationFW_appcore_get_rotation_state_func.c
deleted file mode 100644 (file)
index 45c0226..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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 <tet_api.h>
-#include <appcore-common.h>
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-static void utc_ApplicationFW_appcore_get_rotation_state_func_01(void);
-static void utc_ApplicationFW_appcore_get_rotation_state_func_02(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_ApplicationFW_appcore_get_rotation_state_func_01, POSITIVE_TC_IDX },
-       { utc_ApplicationFW_appcore_get_rotation_state_func_02, NEGATIVE_TC_IDX },
-       { NULL, 0},
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of appcore_get_rotation_state()
- */
-static void utc_ApplicationFW_appcore_get_rotation_state_func_01(void)
-{
-       int r = 0;
-       enum appcore_rm curr;
-
-       r = appcore_get_rotation_state(&curr);
-       if (r) {
-               tet_infoline("appcore_get_rotation_state() failed in positive test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-       tet_result(TET_PASS);
-}
-
-/**
- * @brief Negative test case of ug_init appcore_get_rotation_state()
- */
-static void utc_ApplicationFW_appcore_get_rotation_state_func_02(void)
-{
-       int r = 0;
-
-       r = appcore_get_rotation_state(NULL);
-       if (!r) {
-               tet_infoline("appcore_get_rotation_state() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-       tet_result(TET_PASS);
-}
diff --git a/TC/unit/utc_ApplicationFW_appcore_init_func.c b/TC/unit/utc_ApplicationFW_appcore_init_func.c
deleted file mode 100644 (file)
index 3c0e283..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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 <tet_api.h>
-#include <appcore-common.h>
-
-struct ui_ops {
-       void *data;
-       void (*cb_app)(int, void *, bundle *);
-};
-
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-static void utc_ApplicationFW_appcore_init_func_01(void);
-static void utc_ApplicationFW_appcore_init_func_02(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_ApplicationFW_appcore_init_func_01, POSITIVE_TC_IDX },
-       { utc_ApplicationFW_appcore_init_func_02, NEGATIVE_TC_IDX },
-       { NULL, 0},
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-       appcore_exit();
-}
-
-static void ui_cb(int evt, void *data, bundle *b)
-{
-}
-
-/**
- * @brief Positive test case of appcore_init()
- */
-static void utc_ApplicationFW_appcore_init_func_01(void)
-{
-       int r = 0;
-       int argc = 1;
-       char *argv[] = {
-               "Testcase",
-               NULL,
-       };
-       const struct ui_ops ops = {
-               .cb_app = ui_cb,
-       };
-
-       r = appcore_init("Testcase", &ops, argc, argv);
-       if (r) {
-               tet_infoline("appcore_init() failed in positive test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-       tet_result(TET_PASS);
-}
-
-/**
- * @brief Negative test case of ug_init appcore_init()
- */
-static void utc_ApplicationFW_appcore_init_func_02(void)
-{
-       int r = 0;
-       int argc = 1;
-       char *argv[] = {
-               "Testcase",
-               NULL,
-       };
-       const struct ui_ops ops = {
-               .cb_app = ui_cb,
-       };
-
-       r = appcore_init(NULL, &ops, argc, argv);
-       if (!r) {
-               tet_infoline("appcore_init() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       r = appcore_init("Testcase", NULL, argc, argv);
-       if (!r) {
-               tet_infoline("appcore_init() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       r = appcore_init("Testcase", &ops, -1, argv);
-       if (!r) {
-               tet_infoline("appcore_init() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       r = appcore_init("Testcase", &ops, argc, NULL);
-       if (!r) {
-               tet_infoline("appcore_init() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       tet_result(TET_PASS);
-}
diff --git a/TC/unit/utc_ApplicationFW_appcore_measure_start_func.c b/TC/unit/utc_ApplicationFW_appcore_measure_start_func.c
deleted file mode 100644 (file)
index 30eb144..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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 <tet_api.h>
-#include <appcore-common.h>
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-static void utc_ApplicationFW_appcore_measure_start_func_01(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_ApplicationFW_appcore_measure_start_func_01, POSITIVE_TC_IDX },
-       { NULL, 0},
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of appcore_measure_start()
- */
-static void utc_ApplicationFW_appcore_measure_start_func_01(void)
-{
-       appcore_measure_start();
-       tet_result(TET_PASS);
-}
-
diff --git a/TC/unit/utc_ApplicationFW_appcore_measure_time_from_func.c b/TC/unit/utc_ApplicationFW_appcore_measure_time_from_func.c
deleted file mode 100644 (file)
index 8af350b..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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 <tet_api.h>
-#include <appcore-common.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <stdio.h>
-
-#define APPCORE_TESTCASE "APPCORE_TESTCASE"
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-static void utc_ApplicationFW_appcore_measure_time_from_func_01(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_ApplicationFW_appcore_measure_time_from_func_01, POSITIVE_TC_IDX },
-       { NULL, 0},
-};
-
-static void startup(void)
-{
-       struct timeval tv;
-       char buf[1024];
-
-       gettimeofday(&tv, NULL);
-
-       snprintf(buf, sizeof(buf), "%d %d", (int)tv.tv_sec, (int)tv.tv_usec);
-       setenv(APPCORE_TESTCASE, buf, 1);
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of appcore_measure_time_from()
- */
-static void utc_ApplicationFW_appcore_measure_time_from_func_01(void)
-{
-       int r = 0;
-
-       r = appcore_measure_time_from(APPCORE_TESTCASE);
-       if (!r) {
-               tet_infoline("appcore_measure_time_from() failed in positive test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       unsetenv(APPCORE_TESTCASE);
-
-       r = appcore_measure_time_from(APPCORE_TESTCASE);
-       if (r) {
-               tet_infoline("appcore_measure_time_from() failed in positive test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       tet_result(TET_PASS);
-}
-
diff --git a/TC/unit/utc_ApplicationFW_appcore_measure_time_func.c b/TC/unit/utc_ApplicationFW_appcore_measure_time_func.c
deleted file mode 100644 (file)
index 245cd9f..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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 <tet_api.h>
-#include <appcore-common.h>
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-static void utc_ApplicationFW_appcore_measure_time_func_01(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_ApplicationFW_appcore_measure_time_func_01, POSITIVE_TC_IDX },
-       { NULL, 0},
-};
-
-static void startup(void)
-{
-       appcore_measure_start();
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of appcore_measure_time()
- */
-static void utc_ApplicationFW_appcore_measure_time_func_01(void)
-{
-       int r = 0;
-
-       r = appcore_measure_time();
-       if (r == 0) {
-               tet_infoline("appcore_measure_time() failed in positive test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-       tet_result(TET_PASS);
-}
-
diff --git a/TC/unit/utc_ApplicationFW_appcore_set_event_callback_func.c b/TC/unit/utc_ApplicationFW_appcore_set_event_callback_func.c
deleted file mode 100644 (file)
index 6cb792c..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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 <tet_api.h>
-#include <appcore-common.h>
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-static void utc_ApplicationFW_appcore_set_event_callback_func_01(void);
-static void utc_ApplicationFW_appcore_set_event_callback_func_02(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_ApplicationFW_appcore_set_event_callback_func_01, POSITIVE_TC_IDX },
-       { utc_ApplicationFW_appcore_set_event_callback_func_02, NEGATIVE_TC_IDX },
-       { NULL, 0},
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-static int cb(void *data)
-{
-
-       return 0;
-}
-
-
-/**
- * @brief Positive test case of appcore_set_event_callback()
- */
-static void utc_ApplicationFW_appcore_set_event_callback_func_01(void)
-{
-       int r = 0;
-
-       r = appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, cb, NULL);
-       if (r) {
-               tet_infoline("appcore_set_event_callback() failed in positive test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       r = appcore_set_event_callback(APPCORE_EVENT_LOW_MEMORY, NULL, NULL);
-       if (r) {
-               tet_infoline("appcore_set_event_callback() failed in positive test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       tet_result(TET_PASS);
-}
-
-/**
- * @brief Negative test case of ug_init appcore_set_event_callback()
- */
-static void utc_ApplicationFW_appcore_set_event_callback_func_02(void)
-{
-       int r = 0;
-
-       r = appcore_set_event_callback(-1, cb, NULL);
-       if (!r) {
-               tet_infoline("appcore_set_event_callback() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-       tet_result(TET_PASS);
-}
diff --git a/TC/unit/utc_ApplicationFW_appcore_set_i18n_func.c b/TC/unit/utc_ApplicationFW_appcore_set_i18n_func.c
deleted file mode 100644 (file)
index 6ec6522..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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 <tet_api.h>
-#include <appcore-common.h>
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-static void utc_ApplicationFW_appcore_set_i18n_func_01(void);
-static void utc_ApplicationFW_appcore_set_i18n_func_02(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_ApplicationFW_appcore_set_i18n_func_01, POSITIVE_TC_IDX },
-       { utc_ApplicationFW_appcore_set_i18n_func_02, NEGATIVE_TC_IDX },
-       { NULL, 0},
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of appcore_set_i18n()
- */
-static void utc_ApplicationFW_appcore_set_i18n_func_01(void)
-{
-       int r = 0;
-
-       r = appcore_set_i18n("Testcase", NULL);
-       if (r) {
-               tet_infoline("appcore_set_i18n() failed in positive test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-       tet_result(TET_PASS);
-}
-
-/**
- * @brief Negative test case of ug_init appcore_set_i18n()
- */
-static void utc_ApplicationFW_appcore_set_i18n_func_02(void)
-{
-       int r = 0;
-
-       r = appcore_set_i18n(NULL, NULL);
-       if (!r) {
-               tet_infoline("appcore_set_i18n() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-
-       tet_result(TET_PASS);
-}
diff --git a/TC/unit/utc_ApplicationFW_appcore_set_rotation_cb_func.c b/TC/unit/utc_ApplicationFW_appcore_set_rotation_cb_func.c
deleted file mode 100644 (file)
index 79a3738..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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 <tet_api.h>
-#include <appcore-common.h>
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-static void utc_ApplicationFW_appcore_set_rotation_cb_func_01(void);
-static void utc_ApplicationFW_appcore_set_rotation_cb_func_02(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_ApplicationFW_appcore_set_rotation_cb_func_01, POSITIVE_TC_IDX },
-       { utc_ApplicationFW_appcore_set_rotation_cb_func_02, NEGATIVE_TC_IDX },
-       { NULL, 0},
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-static int rot_cb(enum appcore_rm rm, void *data)
-{
-
-       return 0;
-}
-
-/**
- * @brief Positive test case of appcore_set_rotation_cb()
- */
-static void utc_ApplicationFW_appcore_set_rotation_cb_func_01(void)
-{
-       int r = 0;
-
-       r = appcore_set_rotation_cb(rot_cb, NULL);
-       if (r) {
-               tet_infoline("appcore_set_rotation_cb() failed in positive test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-       tet_result(TET_PASS);
-}
-
-/**
- * @brief Negative test case of ug_init appcore_set_rotation_cb()
- */
-static void utc_ApplicationFW_appcore_set_rotation_cb_func_02(void)
-{
-       int r = 0;
-
-       r = appcore_set_rotation_cb(NULL, NULL);
-       if (!r) {
-               tet_infoline("appcore_set_rotation_cb() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-       tet_result(TET_PASS);
-}
diff --git a/TC/unit/utc_ApplicationFW_appcore_unset_rotation_cb_func.c b/TC/unit/utc_ApplicationFW_appcore_unset_rotation_cb_func.c
deleted file mode 100644 (file)
index 493315c..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  app-core
- *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@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 <tet_api.h>
-#include <appcore-common.h>
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-static void utc_ApplicationFW_appcore_unset_rotation_cb_func_01(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_ApplicationFW_appcore_unset_rotation_cb_func_01, POSITIVE_TC_IDX },
-       { NULL, 0},
-};
-
-static void startup(void)
-{
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of appcore_unset_rotation_cb()
- */
-static void utc_ApplicationFW_appcore_unset_rotation_cb_func_01(void)
-{
-       int r = 0;
-
-       r = appcore_unset_rotation_cb();
-       if (r) {
-               tet_infoline("appcore_unset_rotation_cb() failed in positive test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-       tet_result(TET_PASS);
-}
-
diff --git a/TC/unit/utc_MODULE_API_func.c.in b/TC/unit/utc_MODULE_API_func.c.in
deleted file mode 100644 (file)
index bf9f90c..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-#include <tet_api.h>
-
-static void startup(void);
-static void cleanup(void);
-
-void (*tet_startup)(void) = startup;
-void (*tet_cleanup)(void) = cleanup;
-
-static void utc_@MODULE@_@API@_func_01(void);
-static void utc_@MODULE@_@API@_func_02(void);
-
-enum {
-       POSITIVE_TC_IDX = 0x01,
-       NEGATIVE_TC_IDX,
-};
-
-struct tet_testlist tet_testlist[] = {
-       { utc_@MODULE@_@API@_func_01, POSITIVE_TC_IDX },
-       { utc_@MODULE@_@API@_func_02, NEGATIVE_TC_IDX },
-};
-
-static void startup(void)
-{
-       int r;
-/*
-       char *err;
-       r = initailze...;
-       if (r) {
-               err = "Error message.......";
-               tet_infoline(err);
-               tet_delete(POSITIVE_TC_IDX, err);
-               tet_delete(NEGATIVE_TC_IDX, err);
-       }
-*/
-
-}
-
-static void cleanup(void)
-{
-}
-
-/**
- * @brief Positive test case of @API@()
- */
-static void utc_@MODULE@_@API@_func_01(void)
-{
-       int r = 0;
-
-/*
-       r = @API@(...);
-*/
-       if (r) {
-               tet_infoline("@API@() failed in positive test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-       tet_result(TET_PASS);
-}
-
-/**
- * @brief Negative test case of ug_init @API@()
- */
-static void utc_@MODULE@_@API@_func_02(void)
-{
-       int r = 0;
-
-/*
-       r = @API@(...);
-*/
-       if (!r) {
-               tet_infoline("@API@() failed in negative test case");
-               tet_result(TET_FAIL);
-               return;
-       }
-       tet_result(TET_PASS);
-}
diff --git a/cmake/Modules/ApplyPkgConfig.cmake b/cmake/Modules/ApplyPkgConfig.cmake
new file mode 100644 (file)
index 0000000..97679d7
--- /dev/null
@@ -0,0 +1,35 @@
+# Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+#
+# This function applies external (out of source tree) dependencies
+# to given target. Arguments are:
+#   TARGET - valid cmake target
+#   PRIVACY - dependency can be inherited by dependent targets or not:
+#     PUBLIC - this should be used by default, cause compile/link flags passing
+#     PRIVATE - do not passes any settings to dependent targets,
+#               may be usefull for static libraries from the inside of the project
+# Argument ARGV2 and following are supposed to be names of checked pkg config
+# packages. This function will use variables created by check_pkg_modules().
+#  - ${DEP_NAME}_LIBRARIES
+#  - ${DEP_NAME}_INCLUDE_DIRS
+#  - ${DEP_NAME}_CFLAGS
+#
+FUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY)
+  MATH(EXPR DEST_INDEX "${ARGC}-1")
+  FOREACH(I RANGE 2 ${DEST_INDEX})
+    IF(NOT ${ARGV${I}}_FOUND)
+      MESSAGE(FATAL_ERROR "Not found dependency - ${ARGV${I}}_FOUND")
+    ENDIF(NOT ${ARGV${I}}_FOUND)
+    TARGET_LINK_LIBRARIES(${TARGET} ${PRIVACY} "${${ARGV${I}}_LIBRARIES}")
+    TARGET_INCLUDE_DIRECTORIES(${TARGET} ${PRIVACY} SYSTEM "${${ARGV${I}}_INCLUDE_DIRS}")
+    STRING(REPLACE ";" " " CFLAGS_STR "${${ARGV${I}}_CFLAGS}")
+    SET(CFLAGS_LIST ${CFLAGS_STR})
+    SEPARATE_ARGUMENTS(CFLAGS_LIST)
+    FOREACH(OPTION ${CFLAGS_LIST})
+      TARGET_COMPILE_OPTIONS(${TARGET} ${PRIVACY} ${OPTION})
+    ENDFOREACH(OPTION)
+    SET_TARGET_PROPERTIES(${TARGET} PROPERTIES SKIP_BUILD_RPATH true)
+  ENDFOREACH(I RANGE 2 ${DEST_INDEX})
+ENDFUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY)
diff --git a/legacy/CMakeLists.txt b/legacy/CMakeLists.txt
new file mode 100644 (file)
index 0000000..622e737
--- /dev/null
@@ -0,0 +1,156 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(appcore C)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR ${LIB_INSTALL_DIR})
+SET(INCLUDEDIR "\${prefix}/include")
+SET(VERSION ${FULLVER})
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/legacy/include)
+
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -Wall")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,--as-needed")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+SET(CMAKE_SKIP_BUILD_RPATH TRUE)
+
+#################################################################
+# Build appcore-common Library
+# ------------------------------
+SET(APPCORE_COMMON "appcore-common")
+SET(SRCS_common
+       src/legacy/appcore.c
+       src/legacy/appcore-measure.c
+       src/legacy/appcore-rotation.c
+       src/legacy/appcore-i18n.c
+       src/base/appcore_base.c
+       src/base/appcore_base_control.c
+       src/watchdog/appcore_watchdog.c)
+
+SET(HEADERS_common
+       appcore-common.h
+       appcore_base.h
+       appcore_watchdog.h
+       appcore_base_control.h)
+
+INCLUDE(FindPkgConfig)
+SET(APPCORE_PKG_CHECK_MODULES "gio-2.0 vconf sensor aul dlog capi-system-info ttrace pkgmgr-info")
+
+pkg_check_modules(pkg_common REQUIRED ${APPCORE_PKG_CHECK_MODULES})
+
+FOREACH(flag ${pkg_common_CFLAGS})
+       SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} ${flag}")
+ENDFOREACH(flag)
+
+ADD_LIBRARY(${APPCORE_COMMON} SHARED ${SRCS_common})
+SET_TARGET_PROPERTIES(${APPCORE_COMMON} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${APPCORE_COMMON} PROPERTIES VERSION ${FULLVER})
+SET_TARGET_PROPERTIES(${APPCORE_COMMON} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_common})
+TARGET_LINK_LIBRARIES(${APPCORE_COMMON} ${pkg_common_LDFLAGS} "-ldl")
+
+CONFIGURE_FILE(${APPCORE_COMMON}.pc.in ${APPCORE_COMMON}.pc @ONLY)
+
+INSTALL(TARGETS ${APPCORE_COMMON} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPCORE_COMMON}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+FOREACH(hfile ${HEADERS_common})
+       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${hfile} DESTINATION include/appcore)
+ENDFOREACH(hfile)
+
+#################################################################
+# Build appcore-ui Library
+# ------------------------------
+SET(APPCORE_UI "appcore-ui")
+SET(SRCS_ui src/ui_base/appcore_ui_base.c src/ui_base/appcore_ui_plugin.c)
+SET(HEADERS_ui appcore_ui_base.h)
+
+INCLUDE(FindPkgConfig)
+SET(APPCORE_UI_PKG_CHECK_MODULES "dlog ecore gobject-2.0 glib-2.0 aul bundle pkgmgr-info ttrace ecore-wl2 tizen-extension-client wayland-client")
+
+pkg_check_modules(pkg_ui REQUIRED ${APPCORE_UI_PKG_CHECK_MODULES})
+
+FOREACH(flag ${pkg_ui_CFLAGS})
+       SET(EXTRA_CFLAGS_ui "${EXTRA_CFLAGS_ui} ${flag}")
+ENDFOREACH(flag)
+
+ADD_LIBRARY(${APPCORE_UI} SHARED ${SRCS_ui})
+SET_TARGET_PROPERTIES(${APPCORE_UI} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${APPCORE_UI} PROPERTIES VERSION ${FULLVER})
+SET_TARGET_PROPERTIES(${APPCORE_UI} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_ui})
+TARGET_LINK_LIBRARIES(${APPCORE_UI} ${pkg_ui_LDFLAGS} ${APPCORE_COMMON})
+
+CONFIGURE_FILE(${APPCORE_UI}.pc.in ${APPCORE_UI}.pc @ONLY)
+
+INSTALL(TARGETS ${APPCORE_UI} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPCORE_UI}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+FOREACH(hfile ${HEADERS_ui})
+       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${hfile} DESTINATION include/appcore)
+ENDFOREACH(hfile)
+
+#################################################################
+# Build appcore-efl Library
+# ------------------------------
+SET(APPCORE_EFL "appcore-efl")
+SET(SRCS_efl src/legacy/appcore-efl.c src/efl_base/appcore_efl_base.c)
+SET(HEADERS_efl appcore-efl.h appcore_efl_base.h)
+
+INCLUDE(FindPkgConfig)
+SET(APPCORE_PKG_CHECK_MODULES2 "elementary dlog aul bundle ttrace")
+
+pkg_check_modules(pkg_efl REQUIRED ${APPCORE_PKG_CHECK_MODULES2})
+
+FOREACH(flag ${pkg_efl_CFLAGS})
+       SET(EXTRA_CFLAGS_efl "${EXTRA_CFLAGS_efl} ${flag}")
+ENDFOREACH(flag)
+
+ADD_LIBRARY(${APPCORE_EFL} SHARED ${SRCS_efl})
+SET_TARGET_PROPERTIES(${APPCORE_EFL} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${APPCORE_EFL} PROPERTIES VERSION ${FULLVER})
+SET_TARGET_PROPERTIES(${APPCORE_EFL} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_efl})
+TARGET_LINK_LIBRARIES(${APPCORE_EFL} ${pkg_efl_LDFLAGS} ${APPCORE_UI})
+
+CONFIGURE_FILE(${APPCORE_EFL}.pc.in ${APPCORE_EFL}.pc @ONLY)
+
+INSTALL(TARGETS ${APPCORE_EFL} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPCORE_EFL}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+FOREACH(hfile ${HEADERS_efl})
+       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${hfile} DESTINATION include/appcore)
+ENDFOREACH(hfile)
+
+#################################################################
+# Build appcore-multiwindow Library
+# ------------------------------
+SET(APPCORE_MULTIWINDOW "appcore-multiwindow")
+SET(SRCS_mw src/multiwindow_base/appcore_multiwindow_base.c
+       src/multiwindow_base/appcore_multiwindow_base_class.c
+       src/multiwindow_base/appcore_multiwindow_base_instance.c
+       src/multiwindow_base/appcore_multiwindow_base_window.c
+       )
+SET(HEADERS_mw appcore_multiwindow_base.h)
+
+INCLUDE(FindPkgConfig)
+SET(APPCORE_MULTIWINDOW_PKG_CHECK_MODULES "dlog ecore gobject-2.0 glib-2.0 aul ecore-wl2")
+
+pkg_check_modules(pkg_mw REQUIRED ${APPCORE_MULTIWINDOW_PKG_CHECK_MODULES})
+
+FOREACH(flag ${pkg_mw_CFLAGS})
+       SET(EXTRA_CFLAGS_mw "${EXTRA_CFLAGS_mw} ${flag}")
+ENDFOREACH(flag)
+
+ADD_LIBRARY(${APPCORE_MULTIWINDOW} SHARED ${SRCS_mw})
+SET_TARGET_PROPERTIES(${APPCORE_MULTIWINDOW} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${APPCORE_MULTIWINDOW} PROPERTIES VERSION ${FULLVER})
+SET_TARGET_PROPERTIES(${APPCORE_MULTIWINDOW} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_mw})
+TARGET_LINK_LIBRARIES(${APPCORE_MULTIWINDOW} ${pkg_mw_LDFLAGS} ${APPCORE_COMMON})
+
+CONFIGURE_FILE(${APPCORE_MULTIWINDOW}.pc.in ${APPCORE_MULTIWINDOW}.pc @ONLY)
+
+INSTALL(TARGETS ${APPCORE_MULTIWINDOW} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPCORE_MULTIWINDOW}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+FOREACH(hfile ${HEADERS_mw})
+       INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${hfile} DESTINATION include/appcore)
+ENDFOREACH(hfile)
similarity index 100%
rename from appcore-efl.pc.in
rename to legacy/appcore-efl.pc.in
similarity index 100%
rename from appcore-ui.pc.in
rename to legacy/appcore-ui.pc.in
index 51bcaf3..bb6230a 100644 (file)
@@ -22,9 +22,15 @@ BuildRequires:  pkgconfig(gobject-2.0)
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(pkgmgr-info)
 BuildRequires:  pkgconfig(ttrace)
+BuildRequires:  pkgconfig(gmock)
 BuildRequires:  cmake
 BuildRequires:  pkgconfig(capi-system-info)
 
+%if 0%{?gcov:1}
+BuildRequires:  lcov
+BuildRequires:  zip
+%endif
+
 %description
 SLP common application basic
 
@@ -114,11 +120,27 @@ Group:      Development/Libraries
 %description template
 Application basics template
 
+
+%if 0%{?gcov:1}
+%package gcov
+Summary:  Application Core API(gcov)
+Group:    Application Framework/Libraries
+
+%description gcov
+gcov objects of a widget application library
+%endif
+
 %prep
 %setup -q
 cp %{SOURCE1001} .
 
 %build
+%if 0%{?gcov:1}
+export CFLAGS+=" -fprofile-arcs -ftest-coverage"
+export CXXFLAGS+=" -fprofile-arcs -ftest-coverage"
+export FFLAGS+=" -fprofile-arcs -ftest-coverage"
+export LDFLAGS+=" -lgcov"
+%endif
 export CFLAGS+=" -DEFL_BETA_API_SUPPORT "
 MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
 %cmake . \
@@ -128,11 +150,29 @@ MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
 
 make %{?_smp_mflags}
 
+%if 0%{?gcov:1}
+mkdir -p gcov-obj
+find . -name '*.gcno' -exec cp '{}' gcov-obj ';'
+%endif
 
 %install
 rm -rf %{buildroot}
 %make_install
 
+%if 0%{?gcov:1}
+mkdir -p %{buildroot}%{_datadir}/gcov/obj
+install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj
+%endif
+
+%check
+ctest -V
+%if 0%{?gcov:1}
+lcov -c --ignore-errors graph --no-external -q -d . -o app-core.info
+genhtml app-core.info -o app-core.out
+zip -r app-core.zip app-core.out
+install -m 0644 app-core.zip %{buildroot}%{_datadir}/gcov/
+%endif
+
 
 %post -n app-core-efl -p /sbin/ldconfig
 
@@ -150,10 +190,13 @@ rm -rf %{buildroot}
 
 %postun -n app-core-ui -p /sbin/ldconfig
 
-
 %files efl
 %manifest %{name}.manifest
 %{_libdir}/libappcore-efl.so.*
+
+%{_includedir}/appcore_cpp/app_core_efl_base.hh
+%{_libdir}/libapp-core-efl-cpp.so*
+%{_libdir}/pkgconfig/app-core-efl-cpp.pc
 %license LICENSE
 
 %files efl-devel
@@ -166,6 +209,10 @@ rm -rf %{buildroot}
 %files multiwindow
 %manifest %{name}.manifest
 %{_libdir}/libappcore-multiwindow.so.*
+
+%{_includedir}/appcore_cpp/app_core_multi_window_base.hh
+%{_libdir}/libapp-core-multi-window-cpp.so*
+%{_libdir}/pkgconfig/app-core-multi-window-cpp.pc
 %license LICENSE
 
 %files multiwindow-devel
@@ -177,6 +224,14 @@ rm -rf %{buildroot}
 %files common
 %manifest %{name}.manifest
 %{_libdir}/libappcore-common.so.*
+
+%{_includedir}/appcore_cpp/app_core_base.hh
+%{_includedir}/appcore_cpp/interface_app_core.hh
+%{_includedir}/appcore_cpp/interface_app_core_ui.hh
+%{_includedir}/appcore_cpp/interface_main_loop.hh
+%{_includedir}/appcore_cpp/interface_window.hh
+%{_libdir}/libapp-core-cpp.so*
+%{_libdir}/pkgconfig/app-core-cpp.pc
 %license LICENSE
 
 %files common-devel
@@ -191,6 +246,11 @@ rm -rf %{buildroot}
 %files ui
 %manifest %{name}.manifest
 %{_libdir}/libappcore-ui.so.*
+
+%{_includedir}/appcore_cpp/app_core_ui_base.hh
+%{_includedir}/appcore/appcore_ui_base.h
+%{_libdir}/libapp-core-ui-cpp.so*
+%{_libdir}/pkgconfig/app-core-ui-cpp.pc
 %license LICENSE
 
 %files ui-devel
@@ -198,3 +258,8 @@ rm -rf %{buildroot}
 %{_includedir}/appcore/appcore_ui_base.h
 %{_libdir}/libappcore-ui.so
 %{_libdir}/pkgconfig/appcore-ui.pc
+
+%if 0%{?gcov:1}
+%files gcov
+%{_datadir}/gcov/*
+%endif
diff --git a/tizen-cpp/CMakeLists.txt b/tizen-cpp/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0814703
--- /dev/null
@@ -0,0 +1,4 @@
+ADD_SUBDIRECTORY(app-core-efl-cpp)
+ADD_SUBDIRECTORY(app-core-multi-window-cpp)
+ADD_SUBDIRECTORY(app-core-cpp)
+ADD_SUBDIRECTORY(app-core-ui-cpp)
diff --git a/tizen-cpp/app-core-cpp/CMakeLists.txt b/tizen-cpp/app-core-cpp/CMakeLists.txt
new file mode 100644 (file)
index 0000000..20fc2e6
--- /dev/null
@@ -0,0 +1,32 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_CORE_CPP_SRCS)
+
+ADD_LIBRARY(${TARGET_APP_CORE_CPP} SHARED ${APP_CORE_CPP_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_APP_CORE_CPP} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/../)
+
+TARGET_LINK_LIBRARIES(${TARGET_APP_CORE_CPP} PUBLIC "-ldl -L/usr/lib/hal")
+SET_TARGET_PROPERTIES(${TARGET_APP_CORE_CPP} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_APP_CORE_CPP} PROPERTIES VERSION ${FULLVER})
+
+APPLY_PKG_CONFIG(${TARGET_APP_CORE_CPP} PUBLIC
+  AUL_DEPS
+  BUNDLE_DEPS
+  CAPI_SYSTEM_INFO_DEPS
+  DLOG_DEPS
+  GIO_2_DEPS
+  PKGMGR_INFO_DEPS
+  SENSOR_DEPS
+  TTRACE_DEPS
+  VCONF_DEPS
+)
+
+CONFIGURE_FILE(${TARGET_APP_CORE_CPP}.pc.in ${TARGET_APP_CORE_CPP}.pc @ONLY)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_APP_CORE_CPP}.pc
+  DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+
+INSTALL(TARGETS ${TARGET_APP_CORE_CPP} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION include/appcore_cpp
+  FILES_MATCHING
+  PATTERN "*.hh")
diff --git a/tizen-cpp/app-core-cpp/app-core-cpp.pc.in b/tizen-cpp/app-core-cpp/app-core-cpp.pc.in
new file mode 100644 (file)
index 0000000..9aec6dd
--- /dev/null
@@ -0,0 +1,14 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDEDIR@
+
+Name: app-core-cpp
+Description: Tizen application core library
+Version: @VERSION@
+Requires.private: sensor vconf aul dlog
+Libs: -L${libdir} -lapp-core-cpp
+Cflags: -I${includedir} -I${includedir}/appcore_cpp
+cppflags: I${includedir} -I${includedir}/appcore_cpp
diff --git a/tizen-cpp/app-core-cpp/app_core_base.cc b/tizen-cpp/app-core-cpp/app_core_base.cc
new file mode 100644 (file)
index 0000000..5adf51c
--- /dev/null
@@ -0,0 +1,1255 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aul.h>
+#include <aul_app_lifecycle.h>
+#include <aul_watchdog.h>
+#include <bundle_internal.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <gio/gio.h>
+#include <glib.h>
+#include <libintl.h>
+#include <linux/limits.h>
+#include <locale.h>
+#include <malloc.h>
+#include <sensor_internal.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <system_info.h>
+#include <ttrace.h>
+#include <unistd.h>
+#include <vconf.h>
+
+#include <cstring>
+#include <list>
+#include <map>
+#include <set>
+#include <sstream>
+
+#include "app-core-cpp/app_core_base.hh"
+#include "common/log_private.hh"
+
+extern "C" void aul_finalize();
+
+namespace tizen_cpp {
+namespace {
+
+enum TizenProfile {
+  Unknown = 0x00,
+  Mobile = 0x01,
+  Wearable = 0x02,
+  Tv = 0x04,
+  Ivi = 0x08,
+  Common = 0x10,
+};
+
+TizenProfile TizenProfileGet() {
+  static TizenProfile profile = TizenProfile::Unknown;
+  if (__builtin_expect(profile != TizenProfile::Unknown, 1))
+    return profile;
+
+  char* profile_name = nullptr;
+  system_info_get_platform_string("http://tizen.org/feature/profile",
+      &profile_name);
+  if (profile_name == nullptr)
+    return profile;
+
+  switch (*profile_name) {
+  case 'm':
+  case 'M':
+    profile = TizenProfile::Mobile;
+    break;
+  case 'w':
+  case 'W':
+    profile = TizenProfile::Wearable;
+    break;
+  case 't':
+  case 'T':
+    profile = TizenProfile::Tv;
+    break;
+  case 'i':
+  case 'I':
+    profile = TizenProfile::Ivi;
+    break;
+  default:
+    profile = TizenProfile::Common;
+    break;
+  }
+  free(profile_name);
+
+  return profile;
+}
+
+constexpr const char PATH_LOCALE[] = "locale";
+constexpr int SQLITE_FLUSH_MAX = 1024 * 1024;
+constexpr const char RESOURCED_FREEZER_PATH[] =
+    "/Org/Tizen/ResourceD/Freezer";
+constexpr const char RESOURCED_FREEZER_INTERFACE[] =
+    "org.tizen.resourced.freezer";
+constexpr const char RESOURCED_FREEZER_SIGNAL[] =
+    "FreezerState";
+
+struct Rotation {
+  int conn;
+  int lock;
+  int ref;
+  tizen_cpp::AppCoreBase::RotationState rm;
+  int charger_status;
+  bool initialized;
+};
+
+Rotation __rotation;
+GDBusConnection* __bus;
+guint __suspend_dbus_handler_initialized;
+AppCoreBase::DisplayState __display_state = AppCoreBase::DISPLAY_STATE_UNKNOWN;
+
+}  // namespace
+
+class AppCoreBase::EventBase::Impl {
+ private:
+  friend class AppCoreBase;
+  Type type_ = IEvent::Type::START;
+  std::string str_val_;
+  int val_ = -1;
+};
+
+class AppCoreBase::Impl {
+ public:
+  explicit Impl(AppCoreBase* parent) : parent_(parent) {
+    if (TizenProfileGet() & TizenProfile::Wearable)
+      feature_ |= FEATURE_CHARGER_STATUS;
+    if (!(TizenProfileGet() & TizenProfile::Tv))
+      feature_ |= FEATURE_BACKGROUND_MANAGEMENT;
+  }
+
+ private:
+  void UnregisterRotationChangedEvent();
+  void RegisterRotationChangedEvent();
+  std::string GetAppName(const char* appid);
+  std::string GetLocaleResourceDir();
+  void UpdateLang();
+  void UpdateRegion();
+  std::list<std::string> SplitLanguage(const std::string& lang);
+  std::string GetLanguage(std::string lang);
+  void AppendDefaultLangs(std::set<std::string>& lang_set);
+  std::string GetStringBefore(const char* str, const char* delim);
+  std::map<std::string, std::set<std::string>> GetLangTable();
+  void AppendLangs(const std::string& lang, std::set<std::string>& lang_set,
+      std::map<std::string, std::set<std::string>>& table);
+  void ChangeLang();
+  void OnFreezerSignal();
+
+  template <class T>
+  void InvokeCallback(T event, IEvent::Type type) {
+    for (auto& i : events_) {
+      if (i->GetType() != type)
+        continue;
+
+      if (i->GetVal(event) != event ||
+          type == IEvent::Type::START ||
+          type == IEvent::Type::UPDATE_REQUESTED) {
+        i->SetVal(event);
+        i->OnEvent(event);
+      }
+    }
+  }
+
+  static void InitSuspendDbusHandler(gpointer data);
+  static gboolean InitSuspendCb(gpointer data);
+  static gboolean InvokeLangChangeCb(gpointer data);
+  static void ReceiveSuspendSignalCb(GDBusConnection*, const gchar*,
+      const gchar*, const gchar*, const gchar*, GVariant*, gpointer);
+  static void OnLowBatteryCb(keynode_t* key, void* data);
+  static void LockCb(keynode_t* node, void* user_data);
+  static void AutoRotationChangedCb(sensor_t sensor, unsigned int event_type,
+      sensor_data_t* data, void* user_data);
+  static void ChargerStatusChangedCb(keynode_t* keynode, void* user_data);
+  static void LanguageChangeCb(keynode_t* key, void* data);
+  static void RegionChangeCb(keynode_t* key, void* data);
+  static void LowMemoryCb(keynode_t* key, void* data);
+  void InitRotation();
+  void FiniRotation();
+  RotationState GetRm(sensor_data_t data);
+  void VerifyLanguage();
+  void SetDefaultEvents();
+  void UnsetDefaultEvents();
+
+ private:
+  friend class AppCoreBase;
+  AppCoreBase* parent_ = nullptr;
+
+  int argc_ = 0;
+  char** argv_ = nullptr;
+  bool suspended_state_ = false;
+  bool allowed_bg_ = false;
+  bool dirty_ = false;
+  unsigned int tid_ = 0;
+  std::list<std::shared_ptr<EventBase>> events_;
+  std::string locale_dir_;
+  guint sid_ = 0;
+  int feature_ = 0;
+  IAppCore* core_delegator_ = nullptr;
+  IMainLoop* loop_delegator_ = nullptr;
+};
+
+AppCoreBase::EventBase::EventBase(Type type)
+    : impl_(std::make_unique<EventBase::Impl>()) {
+  impl_->type_ = type;
+}
+
+AppCoreBase::EventBase::~EventBase() = default;
+
+IAppCore::IEvent::Type AppCoreBase::EventBase::GetType() const {
+  return impl_->type_;
+}
+
+std::string AppCoreBase::EventBase::GetVal(std::string cur) const {
+  return impl_->str_val_;
+}
+
+int AppCoreBase::EventBase::GetVal(int cur) const {
+  return impl_->val_;
+}
+
+void AppCoreBase::EventBase::SetVal(std::string val) {
+  impl_->str_val_ = std::move(val);
+}
+
+void AppCoreBase::EventBase::SetVal(int val) {
+  impl_->val_ = std::move(val);
+}
+
+AppCoreBase::AppCoreBase() : impl_(std::make_unique<AppCoreBase::Impl>(this)) {}
+AppCoreBase::~AppCoreBase() = default;
+
+void AppCoreBase::Impl::ChangeLang() {
+  const char* lang = getenv("LANG");
+  if (lang == nullptr)
+    return;
+
+  InvokeCallback(lang, IEvent::Type::LANG_CHANGE);
+}
+
+void AppCoreBase::RaiseEvent(int event, IEvent::Type type) {
+  impl_->InvokeCallback(event, type);
+}
+
+void AppCoreBase::RaiseEvent(const std::string& event, IEvent::Type type) {
+  impl_->InvokeCallback(event, type);
+}
+
+void AppCoreBase::Impl::OnFreezerSignal() {
+  if (!allowed_bg_ && suspended_state_) {
+    parent_->RemoveSuspendTimer();
+    InvokeCallback(SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND,
+        IEvent::Type::SUSPENDED_STATE_CHANGE);
+    suspended_state_ = false;
+    parent_->AddSuspendTimer();
+  }
+}
+
+AppCoreBase::RotationState AppCoreBase::Impl::GetRm(sensor_data_t data) {
+  if (data.value_count <= 0) {
+    _E("Failed to get sensor data");
+    return ROTATION_UNKNOWN;
+  }
+
+  int event = data.values[0];
+  switch (event) {
+  case AUTO_ROTATION_DEGREE_0:
+    return ROTATION_PORTRAIT_NORMAL;
+  case AUTO_ROTATION_DEGREE_90:
+    return ROTATION_LANDSCAPE_NORMAL;
+  case AUTO_ROTATION_DEGREE_180:
+    return ROTATION_PORTRAIT_REVERSE;
+  case AUTO_ROTATION_DEGREE_270:
+    return ROTATION_LANDSCAPE_REVERSE;
+  default:
+    return ROTATION_UNKNOWN;
+  }
+}
+
+void AppCoreBase::Impl::InitSuspendDbusHandler(gpointer data) {
+  if (__suspend_dbus_handler_initialized)
+    return;
+
+  if (__bus == nullptr) {
+    GError* err = nullptr;
+    __bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &err);
+    if (__bus == nullptr) {
+      _E("Failed to connect to the D-BUS daemon: %s", err->message);
+      g_error_free(err);
+      return;
+    }
+  }
+
+  __suspend_dbus_handler_initialized = g_dbus_connection_signal_subscribe(
+    __bus, nullptr, RESOURCED_FREEZER_INTERFACE, RESOURCED_FREEZER_SIGNAL,
+    RESOURCED_FREEZER_PATH, nullptr, G_DBUS_SIGNAL_FLAGS_NONE,
+    ReceiveSuspendSignalCb, data, nullptr);
+
+  if (__suspend_dbus_handler_initialized == 0) {
+    _E("g_dbus_connection_signal_subscribe() is failed.");
+    return;
+  }
+
+  _D("[__SUSPEND__] suspend signal initialized");
+}
+
+gboolean AppCoreBase::Impl::InitSuspendCb(gpointer data) {
+  InitSuspendDbusHandler(data);
+  return G_SOURCE_REMOVE;
+}
+
+gboolean AppCoreBase::Impl::InvokeLangChangeCb(gpointer data) {
+  AppCoreBase* base = reinterpret_cast<AppCoreBase*>(data);
+  base->impl_->sid_ = 0;
+  base->impl_->ChangeLang();
+  return G_SOURCE_REMOVE;
+}
+
+void AppCoreBase::Impl::ReceiveSuspendSignalCb(GDBusConnection*, const gchar*,
+    const gchar*, const gchar*, const gchar* signal_name, GVariant* parameters,
+    gpointer user_data) {
+  if (g_strcmp0(signal_name, RESOURCED_FREEZER_SIGNAL) == 0) {
+    gint pid = -1;
+    gint status = 0;
+    g_variant_get(parameters, "(ii)", &status, &pid);
+    if (pid == getpid() && status == 0) {
+      AppCoreBase* base = reinterpret_cast<AppCoreBase*>(user_data);
+      base->impl_->OnFreezerSignal();
+    }
+  }
+}
+
+void AppCoreBase::Impl::LanguageChangeCb(keynode_t* key, void* user_data) {
+  AppCoreBase* base = reinterpret_cast<AppCoreBase*>(user_data);
+  if (base->impl_->sid_) {
+    g_source_remove(base->impl_->sid_);
+    base->impl_->sid_ = 0;
+  }
+
+  char* val = vconf_keynode_get_str(key);
+  if (val == nullptr)
+    return;
+
+  base->impl_->UpdateLang();
+  base->impl_->InvokeCallback(val, IEvent::Type::LANG_CHANGE);
+}
+
+void AppCoreBase::Impl::RegionChangeCb(keynode_t* key, void* user_data) {
+  const char* name = vconf_keynode_get_name(key);
+  if (name == nullptr)
+    return;
+
+  if (strcmp(name, VCONFKEY_REGIONFORMAT) &&
+      strcmp(name, VCONFKEY_REGIONFORMAT_TIME1224))
+    return;
+
+  char* val = vconf_get_str(VCONFKEY_REGIONFORMAT);
+  if (val == nullptr)
+    return;
+  std::unique_ptr<char, decltype(std::free)*> region_auto(val, std::free);
+
+  AppCoreBase* base = reinterpret_cast<AppCoreBase*>(user_data);
+  base->impl_->UpdateRegion();
+  base->impl_->InvokeCallback(val, IEvent::Type::REGION_CHANGE);
+}
+
+void AppCoreBase::Impl::LowMemoryCb(keynode_t* key, void* user_data) {
+  int val = vconf_keynode_get_int(key);
+  if (val >= VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) {
+    AppCoreBase* base = reinterpret_cast<AppCoreBase*>(user_data);
+    base->impl_->InvokeCallback(val, IEvent::Type::LOW_MEMORY);
+    malloc_trim(0);
+  }
+}
+
+void AppCoreBase::Impl::ChargerStatusChangedCb(keynode_t* keynode,
+    void* user_data) {
+  AppCoreBase* base = reinterpret_cast<AppCoreBase*>(user_data);
+  if (base->impl_->feature_ & FEATURE_CHARGER_STATUS) {
+    __rotation.charger_status = vconf_keynode_get_int(keynode);
+    if (__rotation.ref) {
+      if (__rotation.charger_status) {
+        base->impl_->InitRotation();
+      } else {
+        base->impl_->FiniRotation();
+      }
+    }
+
+    _D("charger status(%d)", __rotation.charger_status);
+  }
+}
+
+void AppCoreBase::Impl::LockCb(keynode_t* node, void* user_data) {
+  AppCoreBase::RotationState rm;
+  AppCoreBase* base = reinterpret_cast<AppCoreBase*>(user_data);
+
+  __rotation.lock = !vconf_keynode_get_bool(node);
+  if (__rotation.lock) {
+    _D("Rotation locked");
+    rm = ROTATION_PORTRAIT_NORMAL;
+  } else {
+    _D("Rotation unlocked");
+    sensor_data_t data;
+    bool r = sensord_get_data(__rotation.conn, AUTO_ROTATION_SENSOR, &data);
+    if (!r) {
+      _E("Failed to get sensor data");
+      return;
+    }
+
+    rm = base->impl_->GetRm(data);
+    if (rm == ROTATION_UNKNOWN) {
+      _E("Unknown mode");
+      return;
+    }
+  }
+
+  if (__rotation.rm == rm)
+    return;
+
+  _D("Rotation: %d -> %d", __rotation.rm, rm);
+  __rotation.rm = rm;
+  base->impl_->InvokeCallback(__rotation.rm,
+      IEvent::Type::DEVICE_ORIENTATION_CHANGED);
+}
+
+void AppCoreBase::Impl::AutoRotationChangedCb(sensor_t sensor,
+    unsigned int event_type, sensor_data_t* data, void* user_data) {
+  if (data == nullptr)
+    return;
+
+  if (__rotation.lock)
+    return;
+
+  if (event_type != AUTO_ROTATION_CHANGE_STATE_EVENT)
+    return;
+
+  AppCoreBase* base = reinterpret_cast<AppCoreBase*>(user_data);
+  AppCoreBase::RotationState rm = base->impl_->GetRm(*data);
+  if (rm == ROTATION_UNKNOWN) {
+    _E("Unknown mode");
+    return;
+  }
+
+  _D("Rotation: %d -> %d", __rotation.rm, rm);
+  __rotation.rm = rm;
+  base->impl_->InvokeCallback(__rotation.rm,
+      IEvent::Type::DEVICE_ORIENTATION_CHANGED);
+}
+
+void AppCoreBase::Impl::InitRotation() {
+  if (__rotation.initialized)
+    return;
+
+  sensor_t sensor = sensord_get_sensor(AUTO_ROTATION_SENSOR);
+  __rotation.conn = sensord_connect(sensor);
+  if (__rotation.conn < 0) {
+    _E("Failed to connect sensord");
+    return;
+  }
+
+  bool r = sensord_register_event(__rotation.conn,
+      AUTO_ROTATION_CHANGE_STATE_EVENT, SENSOR_INTERVAL_NORMAL, 0,
+      AutoRotationChangedCb, parent_);
+  if (!r) {
+    _E("Failed to register auto rotation change event");
+    sensord_disconnect(__rotation.conn);
+    return;
+  }
+
+  r = sensord_start(__rotation.conn, 0);
+  if (!r) {
+    _E("Failed to start sensord");
+    sensord_unregister_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT);
+    sensord_disconnect(__rotation.conn);
+    return;
+  }
+
+  int lock = 0;
+  vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &lock);
+  vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, LockCb,
+      parent_);
+
+  __rotation.lock = !lock;
+  __rotation.initialized = true;
+}
+
+void AppCoreBase::Impl::FiniRotation() {
+  if (!__rotation.initialized)
+    return;
+
+  vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, LockCb);
+  sensord_unregister_event(__rotation.conn, AUTO_ROTATION_CHANGE_STATE_EVENT);
+  sensord_stop(__rotation.conn);
+  sensord_disconnect(__rotation.conn);
+
+  __rotation.lock = 0;
+  __rotation.initialized = false;
+}
+
+void AppCoreBase::Impl::VerifyLanguage() {
+  const char* env_lang = getenv("LANG");
+  if (env_lang == nullptr)
+    return;
+
+  char* lang = vconf_get_str(VCONFKEY_LANGSET);
+  if (lang == nullptr)
+    return;
+
+  std::unique_ptr<char, decltype(std::free)*> lang_auto(lang, std::free);
+
+  if (strcmp(env_lang, lang) != 0) {
+    _I("LANG(%s), LANGSET(%s)", env_lang, lang);
+    sid_ = g_idle_add(InvokeLangChangeCb, parent_);
+  }
+}
+
+void AppCoreBase::Impl::SetDefaultEvents() {
+  vconf_notify_key_changed(VCONFKEY_LANGSET, LanguageChangeCb, parent_);
+  int r = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, RegionChangeCb,
+      parent_);
+  if (r == 0) {
+    vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, RegionChangeCb,
+        parent_);
+  }
+
+  vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, LowMemoryCb, parent_);
+}
+
+void AppCoreBase::Impl::UnsetDefaultEvents() {
+  vconf_ignore_key_changed(VCONFKEY_LANGSET, LanguageChangeCb);
+  int r = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, RegionChangeCb);
+  if (r == 0)
+    vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224, RegionChangeCb);
+
+  vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, LowMemoryCb);
+}
+
+int AppCoreBase::OnReceive(aul_type type, tizen_base::Bundle b) {
+  switch (type) {
+  case AUL_START:
+    _D("[APP %d]     AUL event: AUL_START", getpid());
+    if (impl_->feature_ & FEATURE_BACKGROUND_MANAGEMENT) {
+      std::string bg = b.GetString(AUL_K_ALLOWED_BG);
+      if (bg == "ALLOWED_BG") {
+        _D("[__SUSPEND__] allowed background");
+        impl_->allowed_bg_ = true;
+        RemoveSuspendTimer();
+      }
+    }
+
+    traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:RESET");
+    if (impl_->core_delegator_)
+      impl_->core_delegator_->OnControl(std::move(b));
+    else
+      OnControl(std::move(b));
+    traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+    break;
+  case AUL_RESUME:
+    _D("[APP %d]     AUL event: AUL_RESUME", getpid());
+    if (impl_->feature_ & FEATURE_BACKGROUND_MANAGEMENT) {
+      std::string bg = b.GetString(AUL_K_ALLOWED_BG);
+      if (bg == "ALLOWED_BG") {
+        _D("[__SUSPEND__] allowed background");
+        impl_->allowed_bg_ = true;
+        RemoveSuspendTimer();
+      }
+    }
+    break;
+  case AUL_TERMINATE:
+    _D("[APP %d]     AUL event: AUL_TERMINATE", getpid());
+    aul_status_update(STATUS_DYING);
+    if (!impl_->allowed_bg_)
+      RemoveSuspendTimer();
+
+    if (impl_->loop_delegator_)
+      impl_->loop_delegator_->OnLoopExit();
+    else
+      OnLoopExit();
+    break;
+  case AUL_TERMINATE_INST:
+  case AUL_TERMINATE_BG_INST:
+  case AUL_TERMINATE_BGAPP:
+    _D("[APP %d]     AUL event: %d", getpid(), type);
+    if (!impl_->allowed_bg_)
+      RemoveSuspendTimer();
+    break;
+  case AUL_WAKE:
+    _D("[APP %d]     AUL event: AUL_WAKE", getpid());
+    if (impl_->feature_ & FEATURE_BACKGROUND_MANAGEMENT) {
+      if (!impl_->allowed_bg_ && impl_->suspended_state_) {
+        RemoveSuspendTimer();
+        int suspend = SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
+        impl_->InvokeCallback(suspend, IEvent::Type::SUSPENDED_STATE_CHANGE);
+        impl_->suspended_state_ = false;
+      }
+    }
+    break;
+  case AUL_SUSPEND:
+    _D("[APP %d]     AUL event: AUL_SUSPEND", getpid());
+    if (impl_->feature_ & FEATURE_BACKGROUND_MANAGEMENT) {
+      if (!impl_->allowed_bg_ && !impl_->suspended_state_) {
+        RemoveSuspendTimer();
+        FlushMemory();
+      }
+    }
+    break;
+  case AUL_UPDATE_REQUESTED:
+    _D("[APP %d]     AUL event: AUL_UPDATE_REQUESTED", getpid());
+    impl_->InvokeCallback(0, IEvent::Type::UPDATE_REQUESTED);
+    break;
+  default:
+    _D("[APP %d]     AUL event: %d", getpid(), type);
+    /* do nothing */
+    break;
+  }
+
+  return 0;
+}
+
+int AppCoreBase::OnCreate() {
+  int ret = aul_launch_init([](aul_type type, bundle* b, void* data) -> int {
+        AppCoreBase* base = reinterpret_cast<AppCoreBase*>(data);
+        if (base->impl_->core_delegator_) {
+          return base->impl_->core_delegator_->OnReceive(type,
+              b ? tizen_base::Bundle(b, false, false) : tizen_base::Bundle());
+        }
+        return base->OnReceive(type,
+            b ? tizen_base::Bundle(b, false, false) : tizen_base::Bundle());
+      }, this);
+  if (ret < 0 && ret != AUL_R_ECANCELED) {
+    _E("aul_launch_init() is failed. error(%d)", ret);
+    return -1;
+  }
+
+  ret = aul_launch_argv_handler(impl_->argc_, impl_->argv_);
+  if (ret < 0) {
+    _E("aul_launch_argv_handler() is failed. error(%d)", ret);
+    return -1;
+  }
+
+  return 0;
+}
+
+int AppCoreBase::OnControl(tizen_base::Bundle b) {
+  return 0;
+}
+
+int AppCoreBase::OnTerminate() {
+  aul_finalize();
+  return 0;
+}
+
+void AppCoreBase::SetCoreDelegator(IAppCore* delegator) {
+  impl_->core_delegator_ = delegator;
+}
+
+void AppCoreBase::SetLoopDelegator(IMainLoop* delegator) {
+  impl_->loop_delegator_ = delegator;
+}
+
+std::string AppCoreBase::Impl::GetAppName(const char* appid) {
+  if (appid == nullptr)
+    return "";
+
+  /* com.vendor.name -> name */
+  const char* name_token = strrchr(appid, '.');
+  if (name_token == nullptr)
+    return appid;
+
+  name_token++;
+  return name_token;
+}
+
+std::string AppCoreBase::Impl::GetLocaleResourceDir() {
+  const char* res_path = aul_get_app_resource_path();
+  if (res_path == nullptr) {
+    _E("Failed to get resource path");
+    return "";
+  }
+
+  std::string path = std::string(res_path) + PATH_LOCALE;
+  if (access(path.c_str(), R_OK) != 0)
+    _W("%s does not exist", path.c_str());
+
+  return path;
+}
+
+int AppCoreBase::OnSetI18n() {
+  char appid[PATH_MAX];
+  int ret = aul_app_get_appid_bypid(getpid(), appid, PATH_MAX);
+  if (ret < 0) {
+    _E("aul_app_get_appid_bypid() is failed. error(%d)", ret);
+    return -1;
+  }
+
+  std::string name = impl_->GetAppName(appid);
+  if (name.empty())
+    return -1;
+
+  std::string locale_dir = impl_->GetLocaleResourceDir();
+  if (locale_dir.empty())
+    return -1;
+
+  return SetI18n(move(name), move(locale_dir));
+}
+
+void AppCoreBase::Impl::OnLowBatteryCb(keynode_t* key, void* data) {
+  int val = vconf_keynode_get_int(key);
+  if (val <= VCONFKEY_SYSMAN_BAT_CRITICAL_LOW) {
+    AppCoreBase* base = reinterpret_cast<AppCoreBase*>(data);
+    base->impl_->InvokeCallback(val, IEvent::Type::LOW_BATTERY);
+  }
+}
+
+void AppCoreBase::Impl::UnregisterRotationChangedEvent() {
+  if (!__rotation.ref)
+    return;
+
+  __rotation.ref--;
+  if (__rotation.ref == 0) {
+    FiniRotation();
+    if (feature_ & FEATURE_CHARGER_STATUS) {
+      vconf_ignore_key_changed(VCONFKEY_SYSMAN_CHARGER_STATUS,
+          ChargerStatusChangedCb);
+    }
+  }
+}
+
+void AppCoreBase::Impl::RegisterRotationChangedEvent() {
+  if (__rotation.ref == 0) {
+    if (feature_ & FEATURE_CHARGER_STATUS) {
+      vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &__rotation.charger_status);
+      vconf_notify_key_changed(VCONFKEY_SYSMAN_CHARGER_STATUS,
+          ChargerStatusChangedCb, parent_);
+      if (__rotation.charger_status)
+        InitRotation();
+    } else {
+      InitRotation();
+    }
+  }
+
+  __rotation.ref++;
+}
+
+int AppCoreBase::OnSetEvent(IEvent::Type event) {
+  switch (event) {
+  case IEvent::Type::LOW_BATTERY:
+    vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
+        impl_->OnLowBatteryCb, this);
+    break;
+  case IEvent::Type::DEVICE_ORIENTATION_CHANGED:
+    impl_->RegisterRotationChangedEvent();
+    break;
+  case IEvent::Type::SUSPENDED_STATE_CHANGE:
+    break;
+  default:
+    break;
+  }
+
+  return 0;
+}
+
+int AppCoreBase::OnUnsetEvent(IEvent::Type event) {
+  switch (event) {
+  case IEvent::Type::LOW_BATTERY:
+    vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
+        impl_->OnLowBatteryCb);
+    break;
+  case IEvent::Type::DEVICE_ORIENTATION_CHANGED:
+    impl_->UnregisterRotationChangedEvent();
+    break;
+  case IEvent::Type::SUSPENDED_STATE_CHANGE:
+    break;
+  default:
+    break;
+  }
+
+  return 0;
+}
+
+int AppCoreBase::OnTrimMemory() {
+  int (*sqlite3_free_heap_memory)(int);
+
+  sqlite3_free_heap_memory = reinterpret_cast<
+      decltype(sqlite3_free_heap_memory)>(
+          dlsym(RTLD_DEFAULT, "sqlite3_release_memory"));
+  if (sqlite3_free_heap_memory)
+    sqlite3_free_heap_memory(SQLITE_FLUSH_MAX);
+
+  malloc_trim(0);
+  return 0;
+}
+
+void AppCoreBase::AddEvent(std::shared_ptr<EventBase> event) {
+  bool found = false;
+  for (auto& ev : impl_->events_) {
+    if (ev->GetType() == event->GetType()) {
+      found = true;
+      break;
+    }
+  }
+
+  if (!found) {
+    if (impl_->core_delegator_)
+      impl_->core_delegator_->OnSetEvent(event->GetType());
+    else
+      OnSetEvent(event->GetType());
+  }
+
+  impl_->events_.push_back(move(event));
+}
+
+bool AppCoreBase::RemoveEvent(std::shared_ptr<EventBase> event) {
+  bool found = false;
+  impl_->events_.remove_if([&](const std::shared_ptr<EventBase>& ptr)->bool {
+    if (event.get() == ptr.get()) {
+      found = true;
+      return true;
+    }
+    return false;
+  });
+
+  return found;
+}
+
+void AppCoreBase::FlushMemory() {
+  if (impl_->core_delegator_)
+    impl_->core_delegator_->OnTrimMemory();
+  else
+    OnTrimMemory();
+
+  impl_->tid_ = 0;
+  if (!impl_->allowed_bg_ && !impl_->suspended_state_) {
+    _D("[__SUSPEND__] flush case");
+    int suspend = SUSPENDED_STATE_WILL_ENTER_SUSPEND;
+    impl_->InvokeCallback(suspend, IEvent::Type::SUSPENDED_STATE_CHANGE);
+    impl_->suspended_state_ = true;
+  }
+}
+
+AppCoreBase::RotationState AppCoreBase::GetRotationState() {
+  if (!__rotation.ref)
+    throw std::runtime_error("invalid rotation state");
+
+  return __rotation.rm;
+}
+
+bool AppCoreBase::IsBgAllowed() {
+  return impl_->allowed_bg_;
+}
+
+bool AppCoreBase::IsSuspended() {
+  return impl_->suspended_state_;
+}
+
+void AppCoreBase::ToggleSuspendedState() {
+  impl_->suspended_state_ = !impl_->suspended_state_;
+}
+
+std::list<std::string> AppCoreBase::Impl::SplitLanguage(
+    const std::string& lang) {
+  std::istringstream ss(lang);
+  std::list<std::string> li;
+  std::string token;
+
+  while (std::getline(ss, token, ':'))
+    li.push_back(token);
+
+  return li;
+}
+
+void AppCoreBase::Impl::AppendDefaultLangs(std::set<std::string>& lang_set) {
+  lang_set.insert({"en_US", "en_GB", "en"});
+}
+
+std::string AppCoreBase::Impl::GetStringBefore(const char* cstr,
+    const char* delim) {
+  if (cstr == nullptr || delim == nullptr)
+    return "";
+
+  auto str = std::string(cstr);
+  auto idx = str.find(delim);
+  return str.substr(0, idx);
+}
+
+std::map<std::string, std::set<std::string>> AppCoreBase::Impl::GetLangTable() {
+  if (locale_dir_.empty())
+    return {};
+
+  DIR* dp = opendir(locale_dir_.c_str());
+  if (dp == nullptr)
+    return {};
+
+  std::map<std::string, std::set<std::string>> table;
+  struct dirent *dentry;
+  while ((dentry = readdir(dp)) != nullptr) {
+    if (!strcmp(dentry->d_name, ".") ||
+        !strcmp(dentry->d_name, ".."))
+      continue;
+
+    std::string buf = locale_dir_ + "/" + dentry->d_name;
+    struct stat stat_buf;
+    int ret = stat(buf.c_str(), &stat_buf);
+    if (ret != 0 || !S_ISDIR(stat_buf.st_mode))
+      continue;
+
+    std::string parent_lang = GetStringBefore(dentry->d_name, "_");
+    if (parent_lang.empty()) {
+      _E("Out of memory");
+      break;
+    }
+
+    table[parent_lang].insert(dentry->d_name);
+  }
+
+  closedir(dp);
+  return table;
+}
+
+void AppCoreBase::Impl::AppendLangs(const std::string& lang,
+    std::set<std::string>& lang_set,
+    std::map<std::string, std::set<std::string>>& table) {
+  if (lang.empty())
+    return;
+
+  lang_set.insert(lang);
+  std::string extract_lang = GetStringBefore(lang.c_str(), ".");
+  if (extract_lang.empty())
+    return;
+
+  if (lang_set.find(extract_lang) != lang_set.end())
+    return;
+
+  std::string parent_lang = GetStringBefore(extract_lang.c_str(), "_");
+  if (parent_lang.empty())
+    return;
+
+  if (table.find(parent_lang) == table.end())
+    return;
+
+  auto it = table[parent_lang].find(extract_lang);
+  if (it != table[parent_lang].end()) {
+    lang_set.insert(move(*it));
+    table[parent_lang].erase(it);
+    return;
+  }
+
+  it = table[parent_lang].find(parent_lang);
+  if (it != table[parent_lang].end()) {
+    lang_set.insert(move(*it));
+    table[parent_lang].erase(parent_lang);
+    return;
+  }
+
+  if (!table[parent_lang].empty()) {
+    auto i = table[parent_lang].begin();
+    lang_set.insert(move(*i));
+    table[parent_lang].erase(i);
+  }
+}
+
+std::string AppCoreBase::Impl::GetLanguage(std::string lang) {
+  std::list<std::string> l = SplitLanguage(lang);
+  if (l.empty())
+    return "";
+
+  auto table = GetLangTable();
+  if (table.empty())
+    return "";
+
+  std::set<std::string> lang_set {};
+  for (auto& i : l)
+    AppendLangs(i, lang_set, table);
+
+  AppendDefaultLangs(lang_set);
+  std::string ret;
+  for (auto& i : lang_set) {
+    if (ret.empty()) {
+      ret = i;
+    } else {
+      ret += ":";
+      ret += i;
+    }
+  }
+
+  return ret;
+}
+
+void AppCoreBase::Impl::UpdateLang() {
+  char* lang = vconf_get_str(VCONFKEY_LANGSET);
+  if (lang == nullptr)
+    return;
+
+  std::unique_ptr<char, decltype(std::free)*> lang_auto(lang, std::free);
+  std::string language = GetLanguage(lang);
+  if (!language.empty()) {
+    _D("*****language(%s)", language.c_str());
+    setenv("LANGUAGE", language.c_str(), 1);
+  } else {
+    setenv("LANGUAGE", lang, 1);
+  }
+  setenv("LANG", lang, 1);
+  setenv("LC_MESSAGES", lang, 1);
+  setenv("LC_ALL", lang, 1);
+  char* r = setlocale(LC_ALL, "");
+  if (r == nullptr) {
+    r = setlocale(LC_ALL, "en_US.UTF-8");
+    if (r != nullptr) {
+      _D("*****appcore setlocale=%s\n", r);
+    } else {
+      _D("*****appcore setlocale=\"C\"");
+      setenv("LC_ALL", "C", 1);
+      r = setlocale(LC_ALL, "");
+      if (r == nullptr)
+        _E("failed to setlocale");
+    }
+  }
+}
+
+void AppCoreBase::Impl::UpdateRegion() {
+  char* region = vconf_get_str(VCONFKEY_REGIONFORMAT);
+  if (region == nullptr)
+    return;
+
+  std::unique_ptr<char, decltype(std::free)*> region_auto(region, std::free);
+  setenv("LC_CTYPE", region, 1);
+  setenv("LC_NUMERIC", region, 1);
+  setenv("LC_TIME", region, 1);
+  setenv("LC_COLLATE", region, 1);
+  setenv("LC_MONETARY", region, 1);
+  setenv("LC_PAPER", region, 1);
+  setenv("LC_NAME", region, 1);
+  setenv("LC_ADDRESS", region, 1);
+  setenv("LC_TELEPHONE", region, 1);
+  setenv("LC_MEASUREMENT", region, 1);
+  setenv("LC_IDENTIFICATION", region, 1);
+  char* r = setlocale(LC_ALL, "");
+  if (r != nullptr) {
+    _D("*****appcore setlocale=%s\n", r);
+  } else {
+    _D("*****appcore setlocale=\"C\"");
+    setenv("LC_ALL", "C", 1);
+    r = setlocale(LC_ALL, "");
+    if (r == nullptr)
+      _E("failed to setlocale");
+  }
+}
+
+int AppCoreBase::SetI18n(std::string domain_name, std::string dir_name) {
+  if (domain_name.empty()) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  if (!dir_name.empty())
+    impl_->locale_dir_ = dir_name;
+
+  impl_->UpdateLang();
+  impl_->UpdateRegion();
+
+  char* r = setlocale(LC_ALL, "");
+  /* if locale is not set properly, try to set "en_US" again */
+  if (r == nullptr) {
+    r = setlocale(LC_ALL, "en_US.UTF-8");
+    if (r == nullptr) {
+      _E("appcore: setlocale() error");
+      _D("*****appcore setlocale=\"C\"");
+      setenv("LC_ALL", "C", 1);
+      r = setlocale(LC_ALL, "");
+      if (r == nullptr)
+        _E("failed to setlocale");
+    }
+  }
+
+  if (r != nullptr)
+    _D("*****appcore setlocale=%s\n", r);
+
+  r = bindtextdomain(domain_name.c_str(), dir_name.c_str());
+  if (r == nullptr)
+    _E("appcore: bindtextdomain() error");
+
+  r = textdomain(domain_name.c_str());
+  if (r == nullptr)
+    _E("appcore: textdomain() error");
+
+  return 0;
+}
+
+void AppCoreBase::Exit() {
+  aul_status_update(STATUS_DYING);
+  if (impl_->loop_delegator_)
+    impl_->loop_delegator_->OnLoopExit();
+  else
+    OnLoopExit();
+}
+
+void AppCoreBase::AddSuspendTimer() {
+  impl_->tid_ = g_timeout_add_seconds(5, [](gpointer data) -> gboolean {
+        AppCoreBase* base = reinterpret_cast<AppCoreBase*>(data);
+        base->FlushMemory();
+        return FALSE;
+      }, this);
+}
+
+void AppCoreBase::RemoveSuspendTimer() {
+  if (impl_->tid_ > 0) {
+    g_source_remove(impl_->tid_);
+    impl_->tid_ = 0;
+  }
+}
+
+void AppCoreBase::SetDisplayState(DisplayState state) {
+  __display_state = state;
+}
+
+AppCoreBase::DisplayState AppCoreBase::GetDisplayState() {
+  return __display_state;
+}
+
+int AppCoreBase::EnableWatchdog() {
+  _I("[__APPCORE_WATCHDOG__] enable");
+  return aul_watchdog_enable();
+}
+
+int AppCoreBase::DisableWatchdog() {
+  _I("[__APPCORE_WATCHDOG__] disable");
+  return aul_watchdog_disable();
+}
+
+int AppCoreBase::KickWatchdog() {
+  _I("[__APPCORE_WATCHDOG__] kick");
+  return aul_watchdog_kick();
+}
+
+void AppCoreBase::Run(int argc, char** argv) {
+  Init(argc, argv);
+  Fini();
+}
+
+void AppCoreBase::Init(int argc, char** argv) {
+  impl_->tid_ = 0;
+  impl_->suspended_state_ = false;
+  impl_->allowed_bg_ = false;
+  impl_->argc_ = argc;
+  impl_->argv_ = argv;
+  traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:OPS_INIT");
+  if (impl_->loop_delegator_)
+    impl_->loop_delegator_->OnLoopInit(argc, argv);
+  else
+    OnLoopInit(argc, argv);
+  traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+
+  if (impl_->feature_ & FEATURE_BACKGROUND_MANAGEMENT)
+    g_idle_add(Impl::InitSuspendCb, this);
+
+  traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:SET_SYSTEM_EVENT");
+  if (!impl_->dirty_) {
+    impl_->dirty_ = true;
+
+    for (auto& e : impl_->events_) {
+      if (impl_->core_delegator_)
+        impl_->core_delegator_->OnSetEvent(e->GetType());
+      else
+        OnSetEvent(e->GetType());
+    }
+  }
+  traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+
+  traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:VERIFY_LANG");
+  impl_->VerifyLanguage();
+  traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+
+  traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:SET_DEFAULT_EVENTS");
+  impl_->SetDefaultEvents();
+  traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+
+  if (impl_->core_delegator_)
+    impl_->core_delegator_->OnSetI18n();
+  else
+    OnSetI18n();
+
+  aul_app_lifecycle_update_state(AUL_APP_LIFECYCLE_STATE_INITIALIZED);
+
+  traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:CREATE");
+  int create = 0;
+  if (impl_->core_delegator_)
+    create = impl_->core_delegator_->OnCreate();
+  else
+    create = OnCreate();
+  traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+
+  aul_app_lifecycle_update_state(AUL_APP_LIFECYCLE_STATE_CREATED);
+  if (create < 0)
+    return;
+
+  if (impl_->loop_delegator_)
+    impl_->loop_delegator_->OnLoopRun();
+  else
+    OnLoopRun();
+}
+
+void AppCoreBase::Fini() {
+  Dispose();
+}
+
+void AppCoreBase::Dispose() {
+  aul_status_update(STATUS_DYING);
+  DisableWatchdog();
+  aul_app_lifecycle_update_state(AUL_APP_LIFECYCLE_STATE_DESTROYED);
+
+  traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:TERMINATE");
+  if (impl_->core_delegator_)
+    impl_->core_delegator_->OnTerminate();
+  else
+    OnTerminate();
+  traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+
+  for (auto& e : impl_->events_) {
+    if (impl_->core_delegator_)
+      impl_->core_delegator_->OnUnsetEvent(e->GetType());
+    else
+      OnUnsetEvent(e->GetType());
+  }
+
+  impl_->UnsetDefaultEvents();
+  if (impl_->sid_) {
+    g_source_remove(impl_->sid_);
+    impl_->sid_ = 0;
+  }
+
+  RemoveSuspendTimer();
+  impl_->dirty_ = false;
+  if (impl_->loop_delegator_)
+    impl_->loop_delegator_->OnLoopFinish();
+  else
+    OnLoopFinish();
+}
+
+void AppCoreBase::SetFeature(int feature) {
+  impl_->feature_ = feature;
+}
+
+int AppCoreBase::GetFeature() const {
+  return impl_->feature_;
+}
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/app-core-cpp/app_core_base.hh b/tizen-cpp/app-core-cpp/app_core_base.hh
new file mode 100644 (file)
index 0000000..ebe1d97
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_APP_CORE_CPP_APP_CORE_BASE_HH_
+#define TIZEN_CPP_APP_CORE_CPP_APP_CORE_BASE_HH_
+
+#include <memory>
+#include <string>
+
+#include <interface_app_core.hh>
+#include <interface_main_loop.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace tizen_cpp {
+
+class EXPORT_API AppCoreBase : public IAppCore, public IMainLoop {
+ public:
+  enum RotationState {
+    ROTATION_UNKNOWN,
+    ROTATION_PORTRAIT_NORMAL,
+    ROTATION_PORTRAIT_REVERSE,
+    ROTATION_LANDSCAPE_NORMAL,
+    ROTATION_LANDSCAPE_REVERSE,
+  };
+
+  enum SuspendedState {
+    SUSPENDED_STATE_WILL_ENTER_SUSPEND = 0,
+    SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND
+  };
+
+  enum DisplayState {
+    DISPLAY_STATE_UNKNOWN,
+    DISPLAY_STATE_ON,
+    DISPLAY_STATE_OFF
+  };
+
+  enum Feature {
+    FEATURE_BACKGROUND_MANAGEMENT = 0x1,
+    FEATURE_CHARGER_STATUS = 0x2
+  };
+
+  class EventBase : public IEvent {
+   public:
+    explicit EventBase(Type type);
+    virtual ~EventBase();
+    Type GetType() const override;
+    std::string GetVal(std::string cur) const;
+    int GetVal(int cur) const;
+    void SetVal(std::string val);
+    void SetVal(int val);
+
+   private:
+    class Impl;
+    std::unique_ptr<Impl> impl_;
+  };
+
+  AppCoreBase();
+  virtual ~AppCoreBase();
+
+  virtual void Run(int argc, char** argv);
+  virtual void Exit();
+  virtual void Dispose();
+  void Init(int argc, char** argv);
+  void Fini();
+  int OnReceive(aul_type type, tizen_base::Bundle b) override;
+  int OnCreate() override;
+  int OnControl(tizen_base::Bundle b) override;
+  int OnTerminate() override;
+  int OnSetI18n() override;
+  int OnSetEvent(IEvent::Type event) override;
+  int OnUnsetEvent(IEvent::Type event) override;
+  int OnTrimMemory() override;
+  void AddEvent(std::shared_ptr<EventBase> event);
+  bool RemoveEvent(std::shared_ptr<EventBase> event);
+  void RaiseEvent(int event, IEvent::Type type);
+  void RaiseEvent(const std::string& event, IEvent::Type type);
+  void FlushMemory();
+  bool IsBgAllowed();
+  bool IsSuspended();
+  void ToggleSuspendedState();
+  int SetI18n(std::string domain_name, std::string dir_name);
+  void AddSuspendTimer();
+  void RemoveSuspendTimer();
+  void SetFeature(int feature);
+  int GetFeature() const;
+  static RotationState GetRotationState();
+  static void SetDisplayState(DisplayState state);
+  static DisplayState GetDisplayState();
+  static int EnableWatchdog();
+  static int DisableWatchdog();
+  static int KickWatchdog();
+
+ protected:
+  void SetCoreDelegator(IAppCore* delegator);
+  void SetLoopDelegator(IMainLoop* delegator);
+
+ private:
+  class Impl;
+  std::unique_ptr<Impl> impl_;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_CPP_APP_CORE_BASE_HH_
diff --git a/tizen-cpp/app-core-cpp/interface_app_core.hh b/tizen-cpp/app-core-cpp/interface_app_core.hh
new file mode 100644 (file)
index 0000000..504abbe
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_APP_CORE_CPP_INTERFACE_APP_CORE_HH_
+#define TIZEN_CPP_APP_CORE_CPP_INTERFACE_APP_CORE_HH_
+
+#include <aul.h>
+#include <bundle_cpp.h>
+
+#include <string>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace tizen_cpp {
+
+class EXPORT_API IAppCore {
+ public:
+  class IEvent {
+   public:
+    enum class Type {
+      START,
+      LOW_MEMORY,
+      LOW_BATTERY,
+      LANG_CHANGE,
+      DEVICE_ORIENTATION_CHANGED,
+      REGION_CHANGE,
+      SUSPENDED_STATE_CHANGE,
+      UPDATE_REQUESTED,
+      END /* for iterate */
+    };
+
+    virtual void OnEvent(const std::string& val) = 0;
+    virtual void OnEvent(int val) = 0;
+    virtual Type GetType() const = 0;
+  };
+
+  virtual ~IAppCore() = default;  // LCOV_EXCL_LINE
+
+  virtual int OnReceive(aul_type type, tizen_base::Bundle b) = 0;
+  virtual int OnCreate() = 0;
+  virtual int OnControl(tizen_base::Bundle b) = 0;
+  virtual int OnTerminate() = 0;
+  virtual int OnSetI18n() = 0;
+  virtual int OnSetEvent(IEvent::Type event) = 0;
+  virtual int OnUnsetEvent(IEvent::Type event) = 0;
+  virtual int OnTrimMemory() = 0;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_CPP_INTERFACE_APP_CORE_HH_
diff --git a/tizen-cpp/app-core-cpp/interface_app_core_ui.hh b/tizen-cpp/app-core-cpp/interface_app_core_ui.hh
new file mode 100644 (file)
index 0000000..08046cc
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_APP_CORE_CPP_INTERFACE_APP_CORE_UI_HH_
+#define TIZEN_CPP_APP_CORE_CPP_INTERFACE_APP_CORE_UI_HH_
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace tizen_cpp {
+
+class EXPORT_API IAppCoreUi {
+ public:
+  virtual ~IAppCoreUi() = default;  // LCOV_EXCL_LINE
+
+  virtual int OnPause() = 0;
+  virtual int OnResume() = 0;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_CPP_INTERFACE_APP_CORE_UI_HH_
diff --git a/tizen-cpp/app-core-cpp/interface_main_loop.hh b/tizen-cpp/app-core-cpp/interface_main_loop.hh
new file mode 100644 (file)
index 0000000..1d8f7ef
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_APP_CORE_CPP_INTERFACE_MAIN_LOOP_HH_
+#define TIZEN_CPP_APP_CORE_CPP_INTERFACE_MAIN_LOOP_HH_
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace tizen_cpp {
+
+class EXPORT_API IMainLoop {
+ public:
+  virtual ~IMainLoop() = default;  // LCOV_EXCL_LINE
+
+  virtual void OnLoopInit(int argc, char** argv) = 0;
+  virtual void OnLoopFinish() = 0;
+  virtual void OnLoopRun() = 0;
+  virtual void OnLoopExit() = 0;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_CPP_INTERFACE_MAIN_LOOP_HH_
diff --git a/tizen-cpp/app-core-cpp/interface_window.hh b/tizen-cpp/app-core-cpp/interface_window.hh
new file mode 100644 (file)
index 0000000..4a013f8
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_APP_CORE_CPP_INTERFACE_WINDOW_HH_
+#define TIZEN_CPP_APP_CORE_CPP_INTERFACE_WINDOW_HH_
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace tizen_cpp {
+
+class EXPORT_API IWindow {
+ public:
+  virtual ~IWindow() = default;  // LCOV_EXCL_LINE
+
+  virtual void OnShow(int type, void* event) = 0;
+  virtual void OnHide(int type, void* event) = 0;
+  virtual void OnLower(int type, void* event) = 0;
+  virtual void OnVisibility(int type, void* event) = 0;
+  virtual void OnPreVisibility(int type, void* event) = 0;
+  virtual void OnAuxMessage(int type, void* event) = 0;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_CPP_INTERFACE_WINDOW_HH_
diff --git a/tizen-cpp/app-core-efl-cpp/CMakeLists.txt b/tizen-cpp/app-core-efl-cpp/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a7c3b03
--- /dev/null
@@ -0,0 +1,38 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_CORE_EFL_CPP_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../common COMMON_SRCS)
+
+ADD_LIBRARY(${TARGET_APP_CORE_EFL_CPP} SHARED
+  ${APP_CORE_EFL_CPP_SRCS}
+  ${COMMON_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_APP_CORE_EFL_CPP} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/../)
+
+TARGET_LINK_LIBRARIES(${TARGET_APP_CORE_EFL_CPP} PUBLIC
+  ${TARGET_APP_CORE_UI_CPP}
+  ${TARGET_APP_CORE_CPP}
+  "-L/usr/lib/hal")
+
+SET_TARGET_PROPERTIES(${TARGET_APP_CORE_EFL_CPP}
+  PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_APP_CORE_EFL_CPP}
+  PROPERTIES VERSION ${FULLVER})
+
+APPLY_PKG_CONFIG(${TARGET_APP_CORE_EFL_CPP} PUBLIC
+  AUL_DEPS
+  BUNDLE_DEPS
+  DLOG_DEPS
+  ELEMENTARY_DEPS
+)
+
+CONFIGURE_FILE(${TARGET_APP_CORE_EFL_CPP}.pc.in
+  ${TARGET_APP_CORE_EFL_CPP}.pc @ONLY)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_APP_CORE_EFL_CPP}.pc
+  DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+
+INSTALL(TARGETS ${TARGET_APP_CORE_EFL_CPP} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION include/appcore_cpp
+  FILES_MATCHING
+  PATTERN "*_private.hh" EXCLUDE
+  PATTERN "*.hh")
diff --git a/tizen-cpp/app-core-efl-cpp/app-core-efl-cpp.pc.in b/tizen-cpp/app-core-efl-cpp/app-core-efl-cpp.pc.in
new file mode 100644 (file)
index 0000000..3eea2e4
--- /dev/null
@@ -0,0 +1,15 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDEDIR@
+
+Name: app-core-efl-cpp
+Description: Tizen application core library for EFL
+Version: @VERSION@
+Requires.private: elementary dlog
+Requires: app-core-cpp app-core-ui-cpp
+Libs: -L${libdir} -lapp-core-efl-cpp
+Cflags: -I${includedir} -I${includedir}/appcore_cpp
+cppflags: I${includedir} -I${includedir}/appcore_cpp
diff --git a/tizen-cpp/app-core-efl-cpp/app_core_efl_base.cc b/tizen-cpp/app-core-efl-cpp/app_core_efl_base.cc
new file mode 100644 (file)
index 0000000..b69ee53
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Elementary.h>
+#include <glib.h>
+#include <stdlib.h>
+
+#include <memory>
+#include <string>
+#include <thread>
+
+#include "app-core-efl-cpp/app_core_efl_base.hh"
+#include "app-core-efl-cpp/voice_elm_private.hh"
+#include "common/log_private.hh"
+
+namespace tizen_cpp {
+
+namespace {
+
+std::unique_ptr<VoiceElm> __vc_elm;
+
+}  // namespace
+
+void AppCoreEflBase::OnLoopInit(int argc, char** argv) {
+  elm_init(argc, argv);
+  unsigned int hint = GetHint();
+  if ((hint & HINT_HW_ACC_CONTROL) && !getenv("AUL_HWACC")) {
+    const char* hwacc = getenv("HWACC");
+    if (hwacc == nullptr) {
+      _D("elm_config_accel_preference_set is not called");
+    } else if (strcmp(hwacc, "USE") == 0) {
+      elm_config_accel_preference_set("hw");
+      _D("elm_config_accel_preference_set : hw");
+    } else if (strcmp(hwacc, "NOT_USE") == 0) {
+      elm_config_accel_preference_set("none");
+      _D("elm_config_accel_preference_set : none");
+    } else {
+      _D("elm_config_accel_preference_set is not called");
+    }
+  }
+
+  if (VoiceElm::IsVtAutoMode()) {
+    std::thread([]{
+          int retry_count = 3;
+          do {
+            if (__vc_elm.get() == nullptr)
+              __vc_elm.reset(VoiceElm::Load());
+
+            if (__vc_elm.get() != nullptr) {
+              g_idle_add([](gpointer data) {
+                    if (__vc_elm.get() != nullptr)
+                      __vc_elm->Init();
+                    return G_SOURCE_REMOVE;
+                  }, nullptr);
+              break;
+            }
+          } while (retry_count--);
+        }).detach();
+  }
+}
+
+void AppCoreEflBase::OnLoopFinish() {
+  if (__vc_elm != nullptr)
+    __vc_elm.reset();
+
+  elm_shutdown();
+
+  /* Check loader case */
+  const char* env = getenv("AUL_LOADER_INIT");
+  if (env && env[0] == '1') {
+    setenv("AUL_LOADER_INIT", "0", 1);
+    elm_shutdown();
+  }
+}
+
+void AppCoreEflBase::OnLoopRun() {
+  elm_run();
+}
+
+void AppCoreEflBase::OnLoopExit() {
+  elm_exit();
+}
+
+int AppCoreEflBase::OnTrimMemory() {
+  _D("Trim memory");
+  elm_cache_all_flush();
+  return AppCoreUiBase::OnTrimMemory();
+}
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/app-core-efl-cpp/app_core_efl_base.hh b/tizen-cpp/app-core-efl-cpp/app_core_efl_base.hh
new file mode 100644 (file)
index 0000000..497fd43
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_APP_CORE_EFL_CPP_APP_CORE_EFL_BASE_HH_
+#define TIZEN_CPP_APP_CORE_EFL_CPP_APP_CORE_EFL_BASE_HH_
+
+#include <app_core_ui_base.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace tizen_cpp {
+
+class EXPORT_API AppCoreEflBase : public AppCoreUiBase {
+ public:
+  explicit AppCoreEflBase(unsigned int hint) : AppCoreUiBase(hint) {}
+
+  void OnLoopInit(int argc, char** argv) override;
+  void OnLoopFinish() override;
+  void OnLoopRun() override;
+  void OnLoopExit() override;
+  int OnTrimMemory() override;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_EFL_CPP_APP_CORE_EFL_BASE_HH_
diff --git a/tizen-cpp/app-core-efl-cpp/voice_elm_private.cc b/tizen-cpp/app-core-efl-cpp/voice_elm_private.cc
new file mode 100644 (file)
index 0000000..9c49b7b
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <new>
+
+#include "app-core-efl-cpp/voice_elm_private.hh"
+#include "common/log_private.hh"
+
+namespace tizen_cpp {
+
+namespace {
+
+constexpr const char kPathLibVcElm[] = "/usr/lib/libvc-elm.so.0";
+constexpr const char kNameVcElmInitialize[] = "vc_elm_initialize";
+constexpr const char kNameVcElmDeinitialize[] = "vc_elm_deinitialize";
+constexpr const char kNameVcElmSetAutoRegisterMode[] =
+    "vc_elm_set_auto_register_mode";
+
+}  // namespace
+
+VoiceElm::VoiceElm(void* handle, VcElmInitializeFunc init_func,
+    VcElmDeinitializeFunc deinit_func,
+    VcElmSetAutoRegisterModeFunc set_auto_register_mode_func)
+    : handle_(handle),
+      init_func_(init_func),
+      deinit_func_(deinit_func),
+      set_auto_register_mode_func_(set_auto_register_mode_func) {
+}
+
+VoiceElm::~VoiceElm() {
+  Fini();
+
+  if (handle_)
+    dlclose(handle_);
+}
+
+VoiceElm* VoiceElm::Load() {
+  if (access(kPathLibVcElm, F_OK) != 0) {
+    _E("access() is failed. path(%s), errno(%d)", kPathLibVcElm, errno);
+    return nullptr;
+  }
+
+  void* handle = dlopen(kPathLibVcElm, RTLD_LAZY | RTLD_LOCAL);
+  if (handle == nullptr) {
+    _E("dlopen() is failed");
+    return nullptr;
+  }
+
+  auto init_func = reinterpret_cast<VcElmInitializeFunc>(
+      dlsym(handle, kNameVcElmInitialize));
+  if (init_func == nullptr) {
+    _E("dlsym() is failed. handle(%p), symbol(%s)",
+        handle, kNameVcElmInitialize);
+    dlclose(handle);
+    return nullptr;
+  }
+
+  auto deinit_func = reinterpret_cast<VcElmDeinitializeFunc>(
+      dlsym(handle, kNameVcElmDeinitialize));
+  if (deinit_func == nullptr) {
+    _E("dlsym() is failed. handle(%p), symbol(%s)",
+        handle, kNameVcElmDeinitialize);
+    dlclose(handle);
+    return nullptr;
+  }
+
+  auto set_auto_register_mode_func =
+      reinterpret_cast<VcElmSetAutoRegisterModeFunc>(
+          dlsym(handle, kNameVcElmSetAutoRegisterMode));
+  if (set_auto_register_mode_func == nullptr) {
+    _E("dlsym() is failed. handle(%p), symbol(%s)",
+        handle, kNameVcElmSetAutoRegisterMode);
+    dlclose(handle);
+    return nullptr;
+  }
+
+  return new (std::nothrow) VoiceElm(
+      handle, init_func, deinit_func, set_auto_register_mode_func);
+}
+
+bool VoiceElm::IsVtAutoMode() {
+  int vt_automode = 0;
+  vconf_get_bool(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE, &vt_automode);
+  return vt_automode ? true : false;
+}
+
+void VoiceElm::Init() {
+  vconf_notify_key_changed(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE,
+      VconfKeyChangedCb, this);
+
+  if (IsVtAutoMode()) {
+    if (!initialized_) {
+      init_func_();
+      initialized_ = true;
+    }
+
+    set_auto_register_mode_func_(2, 0);
+  }
+}
+
+void VoiceElm::Fini() {
+  vconf_ignore_key_changed(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE,
+      VconfKeyChangedCb);
+
+  if (initialized_) {
+    deinit_func_();
+    initialized_ = false;
+  }
+}
+
+void VoiceElm::VconfKeyChangedCb(keynode_t* key, void* data) {
+  auto* handle = static_cast<VoiceElm*>(data);
+  int vt_automode = vconf_keynode_get_bool(key);
+  if (vt_automode) {
+    if (!handle->initialized_) {
+      handle->init_func_();
+      handle->initialized_ = true;
+    }
+
+    handle->set_auto_register_mode_func_(2, 0);
+  } else {
+    handle->deinit_func_();
+    handle->initialized_ = false;
+  }
+}
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/app-core-efl-cpp/voice_elm_private.hh b/tizen-cpp/app-core-efl-cpp/voice_elm_private.hh
new file mode 100644 (file)
index 0000000..d160627
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_APP_CORE_EFL_CPP_VOICE_ELM_PRIVATE_HH
+#define TIZEN_CPP_APP_CORE_EFL_CPP_VOICE_ELM_PRIVATE_HH_
+
+#include <vconf.h>
+
+namespace tizen_cpp {
+
+class VoiceElm {
+ public:
+  using VcElmInitializeFunc = int (*)(void);
+  using VcElmDeinitializeFunc = int (*)(void);
+  using VcElmSetAutoRegisterModeFunc = int (*)(int, int);
+
+  VoiceElm(void* handle, VcElmInitializeFunc init_func,
+      VcElmDeinitializeFunc deinit_func,
+      VcElmSetAutoRegisterModeFunc set_auto_register_mode_func);
+  ~VoiceElm();
+
+  static VoiceElm* Load();
+  static bool IsVtAutoMode();
+
+  void Init();
+  void Fini();
+
+ private:
+  static void VconfKeyChangedCb(keynode_t* key, void* data);
+
+ private:
+  bool initialized_ = false;
+  void* handle_ = nullptr;
+  VcElmInitializeFunc init_func_ = nullptr;
+  VcElmDeinitializeFunc deinit_func_ = nullptr;
+  VcElmSetAutoRegisterModeFunc set_auto_register_mode_func_ = nullptr;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_EFL_CPP_VOICE_ELM_PRIVATE_HH_
diff --git a/tizen-cpp/app-core-multi-window-cpp/CMakeLists.txt b/tizen-cpp/app-core-multi-window-cpp/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3285e7d
--- /dev/null
@@ -0,0 +1,42 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}
+  APP_CORE_MULTI_WINDOW_CPP_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../common
+  COMMON_SRCS)
+
+ADD_LIBRARY(${TARGET_APP_CORE_MULTI_WINDOW_CPP} SHARED
+  ${APP_CORE_MULTI_WINDOW_CPP_SRCS}
+  ${COMMON_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_APP_CORE_MULTI_WINDOW_CPP} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/../)
+
+TARGET_LINK_LIBRARIES(${TARGET_APP_CORE_MULTI_WINDOW_CPP} PUBLIC
+  ${TARGET_APP_CORE_CPP}
+  "-L/usr/lib/hal")
+
+SET_TARGET_PROPERTIES(${TARGET_APP_CORE_MULTI_WINDOW_CPP}
+  PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_APP_CORE_MULTI_WINDOW_CPP}
+  PROPERTIES VERSION ${FULLVER})
+
+APPLY_PKG_CONFIG(${TARGET_APP_CORE_MULTI_WINDOW_CPP} PUBLIC
+  AUL_DEPS
+  DLOG_DEPS
+  ECORE_DEPS
+  ECORE_WL2_DEPS
+  GLIB_2_DEPS
+  GOBJECT_2_DEPS
+)
+
+CONFIGURE_FILE(${TARGET_APP_CORE_MULTI_WINDOW_CPP}.pc.in
+  ${TARGET_APP_CORE_MULTI_WINDOW_CPP}.pc @ONLY)
+INSTALL(FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_APP_CORE_MULTI_WINDOW_CPP}.pc
+  DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+
+INSTALL(TARGETS ${TARGET_APP_CORE_MULTI_WINDOW_CPP}
+  DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION include/appcore_cpp
+  FILES_MATCHING
+  PATTERN "*.hh")
diff --git a/tizen-cpp/app-core-multi-window-cpp/app-core-multi-window-cpp.pc.in b/tizen-cpp/app-core-multi-window-cpp/app-core-multi-window-cpp.pc.in
new file mode 100644 (file)
index 0000000..de8c26b
--- /dev/null
@@ -0,0 +1,15 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDEDIR@
+
+Name: app-core-multi-window-cpp
+Description: Tizen application core library for multiwindow
+Version: @VERSION@
+Requires.private: ecore-wl2 dlog
+Requires: app-core-cpp
+Libs: -L${libdir} -lapp-core-multi-window-cpp
+Cflags: -I${includedir} -I${includedir}/appcore_cpp
+cppflags: I${includedir} -I${includedir}/appcore_cpp
diff --git a/tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.cc b/tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.cc
new file mode 100644 (file)
index 0000000..df107e5
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <list>
+#include <map>
+#include <stdexcept>
+#include <string>
+
+#include "app-core-multi-window-cpp/app_core_multi_window_base.hh"
+#include "common/ecore_handler.hh"
+#include "common/log_private.hh"
+
+namespace tizen_cpp {
+
+class AppCoreMultiWindowBase::Context::Impl {
+ public:
+  Impl(std::string context_id, std::string inst_id, AppCoreMultiWindowBase* app)
+      : id_(inst_id), context_id_(context_id), app_(app) {}
+
+ private:
+  friend class AppCoreMultiWindowBase::Context;
+  bool paused_ = true;
+  std::string id_;
+  std::string context_id_;
+  int wid_ = 0;
+  AppCoreMultiWindowBase* app_;
+};
+
+class AppCoreMultiWindowBase::Impl {
+ private:
+  friend class AppCoreMultiWindowBase;
+  std::shared_ptr<EcoreHandler> handler_;
+  std::map<std::string, std::shared_ptr<Context::IFactory>> factory_map_;
+  std::list<std::shared_ptr<Context>> contexts_;
+  std::unique_ptr<EcoreHandler::ITrim> trim_;
+};
+
+AppCoreMultiWindowBase::Context::Context(std::string context_id,
+    std::string inst_id, AppCoreMultiWindowBase* app)
+    : impl_(std::make_unique<Impl>(
+          std::move(context_id), std::move(inst_id), app)) {
+}
+
+AppCoreMultiWindowBase::Context::~Context() = default;
+
+void AppCoreMultiWindowBase::Context::Exit() {
+  Context::Pause();
+  OnTerminate();
+}
+
+void AppCoreMultiWindowBase::Context::Drop() {
+  OnTerminate();
+}
+
+void AppCoreMultiWindowBase::Context::Pause() {
+  if (impl_->paused_)
+    return;
+
+  OnPause();
+  impl_->paused_ = true;
+}
+
+void AppCoreMultiWindowBase::Context::Resume() {
+  if (!impl_->paused_)
+    return;
+
+  OnResume();
+  impl_->paused_ = false;
+}
+
+bool AppCoreMultiWindowBase::Context::IsResumed() {
+  return !impl_->paused_;
+}
+
+const std::string& AppCoreMultiWindowBase::Context::GetInstId() const {
+  return impl_->id_;
+}
+
+const std::string& AppCoreMultiWindowBase::Context::GetContextId() const {
+  return impl_->context_id_;
+}
+
+int AppCoreMultiWindowBase::Context::GetWindowId() const {
+  return impl_->wid_;
+}
+
+void AppCoreMultiWindowBase::Context::WindowBind(Ecore_Wl2_Window* wl_win) {
+  if (wl_win == nullptr) {
+    _E("Invalid parameter");
+    return;
+  }
+
+  impl_->wid_ = ecore_wl2_window_id_get(wl_win);
+}
+
+void AppCoreMultiWindowBase::Context::WindowUnbind() {
+  impl_->wid_ = 0;
+}
+
+AppCoreMultiWindowBase* AppCoreMultiWindowBase::Context::GetApp() {
+  return impl_->app_;
+}
+
+AppCoreMultiWindowBase::AppCoreMultiWindowBase() :
+    impl_(std::make_unique<Impl>()) {}
+
+AppCoreMultiWindowBase::~AppCoreMultiWindowBase() = default;
+
+const std::list<std::shared_ptr<AppCoreMultiWindowBase::Context>>&
+AppCoreMultiWindowBase::GetContexts() {
+  return impl_->contexts_;
+}
+
+int AppCoreMultiWindowBase::GetContextCnt() const {
+  return impl_->contexts_.size();
+}
+
+void AppCoreMultiWindowBase::ExitContext(
+    std::shared_ptr<AppCoreMultiWindowBase::Context> context) {
+  context->Exit();
+  impl_->contexts_.remove(context);
+}
+
+std::shared_ptr<AppCoreMultiWindowBase::Context>
+AppCoreMultiWindowBase::CreateContext(const std::string& context_id,
+    const std::string& inst_id) {
+  auto i = impl_->factory_map_.find(context_id);
+  if (i == impl_->factory_map_.end())
+    throw std::runtime_error("failed to find factory");
+
+  std::shared_ptr<Context> c = (*i).second->Create(inst_id, this);
+  return c;
+}
+
+std::shared_ptr<AppCoreMultiWindowBase::Context>
+AppCoreMultiWindowBase::RunContext(
+    std::shared_ptr<AppCoreMultiWindowBase::Context> cxt) {
+  impl_->contexts_.push_back(cxt);
+  try {
+    cxt->OnCreate();
+  } catch (const std::runtime_error&) {
+    cxt->Drop();
+    impl_->contexts_.remove(cxt);
+    return {};
+  }
+
+  return cxt;
+}
+
+std::shared_ptr<AppCoreMultiWindowBase::Context>
+AppCoreMultiWindowBase::RunContext(const std::string& context_id,
+    const std::string& inst_id) {
+  auto c = CreateContext(context_id, inst_id);
+  return RunContext(c);
+}
+
+std::shared_ptr<AppCoreMultiWindowBase::Context>
+AppCoreMultiWindowBase::FindById(const std::string& inst_id) {
+  for (auto& i : impl_->contexts_) {
+    if (i->GetInstId() == inst_id) {
+      return i;
+    }
+  }
+
+  return {};
+}
+
+std::shared_ptr<AppCoreMultiWindowBase::Context>
+AppCoreMultiWindowBase::FindByWindowId(int win_id) {
+  for (auto& i : impl_->contexts_) {
+    if (i->GetWindowId() == win_id) {
+      return i;
+    }
+  }
+
+  return {};
+}
+
+void AppCoreMultiWindowBase::Run(int argc, char** argv) {
+  AppCoreBase::Run(argc, argv);
+}
+
+void AppCoreMultiWindowBase::Dispose() {
+  for (auto& i : impl_->contexts_) {
+    i->Exit();
+  }
+  impl_->contexts_.clear();
+  impl_->factory_map_.clear();
+  if (impl_->handler_.get() != nullptr)
+    impl_->handler_->Fini();
+  AppCoreBase::Dispose();
+}
+
+int AppCoreMultiWindowBase::OnCreate() {
+  AppCoreBase::OnCreate();
+
+  class Trimmer : public EcoreHandler::ITrim {
+   public:
+    bool IsTrimmable() {
+      return base_->IsResumed();
+    }
+
+    void OnTrim() {
+      base_->OnTrimMemory();
+    }
+
+    explicit Trimmer(AppCoreMultiWindowBase* base) : base_(base) {}
+
+   private:
+    AppCoreMultiWindowBase* base_;
+  };
+
+  impl_->trim_ = std::unique_ptr<EcoreHandler::ITrim>(new Trimmer(this));
+
+  impl_->handler_ = std::make_shared<EcoreHandler>(this, impl_->trim_.get());
+  impl_->handler_->Init();
+  return 0;
+}
+
+bool AppCoreMultiWindowBase::IsResumed() {
+  for (auto& i : impl_->contexts_) {
+    if (i->IsResumed())
+      return true;
+  }
+
+  return false;
+}
+
+void AppCoreMultiWindowBase::OnShow(int type, void* event) {
+}
+
+void AppCoreMultiWindowBase::OnHide(int type, void* event) {
+  Ecore_Wl2_Event_Window_Hide* ev =
+      static_cast<Ecore_Wl2_Event_Window_Hide*>(event);
+  auto cxt = FindByWindowId(ev->win);
+  if (cxt.get() == nullptr)
+    return;
+
+  cxt->WindowUnbind();
+}
+
+void AppCoreMultiWindowBase::OnLower(int type, void* event) {
+}
+
+void AppCoreMultiWindowBase::OnVisibility(int type, void* event) {
+  auto* ev = static_cast<Ecore_Wl2_Event_Window_Visibility_Change*>(event);
+  auto cxt = FindByWindowId(ev->win);
+  if (cxt.get() == nullptr)
+    return;
+
+  if (ev->fully_obscured)
+    cxt->Context::Pause();
+  else
+    cxt->Context::Resume();
+}
+
+void AppCoreMultiWindowBase::OnPreVisibility(int type, void* event) {
+  auto* ev = static_cast<Ecore_Wl2_Event_Window_Pre_Visibility_Change*>(event);
+  auto cxt = FindByWindowId(ev->win);
+  if (cxt.get() == nullptr)
+    return;
+
+  if (ev->type == ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED)
+    cxt->Context::Resume();
+}
+
+void AppCoreMultiWindowBase::OnAuxMessage(int type, void* event) {
+  auto* ev = static_cast<Ecore_Wl2_Event_Aux_Message*>(event);
+  if (ev->key && !strcmp(ev->key, "dpms_wm")) {
+    if (ev->val && !strcmp(ev->val, "on")) {
+      _D("Display state: on");
+      AppCoreBase::SetDisplayState(AppCoreBase::DISPLAY_STATE_ON);
+    } else if (ev->val && !strcmp(ev->val, "off")) {
+      _D("Display state: off");
+      AppCoreBase::SetDisplayState(AppCoreBase::DISPLAY_STATE_OFF);
+    } else {
+      _E("Unknown state: %s", ev->val);
+    }
+  }
+}
+
+void AppCoreMultiWindowBase::AddContextFactory(
+    std::shared_ptr<AppCoreMultiWindowBase::Context::IFactory> factory,
+    const std::string& context_id) {
+  impl_->factory_map_[context_id] = std::move(factory);
+}
+
+std::shared_ptr<AppCoreMultiWindowBase::Context::IFactory>
+AppCoreMultiWindowBase::GetContextFactory(const std::string& context_id) {
+  return impl_->factory_map_[context_id];
+}
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.hh b/tizen-cpp/app-core-multi-window-cpp/app_core_multi_window_base.hh
new file mode 100644 (file)
index 0000000..d308f0b
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_APP_CORE_MULTI_WINDOW_CPP_APP_CORE_MULTI_WINDOW_BASE_HH_
+#define TIZEN_CPP_APP_CORE_MULTI_WINDOW_CPP_APP_CORE_MULTI_WINDOW_BASE_HH_
+
+#include <Ecore_Wl2.h>
+
+#include <list>
+#include <memory>
+#include <string>
+
+#include <app_core_base.hh>
+#include <interface_window.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace tizen_cpp {
+
+class EXPORT_API AppCoreMultiWindowBase : public AppCoreBase, public IWindow {
+ public:
+  class Context {
+   public:
+    class IFactory {
+     public:
+      virtual ~IFactory() = default;
+      virtual std::unique_ptr<Context> Create(std::string inst_id,
+          AppCoreMultiWindowBase* app) = 0;
+    };
+
+    Context(std::string context_id, std::string inst_id,
+        AppCoreMultiWindowBase* app);
+    virtual ~Context();
+
+    virtual void OnCreate() = 0;
+    virtual void OnTerminate() = 0;
+    virtual void OnPause() = 0;
+    virtual void OnResume() = 0;
+    virtual void Exit();
+    virtual void WindowBind(Ecore_Wl2_Window* wl_win);
+    virtual void WindowUnbind();
+    virtual void Drop();
+    virtual void Pause();
+    virtual void Resume();
+    bool IsResumed();
+    const std::string& GetInstId() const;
+    const std::string& GetContextId() const;
+    int GetWindowId() const;
+    AppCoreMultiWindowBase* GetApp();
+
+   private:
+    class Impl;
+    std::unique_ptr<Impl> impl_;
+  };
+
+  AppCoreMultiWindowBase();
+  virtual ~AppCoreMultiWindowBase();
+
+  int OnCreate() override;
+  void OnShow(int type, void* event) override;
+  void OnHide(int type, void* event) override;
+  void OnLower(int type, void* event) override;
+  void OnVisibility(int type, void* event) override;
+  void OnPreVisibility(int type, void* event) override;
+  void OnAuxMessage(int type, void* event) override;
+  bool IsResumed();
+  int GetContextCnt() const;
+  const std::list<std::shared_ptr<Context>>& GetContexts();
+  virtual void ExitContext(std::shared_ptr<Context> context);
+  std::shared_ptr<Context> FindById(const std::string& inst_id);
+  std::shared_ptr<Context> FindByWindowId(int win_id);
+  void AddContextFactory(std::shared_ptr<Context::IFactory> factory,
+      const std::string& context_id);
+  std::shared_ptr<Context> RunContext(const std::string& context_id,
+      const std::string& inst_id);
+  std::shared_ptr<Context> RunContext(std::shared_ptr<Context> cxt);
+  std::shared_ptr<Context> CreateContext(const std::string& context_id,
+      const std::string& inst_id);
+  void Run(int argc, char** argv) override;
+  std::shared_ptr<Context::IFactory> GetContextFactory(
+      const std::string& context_id);
+  void Dispose() override;
+
+ private:
+  class Impl;
+  std::unique_ptr<Impl> impl_;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_MULTI_WINDOW_CPP__APP_CORE_MULTI_WINDOW_BASE_HH_
diff --git a/tizen-cpp/app-core-ui-cpp/CMakeLists.txt b/tizen-cpp/app-core-ui-cpp/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a4d55d8
--- /dev/null
@@ -0,0 +1,48 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_CORE_UI_CPP_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../common COMMON_SRCS)
+
+ADD_LIBRARY(${TARGET_APP_CORE_UI_CPP} SHARED
+  ${APP_CORE_UI_CPP_SRCS}
+  ${COMMON_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_APP_CORE_UI_CPP} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/../)
+
+TARGET_LINK_LIBRARIES(${TARGET_APP_CORE_UI_CPP} PUBLIC
+  ${TARGET_APP_CORE_CPP}
+  "-L/usr/lib/hal")
+
+SET_TARGET_PROPERTIES(${TARGET_APP_CORE_UI_CPP}
+  PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_APP_CORE_UI_CPP}
+  PROPERTIES VERSION ${FULLVER})
+
+APPLY_PKG_CONFIG(${TARGET_APP_CORE_UI_CPP} PUBLIC
+  AUL_DEPS
+  BUNDLE_DEPS
+  DLOG_DEPS
+  ECORE_DEPS
+  ECORE_WL2_DEPS
+  GLIB_2_DEPS
+  GOBJECT_2_DEPS
+  PKGMGR_INFO_DEPS
+  TIZEN_EXTENSION_CLIENT_DEPS
+  TTRACE_DEPS
+  WAYLAND_CLIENT_DEPS
+)
+
+CONFIGURE_FILE(${TARGET_APP_CORE_UI_CPP}.pc.in
+  ${TARGET_APP_CORE_UI_CPP}.pc @ONLY)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_APP_CORE_UI_CPP}.pc
+  DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+
+INSTALL(TARGETS ${TARGET_APP_CORE_UI_CPP} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION include/appcore_cpp
+  FILES_MATCHING
+  PATTERN "*_private.hh" EXCLUDE
+  PATTERN "*.hh")
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
+  DESTINATION include/appcore
+  FILES_MATCHING
+  PATTERN "*.h")
diff --git a/tizen-cpp/app-core-ui-cpp/app-core-ui-cpp.pc.in b/tizen-cpp/app-core-ui-cpp/app-core-ui-cpp.pc.in
new file mode 100644 (file)
index 0000000..20ed780
--- /dev/null
@@ -0,0 +1,15 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDEDIR@
+
+Name: app-core-ui-cpp
+Description: Tizen application core library for UI
+Version: @VERSION@
+Requires.private: dlog
+Requires: app-core-cpp
+Libs: -L${libdir} -lapp-core-ui-cpp
+Cflags: -I${includedir} -I${includedir}/appcore_cpp
+cppflags: I${includedir} -I${includedir}/appcore_cpp
diff --git a/tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc b/tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc
new file mode 100644 (file)
index 0000000..7102c71
--- /dev/null
@@ -0,0 +1,788 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_Wl2.h>
+#include <aul_app_lifecycle.h>
+#include <aul_rpc_port.h>
+#include <aul_svc.h>
+#include <bundle_internal.h>
+#include <sys/types.h>
+#include <ttrace.h>
+#include <unistd.h>
+
+#include <list>
+#include <memory>
+#include <string>
+
+#include "app-core-cpp/app_core_base.hh"
+#include "app-core-ui-cpp/app_core_ui_base.hh"
+#include "app-core-ui-cpp/app_core_ui_delegator_private.hh"
+#include "app-core-ui-cpp/app_core_ui_plugin_private.hh"
+#include "app-core-ui-cpp/appcore_ui_base.h"
+#include "app-core-ui-cpp/wayland_handler_private.hh"
+#include "common/ecore_handler.hh"
+#include "common/log_private.hh"
+
+namespace tizen_cpp {
+
+class AppCoreUiBase::Impl {
+ public:
+  Impl(AppCoreUiBase* parent, unsigned int hint)
+      : parent_(parent),
+        hint_(hint),
+        handler_(std::make_shared<EcoreHandler>(parent)),
+        wl_handler_(new WaylandHandler()) {
+  }
+
+ private:
+  friend class AppCoreUiBase;
+  AppCoreUiBase* parent_;
+
+  enum AppState {
+    AS_NONE,
+    AS_CREATED,
+    AS_RUNNING,
+    AS_PAUSED,
+    AS_DYING,
+  };
+
+  enum VisibilityType {
+    VT_NONE,
+    VT_UNOBSCURED,
+    VT_FULLY_OBSCURED,
+  };
+
+  enum WinStatus {
+    WS_NONE,
+    WS_PAUSE,
+    WS_RESUME,
+  };
+
+  struct WinNode {
+    unsigned int win_;
+    unsigned int surf_;
+    int vis_;
+    WinNode(unsigned int win, unsigned int surf)
+        : win_(win), surf_(surf), vis_(VT_NONE) {
+    }
+  };
+
+  void ExitFromSuspend();
+  void PrepareToSuspend();
+  void DoStart(tizen_base::Bundle b);
+  void DoResume();
+  void DoPause();
+  bool CheckVisible();
+  int IsLegacyLifecycle();
+  std::shared_ptr<struct WinNode> FindWin(unsigned int win);
+  bool AddWin(unsigned int win, unsigned int surf);
+  bool DeleteWin(unsigned int win);
+  bool UpdateWin(unsigned int win, unsigned int surf, int vis);
+  void RaiseWin();
+  void PauseWin();
+  void ApplyBgState(bool bg_state);
+  void SetAppId();
+  int InitWl();
+  int FiniWl();
+  void PluginInit(int argc, char** argv);
+  void PluginFini();
+
+  std::list<std::shared_ptr<WinNode>> winnode_list_;
+  unsigned int hint_;
+  std::string below_app_;
+  bool first_launch_ = true;
+  bool bg_state_ = false;
+  bool resource_reclaiming_ = true;
+  std::string appid_;
+  AppState state_ = AS_NONE;
+  WinStatus w_status_ = WS_NONE;
+  std::shared_ptr<EcoreHandler> handler_;
+  std::unique_ptr<WaylandHandler> wl_handler_;
+  IAppCoreUi* core_ui_delegator_ = nullptr;
+  std::unique_ptr<AppCoreUiDelegator> plugin_delegator_;
+  std::unique_ptr<AppCoreUiPlugin> plugin_;
+};
+
+AppCoreUiBase::AppCoreUiBase(unsigned int hint)
+    : impl_(new Impl(this, hint)) {
+}
+
+AppCoreUiBase::~AppCoreUiBase() = default;
+
+std::shared_ptr<AppCoreUiBase::Impl::WinNode> AppCoreUiBase::Impl::FindWin(
+    unsigned int win) {
+  for (auto& i : winnode_list_) {
+    if (i->win_ == win)
+      return i;
+  }
+
+  return nullptr;
+}
+
+bool AppCoreUiBase::Impl::AddWin(unsigned int win, unsigned int surf) {
+  _D("[EVENT_TEST][EVENT] __add_win WIN: %u", win);
+  std::shared_ptr<AppCoreUiBase::Impl::WinNode> node = FindWin(win);
+  if (node != nullptr) {
+    _D("[EVENT_TEST][EVENT] ERROR There is already window: %u", win);
+    return false;
+  }
+
+  winnode_list_.emplace_back(new WinNode(win, surf));
+  return true;
+}
+
+bool AppCoreUiBase::Impl::DeleteWin(unsigned int win) {
+  std::shared_ptr<struct AppCoreUiBase::Impl::WinNode> node = FindWin(win);
+  if (node == nullptr) {
+    _D("[EVENT_TEST][EVENT] ERROR There is no window: %u", win);
+    return false;
+  }
+
+  winnode_list_.remove_if(
+      [win](std::shared_ptr<struct AppCoreUiBase::Impl::WinNode> node) {
+        return node->win_ == win;
+      });
+  return true;
+}
+
+bool AppCoreUiBase::Impl::UpdateWin(unsigned int win, unsigned int surf,
+    int vis) {
+  std::shared_ptr<AppCoreUiBase::Impl::WinNode> node = FindWin(win);
+  if (node == nullptr) {
+    _D("[EVENT_TEST][EVENT] ERROR There is no window: %u", win);
+    return false;
+  }
+
+  node->win_ = win;
+  if (surf != 0)
+    node->surf_ = surf;
+  if (vis != VT_NONE)
+    node->vis_ = vis;
+
+  return true;
+}
+
+void AppCoreUiBase::Impl::RaiseWin() {
+  if (!(hint_ & HINT_WINDOW_STACK_CONTROL))
+    return;
+
+  unsigned int win_id = parent_->GetMainWindow();
+  _I("Raise window: %u", win_id);
+  handler_->RaiseWin(win_id);
+}
+
+void AppCoreUiBase::Impl::PauseWin() {
+  if (!(hint_ & HINT_WINDOW_STACK_CONTROL))
+    return;
+
+  _D("Pause window");
+  for (auto& i : winnode_list_) {
+    _D("Pause window: %u", i->win_);
+    handler_->PauseWin(i->win_);
+  }
+}
+
+unsigned int AppCoreUiBase::GetMainWindow() {
+  if (impl_->winnode_list_.empty())
+    return 0;
+
+  return impl_->winnode_list_.begin()->get()->win_;
+}
+
+unsigned int AppCoreUiBase::GetMainSurface() {
+  if (impl_->winnode_list_.empty())
+    return 0;
+
+  return impl_->winnode_list_.begin()->get()->surf_;
+}
+
+void AppCoreUiBase::SetCoreUiDelegator(IAppCoreUi* delegator) {
+  impl_->core_ui_delegator_ = delegator;
+}
+
+void AppCoreUiBase::SetWindowDelegator(IWindow* delegator) {
+  impl_->handler_->SetWindow(delegator);
+}
+
+int AppCoreUiBase::Impl::InitWl() {
+  return wl_handler_->Init();
+}
+
+int AppCoreUiBase::Impl::FiniWl() {
+  wl_handler_->Fini();
+  return 0;
+}
+
+void AppCoreUiBase::Impl::ApplyBgState(bool bg_state) {
+  if (wl_handler_->Init() < 0)
+    return;
+
+  if (bg_state)
+    wl_handler_->SetBgState();
+  else
+    wl_handler_->UnsetBgState();
+
+  parent_->SetBgState(bg_state);
+}
+
+void AppCoreUiBase::Impl::SetAppId() {
+  if (wl_handler_->Init() < 0)
+    return;
+
+  wl_handler_->SetAppId(appid_);
+}
+
+void AppCoreUiBase::Impl::PluginInit(int argc, char** argv) {
+  plugin_.reset(AppCoreUiPlugin::Load());
+  if (plugin_ == nullptr)
+    return;
+
+  appcore_ui_base_ops ops;
+  ops.base.create = [](void* data) -> int {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    return base->OnCreate();
+  };
+
+  ops.base.control = [](bundle* b, void* data) -> int {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    return base->OnControl(tizen_base::Bundle(b));
+  };
+
+  ops.base.terminate = [](void* data) -> int {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    return base->OnTerminate();
+  };
+
+  ops.base.receive = [](aul_type type, bundle* b, void* data) -> int {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    return base->OnReceive(type, tizen_base::Bundle(b));
+  };
+
+  ops.base.set_i18n = [](void* data) -> int {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    return base->OnSetI18n();
+  };
+
+  ops.base.init = [](int argc, char** argv, void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnLoopInit(argc, argv);
+  };
+
+  ops.base.finish = [](void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnLoopFinish();
+  };
+
+  ops.base.run = [](void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnLoopRun();
+  };
+
+  ops.base.exit = [](void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnLoopExit();
+  };
+
+  ops.base.set_event = [](enum appcore_base_event event, void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnSetEvent(static_cast<IAppCore::IEvent::Type>(event));
+  };
+
+  ops.base.unset_event = [](enum appcore_base_event event, void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnUnsetEvent(static_cast<IAppCore::IEvent::Type>(event));
+  };
+
+  ops.base.trim_memory = [](void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnTrimMemory();
+  };
+
+  ops.pause = [](void* data) -> int {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    return base->OnPause();
+  };
+
+  ops.resume = [](void* data) -> int {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    return base->OnResume();
+  };
+
+  ops.window.show = [](int type, void* event, void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnShow(type, event);
+  };
+
+  ops.window.hide = [](int type, void* event, void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnHide(type, event);
+  };
+
+  ops.window.lower = [](int type, void* event, void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnLower(type, event);
+  };
+
+  ops.window.visibility = [](int type, void* event, void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnVisibility(type, event);
+  };
+
+  ops.window.pre_visibility = [](int type, void* event, void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnPreVisibility(type, event);
+  };
+
+  ops.window.aux_message = [](int type, void* event, void* data) {
+    auto* base = reinterpret_cast<AppCoreUiBase*>(data);
+    base->OnAuxMessage(type, event);
+  };
+
+  plugin_->Init(&ops, argc, argv, &hint_);
+  plugin_delegator_.reset(new AppCoreUiDelegator(ops, parent_));
+  parent_->SetCoreDelegator(plugin_delegator_.get());
+  parent_->SetLoopDelegator(plugin_delegator_.get());
+  parent_->SetCoreUiDelegator(plugin_delegator_.get());
+  parent_->SetWindowDelegator(plugin_delegator_.get());
+}
+
+void AppCoreUiBase::Impl::PluginFini() {
+  if (plugin_ == nullptr)
+    return;
+
+  plugin_->Fini();
+}
+
+void AppCoreUiBase::Run(int argc, char** argv) {
+  SetCoreDelegator(nullptr);
+  SetLoopDelegator(nullptr);
+  SetCoreUiDelegator(nullptr);
+  SetWindowDelegator(this);
+  impl_->plugin_delegator_.reset();
+  impl_->PluginInit(argc, argv);
+
+  char appid[PATH_MAX] = {0, };
+  int ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
+  if (ret != 0)
+    _E("Fail to get appid. pid(%d)", getpid());
+
+  impl_->handler_->Init();
+  impl_->state_ = Impl::AS_NONE;
+  impl_->w_status_ = Impl::WS_NONE;
+  impl_->appid_ = std::string(appid);
+  LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:main:done]", appid);
+  if (impl_->hint_ & HINT_BG_LAUNCH_CONTROL) {
+    tizen_base::Bundle b(bundle_import_from_argv(argc, argv), false, true);
+    if (!b.IsEmpty()) {
+      std::string bg_launch = b.GetString(AUL_SVC_K_BG_LAUNCH);
+      if (bg_launch.compare("enable") == 0)
+        impl_->ApplyBgState(true);
+    }
+  }
+
+  if (impl_->hint_ & HINT_WINDOW_ID_CONTROL)
+    impl_->SetAppId();
+
+  AppCoreBase::Run(argc, argv);
+}
+
+void AppCoreUiBase::Dispose() {
+  impl_->handler_->Fini();
+  impl_->FiniWl();
+
+  impl_->appid_.clear();
+
+  AppCoreBase::Dispose();
+  impl_->PluginFini();
+}
+
+void AppCoreUiBase::Impl::PrepareToSuspend() {
+  if (parent_->IsBgAllowed() && !parent_->IsSuspended()) {
+    SuspendedState suspend = SUSPENDED_STATE_WILL_ENTER_SUSPEND;
+    parent_->RaiseEvent(suspend, IEvent::Type::SUSPENDED_STATE_CHANGE);
+    parent_->ToggleSuspendedState();
+  }
+}
+
+void AppCoreUiBase::Impl::ExitFromSuspend() {
+  if (parent_->IsSuspended()) {
+    SuspendedState suspend = SUSPENDED_STATE_DID_EXIT_FROM_SUSPEND;
+    parent_->RaiseEvent(suspend, IEvent::Type::SUSPENDED_STATE_CHANGE);
+    parent_->ToggleSuspendedState();
+  }
+}
+
+void AppCoreUiBase::Impl::DoPause() {
+  if (state_ == AS_RUNNING) {
+    aul_app_lifecycle_update_state(AUL_APP_LIFECYCLE_STATE_PAUSED);
+    state_ = AS_PAUSED;
+    traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:PAUSE");
+    _D("Call pause callback");
+    int ret;
+    if (core_ui_delegator_)
+      ret = core_ui_delegator_->OnPause();
+    else
+      ret = parent_->OnPause();
+
+    traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+    if (ret >= 0 && resource_reclaiming_)
+      parent_->AddSuspendTimer();
+
+    PrepareToSuspend();
+  }
+
+  aul_status_update(STATUS_BG);
+}
+
+void AppCoreUiBase::Impl::DoResume() {
+  if (state_ == AS_PAUSED || state_ == AS_CREATED) {
+    aul_app_lifecycle_update_state(AUL_APP_LIFECYCLE_STATE_RESUMED);
+    ExitFromSuspend();
+    state_ = AS_RUNNING;
+    LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:start]", appid_.c_str());
+    traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:RESUME");
+    _D("Call resume callback");
+    parent_->RemoveSuspendTimer();
+    if (core_ui_delegator_)
+      core_ui_delegator_->OnResume();
+    else
+      parent_->OnResume();
+
+    traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+    LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:resume:done]", appid_.c_str());
+  }
+
+  aul_status_update(STATUS_VISIBLE);
+}
+
+void AppCoreUiBase::Impl::DoStart(tizen_base::Bundle b) {
+  if (parent_->GetHint() & HINT_WINDOW_STACK_CONTROL)
+    below_app_ = b.GetString(AUL_SVC_K_RELOCATE_BELOW);
+
+  if (first_launch_) {
+    first_launch_ = false;
+    return;
+  }
+
+  if (parent_->GetHint() & HINT_BG_LAUNCH_CONTROL) {
+    std::string bg_launch = b.GetString(AUL_SVC_K_BG_LAUNCH);
+    if (!bg_launch.empty() && bg_launch.compare("enable") == 0) {
+      if (!bg_state_ && state_ != AS_RUNNING)
+        ApplyBgState(true);
+    } else {
+      if (bg_state_)
+        ApplyBgState(false);
+    }
+  }
+
+  if (parent_->GetHint() & HINT_WINDOW_AUTO_CONTROL) {
+    if (!bg_state_) {
+      std::string rpc_port = b.GetString(AUL_K_RPC_PORT);
+      if (rpc_port.empty())
+        RaiseWin();
+    }
+  }
+}
+
+int AppCoreUiBase::Impl::IsLegacyLifecycle() {
+  static int is_legacy = -1;
+  if (__builtin_expect(is_legacy != -1, 1))
+    return is_legacy;
+
+  const char* api_version = getenv("TIZEN_API_VERSION");
+  if (api_version) {
+    if (strverscmp("2.4", api_version) > 0 &&
+        strverscmp("2.2.1", api_version) < 0)
+      is_legacy = 1;
+    else
+      is_legacy = 0;
+  } else {
+    is_legacy = 0;
+  }
+
+  return is_legacy;
+}
+
+int AppCoreUiBase::OnPause() {
+  return 0;
+}
+
+int AppCoreUiBase::OnResume() {
+  return 0;
+}
+
+int AppCoreUiBase::OnReceive(aul_type type, tizen_base::Bundle b) {
+  if (impl_->state_ == Impl::AS_DYING) {
+    _E("Skip the event in dying state");
+    return 0;
+  }
+
+  if ((type == AUL_TERMINATE_BGAPP || type == AUL_TERMINATE_BG_INST) &&
+      impl_->state_ != Impl::AS_PAUSED)
+    return 0;
+
+  if (type == AUL_START)
+    impl_->ExitFromSuspend();
+
+  AppCoreBase::OnReceive(type, b);
+
+  switch (type) {
+  case AUL_START:
+    impl_->DoStart(b);
+    if (GetHint() & HINT_LEGACY_CONTROL) {
+      if (impl_->bg_state_ && impl_->IsLegacyLifecycle()) {
+        _D("Legacy lifecycle");
+        impl_->DoResume();
+      }
+    }
+    break;
+  case AUL_RESUME:
+    if (impl_->bg_state_)
+      impl_->ApplyBgState(false);
+
+    impl_->RaiseWin();
+    break;
+  case AUL_TERMINATE:
+    if (impl_->state_ == Impl::AS_RUNNING) {
+      _D("Call pause callback");
+      if (impl_->core_ui_delegator_)
+        impl_->core_ui_delegator_->OnPause();
+      else
+        OnPause();
+    }
+    impl_->state_ = Impl::AS_DYING;
+    break;
+  case AUL_TERMINATE_BGAPP:
+  case AUL_TERMINATE_BG_INST:
+  case AUL_TERMINATE_INST:
+    _D("[APP %d] TERMINATE", getpid());
+    if (impl_->state_ == Impl::AS_RUNNING) {
+      _D("Call pause callback");
+      if (impl_->core_ui_delegator_)
+        impl_->core_ui_delegator_->OnPause();
+      else
+        OnPause();
+    }
+    impl_->state_ = Impl::AS_DYING;
+    aul_status_update(STATUS_DYING);
+    Exit();
+    break;
+  case AUL_PAUSE:
+    impl_->PauseWin();
+    break;
+  default:
+    break;
+  }
+
+  return 0;
+}
+
+int AppCoreUiBase::OnCreate() {
+  AppCoreBase::OnCreate();
+  impl_->state_ = Impl::AS_CREATED;
+  LOG(LOG_DEBUG, "LAUNCH", "[%s:Application:create:done]",
+      impl_->appid_.c_str());
+  return 0;
+}
+
+int AppCoreUiBase::OnTerminate() {
+  if (impl_->state_ == Impl::AS_RUNNING) {
+    _D("Call pause callback");
+    OnPause();
+  }
+
+  impl_->state_ = Impl::AS_DYING;
+  AppCoreBase::OnTerminate();
+  return 0;
+}
+
+int AppCoreUiBase::OnTrimMemory() {
+  return AppCoreBase::OnTrimMemory();
+}
+
+int AppCoreUiBase::GroupAdd() {
+  _D("Group attach");
+  static bool attached = false;
+  if (attached)
+    return 0;
+
+  int wid = GetMainSurface();
+  if (wid == 0) {
+    _E("window wasn't ready");
+    return -1;
+  }
+
+  int ret = aul_app_group_set_window(wid);
+  if (ret < 0) {
+    _E("Failed to set app group window. error(%d)", ret);
+    return ret;
+  }
+
+  attached = true;
+  return 0;
+}
+
+void AppCoreUiBase::GroupRemove() {
+  _D("Group lower");
+  int exit = 0;
+  aul_app_group_lower(&exit);
+  if (exit) {
+    _W("Sub App");
+    Exit();
+  }
+}
+
+void AppCoreUiBase::OnShow(int type, void* event) {
+  auto* ev = reinterpret_cast<Ecore_Wl2_Event_Window_Show*>(event);
+  if (ev->parent_win != 0)
+    return;
+
+  unsigned int win = static_cast<unsigned int>(ev->win);
+  unsigned int surf = static_cast<unsigned int>(ev->data[0]);
+  _D("[EVENT_TEST][EVENT] GET SHOW EVENT!!!. WIN: %u, %u", win, surf);
+
+  if (!impl_->FindWin(win))
+    impl_->AddWin(win, surf);
+  else
+    impl_->UpdateWin(win, surf, Impl::VT_NONE);
+
+  if (surf != 0)
+    GroupAdd();
+}
+
+bool AppCoreUiBase::Impl::CheckVisible() {
+  _D("[EVENT_TEST][EVENT] __check_visible");
+  for (auto& i : winnode_list_) {
+    _D("win : %u visibility : %d", i->win_, i->vis_);
+    if (i->vis_ == VT_UNOBSCURED)
+      return true;
+  }
+
+  return false;
+}
+
+void AppCoreUiBase::OnHide(int type, void* event) {
+  auto* ev = reinterpret_cast<Ecore_Wl2_Event_Window_Hide*>(event);
+  _D("[EVENT_TEST][EVENT] GET HIDE EVENT!!!. WIN :%d", ev->win);
+  if (impl_->FindWin((unsigned int)ev->win)) {
+    impl_->DeleteWin((unsigned int)ev->win);
+    bool bvisibility = impl_->CheckVisible();
+    if (!bvisibility && impl_->w_status_ != Impl::WS_PAUSE) {
+      _D("Go to Pasue state");
+      impl_->w_status_ = Impl::WS_PAUSE;
+      impl_->DoPause();
+    }
+  }
+}
+
+void AppCoreUiBase::OnLower(int type, void* event) {
+  auto* ev = reinterpret_cast<Ecore_Wl2_Event_Window_Lower*>(event);
+  if (!ev)
+    return;
+
+  _D("ECORE_WL2_EVENT_WINDOW_LOWER window id: %u", ev->win);
+  if (!(impl_->hint_ & HINT_WINDOW_GROUP_CONTROL))
+    return;
+
+  GroupRemove();
+}
+
+void AppCoreUiBase::OnVisibility(int type, void* event) {
+  auto* ev = reinterpret_cast<Ecore_Wl2_Event_Window_Visibility_Change*>(event);
+  impl_->UpdateWin((unsigned int)ev->win, 0,
+      ev->fully_obscured ? Impl::VT_FULLY_OBSCURED : Impl::VT_UNOBSCURED);
+  bool bvisibility = impl_->CheckVisible();
+  _D("bvisibility %d, w_status_ %d", bvisibility, impl_->w_status_);
+
+  if (bvisibility && (impl_->hint_ & HINT_WINDOW_STACK_CONTROL) &&
+      !impl_->below_app_.empty()) {
+    aul_app_group_activate_below(impl_->below_app_.c_str());
+    impl_->below_app_.clear();
+  }
+
+  if (bvisibility && impl_->w_status_ != Impl::WS_RESUME) {
+    _D("Go to Resume state");
+    impl_->w_status_ = Impl::WS_RESUME;
+    impl_->DoResume();
+  } else if (!bvisibility && impl_->w_status_ != Impl::WS_PAUSE) {
+    _D("Go to Pasue state");
+    impl_->w_status_ = Impl::WS_PAUSE;
+    impl_->DoPause();
+  } else {
+    _D("No change state");
+  }
+}
+
+void AppCoreUiBase::OnPreVisibility(int type, void* event) {
+  auto* ev = reinterpret_cast<Ecore_Wl2_Event_Window_Pre_Visibility_Change*>(
+      event);
+  if (ev && ev->type == ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED) {
+    impl_->UpdateWin((unsigned int)ev->win, 0, Impl::VT_UNOBSCURED);
+    bool bvisibility = impl_->CheckVisible();
+
+    _D("bvisibility %d, w_status_ %d", bvisibility, impl_->w_status_);
+    if (bvisibility && impl_->w_status_ != Impl::WS_RESUME) {
+      _D(" Go to Resume state");
+      impl_->w_status_ = Impl::WS_RESUME;
+      impl_->DoResume();
+    }
+  }
+}
+
+void AppCoreUiBase::OnAuxMessage(int type, void* event) {
+  auto* ev = reinterpret_cast<Ecore_Wl2_Event_Aux_Message*>(event);
+  if (ev->key && !strcmp(ev->key, "dpms_wm")) {
+    if (ev->val && !strcmp(ev->val, "on")) {
+      _D("Display state: on");
+      SetDisplayState(DISPLAY_STATE_ON);
+    } else if (ev->val && !strcmp(ev->val, "off")) {
+      _D("Display state: off");
+      SetDisplayState(DISPLAY_STATE_OFF);
+    } else {
+      _E("Unknown state: %s", ev->val);
+    }
+  }
+}
+
+void AppCoreUiBase::Pause() {
+  impl_->DoPause();
+}
+
+void AppCoreUiBase::Resume() {
+  impl_->DoResume();
+}
+
+bool AppCoreUiBase::IsResumed() {
+  return impl_->state_ == Impl::AS_RUNNING;
+}
+
+int AppCoreUiBase::GetHint() {
+  return impl_->hint_;
+}
+
+bool AppCoreUiBase::GetBgState() {
+  return impl_->bg_state_;
+}
+
+void AppCoreUiBase::SetBgState(bool bg_state) {
+  impl_->bg_state_ = bg_state;
+}
+
+void AppCoreUiBase::SetSystemResourceReclaiming(bool enable) {
+  impl_->resource_reclaiming_ = enable;
+}
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/app-core-ui-cpp/app_core_ui_base.hh b/tizen-cpp/app-core-ui-cpp/app_core_ui_base.hh
new file mode 100644 (file)
index 0000000..2d06eb9
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_APP_CORE_UI_CPP_APP_CORE_UI_BASE_HH_
+#define TIZEN_CPP_APP_CORE_UI_CPP_APP_CORE_UI_BASE_HH_
+
+#include <memory>
+
+#include <app_core_base.hh>
+#include <interface_app_core_ui.hh>
+#include <interface_window.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace tizen_cpp {
+
+class EXPORT_API AppCoreUiBase : public AppCoreBase,
+                                 public IAppCoreUi,
+                                 public IWindow {
+ public:
+  constexpr static int HINT_WINDOW_GROUP_CONTROL = 0x1;
+  constexpr static int HINT_WINDOW_STACK_CONTROL = 0x2;
+  constexpr static int HINT_BG_LAUNCH_CONTROL = 0x4;
+  constexpr static int HINT_HW_ACC_CONTROL = 0x8;
+  constexpr static int HINT_WINDOW_AUTO_CONTROL = 0x10;
+  constexpr static int HINT_LEGACY_CONTROL = 0x20;
+  constexpr static int HINT_WINDOW_ID_CONTROL = 0x40;
+
+  AppCoreUiBase(unsigned int hint);
+  virtual ~AppCoreUiBase();
+
+  int OnPause() override;
+  int OnResume() override;
+  int OnReceive(aul_type type, tizen_base::Bundle b) override;
+  int OnCreate() override;
+  int OnTerminate() override;
+  int OnTrimMemory() override;
+  void OnShow(int type, void* event) override;
+  void OnHide(int type, void* event) override;
+  void OnLower(int type, void* event) override;
+  void OnVisibility(int type, void* event) override;
+  void OnPreVisibility(int type, void* event) override;
+  void OnAuxMessage(int type, void* event) override;
+  void Pause();
+  void Resume();
+  bool IsResumed();
+  int GroupAdd();
+  void GroupRemove();
+  unsigned int GetMainWindow();
+  unsigned int GetMainSurface();
+  int GetHint();
+  bool GetBgState();
+  void SetBgState(bool bg_state);
+  void SetSystemResourceReclaiming(bool enable);
+  void Run(int argc, char** argv) override;
+  void Dispose() override;
+
+ protected:
+  void SetCoreUiDelegator(IAppCoreUi* delegator);
+  void SetWindowDelegator(IWindow* delegator);
+
+ private:
+  class Impl;
+  std::unique_ptr<Impl> impl_;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_UI_CPP_APP_CORE_UI_BASE_HH_
diff --git a/tizen-cpp/app-core-ui-cpp/app_core_ui_base_legacy.cc b/tizen-cpp/app-core-ui-cpp/app_core_ui_base_legacy.cc
new file mode 100644 (file)
index 0000000..1261323
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "app_core_ui_base.hh"
+#include "appcore_ui_base.h"
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__ ((visibility("default")))
+
+namespace tizen_cpp {
+
+namespace {
+
+class AppCoreUi : public AppCoreUiBase {
+ public:
+  AppCoreUi(unsigned int hint, appcore_ui_base_ops ops, void* data)
+      : AppCoreUiBase(hint), ops_(ops), data_(data) {}
+
+  void OnLoopInit(int argc, char** argv) override {
+    if (ops_.base.init)
+      ops_.base.init(argc, argv, data_);
+  }
+
+  void OnLoopFinish() override {
+    if (ops_.base.finish)
+      ops_.base.finish(data_);
+  }
+
+  void OnLoopRun() override {
+    if (ops_.base.run)
+      ops_.base.run(data_);
+  }
+
+  void OnLoopExit() override {
+    if (ops_.base.exit)
+      ops_.base.exit(data_);
+  }
+
+  int OnReceive(aul_type type, tizen_base::Bundle b) override {
+    if (ops_.base.receive)
+      return ops_.base.receive(type, b.GetHandle(), data_);
+    return -1;
+  }
+
+  int OnCreate() override {
+    if (ops_.base.create)
+      return ops_.base.create(data_);
+    return -1;
+  }
+
+  int OnControl(tizen_base::Bundle b) override {
+    if (ops_.base.control)
+      return ops_.base.control(b.GetHandle(), data_);
+    return -1;
+  }
+
+  int OnTerminate() override {
+    if (ops_.base.terminate)
+      return ops_.base.terminate(data_);
+    return -1;
+  }
+
+  int OnSetI18n() override {
+    if (ops_.base.set_i18n)
+      return ops_.base.set_i18n(data_);
+    return -1;
+  }
+
+  int OnSetEvent(IEvent::Type event) override {
+    if (!ops_.base.set_event)
+      return -1;
+
+    ops_.base.set_event((appcore_base_event)event, data_);
+    return 0;
+  }
+
+  int OnUnsetEvent(IEvent::Type event) override {
+    if (!ops_.base.unset_event)
+      return -1;
+
+    ops_.base.unset_event((appcore_base_event)event, data_);
+    return 0;
+  }
+
+  int OnTrimMemory() override {
+    if (!ops_.base.trim_memory)
+      return -1;
+
+    ops_.base.trim_memory(data_);
+    return 0;
+  }
+
+  int OnPause() override {
+    if (ops_.pause)
+      return ops_.pause(data_);
+    return -1;
+  }
+
+  int OnResume() override {
+    if (ops_.resume)
+      return ops_.resume(data_);
+    return -1;
+  }
+
+  void OnShow(int type, void* event) override {
+    if (ops_.window.show)
+      ops_.window.show(type, event, data_);
+  }
+
+  void OnHide(int type, void* event) override {
+    if (ops_.window.hide)
+      ops_.window.hide(type, event, data_);
+  }
+
+  void OnLower(int type, void* event) override {
+    if (ops_.window.lower)
+      ops_.window.lower(type, event, data_);
+  }
+
+  void OnVisibility(int type, void* event) override {
+    if (ops_.window.visibility)
+      ops_.window.visibility(type, event, data_);
+  }
+
+  void OnPreVisibility(int type, void* event) override {
+    if (ops_.window.pre_visibility)
+      ops_.window.pre_visibility(type, event, data_);
+  }
+
+  void OnAuxMessage(int type, void* event) override {
+    if (ops_.window.aux_message)
+      ops_.window.aux_message(type, event, data_);
+  }
+
+ private:
+  appcore_ui_base_ops ops_;
+  void* data_;
+};
+
+std::unique_ptr<AppCoreUi> __context;
+
+int __on_control(bundle* b, void* data) {
+  return appcore_ui_base_on_control(b);
+}
+
+int __on_set_i18n(void* data) {
+  return appcore_ui_base_on_set_i18n();
+}
+
+void __on_set_event(enum appcore_base_event event, void* data) {
+  appcore_ui_base_on_set_event(event);
+}
+
+void __on_unset_event(enum appcore_base_event event, void* data) {
+  appcore_ui_base_on_unset_event(event);
+}
+
+void __on_trim_memory(void* data) {
+  appcore_ui_base_on_trim_memory();
+}
+
+int __on_receive(aul_type type, bundle* b, void* data) {
+  return appcore_ui_base_on_receive(type, b);
+}
+
+int __on_create(void* data) {
+  return appcore_ui_base_on_create();
+}
+
+int __on_terminate(void* data) {
+  return appcore_ui_base_on_terminate();
+}
+
+int __on_pause(void* data) {
+  return appcore_ui_base_on_pause();
+}
+
+int __on_resume(void* data) {
+  return appcore_ui_base_on_resume();
+}
+
+void __window_on_show(int type, void* event, void* data) {
+  appcore_ui_base_window_on_show(type, event);
+}
+
+void __window_on_hide(int type, void* event, void* data) {
+  appcore_ui_base_window_on_hide(type, event);
+}
+
+void __window_on_lower(int type, void* event, void* data) {
+  appcore_ui_base_window_on_lower(type, event);
+}
+
+void __window_on_visibility(int type, void* event, void* data) {
+  appcore_ui_base_window_on_visibility(type, event);
+}
+
+void __window_on_pre_visibility(int type, void* event, void* data) {
+  appcore_ui_base_window_on_pre_visibility(type, event);
+}
+
+void __window_on_aux_message(int type, void* event, void* data) {
+  appcore_ui_base_window_on_aux_message(type, event);
+}
+
+}  // namespace
+}  // namespace tizen_cpp
+
+using namespace tizen_cpp;
+
+extern "C" EXPORT_API int appcore_ui_base_on_receive(aul_type type, bundle*b) {
+  if (__context.get() == nullptr)
+    return -1;
+  return __context->AppCoreUiBase::OnReceive(type, tizen_base::Bundle(b));
+}
+
+extern "C" EXPORT_API int appcore_ui_base_on_create(void) {
+  if (__context.get() == nullptr)
+    return -1;
+  return __context->AppCoreUiBase::OnCreate();
+}
+
+extern "C" EXPORT_API int appcore_ui_base_on_terminate(void) {
+  if (__context.get() == nullptr)
+    return -1;
+  return __context->AppCoreUiBase::OnTerminate();
+}
+
+extern "C" EXPORT_API int appcore_ui_base_on_pause(void) {
+  if (__context.get() == nullptr)
+    return -1;
+  return __context->AppCoreUiBase::OnPause();
+}
+
+extern "C" EXPORT_API int appcore_ui_base_on_resume(void) {
+  if (__context.get() == nullptr)
+    return -1;
+  return __context->AppCoreUiBase::OnResume();
+}
+
+extern "C" EXPORT_API int appcore_ui_base_on_control(bundle* b) {
+  if (__context.get() == nullptr)
+    return -1;
+  return __context->AppCoreUiBase::OnControl(
+      b ? tizen_base::Bundle(b) : tizen_base::Bundle());
+}
+
+extern "C" EXPORT_API int appcore_ui_base_on_trim_memory(void) {
+  if (__context.get() == nullptr)
+    return -1;
+  return __context->AppCoreUiBase::OnTrimMemory();
+}
+
+extern "C" EXPORT_API void appcore_ui_base_window_on_show(int type,
+    void* event) {
+  if (__context.get() == nullptr)
+    return;
+  __context->AppCoreUiBase::OnShow(type, event);
+}
+
+extern "C" EXPORT_API void appcore_ui_base_window_on_hide(int type,
+    void* event) {
+  if (__context.get() == nullptr)
+    return;
+  __context->AppCoreUiBase::OnHide(type, event);
+}
+
+extern "C" EXPORT_API void appcore_ui_base_window_on_lower(int type,
+    void* event) {
+  if (__context.get() == nullptr)
+    return;
+  __context->AppCoreUiBase::OnLower(type, event);
+}
+
+extern "C" EXPORT_API void appcore_ui_base_window_on_visibility(int type,
+    void* event) {
+  if (__context.get() == nullptr)
+    return;
+  __context->AppCoreUiBase::OnVisibility(type, event);
+}
+
+extern "C" EXPORT_API void appcore_ui_base_window_on_pre_visibility(int type,
+    void* event) {
+  if (__context.get() == nullptr)
+    return;
+  __context->AppCoreUiBase::OnPreVisibility(type, event);
+}
+
+extern "C" EXPORT_API void appcore_ui_base_window_on_aux_message(int type,
+    void* event) {
+  if (__context.get() == nullptr)
+    return;
+  __context->AppCoreUiBase::OnAuxMessage(type, event);
+}
+
+extern "C" EXPORT_API int appcore_ui_base_on_set_i18n(void) {
+  if (__context.get() == nullptr)
+    return -1;
+  return __context->AppCoreUiBase::OnSetI18n();
+}
+
+extern "C" EXPORT_API void appcore_ui_base_on_set_event(
+    enum appcore_base_event event) {
+  if (__context.get() == nullptr)
+    return;
+  __context->AppCoreUiBase::OnSetEvent(
+      static_cast<AppCoreBase::IEvent::Type>(event));
+}
+
+extern "C" EXPORT_API void appcore_ui_base_on_unset_event(
+    enum appcore_base_event event) {
+  if (__context.get() == nullptr)
+    return;
+  __context->AppCoreUiBase::OnUnsetEvent(
+      static_cast<AppCoreBase::IEvent::Type>(event));
+}
+
+extern "C" EXPORT_API int appcore_ui_base_init(appcore_ui_base_ops ops,
+    int argc, char** argv, void* data, unsigned int hint) {
+  __context.reset(new AppCoreUi(hint, ops, data));
+  try {
+    __context->Init(argc, argv);
+  } catch (const std::runtime_error&) {
+    return -1;
+  }
+
+  return 0;
+}
+
+extern "C" EXPORT_API void appcore_ui_base_fini(void) {
+  if (__context.get() == nullptr)
+    return;
+  __context->Fini();
+  __context.reset();
+}
+
+extern "C" EXPORT_API appcore_ui_base_ops
+appcore_ui_base_get_default_ops(void) {
+  appcore_ui_base_ops ops;
+
+  ops.base.create = __on_create;
+  ops.base.control = __on_control;
+  ops.base.terminate = __on_terminate;
+  ops.base.receive = __on_receive;
+  ops.base.set_i18n = __on_set_i18n;
+  ops.base.init = nullptr;
+  ops.base.finish = nullptr;
+  ops.base.run = nullptr;
+  ops.base.exit = nullptr;
+  ops.base.set_event = __on_set_event;
+  ops.base.unset_event = __on_unset_event;
+  ops.base. trim_memory = __on_trim_memory;
+  ops.pause = __on_pause;
+  ops.resume = __on_resume;
+  ops.window.show = __window_on_show;
+  ops.window.hide = __window_on_hide;
+  ops.window.lower = __window_on_lower;
+  ops.window.visibility = __window_on_visibility;
+  ops.window.pre_visibility = __window_on_pre_visibility;
+  ops.window.aux_message = __window_on_aux_message;
+
+  return ops;
+}
+
+extern "C" EXPORT_API void appcore_ui_base_pause(void) {
+  if (__context.get() == nullptr)
+    return;
+  __context->Pause();
+}
+
+extern "C" EXPORT_API void appcore_ui_base_resume(void) {
+  if (__context.get() == nullptr)
+    return;
+  __context->Resume();
+}
+
+extern "C" EXPORT_API bool appcore_ui_base_is_resumed(void) {
+  if (__context.get() == nullptr)
+    return false;
+  return __context->IsResumed();
+}
+
+extern "C" EXPORT_API void appcore_ui_base_exit(void) {
+  if (__context.get() == nullptr)
+    return;
+  __context->Exit();
+}
+
+extern "C" EXPORT_API int appcore_ui_base_group_add() {
+  if (__context.get() == nullptr)
+    return -1;
+  return __context->GroupAdd();
+}
+
+extern "C" EXPORT_API void appcore_ui_base_group_remove() {
+  if (__context.get() == nullptr)
+    return;
+  __context->GroupRemove();
+}
+
+extern "C" EXPORT_API unsigned int appcore_ui_base_get_main_window(void) {
+  if (__context.get() == nullptr)
+    return 0;
+  return __context->GetMainWindow();
+}
+
+extern "C" EXPORT_API unsigned int appcore_ui_base_get_main_surface(void) {
+  if (__context.get() == nullptr)
+    return 0;
+  return __context->GetMainSurface();
+}
+
+extern "C" EXPORT_API int appcore_ui_base_get_hint(void) {
+  if (__context.get() == nullptr)
+    return 0;
+  return __context->GetHint();
+}
+
+extern "C" EXPORT_API bool appcore_ui_base_get_bg_state(void) {
+  if (__context.get() == nullptr)
+    return false;
+  return __context->GetBgState();
+}
+
+extern "C" EXPORT_API void appcore_ui_base_set_bg_state(bool bg_state) {
+  if (__context.get() == nullptr)
+    return;
+  __context->SetBgState(bg_state);
+}
+
+extern "C" EXPORT_API void appcore_ui_base_set_system_resource_reclaiming(
+    bool enable) {
+  if (__context.get() == nullptr)
+    return;
+  __context->SetSystemResourceReclaiming(enable);
+}
diff --git a/tizen-cpp/app-core-ui-cpp/app_core_ui_delegator_private.cc b/tizen-cpp/app-core-ui-cpp/app_core_ui_delegator_private.cc
new file mode 100644 (file)
index 0000000..335676b
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "app-core-ui-cpp/app_core_ui_delegator_private.hh"
+
+namespace tizen_cpp {
+
+AppCoreUiDelegator::AppCoreUiDelegator(appcore_ui_base_ops ops,
+    AppCoreUiBase* base)
+    : ops_(ops), base_(base) {
+}
+
+int AppCoreUiDelegator::OnReceive(aul_type type, tizen_base::Bundle b) {
+  if (ops_.base.receive)
+    return ops_.base.receive(type, b.GetHandle(), base_);
+  return -1;
+}
+
+int AppCoreUiDelegator::OnCreate() {
+  if (ops_.base.create)
+    return ops_.base.create(base_);
+  return -1;
+}
+
+int AppCoreUiDelegator::OnControl(tizen_base::Bundle b) {
+  if (ops_.base.control)
+    return ops_.base.control(b.GetHandle(), base_);
+  return -1;
+}
+
+int AppCoreUiDelegator::OnTerminate() {
+  if (ops_.base.terminate)
+    return ops_.base.terminate(base_);
+  return -1;
+}
+
+int AppCoreUiDelegator::OnSetI18n() {
+  if (ops_.base.set_i18n)
+    return ops_.base.set_i18n(base_);
+  return -1;
+}
+
+int AppCoreUiDelegator::OnSetEvent(IEvent::Type event) {
+  if (ops_.base.set_event)
+    ops_.base.set_event(static_cast<appcore_base_event>(event), base_);
+  return 0;
+}
+
+int AppCoreUiDelegator::OnUnsetEvent(IEvent::Type event) {
+  if (ops_.base.unset_event)
+    ops_.base.unset_event(static_cast<appcore_base_event>(event), base_);
+  return 0;
+}
+
+int AppCoreUiDelegator::OnTrimMemory() {
+  if (ops_.base.trim_memory)
+    ops_.base.trim_memory(base_);
+  return 0;
+}
+
+void AppCoreUiDelegator::OnLoopInit(int argc, char** argv) {
+  if (ops_.base.init)
+    ops_.base.init(argc, argv, base_);
+}
+
+void AppCoreUiDelegator::OnLoopFinish() {
+  if (ops_.base.finish)
+    ops_.base.finish(base_);
+}
+
+void AppCoreUiDelegator::OnLoopRun() {
+  if (ops_.base.run)
+    ops_.base.run(base_);
+}
+
+void AppCoreUiDelegator::OnLoopExit() {
+  if (ops_.base.exit)
+    ops_.base.exit(base_);
+}
+
+int AppCoreUiDelegator::OnPause() {
+  if (ops_.pause)
+    return ops_.pause(base_);
+  return -1;
+}
+
+int AppCoreUiDelegator::OnResume() {
+  if (ops_.resume)
+    return ops_.resume(base_);
+  return -1;
+}
+
+void AppCoreUiDelegator::OnShow(int type, void* event) {
+  if (ops_.window.show)
+    ops_.window.show(type, event, base_);
+}
+
+void AppCoreUiDelegator::OnHide(int type, void* event) {
+  if (ops_.window.hide)
+    ops_.window.hide(type, event, base_);
+}
+
+void AppCoreUiDelegator::OnLower(int type, void* event) {
+  if (ops_.window.lower)
+    ops_.window.lower(type, event, base_);
+}
+
+void AppCoreUiDelegator::OnVisibility(int type, void* event) {
+  if (ops_.window.visibility)
+    ops_.window.visibility(type, event, base_);
+}
+
+void AppCoreUiDelegator::OnPreVisibility(int type, void* event) {
+  if (ops_.window.pre_visibility)
+    ops_.window.pre_visibility(type, event, base_);
+}
+
+void AppCoreUiDelegator::OnAuxMessage(int type, void* event) {
+  if (ops_.window.aux_message)
+    ops_.window.aux_message(type, event, base_);
+}
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/app-core-ui-cpp/app_core_ui_delegator_private.hh b/tizen-cpp/app-core-ui-cpp/app_core_ui_delegator_private.hh
new file mode 100644 (file)
index 0000000..6b6dd4f
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_APP_CORE_UI_CPP_APP_CORE_UI_DELEGATOR_PRIVATE_HH_
+#define TIZEN_CPP_APP_CORE_UI_CPP_APP_CORE_UI_DELEGATOR_PRIVATE_HH_
+
+#include "app-core-ui-cpp/app_core_ui_base.hh"
+#include "app-core-ui-cpp/appcore_ui_base.h"
+
+namespace tizen_cpp {
+
+class AppCoreUiDelegator : public IAppCore,
+                           public IMainLoop,
+                           public IAppCoreUi,
+                           public IWindow {
+ public:
+  AppCoreUiDelegator(appcore_ui_base_ops ops, AppCoreUiBase* base);
+
+  int OnReceive(aul_type type, tizen_base::Bundle b) override;
+  int OnCreate();
+  int OnControl(tizen_base::Bundle b);
+  int OnTerminate();
+  int OnSetI18n();
+  int OnSetEvent(IEvent::Type event);
+  int OnUnsetEvent(IEvent::Type event);
+  int OnTrimMemory();
+  void OnLoopInit(int argc, char** argv);
+  void OnLoopFinish();
+  void OnLoopRun();
+  void OnLoopExit();
+  int OnPause();
+  int OnResume();
+  void OnShow(int type, void* event);
+  void OnHide(int type, void* event);
+  void OnLower(int type, void* event);
+  void OnVisibility(int type, void* event);
+  void OnPreVisibility(int type, void* event);
+  void OnAuxMessage(int type, void* event);
+
+ private:
+  appcore_ui_base_ops ops_;
+  AppCoreUiBase* base_;
+};
+
+} // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_UI_CPP_APP_CORE_UI_DELEGATOR_PRIVATE_HH_
diff --git a/tizen-cpp/app-core-ui-cpp/app_core_ui_plugin_private.cc b/tizen-cpp/app-core-ui-cpp/app_core_ui_plugin_private.cc
new file mode 100644 (file)
index 0000000..71b01e9
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <new>
+
+#include "app-core-ui-cpp/app_core_ui_plugin_private.hh"
+#include "app-core-ui-cpp/appcore_ui_base.h"
+#include "common/log_private.hh"
+
+namespace tizen_cpp {
+
+namespace {
+
+constexpr const char kPathLibAppCoreUiPlugin[] =
+    "/usr/share/appcore/plugins/libappcore-ui-plugin.so";
+constexpr const char kAppCoreUiPluginInit[] = "APPCORE_UI_PLUGIN_INIT";
+constexpr const char kAppCoreUiPluginFini[] = "APPCORE_UI_PLUGIN_FINI";
+
+}  // namespace
+
+AppCoreUiPlugin::AppCoreUiPlugin(void* handle, PluginInitFunc init_func,
+    PluginFiniFunc fini_func)
+    : handle_(handle), init_func_(init_func), fini_func_(fini_func) {
+}
+
+AppCoreUiPlugin::~AppCoreUiPlugin() {
+  if (handle_)
+    dlclose(handle_);
+}
+
+AppCoreUiPlugin* AppCoreUiPlugin::Load() {
+  if (access(kPathLibAppCoreUiPlugin, F_OK) != 0)
+    return nullptr;
+
+  void* handle = dlopen(kPathLibAppCoreUiPlugin, RTLD_LAZY);
+  if (handle == nullptr) {
+    _E("dlopen() is failed. path(%s)", kPathLibAppCoreUiPlugin);
+    return nullptr;
+  }
+
+  auto init_func = reinterpret_cast<PluginInitFunc>(
+      dlsym(handle, kAppCoreUiPluginInit));
+  if (init_func == nullptr)
+    _W("dlsym() is failed. symbol(%s)", kAppCoreUiPluginInit);
+
+  auto fini_func = reinterpret_cast<PluginFiniFunc>(
+      dlsym(handle, kAppCoreUiPluginFini));
+  if (fini_func == nullptr)
+    _W("dlsym() is failed. symbol(%s)", kAppCoreUiPluginFini);
+
+  return new (std::nothrow) AppCoreUiPlugin(handle, init_func, fini_func);
+}
+
+void AppCoreUiPlugin::Init(appcore_ui_base_ops* ops, int argc, char** argv,
+    unsigned int* hint) {
+  _I("[__PLUGIN__] INIT");
+  if (init_func_ == nullptr)
+    return;
+
+  init_func_(ops, argc, argv, hint);
+}
+
+void AppCoreUiPlugin::Fini() {
+  _I("[__PLUGIN__] FINI");
+  if (fini_func_ == nullptr)
+    return;
+
+  fini_func_();
+}
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/app-core-ui-cpp/app_core_ui_plugin_private.hh b/tizen-cpp/app-core-ui-cpp/app_core_ui_plugin_private.hh
new file mode 100644 (file)
index 0000000..77e8ce7
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_APP_CORE_UI_CPP_APP_CORE_UI_PLUGIN_PRIVATE_HH_
+#define TIZEN_CPP_APP_CORE_UI_CPP_APP_CORE_UI_PLUGIN_PRIVATE_HH_
+
+#include "appcore_ui_base.h"
+
+namespace tizen_cpp {
+
+class AppCoreUiPlugin {
+ public:
+  using PluginInitFunc =
+      int (*)(appcore_ui_base_ops*, int, char**, unsigned int*);
+  using PluginFiniFunc = int (*)(void);
+
+  AppCoreUiPlugin(void* handle, PluginInitFunc init_func,
+      PluginFiniFunc fini_func);
+  ~AppCoreUiPlugin();
+
+  static AppCoreUiPlugin* Load();
+
+  void Init(appcore_ui_base_ops* ops, int argc, char** argv,
+      unsigned int* hint);
+  void Fini();
+
+ private:
+  void* handle_ = nullptr;
+  PluginInitFunc init_func_ = nullptr;
+  PluginFiniFunc fini_func_ = nullptr;
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_UI_CPP_APP_CORE_UI_PLUGIN_PRIVATE_HH_
diff --git a/tizen-cpp/app-core-ui-cpp/appcore_ui_base.h b/tizen-cpp/app-core-ui-cpp/appcore_ui_base.h
new file mode 100644 (file)
index 0000000..671b440
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2021 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 TIZEN_CPP_APP_CORE_UI_BASE_H_
+#define TIZEN_CPP_APP_CORE_UI_BASE_H_
+
+#include <libintl.h>
+#include <bundle.h>
+#include <aul.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum appcore_base_event {
+       APPCORE_BASE_EVENT_START,
+       APPCORE_BASE_EVENT_LOW_MEMORY,
+       APPCORE_BASE_EVENT_LOW_BATTERY,
+       APPCORE_BASE_EVENT_LANG_CHANGE,
+       APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED,
+       APPCORE_BASE_EVENT_REGION_CHANGE,
+       APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE,
+       APPCORE_BASE_EVENT_UPDATE_REQUESTED,
+       APPCORE_BASE_EVENT_MAX,
+};
+
+typedef struct _appcore_base_ops {
+       int (*create) (void *data);
+       int (*terminate) (void *data);
+       int (*control) (bundle *b, void *data);
+       int (*receive)(aul_type type, bundle *b, void *data);
+       int (*set_i18n)(void *data);
+       void (*init)(int argc, char **argv, void *data);
+       void (*finish)(void* data);
+       void (*run)(void *data);
+       void (*exit)(void *data);
+       void (*set_event)(enum appcore_base_event event, void *data);
+       void (*unset_event)(enum appcore_base_event event, void *data);
+       void (*trim_memory)(void *data);
+} appcore_base_ops;
+
+typedef struct _appcore_ui_base_window_ops {
+       void (*show)(int type, void *event, void *data);
+       void (*hide)(int type, void *event, void *data);
+       void (*lower)(int type, void *event, void *data);
+       void (*visibility)(int type, void *event, void *data);
+       void (*pre_visibility)(int type, void *event, void *data);
+       void (*aux_message)(int type, void *event, void *data);
+} appcore_ui_base_window_ops;
+
+typedef struct _appcore_ui_base_ops {
+       int (*pause) (void *data);
+       int (*resume) (void *data);
+       appcore_base_ops base;
+       appcore_ui_base_window_ops window;
+} appcore_ui_base_ops;
+
+enum appcore_ui_base_hint {
+       APPCORE_UI_BASE_HINT_WINDOW_GROUP_CONTROL = 0x1,
+       APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL = 0x2,
+       APPCORE_UI_BASE_HINT_BG_LAUNCH_CONTROL = 0x4,
+       APPCORE_UI_BASE_HINT_HW_ACC_CONTROL = 0x8,
+       APPCORE_UI_BASE_HINT_WINDOW_AUTO_CONTROL = 0x10,
+       APPCORE_UI_BASE_HINT_LEGACY_CONTROL = 0x20,
+       APPCORE_UI_BASE_HINT_WINDOW_ID_CONTROL = 0x40,
+};
+
+int appcore_ui_base_on_receive(aul_type type, bundle *b);
+int appcore_ui_base_on_create(void);
+int appcore_ui_base_on_terminate(void);
+int appcore_ui_base_on_pause(void);
+int appcore_ui_base_on_resume(void);
+int appcore_ui_base_on_control(bundle *b);
+int appcore_ui_base_on_trim_memory(void);
+void appcore_ui_base_window_on_show(int type, void *event);
+void appcore_ui_base_window_on_hide(int type, void *event);
+void appcore_ui_base_window_on_lower(int type, void *event);
+void appcore_ui_base_window_on_visibility(int type, void *event);
+void appcore_ui_base_window_on_pre_visibility(int type, void *event);
+void appcore_ui_base_window_on_aux_message(int type, void *event);
+int appcore_ui_base_on_set_i18n(void);
+void appcore_ui_base_on_set_event(enum appcore_base_event event);
+void appcore_ui_base_on_unset_event(enum appcore_base_event event);
+int appcore_ui_base_init(appcore_ui_base_ops ops, int argc, char **argv,
+               void *data, unsigned int hint);
+void appcore_ui_base_fini(void);
+appcore_ui_base_ops appcore_ui_base_get_default_ops(void);
+void appcore_ui_base_pause(void);
+void appcore_ui_base_resume(void);
+bool appcore_ui_base_is_resumed(void);
+void appcore_ui_base_exit(void);
+int appcore_ui_base_group_add();
+void appcore_ui_base_group_remove();
+unsigned int appcore_ui_base_get_main_window(void);
+unsigned int appcore_ui_base_get_main_surface(void);
+int appcore_ui_base_get_hint(void);
+bool appcore_ui_base_get_bg_state(void);
+void appcore_ui_base_set_bg_state(bool bg_state);
+void appcore_ui_base_set_system_resource_reclaiming(bool enable);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // TIZEN_CPP_APP_CORE_UI_BASE_H_
diff --git a/tizen-cpp/app-core-ui-cpp/wayland_handler_private.cc b/tizen-cpp/app-core-ui-cpp/wayland_handler_private.cc
new file mode 100644 (file)
index 0000000..7eb953f
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <unistd.h>
+
+#include "app-core-ui-cpp/wayland_handler_private.hh"
+#include "common/log_private.hh"
+
+namespace tizen_cpp {
+
+WaylandHandler::WaylandHandler() {
+}
+
+WaylandHandler::~WaylandHandler() {
+  Fini();
+}
+
+int WaylandHandler::Init() {
+  _D("INIT");
+  if (__builtin_expect(initialized_, 1))
+    return 0;
+
+  dsp_ = wl_display_connect(nullptr);
+  if (dsp_ == nullptr) {
+    _E("wl_display_connect() is failed");
+    return -1;
+  }
+
+  reg_ = wl_display_get_registry(dsp_);
+  if (reg_ == nullptr) {
+    _E("wl_display_get_registry() is failed");
+    Fini();
+    return -1;
+  }
+
+  wl_registry_add_listener(reg_, &reg_listener_, this);
+  wl_display_roundtrip(dsp_);
+
+  if (tz_policy_ == nullptr) {
+    _E("Failed to get tizen policy interface");
+    Fini();
+    return -1;
+  }
+
+  initialized_ = true;
+  return 0;
+}
+
+void WaylandHandler::Fini() {
+  if (!initialized_)
+    return;
+
+  if (tz_policy_) {
+    tizen_policy_destroy(tz_policy_);
+    tz_policy_ = nullptr;
+  }
+
+  if (reg_) {
+    wl_registry_destroy(reg_);
+    reg_ = nullptr;
+  }
+
+  if (dsp_) {
+    wl_display_disconnect(dsp_);
+    dsp_ = nullptr;
+  }
+
+  initialized_ = false;
+}
+
+void WaylandHandler::SetBgState() {
+  if (!initialized_)
+    return;
+
+  tizen_policy_set_background_state(tz_policy_, getpid());
+  wl_display_roundtrip(dsp_);
+  _D("Set Background State");
+}
+
+void WaylandHandler::UnsetBgState() {
+  if (!initialized_)
+    return;
+
+  tizen_policy_unset_background_state(tz_policy_, getpid());
+  wl_display_roundtrip(dsp_);
+  _D("Unset Background State");
+}
+
+void WaylandHandler::SetAppId(const std::string& app_id) {
+  if (!initialized_)
+    return;
+
+  tizen_policy_set_appid(tz_policy_, getpid(), app_id.c_str());
+  wl_display_roundtrip(dsp_);
+  _D("Set AppId: %s", app_id.c_str());
+}
+
+void WaylandHandler::WlListenerCb(void* data, struct wl_registry* reg,
+    uint32_t id, const char* interface, uint32_t ver) {
+  if (interface && !strcmp(interface, "tizen_policy")) {
+    auto* handle = static_cast<WaylandHandler*>(data);
+    if (handle->tz_policy_ == nullptr) {
+      handle->tz_policy_ = reinterpret_cast<struct tizen_policy*>(
+          wl_registry_bind(reinterpret_cast<struct wl_registry*>(handle->reg_),
+            id, &tizen_policy_interface, 7));
+    }
+  }
+}
+
+void WaylandHandler::WlListenerRemoveCb(void* data, struct wl_registry* reg,
+    unsigned int id) {
+}
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/app-core-ui-cpp/wayland_handler_private.hh b/tizen-cpp/app-core-ui-cpp/wayland_handler_private.hh
new file mode 100644 (file)
index 0000000..16dbe67
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_APP_CORE_UI_CPP_WAYLAND_HANDLER_PRIVATE_HH_
+#define TIZEN_CPP_APP_CORE_UI_CPP_WAYLAND_HANDLER_PRIVATE_HH_
+
+#include <tizen-extension-client-protocol.h>
+#include <wayland-client.h>
+#include <wayland-tbm-client.h>
+
+#include <string>
+
+namespace tizen_cpp {
+
+class WaylandHandler {
+ public:
+  WaylandHandler();
+  ~WaylandHandler();
+
+  int Init();
+  void Fini();
+  void SetBgState();
+  void UnsetBgState();
+  void SetAppId(const std::string& app_id);
+
+ private:
+  static void WlListenerCb(void* data, struct wl_registry* reg,
+      uint32_t id, const char* interface, uint32_t ver);
+  static void WlListenerRemoveCb(void* data, struct wl_registry* reg,
+      unsigned int id);
+
+ private:
+  bool initialized_ = false;
+  struct wl_display* dsp_ = nullptr;
+  struct wl_registry* reg_ = nullptr;
+  struct tizen_policy* tz_policy_ = nullptr;
+
+  const struct wl_registry_listener reg_listener_ = {
+    WlListenerCb,
+    WlListenerRemoveCb
+  };
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_UI_CPP_WAYLAND_HANDLER_PRIVATE_HH_
diff --git a/tizen-cpp/common/ecore_handler.cc b/tizen-cpp/common/ecore_handler.cc
new file mode 100644 (file)
index 0000000..ace58b1
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <ttrace.h>
+
+#include <stdexcept>
+
+#include "common/log_private.hh"
+#include "common/ecore_handler.hh"
+
+namespace tizen_cpp {
+
+gboolean EcoreHandler::FlushMemoryCb(gpointer data) {
+  _D("Flush memory");
+  EcoreHandler* base = reinterpret_cast<EcoreHandler*>(data);
+  base->GetTrim()->OnTrim();
+  base->flush_timer_ = 0;
+  return G_SOURCE_REMOVE;
+}
+
+void EcoreHandler::AddFlushTimer() {
+  if (flush_timer_ != 0)
+    return;
+
+  flush_timer_ = g_timeout_add(5000, FlushMemoryCb, this);
+}
+
+void EcoreHandler::RemoveFlushTimer() {
+  if (flush_timer_ == 0)
+    return;
+
+  g_source_remove(flush_timer_);
+  flush_timer_ = 0;
+}
+
+Eina_Bool EcoreHandler::StubShowCb(void* data, int type, void* event) {
+  EcoreHandler* base = reinterpret_cast<EcoreHandler*>(data);
+  base->GetWindow()->OnShow(type, event);
+  return ECORE_CALLBACK_RENEW;
+}
+
+Eina_Bool EcoreHandler::StubHideCb(void* data, int type, void* event) {
+  EcoreHandler* base = reinterpret_cast<EcoreHandler*>(data);
+  base->GetWindow()->OnHide(type, event);
+  return ECORE_CALLBACK_RENEW;
+}
+
+Eina_Bool EcoreHandler::StubVisibilityCb(void* data, int type, void* event) {
+  auto* ev = reinterpret_cast<Ecore_Wl2_Event_Window_Visibility_Change*>(event);
+  EcoreHandler* base = reinterpret_cast<EcoreHandler*>(data);
+  base->GetWindow()->OnVisibility(type, event);
+
+  if (!base->GetTrim())
+    return ECORE_CALLBACK_RENEW;
+
+  if (ev && ev->fully_obscured) {
+    if (base->GetTrim()->IsTrimmable())
+      base->AddFlushTimer();
+  } else {
+    base->RemoveFlushTimer();
+  }
+
+  return ECORE_CALLBACK_RENEW;
+}
+
+Eina_Bool EcoreHandler::StubLowerCb(void* data, int type, void* event) {
+  EcoreHandler* base = reinterpret_cast<EcoreHandler*>(data);
+  base->GetWindow()->OnLower(type, event);
+  return ECORE_CALLBACK_RENEW;
+}
+
+Eina_Bool EcoreHandler::StubPreVisibilityCb(void* data, int type, void* event) {
+  auto* ev = reinterpret_cast<Ecore_Wl2_Event_Window_Pre_Visibility_Change*>(
+      event);
+  EcoreHandler* base = reinterpret_cast<EcoreHandler*>(data);
+  base->GetWindow()->OnPreVisibility(type, event);
+
+  if (!base->GetTrim())
+    return ECORE_CALLBACK_RENEW;
+
+  if (ev && ev->type == ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED)
+    base->RemoveFlushTimer();
+
+  return ECORE_CALLBACK_RENEW;
+}
+
+Eina_Bool EcoreHandler::StubAuxMessageCb(void* data, int type, void* event) {
+  EcoreHandler* base = reinterpret_cast<EcoreHandler*>(data);
+  base->GetWindow()->OnAuxMessage(type, event);
+  return ECORE_CALLBACK_RENEW;
+}
+
+void EcoreHandler::Init() {
+  if (initialized_)
+    return;
+
+  traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:ECORE_WL2_INIT");
+  if (!ecore_wl2_init()) {
+    _E("Failed to initialize Ecore Wayland2");
+    throw std::runtime_error("could not init wl2");
+  }
+  traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+
+  traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "APPCORE:DISPLAY_CONNECT");
+  ecore_wl2_display_connect(nullptr);
+  traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
+
+  hshow_ = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_SHOW,
+      StubShowCb, this);
+  if (hshow_ == nullptr)
+    _E("Failed to add ECORE_WL_EVENT_WINDOW_SHOW event");
+
+  hhide_ = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_HIDE,
+      StubHideCb, this);
+  if (hhide_ == nullptr)
+    _E("Failed to add ECORE_WL_EVENT_WINDOW_HIDE event");
+
+  hvchange_ = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE,
+      StubVisibilityCb, this);
+  if (hvchange_ == nullptr)
+    _E("Failed to add ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE event");
+
+  hlower_ = ecore_event_handler_add(ECORE_WL2_EVENT_WINDOW_LOWER,
+      StubLowerCb, this);
+  if (hlower_ == nullptr)
+    _E("Failed to add ECORE_WL_EVENT_WINDOW_LOWER event");
+
+  hpvchange_ = ecore_event_handler_add(
+      ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE, StubPreVisibilityCb, this);
+  if (hpvchange_ == nullptr)
+    _E("Failed to add ECORE_WL_EVENT_WINDOW_PRE_VISIBILITY_CHANGE event");
+
+  hauxmsg_ = ecore_event_handler_add(ECORE_WL2_EVENT_AUX_MESSAGE,
+      StubAuxMessageCb, this);
+  if (hauxmsg_ == nullptr)
+    _E("Failed to add ECORE_WL2_EVENT_AUX_MESSAGE event");
+
+  initialized_ = true;
+}
+
+void EcoreHandler::Fini() {
+  if (!initialized_)
+    return;
+
+  RemoveFlushTimer();
+
+  if (hshow_) {
+    ecore_event_handler_del(hshow_);
+    hshow_ = nullptr;
+  }
+
+  if (hhide_) {
+    ecore_event_handler_del(hhide_);
+    hhide_ = nullptr;
+  }
+
+  if (hvchange_) {
+    ecore_event_handler_del(hvchange_);
+    hvchange_ = nullptr;
+  }
+
+  if (hlower_) {
+    ecore_event_handler_del(hlower_);
+    hlower_ = nullptr;
+  }
+
+  if (hpvchange_) {
+    ecore_event_handler_del(hpvchange_);
+    hpvchange_ = nullptr;
+  }
+
+  if (hauxmsg_) {
+    ecore_event_handler_del(hauxmsg_);
+    hauxmsg_ = nullptr;
+  }
+
+  _E("Disconnect Wayland display");
+  ecore_wl2_display_disconnect(ecore_wl2_connected_display_get(nullptr));
+  ecore_wl2_shutdown();
+  initialized_ = false;
+}
+
+void EcoreHandler::RaiseWin(unsigned int win_id) {
+  auto* win = ecore_wl2_display_window_find(
+      ecore_wl2_connected_display_get(nullptr), win_id);
+  ecore_wl2_window_activate(win);
+}
+
+void EcoreHandler::PauseWin(unsigned int win_id) {
+  auto* win = ecore_wl2_display_window_find(
+      ecore_wl2_connected_display_get(nullptr), win_id);
+  ecore_wl2_window_iconified_set(win, EINA_TRUE);
+}
+
+EcoreHandler::EcoreHandler(IWindow* win) : window_(win) {
+}
+
+EcoreHandler::EcoreHandler(IWindow* win, ITrim* trim)
+    : trim_(trim), window_(win) {
+}
+
+EcoreHandler::~EcoreHandler() {
+  Fini();
+}
+
+EcoreHandler::ITrim* EcoreHandler::GetTrim() {
+  return trim_;
+}
+
+IWindow* EcoreHandler::GetWindow() {
+  return window_;
+}
+
+void EcoreHandler::SetWindow(IWindow* win) {
+  window_ = win;
+}
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/common/ecore_handler.hh b/tizen-cpp/common/ecore_handler.hh
new file mode 100644 (file)
index 0000000..04e641d
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_COMMON_ECORE_HANDLER_HH_
+#define TIZEN_CPP_COMMON_ECORE_HANDLER_HH_
+
+#include <Ecore_Wl2.h>
+#include <glib.h>
+
+#include "app-core-cpp/interface_window.hh"
+
+namespace tizen_cpp {
+
+class EcoreHandler {
+ public:
+  class ITrim {
+   public:
+    virtual ~ITrim() = default;
+    virtual bool IsTrimmable() = 0;
+    virtual void OnTrim() = 0;
+  };
+
+  EcoreHandler(IWindow* win);
+  EcoreHandler(IWindow* win, ITrim* trim);
+  ~EcoreHandler();
+
+  void Init();
+  void Fini();
+  void RaiseWin(unsigned int win_id);
+  void PauseWin(unsigned int win_id);
+  ITrim* GetTrim();
+  IWindow* GetWindow();
+  void SetWindow(IWindow* win);
+
+ private:
+  EcoreHandler();
+  void AddFlushTimer();
+  void RemoveFlushTimer();
+
+  static gboolean FlushMemoryCb(gpointer data);
+  static Eina_Bool StubShowCb(void* data, int type, void* event);
+  static Eina_Bool StubHideCb(void* data, int type, void* event);
+  static Eina_Bool StubVisibilityCb(void* data, int type, void* event);
+  static Eina_Bool StubLowerCb(void* data, int type, void* event);
+  static Eina_Bool StubPreVisibilityCb(void* data, int type, void* event);
+  static Eina_Bool StubAuxMessageCb(void* data, int type, void* event);
+
+ private:
+  bool initialized_ = false;
+  Ecore_Event_Handler* hshow_ = nullptr;
+  Ecore_Event_Handler* hhide_ = nullptr;
+  Ecore_Event_Handler* hvchange_ = nullptr;
+  Ecore_Event_Handler* hlower_ = nullptr;
+  Ecore_Event_Handler* hpvchange_ = nullptr;
+  Ecore_Event_Handler* hauxmsg_ = nullptr;
+  ITrim* trim_ = nullptr;
+  IWindow* window_ = nullptr;
+  guint flush_timer_ = 0;
+};
+
+} // namepace tizen_cpp
+
+#endif // TIZEN_CPP_COMMON_ECORE_HANDLER_HH
diff --git a/tizen-cpp/common/log_private.hh b/tizen-cpp/common/log_private.hh
new file mode 100644 (file)
index 0000000..638f90b
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CPP_COMMON_LOG_PRIVATE_HH_
+#define TIZEN_CPP_COMMON_LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "APP_CORE_CPP"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif  // TIZEN_CPP_COMMON_LOG_PRIVATE_HH_
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8940982
--- /dev/null
@@ -0,0 +1,55 @@
+SET(TARGET_UNIT_TEST "app-core_unittests")
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/app-core-cpp
+  LIB_APP_CORE_CPP_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/app-core-ui-cpp
+  LIB_APP_CORE_UI_CPP_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/app-core-efl-cpp
+  LIB_APP_CORE_EFL_CPP_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/app-core-multi-window-cpp
+  LIB_APP_CORE_MULTI_WINDOW_CPP_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/common
+  LIB_COMMON_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} TEST_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/mock/ MOCK_SRCS)
+
+ADD_EXECUTABLE(${TARGET_UNIT_TEST}
+  ${MOCK_SRCS}
+  ${TEST_SRCS}
+  ${LIB_APP_CORE_CPP_SRCS}
+  ${LIB_APP_CORE_UI_CPP_SRCS}
+  ${LIB_APP_CORE_EFL_CPP_SRCS}
+  ${LIB_APP_CORE_MULTI_WINDOW_CPP_SRCS}
+  ${LIB_COMMON_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_UNIT_TEST} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/../
+  ${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/
+  ${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/app-core-cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/app-core-ui-cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/app-core-efl-cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/app-core-multi-window-cpp
+  ${CMAKE_CURRENT_SOURCE_DIR}/../tizen-cpp/common
+)
+
+APPLY_PKG_CONFIG(${TARGET_UNIT_TEST} PUBLIC
+  AUL_DEPS
+  BUNDLE_DEPS
+  CAPI_SYSTEM_INFO_DEPS
+  DLOG_DEPS
+  ECORE_WL2_DEPS
+  ELEMENTARY_DEPS
+  GIO_2_DEPS
+  GMOCK_DEPS
+  PKGMGR_INFO_DEPS
+  SENSOR_DEPS
+  TIZEN_EXTENSION_CLIENT_DEPS
+  TTRACE_DEPS
+  VCONF_DEPS
+  WAYLAND_CLIENT_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_UNIT_TEST} PUBLIC "-L/usr/lib/hal")
+SET_TARGET_PROPERTIES(${TARGET_UNIT_TEST} PROPERTIES COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_UNIT_TEST} PROPERTIES LINK_FLAGS "-pie")
diff --git a/unittests/app_core_base_test.cc b/unittests/app_core_base_test.cc
new file mode 100644 (file)
index 0000000..7d63a8d
--- /dev/null
@@ -0,0 +1,788 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+#include <stdio.h>
+#include <glib.h>
+#include <bundle_cpp.h>
+#include <bundle_internal.h>
+
+#include "mock/test_fixture.h"
+#include "mock/aul_mock.h"
+#include "mock/sensor_mock.h"
+#include "mock/vconf_mock.h"
+#include "mock/dbus_mock.h"
+#include "mock/dl_mock.h"
+#include "mock/app_core_base_mock.h"
+
+#include <functional>
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::Invoke;
+
+namespace {
+class Mocks : public ::testing::NiceMock<AulMock>,
+    virtual public ::testing::NiceMock<SensorMock>,
+    virtual public ::testing::NiceMock<DbusMock>,
+    virtual public ::testing::NiceMock<DlMock>,
+    virtual public ::testing::NiceMock<VConfMock> {};
+
+}  // namespace
+
+namespace tizen_cpp {
+class AppCoreBaseTest : public TestFixture {
+ public:
+  AppCoreBaseTest() : TestFixture(std::make_unique<::Mocks>()) {}
+
+  virtual void SetUp() {}
+
+  virtual void TearDown() {}
+
+  static void SetUpTestCase() {
+    mkdir("/tmp/locale", 0777);
+    mkdir("/tmp/locale/cs", 0777);
+    mkdir("/tmp/locale/de", 0777);
+    mkdir("/tmp/locale/en", 0777);
+    mkdir("/tmp/locale/en_US", 0777);
+  }
+
+  static void TearDownTestCase() {
+    rmdir("/tmp/locale/en_US");
+    rmdir("/tmp/locale/en");
+    rmdir("/tmp/locale/de");
+    rmdir("/tmp/locale/cs");
+    rmdir("/tmp/locale");
+  }
+};
+
+class DummyArgs {
+ public:
+  DummyArgs() {
+    tizen_base::Bundle b;
+    b.Add("dummy", "dummy");
+    argc_ = bundle_export_to_argv(b.GetHandle(), &argv_);
+  }
+
+  DummyArgs(std::string key, std::string val) {
+    tizen_base::Bundle b;
+    b.Add(std::move(key), std::move(val));
+    argc_ = bundle_export_to_argv(b.GetHandle(), &argv_);
+  }
+
+  ~DummyArgs() {
+    bundle_free_exported_argv(argc_, &argv_);
+  }
+
+  int GetArgc() const {
+    return argc_;
+  }
+
+  char** GetArgv() const {
+    return argv_;
+  }
+
+ private:
+  int argc_ = 0;
+  char** argv_ = nullptr;
+};
+
+class TestEvent : public AppCoreBase::EventBase {
+ public:
+  TestEvent(Type type) : EventBase(type) {}
+
+  void OnEvent(const std::string& val) override {
+    SetVal(val);
+  }
+  void OnEvent(int val) override {
+    SetVal(val);
+  }
+};
+
+TEST_F(AppCoreBaseTest, AppCoreBase_Run_Cancel) {
+  testing::NiceMock<AppCoreBaseMock> core;
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        return -1;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnLoopInit(_, _))
+      .Times(1);
+  EXPECT_CALL(core, OnLoopFinish())
+      .Times(1);
+  EXPECT_CALL(core, OnLoopRun())
+      .Times(0);
+  EXPECT_CALL(core, OnLoopExit())
+      .Times(0);
+
+  DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_Run) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_Init_Fini) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  DummyArgs da;
+  core.Init(da.GetArgc(), da.GetArgv());
+  core.Fini();
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_Run_Again) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  ON_CALL(core, OnCreate())
+      .WillByDefault(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+
+  EXPECT_CALL(core, OnCreate())
+      .Times(2);
+  EXPECT_CALL(core, OnTerminate())
+      .Times(2);
+
+  DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_OnControl) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnReceive(_, _))
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .Times(1);
+
+  DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_AddEvent) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->RaiseEvent(9216, IAppCore::IEvent::Type::LOW_MEMORY);
+          obj->RaiseEvent("test", IAppCore::IEvent::Type::LOW_MEMORY);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  DummyArgs da;
+  auto ev = std::shared_ptr<AppCoreBase::EventBase>(
+      new TestEvent(IAppCore::IEvent::Type::LOW_MEMORY));
+  core.AddEvent(ev);
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_EQ(ev->GetVal(0), 9216);
+  EXPECT_EQ(ev->GetVal(""), "test");
+  core.RemoveEvent(ev);
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_AllowBG) {
+  testing::NiceMock<AppCoreBaseMock> core;
+  bool bg = false;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnReceive(_, _))
+      .WillOnce(Invoke([&core, &bg](aul_type type, tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreBase::OnReceive(type, std::move(b));
+        bg = core.IsBgAllowed();
+        return ret;
+      }));
+
+  DummyArgs da(AUL_K_ALLOWED_BG, "ALLOWED_BG");
+  core.SetFeature(AppCoreBase::FEATURE_BACKGROUND_MANAGEMENT);
+  EXPECT_EQ(core.GetFeature(), AppCoreBase::FEATURE_BACKGROUND_MANAGEMENT);
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_TRUE(bg);
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_IsSuspended) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_FALSE(core.IsSuspended());
+  core.ToggleSuspendedState();
+  EXPECT_TRUE(core.IsSuspended());
+  core.ToggleSuspendedState();
+  EXPECT_FALSE(core.IsSuspended());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_FlushMemory) {
+  testing::NiceMock<AppCoreBaseMock> core;
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->FlushMemory();
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  EXPECT_CALL(core, OnTrimMemory())
+      .Times(1);
+
+  DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_GetRotationState_N) {
+  bool result = false;
+
+  try {
+    AppCoreBase::GetRotationState();
+  } catch (const std::runtime_error& e) {
+    EXPECT_STREQ(e.what(), "invalid rotation state");
+    result = true;
+  }
+
+  EXPECT_TRUE(result);
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_GetRotationState) {
+  testing::NiceMock<AppCoreBaseMock> core;
+  AppCoreBase::RotationState rst = AppCoreBase::ROTATION_UNKNOWN;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core, &rst]() -> int {
+        core.AppCoreBase::OnCreate();
+        rst = AppCoreBase::GetRotationState();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(GetMock<SensorMock>(), sensord_register_event(_, _, _, _, _, _))
+      .WillOnce(Invoke([](int handle, unsigned int event_type,
+          unsigned int interval, unsigned int max_batch_latency,
+          sensor_cb_t cb, void *user_data) -> bool {
+          sensor_t sensor = { 0, };
+          sensor_data_t data = { 0, };
+          data.value_count = 1;
+          data.values[0] = AUTO_ROTATION_DEGREE_0;
+          cb(sensor, AUTO_ROTATION_CHANGE_STATE_EVENT, &data, user_data);
+        return true;
+      }));
+
+  DummyArgs da;
+  auto ev = std::shared_ptr<AppCoreBase::EventBase>(
+      new TestEvent(IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED));
+  core.AddEvent(ev);
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_EQ(rst, AppCoreBase::ROTATION_PORTRAIT_NORMAL);
+  core.RemoveEvent(ev);
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_LockCb) {
+  testing::NiceMock<AppCoreBaseMock> core;
+  AppCoreBase::RotationState rst = AppCoreBase::ROTATION_UNKNOWN;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core, &rst]() -> int {
+        core.AppCoreBase::OnCreate();
+        GetMock<VConfMock>().ChangeBool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, true);
+        rst = AppCoreBase::GetRotationState();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  DummyArgs da;
+  auto ev = std::shared_ptr<AppCoreBase::EventBase>(
+      new TestEvent(IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED));
+  core.AddEvent(ev);
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_EQ(rst, AppCoreBase::ROTATION_PORTRAIT_NORMAL);
+  core.RemoveEvent(ev);
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_ChargerStatusChangedCb) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&]() -> int {
+        core.AppCoreBase::OnCreate();
+        GetMock<VConfMock>().ChangeInt(VCONFKEY_SYSMAN_CHARGER_STATUS, 0);
+        GetMock<VConfMock>().ChangeInt(VCONFKEY_SYSMAN_CHARGER_STATUS, 1);
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  DummyArgs da;
+  auto ev = std::shared_ptr<AppCoreBase::EventBase>(
+      new TestEvent(IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED));
+  core.SetFeature(AppCoreBase::FEATURE_CHARGER_STATUS);
+  core.AddEvent(ev);
+  core.Run(da.GetArgc(), da.GetArgv());
+  core.RemoveEvent(ev);
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_AddEvent_LanguageChanged) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreBase::OnControl(std::move(b));
+        GetMock<VConfMock>().ChangeStr(VCONFKEY_LANGSET, "en_US:kr:fr");
+        return ret;
+      }));
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_str(_))
+      .WillRepeatedly(Invoke([](const char* key) -> char* {
+        if (strcmp(key, VCONFKEY_LANGSET) == 0) {
+          return strdup("en_US:kr:fr");
+        }
+        return nullptr;
+      }));
+
+  DummyArgs da;
+  auto ev = std::shared_ptr<AppCoreBase::EventBase>(
+      new TestEvent(IAppCore::IEvent::Type::LANG_CHANGE));
+  core.AddEvent(ev);
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_EQ(ev->GetVal(""), "en_US:kr:fr");
+  core.RemoveEvent(ev);
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_AddEvent_RegionChanged) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreBase::OnControl(std::move(b));
+        GetMock<VConfMock>().ChangeStr(VCONFKEY_REGIONFORMAT, "US");
+        return ret;
+      }));
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_str(_))
+      .WillRepeatedly(Invoke([](const char* key) -> char* {
+        if (strcmp(key, VCONFKEY_REGIONFORMAT) == 0) {
+          return strdup("US");
+        }
+        return nullptr;
+      }));
+
+  DummyArgs da;
+  auto ev = std::shared_ptr<AppCoreBase::EventBase>(
+      new TestEvent(IAppCore::IEvent::Type::REGION_CHANGE));
+  core.AddEvent(ev);
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_EQ(ev->GetVal(""), "US");
+  core.RemoveEvent(ev);
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_AddEvent_LowBattery) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreBase::OnControl(std::move(b));
+        GetMock<VConfMock>().ChangeInt(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW,
+            VCONFKEY_SYSMAN_BAT_CRITICAL_LOW);
+        return ret;
+      }));
+
+  DummyArgs da;
+  auto ev = std::shared_ptr<AppCoreBase::EventBase>(
+      new TestEvent(IAppCore::IEvent::Type::LOW_BATTERY));
+  core.AddEvent(ev);
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_EQ(ev->GetVal(0), VCONFKEY_SYSMAN_BAT_CRITICAL_LOW);
+  core.RemoveEvent(ev);
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_AddEvent_LowMemory) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreBase::OnControl(std::move(b));
+        GetMock<VConfMock>().ChangeInt(VCONFKEY_SYSMAN_LOW_MEMORY,
+            VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING);
+        return ret;
+      }));
+
+  DummyArgs da;
+  auto ev = std::shared_ptr<AppCoreBase::EventBase>(
+      new TestEvent(IAppCore::IEvent::Type::LOW_MEMORY));
+  core.AddEvent(ev);
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_EQ(ev->GetVal(0), VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING);
+  core.RemoveEvent(ev);
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_EnableWatchdog) {
+  EXPECT_CALL(GetMock<AulMock>(), aul_watchdog_enable())
+      .Times(1);
+  AppCoreBase::EnableWatchdog();
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_DisableWatchdog) {
+  EXPECT_CALL(GetMock<AulMock>(), aul_watchdog_disable())
+      .Times(1);
+  AppCoreBase::DisableWatchdog();
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_KickWatchdog) {
+  EXPECT_CALL(GetMock<AulMock>(), aul_watchdog_kick())
+      .Times(1);
+  AppCoreBase::KickWatchdog();
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_OnReceive_AUL_TERMINATE) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&]() -> int {
+        return core.AppCoreBase::OnCreate();
+      }));
+  EXPECT_CALL(core, OnReceive(_, _))
+      .Times(2);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreBase::OnControl(std::move(b));
+        GetMock<AulMock>().SetEvent(AUL_TERMINATE, bundle_create());
+        return ret;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_OnReceive_AUL_RESUME) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnReceive(_, _))
+      .Times(2);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreBase::OnControl(std::move(b));
+        bundle* kb = bundle_create();
+        bundle_add_str(kb, AUL_K_ALLOWED_BG, "ALLOWED_BG");
+        GetMock<AulMock>().SetEvent(AUL_RESUME, kb);
+        return ret;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  DummyArgs da;
+  core.SetFeature(AppCoreBase::FEATURE_BACKGROUND_MANAGEMENT);
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_OnReceive_AUL_UPDATE_REQUESTED) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnReceive(_, _))
+      .Times(2);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreBase::OnControl(std::move(b));
+        GetMock<AulMock>().SetEvent(AUL_UPDATE_REQUESTED, bundle_create());
+        return ret;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_OnReceive_INVALID_EVENT) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnReceive(_, _))
+      .Times(2);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreBase::OnControl(std::move(b));
+        GetMock<AulMock>().SetEvent((aul_type)9216, bundle_create());
+        return ret;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_OnReceive_AUL_TERMINATE_INST) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnReceive(_, _))
+      .Times(2);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreBase::OnControl(std::move(b));
+        GetMock<AulMock>().SetEvent(AUL_TERMINATE_INST, bundle_create());
+        return ret;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_OnReceive_AUL_SUSPEND) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnReceive(_, _))
+      .Times(2);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreBase::OnControl(std::move(b));
+        GetMock<AulMock>().SetEvent(AUL_SUSPEND, bundle_create());
+        return ret;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  DummyArgs da;
+  core.SetFeature(AppCoreBase::FEATURE_BACKGROUND_MANAGEMENT);
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_TRUE(core.IsSuspended());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_OnReceive_AUL_WAKE) {
+  testing::NiceMock<AppCoreBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreBase::OnCreate();
+        core.ToggleSuspendedState();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnReceive(_, _))
+      .Times(2);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreBase::OnControl(std::move(b));
+        GetMock<AulMock>().SetEvent(AUL_WAKE, bundle_create());
+        return ret;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  DummyArgs da;
+  core.SetFeature(AppCoreBase::FEATURE_BACKGROUND_MANAGEMENT);
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_FALSE(core.IsSuspended());
+}
+
+TEST_F(AppCoreBaseTest, AppCoreBase_RotationState) {
+  EXPECT_EQ(AppCoreBase::GetDisplayState(), AppCoreBase::DISPLAY_STATE_UNKNOWN);
+  AppCoreBase::SetDisplayState(AppCoreBase::DISPLAY_STATE_ON);
+  EXPECT_EQ(AppCoreBase::GetDisplayState(), AppCoreBase::DISPLAY_STATE_ON);
+  AppCoreBase::SetDisplayState(AppCoreBase::DISPLAY_STATE_UNKNOWN);
+  EXPECT_EQ(AppCoreBase::GetDisplayState(), AppCoreBase::DISPLAY_STATE_UNKNOWN);
+}
+
+} // namespace tizen_cpp
diff --git a/unittests/app_core_efl_base_test.cc b/unittests/app_core_efl_base_test.cc
new file mode 100644 (file)
index 0000000..bb74996
--- /dev/null
@@ -0,0 +1,855 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+#include <stdio.h>
+#include <glib.h>
+#include <bundle_cpp.h>
+#include <bundle_internal.h>
+#include <aul_svc.h>
+
+#include "mock/test_fixture.h"
+#include "mock/aul_mock.h"
+#include "mock/sensor_mock.h"
+#include "mock/vconf_mock.h"
+#include "mock/dbus_mock.h"
+#include "mock/elm_mock.h"
+#include "mock/wayland_mock.h"
+#include "mock/ecore_wl2_mock.h"
+#include "mock/ecore_mock.h"
+#include "mock/dl_mock.h"
+#include "mock/app_core_efl_base_mock.h"
+#include "appcore_ui_base.h"
+
+#include <functional>
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::Invoke;
+
+namespace {
+class Mocks : public ::testing::NiceMock<AulMock>,
+    virtual public ::testing::NiceMock<EcoreWl2Mock>,
+    virtual public ::testing::NiceMock<SensorMock>,
+    virtual public ::testing::NiceMock<DbusMock>,
+    virtual public ::testing::NiceMock<ElmMock>,
+    virtual public ::testing::NiceMock<WaylandMock>,
+    virtual public ::testing::NiceMock<EcoreMock>,
+    virtual public ::testing::NiceMock<DlMock>,
+    virtual public ::testing::NiceMock<VConfMock> {};
+
+class DummyArgs {
+ public:
+  DummyArgs() {
+    tizen_base::Bundle b;
+    b.Add("dummy", "dummy");
+    argc_ = bundle_export_to_argv(b.GetHandle(), &argv_);
+  }
+
+  DummyArgs(std::string key, std::string val) {
+    tizen_base::Bundle b;
+    b.Add(std::move(key), std::move(val));
+    argc_ = bundle_export_to_argv(b.GetHandle(), &argv_);
+  }
+
+  ~DummyArgs() {
+    bundle_free_exported_argv(argc_, &argv_);
+  }
+
+  int GetArgc() const {
+    return argc_;
+  }
+
+  char** GetArgv() const {
+    return argv_;
+  }
+
+ private:
+  int argc_ = 0;
+  char** argv_ = nullptr;
+};
+
+int __vc_elm_initialize(void) {
+  return 0;
+}
+
+int __vc_elm_deinitialize(void) {
+  return 0;
+}
+
+int __vc_elm_set_auto_register_mode(int, int) {
+  return 0;
+}
+
+int __ui_plugin_init_dummy(appcore_ui_base_ops* ops, int argc, char** argv,
+    unsigned int *hint) {
+  return 0;
+}
+
+int __ui_plugin_fini_dummy(void) {
+  return 0;
+}
+
+}  // namespace
+
+namespace tizen_cpp {
+
+class AppCoreEflBaseTest : public TestFixture {
+ public:
+  AppCoreEflBaseTest() : TestFixture(std::make_unique<::Mocks>()) {}
+
+  virtual void SetUp() {}
+
+  virtual void TearDown() {}
+};
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_Run) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_bool(_, _))
+      .WillRepeatedly(Invoke([&](const char *in_key,
+          int* val) -> int {
+        if (strcmp(in_key, VCONFKEY_VC_VOICE_TOUCH_AUTOMODE) == 0) {
+          *val = 1;
+          return 0;
+        }
+
+        *val = 0;
+        return 0;
+      }));
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_AddEvent_OnTrimMemory) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(6000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnReceive(_, _))
+      .Times(2);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreEflBase::OnControl(std::move(b));
+        GetMock<AulMock>().SetEvent(AUL_SUSPEND, bundle_create());
+        return ret;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnTrimMemory())
+      .Times(1);
+
+  ::DummyArgs da;
+  core.SetFeature(AppCoreBase::FEATURE_BACKGROUND_MANAGEMENT);
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_AddEvent_SetSystemResourceReclaiming) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(6000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreEflBase::OnControl(std::move(b));
+        core.Resume();
+        core.Pause();
+        return ret;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnTrimMemory())
+      .Times(0);
+
+  ::DummyArgs da;
+  core.SetFeature(AppCoreBase::FEATURE_BACKGROUND_MANAGEMENT);
+  core.SetSystemResourceReclaiming(false);
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_OnResume) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreEflBase::OnControl(std::move(b));
+        Ecore_Wl2_Event_Window_Show ev_show;
+        ev_show.win = 1;
+        ev_show.parent_win = 0;
+        ev_show.data[0] = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_SHOW, &ev_show);
+
+        Ecore_Wl2_Event_Window_Pre_Visibility_Change ev_pre;
+        ev_pre.type = ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED;
+        ev_pre.win = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE, &ev_pre);
+
+        Ecore_Wl2_Event_Window_Visibility_Change event;
+        event.win = 1;
+        event.fully_obscured = 0;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+
+        event.fully_obscured = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+
+        Ecore_Wl2_Event_Window_Hide ev_hide;
+        ev_hide.win = 1;
+        ev_hide.parent_win = 0;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_HIDE, &ev_hide);
+
+        return ret;
+      }));
+  EXPECT_CALL(core, OnResume())
+      .Times(1);
+  EXPECT_CALL(core, OnPause())
+      .Times(1);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_RaiseWin) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(3000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreEflBase::OnControl(std::move(b));
+        Ecore_Wl2_Event_Window_Show ev_show;
+        ev_show.win = 1;
+        ev_show.parent_win = 0;
+        ev_show.data[0] = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_SHOW, &ev_show);
+
+        Ecore_Wl2_Event_Window_Pre_Visibility_Change ev_pre;
+        ev_pre.type = ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED;
+        ev_pre.win = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE, &ev_pre);
+
+        Ecore_Wl2_Event_Window_Visibility_Change event;
+        event.win = 1;
+        event.fully_obscured = 0;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+
+        event.fully_obscured = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+
+        GetMock<AulMock>().SetEvent(AUL_START, bundle_create());
+        return ret;
+      }))
+      .WillRepeatedly(Invoke([&](tizen_base::Bundle b) -> int {
+        return core.AppCoreEflBase::OnControl(std::move(b));
+      }));
+  EXPECT_CALL(GetMock<EcoreWl2Mock>(), ecore_wl2_window_activate(_))
+    .WillOnce(Invoke([&](Ecore_Wl2_Window* win) {
+      Ecore_Wl2_Event_Window_Visibility_Change event;
+      event.win = 1;
+      event.fully_obscured = 0;
+      GetMock<EcoreMock>().SendEvent(
+          ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+    }));
+
+  EXPECT_CALL(core, OnResume())
+      .Times(2);
+  EXPECT_CALL(core, OnPause())
+      .Times(2);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_PauseWin) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(3000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreEflBase::OnControl(std::move(b));
+        Ecore_Wl2_Event_Window_Show ev_show;
+        ev_show.win = 1;
+        ev_show.parent_win = 0;
+        ev_show.data[0] = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_SHOW, &ev_show);
+
+        Ecore_Wl2_Event_Window_Pre_Visibility_Change ev_pre;
+        ev_pre.type = ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED;
+        ev_pre.win = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE, &ev_pre);
+
+        Ecore_Wl2_Event_Window_Visibility_Change event;
+        event.win = 1;
+        event.fully_obscured = 0;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+
+        GetMock<AulMock>().SetEvent(AUL_PAUSE, bundle_create());
+        return ret;
+      }))
+      .WillRepeatedly(Invoke([&](tizen_base::Bundle b) -> int {
+        return core.AppCoreEflBase::OnControl(std::move(b));
+      }));
+  EXPECT_CALL(GetMock<EcoreWl2Mock>(), ecore_wl2_window_iconified_set(_, _))
+    .WillOnce(Invoke([&](Ecore_Wl2_Window* win, Eina_Bool) {
+      Ecore_Wl2_Event_Window_Visibility_Change event;
+      event.win = 1;
+      event.fully_obscured = 1;
+      GetMock<EcoreMock>().SendEvent(
+          ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+    }));
+
+  EXPECT_CALL(core, OnResume())
+      .Times(1);
+  EXPECT_CALL(core, OnPause())
+      .Times(1);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_AUL_RESUME) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(3000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreEflBase::OnControl(std::move(b));
+        Ecore_Wl2_Event_Window_Show ev_show;
+        ev_show.win = 1;
+        ev_show.parent_win = 0;
+        ev_show.data[0] = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_SHOW, &ev_show);
+
+        GetMock<AulMock>().SetEvent(AUL_RESUME, bundle_create());
+        return ret;
+      }))
+      .WillRepeatedly(Invoke([&](tizen_base::Bundle b) -> int {
+        return core.AppCoreEflBase::OnControl(std::move(b));
+      }));
+  EXPECT_CALL(GetMock<EcoreWl2Mock>(), ecore_wl2_window_activate(_))
+    .WillOnce(Invoke([&](Ecore_Wl2_Window* win) {
+      Ecore_Wl2_Event_Window_Visibility_Change event;
+      event.win = 1;
+      event.fully_obscured = 0;
+      GetMock<EcoreMock>().SendEvent(
+          ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+    }));
+
+  EXPECT_CALL(core, OnResume())
+      .Times(1);
+  EXPECT_CALL(core, OnPause())
+      .Times(1);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_AUL_TERMINATE_INST) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreEflBase::OnControl(std::move(b));
+
+        GetMock<AulMock>().SetEvent(AUL_TERMINATE_INST, bundle_create());
+        return ret;
+      }));
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_AUL_TERMINATE) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreEflBase::OnControl(std::move(b));
+
+        GetMock<AulMock>().SetEvent(AUL_TERMINATE, bundle_create());
+        return ret;
+      }));
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_IsResumed) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+  bool resumed = false;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreEflBase::OnControl(std::move(b));
+        core.Resume();
+        core.Pause();
+        core.Resume();
+        resumed = core.IsResumed();
+
+        GetMock<AulMock>().SetEvent(AUL_TERMINATE, bundle_create());
+        return ret;
+      }));
+  EXPECT_CALL(core, OnResume())
+      .Times(2);
+  EXPECT_CALL(core, OnPause())
+      .Times(2);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_TRUE(resumed);
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_VcElm) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_bool(_, _))
+      .WillRepeatedly(Invoke([&](const char *in_key,
+          int* val) -> int {
+        if (strcmp(in_key, VCONFKEY_VC_VOICE_TOUCH_AUTOMODE) == 0) {
+          *val = 1;
+          return 0;
+        }
+
+        *val = 0;
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<DlMock>(), dlsym(_, _))
+      .WillRepeatedly(Invoke([&](void* handle, const char* name) -> void* {
+        if (strcmp(name, "vc_elm_initialize") == 0) {
+          return (void*)__vc_elm_initialize;
+        } else if (strcmp(name, "vc_elm_deinitialize") == 0) {
+          return (void*)__vc_elm_deinitialize;
+        } else if (strcmp(name, "vc_elm_set_auto_register_mode") == 0) {
+          return (void*)__vc_elm_set_auto_register_mode;
+        }
+
+        return nullptr;
+      }));
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_VcElm2) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          GetMock<VConfMock>().ChangeBool(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE, false);
+          GetMock<VConfMock>().ChangeBool(VCONFKEY_VC_VOICE_TOUCH_AUTOMODE, true);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(GetMock<VConfMock>(), vconf_get_bool(_, _))
+      .WillRepeatedly(Invoke([&](const char *in_key,
+          int* val) -> int {
+        if (strcmp(in_key, VCONFKEY_VC_VOICE_TOUCH_AUTOMODE) == 0) {
+          *val = 1;
+          return 0;
+        }
+
+        *val = 0;
+        return 0;
+      }));
+  EXPECT_CALL(GetMock<DlMock>(), dlsym(_, _))
+      .WillRepeatedly(Invoke([&](void* handle, const char* name) -> void* {
+        if (strcmp(name, "vc_elm_initialize") == 0) {
+          return (void*)__vc_elm_initialize;
+        } else if (strcmp(name, "vc_elm_deinitialize") == 0) {
+          return (void*)__vc_elm_deinitialize;
+        } else if (strcmp(name, "vc_elm_set_auto_register_mode") == 0) {
+          return (void*)__vc_elm_set_auto_register_mode;
+        }
+
+        return nullptr;
+      }));
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_Aux) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+  AppCoreBase::DisplayState state = AppCoreBase::DISPLAY_STATE_UNKNOWN;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreEflBase::OnControl(std::move(b));
+
+        Ecore_Wl2_Event_Aux_Message event;
+        event.key = "dpms_wm";
+        event.val = "off";
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_AUX_MESSAGE, &event);
+        event.val = "on";
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_AUX_MESSAGE, &event);
+        state = AppCoreBase::GetDisplayState();
+        return ret;
+      }));
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_EQ(AppCoreBase::DISPLAY_STATE_ON, state);
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_GetBgState) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  core.SetBgState(true);
+  EXPECT_TRUE(core.GetBgState());
+  core.SetBgState(false);
+  EXPECT_FALSE(core.GetBgState());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_IsLegacyLifecycle) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .Times(1);
+  EXPECT_CALL(core, OnResume())
+      .Times(1);
+  EXPECT_CALL(core, OnPause())
+      .Times(1);
+
+  ::DummyArgs da;
+  setenv("TIZEN_API_VERSION", "2.3", 1);
+  core.SetBgState(true);
+  core.Run(da.GetArgc(), da.GetArgv());
+  unsetenv("TIZEN_API_VERSION");
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_ApplyBgState) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+    .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+      int ret = core.AppCoreEflBase::OnControl(std::move(b));
+      GetMock<AulMock>().SetEvent(AUL_START, bundle_create());
+      return ret;
+    }))
+    .WillRepeatedly(Invoke([&](tizen_base::Bundle b) -> int {
+      return core.AppCoreEflBase::OnControl(std::move(b));
+    }));
+
+  ::DummyArgs da(AUL_SVC_K_BG_LAUNCH, "enable");
+  core.SetBgState(false);
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_OnLower) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        return core.AppCoreEflBase::OnCreate();
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreEflBase::OnControl(std::move(b));
+        Ecore_Wl2_Event_Window_Show ev_show;
+        ev_show.win = 1;
+        ev_show.parent_win = 0;
+        ev_show.data[0] = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_SHOW, &ev_show);
+
+        Ecore_Wl2_Event_Window_Visibility_Change event;
+        event.win = 1;
+        event.fully_obscured = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+
+        Ecore_Wl2_Event_Window_Lower ev_lower;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_LOWER, &ev_lower);
+
+        return ret;
+      }));
+  EXPECT_CALL(GetMock<AulMock>(), aul_app_group_lower(_))
+    .WillOnce(Invoke([&](int* exit) {
+      *exit = 1;
+    }));
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_Plugin) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(GetMock<DlMock>(), dlsym(_, _))
+      .WillRepeatedly(Invoke([&](void* handle, const char* name) -> void* {
+        if (strcmp(name, "APPCORE_UI_PLUGIN_INIT") == 0) {
+          return (void*)__ui_plugin_init_dummy;
+        } else if (strcmp(name, "APPCORE_UI_PLUGIN_FINI") == 0) {
+          return (void*)__ui_plugin_fini_dummy;
+        }
+
+        return nullptr;
+      }));
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreEflBaseTest, AppCoreEflBase_Plugin2) {
+  testing::NiceMock<AppCoreEflBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreEflBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreEflBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreEflBase::OnControl(std::move(b));
+        Ecore_Wl2_Event_Window_Show ev_show;
+        ev_show.win = 1;
+        ev_show.parent_win = 0;
+        ev_show.data[0] = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_SHOW, &ev_show);
+
+        Ecore_Wl2_Event_Window_Pre_Visibility_Change ev_pre;
+        ev_pre.type = ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED;
+        ev_pre.win = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE, &ev_pre);
+
+        Ecore_Wl2_Event_Window_Visibility_Change event;
+        event.win = 1;
+        event.fully_obscured = 0;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+
+        event.fully_obscured = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+
+        Ecore_Wl2_Event_Window_Hide ev_hide;
+        ev_hide.win = 1;
+        ev_hide.parent_win = 0;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_HIDE, &ev_hide);
+
+        return ret;
+      }));
+  EXPECT_CALL(GetMock<DlMock>(), dlsym(_, _))
+      .WillRepeatedly(Invoke([&](void* handle, const char* name) -> void* {
+        if (strcmp(name, "APPCORE_UI_PLUGIN_INIT") == 0) {
+          return (void*)__ui_plugin_init_dummy;
+        } else if (strcmp(name, "APPCORE_UI_PLUGIN_FINI") == 0) {
+          return (void*)__ui_plugin_fini_dummy;
+        }
+
+        return nullptr;
+      }));
+  EXPECT_CALL(core, OnResume())
+      .Times(1);
+  EXPECT_CALL(core, OnPause())
+      .Times(1);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+
+} // namespace tizen_cpp
diff --git a/unittests/app_core_multi_window_base_test.cc b/unittests/app_core_multi_window_base_test.cc
new file mode 100644 (file)
index 0000000..b00f1a0
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+#include <stdio.h>
+#include <glib.h>
+#include <bundle_cpp.h>
+#include <bundle_internal.h>
+
+#include "mock/test_fixture.h"
+#include "mock/aul_mock.h"
+#include "mock/sensor_mock.h"
+#include "mock/vconf_mock.h"
+#include "mock/dbus_mock.h"
+#include "mock/elm_mock.h"
+#include "mock/wayland_mock.h"
+#include "mock/ecore_wl2_mock.h"
+#include "mock/ecore_mock.h"
+#include "mock/dl_mock.h"
+#include "mock/app_core_multi_window_base_mock.h"
+#include "mock/app_core_multi_window_base_context_mock.h"
+
+#include <functional>
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::Invoke;
+
+namespace {
+class Mocks : public ::testing::NiceMock<AulMock>,
+    virtual public ::testing::NiceMock<EcoreWl2Mock>,
+    virtual public ::testing::NiceMock<SensorMock>,
+    virtual public ::testing::NiceMock<DbusMock>,
+    virtual public ::testing::NiceMock<ElmMock>,
+    virtual public ::testing::NiceMock<WaylandMock>,
+    virtual public ::testing::NiceMock<EcoreMock>,
+    virtual public ::testing::NiceMock<DlMock>,
+    virtual public ::testing::NiceMock<VConfMock> {};
+
+class DummyArgs {
+ public:
+  DummyArgs() {
+    tizen_base::Bundle b;
+    b.Add("dummy", "dummy");
+    argc_ = bundle_export_to_argv(b.GetHandle(), &argv_);
+  }
+
+  DummyArgs(std::string key, std::string val) {
+    tizen_base::Bundle b;
+    b.Add(std::move(key), std::move(val));
+    argc_ = bundle_export_to_argv(b.GetHandle(), &argv_);
+  }
+
+  ~DummyArgs() {
+    bundle_free_exported_argv(argc_, &argv_);
+  }
+
+  int GetArgc() const {
+    return argc_;
+  }
+
+  char** GetArgv() const {
+    return argv_;
+  }
+
+ private:
+  int argc_ = 0;
+  char** argv_ = nullptr;
+};
+
+}  // namespace
+
+namespace tizen_cpp {
+
+class AppCoreMultiWindowBaseTest : public TestFixture {
+ public:
+  AppCoreMultiWindowBaseTest() : TestFixture(std::make_unique<::Mocks>()) {}
+
+  virtual void SetUp() {}
+
+  virtual void TearDown() {}
+};
+
+TEST_F(AppCoreMultiWindowBaseTest, AppCoreMultiWindowBase_Run) {
+  testing::NiceMock<AppCoreMultiWindowBaseMock> core;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&core]() -> int {
+        core.AppCoreMultiWindowBase::OnCreate();
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreMultiWindowBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreMultiWindowBaseTest, AppCoreMultiWindowBase_AddContextFactory) {
+  testing::NiceMock<AppCoreMultiWindowBaseMock> core;
+  std::shared_ptr<AppCoreMultiWindowBase::Context::IFactory> ret_factory;
+  std::string context_id = "test_context_id";
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&]() -> int {
+        core.AppCoreMultiWindowBase::OnCreate();
+        auto f = std::make_shared<AppCoreMultiWindowBaseContextMock::Factory>(context_id, &core);
+        core.AddContextFactory(f, context_id);
+        ret_factory = core.GetContextFactory(context_id);
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreMultiWindowBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_NE(ret_factory.get(), nullptr);
+}
+
+TEST_F(AppCoreMultiWindowBaseTest, AppCoreMultiWindowBase_RunContext) {
+  testing::NiceMock<AppCoreMultiWindowBaseMock> core;
+  std::string context_id = "test_context_id";
+  auto f = std::make_shared<AppCoreMultiWindowBaseContextMock::Factory>(context_id, &core);
+  auto* cxt = f->GetPreInitObj();
+  std::string ret_init_id;
+  std::string ret_context_id;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&]() -> int {
+        core.AppCoreMultiWindowBase::OnCreate();
+        core.AddContextFactory(f, context_id);
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreMultiWindowBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreMultiWindowBase::OnControl(std::move(b));
+        auto c = core.RunContext(context_id, "pre_init");
+        ret_init_id = c->GetInstId();
+        ret_context_id = c->GetContextId();
+        return ret;
+      }));
+  EXPECT_CALL(*cxt, OnCreate())
+      .Times(1);
+  EXPECT_CALL(*cxt, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(*cxt, OnPause())
+      .Times(0);
+  EXPECT_CALL(*cxt, OnResume())
+      .Times(0);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_EQ(ret_init_id, "pre_init");
+  EXPECT_EQ(ret_context_id, context_id);
+}
+
+TEST_F(AppCoreMultiWindowBaseTest, AppCoreMultiWindowBase_ExitContext) {
+  testing::NiceMock<AppCoreMultiWindowBaseMock> core;
+  std::string context_id = "test_context_id";
+  auto f = std::make_shared<AppCoreMultiWindowBaseContextMock::Factory>(context_id, &core);
+  auto* cxt = f->GetPreInitObj();
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&]() -> int {
+        core.AppCoreMultiWindowBase::OnCreate();
+        core.AddContextFactory(f, context_id);
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreMultiWindowBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreMultiWindowBase::OnControl(std::move(b));
+        auto c = core.RunContext(context_id, "pre_init");
+        core.ExitContext(c);
+        return ret;
+      }));
+  EXPECT_CALL(*cxt, OnCreate())
+      .Times(1);
+  EXPECT_CALL(*cxt, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(*cxt, OnPause())
+      .Times(0);
+  EXPECT_CALL(*cxt, OnResume())
+      .Times(0);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreMultiWindowBaseTest, AppCoreMultiWindowBase_Resume) {
+  testing::NiceMock<AppCoreMultiWindowBaseMock> core;
+  std::string context_id = "test_context_id";
+  auto f = std::make_shared<AppCoreMultiWindowBaseContextMock::Factory>(context_id, &core);
+  auto* cxt = f->GetPreInitObj();
+  bool is_resumed = false;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&]() -> int {
+        core.AppCoreMultiWindowBase::OnCreate();
+        core.AddContextFactory(f, context_id);
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreMultiWindowBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreMultiWindowBase::OnControl(std::move(b));
+        auto c = core.RunContext(context_id, "pre_init");
+        c->Resume();
+        is_resumed = c->IsResumed();
+        c->Pause();
+        return ret;
+      }));
+  EXPECT_CALL(*cxt, OnCreate())
+      .Times(1);
+  EXPECT_CALL(*cxt, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(*cxt, OnPause())
+      .Times(1);
+  EXPECT_CALL(*cxt, OnResume())
+      .Times(1);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_TRUE(is_resumed);
+}
+
+TEST_F(AppCoreMultiWindowBaseTest, AppCoreMultiWindowBase_OnVisibility) {
+  testing::NiceMock<AppCoreMultiWindowBaseMock> core;
+  std::string context_id = "test_context_id";
+  auto f = std::make_shared<AppCoreMultiWindowBaseContextMock::Factory>(context_id, &core);
+  auto* cxt = f->GetPreInitObj();
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&]() -> int {
+        core.AppCoreMultiWindowBase::OnCreate();
+        core.AddContextFactory(f, context_id);
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreMultiWindowBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreMultiWindowBase::OnControl(std::move(b));
+        core.RunContext(context_id, "pre_init");
+        return ret;
+      }));
+  EXPECT_CALL(GetMock<EcoreWl2Mock>(), ecore_wl2_window_id_get(_))
+      .WillRepeatedly(Invoke([&](Ecore_Wl2_Window* win) -> int {
+        return 1;
+      }));
+  EXPECT_CALL(*cxt, OnCreate())
+      .WillOnce(Invoke([&]() {
+        int dummy;
+        Ecore_Wl2_Window* win = reinterpret_cast<Ecore_Wl2_Window*>(&dummy);
+        cxt->WindowBind(win);
+
+        Ecore_Wl2_Event_Window_Show ev_show;
+        ev_show.win = 1;
+        ev_show.parent_win = 0;
+        ev_show.data[0] = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_SHOW, &ev_show);
+
+        Ecore_Wl2_Event_Window_Pre_Visibility_Change ev_pre;
+        ev_pre.type = ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED;
+        ev_pre.win = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE, &ev_pre);
+
+        Ecore_Wl2_Event_Window_Visibility_Change event;
+        event.win = 1;
+        event.fully_obscured = 0;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+
+        event.fully_obscured = 1;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE, &event);
+
+        Ecore_Wl2_Event_Window_Hide ev_hide;
+        ev_hide.win = 1;
+        ev_hide.parent_win = 0;
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_WINDOW_HIDE, &ev_hide);
+      }));
+  EXPECT_CALL(*cxt, OnTerminate())
+      .WillOnce(Invoke([&]() {
+        cxt->WindowUnbind();
+      }));
+  EXPECT_CALL(*cxt, OnPause())
+      .Times(1);
+  EXPECT_CALL(*cxt, OnResume())
+      .Times(1);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+}
+
+TEST_F(AppCoreMultiWindowBaseTest, AppCoreMultiWindowBase_OnAuxMessage) {
+  testing::NiceMock<AppCoreMultiWindowBaseMock> core;
+  std::string context_id = "test_context_id";
+  auto f = std::make_shared<AppCoreMultiWindowBaseContextMock::Factory>(context_id, &core);
+  auto* cxt = f->GetPreInitObj();
+  AppCoreBase::DisplayState state = AppCoreBase::DISPLAY_STATE_UNKNOWN;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&]() -> int {
+        core.AppCoreMultiWindowBase::OnCreate();
+        core.AddContextFactory(f, context_id);
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreMultiWindowBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreMultiWindowBase::OnControl(std::move(b));
+        core.RunContext(context_id, "pre_init");
+        return ret;
+      }));
+  EXPECT_CALL(GetMock<EcoreWl2Mock>(), ecore_wl2_window_id_get(_))
+      .WillRepeatedly(Invoke([&](Ecore_Wl2_Window* win) -> int {
+        return 1;
+      }));
+  EXPECT_CALL(*cxt, OnCreate())
+      .WillOnce(Invoke([&]() {
+        Ecore_Wl2_Event_Aux_Message event;
+        event.key = "dpms_wm";
+        event.val = "off";
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_AUX_MESSAGE, &event);
+        event.val = "on";
+        GetMock<EcoreMock>().SendEvent(
+            ECORE_WL2_EVENT_AUX_MESSAGE, &event);
+        state = AppCoreBase::GetDisplayState();
+      }));
+  EXPECT_CALL(*cxt, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(*cxt, OnPause())
+      .Times(0);
+  EXPECT_CALL(*cxt, OnResume())
+      .Times(0);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_EQ(AppCoreBase::DISPLAY_STATE_ON, state);
+}
+
+TEST_F(AppCoreMultiWindowBaseTest, AppCoreMultiWindowBase_FindById) {
+  testing::NiceMock<AppCoreMultiWindowBaseMock> core;
+  std::string context_id = "test_context_id";
+  auto f = std::make_shared<AppCoreMultiWindowBaseContextMock::Factory>(context_id, &core);
+  auto* cxt = f->GetPreInitObj();
+  std::shared_ptr<AppCoreMultiWindowBase::Context> found;
+
+  EXPECT_CALL(core, OnCreate())
+      .WillOnce(Invoke([&]() -> int {
+        core.AppCoreMultiWindowBase::OnCreate();
+        core.AddContextFactory(f, context_id);
+        g_timeout_add(1000, [](gpointer data) -> gboolean {
+          auto* obj = static_cast<testing::NiceMock<AppCoreMultiWindowBaseMock>*>(data);
+          obj->Exit();
+          return G_SOURCE_REMOVE;
+        }, &core);
+        return 0;
+      }));
+  EXPECT_CALL(core, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(core, OnControl(_))
+      .WillOnce(Invoke([&](tizen_base::Bundle b) -> int {
+        int ret = core.AppCoreMultiWindowBase::OnControl(std::move(b));
+        core.RunContext(context_id, "pre_init");
+        found = core.FindById("pre_init");
+        return ret;
+      }));
+  EXPECT_CALL(*cxt, OnCreate())
+      .Times(1);
+  EXPECT_CALL(*cxt, OnTerminate())
+      .Times(1);
+  EXPECT_CALL(*cxt, OnPause())
+      .Times(0);
+  EXPECT_CALL(*cxt, OnResume())
+      .Times(0);
+
+  ::DummyArgs da;
+  core.Run(da.GetArgc(), da.GetArgv());
+  EXPECT_NE(found.get(), nullptr);
+}
+
+} // namespace tizen_cpp
diff --git a/unittests/main.cc b/unittests/main.cc
new file mode 100644 (file)
index 0000000..db16de3
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+
+//#define LOG_INTERNAL
+
+#ifdef LOG_INTERNAL
+#include <dlog.h>
+
+extern "C" int __dlog_print(log_id_t log_id, int prio, const char *tag, const char *fmt, ...) {
+  printf("%s:", tag);
+  va_list ap;
+  va_start(ap, fmt);
+  vprintf(fmt, ap);
+  va_end(ap);
+  printf("\n");
+
+  return 0;
+}
+#endif
+
+int main(int argc, char* argv[]) {
+  int ret = 0;
+  try {
+    ::testing::InitGoogleTest(&argc, argv);
+  } catch(...) {
+    std::cout << "Exception occured" << std::endl;
+    return 1;
+  }
+
+  try {
+    return RUN_ALL_TESTS();
+  } catch(const ::testing::internal::GoogleTestFailureException& e) {
+    std::cout << "GoogleTestFailureException occured:" << e.what() << std::endl;
+    ret = 1;
+  }
+
+  return ret;
+}
diff --git a/unittests/mock/app_core_base_mock.h b/unittests/mock/app_core_base_mock.h
new file mode 100644 (file)
index 0000000..a80515a
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_APP_CORE_BASE_MOCK_H_
+#define UNIT_TESTS_MOCK_APP_CORE_BASE_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <bundle_cpp.h>
+#include <aul.h>
+
+#include "app_core_base.hh"
+
+class AppCoreBaseMock : public tizen_cpp::AppCoreBase {
+ public:
+  AppCoreBaseMock() {
+    using ::testing::_;
+    using ::testing::Invoke;
+
+    ON_CALL(*this, OnLoopInit(_, _))
+        .WillByDefault(Invoke([&](int argc, char** argv) {
+          loop_ = g_main_loop_new(NULL, FALSE);
+        }));
+    ON_CALL(*this, OnLoopFinish())
+        .WillByDefault(Invoke([&]() {
+          g_main_loop_unref(loop_);
+        }));
+    ON_CALL(*this, OnLoopRun())
+        .WillByDefault(Invoke([&]() {
+          g_main_loop_run(loop_);
+        }));
+    ON_CALL(*this, OnLoopExit())
+        .WillByDefault(Invoke([&]() {
+          g_main_loop_quit(loop_);
+        }));
+    ON_CALL(*this, OnTrimMemory())
+        .WillByDefault(Invoke([&]() -> int {
+          return AppCoreBase::OnTrimMemory();
+        }));
+    ON_CALL(*this, OnCreate())
+        .WillByDefault(Invoke([&]() -> int {
+          return AppCoreBase::OnCreate();
+        }));
+    ON_CALL(*this, OnTerminate())
+        .WillByDefault(Invoke([&]() -> int {
+          return AppCoreBase::OnTerminate();
+        }));
+    ON_CALL(*this, OnReceive(_, _))
+        .WillByDefault(Invoke([&](aul_type type, tizen_base::Bundle b) -> int {
+          return AppCoreBase::OnReceive(type, std::move(b));
+        }));
+    ON_CALL(*this, OnControl(_))
+        .WillByDefault(Invoke([&](tizen_base::Bundle b) -> int {
+          return AppCoreBase::OnControl(std::move(b));
+        }));
+  }
+
+  virtual ~AppCoreBaseMock() = default;
+
+  MOCK_METHOD0(OnCreate, int ());
+  MOCK_METHOD2(OnReceive, int (aul_type, tizen_base::Bundle));
+  MOCK_METHOD1(OnControl, int (tizen_base::Bundle));
+  MOCK_METHOD0(OnTerminate, int ());
+  MOCK_METHOD2(OnLoopInit, void (int, char**));
+  MOCK_METHOD0(OnLoopFinish, void ());
+  MOCK_METHOD0(OnLoopRun, void ());
+  MOCK_METHOD0(OnLoopExit, void ());
+  MOCK_METHOD0(OnTrimMemory, int ());
+
+ private:
+  GMainLoop* loop_ = nullptr;
+};
+
+#endif  // UNIT_TESTS_MOCK_APP_CORE_BASE_MOCK_H_
+
diff --git a/unittests/mock/app_core_efl_base_mock.h b/unittests/mock/app_core_efl_base_mock.h
new file mode 100644 (file)
index 0000000..3148d8c
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_APP_CORE_EFL_BASE_MOCK_H_
+#define UNIT_TESTS_MOCK_APP_CORE_EFL_BASE_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <bundle_cpp.h>
+#include <aul.h>
+
+#include "app_core_efl_base.hh"
+
+class AppCoreEflBaseMock : public tizen_cpp::AppCoreEflBase {
+ public:
+  AppCoreEflBaseMock() : AppCoreEflBase(
+      HINT_WINDOW_GROUP_CONTROL | HINT_WINDOW_STACK_CONTROL |
+      HINT_BG_LAUNCH_CONTROL | HINT_HW_ACC_CONTROL |
+      HINT_WINDOW_AUTO_CONTROL | HINT_LEGACY_CONTROL |
+      HINT_WINDOW_ID_CONTROL) {
+    using ::testing::_;
+    using ::testing::Invoke;
+
+    ON_CALL(*this, OnCreate())
+        .WillByDefault(Invoke([&]() -> int {
+          return AppCoreEflBase::OnCreate();
+        }));
+    ON_CALL(*this, OnTerminate())
+        .WillByDefault(Invoke([&]() -> int {
+          return AppCoreEflBase::OnTerminate();
+        }));
+    ON_CALL(*this, OnReceive(_, _))
+        .WillByDefault(Invoke([&](aul_type type, tizen_base::Bundle b) -> int {
+          return AppCoreEflBase::OnReceive(type, std::move(b));
+        }));
+    ON_CALL(*this, OnControl(_))
+        .WillByDefault(Invoke([&](tizen_base::Bundle b) -> int {
+          return AppCoreEflBase::OnControl(std::move(b));
+        }));
+    ON_CALL(*this, OnPause())
+        .WillByDefault(Invoke([&]() -> int {
+          return AppCoreEflBase::OnPause();
+        }));
+    ON_CALL(*this, OnResume())
+        .WillByDefault(Invoke([&]() -> int {
+          return AppCoreEflBase::OnResume();
+        }));
+    ON_CALL(*this, OnTrimMemory())
+        .WillByDefault(Invoke([&]() -> int {
+          return AppCoreEflBase::OnTrimMemory();
+        }));
+  }
+
+  virtual ~AppCoreEflBaseMock() = default;
+
+  MOCK_METHOD0(OnCreate, int ());
+  MOCK_METHOD2(OnReceive, int (aul_type, tizen_base::Bundle));
+  MOCK_METHOD1(OnControl, int (tizen_base::Bundle));
+  MOCK_METHOD0(OnPause, int ());
+  MOCK_METHOD0(OnResume, int ());
+  MOCK_METHOD0(OnTerminate, int ());
+  MOCK_METHOD0(OnTrimMemory, int ());
+};
+
+#endif  // UNIT_TESTS_MOCK_APP_CORE_EFL_BASE_MOCK_H_
+
diff --git a/unittests/mock/app_core_multi_window_base_context_mock.h b/unittests/mock/app_core_multi_window_base_context_mock.h
new file mode 100644 (file)
index 0000000..ef97ddc
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_APP_CORE_MULTI_WINDOW_BASE_CONTEXT_MOCK_H_
+#define UNIT_TESTS_MOCK_APP_CORE_MULTI_WINDOW_BASE_CONTEXT_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <glib.h>
+
+#include "app_core_multi_window_base.hh"
+
+class AppCoreMultiWindowBaseContextMock : public tizen_cpp::AppCoreMultiWindowBase::Context {
+ public:
+  AppCoreMultiWindowBaseContextMock(std::string context_id, std::string inst_id,
+      tizen_cpp::AppCoreMultiWindowBase* app) : Context(context_id, inst_id, app) {}
+
+  class Factory : public IFactory {
+   public:
+    Factory(std::string context_id, tizen_cpp::AppCoreMultiWindowBase* app) : context_id_(std::move(context_id)) {
+      pre_init_.reset(new testing::NiceMock<AppCoreMultiWindowBaseContextMock>(context_id_, "pre_init", app));
+    }
+
+    std::unique_ptr<Context> Create(std::string inst_id, tizen_cpp::AppCoreMultiWindowBase* app) override {
+      if (inst_id == "pre_init")
+        return std::move(pre_init_);
+
+      return std::unique_ptr<Context>(
+          new testing::NiceMock<AppCoreMultiWindowBaseContextMock>(context_id_, std::move(inst_id), app));
+    }
+
+    testing::NiceMock<AppCoreMultiWindowBaseContextMock>* GetPreInitObj() {
+      return (testing::NiceMock<AppCoreMultiWindowBaseContextMock>*)(pre_init_.get());
+    }
+
+   private:
+    std::string context_id_;
+    std::unique_ptr<Context> pre_init_;
+  };
+
+  MOCK_METHOD0(OnCreate, void ());
+  MOCK_METHOD0(OnTerminate, void ());
+  MOCK_METHOD0(OnPause, void ());
+  MOCK_METHOD0(OnResume, void ());
+};
+
+#endif  // UNIT_TESTS_MOCK_APP_CORE_MULTI_WINDOW_BASE_CONTEXT_MOCK_H_
+
diff --git a/unittests/mock/app_core_multi_window_base_mock.h b/unittests/mock/app_core_multi_window_base_mock.h
new file mode 100644 (file)
index 0000000..ddae120
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_APP_CORE_MULTI_WINDOW_BASE_MOCK_H_
+#define UNIT_TESTS_MOCK_APP_CORE_MULTI_WINDOW_BASE_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <glib.h>
+
+#include "app_core_multi_window_base.hh"
+
+class AppCoreMultiWindowBaseMock : public tizen_cpp::AppCoreMultiWindowBase {
+ public:
+  AppCoreMultiWindowBaseMock() {
+    using ::testing::_;
+    using ::testing::Invoke;
+
+    ON_CALL(*this, OnLoopInit(_, _))
+        .WillByDefault(Invoke([&](int argc, char** argv) {
+          loop_ = g_main_loop_new(nullptr, FALSE);
+        }));
+    ON_CALL(*this, OnLoopFinish())
+        .WillByDefault(Invoke([&]() {
+          g_main_loop_unref(loop_);
+        }));
+    ON_CALL(*this, OnLoopRun())
+        .WillByDefault(Invoke([&]() {
+          g_main_loop_run(loop_);
+        }));
+    ON_CALL(*this, OnLoopExit())
+        .WillByDefault(Invoke([&]() {
+          g_main_loop_quit(loop_);
+        }));
+    ON_CALL(*this, OnCreate())
+        .WillByDefault(Invoke([&]() -> int {
+          return AppCoreMultiWindowBase::OnCreate();
+        }));
+    ON_CALL(*this, OnTerminate())
+        .WillByDefault(Invoke([&]() -> int {
+          return AppCoreMultiWindowBase::OnTerminate();
+        }));
+    ON_CALL(*this, OnControl(_))
+        .WillByDefault(Invoke([&](tizen_base::Bundle b) -> int {
+          return AppCoreMultiWindowBase::OnControl(std::move(b));
+        }));
+  }
+
+  MOCK_METHOD0(OnCreate, int ());
+  MOCK_METHOD0(OnTerminate, int ());
+  MOCK_METHOD1(OnControl, int (tizen_base::Bundle));
+  MOCK_METHOD2(OnLoopInit, void (int, char**));
+  MOCK_METHOD0(OnLoopFinish, void ());
+  MOCK_METHOD0(OnLoopRun, void ());
+  MOCK_METHOD0(OnLoopExit, void ());
+
+ private:
+  GMainLoop* loop_ = nullptr;
+};
+
+#endif  // UNIT_TESTS_MOCK_APP_CORE_MULTI_WINDOW_BASE_MOCK_H_
+
diff --git a/unittests/mock/aul_mock.cc b/unittests/mock/aul_mock.cc
new file mode 100644 (file)
index 0000000..332259f
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <bundle_internal.h>
+
+#include "mock/aul_mock.h"
+#include "mock/mock_hook.h"
+#include "mock/test_fixture.h"
+
+
+extern "C" int aul_launch_init(aul_handler_fn callback, void *user_data) {
+  return MOCK_HOOK_P2(AulMock, aul_launch_init, callback, user_data);
+}
+
+extern "C" void aul_finalize(void) {
+  MOCK_HOOK_P0(AulMock, aul_finalize);
+}
+
+extern "C" int aul_launch_argv_handler(int argc, char **argv) {
+  return MOCK_HOOK_P2(AulMock, aul_launch_argv_handler, argc, argv);
+}
+
+extern "C" int aul_app_get_appid_bypid(int pid, char *appid, int len) {
+  return MOCK_HOOK_P3(AulMock, aul_app_get_appid_bypid, pid, appid, len);
+}
+
+extern "C" const char* aul_get_app_resource_path(void) {
+  return MOCK_HOOK_P0(AulMock, aul_get_app_resource_path);
+}
+
+extern "C" int aul_watchdog_enable(void) {
+  return MOCK_HOOK_P0(AulMock, aul_watchdog_enable);
+}
+
+extern "C" int aul_watchdog_disable(void) {
+  return MOCK_HOOK_P0(AulMock, aul_watchdog_disable);
+}
+
+extern "C" int aul_watchdog_kick(void) {
+  return MOCK_HOOK_P0(AulMock, aul_watchdog_kick);
+}
+
+extern "C" void aul_app_group_lower(int* exit) {
+  MOCK_HOOK_P1(AulMock, aul_app_group_lower, exit);
+}
\ No newline at end of file
diff --git a/unittests/mock/aul_mock.h b/unittests/mock/aul_mock.h
new file mode 100644 (file)
index 0000000..7348693
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_AUL_MOCK_H_
+#define UNIT_TESTS_MOCK_AUL_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <bundle.h>
+#include <bundle_cpp.h>
+#include <aul.h>
+
+#include "mock/module_mock.h"
+
+class AulMock : public virtual ModuleMock {
+ public:
+  AulMock() {
+    using ::testing::_;
+    using ::testing::Return;
+    using ::testing::Invoke;
+
+    ON_CALL(*this, aul_launch_init(_, _))
+        .WillByDefault(Invoke([&](aul_handler_fn callback, void *user_data) -> int {
+          callback_ = callback;
+          user_data_ = user_data;
+          return 0;
+        }));
+    ON_CALL(*this, aul_finalize())
+        .WillByDefault(Invoke([&]() {
+          callback_ = nullptr;
+          user_data_ = nullptr;
+          if (timer_) {
+            g_source_remove(timer_);
+            timer_ = 0;
+          }
+          if (args_) {
+            bundle_free(args_);
+            args_ = nullptr;
+          }
+        }));
+    ON_CALL(*this, aul_launch_argv_handler(_, _))
+        .WillByDefault(Invoke([&](int argc, char **argv) -> int {
+          args_ = bundle_import_from_argv(argc, argv);
+          timer_ = g_idle_add([](gpointer data)-> gboolean {
+                AulMock* obj = static_cast<AulMock*>(data);
+                if (obj->callback_)
+                  obj->callback_(AUL_START, obj->args_, obj->user_data_);
+                obj->timer_ = 0;
+                return G_SOURCE_REMOVE;
+              }, this);
+          if (timer_ <= 0)
+            return AUL_R_ERROR;
+
+          return AUL_R_OK;
+        }));
+    ON_CALL(*this, aul_app_get_appid_bypid(_, _, _))
+        .WillByDefault(Invoke([&](int pid, char *appid, int len) -> int {
+          snprintf(appid, len, "test_appid");
+          return 0;
+        }));
+    ON_CALL(*this, aul_get_app_resource_path())
+        .WillByDefault(Invoke([&]() -> const char* {
+          static const char res_path[] = "/tmp/";
+          return res_path;
+        }));
+    ON_CALL(*this, aul_watchdog_enable())
+        .WillByDefault(Return(0));
+    ON_CALL(*this, aul_watchdog_disable())
+        .WillByDefault(Return(0));
+    ON_CALL(*this, aul_watchdog_kick())
+        .WillByDefault(Return(0));
+  }
+
+  virtual ~AulMock() {}
+
+  MOCK_METHOD2(aul_launch_init, int (aul_handler_fn , void*));
+  MOCK_METHOD0(aul_finalize, void ());
+  MOCK_METHOD2(aul_launch_argv_handler, int (int, char **));
+  MOCK_METHOD3(aul_app_get_appid_bypid, int (int, char*, int));
+  MOCK_METHOD0(aul_get_app_resource_path, const char* ());
+  MOCK_METHOD0(aul_watchdog_enable, int ());
+  MOCK_METHOD0(aul_watchdog_disable, int ());
+  MOCK_METHOD0(aul_watchdog_kick, int ());
+  MOCK_METHOD1(aul_app_group_lower, void (int*));
+
+  void SetEvent(aul_type type, bundle* b) {
+    if (args_)
+      bundle_free(args_);
+    args_ = b;
+    type_ = type;
+    g_idle_add([](gpointer data)-> gboolean {
+          AulMock* obj = static_cast<AulMock*>(data);
+          tizen_base::Bundle args(obj->args_);
+          bundle_free(obj->args_);
+          obj->args_ = nullptr;
+          if (obj->callback_) {
+            obj->callback_(obj->type_, args.GetHandle(), obj->user_data_);
+          }
+          return G_SOURCE_REMOVE;
+        }, this);
+  }
+
+ private:
+  aul_handler_fn callback_ = nullptr;
+  void* user_data_ = nullptr;
+  guint timer_ = 0;
+  bundle* args_ = nullptr;
+  aul_type type_ = static_cast<aul_type>(-1);
+};
+
+#endif  // UNIT_TESTS_MOCK_AUL_MOCK_H_
+
diff --git a/unittests/mock/dbus_mock.cc b/unittests/mock/dbus_mock.cc
new file mode 100644 (file)
index 0000000..56f23d0
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "mock/dbus_mock.h"
+#include "mock/mock_hook.h"
+#include "mock/test_fixture.h"
+
+extern "C" GDBusConnection* g_bus_get_sync(GBusType bus_type,
+    GCancellable* cancellable, GError** error) {
+  return MOCK_HOOK_P3(DbusMock, g_bus_get_sync, bus_type, cancellable, error);
+}
+
+extern "C" guint g_dbus_connection_signal_subscribe(GDBusConnection* arg0,
+    const gchar* arg1, const gchar* arg2, const gchar* arg3, const gchar* arg4,
+    const gchar* arg5, GDBusSignalFlags arg6, GDBusSignalCallback arg7,
+    gpointer arg8, GDestroyNotify arg9) {
+  return MOCK_HOOK_P10(DbusMock, g_dbus_connection_signal_subscribe,
+      arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
+}
diff --git a/unittests/mock/dbus_mock.h b/unittests/mock/dbus_mock.h
new file mode 100644 (file)
index 0000000..c4bf82b
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_DBUS_MOCK_H_
+#define UNIT_TESTS_MOCK_DBUS_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "mock/module_mock.h"
+
+class DbusMock : public virtual ModuleMock {
+ public:
+  DbusMock() {
+    using ::testing::_;
+    using ::testing::Return;
+    using ::testing::Invoke;
+
+    static int dummy;
+    conn_ = (GDBusConnection*)&dummy;
+
+    ON_CALL(*this, g_bus_get_sync(_, _, _))
+      .WillByDefault(Return(conn_));
+  }
+
+  MOCK_METHOD3(g_bus_get_sync, GDBusConnection* (GBusType, GCancellable*, GError**));
+  MOCK_METHOD10(g_dbus_connection_signal_subscribe,
+      guint(GDBusConnection*, const gchar*, const gchar*, const gchar*,
+      const gchar*, const gchar*, GDBusSignalFlags, GDBusSignalCallback,
+      gpointer, GDestroyNotify));
+
+  private:
+    GDBusConnection* conn_ = nullptr;
+};
+
+#endif  // UNIT_TESTS_MOCK_DBUS_MOCK_H_
+
diff --git a/unittests/mock/dl_mock.cc b/unittests/mock/dl_mock.cc
new file mode 100644 (file)
index 0000000..c322708
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "mock/dl_mock.h"
+#include "mock/mock_hook.h"
+#include "mock/test_fixture.h"
+
+int DlMock::dummy_;
+
+extern "C" void* dlopen(const char* name, int mode) {
+  return MOCK_HOOK_P2(DlMock, dlopen, name, mode);
+}
+
+extern "C" int dlclose(void* handle) {
+  return MOCK_HOOK_P1(DlMock, dlclose, handle);
+}
+
+extern "C" void* dlsym(void* handle, const char* name) {
+  return MOCK_HOOK_P2(DlMock, dlsym, handle, name);
+}
+
+extern "C" int access(const char* pathname, int mode) {
+  return MOCK_HOOK_P2(DlMock, access, pathname, mode);
+}
diff --git a/unittests/mock/dl_mock.h b/unittests/mock/dl_mock.h
new file mode 100644 (file)
index 0000000..3a148b7
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_DL_MOCK_H_
+#define UNIT_TESTS_MOCK_DL_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <dlfcn.h>
+
+#include "mock/module_mock.h"
+
+class DlMock : public virtual ModuleMock {
+ public:
+  DlMock() {
+    using ::testing::_;
+    using ::testing::Return;
+    using ::testing::Invoke;
+
+    ON_CALL(*this, dlopen(_, _))
+        .WillByDefault(Return((void*)&dummy_));
+    ON_CALL(*this, dlclose(_))
+        .WillByDefault(Return(0));
+    ON_CALL(*this, dlsym(_, _))
+        .WillByDefault(Return(nullptr));
+    ON_CALL(*this, access(_, _))
+        .WillByDefault(Return(0));
+  }
+
+  MOCK_METHOD2(dlopen, void* (const char*, int));
+  MOCK_METHOD1(dlclose, int (void*));
+  MOCK_METHOD2(dlsym, void* (void*, const char*));
+  MOCK_METHOD2(access, int (const char*, int));
+
+ private:
+  static int dummy_;
+};
+
+#endif  // UNIT_TESTS_MOCK_DL_MOCK_H_
+
diff --git a/unittests/mock/ecore_mock.cc b/unittests/mock/ecore_mock.cc
new file mode 100644 (file)
index 0000000..7812dce
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "mock/ecore_mock.h"
+#include "mock/mock_hook.h"
+#include "mock/test_fixture.h"
+
+
+extern "C" Ecore_Event_Handler* ecore_event_handler_add(
+    int type, Ecore_Event_Handler_Cb func, const void* data) {
+  return MOCK_HOOK_P3(EcoreMock, ecore_event_handler_add, type, func, data);
+}
+
+extern "C" void* ecore_event_handler_del(Ecore_Event_Handler* event_handler) {
+  return MOCK_HOOK_P1(EcoreMock, ecore_event_handler_del, event_handler);
+}
diff --git a/unittests/mock/ecore_mock.h b/unittests/mock/ecore_mock.h
new file mode 100644 (file)
index 0000000..e6e7b4d
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_ECORE_MOCK_H_
+#define UNIT_TESTS_MOCK_ECORE_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <Ecore_Wl2.h>
+
+#include "mock/module_mock.h"
+
+#include <map>
+
+class EcoreMock : public virtual ModuleMock {
+ public:
+  EcoreMock() {
+    using ::testing::_;
+    using ::testing::Invoke;
+
+    ON_CALL(*this, ecore_event_handler_add(_, _, _))
+      .WillByDefault(Invoke([&](int type, Ecore_Event_Handler_Cb cb, const void* data) -> Ecore_Event_Handler* {
+        static int dummy;
+        events_[type] = std::pair<Ecore_Event_Handler_Cb, const void*>(cb, data);
+        return (Ecore_Event_Handler*)&dummy;
+      }));
+    ON_CALL(*this, ecore_event_handler_del(_))
+      .WillByDefault(Invoke([&](Ecore_Event_Handler*) -> void* {
+        return nullptr;
+      }));
+  }
+
+  void SendEvent(int type, void* event) {
+    auto val = events_[type];
+    val.first((void*)(val.second), type, event);
+  }
+
+  MOCK_METHOD3(ecore_event_handler_add,
+      Ecore_Event_Handler*(int, Ecore_Event_Handler_Cb, const void*));
+  MOCK_METHOD1(ecore_event_handler_del,
+      void*(Ecore_Event_Handler*));
+
+ private:
+  std::map<int, std::pair<Ecore_Event_Handler_Cb, const void*>> events_;
+};
+
+#endif  // UNIT_TESTS_MOCK_ECORE_MOCK_H_
+
diff --git a/unittests/mock/ecore_wl2_mock.cc b/unittests/mock/ecore_wl2_mock.cc
new file mode 100644 (file)
index 0000000..3a380fe
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "mock/ecore_wl2_mock.h"
+#include "mock/mock_hook.h"
+#include "mock/test_fixture.h"
+
+
+extern "C" int ecore_wl2_init() {
+  return MOCK_HOOK_P0(EcoreWl2Mock, ecore_wl2_init);
+}
+
+extern "C" Ecore_Wl2_Display* ecore_wl2_connected_display_get(
+    const char *display) {
+  return MOCK_HOOK_P1(EcoreWl2Mock, ecore_wl2_connected_display_get, display);
+}
+
+extern "C" void ecore_wl2_window_activate(Ecore_Wl2_Window* window) {
+  return MOCK_HOOK_P1(EcoreWl2Mock, ecore_wl2_window_activate, window);
+}
+
+extern "C" void ecore_wl2_window_iconified_set(
+    Ecore_Wl2_Window *win, Eina_Bool flag) {
+  return MOCK_HOOK_P2(EcoreWl2Mock, ecore_wl2_window_iconified_set, win, flag);
+}
+
+extern "C" void ecore_wl2_window_class_set(
+    Ecore_Wl2_Window *win, const char *name) {
+  return MOCK_HOOK_P2(EcoreWl2Mock, ecore_wl2_window_class_set, win, name);
+}
+
+extern "C" int ecore_wl2_window_id_get(
+    Ecore_Wl2_Window *win) {
+  return MOCK_HOOK_P1(EcoreWl2Mock, ecore_wl2_window_id_get, win);
+}
+
+extern "C" void ecore_wl2_display_disconnect(
+    Ecore_Wl2_Display *display) {
+  return MOCK_HOOK_P1(EcoreWl2Mock, ecore_wl2_display_disconnect, display);
+}
+
+extern "C" int ecore_wl2_shutdown() {
+  return MOCK_HOOK_P0(EcoreWl2Mock, ecore_wl2_shutdown);
+}
+
+extern "C" Ecore_Wl2_Display *ecore_wl2_display_connect(const char *conn) {
+  return MOCK_HOOK_P1(EcoreWl2Mock, ecore_wl2_display_connect, conn);
+}
+
+extern "C" struct wl_surface *ecore_wl2_window_surface_get(Ecore_Wl2_Window *window) {
+  return MOCK_HOOK_P1(EcoreWl2Mock, ecore_wl2_window_surface_get, window);
+}
+
+extern "C" Ecore_Wl2_Window* ecore_wl2_display_window_find(
+    Ecore_Wl2_Display* display, unsigned int id) {
+  return MOCK_HOOK_P2(EcoreWl2Mock, ecore_wl2_display_window_find, display, id);
+}
\ No newline at end of file
diff --git a/unittests/mock/ecore_wl2_mock.h b/unittests/mock/ecore_wl2_mock.h
new file mode 100644 (file)
index 0000000..558ddd3
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_ECORE_WL2_MOCK_H_
+#define UNIT_TESTS_MOCK_ECORE_WL2_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <Ecore_Wl2.h>
+
+#include "mock/module_mock.h"
+
+class EcoreWl2Mock : public virtual ModuleMock {
+ public:
+  EcoreWl2Mock() {
+    using ::testing::_;
+    using ::testing::Invoke;
+
+    ON_CALL(*this, ecore_wl2_init())
+      .WillByDefault(Invoke([&]() -> int {
+          ECORE_WL2_EVENT_WINDOW_SHOW = 1;
+          ECORE_WL2_EVENT_WINDOW_HIDE = 2;
+          ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE = 3;
+          ECORE_WL2_EVENT_WINDOW_LOWER = 4;
+          ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE = 5;
+          ECORE_WL2_EVENT_AUX_MESSAGE = 6;
+        return 1;
+      }));
+  }
+
+  MOCK_METHOD0(ecore_wl2_init, int());
+  MOCK_METHOD1(ecore_wl2_connected_display_get,
+      Ecore_Wl2_Display*(const char *));
+  MOCK_METHOD2(ecore_wl2_window_iconified_set,
+      void(Ecore_Wl2_Window *, Eina_Bool));
+  MOCK_METHOD2(ecore_wl2_window_class_set,
+      void(Ecore_Wl2_Window *, const char *));
+  MOCK_METHOD1(ecore_wl2_window_id_get,
+      int(Ecore_Wl2_Window *));
+  MOCK_METHOD1(ecore_wl2_display_disconnect,
+      void(Ecore_Wl2_Display *));
+  MOCK_METHOD0(ecore_wl2_shutdown, int());
+  MOCK_METHOD1(ecore_wl2_display_connect,
+      Ecore_Wl2_Display *(const char *));
+  MOCK_METHOD1(ecore_wl2_window_surface_get,
+      struct wl_surface *(Ecore_Wl2_Window *));
+  MOCK_METHOD1(ecore_wl2_window_activate, void (Ecore_Wl2_Window*));
+  MOCK_METHOD2(ecore_wl2_display_window_find,
+      Ecore_Wl2_Window* (Ecore_Wl2_Display*, unsigned int));
+};
+
+#endif  // UNIT_TESTS_MOCK_ECORE_WL2_MOCK_H_
+
diff --git a/unittests/mock/elm_mock.cc b/unittests/mock/elm_mock.cc
new file mode 100644 (file)
index 0000000..eb4eef1
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "mock/elm_mock.h"
+#include "mock/mock_hook.h"
+#include "mock/test_fixture.h"
+
+extern "C" int elm_init(int argc, char** argv) {
+  return MOCK_HOOK_P2(ElmMock, elm_init, argc, argv);
+}
+
+extern "C" int elm_shutdown() {
+  return MOCK_HOOK_P0(ElmMock, elm_shutdown);
+}
+
+extern "C" void elm_run() {
+  MOCK_HOOK_P0(ElmMock, elm_run);
+}
+
+extern "C" void elm_exit() {
+  MOCK_HOOK_P0(ElmMock, elm_exit);
+}
+
+extern "C" void elm_config_accel_preference_set(const char* arg1) {
+  MOCK_HOOK_P1(ElmMock, elm_config_accel_preference_set, arg1);
+}
+
+extern "C" void elm_cache_all_flush() {
+  MOCK_HOOK_P0(ElmMock, elm_cache_all_flush);
+}
diff --git a/unittests/mock/elm_mock.h b/unittests/mock/elm_mock.h
new file mode 100644 (file)
index 0000000..51f601c
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_ELM_MOCK_H_
+#define UNIT_TESTS_MOCK_ELM_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <glib.h>
+#include <Elementary.h>
+
+#include "mock/module_mock.h"
+
+class ElmMock : public virtual ModuleMock {
+ public:
+  ElmMock() {
+    using ::testing::_;
+    using ::testing::Invoke;
+
+    ON_CALL(*this, elm_init(_, _))
+      .WillByDefault(Invoke([&](int argc, char **argv) -> int {
+        loop_ = g_main_loop_new(NULL, FALSE);
+        return 0;
+      }));
+    ON_CALL(*this, elm_shutdown())
+      .WillByDefault(Invoke([&]() -> int {
+        g_main_loop_unref(loop_);
+        return 0;
+      }));
+    ON_CALL(*this, elm_run())
+      .WillByDefault(Invoke([&]() {
+        g_main_loop_run(loop_);
+      }));
+    ON_CALL(*this, elm_exit())
+      .WillByDefault(Invoke([&]() {
+        g_main_loop_quit(loop_);
+      }));
+  }
+
+  MOCK_METHOD2(elm_init, int (int, char**));
+  MOCK_METHOD0(elm_shutdown, int ());
+  MOCK_METHOD0(elm_run, void ());
+  MOCK_METHOD0(elm_exit, void ());
+  MOCK_METHOD1(elm_config_accel_preference_set, void (const char*));
+  MOCK_METHOD0(elm_cache_all_flush, void ());
+
+ private:
+  GMainLoop* loop_ = nullptr;
+};
+
+#endif  // UNIT_TESTS_MOCK_ELM_MOCK_H_
+
diff --git a/unittests/mock/mock_hook.h b/unittests/mock/mock_hook.h
new file mode 100644 (file)
index 0000000..4a77577
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 MOCK_MOCK_HOOK_H_
+#define MOCK_MOCK_HOOK_H_
+
+#define MOCK_HOOK_P0(MOCK_CLASS, f)                                            \
+    TestFixture::GetMock<MOCK_CLASS>().f()
+#define MOCK_HOOK_P1(MOCK_CLASS, f, p1)                                        \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1)
+#define MOCK_HOOK_P2(MOCK_CLASS, f, p1, p2)                                    \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2)
+#define MOCK_HOOK_P3(MOCK_CLASS, f, p1, p2, p3)                                \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3)
+#define MOCK_HOOK_P4(MOCK_CLASS, f, p1, p2, p3, p4)                            \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4)
+#define MOCK_HOOK_P5(MOCK_CLASS, f, p1, p2, p3, p4, p5)                        \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4, p5)
+#define MOCK_HOOK_P6(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6)                    \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4, p5, p6)
+#define MOCK_HOOK_P7(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6, p7)                \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4, p5, p6, p7)
+#define MOCK_HOOK_P8(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6, p7, p8)            \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4, p5, p6, p7, p8)
+#define MOCK_HOOK_P10(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)  \
+    TestFixture::GetMock<MOCK_CLASS>().f(                                      \
+        p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
+
+#endif  // MOCK_MOCK_HOOK_H_
diff --git a/unittests/mock/module_mock.h b/unittests/mock/module_mock.h
new file mode 100644 (file)
index 0000000..1b7b73e
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 MOCK_MODULE_MOCK_H_
+#define MOCK_MODULE_MOCK_H_
+
+class ModuleMock {
+ public:
+  virtual ~ModuleMock() {}
+};
+
+#endif  // MOCK_MODULE_MOCK_H_
diff --git a/unittests/mock/sensor_mock.cc b/unittests/mock/sensor_mock.cc
new file mode 100644 (file)
index 0000000..aa1c640
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "mock/sensor_mock.h"
+#include "mock/mock_hook.h"
+#include "mock/test_fixture.h"
+
+
+extern "C" int sensord_connect(sensor_t sensor) {
+  return MOCK_HOOK_P1(SensorMock, sensord_connect, sensor);
+}
+
+extern "C" bool sensord_disconnect(int handle) {
+  return MOCK_HOOK_P1(SensorMock, sensord_disconnect, handle);
+}
+
+extern "C" bool sensord_register_event(int handle, unsigned int event_type,
+    unsigned int interval, unsigned int max_batch_latency,
+    sensor_cb_t cb, void *user_data) {
+  return MOCK_HOOK_P6(SensorMock, sensord_register_event,
+      handle, event_type, interval, max_batch_latency, cb, user_data);
+}
+
+extern "C" bool sensord_unregister_event(int handle, unsigned int event_type) {
+  return MOCK_HOOK_P2(SensorMock, sensord_unregister_event, handle, event_type);
+}
+
+extern "C" bool sensord_start(int handle, int option) {
+  return MOCK_HOOK_P2(SensorMock, sensord_start, handle, option);
+}
+
+extern "C" bool sensord_stop(int handle) {
+  return MOCK_HOOK_P1(SensorMock, sensord_stop, handle);
+}
+
+extern "C" bool sensord_get_data(int handle, unsigned int data_id,
+    sensor_data_t* sensor_data) {
+  return MOCK_HOOK_P3(SensorMock, sensord_get_data, handle, data_id, sensor_data);
+}
\ No newline at end of file
diff --git a/unittests/mock/sensor_mock.h b/unittests/mock/sensor_mock.h
new file mode 100644 (file)
index 0000000..90b6697
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_SENSOR_MOCK_H_
+#define UNIT_TESTS_MOCK_SENSOR_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <sensor_internal.h>
+
+#include "mock/module_mock.h"
+
+class SensorMock : public virtual ModuleMock {
+ public:
+  SensorMock() {
+    using ::testing::_;
+    using ::testing::Return;
+    using ::testing::Invoke;
+
+    ON_CALL(*this, sensord_connect(_))
+      .WillByDefault(Return(1));
+    ON_CALL(*this, sensord_disconnect(_))
+      .WillByDefault(Return(true));
+    ON_CALL(*this, sensord_register_event(_, _, _, _, _, _))
+      .WillByDefault(Return(true));
+    ON_CALL(*this, sensord_unregister_event(_, _))
+      .WillByDefault(Return(true));
+    ON_CALL(*this, sensord_start(_, _))
+      .WillByDefault(Return(true));
+    ON_CALL(*this, sensord_stop(_))
+      .WillByDefault(Return(true));
+    ON_CALL(*this, sensord_get_data(_, _, _))
+      .WillByDefault(Invoke([&](int handle, unsigned int data_id,
+          sensor_data_t* sensor_data) -> bool {
+        sensor_data->value_count = 1;
+        sensor_data->values[0] = AUTO_ROTATION_DEGREE_0;
+        return true;
+      }));
+  }
+
+  MOCK_METHOD1(sensord_connect, int (sensor_t));
+  MOCK_METHOD1(sensord_disconnect, bool (int));
+  MOCK_METHOD6(sensord_register_event, bool (int, unsigned int,
+      unsigned int, unsigned int, sensor_cb_t, void*));
+  MOCK_METHOD2(sensord_unregister_event, bool (int, unsigned int));
+  MOCK_METHOD2(sensord_start, bool (int, int));
+  MOCK_METHOD1(sensord_stop, bool (int));
+  MOCK_METHOD3(sensord_get_data, bool (int, unsigned int, sensor_data_t*));
+};
+
+#endif  // UNIT_TESTS_MOCK_SENSOR_MOCK_H_
+
diff --git a/unittests/mock/test_fixture.cc b/unittests/mock/test_fixture.cc
new file mode 100644 (file)
index 0000000..8abae0c
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_fixture.h"
+
+#include <memory>
+
+std::unique_ptr<ModuleMock> TestFixture::mock_;
diff --git a/unittests/mock/test_fixture.h b/unittests/mock/test_fixture.h
new file mode 100644 (file)
index 0000000..1bd48c9
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 MOCK_TEST_FIXTURE_H_
+#define MOCK_TEST_FIXTURE_H_
+
+#include <gtest/gtest.h>
+
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <utility>
+
+#include "module_mock.h"
+
+class TestFixture : public ::testing::Test {
+ public:
+  explicit TestFixture(std::unique_ptr<ModuleMock>&& mock) {
+    mock_ = std::move(mock);
+  }
+  virtual ~TestFixture() {
+    mock_.reset();
+  }
+
+  virtual void SetUp() {}
+  virtual void TearDown() {}
+
+  template <typename T>
+  static T& GetMock() {
+    auto ptr = dynamic_cast<T*>(mock_.get());
+    if (!ptr)
+      throw std::invalid_argument("The test does not provide mock of \"" +
+          std::string(typeid(T).name()) + "\"");
+    return *ptr;
+  }
+
+  static std::unique_ptr<ModuleMock> mock_;
+};
+
+#endif  // MOCK_TEST_FIXTURE_H_
diff --git a/unittests/mock/vconf_mock.cc b/unittests/mock/vconf_mock.cc
new file mode 100644 (file)
index 0000000..de7d364
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "mock/vconf_mock.h"
+#include "mock/mock_hook.h"
+#include "mock/test_fixture.h"
+
+
+extern "C" int vconf_notify_key_changed(const char *in_key,
+    vconf_callback_fn cb, void *user_data) {
+  return MOCK_HOOK_P3(VConfMock, vconf_notify_key_changed,
+      in_key, cb, user_data);
+}
+
+extern "C" int vconf_ignore_key_changed(const char *in_key,
+    vconf_callback_fn cb) {
+  return MOCK_HOOK_P2(VConfMock, vconf_ignore_key_changed,
+      in_key, cb);
+}
+
+extern "C" char* vconf_get_str(const char* in_key) {
+  return MOCK_HOOK_P1(VConfMock, vconf_get_str, in_key);
+}
+
+extern "C" int vconf_get_int(const char* in_key, int* val) {
+  return MOCK_HOOK_P2(VConfMock, vconf_get_int, in_key, val);
+}
+
+extern "C" int vconf_get_bool(const char* in_key, int* val) {
+  return MOCK_HOOK_P2(VConfMock, vconf_get_bool, in_key, val);
+}
diff --git a/unittests/mock/vconf_mock.h b/unittests/mock/vconf_mock.h
new file mode 100644 (file)
index 0000000..1c3b18c
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_VCONF_MOCK_H_
+#define UNIT_TESTS_MOCK_VCONF_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <vconf.h>
+
+#include "mock/module_mock.h"
+
+#include <map>
+
+class VConfMock : public virtual ModuleMock {
+ public:
+  VConfMock() {
+    using ::testing::_;
+    using ::testing::Return;
+    using ::testing::Invoke;
+
+    ON_CALL(*this, vconf_notify_key_changed(_, _, _))
+      .WillByDefault(Invoke([&](const char *in_key,
+          vconf_callback_fn cb, void *user_data) -> int {
+        data_[in_key] = { cb, user_data };
+        return 0;
+      }));
+    ON_CALL(*this, vconf_ignore_key_changed(_, _))
+      .WillByDefault(Invoke([&](const char *in_key,
+          vconf_callback_fn cb) -> int {
+        data_.erase(in_key);
+        return 0;
+      }));
+    ON_CALL(*this, vconf_get_str(_))
+      .WillByDefault(Return(nullptr));
+    ON_CALL(*this, vconf_get_int(_, _))
+      .WillByDefault(Invoke([&](const char *in_key,
+          int* val) -> int {
+        *val = 0;
+        return 0;
+      }));
+    ON_CALL(*this, vconf_get_bool(_, _))
+      .WillByDefault(Invoke([&](const char *in_key,
+          int* val) -> int {
+        *val = 0;
+        return 0;
+      }));
+  }
+
+  MOCK_METHOD3(vconf_notify_key_changed, int (const char*,
+      vconf_callback_fn, void*));
+  MOCK_METHOD2(vconf_ignore_key_changed, int (const char*,
+      vconf_callback_fn));
+  MOCK_METHOD1(vconf_get_str, char* (const char*));
+  MOCK_METHOD2(vconf_get_int, int (const char*, int*));
+  MOCK_METHOD2(vconf_get_bool, int (const char*, int*));
+
+  void ChangeStr(const std::string& key, const std::string& val) {
+    if (data_.find(key) == data_.end())
+      return;
+
+    keynode_t node;
+    node.type = VCONF_TYPE_STRING;
+    node.keyname = const_cast<char*>(key.c_str());
+    node.value.s = const_cast<char*>(val.c_str());
+
+    data_[key].first(&node, data_[key].second);
+  }
+
+  void ChangeInt(const std::string& key, int val) {
+    if (data_.find(key) == data_.end())
+      return;
+
+    keynode_t node;
+    node.type = VCONF_TYPE_INT;
+    node.keyname = const_cast<char*>(key.c_str());
+    node.value.i = val;
+
+    data_[key].first(&node, data_[key].second);
+  }
+
+  void ChangeBool(const std::string& key, bool val) {
+    if (data_.find(key) == data_.end())
+      return;
+
+    keynode_t node;
+    node.type = VCONF_TYPE_BOOL;
+    node.keyname = const_cast<char*>(key.c_str());
+    node.value.b = val;
+
+    data_[key].first(&node, data_[key].second);
+  }
+
+ private:
+  std::map<std::string, std::pair<vconf_callback_fn, void*>> data_;
+};
+
+#endif  // UNIT_TESTS_MOCK_VCONF_MOCK_H_
+
diff --git a/unittests/mock/wayland_mock.cc b/unittests/mock/wayland_mock.cc
new file mode 100644 (file)
index 0000000..9040e03
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "mock/wayland_mock.h"
+#include "mock/mock_hook.h"
+#include "mock/test_fixture.h"
+
+extern "C" wl_display* wl_display_connect(const char *name) {
+  return MOCK_HOOK_P1(WaylandMock, wl_display_connect, name);
+}
+
+extern "C" void wl_display_disconnect(wl_display* display) {
+  MOCK_HOOK_P1(WaylandMock, wl_display_disconnect, display);
+}
+
+extern "C" wl_proxy* wl_proxy_marshal_constructor(wl_proxy* proxy, uint32_t opcode,
+    const wl_interface* interface, ...) {
+  static int dummy;
+  return (wl_proxy*)&dummy;
+}
+
+extern "C" int wl_proxy_add_listener(wl_proxy *proxy,
+    void (**implementation)(void), void *data) {
+  return MOCK_HOOK_P3(WaylandMock, wl_proxy_add_listener, proxy,
+      implementation, data);
+}
+
+extern "C" int wl_display_roundtrip(wl_display* display) {
+  return MOCK_HOOK_P1(WaylandMock, wl_display_roundtrip, display);
+}
+
+extern "C" void wl_proxy_marshal(wl_proxy *proxy, uint32_t opcode, ...) {
+}
+
+extern "C" void wl_proxy_destroy(wl_proxy *proxy) {
+}
diff --git a/unittests/mock/wayland_mock.h b/unittests/mock/wayland_mock.h
new file mode 100644 (file)
index 0000000..91ca2fe
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 UNIT_TESTS_MOCK_WAYLAND_MOCK_H_
+#define UNIT_TESTS_MOCK_WAYLAND_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <wayland-client.h>
+#include <wayland-tbm-client.h>
+#include <tizen-extension-client-protocol.h>
+
+#include "mock/module_mock.h"
+
+class WaylandMock : public virtual ModuleMock {
+ public:
+  WaylandMock() {
+    using ::testing::_;
+    using ::testing::Invoke;
+
+    ON_CALL(*this, wl_display_connect(_))
+      .WillByDefault(Invoke([&](const char*) -> wl_display* {
+        static int dummy;
+        return (wl_display*)&dummy;
+      }));
+  }
+
+  MOCK_METHOD1(wl_display_connect, wl_display* (const char*));
+  MOCK_METHOD1(wl_display_disconnect, void (wl_display*));
+  MOCK_METHOD3(wl_proxy_add_listener, int (wl_proxy*, void (**)(void), void*));
+  MOCK_METHOD1(wl_display_roundtrip, int (wl_display*));
+};
+
+#endif  // UNIT_TESTS_MOCK_WAYLAND_MOCK_H_
+