From b2321481540505a395233987b535c0d457d41df7 Mon Sep 17 00:00:00 2001 From: "huiyu.eun" Date: Mon, 15 Apr 2024 19:47:02 +0900 Subject: [PATCH] Split tizen-application model Change-Id: Icc01f4c961a773ed5769477057bb71be070383b4 Signed-off-by: huiyu.eun --- build/tizen/CMakeLists.txt | 8 + build/tizen/application-model/CMakeLists.txt | 101 ++ .../dali2-adaptor-application-normal.pc.in | 15 + build/tizen/deps-check.cmake | 1 + dali/internal/adaptor/common/framework.h | 20 + .../adaptor/tizen-wayland/framework-tizen.cpp | 1313 ++------------------ .../adaptor/tizen-wayland/framework-tizen.h | 31 +- .../appmodel-component-based-tizen.cpp | 195 +++ .../appmodel-component-based-tizen.h | 55 + dali/internal/application-model/file.list | 18 + .../normal/appmodel-normal-tizen.cpp | 803 ++++++++++++ .../normal/appmodel-normal-tizen.h | 55 + .../watch/appmodel-watch-tizen.cpp | 444 +++++++ .../application-model/watch/appmodel-watch-tizen.h | 56 + .../widget/appmodel-widget-tizen.cpp | 451 +++++++ .../widget/appmodel-widget-tizen.h | 59 + .../application-model/widget/widget-base-tizen.cpp | 243 ++++ .../application-model/widget/widget-base-tizen.h | 52 + .../widget-application-impl-tizen.cpp | 247 +--- .../tizen-wayland/widget-application-impl-tizen.h | 26 +- .../tizen-wayland/widget-controller-tizen.cpp | 46 +- dali/public-api/watch/watch-time.h | 2 +- packaging/dali-adaptor.spec | 5 + 23 files changed, 2843 insertions(+), 1403 deletions(-) create mode 100644 build/tizen/application-model/CMakeLists.txt create mode 100644 build/tizen/application-model/dali2-adaptor-application-normal.pc.in create mode 100644 dali/internal/application-model/component-based/appmodel-component-based-tizen.cpp create mode 100644 dali/internal/application-model/component-based/appmodel-component-based-tizen.h create mode 100644 dali/internal/application-model/file.list create mode 100644 dali/internal/application-model/normal/appmodel-normal-tizen.cpp create mode 100644 dali/internal/application-model/normal/appmodel-normal-tizen.h create mode 100644 dali/internal/application-model/watch/appmodel-watch-tizen.cpp create mode 100644 dali/internal/application-model/watch/appmodel-watch-tizen.h create mode 100644 dali/internal/application-model/widget/appmodel-widget-tizen.cpp create mode 100644 dali/internal/application-model/widget/appmodel-widget-tizen.h create mode 100644 dali/internal/application-model/widget/widget-base-tizen.cpp create mode 100644 dali/internal/application-model/widget/widget-base-tizen.h diff --git a/build/tizen/CMakeLists.txt b/build/tizen/CMakeLists.txt index 3ba49c3..c26a58e 100644 --- a/build/tizen/CMakeLists.txt +++ b/build/tizen/CMakeLists.txt @@ -18,6 +18,7 @@ ENDIF() OPTION(ENABLE_PKG_CONFIGURE "Use pkgconfig" ON) OPTION(ENABLE_LINK_TEST "Enable the link test" ON) OPTION(ENABLE_ATSPI "Enable AT-SPI accessibility" ON) +OPTION(ENABLE_APPMODEL "Enable AppModel" OFF) OPTION(ENABLE_TRACE "Enable Trace" OFF) OPTION(ENABLE_TRACE_STREAMLINE "Enable Trace (Streamline)" OFF) @@ -292,6 +293,7 @@ ENDMACRO(INSTALL_HEADERS_WITH_DIRECTORY) SET( tizenadaptorpublicapidir ${INCLUDE_DIR}/dali/public-api ) SET( tizenadaptordevelapidir ${INCLUDE_DIR}/dali/devel-api ) SET( tizenadaptorintegrationapidir ${INCLUDE_DIR}/dali/integration-api/adaptor-framework ) +SET( tizenadaptorapplicationapidir ${INCLUDE_DIR}/dali/internal/application-model ) SET( tizenadaptorframeworkpublicapidir ${tizenadaptorpublicapidir}/adaptor-framework ) SET( tizenadaptorframeworkdevelapidir ${tizenadaptordevelapidir}/adaptor-framework ) SET( tizencanvasrendererdevelapidir ${tizenadaptorframeworkdevelapidir}/canvas-renderer ) @@ -308,6 +310,7 @@ SET( androidadaptorintegrationapidir ${INCLUDE_DIR}/dali/integration-api/adaptor # Install headers INSTALL( FILES ${public_api_header_files} DESTINATION ${tizenadaptorpublicapidir} ) INSTALL( FILES ${adaptor_integration_api_header_files} DESTINATION ${tizenadaptorintegrationapidir} ) +INSTALL( FILES ${adaptor_application_api_header_files} DESTINATION ${tizenadaptorapplicationapidir} ) INSTALL( FILES ${public_api_adaptor_framework_header_files} DESTINATION ${tizenadaptorframeworkpublicapidir} ) INSTALL( FILES ${devel_api_adaptor_framework_header_files} DESTINATION ${tizenadaptorframeworkdevelapidir} ) INSTALL( FILES ${devel_api_adaptor_framework_canvas_renderer_header_files} DESTINATION ${tizencanvasrendererdevelapidir} ) @@ -446,6 +449,7 @@ MESSAGE( STATUS "Using Tizen APP FW libraries: ${ENABLE_APPFW}") MESSAGE( STATUS "Use pkg configure: ${ENABLE_PKG_CONFIGURE}" ) MESSAGE( STATUS "Enable link test: ${ENABLE_LINK_TEST}" ) MESSAGE( STATUS "Enable AT-SPI: ${ENABLE_ATSPI}" ) +MESSAGE( STATUS "Enable AppModel: ${ENABLE_APPMODEL}" ) MESSAGE( STATUS "Enable Trace: ${ENABLE_TRACE_STRING}" ) MESSAGE( STATUS "Enable VConf: ${ENABLE_VCONF}" ) MESSAGE( STATUS "Tizen Platform Config supported ${TIZEN_PLATFORM_CONFIG_SUPPORTED_LOGMSG}") @@ -458,4 +462,8 @@ IF( enable_feedback ) ADD_SUBDIRECTORY( plugins ) ENDIF() +IF( ENABLE_APPMODEL ) + ADD_SUBDIRECTORY( application-model ) +ENDIF() + CLEAN_ARG_CACHE() diff --git a/build/tizen/application-model/CMakeLists.txt b/build/tizen/application-model/CMakeLists.txt new file mode 100644 index 0000000..78917b2 --- /dev/null +++ b/build/tizen/application-model/CMakeLists.txt @@ -0,0 +1,101 @@ +IF( (NOT UBUNTU_PROFILE) ) + SET(APPLICATION_NORMAL_TARGET dali2-adaptor-application-normal ) + SET(APPLICATION_WIDGET_TARGET dali2-adaptor-application-widget ) + SET(APPLICATION_WATCH_TARGET dali2-adaptor-application-watch ) + SET(APPLICATION_COMPONENT_BASED_TARGET dali2-adaptor-application-component-based ) + + MESSAGE(STATUS ${ROOT_SRC_DIR}/dali/internal/application-model ) + SET( appmodel_src_dir ${ROOT_SRC_DIR}/dali/internal/application-model ) + + INCLUDE( ${appmodel_src_dir}/file.list ) + + SET( APPLICATION_NORMAL_SOURCES ${app_normal_src_files} ) + SET( APPLICATION_WIDGET_SOURCES ${app_widget_src_files} ) + SET( APPLICATION_WATCH_SOURCES ${app_watch_src_files} ) + SET( APPLICATION_COMPONENT_BASED_SOURCES ${app_component_based_src_files} ) + + ADD_LIBRARY( ${APPLICATION_NORMAL_TARGET} SHARED ${APPLICATION_NORMAL_SOURCES} ) + ADD_LIBRARY( ${APPLICATION_WIDGET_TARGET} SHARED ${APPLICATION_WIDGET_SOURCES} ) + ADD_LIBRARY( ${APPLICATION_WATCH_TARGET} SHARED ${APPLICATION_WATCH_SOURCES} ) + ADD_LIBRARY( ${APPLICATION_COMPONENT_BASED_TARGET} SHARED ${APPLICATION_COMPONENT_BASED_SOURCES} ) + + OPTION(ENABLE_PKG_CONFIGURE "Use pkgconfig" ON) + + IF (ENABLE_PKG_CONFIGURE) + FIND_PACKAGE(PkgConfig REQUIRED) + PKG_CHECK_MODULES(APPCOREUICPP app-core-ui-cpp) + PKG_CHECK_MODULES(ELDBUS eldbus) + + SET(CORE_PKG_CFG_FILE dali2-adaptor-application-normal.pc) + CONFIGURE_FILE(${CMAKE_CURRENT_LIST_DIR}/${CORE_PKG_CFG_FILE}.in ${CORE_PKG_CFG_FILE} @ONLY) + ENDIF() + + TARGET_LINK_LIBRARIES( ${APPLICATION_NORMAL_TARGET} PUBLIC + ${DLOG_LDFLAGS} + ${DALICORE_LDFLAGS} + ${APPCOREUICPP_LDFLAGS} + ${ELDBUS_LDFLAGS} + dali2-adaptor + ) + + TARGET_COMPILE_OPTIONS( ${APPLICATION_NORMAL_TARGET} PUBLIC + ${DLOG_CFLAGS} + ${DALICORE_CFLAGS} + ${APPCOREUICPP_CFLAGS} + ${ELDBUS_CFLAGS} + -I../../../ + -Wall + ) + + TARGET_LINK_LIBRARIES( ${APPLICATION_WIDGET_TARGET} PUBLIC + ${DLOG_LDFLAGS} + ${DALICORE_LDFLAGS} + ${ELDBUS_LDFLAGS} + dali2-adaptor + ) + + TARGET_COMPILE_OPTIONS( ${APPLICATION_WIDGET_TARGET} PUBLIC + ${DLOG_CFLAGS} + ${DALICORE_CFLAGS} + ${ELDBUS_CFLAGS} + -I../../../ + -Wall + ) + + TARGET_LINK_LIBRARIES( ${APPLICATION_WATCH_TARGET} PUBLIC + ${DLOG_LDFLAGS} + ${DALICORE_LDFLAGS} + ${ELDBUS_LDFLAGS} + dali2-adaptor + ) + + TARGET_COMPILE_OPTIONS( ${APPLICATION_WATCH_TARGET} PUBLIC + ${DLOG_CFLAGS} + ${DALICORE_CFLAGS} + ${ELDBUS_CFLAGS} + -I../../../ + -Wall + ) + + TARGET_LINK_LIBRARIES( ${APPLICATION_COMPONENT_BASED_TARGET} PUBLIC + ${DLOG_LDFLAGS} + ${DALICORE_LDFLAGS} + ${ELDBUS_LDFLAGS} + dali2-adaptor + ) + + TARGET_COMPILE_OPTIONS( ${APPLICATION_COMPONENT_BASED_TARGET} PUBLIC + ${DLOG_CFLAGS} + ${DALICORE_CFLAGS} + ${ELDBUS_CFLAGS} + -I../../../ + -Wall + ) + + + INSTALL( TARGETS ${APPLICATION_NORMAL_TARGET} DESTINATION ${LIB_DIR} ) + INSTALL( TARGETS ${APPLICATION_WIDGET_TARGET} DESTINATION ${LIB_DIR} ) + INSTALL( TARGETS ${APPLICATION_WATCH_TARGET} DESTINATION ${LIB_DIR} ) + INSTALL( TARGETS ${APPLICATION_COMPONENT_BASED_TARGET} DESTINATION ${LIB_DIR} ) +ENDIF() + diff --git a/build/tizen/application-model/dali2-adaptor-application-normal.pc.in b/build/tizen/application-model/dali2-adaptor-application-normal.pc.in new file mode 100644 index 0000000..2edc63b --- /dev/null +++ b/build/tizen/application-model/dali2-adaptor-application-normal.pc.in @@ -0,0 +1,15 @@ +#Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +apiversion=@DALI_ADAPTOR_VERSION@ +libdir=@LIB_DIR@ +includedir=@DEV_INCLUDE_PATH@ + +Name: dali-adaptor +Description: DALi adaptor for application-normal +Version: ${apiversion} +Requires: dali2-adaptor +Libs: -L${libdir} -ldali2-adaptor-application-normal +Cflags: -I${includedir}/dali + diff --git a/build/tizen/deps-check.cmake b/build/tizen/deps-check.cmake index 59e1cd0..7469d12 100755 --- a/build/tizen/deps-check.cmake +++ b/build/tizen/deps-check.cmake @@ -19,6 +19,7 @@ ARG_ENABLE( ENABLE_PROFILE enable_profile "${ENABLE_VAL};UBUNTU" "Select the var ARG_ENABLE( ENABLE_TIZEN_MAJOR_VERSION enable_tizen_major_version "${ENABLE_VAL};0" "Specify the Tizen Major version for backwards compatibility" ) ARG_ENABLE( ENABLE_FEEDBACK enable_feedback 1 "Enable feedback plugin" ) +ARG_ENABLE( ENABLE_APPMODEL enable_appmodel 1 "Enable appmodel" ) ARG_ENABLE( ENABLE_WAYLAND enable_wayland "${ENABLE_VAL}" "Build on Wayland" ) ARG_ENABLE( ENABLE_ECORE_WAYLAND2 enable_ecore_wayland2 "${ENABLE_VAL}" "Build on Ecore Wayland2" ) diff --git a/dali/internal/adaptor/common/framework.h b/dali/internal/adaptor/common/framework.h index ad89efe..c47bd14 100644 --- a/dali/internal/adaptor/common/framework.h +++ b/dali/internal/adaptor/common/framework.h @@ -331,6 +331,26 @@ public: mArgv = argv; } + Observer& GetObserver() + { + return mObserver; + } + + int* GetArgc() + { + return mArgc; + } + + char*** GetArgv() + { + return mArgv; + } + + TaskObserver& GetTaskObserver() + { + return mTaskObserver; + } + private: /** * Called if the application is aborted. diff --git a/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp b/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp index 50a1a53..8a24537 100644 --- a/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp +++ b/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp @@ -18,40 +18,20 @@ #include // EXTERNAL INCLUDES -#include -#include -#include -#include +#include #include -#include #include #include -#include -#include -#include +#include #ifdef UI_THREAD_AVAILABLE #include #endif -// CONDITIONAL INCLUDES -#ifdef APPCORE_WATCH_AVAILABLE -#include -#endif -#ifdef DALI_ELDBUS_AVAILABLE -#include -#endif // DALI_ELDBUS_AVAILABLE - -#ifdef COMPONENT_APPLICATION_SUPPORT -#include -#endif - +// INTERNAL INCLUDES #include #include -// INTERNAL INCLUDES -#include - using namespace tizen_cpp; namespace Dali @@ -62,1246 +42,218 @@ namespace Adaptor { namespace { +constexpr char const* const kApplicationNamePrefix = "libdali2-adaptor-application-"; +constexpr char const* const kApplicationNamePostfix = ".so"; + +std::string MakePluginName(const char* appModelName) +{ + std::stringstream fullName; + fullName << kApplicationNamePrefix << appModelName << kApplicationNamePostfix; + return fullName.str(); +} + #if defined(DEBUG_ENABLED) Integration::Log::Filter* gDBusLogging = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DBUS"); #endif DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_FRAMEWORK, true); -bool IsWidgetFeatureEnabled() -{ - static bool feature = false; - static bool retrieved = false; - int ret; - - if(retrieved == true) - { - return feature; - } - - ret = system_info_get_platform_bool("http://tizen.org/feature/shell.appwidget", &feature); - if(ret != SYSTEM_INFO_ERROR_NONE) - { - DALI_LOG_ERROR("failed to get system info"); - return false; - } - - retrieved = true; - return feature; -} - // Note : tizen appfw don't consider zero-arguments case. // If framework argc & argv is nullptr, We should add at least one argv. const int gTizenDummyArgc = 1; const char* gTizenDummyArgv[1] = {"dali-tizen-app"}; - } // anonymous namespace -namespace AppCore -{ -typedef enum -{ - LOW_MEMORY, //< The low memory event - LOW_BATTERY, //< The low battery event - LANGUAGE_CHANGED, //< The system language changed event - DEVICE_ORIENTATION_CHANGED, //< The device orientation changed event - REGION_FORMAT_CHANGED, //< The region format changed event - SUSPENDED_STATE_CHANGED, //< The suspended state changed event of the application - UPDATE_REQUESTED, //< The update requested event. This event can occur when an app needs to be updated. It is dependent on target devices. -} AppEventType; - -static int AppEventConverter[APPCORE_BASE_EVENT_MAX] = - { - [LOW_MEMORY] = APPCORE_BASE_EVENT_LOW_MEMORY, - [LOW_BATTERY] = APPCORE_BASE_EVENT_LOW_BATTERY, - [LANGUAGE_CHANGED] = APPCORE_BASE_EVENT_LANG_CHANGE, - [DEVICE_ORIENTATION_CHANGED] = APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED, - [REGION_FORMAT_CHANGED] = APPCORE_BASE_EVENT_REGION_CHANGE, - [SUSPENDED_STATE_CHANGED] = APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE, -}; - -struct AppEventInfo -{ - AppEventType type; - void* value; -}; - -typedef struct AppEventInfo* AppEventInfoPtr; - -typedef void (*AppEventCallback)(AppEventInfoPtr eventInfo, void* userData); - -struct AppEventHandler -{ - AppEventType type; - AppEventCallback cb; - void* data; - void* raw; -}; - -typedef struct AppEventHandler* AppEventHandlerPtr; - -int EventCallback(void* event, void* data) -{ - AppEventHandlerPtr handler = static_cast(data); - - struct AppEventInfo appEvent; - - appEvent.type = handler->type; - appEvent.value = event; - - if(handler->cb) - handler->cb(&appEvent, handler->data); - - return 0; -} - -int AppAddEventHandler(AppEventHandlerPtr* eventHandler, AppEventType eventType, AppEventCallback callback, void* userData) -{ - AppEventHandlerPtr handler; - - handler = static_cast(calloc(1, sizeof(struct AppEventHandler))); - if(!handler) - { - DALI_LOG_ERROR("failed to create handler"); - return TIZEN_ERROR_UNKNOWN; - } - else - { - handler->type = eventType; - handler->cb = callback; - handler->data = userData; - handler->raw = appcore_base_add_event(static_cast(AppEventConverter[static_cast(eventType)]), EventCallback, handler); - - *eventHandler = handler; - - return TIZEN_ERROR_NONE; - } -} - -DeviceStatus::Memory::Status GetMemoryStatus(app_event_low_memory_status_e memoryStatus) -{ - switch(memoryStatus) - { - case APP_EVENT_LOW_MEMORY_SOFT_WARNING: // 0x02 - { - return Dali::DeviceStatus::Memory::Status::LOW; - } - case APP_EVENT_LOW_MEMORY_HARD_WARNING: // 0x04 - { - return Dali::DeviceStatus::Memory::Status::CRITICALLY_LOW; - } - default: // APP_EVENT_LOW_MEMORY_NORMAL 0x01 - { - return Dali::DeviceStatus::Memory::Status::NORMAL; - } - } -} - -DeviceStatus::Battery::Status GetBatteryStatus(app_event_low_battery_status_e batteryStatus) -{ - switch(batteryStatus) - { - case APP_EVENT_LOW_BATTERY_POWER_OFF: // 1 - { - return Dali::DeviceStatus::Battery::Status::POWER_OFF; - } - case APP_EVENT_LOW_BATTERY_CRITICAL_LOW: // 2 - { - return Dali::DeviceStatus::Battery::Status::CRITICALLY_LOW; - } - default: - { - return Dali::DeviceStatus::Battery::Status::NORMAL; - } - } -} - -DeviceStatus::Orientation::Status GetOrientationStatus(app_device_orientation_e orientationStatus) -{ - switch(orientationStatus) - { - case APP_DEVICE_ORIENTATION_0: - { - return Dali::DeviceStatus::Orientation::Status::ORIENTATION_0; - } - case APP_DEVICE_ORIENTATION_90: - { - return Dali::DeviceStatus::Orientation::Status::ORIENTATION_90; - } - case APP_DEVICE_ORIENTATION_180: - { - return Dali::DeviceStatus::Orientation::Status::ORIENTATION_180; - } - case APP_DEVICE_ORIENTATION_270: - { - return Dali::DeviceStatus::Orientation::Status::ORIENTATION_270; - } - default: - { - return Dali::DeviceStatus::Orientation::Status::ORIENTATION_0; - } - } -} - -} // namespace AppCore - /** * Impl to hide EFL data members */ struct FrameworkTizen::Impl { - class UiAppContext : public AppCoreUiBase + // Constructor + Impl(void* data, Type type, bool isUiThread) { - public: - class Task : public AppCoreTaskBase + mFramework = static_cast(data); + mUiThread = isUiThread; +#ifndef APPCORE_WATCH_AVAILABLE + if(type == WATCH) { - public: - explicit Task(FrameworkTizen* framework) - : mFramework(framework), - mNewBatteryStatus(Dali::DeviceStatus::Battery::Status::NORMAL), - mNewMemoryStatus(Dali::DeviceStatus::Memory::NORMAL), - mNewDeviceOrientationStatus(Dali::DeviceStatus::Orientation::ORIENTATION_0) - { - } - - virtual ~Task() - { - } - - int OnCreate() override - { - // On the main thread, the log functions are not set. So print_log() is used directly. - print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnCreate() emitted", __MODULE__, __func__, __LINE__); - mFramework->mTaskObserver.OnTaskInit(); - return AppCoreTaskBase::OnCreate(); - } - - int OnTerminate() override - { - print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnTerminate() emitted", __MODULE__, __func__, __LINE__); - mFramework->mTaskObserver.OnTaskTerminate(); - return AppCoreTaskBase::OnTerminate(); - } - - int OnControl(tizen_base::Bundle b) override - { - print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnControl() emitted", __MODULE__, __func__, __LINE__); - AppCoreTaskBase::OnControl(b); - - app_control_h appControl = nullptr; - - auto* bundleData = b.GetHandle(); - if(bundleData) - { - if(app_control_create_event(bundleData, &appControl) != TIZEN_ERROR_NONE) - { - print_log(DLOG_ERROR, "DALI", "%s: %s(%d) > Failed to create an app_control handle with Bundle", __MODULE__, __func__, __LINE__); - } - } - else - { - if(app_control_create(&appControl) != TIZEN_ERROR_NONE) - { - print_log(DLOG_ERROR, "DALI", "%s: %s(%d) > Failed to create an app_control handle", __MODULE__, __func__, __LINE__); - } - } - mFramework->mTaskObserver.OnTaskAppControl(appControl); - - app_control_destroy(appControl); - return 0; - } - - void OnUiEvent(AppCoreTaskBase::UiState state) override - { - // This event is emitted when the UI thread is paused or resumed. - print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnUiEvent() emitted", __MODULE__, __func__, __LINE__); - - // Note: This isn't implemented. - AppCoreTaskBase::OnUiEvent(state); - } - - void OnLowMemory(AppCoreTaskBase::LowMemoryState state) override - { - print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLowMemory() emitted", __MODULE__, __func__, __LINE__); - - mNewMemoryStatus = AppCore::GetMemoryStatus(static_cast(state)); - - PostToUiThread( - [](gpointer userData) -> gboolean { - auto* task = static_cast(userData); - auto* framework = static_cast(task->mFramework); - framework->mObserver.OnMemoryLow(task->mNewMemoryStatus); - return G_SOURCE_REMOVE; - }); - mFramework->mTaskObserver.OnTaskMemoryLow(mNewMemoryStatus); - AppCoreTaskBase::OnLowMemory(state); - } - - void OnDeviceOrientationChanged(AppCoreTaskBase::DeviceOrientationState state) override - { - print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnDeviceOrientationChanged() emitted, orientation :%d", __MODULE__, __func__, __LINE__, state); - - mNewDeviceOrientationStatus = AppCore::GetOrientationStatus(static_cast(state)); - - PostToUiThread( - [](gpointer userData) -> gboolean { - auto* task = static_cast(userData); - auto* framework = static_cast(task->mFramework); - framework->mObserver.OnDeviceOrientationChanged(task->mNewDeviceOrientationStatus); - return G_SOURCE_REMOVE; - }); - - mFramework->mTaskObserver.OnTaskDeviceOrientationChanged(mNewDeviceOrientationStatus); - - AppCoreTaskBase::OnDeviceOrientationChanged(state); - } - void OnLowBattery(AppCoreTaskBase::LowBatteryState state) override - { - print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLowBattery() emitted", __MODULE__, __func__, __LINE__); - mNewBatteryStatus = AppCore::GetBatteryStatus(static_cast(state)); - - PostToUiThread( - [](gpointer userData) -> gboolean { - auto* task = static_cast(userData); - auto* framework = static_cast(task->mFramework); - framework->mObserver.OnBatteryLow(task->mNewBatteryStatus); - return G_SOURCE_REMOVE; - }); - mFramework->mTaskObserver.OnTaskBatteryLow(mNewBatteryStatus); - AppCoreTaskBase::OnLowBattery(state); - } - - void OnLangChanged(const std::string& lang) override - { - print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLangChanged() emitted", __MODULE__, __func__, __LINE__); - mNewLanguage = lang; - mFramework->SetLanguage(mNewLanguage); - - PostToUiThread( - [](gpointer userData) -> gboolean { - auto* task = static_cast(userData); - auto* framework = static_cast(task->mFramework); - framework->mObserver.OnLanguageChanged(); - return G_SOURCE_REMOVE; - }); - - mFramework->mTaskObserver.OnTaskLanguageChanged(); - AppCoreTaskBase::OnLangChanged(lang); - } - - void OnRegionChanged(const std::string& region) override - { - print_log(DLOG_INFO, "DALI", "%s: %s(%d) > nRegionChanged() emitted", __MODULE__, __func__, __LINE__); - mNewRegion = region; - mFramework->SetRegion(mNewRegion); - - PostToUiThread( - [](gpointer userData) -> gboolean { - auto* task = static_cast(userData); - auto* framework = static_cast(task->mFramework); - framework->mObserver.OnRegionChanged(); - return G_SOURCE_REMOVE; - }); - - mFramework->mTaskObserver.OnTaskRegionChanged(); - AppCoreTaskBase::OnRegionChanged(mNewRegion); - } + throw Dali::DaliException("", "Watch Application is not supported."); + } +#endif + mApplicationType = type; - private: - GMainContext* GetTizenGlibContext() + std::string pluginName; + switch(mApplicationType) + { + case NORMAL: { - GMainContext* context; - const char* env = getenv("TIZEN_GLIB_CONTEXT"); - if(env) - { - context = (GMainContext*)strtoul(env, nullptr, 10); - } - else - { - context = nullptr; - } - - return context; + pluginName = MakePluginName("normal"); + break; } - - void PostToUiThread(GSourceFunc func) + case WIDGET: { - GSource* source = g_idle_source_new(); - g_source_set_callback(source, func, this, nullptr); - g_source_attach(source, GetTizenGlibContext()); - g_source_unref(source); + pluginName = MakePluginName("widget"); + break; } - - private: - FrameworkTizen* mFramework; - std::string mNewLanguage; - std::string mNewRegion; - Dali::DeviceStatus::Battery::Status mNewBatteryStatus; - Dali::DeviceStatus::Memory::Status mNewMemoryStatus; - Dali::DeviceStatus::Orientation::Status mNewDeviceOrientationStatus; - }; - - explicit UiAppContext(unsigned int hint, FrameworkTizen* framework) - : AppCoreUiBase(hint), - mFramework(framework), - mUseUiThread(false) - { - if(hint & AppCoreUiBase::HINT_DUAL_THREAD) + case WATCH: { - mUseUiThread = true; + pluginName = MakePluginName("watch"); + break; } - - if(!mUseUiThread) +#ifdef COMPONENT_APPLICATION_SUPPORT + case COMPONENT: { - mLanguageChanged = std::make_shared(IAppCore::IEvent::Type::LANG_CHANGE, OnLanguageChanged, this); - AddEvent(mLanguageChanged); - - mDeviceOrientationChanged = std::make_shared(IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED, OnDeviceOrientationChanged, this); - AddEvent(mDeviceOrientationChanged); - - mRegionFormatChanged = std::make_shared(IAppCore::IEvent::Type::REGION_CHANGE, OnRegionFormatChanged, this); - AddEvent(mRegionFormatChanged); - - mLowMemory = std::make_shared(IAppCore::IEvent::Type::LOW_MEMORY, OnLowMemory, this); - AddEvent(mLowMemory); - - mLowBattery = std::make_shared(IAppCore::IEvent::Type::LOW_BATTERY, OnLowBattery, this); - AddEvent(mLowBattery); + pluginName = MakePluginName("component-based"); + break; } - } - - virtual ~UiAppContext() - { - if(!mUseUiThread) +#endif + default: { - RemoveEvent(mLowBattery); - RemoveEvent(mLowMemory); - RemoveEvent(mRegionFormatChanged); - RemoveEvent(mDeviceOrientationChanged); - RemoveEvent(mLanguageChanged); + DALI_LOG_ERROR("Invalid app type : %d\n", static_cast(mApplicationType)); + pluginName = MakePluginName("normal"); } } - std::unique_ptr CreateTask() override + mHandle = dlopen(pluginName.c_str(), RTLD_LAZY); + if(mHandle == nullptr) { - return std::unique_ptr( - new Task(mFramework)); + print_log(DLOG_INFO, "DALI", "error : %s", dlerror() ); + return; } - int OnCreate() override + createFunctionPtr = reinterpret_cast(dlsym(mHandle, "Create")); + if(createFunctionPtr == nullptr) { - AppCoreUiBase::OnCreate(); - mFramework->Create(); - return 0; + DALI_LOG_ERROR("createFunctionPtr is null\n"); } - - int OnTerminate() override + destroyFunctionPtr = reinterpret_cast(dlsym(mHandle, "Destroy")); + if(destroyFunctionPtr == nullptr) { - AppCoreUiBase::OnTerminate(); - auto* observer = &mFramework->mObserver; - observer->OnTerminate(); - return 0; + DALI_LOG_ERROR("destroyFunctionPtr is null\n"); } - - int OnPause() override + appMainFunctionPtr = reinterpret_cast(dlsym(mHandle, "AppMain")); + if(appMainFunctionPtr == nullptr) { - AppCoreUiBase::OnPause(); - auto* observer = &mFramework->mObserver; - observer->OnPause(); - return 0; + DALI_LOG_ERROR("appMainFunctionPtr is null\n"); } - - int OnResume() override + appExitFunctionPtr = reinterpret_cast(dlsym(mHandle, "AppExit")); + if(appExitFunctionPtr == nullptr) { - AppCoreUiBase::OnResume(); - auto* observer = &mFramework->mObserver; - observer->OnResume(); - return 0; + DALI_LOG_ERROR("appExitFunctionPtr is null\n"); } + } - int OnControl(tizen_base::Bundle b) override + ~Impl() + { + if(mHandle != NULL) { - AppCoreUiBase::OnControl(b); - - app_control_h appControl = nullptr; - - auto* bundleData = b.GetHandle(); - if(bundleData) - { - if(app_control_create_event(bundleData, &appControl) != TIZEN_ERROR_NONE) - { - DALI_LOG_ERROR("Failed to create an app_control handle"); - return 0; - } - } - else + if(destroyFunctionPtr != NULL) { - if(app_control_create(&appControl) != TIZEN_ERROR_NONE) - { - DALI_LOG_ERROR("Failed to create an app_control handle"); - return 0; - } + destroyFunctionPtr(baseAppPtr); } - auto* observer = &mFramework->mObserver; - ProcessBundle(mFramework, bundleData); - observer->OnReset(); - observer->OnAppControl(appControl); - app_control_destroy(appControl); - return 0; + dlclose(mHandle); } + } - void OnLoopInit(int argc, char** argv) override + int AppMain() + { + if(mHandle == nullptr) { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" - ecore_init(); - ecore_app_args_set(argc, (const char**)argv); -#pragma GCC diagnostic pop - -#ifdef DALI_ELDBUS_AVAILABLE - // Initialize ElDBus. - DALI_LOG_INFO(gDBusLogging, Debug::General, "Starting DBus Initialization\n"); - eldbus_init(); -#endif + print_log(DLOG_INFO, "DALI", "mHandle is null"); + return TIZEN_ERROR_NOT_SUPPORTED; } - void OnLoopFinish() override + if(createFunctionPtr != nullptr) { - ecore_shutdown(); - - if(getenv("AUL_LOADER_INIT")) - { - setenv("AUL_LOADER_INIT", "0", 1); - ecore_shutdown(); - } - -#ifdef DALI_ELDBUS_AVAILABLE - // Shutdown ELDBus. - DALI_LOG_INFO(gDBusLogging, Debug::General, "Shutting down DBus\n"); - eldbus_shutdown(); -#endif + baseAppPtr = createFunctionPtr(); } - void OnLoopRun() override + if(baseAppPtr == nullptr) { - ecore_main_loop_begin(); + DALI_LOG_ERROR("p is null\n"); + return TIZEN_ERROR_NOT_SUPPORTED; } - void OnLoopExit() override + int ret = 0; + if(appMainFunctionPtr != nullptr) { - ecore_main_loop_quit(); + ret = appMainFunctionPtr(mUiThread, mFramework, baseAppPtr); } + return ret; + } - private: - static void OnLanguageChanged(app_event_info_h event_info, void* user_data) + void AppExit() + { + if(baseAppPtr == nullptr) { - auto* context = static_cast(user_data); - auto* framework = context->mFramework; - Observer* observer = &framework->mObserver; - - char* lang = nullptr; - auto appEventReturn = app_event_get_language(event_info, &lang); - if(appEventReturn == APP_ERROR_NONE && lang) - { - framework->SetLanguage(std::string(lang)); - observer->OnLanguageChanged(); - free(lang); - } - else - { - DALI_LOG_ERROR("NULL pointer in Language changed event. Error code : %d\n", static_cast(appEventReturn)); - } + DALI_LOG_ERROR("baseAppPtr is null\n"); + return; } + appExitFunctionPtr(baseAppPtr); + } - static void OnRegionFormatChanged(app_event_info_h event_info, void* user_data) - { - auto* context = static_cast(user_data); - auto* framework = context->mFramework; - Observer* observer = &framework->mObserver; + void SetLanguage(const std::string& language) + { + mLanguage = language; + } - char* region = nullptr; - auto appEventReturn = app_event_get_region_format(event_info, ®ion); - if(appEventReturn == APP_ERROR_NONE && region) - { - framework->SetRegion(std::string(region)); - observer->OnRegionChanged(); - free(region); - } - else - { - DALI_LOG_ERROR("NULL pointer in Region changed event. Error code : %d\n", static_cast(appEventReturn)); - } - } + void SetRegion(const std::string& region) + { + mRegion = region; + } - static void OnLowBattery(app_event_info_h event_info, void* user_data) + std::string GetLanguage() + { + if(mLanguage.empty()) { - auto* context = static_cast(user_data); - auto* framework = context->mFramework; - Observer* observer = &framework->mObserver; + char* language = nullptr; + system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &language); - app_event_low_battery_status_e status; - auto appEventReturn = app_event_get_low_battery_status(event_info, &status); - if(appEventReturn == APP_ERROR_NONE) - { - Dali::DeviceStatus::Battery::Status result = AppCore::GetBatteryStatus(status); - observer->OnBatteryLow(result); - } - else + if(language != nullptr) { - DALI_LOG_ERROR("Fail to get low battery status event. Error code : %d\n", static_cast(appEventReturn)); + mLanguage = std::string(language); + free(language); } } + return mLanguage; + } - static void OnLowMemory(app_event_info_h event_info, void* user_data) + std::string GetRegion() + { + if(mRegion.empty()) { - auto* context = static_cast(user_data); - auto* framework = context->mFramework; - Observer* observer = &framework->mObserver; + char* region = nullptr; + system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY, ®ion); - app_event_low_memory_status_e status; - auto appEventReturn = app_event_get_low_memory_status(event_info, &status); - if(appEventReturn == APP_ERROR_NONE) - { - Dali::DeviceStatus::Memory::Status result = AppCore::GetMemoryStatus(status); - observer->OnMemoryLow(result); - } - else + if(region != nullptr) { - DALI_LOG_ERROR("Fail to get low memory status event. Error code : %d\n", static_cast(appEventReturn)); + mRegion = std::string(region); + free(region); } } + return mRegion; + } - static void OnDeviceOrientationChanged(app_event_info_h event_info, void* user_data) - { - auto* context = static_cast(user_data); - auto* framework = context->mFramework; - Observer* observer = &framework->mObserver; + using CreateFunction = void* (*)(); + using DestroyFunction = void (*)(void*); - app_device_orientation_e status; - auto appEventReturn = app_event_get_device_orientation(event_info, &status); - if(appEventReturn == APP_ERROR_NONE) - { - Dali::DeviceStatus::Orientation::Status result = AppCore::GetOrientationStatus(status); - observer->OnDeviceOrientationChanged(result); - } - else - { - DALI_LOG_ERROR("Fail to get device orientation event. Error code : %d\n", static_cast(appEventReturn)); - } - } + using AppMainFunction = int (*)(bool, void*, void*); + using AppExitFunction = void (*)(void*); - void ProcessBundle(FrameworkTizen* framework, bundle* bundleData) - { - if(bundleData == nullptr) - { - return; - } - - // get bundle name - char* bundleName = const_cast(bundle_get_val(bundleData, "name")); - if(bundleName != nullptr) - { - framework->SetBundleName(bundleName); - } - - // get bundle? id - char* bundleId = const_cast(bundle_get_val(bundleData, "id")); - if(bundleId != nullptr) - { - framework->SetBundleId(bundleId); - } - } - - private: - FrameworkTizen* mFramework; - std::shared_ptr mLanguageChanged; - std::shared_ptr mDeviceOrientationChanged; - std::shared_ptr mRegionFormatChanged; - std::shared_ptr mLowBattery; - std::shared_ptr mLowMemory; - bool mUseUiThread; - }; - - // Constructor - Impl(void* data, Type type, bool useUiThread) - : handlers{nullptr, nullptr, nullptr, nullptr, nullptr}, - mUseUiThread(useUiThread) -#ifdef APPCORE_WATCH_AVAILABLE - , - mWatchCallback() -#endif - { - mFramework = static_cast(data); - -#ifndef APPCORE_WATCH_AVAILABLE - if(type == WATCH) - { - throw Dali::DaliException("", "Watch Application is not supported."); - } -#endif - mApplicationType = type; - } - - ~Impl() - { - } - - int AppMain() - { - // TODO: The app-core-cpp has to be applied to the other app types. - int ret; - switch(mApplicationType) - { - case NORMAL: - { - ret = AppNormalMain(); - break; - } - case WIDGET: - { - ret = AppWidgetMain(); - break; - } - case WATCH: - { - ret = AppWatchMain(); - break; - } -#ifdef COMPONENT_APPLICATION_SUPPORT - case COMPONENT: - { - ret = AppComponentMain(); - break; - } -#endif - default: - { - DALI_LOG_ERROR("Invalid app type : %d\n", static_cast(mApplicationType)); - ret = APP_ERROR_NOT_SUPPORTED; - } - } - return ret; - } - - void AppExit() - { - switch(mApplicationType) - { - case NORMAL: - { - AppNormalExit(); - break; - } - case WIDGET: - { - AppWidgetExit(); - break; - } - case WATCH: - { - AppWatchExit(); - break; - } -#ifdef COMPONENT_APPLICATION_SUPPORT - case COMPONENT: - { - AppComponentExit(); - break; - } -#endif - default: - { - DALI_LOG_ERROR("Invalid app type : %d\n", static_cast(mApplicationType)); - } - } - } - - void SetLanguage(const std::string& language) - { - mLanguage = language; - } - - void SetRegion(const std::string& region) - { - mRegion = region; - } - - std::string GetLanguage() - { - if(mLanguage.empty()) - { - char* language = nullptr; - system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &language); - - if(language != nullptr) - { - mLanguage = std::string(language); - free(language); - } - } - return mLanguage; - } - - std::string GetRegion() - { - if(mRegion.empty()) - { - char* region = nullptr; - system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY, ®ion); - - if(region != nullptr) - { - mRegion = std::string(region); - free(region); - } - } - return mRegion; - } + void* mHandle{nullptr}; + CreateFunction createFunctionPtr; + DestroyFunction destroyFunctionPtr; + AppMainFunction appMainFunctionPtr; + AppExitFunction appExitFunctionPtr; + void* baseAppPtr = nullptr; + bool mUiThread; // Data - Type mApplicationType; - std::string mLanguage{}; - std::string mRegion{}; + Type mApplicationType; + std::string mLanguage{}; + std::string mRegion{}; FrameworkTizen* mFramework; - AppCore::AppEventHandlerPtr handlers[5]; - std::unique_ptr mUiAppContext{nullptr}; - bool mUseUiThread{false}; -#ifdef APPCORE_WATCH_AVAILABLE - watch_app_lifecycle_callback_s mWatchCallback; -#endif - - static void ProcessBundle(FrameworkTizen* framework, bundle* bundleData) - { - if(bundleData == NULL) - { - return; - } - - // get bundle name - char* bundleName = const_cast(bundle_get_val(bundleData, "name")); - if(bundleName != NULL) - { - framework->SetBundleName(bundleName); - } - - // get bundle? id - char* bundleId = const_cast(bundle_get_val(bundleData, "id")); - if(bundleId != NULL) - { - framework->SetBundleId(bundleId); - } - } - - static void AppInit(int argc, char** argv, void* data) - { -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" - ecore_init(); - ecore_app_args_set(argc, (const char**)argv); -#pragma GCC diagnostic pop - -#ifdef DALI_ELDBUS_AVAILABLE - // Initialize ElDBus. - DALI_LOG_INFO(gDBusLogging, Debug::General, "Starting DBus Initialization\n"); - eldbus_init(); -#endif - } - - static void AppFinish(void) - { - ecore_shutdown(); - - if(getenv("AUL_LOADER_INIT")) - { - setenv("AUL_LOADER_INIT", "0", 1); - ecore_shutdown(); - } - -#ifdef DALI_ELDBUS_AVAILABLE - // Shutdown ELDBus. - DALI_LOG_INFO(gDBusLogging, Debug::General, "Shutting down DBus\n"); - eldbus_shutdown(); -#endif - } - - static void AppRun(void* data) - { - ecore_main_loop_begin(); - } - - static void AppExit(void* data) - { - ecore_main_loop_quit(); - } - - static void AppLanguageChanged(AppCore::AppEventInfoPtr event, void* data) - { - FrameworkTizen* framework = static_cast(data); - Observer* observer = &framework->mObserver; - - if(event && event->value) - { - framework->SetLanguage(std::string(static_cast(event->value))); - observer->OnLanguageChanged(); - } - else - { - DALI_LOG_ERROR("NULL pointer in Language changed event\n"); - } - } - - static void AppRegionChanged(AppCore::AppEventInfoPtr event, void* data) - { - FrameworkTizen* framework = static_cast(data); - Observer* observer = &framework->mObserver; - - if(event && event->value) - { - framework->SetRegion(std::string(static_cast(event->value))); - observer->OnRegionChanged(); - } - else - { - DALI_LOG_ERROR("NULL pointer in Region changed event\n"); - } - } - - static void AppBatteryLow(AppCore::AppEventInfoPtr event, void* data) - { - Observer* observer = &static_cast(data)->mObserver; - int status = *static_cast(event->value); - Dali::DeviceStatus::Battery::Status result = Dali::DeviceStatus::Battery::Status::NORMAL; - - // convert to dali battery status - switch(status) - { - case 1: - { - result = Dali::DeviceStatus::Battery::POWER_OFF; - break; - } - case 2: - { - result = Dali::DeviceStatus::Battery::CRITICALLY_LOW; - break; - } - default: - break; - } - observer->OnBatteryLow(result); - } - - static void AppMemoryLow(AppCore::AppEventInfoPtr event, void* data) - { - Observer* observer = &static_cast(data)->mObserver; - int status = *static_cast(event->value); - Dali::DeviceStatus::Memory::Status result = Dali::DeviceStatus::Memory::Status::NORMAL; - - // convert to dali memmory status - switch(status) - { - case 1: - { - result = Dali::DeviceStatus::Memory::NORMAL; - break; - } - case 2: - { - result = Dali::DeviceStatus::Memory::LOW; - break; - } - case 4: - { - result = Dali::DeviceStatus::Memory::CRITICALLY_LOW; - break; - } - default: - break; - } - observer->OnMemoryLow(result); - } - - static void AppDeviceOrientationChanged(AppCore::AppEventInfoPtr event, void* data) - { - Observer* observer = &static_cast(data)->mObserver; - int status = *static_cast(event->value); - Dali::DeviceStatus::Orientation::Status result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_0; - - switch(status) - { - case APP_DEVICE_ORIENTATION_0: - { - result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_0; - break; - } - case APP_DEVICE_ORIENTATION_90: - { - result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_90; - break; - } - case APP_DEVICE_ORIENTATION_180: - { - result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_180; - break; - } - case APP_DEVICE_ORIENTATION_270: - { - result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_270; - break; - } - - default: - break; - } - observer->OnDeviceOrientationChanged(result); - } - - int AppNormalMain() - { - if(mUiAppContext.get() == nullptr) - { - unsigned int hint = AppCoreUiBase::HINT_WINDOW_GROUP_CONTROL | - AppCoreUiBase::HINT_WINDOW_STACK_CONTROL | - AppCoreUiBase::HINT_BG_LAUNCH_CONTROL | - AppCoreUiBase::HINT_HW_ACC_CONTROL | - AppCoreUiBase::HINT_WINDOW_AUTO_CONTROL; - -#ifdef UI_THREAD_AVAILABLE - // For testing UIThread model, This code turns on the UI Thread feature forcibly. - // ex) app_launcher -e [APPID] __K_UI_THREAD enable - // This code doesn't change mUseUiThread in Internal::Application - bundle* b = bundle_import_from_argv(*mFramework->mArgc, *mFramework->mArgv); - if(b != nullptr) - { - const char* val = bundle_get_val(b, "__K_UI_THREAD"); - if(val != nullptr && strcmp(val, "enable") == 0) - { - mUseUiThread = true; - } - - bundle_free(b); - } - - if(mUseUiThread) - { - hint |= AppCoreUiBase::HINT_DUAL_THREAD; - } -#endif - - mUiAppContext = std::make_unique(hint, mFramework); - } - - mUiAppContext->Run(*mFramework->mArgc, *mFramework->mArgv); - return APP_ERROR_NONE; - } - - void AppNormalExit() - { - if(mUiAppContext.get() == nullptr) - { - return; - } - - mUiAppContext->Exit(); - } - - void AppWidgetExit() - { - widget_base_exit(); - } - - static int WidgetAppCreate(void* data) - { - widget_base_on_create(); - return static_cast(static_cast(data)->Create()); - } - - static int WidgetAppTerminate(void* data) - { - Observer* observer = &static_cast(data)->mObserver; - observer->OnTerminate(); - - widget_base_on_terminate(); - return 0; - } - - int AppWidgetMain() - { - if(!IsWidgetFeatureEnabled()) - { - DALI_LOG_ERROR("widget feature is not supported"); - return APP_ERROR_NOT_SUPPORTED; - } - - AppCore::AppAddEventHandler(&handlers[AppCore::LOW_BATTERY], AppCore::LOW_BATTERY, AppBatteryLow, mFramework); - AppCore::AppAddEventHandler(&handlers[AppCore::LOW_MEMORY], AppCore::LOW_MEMORY, AppMemoryLow, mFramework); - AppCore::AppAddEventHandler(&handlers[AppCore::DEVICE_ORIENTATION_CHANGED], AppCore::DEVICE_ORIENTATION_CHANGED, AppDeviceOrientationChanged, mFramework); - AppCore::AppAddEventHandler(&handlers[AppCore::LANGUAGE_CHANGED], AppCore::LANGUAGE_CHANGED, AppLanguageChanged, mFramework); - AppCore::AppAddEventHandler(&handlers[AppCore::REGION_FORMAT_CHANGED], AppCore::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework); - - widget_base_ops ops = widget_base_get_default_ops(); - - /* override methods */ - ops.create = WidgetAppCreate; - ops.terminate = WidgetAppTerminate; - ops.init = AppInit; - ops.finish = AppFinish; - ops.run = AppRun; - ops.exit = AppExit; - - int result = widget_base_init(ops, *mFramework->mArgc, *mFramework->mArgv, mFramework); - - widget_base_fini(); - - return result; - } - -#ifdef APPCORE_WATCH_AVAILABLE - static bool WatchAppCreate(int width, int height, void* data) - { - return static_cast(data)->Create(); - } - - static void WatchAppTimeTick(watch_time_h time, void* data) - { - Observer* observer = &static_cast(data)->mObserver; - WatchTime curTime(time); - - observer->OnTimeTick(curTime); - } - - static void WatchAppAmbientTick(watch_time_h time, void* data) - { - Observer* observer = &static_cast(data)->mObserver; - WatchTime curTime(time); - - observer->OnAmbientTick(curTime); - } - - static void WatchAppAmbientChanged(bool ambient, void* data) - { - Observer* observer = &static_cast(data)->mObserver; - - observer->OnAmbientChanged(ambient); - } - - static void WatchAppControl(app_control_h app_control, void* data) - { - FrameworkTizen* framework = static_cast(data); - Observer* observer = &framework->mObserver; - bundle* bundleData = NULL; - - app_control_to_bundle(app_control, &bundleData); - ProcessBundle(framework, bundleData); - - observer->OnReset(); - observer->OnAppControl(app_control); - } - - static void WatchAppTerminate(void* data) - { - Observer* observer = &static_cast(data)->mObserver; - - observer->OnTerminate(); - } - - static void WatchAppPause(void* data) - { - Observer* observer = &static_cast(data)->mObserver; - - observer->OnPause(); - } - - static void WatchAppResume(void* data) - { - Observer* observer = &static_cast(data)->mObserver; - - observer->OnResume(); - } - -#endif - - int AppWatchMain() - { - int ret = APP_ERROR_NOT_SUPPORTED; - -#ifdef APPCORE_WATCH_AVAILABLE - mWatchCallback.create = WatchAppCreate; - mWatchCallback.app_control = WatchAppControl; - mWatchCallback.terminate = WatchAppTerminate; - mWatchCallback.pause = WatchAppPause; - mWatchCallback.resume = WatchAppResume; - mWatchCallback.time_tick = WatchAppTimeTick; - mWatchCallback.ambient_tick = WatchAppAmbientTick; - mWatchCallback.ambient_changed = WatchAppAmbientChanged; - - AppCore::AppAddEventHandler(&handlers[AppCore::LOW_BATTERY], AppCore::LOW_BATTERY, AppBatteryLow, mFramework); - AppCore::AppAddEventHandler(&handlers[AppCore::LOW_MEMORY], AppCore::LOW_MEMORY, AppMemoryLow, mFramework); - AppCore::AppAddEventHandler(&handlers[AppCore::LANGUAGE_CHANGED], AppCore::LANGUAGE_CHANGED, AppLanguageChanged, mFramework); - AppCore::AppAddEventHandler(&handlers[AppCore::REGION_FORMAT_CHANGED], AppCore::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework); - - ret = watch_app_main(*mFramework->mArgc, *mFramework->mArgv, &mWatchCallback, mFramework); -#else - DALI_LOG_ERROR("watch feature is not supported"); -#endif - return ret; - } - - void AppWatchExit() - { -#ifdef APPCORE_WATCH_AVAILABLE - watch_app_exit(); -#endif - } - -#ifdef COMPONENT_APPLICATION_SUPPORT - int AppComponentMain() - { - /*Crate component_based_app_base_lifecycle_callback*/ - component_based_app_base_lifecycle_callback_s callback; - callback.init = AppInit; - callback.run = AppRun; - callback.exit = AppExit; - callback.create = ComponentAppCreate; - callback.terminate = ComponentAppTerminate; - callback.fini = ComponentAppFinish; - - return component_based_app_base_main(*mFramework->mArgc, *mFramework->mArgv, &callback, mFramework); - } - - static void* ComponentAppCreate(void* data) - { - FrameworkTizen* framework = static_cast(data); - Observer* observer = &framework->mObserver; - observer->OnInit(); - - return Dali::AnyCast(observer->OnCreate()); - } - - static void ComponentAppTerminate(void* data) - { - Observer* observer = &static_cast(data)->mObserver; - observer->OnTerminate(); - } - - static void ComponentAppFinish(void* data) - { - ecore_shutdown(); - - if(getenv("AUL_LOADER_INIT")) - { - setenv("AUL_LOADER_INIT", "0", 1); - ecore_shutdown(); - } - } - - void AppComponentExit() - { - component_based_app_base_exit(); - } - -#endif private: // Undefined @@ -1361,7 +313,7 @@ void FrameworkTizen::Run() DALI_TRACE_BEGIN(gTraceFilter, "DALI_APPMAIN"); ret = mImpl->AppMain(); DALI_TRACE_END(gTraceFilter, "DALI_APPMAIN"); - if(ret != APP_ERROR_NONE) + if(ret != TIZEN_ERROR_NONE) { DALI_LOG_ERROR("Framework::Run(), ui_app_main() is failed. err = %d\n", ret); } @@ -1424,7 +376,6 @@ struct UIThreadLoader::Impl #ifdef UI_THREAD_AVAILABLE mUIThreadLoader = static_cast(data); mAppCoreUiThreadBase = new AppCoreUiThreadBase(); - print_log(DLOG_INFO, "DALI", "%s: %s(%d) > Create mAppCoreUiThreadBase(%p)", __MODULE__, __func__, __LINE__, mAppCoreUiThreadBase); #endif } diff --git a/dali/internal/adaptor/tizen-wayland/framework-tizen.h b/dali/internal/adaptor/tizen-wayland/framework-tizen.h index c6c182a..996c896 100644 --- a/dali/internal/adaptor/tizen-wayland/framework-tizen.h +++ b/dali/internal/adaptor/tizen-wayland/framework-tizen.h @@ -29,7 +29,7 @@ namespace Adaptor /** * FrameworkTizen class provides an Framework Tizen implementation. */ -class FrameworkTizen : public Framework +class DALI_ADAPTOR_API FrameworkTizen : public Framework { public: /** @@ -59,11 +59,21 @@ public: std::string GetBundleName() const; /** + * Called app_reset callback was called with bundle. + */ + void SetBundleName(const std::string& name); + + /** * Gets bundle id which was passed in app_reset callback. */ std::string GetBundleId() const; /** + * Called app_reset callback was called with bundle. + */ + void SetBundleId(const std::string& id); + + /** * Sets system language. */ void SetLanguage(const std::string& language); @@ -83,26 +93,15 @@ public: */ std::string GetRegion() const override; -private: - // Undefined - FrameworkTizen(const FrameworkTizen&) = delete; - FrameworkTizen& operator=(FrameworkTizen&) = delete; - -private: /** * Called when the application is created. */ bool Create(); - /** - * Called app_reset callback was called with bundle. - */ - void SetBundleName(const std::string& name); - - /** - * Called app_reset callback was called with bundle. - */ - void SetBundleId(const std::string& id); +private: + // Undefined + FrameworkTizen(const FrameworkTizen&) = delete; + FrameworkTizen& operator=(FrameworkTizen&) = delete; private: bool mInitialised; diff --git a/dali/internal/application-model/component-based/appmodel-component-based-tizen.cpp b/dali/internal/application-model/component-based/appmodel-component-based-tizen.cpp new file mode 100644 index 0000000..c28c1db --- /dev/null +++ b/dali/internal/application-model/component-based/appmodel-component-based-tizen.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include + +// CONDITIONAL INCLUDES +#ifdef COMPONENT_APPLICATION_SUPPORT +#include +#endif +#ifdef DALI_ELDBUS_AVAILABLE +#include +#endif // DALI_ELDBUS_AVAILABLE + +// INTERNAL INCLUDES +#include +#include +#include +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ +extern "C" DALI_ADAPTOR_API AppModelComponentBased* Create() { + return new AppModelComponentBased; +} + +extern "C" DALI_ADAPTOR_API void Destroy(void* p) { + delete p; +} + +extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData) { + AppModelComponentBased* appComponent = static_cast(pData); + int ret = 0; + if (appComponent != nullptr) + { + ret = appComponent->AppMain(data); + } + else + { + print_log(DLOG_INFO, "DALI", "appComponent is nullptr"); + } + return ret; +} + +extern "C" DALI_ADAPTOR_API void AppExit(AppModelComponentBased* p) { + p->AppExit(); +} + +namespace +{ +#if defined(DEBUG_ENABLED) +Integration::Log::Filter* gDBusLogging = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DBUS"); +#endif +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_FRAMEWORK, true); +} // anonymous namespace + +struct DALI_ADAPTOR_API AppModelComponentBased::Impl +{ + int AppMain(void* data) + { + int ret = TIZEN_ERROR_NOT_SUPPORTED; +#ifdef COMPONENT_APPLICATION_SUPPORT + FrameworkTizen* mFramework = static_cast(data); + + /*Crate component_based_app_base_lifecycle_callback*/ + component_based_app_base_lifecycle_callback_s callback; + callback.init = AppInit; + callback.run = AppRun; + callback.exit = AppExit; + callback.create = ComponentAppCreate; + callback.terminate = ComponentAppTerminate; + callback.fini = ComponentAppFinish; + + ret = component_based_app_base_main(*mFramework->GetArgc(), *mFramework->GetArgv(), &callback, mFramework);; +#else + DALI_LOG_ERROR("component application feature is not supported"); +#endif + return ret; + } + + static void AppInit(int argc, char** argv, void* data) + { + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wold-style-cast" + ecore_init(); + ecore_app_args_set(argc, (const char**)argv); + #pragma GCC diagnostic pop + + #ifdef DALI_ELDBUS_AVAILABLE + // Initialize ElDBus. + DALI_LOG_INFO(gDBusLogging, Debug::General, "Starting DBus Initialization\n"); + eldbus_init(); + #endif + } + + static void AppRun(void* data) + { + ecore_main_loop_begin(); + } + + static void AppExit(void* data) + { + ecore_main_loop_quit(); + } + + static void* ComponentAppCreate(void* data) + { + FrameworkTizen* framework = static_cast(data); + Framework::Observer* observer = &framework->GetObserver(); + observer->OnInit(); + + return Dali::AnyCast(observer->OnCreate()); + } + + static void ComponentAppTerminate(void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + observer->OnTerminate(); + } + + static void ComponentAppFinish(void* data) + { + ecore_shutdown(); + + if(getenv("AUL_LOADER_INIT")) + { + setenv("AUL_LOADER_INIT", "0", 1); + ecore_shutdown(); + } + } + + void AppExit() + { +#ifdef COMPONENT_APPLICATION_SUPPORT + component_based_app_base_exit(); +#endif + } + + Impl(void* data) + { + mAppModelComponentBased = static_cast(data); + } + + ~Impl() + { + } + + AppModelComponentBased* mAppModelComponentBased; + +}; + +AppModelComponentBased::AppModelComponentBased() +{ + mImpl = new Impl(this); +} + +AppModelComponentBased::~AppModelComponentBased() +{ + delete mImpl; +} + +int AppModelComponentBased::AppMain(void *data) +{ + return mImpl->AppMain(data); +} + +void AppModelComponentBased::AppExit() +{ + mImpl->AppExit(); +} +} // Adaptor +} // Internal +} // Dali \ No newline at end of file diff --git a/dali/internal/application-model/component-based/appmodel-component-based-tizen.h b/dali/internal/application-model/component-based/appmodel-component-based-tizen.h new file mode 100644 index 0000000..a42fe84 --- /dev/null +++ b/dali/internal/application-model/component-based/appmodel-component-based-tizen.h @@ -0,0 +1,55 @@ +#ifndef APPMODEL_COMPONENT_BASED_H +#define APPMODEL_COMPONENT_BASED_H + +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ +class AppModelComponentBased +{ +public: // Construction & Destruction + /** + * Constructor + */ + AppModelComponentBased(); + + /** + * Destructor + */ + ~AppModelComponentBased(); + +public: + int AppMain(void* data); + void AppExit(); + +private: // impl members + struct Impl; + Impl* mImpl; +}; +} +} +} + +#endif // APPMODEL_COMPONENT_BASED_H diff --git a/dali/internal/application-model/file.list b/dali/internal/application-model/file.list new file mode 100644 index 0000000..febe239 --- /dev/null +++ b/dali/internal/application-model/file.list @@ -0,0 +1,18 @@ +# Add local source files here + +SET( app_normal_src_files + ${appmodel_src_dir}/normal/appmodel-normal-tizen.cpp +) + +SET( app_widget_src_files + ${appmodel_src_dir}/widget/appmodel-widget-tizen.cpp + ${appmodel_src_dir}/widget/widget-base-tizen.cpp +) + +SET( app_watch_src_files + ${appmodel_src_dir}/watch/appmodel-watch-tizen.cpp +) + +SET( app_component_based_src_files + ${appmodel_src_dir}/component-based/appmodel-component-based-tizen.cpp +) diff --git a/dali/internal/application-model/normal/appmodel-normal-tizen.cpp b/dali/internal/application-model/normal/appmodel-normal-tizen.cpp new file mode 100644 index 0000000..4b27e14 --- /dev/null +++ b/dali/internal/application-model/normal/appmodel-normal-tizen.cpp @@ -0,0 +1,803 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// CONDITIONAL INCLUDES +#ifdef DALI_ELDBUS_AVAILABLE +#include +#endif // DALI_ELDBUS_AVAILABLE + +// INTERNAL INCLUDES +#include +#include +#include +#include + +using namespace tizen_cpp; + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ +extern "C" DALI_ADAPTOR_API AppModelNormal* Create() { + return new AppModelNormal(false); +} + +extern "C" DALI_ADAPTOR_API void Destroy(void* p) { + delete p; +} + +extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData) { + AppModelNormal* appNormal = static_cast(pData); + int ret = 0; + if (appNormal != nullptr) + { + ret = appNormal->AppMain(data); + } + else + { + print_log(DLOG_INFO, "DALI", "appNormal is nullptr"); + } + return ret; +} + +extern "C" DALI_ADAPTOR_API void AppExit(AppModelNormal* p) { + p->AppExit(); +} + +namespace +{ +#if defined(DEBUG_ENABLED) +Integration::Log::Filter* gDBusLogging = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DBUS"); +#endif +} // anonymous namespace + +namespace AppCore +{ + +typedef enum +{ + LOW_MEMORY, //< The low memory event + LOW_BATTERY, //< The low battery event + LANGUAGE_CHANGED, //< The system language changed event + DEVICE_ORIENTATION_CHANGED, //< The device orientation changed event + REGION_FORMAT_CHANGED, //< The region format changed event + SUSPENDED_STATE_CHANGED, //< The suspended state changed event of the application + UPDATE_REQUESTED, //< The update requested event. This event can occur when an app needs to be updated. It is dependent on target devices. +} AppEventType; + +static int AppEventConverter[APPCORE_BASE_EVENT_MAX] = +{ + [LOW_MEMORY] = APPCORE_BASE_EVENT_LOW_MEMORY, + [LOW_BATTERY] = APPCORE_BASE_EVENT_LOW_BATTERY, + [LANGUAGE_CHANGED] = APPCORE_BASE_EVENT_LANG_CHANGE, + [DEVICE_ORIENTATION_CHANGED] = APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED, + [REGION_FORMAT_CHANGED] = APPCORE_BASE_EVENT_REGION_CHANGE, + [SUSPENDED_STATE_CHANGED] = APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE, +}; + +struct AppEventInfo +{ + AppEventType type; + void* value; +}; + +typedef struct AppEventInfo* AppEventInfoPtr; + +typedef void (*AppEventCallback)(AppEventInfoPtr eventInfo, void* userData); + +struct AppEventHandler +{ + AppEventType type; + AppEventCallback cb; + void* data; + void* raw; +}; + +typedef struct AppEventHandler* AppEventHandlerPtr; + +int EventCallback(void* event, void* data) +{ + AppEventHandlerPtr handler = static_cast(data); + + struct AppEventInfo appEvent; + + appEvent.type = handler->type; + appEvent.value = event; + + if(handler->cb) + handler->cb(&appEvent, handler->data); + + return 0; +} + +int AppAddEventHandler(AppEventHandlerPtr* eventHandler, AppEventType eventType, AppEventCallback callback, void* userData) +{ + AppEventHandlerPtr handler; + + handler = static_cast(calloc(1, sizeof(struct AppEventHandler))); + if(!handler) + { + DALI_LOG_ERROR("failed to create handler"); + return TIZEN_ERROR_UNKNOWN; + } + else + { + handler->type = eventType; + handler->cb = callback; + handler->data = userData; + handler->raw = appcore_base_add_event(static_cast(AppEventConverter[static_cast(eventType)]), EventCallback, handler); + + *eventHandler = handler; + + return TIZEN_ERROR_NONE; + } +} + +DeviceStatus::Memory::Status GetMemoryStatus(app_event_low_memory_status_e memoryStatus) +{ + switch(memoryStatus) + { + case APP_EVENT_LOW_MEMORY_SOFT_WARNING: // 0x02 + { + return Dali::DeviceStatus::Memory::Status::LOW; + } + case APP_EVENT_LOW_MEMORY_HARD_WARNING: // 0x04 + { + return Dali::DeviceStatus::Memory::Status::CRITICALLY_LOW; + } + default: // APP_EVENT_LOW_MEMORY_NORMAL 0x01 + { + return Dali::DeviceStatus::Memory::Status::NORMAL; + } + } +} + +DeviceStatus::Battery::Status GetBatteryStatus(app_event_low_battery_status_e batteryStatus) +{ + switch(batteryStatus) + { + case APP_EVENT_LOW_BATTERY_POWER_OFF: // 1 + { + return Dali::DeviceStatus::Battery::Status::POWER_OFF; + } + case APP_EVENT_LOW_BATTERY_CRITICAL_LOW: // 2 + { + return Dali::DeviceStatus::Battery::Status::CRITICALLY_LOW; + } + default: + { + return Dali::DeviceStatus::Battery::Status::NORMAL; + } + } +} + +DeviceStatus::Orientation::Status GetOrientationStatus(app_device_orientation_e orientationStatus) +{ + switch(orientationStatus) + { + case APP_DEVICE_ORIENTATION_0: + { + return Dali::DeviceStatus::Orientation::Status::ORIENTATION_0; + } + case APP_DEVICE_ORIENTATION_90: + { + return Dali::DeviceStatus::Orientation::Status::ORIENTATION_90; + } + case APP_DEVICE_ORIENTATION_180: + { + return Dali::DeviceStatus::Orientation::Status::ORIENTATION_180; + } + case APP_DEVICE_ORIENTATION_270: + { + return Dali::DeviceStatus::Orientation::Status::ORIENTATION_270; + } + default: + { + return Dali::DeviceStatus::Orientation::Status::ORIENTATION_0; + } + } +} +} + +struct DALI_ADAPTOR_API AppModelNormal::Impl +{ + class UiAppContext : public AppCoreUiBase + { + public: + class Task : public AppCoreTaskBase + { + public: + explicit Task(FrameworkTizen* framework) + : mFramework(framework), + mNewBatteryStatus(Dali::DeviceStatus::Battery::Status::NORMAL), + mNewMemoryStatus(Dali::DeviceStatus::Memory::NORMAL), + mNewDeviceOrientationStatus(Dali::DeviceStatus::Orientation::ORIENTATION_0) + { + } + + virtual ~Task() + { + } + + int OnCreate() override + { + // On the main thread, the log functions are not set. So print_log() is used directly. + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnCreate() emitted", __MODULE__, __func__, __LINE__); + mFramework->GetTaskObserver().OnTaskInit(); + return AppCoreTaskBase::OnCreate(); + } + + int OnTerminate() override + { + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnTerminate() emitted", __MODULE__, __func__, __LINE__); + mFramework->GetTaskObserver().OnTaskTerminate(); + return AppCoreTaskBase::OnTerminate(); + } + + int OnControl(tizen_base::Bundle b) override + { + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnControl() emitted", __MODULE__, __func__, __LINE__); + AppCoreTaskBase::OnControl(b); + + app_control_h appControl = nullptr; + + auto* bundleData = b.GetHandle(); + if(bundleData) + { + if(app_control_create_event(bundleData, &appControl) != TIZEN_ERROR_NONE) + { + print_log(DLOG_ERROR, "DALI", "%s: %s(%d) > Failed to create an app_control handle with Bundle", __MODULE__, __func__, __LINE__); + } + } + else + { + if(app_control_create(&appControl) != TIZEN_ERROR_NONE) + { + print_log(DLOG_ERROR, "DALI", "%s: %s(%d) > Failed to create an app_control handle", __MODULE__, __func__, __LINE__); + } + } + mFramework->GetTaskObserver().OnTaskAppControl(appControl); + + app_control_destroy(appControl); + return 0; + } + + void OnUiEvent(AppCoreTaskBase::UiState state) override + { + // This event is emitted when the UI thread is paused or resumed. + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnUiEvent() emitted", __MODULE__, __func__, __LINE__); + + // Note: This isn't implemented. + AppCoreTaskBase::OnUiEvent(state); + } + + void OnLowMemory(AppCoreTaskBase::LowMemoryState state) override + { + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLowMemory() emitted", __MODULE__, __func__, __LINE__); + + mNewMemoryStatus = AppCore::GetMemoryStatus(static_cast(state)); + + PostToUiThread( + [](gpointer userData) -> gboolean { + auto* task = static_cast(userData); + auto* framework = static_cast(task->mFramework); + framework->GetObserver().OnMemoryLow(task->mNewMemoryStatus); + return G_SOURCE_REMOVE; + }); + mFramework->GetTaskObserver().OnTaskMemoryLow(mNewMemoryStatus); + AppCoreTaskBase::OnLowMemory(state); + } + + void OnDeviceOrientationChanged(AppCoreTaskBase::DeviceOrientationState state) override + { + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnDeviceOrientationChanged() emitted, orientation :%d", __MODULE__, __func__, __LINE__, state); + + mNewDeviceOrientationStatus = AppCore::GetOrientationStatus(static_cast(state)); + + PostToUiThread( + [](gpointer userData) -> gboolean { + auto* task = static_cast(userData); + auto* framework = static_cast(task->mFramework); + framework->GetObserver().OnDeviceOrientationChanged(task->mNewDeviceOrientationStatus); + return G_SOURCE_REMOVE; + }); + + mFramework->GetTaskObserver().OnTaskDeviceOrientationChanged(mNewDeviceOrientationStatus); + + AppCoreTaskBase::OnDeviceOrientationChanged(state); + } + void OnLowBattery(AppCoreTaskBase::LowBatteryState state) override + { + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLowBattery() emitted", __MODULE__, __func__, __LINE__); + mNewBatteryStatus = AppCore::GetBatteryStatus(static_cast(state)); + + PostToUiThread( + [](gpointer userData) -> gboolean { + auto* task = static_cast(userData); + auto* framework = static_cast(task->mFramework); + framework->GetObserver().OnBatteryLow(task->mNewBatteryStatus); + return G_SOURCE_REMOVE; + }); + mFramework->GetTaskObserver().OnTaskBatteryLow(mNewBatteryStatus); + AppCoreTaskBase::OnLowBattery(state); + } + + void OnLangChanged(const std::string& lang) override + { + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLangChanged() emitted 1", __MODULE__, __func__, __LINE__); + mNewLanguage = lang; + mFramework->SetLanguage(mNewLanguage); + + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLangChanged() emitted 2", __MODULE__, __func__, __LINE__); + PostToUiThread( + [](gpointer userData) -> gboolean { + auto* task = static_cast(userData); + auto* framework = static_cast(task->mFramework); + framework->GetObserver().OnLanguageChanged(); + return G_SOURCE_REMOVE; + }); + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLangChanged() emitted 3", __MODULE__, __func__, __LINE__); + + mFramework->GetTaskObserver().OnTaskLanguageChanged(); + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLangChanged() emitted 4", __MODULE__, __func__, __LINE__); + AppCoreTaskBase::OnLangChanged(lang); + + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLangChanged() emitted 5", __MODULE__, __func__, __LINE__); + } + + void OnRegionChanged(const std::string& region) override + { + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > nRegionChanged() emitted", __MODULE__, __func__, __LINE__); + mNewRegion = region; + mFramework->SetRegion(mNewRegion); + + PostToUiThread( + [](gpointer userData) -> gboolean { + auto* task = static_cast(userData); + auto* framework = static_cast(task->mFramework); + framework->GetObserver().OnRegionChanged(); + return G_SOURCE_REMOVE; + }); + + mFramework->GetTaskObserver().OnTaskRegionChanged(); + AppCoreTaskBase::OnRegionChanged(mNewRegion); + } + + private: + GMainContext* GetTizenGlibContext() + { + GMainContext* context; + const char* env = getenv("TIZEN_GLIB_CONTEXT"); + if(env) + { + context = (GMainContext*)strtoul(env, nullptr, 10); + } + else + { + context = nullptr; + } + + return context; + } + + void PostToUiThread(GSourceFunc func) + { + GSource* source = g_idle_source_new(); + g_source_set_callback(source, func, this, nullptr); + g_source_attach(source, GetTizenGlibContext()); + g_source_unref(source); + } + + private: + FrameworkTizen* mFramework; + std::string mNewLanguage; + std::string mNewRegion; + Dali::DeviceStatus::Battery::Status mNewBatteryStatus; + Dali::DeviceStatus::Memory::Status mNewMemoryStatus; + Dali::DeviceStatus::Orientation::Status mNewDeviceOrientationStatus; + }; + + explicit UiAppContext(unsigned int hint, FrameworkTizen* framework) + : AppCoreUiBase(hint), + mFramework(framework), + mUseUiThread(false) + { + if(hint & AppCoreUiBase::HINT_DUAL_THREAD) + { + mUseUiThread = true; + } + + if(!mUseUiThread) + { + mLanguageChanged = std::make_shared(IAppCore::IEvent::Type::LANG_CHANGE, OnLanguageChanged, this); + AddEvent(mLanguageChanged); + + mDeviceOrientationChanged = std::make_shared(IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED, OnDeviceOrientationChanged, this); + AddEvent(mDeviceOrientationChanged); + + mRegionFormatChanged = std::make_shared(IAppCore::IEvent::Type::REGION_CHANGE, OnRegionFormatChanged, this); + AddEvent(mRegionFormatChanged); + + mLowMemory = std::make_shared(IAppCore::IEvent::Type::LOW_MEMORY, OnLowMemory, this); + AddEvent(mLowMemory); + + mLowBattery = std::make_shared(IAppCore::IEvent::Type::LOW_BATTERY, OnLowBattery, this); + AddEvent(mLowBattery); + } + } + + virtual ~UiAppContext() + { + if(!mUseUiThread) + { + RemoveEvent(mLowBattery); + RemoveEvent(mLowMemory); + RemoveEvent(mRegionFormatChanged); + RemoveEvent(mDeviceOrientationChanged); + RemoveEvent(mLanguageChanged); + } + } + + std::unique_ptr CreateTask() override + { + return std::unique_ptr( + new Task(mFramework)); + } + + int OnCreate() override + { + AppCoreUiBase::OnCreate(); + mFramework->Create(); + return 0; + } + + int OnTerminate() override + { + AppCoreUiBase::OnTerminate(); + auto* observer = &mFramework->GetObserver(); + observer->OnTerminate(); + return 0; + } + + int OnPause() override + { + AppCoreUiBase::OnPause(); + auto* observer = &mFramework->GetObserver(); + observer->OnPause(); + return 0; + } + + int OnResume() override + { + AppCoreUiBase::OnResume(); + auto* observer = &mFramework->GetObserver(); + observer->OnResume(); + return 0; + } + + int OnControl(tizen_base::Bundle b) override + { + AppCoreUiBase::OnControl(b); + + app_control_h appControl = nullptr; + + auto* bundleData = b.GetHandle(); + if(bundleData) + { + if(app_control_create_event(bundleData, &appControl) != TIZEN_ERROR_NONE) + { + DALI_LOG_ERROR("Failed to create an app_control handle"); + return 0; + } + } + else + { + if(app_control_create(&appControl) != TIZEN_ERROR_NONE) + { + DALI_LOG_ERROR("Failed to create an app_control handle"); + return 0; + } + } + + auto* observer = &mFramework->GetObserver(); + ProcessBundle(mFramework, bundleData); + observer->OnReset(); + observer->OnAppControl(appControl); + app_control_destroy(appControl); + return 0; + } + + void OnLoopInit(int argc, char** argv) override + { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wold-style-cast" + ecore_init(); + ecore_app_args_set(argc, (const char**)argv); +#pragma GCC diagnostic pop + +#ifdef DALI_ELDBUS_AVAILABLE + // Initialize ElDBus. + DALI_LOG_INFO(gDBusLogging, Debug::General, "Starting DBus Initialization\n"); + eldbus_init(); +#endif + } + + void OnLoopFinish() override + { + ecore_shutdown(); + + if(getenv("AUL_LOADER_INIT")) + { + setenv("AUL_LOADER_INIT", "0", 1); + ecore_shutdown(); + } + +#ifdef DALI_ELDBUS_AVAILABLE + // Shutdown ELDBus. + DALI_LOG_INFO(gDBusLogging, Debug::General, "Shutting down DBus\n"); + eldbus_shutdown(); +#endif + } + + void OnLoopRun() override + { + ecore_main_loop_begin(); + } + + void OnLoopExit() override + { + ecore_main_loop_quit(); + } + + private: + static void OnLanguageChanged(app_event_info_h event_info, void* user_data) + { + auto* context = static_cast(user_data); + auto* framework = context->mFramework; + Framework::Observer* observer = &framework->GetObserver(); + + char* lang = nullptr; + auto appEventReturn = app_event_get_language(event_info, &lang); + if(appEventReturn == APP_ERROR_NONE && lang) + { + framework->SetLanguage(std::string(lang)); + observer->OnLanguageChanged(); + free(lang); + } + else + { + DALI_LOG_ERROR("NULL pointer in Language changed event. Error code : %d\n", static_cast(appEventReturn)); + } + } + + static void OnRegionFormatChanged(app_event_info_h event_info, void* user_data) + { + auto* context = static_cast(user_data); + auto* framework = context->mFramework; + Framework::Observer* observer = &framework->GetObserver(); + + char* region = nullptr; + auto appEventReturn = app_event_get_region_format(event_info, ®ion); + if(appEventReturn == APP_ERROR_NONE && region) + { + framework->SetRegion(std::string(region)); + observer->OnRegionChanged(); + free(region); + } + else + { + DALI_LOG_ERROR("NULL pointer in Region changed event. Error code : %d\n", static_cast(appEventReturn)); + } + } + + static void OnLowBattery(app_event_info_h event_info, void* user_data) + { + auto* context = static_cast(user_data); + auto* framework = context->mFramework; + Framework::Observer* observer = &framework->GetObserver(); + + app_event_low_battery_status_e status; + auto appEventReturn = app_event_get_low_battery_status(event_info, &status); + if(appEventReturn == APP_ERROR_NONE) + { + Dali::DeviceStatus::Battery::Status result = AppCore::GetBatteryStatus(status); + observer->OnBatteryLow(result); + } + else + { + DALI_LOG_ERROR("Fail to get low battery status event. Error code : %d\n", static_cast(appEventReturn)); + } + } + + static void OnLowMemory(app_event_info_h event_info, void* user_data) + { + auto* context = static_cast(user_data); + auto* framework = context->mFramework; + Framework::Observer* observer = &framework->GetObserver(); + + app_event_low_memory_status_e status; + auto appEventReturn = app_event_get_low_memory_status(event_info, &status); + if(appEventReturn == APP_ERROR_NONE) + { + Dali::DeviceStatus::Memory::Status result = AppCore::GetMemoryStatus(status); + observer->OnMemoryLow(result); + } + else + { + DALI_LOG_ERROR("Fail to get low memory status event. Error code : %d\n", static_cast(appEventReturn)); + } + } + + static void OnDeviceOrientationChanged(app_event_info_h event_info, void* user_data) + { + auto* context = static_cast(user_data); + auto* framework = context->mFramework; + Framework::Observer* observer = &framework->GetObserver(); + + app_device_orientation_e status; + auto appEventReturn = app_event_get_device_orientation(event_info, &status); + if(appEventReturn == APP_ERROR_NONE) + { + Dali::DeviceStatus::Orientation::Status result = AppCore::GetOrientationStatus(status); + observer->OnDeviceOrientationChanged(result); + } + else + { + DALI_LOG_ERROR("Fail to get device orientation event. Error code : %d\n", static_cast(appEventReturn)); + } + } + + void ProcessBundle(FrameworkTizen* framework, bundle* bundleData) + { + if(bundleData == nullptr) + { + return; + } + + // get bundle name + char* bundleName = const_cast(bundle_get_val(bundleData, "name")); + if(bundleName != nullptr) + { + framework->SetBundleName(bundleName); + } + + // get bundle? id + char* bundleId = const_cast(bundle_get_val(bundleData, "id")); + if(bundleId != nullptr) + { + framework->SetBundleId(bundleId); + } + } + + private: + FrameworkTizen* mFramework; + std::shared_ptr mLanguageChanged; + std::shared_ptr mDeviceOrientationChanged; + std::shared_ptr mRegionFormatChanged; + std::shared_ptr mLowBattery; + std::shared_ptr mLowMemory; + bool mUseUiThread; + }; + + int AppMain(void* data) + { + FrameworkTizen* mFramework = static_cast(data); + if(mUiAppContext.get() == nullptr) + { + unsigned int hint = AppCoreUiBase::HINT_WINDOW_GROUP_CONTROL | + AppCoreUiBase::HINT_WINDOW_STACK_CONTROL | + AppCoreUiBase::HINT_BG_LAUNCH_CONTROL | + AppCoreUiBase::HINT_HW_ACC_CONTROL | + AppCoreUiBase::HINT_WINDOW_AUTO_CONTROL; + +#ifdef UI_THREAD_AVAILABLE + // For testing UIThread model, This code turns on the UI Thread feature forcibly. + // ex) app_launcher -e [APPID] __K_UI_THREAD enable + // This code doesn't change mUseUiThread in Internal::Application + bundle* b = bundle_import_from_argv(*mFramework->GetArgc(), *mFramework->GetArgv()); + if(b != nullptr) + { + const char* val = bundle_get_val(b, "__K_UI_THREAD"); + if(val != nullptr && strcmp(val, "enable") == 0) + { + mUseUiThread = true; + } + + bundle_free(b); + } + + if(mUseUiThread) + { + hint |= AppCoreUiBase::HINT_DUAL_THREAD; + } +#endif + + mUiAppContext = std::make_unique(hint, mFramework); + } + + mUiAppContext->Run(*mFramework->GetArgc(), *mFramework->GetArgv()); + return APP_ERROR_NONE; + } + + void AppExit() + { + if(mUiAppContext.get() == nullptr) + { + return; + } + + mUiAppContext->Exit(); + } + + Impl(void* data, bool useUiThread) + : mUseUiThread(useUiThread) + { + mAppModelNormal = static_cast(data); + } + + ~Impl() + { + } + + AppModelNormal* mAppModelNormal; + std::unique_ptr mUiAppContext{nullptr}; + bool mUseUiThread{false}; +}; + +AppModelNormal::AppModelNormal(bool isUiThread) +{ + mImpl = new Impl(this, isUiThread); +} + +AppModelNormal::~AppModelNormal() +{ + delete mImpl; +} + +int AppModelNormal::AppMain(void* data) +{ + return mImpl->AppMain(data); +} + +void AppModelNormal::AppExit() +{ + mImpl->AppExit(); +} + +} // Adaptor +} // Internal +} // Dali + diff --git a/dali/internal/application-model/normal/appmodel-normal-tizen.h b/dali/internal/application-model/normal/appmodel-normal-tizen.h new file mode 100644 index 0000000..4038802 --- /dev/null +++ b/dali/internal/application-model/normal/appmodel-normal-tizen.h @@ -0,0 +1,55 @@ +#ifndef APPMODEL_NORMAL_H +#define APPMODEL_NORMAL_H +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ +class AppModelNormal +{ +public: // Construction & Destruction + /** + * Constructor + */ + AppModelNormal(bool isUiThread); + + /** + * Destructor + */ + ~AppModelNormal(); + +public: + int AppMain(void* data); + void AppExit(); + +private: // impl members + struct Impl; + Impl* mImpl; +}; +} +} +} + +#endif // APPMODEL_NORMAL_H + diff --git a/dali/internal/application-model/watch/appmodel-watch-tizen.cpp b/dali/internal/application-model/watch/appmodel-watch-tizen.cpp new file mode 100644 index 0000000..6a7a5d5 --- /dev/null +++ b/dali/internal/application-model/watch/appmodel-watch-tizen.cpp @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// CONDITIONAL INCLUDES +#ifdef APPCORE_WATCH_AVAILABLE +#include +#endif + +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ +extern "C" DALI_ADAPTOR_API AppModelWatch* Create() { + return new AppModelWatch; +} + +extern "C" DALI_ADAPTOR_API void Destroy(void* p) { + delete p; +} + +extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData) { + AppModelWatch* appWatch = static_cast(pData); + int ret = 0; + if (appWatch != nullptr) + { + ret = appWatch->AppMain(data); + } + else + { + print_log(DLOG_INFO, "DALI", "appWatch is nullptr"); + } + return ret; +} + +extern "C" DALI_ADAPTOR_API void AppExit(AppModelWatch* p) { + p->AppExit(); +} + +namespace AppCoreWatch +{ +typedef enum +{ + LOW_MEMORY, //< The low memory event + LOW_BATTERY, //< The low battery event + LANGUAGE_CHANGED, //< The system language changed event + DEVICE_ORIENTATION_CHANGED, //< The device orientation changed event + REGION_FORMAT_CHANGED, //< The region format changed event + SUSPENDED_STATE_CHANGED, //< The suspended state changed event of the application + UPDATE_REQUESTED, //< The update requested event. This event can occur when an app needs to be updated. It is dependent on target devices. +} AppEventType; + +static int AppEventConverter[APPCORE_BASE_EVENT_MAX] = +{ + [LOW_MEMORY] = APPCORE_BASE_EVENT_LOW_MEMORY, + [LOW_BATTERY] = APPCORE_BASE_EVENT_LOW_BATTERY, + [LANGUAGE_CHANGED] = APPCORE_BASE_EVENT_LANG_CHANGE, + [DEVICE_ORIENTATION_CHANGED] = APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED, + [REGION_FORMAT_CHANGED] = APPCORE_BASE_EVENT_REGION_CHANGE, + [SUSPENDED_STATE_CHANGED] = APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE, +}; + +struct AppEventInfo +{ + AppEventType type; + void* value; +}; + +typedef struct AppEventInfo* AppEventInfoPtr; + +typedef void (*AppEventCallback)(AppEventInfoPtr eventInfo, void* userData); + +struct AppEventHandler +{ + AppEventType type; + AppEventCallback cb; + void* data; + void* raw; +}; + +typedef struct AppEventHandler* AppEventHandlerPtr; + +int EventCallback(void* event, void* data) +{ + AppEventHandlerPtr handler = static_cast(data); + + struct AppEventInfo appEvent; + + appEvent.type = handler->type; + appEvent.value = event; + + if(handler->cb) + handler->cb(&appEvent, handler->data); + + return 0; +} + +int AppAddEventHandler(AppEventHandlerPtr* eventHandler, AppEventType eventType, AppEventCallback callback, void* userData) +{ + AppEventHandlerPtr handler; + + handler = static_cast(calloc(1, sizeof(struct AppEventHandler))); + if(!handler) + { + DALI_LOG_ERROR("failed to create handler"); + return TIZEN_ERROR_UNKNOWN; + } + else + { + handler->type = eventType; + handler->cb = callback; + handler->data = userData; + handler->raw = appcore_base_add_event(static_cast(AppEventConverter[static_cast(eventType)]), EventCallback, handler); + + *eventHandler = handler; + + return TIZEN_ERROR_NONE; + } +} +} +struct DALI_ADAPTOR_API AppModelWatch::Impl +{ + +#ifdef APPCORE_WATCH_AVAILABLE + static bool WatchAppCreate(int width, int height, void* data) + { + return static_cast(data)->Create(); + } + + static void WatchAppTimeTick(watch_time_h time, void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + WatchTime curTime(time); + + observer->OnTimeTick(curTime); + } + + static void WatchAppAmbientTick(watch_time_h time, void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + WatchTime curTime(time); + + observer->OnAmbientTick(curTime); + } + + static void WatchAppAmbientChanged(bool ambient, void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + + observer->OnAmbientChanged(ambient); + } + + static void WatchAppControl(app_control_h app_control, void* data) + { + FrameworkTizen* framework = static_cast(data); + Framework::Observer* observer = &framework->GetObserver(); + bundle* bundleData = NULL; + + app_control_to_bundle(app_control, &bundleData); + ProcessBundle(framework, bundleData); + + observer->OnReset(); + observer->OnAppControl(app_control); + } + + static void WatchAppTerminate(void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + + observer->OnTerminate(); + } + + static void WatchAppPause(void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + + observer->OnPause(); + } + + static void WatchAppResume(void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + + observer->OnResume(); + } + + static void ProcessBundle(FrameworkTizen* framework, bundle* bundleData) + { + if(bundleData == NULL) + { + return; + } + + // get bundle name + char* bundleName = const_cast(bundle_get_val(bundleData, "name")); + if(bundleName != NULL) + { + framework->SetBundleName(bundleName); + } + + // get bundle? id + char* bundleId = const_cast(bundle_get_val(bundleData, "id")); + if(bundleId != NULL) + { + framework->SetBundleId(bundleId); + } + } +#endif + + static void AppLanguageChanged(AppCoreWatch::AppEventInfoPtr event, void* data) + { + FrameworkTizen* framework = static_cast(data); + Framework::Observer* observer = &framework->GetObserver(); + + if(event && event->value) + { + framework->SetLanguage(std::string(static_cast(event->value))); + observer->OnLanguageChanged(); + } + else + { + DALI_LOG_ERROR("NULL pointer in Language changed event\n"); + } + } + + static void AppRegionChanged(AppCoreWatch::AppEventInfoPtr event, void* data) + { + FrameworkTizen* framework = static_cast(data); + Framework::Observer* observer = &framework->GetObserver(); + + if(event && event->value) + { + framework->SetRegion(std::string(static_cast(event->value))); + observer->OnRegionChanged(); + } + else + { + DALI_LOG_ERROR("NULL pointer in Region changed event\n"); + } + } + + static void AppBatteryLow(AppCoreWatch::AppEventInfoPtr event, void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + int status = *static_cast(event->value); + Dali::DeviceStatus::Battery::Status result = Dali::DeviceStatus::Battery::Status::NORMAL; + + // convert to dali battery status + switch(status) + { + case 1: + { + result = Dali::DeviceStatus::Battery::POWER_OFF; + break; + } + case 2: + { + result = Dali::DeviceStatus::Battery::CRITICALLY_LOW; + break; + } + default: + break; + } + observer->OnBatteryLow(result); + } + + static void AppMemoryLow(AppCoreWatch::AppEventInfoPtr event, void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + int status = *static_cast(event->value); + Dali::DeviceStatus::Memory::Status result = Dali::DeviceStatus::Memory::Status::NORMAL; + + // convert to dali memmory status + switch(status) + { + case 1: + { + result = Dali::DeviceStatus::Memory::NORMAL; + break; + } + case 2: + { + result = Dali::DeviceStatus::Memory::LOW; + break; + } + case 4: + { + result = Dali::DeviceStatus::Memory::CRITICALLY_LOW; + break; + } + default: + break; + } + observer->OnMemoryLow(result); + } + + static void AppDeviceOrientationChanged(AppCoreWatch::AppEventInfoPtr event, void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + int status = *static_cast(event->value); + Dali::DeviceStatus::Orientation::Status result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_0; + + switch(status) + { + case APP_DEVICE_ORIENTATION_0: + { + result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_0; + break; + } + case APP_DEVICE_ORIENTATION_90: + { + result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_90; + break; + } + case APP_DEVICE_ORIENTATION_180: + { + result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_180; + break; + } + case APP_DEVICE_ORIENTATION_270: + { + result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_270; + break; + } + + default: + break; + } + observer->OnDeviceOrientationChanged(result); + } + + int AppMain(void* data) + { + int ret = TIZEN_ERROR_NOT_SUPPORTED; + +#ifdef APPCORE_WATCH_AVAILABLE + FrameworkTizen* mFramework = static_cast(data); + mWatchCallback.create = WatchAppCreate; + mWatchCallback.app_control = WatchAppControl; + mWatchCallback.terminate = WatchAppTerminate; + mWatchCallback.pause = WatchAppPause; + mWatchCallback.resume = WatchAppResume; + mWatchCallback.time_tick = WatchAppTimeTick; + mWatchCallback.ambient_tick = WatchAppAmbientTick; + mWatchCallback.ambient_changed = WatchAppAmbientChanged; + + AppCoreWatch::AppAddEventHandler(&handlers[AppCoreWatch::LOW_BATTERY], AppCoreWatch::LOW_BATTERY, AppBatteryLow, mFramework); + AppCoreWatch::AppAddEventHandler(&handlers[AppCoreWatch::LOW_MEMORY], AppCoreWatch::LOW_MEMORY, AppMemoryLow, mFramework); + AppCoreWatch::AppAddEventHandler(&handlers[AppCoreWatch::LANGUAGE_CHANGED], AppCoreWatch::LANGUAGE_CHANGED, AppLanguageChanged, mFramework); + AppCoreWatch::AppAddEventHandler(&handlers[AppCoreWatch::REGION_FORMAT_CHANGED], AppCoreWatch::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework); + + ret = watch_app_main(*mFramework->GetArgc(), *mFramework->GetArgv(), &mWatchCallback, mFramework); +#else + DALI_LOG_ERROR("watch feature is not supported"); +#endif + return ret; + } + + void AppExit() + { +#ifdef APPCORE_WATCH_AVAILABLE + watch_app_exit(); +#endif + } + + + Impl(void* data) + : handlers{nullptr, nullptr, nullptr, nullptr, nullptr} +#ifdef APPCORE_WATCH_AVAILABLE + , + mWatchCallback() +#endif + { + mAppModelWatch = static_cast(data); + } + + ~Impl() + { + } + + AppModelWatch* mAppModelWatch; + AppCoreWatch::AppEventHandlerPtr handlers[5]; +#ifdef APPCORE_WATCH_AVAILABLE + watch_app_lifecycle_callback_s mWatchCallback; +#endif +}; + +AppModelWatch::AppModelWatch() +{ + mImpl = new Impl(this); +} + +AppModelWatch::~AppModelWatch() +{ + delete mImpl; +} + +int AppModelWatch::AppMain(void *data) +{ + return mImpl->AppMain(data); +} + +void AppModelWatch::AppExit() +{ + mImpl->AppExit(); +} + +} // Adaptor +} // Internal +} // Dali + diff --git a/dali/internal/application-model/watch/appmodel-watch-tizen.h b/dali/internal/application-model/watch/appmodel-watch-tizen.h new file mode 100644 index 0000000..f97b23f --- /dev/null +++ b/dali/internal/application-model/watch/appmodel-watch-tizen.h @@ -0,0 +1,56 @@ +#ifndef APPMODEL_WATCH_H +#define APPMODEL_WATCH_H +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ +class AppModelWatch +{ +public: // Construction & Destruction + /** + * Constructor + */ + AppModelWatch(); + + /** + * Destructor + */ + ~AppModelWatch(); + +public: + int AppMain(void* data); + void AppExit(); + +private: // impl members + struct Impl; + Impl* mImpl; +}; + +} +} +} + +#endif // APPMODEL_WATCH_H + diff --git a/dali/internal/application-model/widget/appmodel-widget-tizen.cpp b/dali/internal/application-model/widget/appmodel-widget-tizen.cpp new file mode 100644 index 0000000..109ed10 --- /dev/null +++ b/dali/internal/application-model/widget/appmodel-widget-tizen.cpp @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DALI_ELDBUS_AVAILABLE +#include +#endif // DALI_ELDBUS_AVAILABLE + +// INTERNAL INCLUDES +#include +#include +#include +#include +#include + +#define DEBUG_PRINTF(fmt, arg...) LOGD(" " fmt, ##arg) + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ + +extern "C" DALI_ADAPTOR_API AppModelWidget* Create() { + print_log(DLOG_INFO, "DALI", "AppModelWidget Create"); + return new AppModelWidget(); +} + +extern "C" DALI_ADAPTOR_API void Destroy(void* p) { + delete p; +} + +extern "C" DALI_ADAPTOR_API int AppMain(bool isUiThread, void* data, void* pData) { + print_log(DLOG_INFO, "DALI", "AppModelWidget AppMain 1"); + AppModelWidget* appWidget = static_cast(pData); + int ret = 0; + if (appWidget != nullptr) + { + print_log(DLOG_INFO, "DALI", "AppModelWidget AppMain 2"); + ret = appWidget->AppMain(data); + } + else + { + print_log(DLOG_INFO, "DALI", "appWidget is nullptr"); + } + return ret; +} + +extern "C" DALI_ADAPTOR_API void AppExit(AppModelWidget* p) { + p->AppExit(); +} + +namespace +{ +#if defined(DEBUG_ENABLED) +Integration::Log::Filter* gDBusLogging = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DBUS"); +#endif +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_FRAMEWORK, true); +} // anonymous namespace + +namespace AppCoreWidget +{ +typedef enum +{ + LOW_MEMORY, //< The low memory event + LOW_BATTERY, //< The low battery event + LANGUAGE_CHANGED, //< The system language changed event + DEVICE_ORIENTATION_CHANGED, //< The device orientation changed event + REGION_FORMAT_CHANGED, //< The region format changed event + SUSPENDED_STATE_CHANGED, //< The suspended state changed event of the application + UPDATE_REQUESTED, //< The update requested event. This event can occur when an app needs to be updated. It is dependent on target devices. +} AppEventType; + +static int AppEventConverter[APPCORE_BASE_EVENT_MAX] = +{ + [LOW_MEMORY] = APPCORE_BASE_EVENT_LOW_MEMORY, + [LOW_BATTERY] = APPCORE_BASE_EVENT_LOW_BATTERY, + [LANGUAGE_CHANGED] = APPCORE_BASE_EVENT_LANG_CHANGE, + [DEVICE_ORIENTATION_CHANGED] = APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED, + [REGION_FORMAT_CHANGED] = APPCORE_BASE_EVENT_REGION_CHANGE, + [SUSPENDED_STATE_CHANGED] = APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE, +}; + +struct AppEventInfo +{ + AppEventType type; + void* value; +}; + +typedef struct AppEventInfo* AppEventInfoPtr; + +typedef void (*AppEventCallback)(AppEventInfoPtr eventInfo, void* userData); + +struct AppEventHandler +{ + AppEventType type; + AppEventCallback cb; + void* data; + void* raw; +}; + +typedef struct AppEventHandler* AppEventHandlerPtr; + +int EventCallback(void* event, void* data) +{ + AppEventHandlerPtr handler = static_cast(data); + + struct AppEventInfo appEvent; + + appEvent.type = handler->type; + appEvent.value = event; + + if(handler->cb) + handler->cb(&appEvent, handler->data); + + return 0; +} + +int AppAddEventHandler(AppEventHandlerPtr* eventHandler, AppEventType eventType, AppEventCallback callback, void* userData) +{ + AppEventHandlerPtr handler; + + handler = static_cast(calloc(1, sizeof(struct AppEventHandler))); + if(!handler) + { + DALI_LOG_ERROR("failed to create handler"); + return TIZEN_ERROR_UNKNOWN; + } + else + { + handler->type = eventType; + handler->cb = callback; + handler->data = userData; + handler->raw = appcore_base_add_event(static_cast(AppEventConverter[static_cast(eventType)]), EventCallback, handler); + + *eventHandler = handler; + + return TIZEN_ERROR_NONE; + } +} +} + +struct DALI_ADAPTOR_API AppModelWidget::Impl +{ + bool IsWidgetFeatureEnabled() + { + static bool feature = false; + static bool retrieved = false; + int ret; + + if(retrieved == true) + { + return feature; + } + + ret = system_info_get_platform_bool("http://tizen.org/feature/shell.appwidget", &feature); + if(ret != SYSTEM_INFO_ERROR_NONE) + { + DALI_LOG_ERROR("failed to get system info"); + return false; + } + + retrieved = true; + return feature; + } + + void AppExit() + { + widget_base_exit(); + } + + static int WidgetAppCreate(void* data) + { + widget_base_on_create(); + return static_cast(static_cast(data)->Create()); + } + + static int WidgetAppTerminate(void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + observer->OnTerminate(); + + widget_base_on_terminate(); + return 0; + } + + static void AppInit(int argc, char** argv, void* data) + { + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wold-style-cast" + ecore_init(); + ecore_app_args_set(argc, (const char**)argv); + #pragma GCC diagnostic pop + + #ifdef DALI_ELDBUS_AVAILABLE + // Initialize ElDBus. + DALI_LOG_INFO(gDBusLogging, Debug::General, "Starting DBus Initialization\n"); + eldbus_init(); + #endif + } + + static void AppFinish(void) + { + ecore_shutdown(); + + if(getenv("AUL_LOADER_INIT")) + { + setenv("AUL_LOADER_INIT", "0", 1); + ecore_shutdown(); + } + + #ifdef DALI_ELDBUS_AVAILABLE + // Shutdown ELDBus. + DALI_LOG_INFO(gDBusLogging, Debug::General, "Shutting down DBus\n"); + eldbus_shutdown(); + #endif + } + + static void AppRun(void* data) + { + ecore_main_loop_begin(); + } + + static void AppExit(void* data) + { + ecore_main_loop_quit(); + } + + + static void AppLanguageChanged(AppCoreWidget::AppEventInfoPtr event, void* data) + { + FrameworkTizen* framework = static_cast(data); + Framework::Observer* observer = &framework->GetObserver(); + + if(event && event->value) + { + framework->SetLanguage(std::string(static_cast(event->value))); + observer->OnLanguageChanged(); + } + else + { + DALI_LOG_ERROR("NULL pointer in Language changed event\n"); + } + } + + static void AppRegionChanged(AppCoreWidget::AppEventInfoPtr event, void* data) + { + FrameworkTizen* framework = static_cast(data); + Framework::Observer* observer = &framework->GetObserver(); + + if(event && event->value) + { + framework->SetRegion(std::string(static_cast(event->value))); + observer->OnRegionChanged(); + } + else + { + DALI_LOG_ERROR("NULL pointer in Region changed event\n"); + } + } + + static void AppBatteryLow(AppCoreWidget::AppEventInfoPtr event, void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + int status = *static_cast(event->value); + Dali::DeviceStatus::Battery::Status result = Dali::DeviceStatus::Battery::Status::NORMAL; + + // convert to dali battery status + switch(status) + { + case 1: + { + result = Dali::DeviceStatus::Battery::POWER_OFF; + break; + } + case 2: + { + result = Dali::DeviceStatus::Battery::CRITICALLY_LOW; + break; + } + default: + break; + } + observer->OnBatteryLow(result); + } + + static void AppMemoryLow(AppCoreWidget::AppEventInfoPtr event, void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + int status = *static_cast(event->value); + Dali::DeviceStatus::Memory::Status result = Dali::DeviceStatus::Memory::Status::NORMAL; + + // convert to dali memmory status + switch(status) + { + case 1: + { + result = Dali::DeviceStatus::Memory::NORMAL; + break; + } + case 2: + { + result = Dali::DeviceStatus::Memory::LOW; + break; + } + case 4: + { + result = Dali::DeviceStatus::Memory::CRITICALLY_LOW; + break; + } + default: + break; + } + observer->OnMemoryLow(result); + } + + static void AppDeviceOrientationChanged(AppCoreWidget::AppEventInfoPtr event, void* data) + { + Framework::Observer* observer = &static_cast(data)->GetObserver(); + int status = *static_cast(event->value); + Dali::DeviceStatus::Orientation::Status result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_0; + + switch(status) + { + case APP_DEVICE_ORIENTATION_0: + { + result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_0; + break; + } + case APP_DEVICE_ORIENTATION_90: + { + result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_90; + break; + } + case APP_DEVICE_ORIENTATION_180: + { + result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_180; + break; + } + case APP_DEVICE_ORIENTATION_270: + { + result = Dali::DeviceStatus::Orientation::Status::ORIENTATION_270; + break; + } + + default: + break; + } + observer->OnDeviceOrientationChanged(result); + } + + int AppMain(void* data) + { + print_log(DLOG_INFO, "DALI", "AppModelWidget AppMain 3"); + if(!IsWidgetFeatureEnabled()) + { + DALI_LOG_ERROR("widget feature is not supported"); + return TIZEN_ERROR_NOT_SUPPORTED; + } + FrameworkTizen* mFramework = static_cast(data); + + AppCoreWidget::AppAddEventHandler(&handlers[AppCoreWidget::LOW_BATTERY], AppCoreWidget::LOW_BATTERY, AppBatteryLow, mFramework); + AppCoreWidget::AppAddEventHandler(&handlers[AppCoreWidget::LOW_MEMORY], AppCoreWidget::LOW_MEMORY, AppMemoryLow, mFramework); + AppCoreWidget::AppAddEventHandler(&handlers[AppCoreWidget::DEVICE_ORIENTATION_CHANGED], AppCoreWidget::DEVICE_ORIENTATION_CHANGED, AppDeviceOrientationChanged, mFramework); + AppCoreWidget::AppAddEventHandler(&handlers[AppCoreWidget::LANGUAGE_CHANGED], AppCoreWidget::LANGUAGE_CHANGED, AppLanguageChanged, mFramework); + AppCoreWidget::AppAddEventHandler(&handlers[AppCoreWidget::REGION_FORMAT_CHANGED], AppCoreWidget::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework); + + widget_base_ops ops = widget_base_get_default_ops(); + print_log(DLOG_INFO, "DALI", "AppModelWidget AppMain 4"); + /* override methods */ + ops.create = WidgetAppCreate; + ops.terminate = WidgetAppTerminate; + ops.init = AppInit; + ops.finish = AppFinish; + ops.run = AppRun; + ops.exit = AppExit; + + print_log(DLOG_INFO, "DALI", "AppModelWidget AppMain 5"); + int result = widget_base_init(ops, *mFramework->GetArgc(), *mFramework->GetArgv(), mFramework); + + widget_base_fini(); + print_log(DLOG_INFO, "DALI", "AppModelWidget AppMain 6"); + return result; + } + + Impl(void* data) + : handlers{nullptr, nullptr, nullptr, nullptr, nullptr} + { + mAppModelWidget = static_cast(data); + } + + ~Impl() + { + } + + AppModelWidget* mAppModelWidget; + AppCoreWidget::AppEventHandlerPtr handlers[5]; +}; // Impl + +AppModelWidget::AppModelWidget() +{ + mImpl = new Impl(this); +} + +AppModelWidget::~AppModelWidget() +{ + delete mImpl; +} + +int AppModelWidget::AppMain(void *data) +{ + return mImpl->AppMain(data); +} + +void AppModelWidget::AppExit() +{ + mImpl->AppExit(); +} + +} // namespace Adaptor + +} // namespace Internal + +} // namespace Dali diff --git a/dali/internal/application-model/widget/appmodel-widget-tizen.h b/dali/internal/application-model/widget/appmodel-widget-tizen.h new file mode 100644 index 0000000..5ea0f31 --- /dev/null +++ b/dali/internal/application-model/widget/appmodel-widget-tizen.h @@ -0,0 +1,59 @@ +#ifndef APPMODEL_WIDGET_TIZEN_H +#define APPMODEL_WIDGET_TIZEN_H + +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ +/** + * Plays feedback effects for Dali-Toolkit UI Controls. + */ +class AppModelWidget +{ +public: // Construction & Destruction + /** + * Constructor + */ + AppModelWidget(); + + /** + * Destructor + */ + ~AppModelWidget(); + +public: + int AppMain(void* data); + void AppExit(); + +private: // impl members + struct Impl; + Impl* mImpl; + +}; +} +} +} // Dali + +#endif \ No newline at end of file diff --git a/dali/internal/application-model/widget/widget-base-tizen.cpp b/dali/internal/application-model/widget/widget-base-tizen.cpp new file mode 100644 index 0000000..d240593 --- /dev/null +++ b/dali/internal/application-model/widget/widget-base-tizen.cpp @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + + +// INTERNAL INCLUDE +#include + +#include +#include +#include + +#include +#include +#include + +// EXTERNAL INCLUDES +#include +#include +#include +#include + +#define DEBUG_PRINTF(fmt, arg...) LOGD(" " fmt, ##arg) + +namespace Dali +{ +namespace Internal +{ +namespace +{ + +int OnInstanceInit(widget_base_instance_h instanceHandle, bundle* content, int w, int h, void* classData) +{ + char* id; + widget_base_context_get_id(instanceHandle, &id); + + widget_base_class_on_create(instanceHandle, content, w, h); + + Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(classData); + + Dali::Window window; + if(application->GetWidgetCount() == 0) + { + window = application->GetWidgetWindow(); + DALI_LOG_RELEASE_INFO("Widget Instance use default Window(win:%p), so it need to bind widget (%dx%d) (id:%s) \n", window, w, h, std::string(id).c_str()); + + } + else + { + window = Dali::Window::New(PositionSize(0, 0, w, h), "", false); + if(window) + { + DALI_LOG_RELEASE_INFO("Widget Instance create new Window (win:%p, cnt:%d) (%dx%d) (id:%s )\n", window, application->GetWidgetCount(), w, h, std::string(id).c_str()); + } + else + { + DALI_LOG_ERROR("This device can't support Multi Widget. it means UI may not be properly drawn."); + window = application->GetWidgetWindow(); + } + } + + Any nativeHandle = window.GetNativeHandle(); + +#ifdef ECORE_WAYLAND2 + Ecore_Wl2_Window* wlWindow = AnyCast(nativeHandle); +#else + Ecore_Wl_Window* wlWindow = AnyCast(nativeHandle); +#endif + + widget_base_context_window_bind(instanceHandle, id, wlWindow); + window.SetSize(Dali::Window::WindowSize(w, h)); + + Dali::Internal::Adaptor::WidgetApplication::CreateWidgetFunctionPair pair = application->GetWidgetCreatingFunctionPair(std::string(id)); + Dali::WidgetApplication::CreateWidgetFunction createFunction = pair.second; + + Dali::Widget widgetInstance = createFunction(pair.first); + + application->InitializeWidget(instanceHandle, widgetInstance); + + application->AddWidget(instanceHandle, widgetInstance, window, std::string(id)); + + std::string encodedContentString = ""; + + if(bundle_get_count(content)) + { + bundle_raw* bundleRaw; + int len; + bundle_encode(content, &bundleRaw, &len); + char* encodedContent = reinterpret_cast(bundleRaw); + encodedContentString = std::string(encodedContent); + free(bundleRaw); + } + + Internal::Adaptor::GetImplementation(widgetInstance).OnCreate(encodedContentString, window); + + // connect keyEvent for widget +#ifdef OVER_TIZEN_VERSION_7 + application->ConnectKeyEvent(window); +#endif + + return 0; +} + +int OnInstanceDestroy(widget_base_instance_h instanceHandle, widget_base_destroy_type_e reason, bundle* content, void* classData) +{ + Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(classData); + + // Get Dali::Widget instance. + Dali::Widget widgetInstance = application->GetWidget(instanceHandle); + + Dali::Widget::Termination destroyReason = Dali::Widget::Termination::TEMPORARY; + + if(reason == WIDGET_BASE_DESTROY_TYPE_PERMANENT) + { + destroyReason = Dali::Widget::Termination::PERMANENT; + } + + std::string encodedContentString = ""; + + if(bundle_get_count(content)) + { + bundle_raw* bundleRaw; + int len; + bundle_encode(content, &bundleRaw, &len); + char* encodedContent = reinterpret_cast(bundleRaw); + encodedContentString = std::string(encodedContent); + free(bundleRaw); + } + + Internal::Adaptor::GetImplementation(widgetInstance).OnTerminate(encodedContentString, destroyReason); + + widget_base_class_on_destroy(instanceHandle, reason, content); + + application->DeleteWidget(instanceHandle); + + return 0; +} + +int OnInstancePause(widget_base_instance_h instanceHandle, void* classData) +{ + widget_base_class_on_pause(instanceHandle); + + Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(classData); + + // Get Dali::Widget instance. + Dali::Widget widgetInstance = application->GetWidget(instanceHandle); + + Internal::Adaptor::GetImplementation(widgetInstance).OnPause(); + + return 0; +} + +int OnInstanceResume(widget_base_instance_h instanceHandle, void* classData) +{ + widget_base_class_on_resume(instanceHandle); + + Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(classData); + + // Get Dali::Widget instance. + Dali::Widget widgetInstance = application->GetWidget(instanceHandle); + + Internal::Adaptor::GetImplementation(widgetInstance).OnResume(); + return 0; +} + +int OnInstanceResize(widget_base_instance_h instanceHandle, int w, int h, void* classData) +{ + widget_base_class_on_resize(instanceHandle, w, h); + + Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(classData); + + // Get Dali::Widget instance. + Dali::Widget widgetInstance = application->GetWidget(instanceHandle); + Dali::Window window = application->GetWindowFromWidget(widgetInstance); + window.SetSize(Dali::Window::WindowSize(w, h)); + Internal::Adaptor::GetImplementation(widgetInstance).OnResize(window); + + return 0; +} + +int OnInstanceUpdate(widget_base_instance_h instanceHandle, bundle* content, int force, void* classData) +{ + widget_base_class_on_update(instanceHandle, content, force); + + Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(classData); + + // Get Dali::Widget instance. + Dali::Widget widgetInstance = application->GetWidget(instanceHandle); + + std::string encodedContentString = ""; + + if(bundle_get_count(content)) + { + bundle_raw* bundleRaw; + int len; + bundle_encode(content, &bundleRaw, &len); + char* encodedContent = reinterpret_cast(bundleRaw); + encodedContentString = std::string(encodedContent); + free(bundleRaw); + } + Internal::Adaptor::GetImplementation(widgetInstance).OnUpdate(encodedContentString, force); + + return 0; +} +} +namespace Adaptor +{ +extern "C" DALI_ADAPTOR_API void RegisterWidgetCallback(const char* widgetName, void* data) { + widget_base_class cls = widget_base_class_get_default(); + cls.ops.create = OnInstanceInit; + cls.ops.destroy = OnInstanceDestroy; + cls.ops.pause = OnInstancePause; + cls.ops.resume = OnInstanceResume; + cls.ops.resize = OnInstanceResize; + cls.ops.update = OnInstanceUpdate; + + widget_base_class_add(cls, widgetName, data); +} + +extern "C" DALI_ADAPTOR_API void SetContentInfo(void* handle, bundle* bundleData) { + widget_base_instance_h handle_instance = static_cast(handle); + //bundle* bundle = static_cast(bundleData); + widget_base_context_set_content_info(handle_instance, bundleData); +} +} +} +} diff --git a/dali/internal/application-model/widget/widget-base-tizen.h b/dali/internal/application-model/widget/widget-base-tizen.h new file mode 100644 index 0000000..7913d8d --- /dev/null +++ b/dali/internal/application-model/widget/widget-base-tizen.h @@ -0,0 +1,52 @@ +#ifndef WIDGET_BASE_TIZEN_H +#define WIDGET_BASE_TIZEN_H + +/* + * Copyright (c) 2024 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +namespace Dali +{ +namespace Internal +{ +namespace Adaptor +{ +/** + * Plays feedback effects for Dali-Toolkit UI Controls. + */ +class WidgetBase +{ +public: // Construction & Destruction + /** + * Constructor + */ + WidgetBase(); + + /** + * Destructor + */ + ~WidgetBase(); + +private: // impl members + struct Impl; + Impl* mImpl; + +}; +} +} +} // Dali + +#endif \ No newline at end of file diff --git a/dali/internal/system/tizen-wayland/widget-application-impl-tizen.cpp b/dali/internal/system/tizen-wayland/widget-application-impl-tizen.cpp index bd76bf4..789eea5 100644 --- a/dali/internal/system/tizen-wayland/widget-application-impl-tizen.cpp +++ b/dali/internal/system/tizen-wayland/widget-application-impl-tizen.cpp @@ -19,23 +19,35 @@ #include // INTERNAL INCLUDE +#include #include #include #include -#include + #include #include // EXTERNAL INCLUDES #include -#include - +#include +#include +#include namespace Dali { namespace Internal { namespace { +constexpr char const* const kApplicationNamePrefix = "libdali2-adaptor-application-"; +constexpr char const* const kApplicationNamePostfix = ".so"; + +std::string MakePluginName(const char* appModelName) +{ + std::stringstream fullName; + fullName << kApplicationNamePrefix << appModelName << kApplicationNamePostfix; + return fullName.str(); +} + /** * This Api is called when widget viewer send keyEvent. * In this API, widget framework create a new keyEvent, find the proper widget and send this event. @@ -75,182 +87,6 @@ bool OnKeyEventCallback(const char* id, screen_connector_event_type_e eventType, } #endif -int OnInstanceInit(widget_base_instance_h instanceHandle, bundle* content, int w, int h, void* classData) -{ - char* id; - widget_base_context_get_id(instanceHandle, &id); - - widget_base_class_on_create(instanceHandle, content, w, h); - - Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(classData); - - Dali::Window window; - if(application->GetWidgetCount() == 0) - { - window = application->GetWindow(); - DALI_LOG_RELEASE_INFO("Widget Instance use default Window(win:%p), so it need to bind widget (%dx%d) (id:%s) \n", window, w, h, std::string(id).c_str()); - } - else - { - window = Dali::Window::New(PositionSize(0, 0, w, h), "", false); - if(window) - { - DALI_LOG_RELEASE_INFO("Widget Instance create new Window (win:%p, cnt:%d) (%dx%d) (id:%s )\n", window, application->GetWidgetCount(), w, h, std::string(id).c_str()); - } - else - { - DALI_LOG_ERROR("This device can't support Multi Widget. it means UI may not be properly drawn."); - window = application->GetWindow(); - } - } - - Any nativeHandle = window.GetNativeHandle(); - -#ifdef ECORE_WAYLAND2 - Ecore_Wl2_Window* wlWindow = AnyCast(nativeHandle); -#else - Ecore_Wl_Window* wlWindow = AnyCast(nativeHandle); -#endif - - widget_base_context_window_bind(instanceHandle, id, wlWindow); - window.SetSize(Dali::Window::WindowSize(w, h)); - - Dali::Internal::Adaptor::WidgetApplication::CreateWidgetFunctionPair pair = application->GetWidgetCreatingFunctionPair(std::string(id)); - Dali::WidgetApplication::CreateWidgetFunction createFunction = pair.second; - - Dali::Widget widgetInstance = createFunction(pair.first); - - Dali::Internal::Adaptor::Widget::Impl* widgetImpl = new Dali::Internal::Adaptor::WidgetImplTizen(instanceHandle); - Internal::Adaptor::GetImplementation(widgetInstance).SetImpl(widgetImpl); - - application->AddWidget(instanceHandle, widgetInstance, window, std::string(id)); - - std::string encodedContentString = ""; - - if(bundle_get_count(content)) - { - bundle_raw* bundleRaw; - int len; - bundle_encode(content, &bundleRaw, &len); - char* encodedContent = reinterpret_cast(bundleRaw); - encodedContentString = std::string(encodedContent); - free(bundleRaw); - } - - Internal::Adaptor::GetImplementation(widgetInstance).OnCreate(encodedContentString, window); - - // connect keyEvent for widget -#ifdef OVER_TIZEN_VERSION_7 - application->ConnectKeyEvent(window); -#endif - - return 0; -} - -int OnInstanceDestroy(widget_base_instance_h instanceHandle, widget_base_destroy_type_e reason, bundle* content, void* classData) -{ - Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(classData); - - // Get Dali::Widget instance. - Dali::Widget widgetInstance = application->GetWidget(instanceHandle); - - Dali::Widget::Termination destroyReason = Dali::Widget::Termination::TEMPORARY; - - if(reason == WIDGET_BASE_DESTROY_TYPE_PERMANENT) - { - destroyReason = Dali::Widget::Termination::PERMANENT; - } - - std::string encodedContentString = ""; - - if(bundle_get_count(content)) - { - bundle_raw* bundleRaw; - int len; - bundle_encode(content, &bundleRaw, &len); - char* encodedContent = reinterpret_cast(bundleRaw); - encodedContentString = std::string(encodedContent); - free(bundleRaw); - } - - Internal::Adaptor::GetImplementation(widgetInstance).OnTerminate(encodedContentString, destroyReason); - - widget_base_class_on_destroy(instanceHandle, reason, content); - - application->DeleteWidget(instanceHandle); - - return 0; -} - -int OnInstancePause(widget_base_instance_h instanceHandle, void* classData) -{ - widget_base_class_on_pause(instanceHandle); - - Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(classData); - - // Get Dali::Widget instance. - Dali::Widget widgetInstance = application->GetWidget(instanceHandle); - - Internal::Adaptor::GetImplementation(widgetInstance).OnPause(); - - return 0; -} - -int OnInstanceResume(widget_base_instance_h instanceHandle, void* classData) -{ - widget_base_class_on_resume(instanceHandle); - - Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(classData); - - // Get Dali::Widget instance. - Dali::Widget widgetInstance = application->GetWidget(instanceHandle); - - Internal::Adaptor::GetImplementation(widgetInstance).OnResume(); - - return 0; -} - -int OnInstanceResize(widget_base_instance_h instanceHandle, int w, int h, void* classData) -{ - widget_base_class_on_resize(instanceHandle, w, h); - - Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(classData); - - // Get Dali::Widget instance. - Dali::Widget widgetInstance = application->GetWidget(instanceHandle); - Dali::Window window = application->GetWindowFromWidget(widgetInstance); - window.SetSize(Dali::Window::WindowSize(w, h)); - Internal::Adaptor::GetImplementation(widgetInstance).OnResize(window); - - return 0; -} - -int OnInstanceUpdate(widget_base_instance_h instanceHandle, bundle* content, int force, void* classData) -{ - widget_base_class_on_update(instanceHandle, content, force); - - Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(classData); - - // Get Dali::Widget instance. - Dali::Widget widgetInstance = application->GetWidget(instanceHandle); - - std::string encodedContentString = ""; - - if(bundle_get_count(content)) - { - bundle_raw* bundleRaw; - int len; - bundle_encode(content, &bundleRaw, &len); - char* encodedContent = reinterpret_cast(bundleRaw); - encodedContentString = std::string(encodedContent); - free(bundleRaw); - } - - Internal::Adaptor::GetImplementation(widgetInstance).OnUpdate(encodedContentString, force); - - return 0; -} - unsigned int GetEnvWidgetRenderRefreshRate() { const char* envVariable = std::getenv(DALI_WIDGET_REFRESH_RATE); @@ -282,20 +118,39 @@ WidgetApplicationTizen::~WidgetApplicationTizen() { } +void WidgetApplicationTizen::InitializeWidget(void* instanceHandle, Dali::Widget widgetInstance) +{ + Dali::Internal::Adaptor::Widget::Impl* widgetImpl = new Dali::Internal::Adaptor::WidgetImplTizen(instanceHandle); + Internal::Adaptor::GetImplementation(widgetInstance).SetImpl(widgetImpl); +} + void WidgetApplicationTizen::RegisterWidgetCreatingFunction(const std::string& widgetName, Dali::WidgetApplication::CreateWidgetFunction createFunction) { AddWidgetCreatingFunctionPair(CreateWidgetFunctionPair(widgetName, createFunction)); - // Register widget class to widget framework - widget_base_class cls = widget_base_class_get_default(); - cls.ops.create = OnInstanceInit; - cls.ops.destroy = OnInstanceDestroy; - cls.ops.pause = OnInstancePause; - cls.ops.resume = OnInstanceResume; - cls.ops.resize = OnInstanceResize; - cls.ops.update = OnInstanceUpdate; + using RegisterFunction = void (*)(const char*, void*); + RegisterFunction registerFunctionPtr; + std::string pluginName = MakePluginName("widget"); + + void* mHandle = dlopen(pluginName.c_str(), RTLD_LAZY); - widget_base_class_add(cls, widgetName.c_str(), this); + if(mHandle == nullptr) + { + print_log(DLOG_INFO, "DALI", "error : %s", dlerror() ); + return; + } + + registerFunctionPtr = reinterpret_cast(dlsym(mHandle, "RegisterWidgetCallback")); + if(registerFunctionPtr == nullptr) + { + DALI_LOG_ERROR("createFunctionPtr is null\n"); + } + registerFunctionPtr(widgetName.c_str(), this); + + if(mHandle!=NULL) + { + dlclose(mHandle); + } } void WidgetApplicationTizen::AddWidgetCreatingFunctionPair(CreateWidgetFunctionPair pair) @@ -318,13 +173,13 @@ WidgetApplicationTizen::CreateWidgetFunctionPair WidgetApplicationTizen::GetWidg return CreateWidgetFunctionPair("", NULL); } -void WidgetApplicationTizen::AddWidget(widget_base_instance_h widgetBaseInstance, Dali::Widget widget, Dali::Window window, const std::string& widgetId) +void WidgetApplicationTizen::AddWidget(void* widgetBaseInstance, Dali::Widget widget, Dali::Window window, const std::string& widgetId) { mWidgetInstanceContainer.push_back(WidgetInstancePair(widgetBaseInstance, widget)); Internal::Adaptor::GetImplementation(widget).SetInformation(window, widgetId); } -Dali::Widget WidgetApplicationTizen::GetWidget(widget_base_instance_h widgetBaseInstance) const +Dali::Widget WidgetApplicationTizen::GetWidget(void* widgetBaseInstance) const { for(auto&& iter : mWidgetInstanceContainer) { @@ -336,7 +191,7 @@ Dali::Widget WidgetApplicationTizen::GetWidget(widget_base_instance_h widgetBase return Dali::Widget(); } -void WidgetApplicationTizen::DeleteWidget(widget_base_instance_h widgetBaseInstance) +void WidgetApplicationTizen::DeleteWidget(void* widgetBaseInstance) { // Delete WidgetInstance auto widgetInstance = std::find_if(mWidgetInstanceContainer.begin(), @@ -359,7 +214,7 @@ Dali::Window WidgetApplicationTizen::GetWindowFromWidget(Dali::Widget widgetInst return Dali::Window(); } -widget_base_instance_h WidgetApplicationTizen::GetWidgetInstanceFromWidgetId(std::string& widgetId) const +void* WidgetApplicationTizen::GetWidgetInstanceFromWidgetId(std::string& widgetId) const { for(auto&& iter : mWidgetInstanceContainer) { @@ -377,6 +232,11 @@ int WidgetApplicationTizen::GetWidgetCount() return mWidgetInstanceContainer.size(); } +Dali::Window WidgetApplicationTizen::GetWidgetWindow() +{ + return GetWindow(); +} + void WidgetApplicationTizen::ConnectKeyEvent(Dali::Window window) { if(!mConnectedKeyEvent) @@ -395,7 +255,7 @@ void WidgetApplicationTizen::OnWindowKeyEvent(const Dali::KeyEvent& event) mReceivedKeyEvent = true; } -bool WidgetApplicationTizen::FeedKeyEvent(widget_base_instance_h instanceHandle, const Dali::KeyEvent& keyEvent) +bool WidgetApplicationTizen::FeedKeyEvent(void* instanceHandle, const Dali::KeyEvent& keyEvent) { bool consumed = true; @@ -443,7 +303,6 @@ Dali::Internal::Adaptor::WidgetApplicationPtr Create(int* argc, char** argv[], c { return WidgetApplicationTizen::New(argc, argv, stylesheet, windowData); } - } // namespace WidgetApplicationFactory } // namespace Adaptor diff --git a/dali/internal/system/tizen-wayland/widget-application-impl-tizen.h b/dali/internal/system/tizen-wayland/widget-application-impl-tizen.h index 8b20e80..b42d8f1 100644 --- a/dali/internal/system/tizen-wayland/widget-application-impl-tizen.h +++ b/dali/internal/system/tizen-wayland/widget-application-impl-tizen.h @@ -20,7 +20,6 @@ // EXTERNAL INCLUDES #include -#include // INTERNAL INCLUDES #include @@ -41,7 +40,7 @@ typedef IntrusivePtr WidgetApplicationPtr; /** * Implementation of the WidgetApplication class. */ -class WidgetApplicationTizen : public WidgetApplication, public ConnectionTracker +class DALI_ADAPTOR_API WidgetApplicationTizen : public WidgetApplication, public ConnectionTracker { public: typedef std::pair CreateWidgetFunctionPair; @@ -63,6 +62,11 @@ public: void OnInit() override; /** + * @copydoc This function creates and initalizes a new Widget instance + */ + void InitializeWidget(void* instanceHandle, Dali::Widget widgetInstance); + + /** * @copydoc Dali::WidgetApplication::RegisterWidgetCreator() */ void RegisterWidgetCreatingFunction(const std::string& widgetName, Dali::WidgetApplication::CreateWidgetFunction createFunction) override; @@ -80,17 +84,17 @@ public: /** * Add widget_base_instance_h - Widget instance pair to container. */ - void AddWidget(widget_base_instance_h widgetBaseInstance, Dali::Widget widget, Dali::Window window, const std::string& widgetId); + void AddWidget(void* widgetBaseInstance, Dali::Widget widget, Dali::Window window, const std::string& widgetId); /** * Find and get Widget instance in container by widget_base_instance_h. */ - Dali::Widget GetWidget(widget_base_instance_h widgetBaseInstance) const; + Dali::Widget GetWidget(void* widgetBaseInstance) const; /** * Delete widget_base_instance_h - Widget instance pair in container. */ - void DeleteWidget(widget_base_instance_h widgetBaseInstance); + void DeleteWidget(void* widgetBaseInstance); /** * Find and get Window instance in container by widget_base_instance_h. @@ -100,13 +104,19 @@ public: /** * Find and get widget_base_instance in container by widget id. */ - widget_base_instance_h GetWidgetInstanceFromWidgetId(std::string& widgetId) const; + void* GetWidgetInstanceFromWidgetId(std::string& widgetId) const; + /** * Get the number of created widget. */ int32_t GetWidgetCount(); /** + * Get the number of created widget. + */ + Dali::Window GetWidgetWindow(); + + /** * @brief connect the keyEvent for window * * @param[in] window window for connecting keyEvent @@ -129,7 +139,7 @@ public: * @param[in] keyEvent The key event for widget * @return True if widget consume keyEvent, false otherwise. */ - bool FeedKeyEvent(widget_base_instance_h instanceHandle, const Dali::KeyEvent& keyEvent); + bool FeedKeyEvent(void* instanceHandle, const Dali::KeyEvent& keyEvent); protected: /** @@ -150,7 +160,7 @@ protected: WidgetApplicationTizen& operator=(Application&) = delete; private: - typedef std::pair WidgetInstancePair; + typedef std::pair WidgetInstancePair; typedef std::vector WidgetInstanceContainer; CreateWidgetFunctionContainer mCreateWidgetFunctionContainer; diff --git a/dali/internal/system/tizen-wayland/widget-controller-tizen.cpp b/dali/internal/system/tizen-wayland/widget-controller-tizen.cpp index 5e03ef1..18c13ae 100644 --- a/dali/internal/system/tizen-wayland/widget-controller-tizen.cpp +++ b/dali/internal/system/tizen-wayland/widget-controller-tizen.cpp @@ -21,19 +21,35 @@ // EXTERNAL INCLUDES #include #include -#include +#include +#include +#include // INTERNAL INCLUDES #include #include +#include namespace Dali { namespace Internal { +namespace +{ +constexpr char const* const kApplicationNamePrefix = "libdali2-adaptor-application-"; +constexpr char const* const kApplicationNamePostfix = ".so"; + +std::string MakePluginName(const char* appModelName) +{ + std::stringstream fullName; + fullName << kApplicationNamePrefix << appModelName << kApplicationNamePostfix; + return fullName.str(); +} + +} namespace Adaptor { -WidgetImplTizen::WidgetImplTizen(widget_base_instance_h instanceHandle) +WidgetImplTizen::WidgetImplTizen(void* instanceHandle) : Widget::Impl(), mInstanceHandle(instanceHandle), mWindow(), @@ -53,9 +69,33 @@ void WidgetImplTizen::SetContentInfo(const std::string& contentInfo) int len = contentInfo.length(); contentBundle = bundle_decode(contentBundleRaw, len); - widget_base_context_set_content_info(mInstanceHandle, contentBundle); + + using SetContentInfoFunc = void (*)(void*, bundle*); + SetContentInfoFunc setContentInfoFuncPtr; + std::string pluginName = MakePluginName("widget"); + + void* mHandle = dlopen(pluginName.c_str(), RTLD_LAZY); + + if(mHandle == nullptr) + { + print_log(DLOG_ERROR, "DALI", "error : %s", dlerror() ); + return; + } + + setContentInfoFuncPtr = reinterpret_cast(dlsym(mHandle, "SetContentInfo")); + if(setContentInfoFuncPtr == nullptr) + { + print_log(DLOG_ERROR, "DALI", "SetContentInfo is null\n" ); + return; + } + setContentInfoFuncPtr(mInstanceHandle, contentBundle); bundle_free(contentBundle); + + if(mHandle!=NULL) + { + dlclose(mHandle); + } } bool WidgetImplTizen::IsKeyEventUsing() const diff --git a/dali/public-api/watch/watch-time.h b/dali/public-api/watch/watch-time.h index c2d0b6f..9b65224 100644 --- a/dali/public-api/watch/watch-time.h +++ b/dali/public-api/watch/watch-time.h @@ -191,7 +191,7 @@ public: bool GetDaylightSavingTimeStatus() const; public: // Not intended for application developers - DALI_INTERNAL WatchTime(void* time_handle); + DALI_ADAPTOR_API WatchTime(void* time_handle); private: // Internal Data struct Impl; diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index 4b0282e..ed1e61a 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -322,6 +322,7 @@ cmake_flags+=" -DCMAKE_INSTALL_LIBDIR=%{_libdir}" cmake_flags+=" -DCMAKE_INSTALL_INCLUDEDIR=%{_includedir}" cmake_flags+=" -DENABLE_TIZEN_MAJOR_VERSION=%{tizen_version_major}" cmake_flags+=" -DENABLE_FEEDBACK=YES" +cmake_flags+=" -DENABLE_APPMODEL=ON" cmake_flags+=" -DENABLE_APPFW=YES" cmake_flags+=" -DCOMPONENT_APPLICATION_SUPPORT=YES" @@ -608,6 +609,10 @@ exit 0 %{_libdir}/libdali2-adaptor.so %{_libdir}/libdali2-adaptor.so.2 %{_libdir}/libdali2-adaptor.so.2.0.0 +%{_libdir}/libdali2-adaptor-application-normal.so* +%{_libdir}/libdali2-adaptor-application-widget.so* +%{_libdir}/libdali2-adaptor-application-watch.so* +%{_libdir}/libdali2-adaptor-application-component-based.so* ################################################# -- 2.7.4