From: Adeel Kazmi Date: Thu, 7 Jul 2022 09:22:42 +0000 (+0000) Subject: Merge "Direct Rendering" into devel/master X-Git-Tag: dali_2.1.30~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dc60601c7426f0a10aefae793ecfdb6b5355a9ba;hp=452c4f518957328984d3ed9b7d7e6507a7c3eb82;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git Merge "Direct Rendering" into devel/master --- diff --git a/dali/devel-api/adaptor-framework/application-devel.cpp b/dali/devel-api/adaptor-framework/application-devel.cpp index 533a68c..8ce55e2 100644 --- a/dali/devel-api/adaptor-framework/application-devel.cpp +++ b/dali/devel-api/adaptor-framework/application-devel.cpp @@ -48,7 +48,7 @@ Application New(int* argc, char** argv[], const std::string& stylesheet, Applica internal->StoreWindowPositionSize(positionSize); } else { - internal = Internal::Adaptor::Application::New(argc, argv, stylesheet, windowMode, positionSize, Internal::Adaptor::Framework::NORMAL, type); + internal = Internal::Adaptor::Application::New(argc, argv, stylesheet, windowMode, positionSize, Internal::Adaptor::Framework::NORMAL, type, false); } return Application(internal.Get()); } diff --git a/dali/devel-api/adaptor-framework/native-image-source-queue.h b/dali/devel-api/adaptor-framework/native-image-source-queue.h index 01ca473..cba01ca 100644 --- a/dali/devel-api/adaptor-framework/native-image-source-queue.h +++ b/dali/devel-api/adaptor-framework/native-image-source-queue.h @@ -65,12 +65,12 @@ public: */ enum class ColorFormat { - RGB888, /// 8 red bits, 8 green bits, 8 blue bits - RGBA8888, /// 8 red bits, 8 green bits, 8 blue bits, alpha 8 bits - RGBX8888, /// 8 red bits, 8 green bits, 8 blue bits, and 8 ignored bits - BGR888, /// 8 blue bits, 8 green bits, 8 red bits - BGRA8888, /// 8 blue bits, 8 green bits, 8 red bits, alpha 8 bits - BGRX8888, /// 8 blue bits, 8 green bits, 8 red bits, and 8 ignored bits + BGR888 = 0, /// 8 blue bits, 8 green bits, 8 red bits + BGRA8888 = 1, /// 8 blue bits, 8 green bits, 8 red bits, alpha 8 bits + BGRX8888 = 2, /// 8 blue bits, 8 green bits, 8 red bits, and 8 ignored bits + RGB888 = 3, /// 8 red bits, 8 green bits, 8 blue bits + RGBA8888 = 4, /// 8 red bits, 8 green bits, 8 blue bits, alpha 8 bits + RGBX8888 = 5, /// 8 red bits, 8 green bits, 8 blue bits, and 8 ignored bits }; /** diff --git a/dali/internal/adaptor/android/framework-android.cpp b/dali/internal/adaptor/android/framework-android.cpp index e01ff71..8151ba8 100644 --- a/dali/internal/adaptor/android/framework-android.cpp +++ b/dali/internal/adaptor/android/framework-android.cpp @@ -488,8 +488,9 @@ struct Framework::Impl } }; -Framework::Framework(Framework::Observer& observer, int* argc, char*** argv, Type type) +Framework::Framework(Framework::Observer& observer, Framework::TaskObserver& taskObserver, int* argc, char*** argv, Type type, bool useUiThread) : mObserver(observer), + mTaskObserver(taskObserver), mInitialised(false), mPaused(false), mRunning(false), diff --git a/dali/internal/adaptor/androidjni/framework-androidjni.cpp b/dali/internal/adaptor/androidjni/framework-androidjni.cpp index caa35be..649d281 100644 --- a/dali/internal/adaptor/androidjni/framework-androidjni.cpp +++ b/dali/internal/adaptor/androidjni/framework-androidjni.cpp @@ -84,8 +84,9 @@ struct Framework::Impl std::string mRegion; }; -Framework::Framework(Framework::Observer& observer, int* argc, char*** argv, Type type) +Framework::Framework(Framework::Observer& observer, Framework::TaskObserver& taskObserver, int* argc, char*** argv, Type type, bool useUiThread) : mObserver(observer), + mTaskObserver(taskObserver), mInitialised(false), mPaused(false), mRunning(false), diff --git a/dali/internal/adaptor/common/application-impl.cpp b/dali/internal/adaptor/common/application-impl.cpp index 97a23e0..13a3fbe 100644 --- a/dali/internal/adaptor/common/application-impl.cpp +++ b/dali/internal/adaptor/common/application-impl.cpp @@ -26,6 +26,7 @@ // INTERNAL INCLUDES #include +#include #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -68,9 +70,10 @@ ApplicationPtr Application::New( Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType, - WindowType type) + WindowType type, + bool useUiThread) { - ApplicationPtr application(new Application(argc, argv, stylesheet, windowMode, positionSize, applicationType, type)); + ApplicationPtr application(new Application(argc, argv, stylesheet, windowMode, positionSize, applicationType, type, useUiThread)); return application; } @@ -80,13 +83,13 @@ void Application::PreInitialize(int* argc, char** argv[]) { Dali::TextAbstraction::FontClientPreInitialize(); - gPreInitializedApplication = new Application(argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL, WindowType::NORMAL); + gPreInitializedApplication = new Application(argc, argv, "", Dali::Application::OPAQUE, PositionSize(), Framework::NORMAL, WindowType::NORMAL, false); gPreInitializedApplication->CreateWindow(); // Only create window gPreInitializedApplication->mLaunchpadState = Launchpad::PRE_INITIALIZED; } } -Application::Application(int* argc, char** argv[], const std::string& stylesheet, Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType, WindowType type) +Application::Application(int* argc, char** argv[], const std::string& stylesheet, Dali::Application::WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType, WindowType type, bool useUiThread) : mInitSignal(), mTerminateSignal(), mPauseSignal(), @@ -108,6 +111,7 @@ Application::Application(int* argc, char** argv[], const std::string& stylesheet mWindowPositionSize(positionSize), mLaunchpadState(Launchpad::NONE), mDefaultWindowType(type), + mUseUiThread(useUiThread), mSlotDelegate(this) { // Get mName from environment options @@ -118,8 +122,14 @@ Application::Application(int* argc, char** argv[], const std::string& stylesheet mMainWindowName = (*argv)[0]; } + const char* uiThreadEnabled = Dali::EnvironmentVariable::GetEnvironmentVariable(DALI_ENV_ENABLE_UI_THREAD); + if(uiThreadEnabled && std::atoi(uiThreadEnabled) != 0) + { + mUseUiThread = true; + } + mCommandLineOptions = new CommandLineOptions(argc, argv); - mFramework = new Framework(*this, argc, argv, applicationType); + mFramework = new Framework(*this, *this, argc, argv, applicationType, mUseUiThread); mUseRemoteSurface = (applicationType == Framework::WATCH); } @@ -169,7 +179,7 @@ void Application::ChangePreInitializedWindowSize() } else if(screenWidth != mWindowPositionSize.width || screenHeight != mWindowPositionSize.height) { - //Some apps can receive screen size differently after launching by specifying size in manifest. + // Some apps can receive screen size differently after launching by specifying size in manifest. mWindowPositionSize.width = screenWidth; mWindowPositionSize.height = screenHeight; mMainWindow.SetSize(Dali::Window::WindowSize(mWindowPositionSize.width, mWindowPositionSize.height)); @@ -397,6 +407,48 @@ void Application::OnSurfaceDestroyed(Any surface) { } +void Application::OnTaskInit() +{ + Dali::Application application(this); + mTaskInitSignal.Emit(application); +} + +void Application::OnTaskTerminate() +{ + Dali::Application application(this); + mTaskTerminateSignal.Emit(application); +} + +void Application::OnTaskAppControl(void* data) +{ + Dali::Application application(this); + mTaskAppControlSignal.Emit(application, data); +} + +void Application::OnTaskLanguageChanged() +{ + Dali::Application application(this); + mTaskLanguageChangedSignal.Emit(application); +} + +void Application::OnTaskRegionChanged() +{ + Dali::Application application(this); + mTaskRegionChangedSignal.Emit(application); +} + +void Application::OnTaskBatteryLow(Dali::DeviceStatus::Battery::Status status) +{ + Dali::Application application(this); + mTaskLowBatterySignal.Emit(status); +} + +void Application::OnTaskMemoryLow(Dali::DeviceStatus::Memory::Status status) +{ + Dali::Application application(this); + mTaskLowMemorySignal.Emit(status); +} + bool Application::AddIdle(CallbackBase* callback, bool hasReturnValue) { return mAdaptor->AddIdle(callback, hasReturnValue); diff --git a/dali/internal/adaptor/common/application-impl.h b/dali/internal/adaptor/common/application-impl.h index ed03bfa..7a1f603 100644 --- a/dali/internal/adaptor/common/application-impl.h +++ b/dali/internal/adaptor/common/application-impl.h @@ -64,7 +64,7 @@ typedef IntrusivePtr ApplicationPtr; /** * Implementation of the Application class. */ -class Application : public BaseObject, public Framework::Observer +class Application : public BaseObject, public Framework::Observer, public Framework::TaskObserver { public: typedef Dali::Application::LowBatterySignalType LowBatterySignalType; @@ -82,8 +82,9 @@ public: * @param[in] positionSize A position and a size of the window * @param[in] applicationType A member of Dali::Framework::Type * @param[in] type It is window type for default window. + * @param[in] useUiThread True if the application would create a UI thread */ - static ApplicationPtr New(int* argc, char** argv[], const std::string& stylesheet, WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType, WindowType type); + static ApplicationPtr New(int* argc, char** argv[], const std::string& stylesheet, WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType, WindowType type, bool useUiThread); /** * @copydoc Dali::DevelApplication::PreInitialize() @@ -180,9 +181,9 @@ public: // From Framework::Observer void OnResume() override; /** - * Called when the framework received AppControlSignal. - * @param[in] The bundle data of AppControl event. - */ + * Called when the framework received AppControlSignal. + * @param[in] The bundle data of AppControl event. + */ void OnAppControl(void* data) override; /** @@ -196,18 +197,18 @@ public: // From Framework::Observer void OnLanguageChanged() override; /** - * Called when the framework informs the application that the region of the device has changed. - */ + * Called when the framework informs the application that the region of the device has changed. + */ void OnRegionChanged() override; /** - * Called when the framework informs the application that the battery level of the device is low. - */ + * Called when the framework informs the application that the battery level of the device is low. + */ void OnBatteryLow(Dali::DeviceStatus::Battery::Status status) override; /** - * Called when the framework informs the application that the memory level of the device is low. - */ + * Called when the framework informs the application that the memory level of the device is low. + */ void OnMemoryLow(Dali::DeviceStatus::Memory::Status status) override; /** @@ -220,6 +221,43 @@ public: // From Framework::Observer */ void OnSurfaceDestroyed(Any newSurface) override; +public: // From Framework::TaskObserver + /** + * Called when the framework is initialised. + */ + void OnTaskInit() override; + + /** + * Called when the framework is terminated. + */ + void OnTaskTerminate() override; + + /** + * Called when the framework received AppControlSignal. + * @param[in] The bundle data of AppControl event. + */ + void OnTaskAppControl(void* data) override; + + /** + * Called when the framework informs the application that the language of the device has changed. + */ + void OnTaskLanguageChanged() override; + + /** + * Called when the framework informs the application that the region of the device has changed. + */ + void OnTaskRegionChanged() override; + + /** + * Called when the framework informs the application that the battery level of the device is low. + */ + void OnTaskBatteryLow(Dali::DeviceStatus::Battery::Status status) override; + + /** + * Called when the framework informs the application that the memory level of the device is low. + */ + void OnTaskMemoryLow(Dali::DeviceStatus::Memory::Status status) override; + public: /** * Sets a user defined theme file. @@ -285,8 +323,8 @@ public: // Signals } /** - * @copydoc Dali::Application::AppControlSignal() - */ + * @copydoc Dali::Application::AppControlSignal() + */ Dali::Application::AppControlSignalType& AppControlSignal() { return mAppControlSignal; @@ -301,29 +339,85 @@ public: // Signals } /** - * @copydoc Dali::Application::RegionChangedSignal() - */ + * @copydoc Dali::Application::RegionChangedSignal() + */ Dali::Application::AppSignalType& RegionChangedSignal() { return mRegionChangedSignal; } /** - * @copydoc Dali::Application::LowBatterySignal() - */ + * @copydoc Dali::Application::LowBatterySignal() + */ Dali::Application::LowBatterySignalType& LowBatterySignal() { return mLowBatterySignal; } /** - * @copydoc Dali::Application:::LowMemorySignal() - */ + * @copydoc Dali::Application:::LowMemorySignal() + */ Dali::Application::LowMemorySignalType& LowMemorySignal() { return mLowMemorySignal; } + /** + * @copydoc Dali::Application::TaskInitSignal() + */ + Dali::Application::AppSignalType& TaskInitSignal() + { + return mTaskInitSignal; + } + + /** + * @copydoc Dali::Application::TaskTerminateSignal() + */ + Dali::Application::AppSignalType& TaskTerminateSignal() + { + return mTaskTerminateSignal; + } + + /** + * @copydoc Dali::Application::TaskAppControlSignal() + */ + Dali::Application::AppControlSignalType& TaskAppControlSignal() + { + return mTaskAppControlSignal; + } + + /** + * @copydoc Dali::Application::TaskLanguageChangedSignal() + */ + Dali::Application::AppSignalType& TaskLanguageChangedSignal() + { + return mTaskLanguageChangedSignal; + } + + /** + * @copydoc Dali::Application::TaskRegionChangedSignal() + */ + Dali::Application::AppSignalType& TaskRegionChangedSignal() + { + return mTaskRegionChangedSignal; + } + + /** + * @copydoc Dali::Application::TaskLowBatterySignal() + */ + Dali::Application::LowBatterySignalType& TaskLowBatterySignal() + { + return mTaskLowBatterySignal; + } + + /** + * @copydoc Dali::Application::TaskLowMemorySignal() + */ + Dali::Application::LowMemorySignalType& TaskLowMemorySignal() + { + return mTaskLowMemorySignal; + } + protected: /** * Private Constructor @@ -334,8 +428,9 @@ protected: * @param[in] positionSize A position and a size of the window * @param[in] applicationType A member of Dali::Framework::Type * @param[in] type The default window's type. + * @param[in] useUiThread True if the application would create UI thread */ - Application(int* argc, char** argv[], const std::string& stylesheet, WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType, WindowType type); + Application(int* argc, char** argv[], const std::string& stylesheet, WINDOW_MODE windowMode, const PositionSize& positionSize, Framework::Type applicationType, WindowType type, bool useUiThread); /** * Destructor @@ -383,6 +478,14 @@ private: LowBatterySignalType mLowBatterySignal; LowMemorySignalType mLowMemorySignal; + AppSignalType mTaskInitSignal; + AppSignalType mTaskTerminateSignal; + AppControlSignalType mTaskAppControlSignal; + AppSignalType mTaskLanguageChangedSignal; + AppSignalType mTaskRegionChangedSignal; + LowBatterySignalType mTaskLowBatterySignal; + LowMemorySignalType mTaskLowMemorySignal; + EventLoop* mEventLoop; Framework* mFramework; @@ -403,6 +506,7 @@ private: Launchpad::State mLaunchpadState; bool mUseRemoteSurface; WindowType mDefaultWindowType; ///< Default window's type. It is used when Application is created. + bool mUseUiThread; SlotDelegate mSlotDelegate; diff --git a/dali/internal/adaptor/common/framework.h b/dali/internal/adaptor/common/framework.h index 5ab74ac..bef6b77 100644 --- a/dali/internal/adaptor/common/framework.h +++ b/dali/internal/adaptor/common/framework.h @@ -59,6 +59,8 @@ public: /** * Observer class for the framework. + * @brief When the UI thread is enabled, the events are emitted on the UI thread. + * When it is disabled, the events are emitted on the main thread. */ class Observer { @@ -99,9 +101,9 @@ public: } /** - * Invoked when the AppControl message is received. - * @param[in] The bundle data of AppControl message. - */ + * Invoked when the AppControl message is received. + * @param[in] The bundle data of AppControl message. + */ virtual void OnAppControl(void*) { } @@ -182,15 +184,75 @@ public: #endif }; + /** + * TaskObserver class for the framework. + * @brief This is used only when UiThread is enabled. the events are emitted on the main thread. + */ + class TaskObserver + { + public: + /** + * Invoked when the application is to be initialised. + */ + virtual void OnTaskInit() + { + } + + /** + * Invoked when the application is to be terminated. + */ + virtual void OnTaskTerminate() + { + } + + /** + * Invoked when the AppControl message is received. + * @param[in] The bundle data of AppControl message. + */ + virtual void OnTaskAppControl(void*) + { + } + + /** + * Invoked when the language of the device is changed. + */ + virtual void OnTaskLanguageChanged() + { + } + + /** + * Invoked when the region is changed. + */ + virtual void OnTaskRegionChanged() + { + } + + /** + * Invoked when the battery level of the device is low. + */ + virtual void OnTaskBatteryLow(Dali::DeviceStatus::Battery::Status status) + { + } + + /** + * Invoked when the memory level of the device is low. + */ + virtual void OnTaskMemoryLow(Dali::DeviceStatus::Memory::Status status) + { + } + }; + public: /** * Constructor - * @param[in] observer The observer of the Framework. - * @param[in] argc A pointer to the number of arguments. - * @param[in] argv A pointer the the argument list. - * @param[in] type The type of application + * @param[in] observer The observer of the Framework. + * @param[in] taskObserver The task observer of the Framework. + * @param[in] argc A pointer to the number of arguments. + * @param[in] argv A pointer the the argument list. + * @param[in] type The type of application + * @param[in] useUiThread True if the application would create a UI thread */ - Framework(Observer& observer, int* argc, char*** argv, Type type = NORMAL); + Framework(Observer& observer, TaskObserver& taskObserver, int* argc, char*** argv, Type type, bool useUiThread); /** * Destructor @@ -328,15 +390,16 @@ private: void InitThreads(); private: - Observer& mObserver; - bool mInitialised; - bool mPaused; - bool mRunning; - int* mArgc; - char*** mArgv; - std::string mBundleName; - std::string mBundleId; - AbortHandler mAbortHandler; + Observer& mObserver; + TaskObserver& mTaskObserver; + bool mInitialised; + bool mPaused; + bool mRunning; + int* mArgc; + char*** mArgv; + std::string mBundleName; + std::string mBundleId; + AbortHandler mAbortHandler; private: // impl members struct Impl; diff --git a/dali/internal/adaptor/macos/framework-mac.mm b/dali/internal/adaptor/macos/framework-mac.mm index 4bd637c..b9c1439 100644 --- a/dali/internal/adaptor/macos/framework-mac.mm +++ b/dali/internal/adaptor/macos/framework-mac.mm @@ -112,8 +112,9 @@ private: std::string mRegion; }; -Framework::Framework( Framework::Observer& observer, int *argc, char ***argv, Type type ) +Framework::Framework(Framework::Observer& observer, Framework::TaskObserver& taskObserver, int* argc, char*** argv, Type type, bool useUiThread) : mObserver(observer), + mTaskObserver(taskObserver), mInitialised(false), mPaused(false), mRunning(false), diff --git a/dali/internal/adaptor/tizen-wayland/component-application-impl.cpp b/dali/internal/adaptor/tizen-wayland/component-application-impl.cpp index ceec60a..09f3aa4 100644 --- a/dali/internal/adaptor/tizen-wayland/component-application-impl.cpp +++ b/dali/internal/adaptor/tizen-wayland/component-application-impl.cpp @@ -35,7 +35,7 @@ ComponentApplicationPtr ComponentApplication::New( } ComponentApplication::ComponentApplication(int* argc, char** argv[], const std::string& stylesheet, Dali::Application::WINDOW_MODE windowMode) -: Application(argc, argv, stylesheet, windowMode, PositionSize(), Framework::COMPONENT, WindowType::NORMAL) +: Application(argc, argv, stylesheet, windowMode, PositionSize(), Framework::COMPONENT, WindowType::NORMAL, false) { } diff --git a/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp b/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp index 7db93c7..3f638d8 100644 --- a/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp +++ b/dali/internal/adaptor/tizen-wayland/framework-tizen.cpp @@ -23,11 +23,14 @@ #include #include #include +#include +#include #include #include #include #include #include + // CONDITIONAL INCLUDES #ifdef APPCORE_WATCH_AVAILABLE #include @@ -219,33 +222,230 @@ struct Framework::Impl class UiAppContext : public AppCoreUiBase { public: + class Task : public AppCoreTaskBase + { + public: + explicit Task(Framework* framework) + : mFramework(framework), + mNewBatteryStatus(Dali::DeviceStatus::Battery::Status::NORMAL), + mNewMemoryStatus(Dali::DeviceStatus::Memory::NORMAL) + { + } + + 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 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); + } + + void OnDeviceOrientationChanged(AppCoreTaskBase::DeviceOrientationState state) override + { + print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnDeviceOrientationChanged() emitted", __MODULE__, __func__, __LINE__); + // Note: This isn't emitted to the App. + AppCoreTaskBase::OnDeviceOrientationChanged(state); + } + + 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: + Framework* mFramework; + std::string mNewLanguage; + std::string mNewRegion; + Dali::DeviceStatus::Battery::Status mNewBatteryStatus; + Dali::DeviceStatus::Memory::Status mNewMemoryStatus; + }; + explicit UiAppContext(unsigned int hint, Framework* framework) : AppCoreUiBase(hint), - mFramework(framework) + mFramework(framework), + mUseUiThread(false) { - mLanguageChanged = std::make_shared(IAppCore::IEvent::Type::LANG_CHANGE, OnLanguageChanged, this); - AddEvent(mLanguageChanged); + 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); + 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); + 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); + 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); + mLowBattery = std::make_shared(IAppCore::IEvent::Type::LOW_BATTERY, OnLowBattery, this); + AddEvent(mLowBattery); + } } virtual ~UiAppContext() { - RemoveEvent(mLowBattery); - RemoveEvent(mLowMemory); - RemoveEvent(mRegionFormatChanged); - RemoveEvent(mDeviceOrientationChanged); - RemoveEvent(mLanguageChanged); + 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 @@ -451,12 +651,14 @@ struct Framework::Impl std::shared_ptr mRegionFormatChanged; std::shared_ptr mLowBattery; std::shared_ptr mLowMemory; + bool mUseUiThread; }; // Constructor - Impl(void* data, Type type) + Impl(void* data, Type type, bool useUiThread) : mAbortCallBack(NULL), - mCallbackManager(NULL) + mCallbackManager(NULL), + mUseUiThread(useUiThread) #ifdef APPCORE_WATCH_AVAILABLE , mWatchCallback() @@ -597,6 +799,7 @@ struct Framework::Impl Framework* mFramework; AppCore::AppEventHandlerPtr handlers[5]; std::unique_ptr mUiAppContext; + bool mUseUiThread; #ifdef APPCORE_WATCH_AVAILABLE watch_app_lifecycle_callback_s mWatchCallback; app_event_handler_h watchHandlers[5]; @@ -767,6 +970,26 @@ struct Framework::Impl AppCoreUiBase::HINT_HW_ACC_CONTROL | AppCoreUiBase::HINT_WINDOW_AUTO_CONTROL; + // 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; + } + mUiAppContext = std::make_unique(hint, mFramework); } @@ -988,8 +1211,9 @@ private: Impl& operator=(const Impl& impl); }; -Framework::Framework(Framework::Observer& observer, int* argc, char*** argv, Type type) +Framework::Framework(Framework::Observer& observer, Framework::TaskObserver& taskObserver, int* argc, char*** argv, Type type, bool useUiThread) : mObserver(observer), + mTaskObserver(taskObserver), mInitialised(false), mPaused(false), mRunning(false), @@ -1010,7 +1234,7 @@ Framework::Framework(Framework::Observer& observer, int* argc, char*** argv, Typ InitThreads(); - mImpl = new Impl(this, type); + mImpl = new Impl(this, type, useUiThread); } Framework::~Framework() diff --git a/dali/internal/adaptor/tizen-wayland/tizen-wearable/watch-application-impl.cpp b/dali/internal/adaptor/tizen-wayland/tizen-wearable/watch-application-impl.cpp index 72cf282..7f7a7f1 100644 --- a/dali/internal/adaptor/tizen-wayland/tizen-wearable/watch-application-impl.cpp +++ b/dali/internal/adaptor/tizen-wayland/tizen-wearable/watch-application-impl.cpp @@ -50,7 +50,7 @@ WatchApplicationPtr WatchApplication::New( } WatchApplication::WatchApplication(int* argc, char** argv[], const std::string& stylesheet, Dali::Application::WINDOW_MODE windowMode) -: Application(argc, argv, stylesheet, windowMode, PositionSize(), Framework::WATCH, WindowType::NORMAL), +: Application(argc, argv, stylesheet, windowMode, PositionSize(), Framework::WATCH, WindowType::NORMAL, false), mState(UNINITIALIZED) { } diff --git a/dali/internal/adaptor/ubuntu/framework-ubuntu.cpp b/dali/internal/adaptor/ubuntu/framework-ubuntu.cpp index 38e3d76..60529c5 100644 --- a/dali/internal/adaptor/ubuntu/framework-ubuntu.cpp +++ b/dali/internal/adaptor/ubuntu/framework-ubuntu.cpp @@ -134,8 +134,9 @@ struct Framework::Impl } }; -Framework::Framework(Framework::Observer& observer, int* argc, char*** argv, Type type) +Framework::Framework(Framework::Observer& observer, Framework::TaskObserver& taskObserver, int* argc, char*** argv, Type type, bool useUiThread) : mObserver(observer), + mTaskObserver(taskObserver), mInitialised(false), mPaused(false), mRunning(false), diff --git a/dali/internal/adaptor/windows/framework-win.cpp b/dali/internal/adaptor/windows/framework-win.cpp index 2a5ab92..0623baf 100644 --- a/dali/internal/adaptor/windows/framework-win.cpp +++ b/dali/internal/adaptor/windows/framework-win.cpp @@ -184,8 +184,9 @@ private: std::string mRegion; }; -Framework::Framework(Framework::Observer& observer, int* argc, char*** argv, Type type) +Framework::Framework(Framework::Observer& observer, Framework::TaskObserver& taskObserver, int* argc, char*** argv, Type type, bool useUiThread) : mObserver(observer), + mTaskObserver(taskObserver), mInitialised(false), mPaused(false), mRunning(false), diff --git a/dali/internal/system/common/environment-variables.h b/dali/internal/system/common/environment-variables.h index f4b661a..c262bd7 100644 --- a/dali/internal/system/common/environment-variables.h +++ b/dali/internal/system/common/environment-variables.h @@ -144,6 +144,8 @@ namespace Adaptor #define DALI_ENV_SUPPRESS_SCREEN_READER "DALI_SUPPRESS_SCREEN_READER" +#define DALI_ENV_ENABLE_UI_THREAD "DALI_ENABLE_UI_THREAD" + } // namespace Adaptor } // namespace Internal diff --git a/dali/internal/system/common/widget-application-impl.cpp b/dali/internal/system/common/widget-application-impl.cpp index 2b07db9..5c7aef6 100644 --- a/dali/internal/system/common/widget-application-impl.cpp +++ b/dali/internal/system/common/widget-application-impl.cpp @@ -48,7 +48,7 @@ WidgetApplicationPtr WidgetApplication::New( } WidgetApplication::WidgetApplication(int* argc, char** argv[], const std::string& stylesheet) -: Application(argc, argv, stylesheet, Dali::WidgetApplication::OPAQUE, PositionSize(), Framework::WIDGET, WindowType::NORMAL) +: Application(argc, argv, stylesheet, Dali::WidgetApplication::OPAQUE, PositionSize(), Framework::WIDGET, WindowType::NORMAL, false) { DALI_LOG_ERROR("WidgetApplication is not implemented in UBUNTU profile.\n"); } diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl/window-base-ecore-wl.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl/window-base-ecore-wl.cpp index ccef811..f123f25 100644 --- a/dali/internal/window-system/tizen-wayland/ecore-wl/window-base-ecore-wl.cpp +++ b/dali/internal/window-system/tizen-wayland/ecore-wl/window-base-ecore-wl.cpp @@ -655,8 +655,8 @@ void WindowBaseEcoreWl::Initialize(PositionSize positionSize, Any surface, bool mEcoreEventHandler.PushBack(ecore_event_handler_add(ECORE_WL_EVENT_SELECTION_DATA_READY, EcoreEventDataReceive, this)); // Register Vconf notify - font name and size - vconf_notify_key_changed(DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged, this); - vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, this); + vconf_notify_key_changed_for_ui_thread(DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged, this); + vconf_notify_key_changed_for_ui_thread(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, this); mDisplay = ecore_wl_display_get(); diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp index 6c15aad..a77a163 100644 --- a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp @@ -824,8 +824,8 @@ void WindowBaseEcoreWl2::Initialize(PositionSize positionSize, Any surface, bool mEcoreEventHandler.PushBack(ecore_event_handler_add(ECORE_WL2_EVENT_AUX_MESSAGE, EcoreEventWindowAuxiliaryMessage, this)); // Register Vconf notify - font name and size - vconf_notify_key_changed(DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged, this); - vconf_notify_key_changed(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, this); + vconf_notify_key_changed_for_ui_thread(DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged, this); + vconf_notify_key_changed_for_ui_thread(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_SIZE, VconfNotifyFontSizeChanged, this); Ecore_Wl2_Display* display = ecore_wl2_connected_display_get(NULL); mDisplay = ecore_wl2_display_get(display); diff --git a/dali/public-api/adaptor-framework/application.cpp b/dali/public-api/adaptor-framework/application.cpp index 17403d2..20099eb 100644 --- a/dali/public-api/adaptor-framework/application.cpp +++ b/dali/public-api/adaptor-framework/application.cpp @@ -46,7 +46,7 @@ Application Application::New(int* argc, char** argv[]) } else { - internal = Internal::Adaptor::Application::New(argc, argv, "", OPAQUE, PositionSize(), Internal::Adaptor::Framework::NORMAL, WindowType::NORMAL); + internal = Internal::Adaptor::Application::New(argc, argv, "", OPAQUE, PositionSize(), Internal::Adaptor::Framework::NORMAL, WindowType::NORMAL, false); } return Application(internal.Get()); } @@ -66,7 +66,7 @@ Application Application::New(int* argc, char** argv[], const std::string& styles } else { - internal = Internal::Adaptor::Application::New(argc, argv, stylesheet, OPAQUE, PositionSize(), Internal::Adaptor::Framework::NORMAL, WindowType::NORMAL); + internal = Internal::Adaptor::Application::New(argc, argv, stylesheet, OPAQUE, PositionSize(), Internal::Adaptor::Framework::NORMAL, WindowType::NORMAL, false); } return Application(internal.Get()); } @@ -88,7 +88,7 @@ Application Application::New(int* argc, char** argv[], const std::string& styles } else { - internal = Internal::Adaptor::Application::New(argc, argv, stylesheet, windowMode, PositionSize(), Internal::Adaptor::Framework::NORMAL, WindowType::NORMAL); + internal = Internal::Adaptor::Application::New(argc, argv, stylesheet, windowMode, PositionSize(), Internal::Adaptor::Framework::NORMAL, WindowType::NORMAL, false); } return Application(internal.Get()); } @@ -113,7 +113,32 @@ Application Application::New(int* argc, char** argv[], const std::string& styles } else { - internal = Internal::Adaptor::Application::New(argc, argv, stylesheet, windowMode, positionSize, Internal::Adaptor::Framework::NORMAL, WindowType::NORMAL); + internal = Internal::Adaptor::Application::New(argc, argv, stylesheet, windowMode, positionSize, Internal::Adaptor::Framework::NORMAL, WindowType::NORMAL, false); + } + return Application(internal.Get()); +} + +Application Application::New(int* argc, char** argv[], const std::string& stylesheet, Application::WINDOW_MODE windowMode, PositionSize positionSize, bool useUiThread) +{ + Internal::Adaptor::ApplicationPtr internal = Internal::Adaptor::Application::GetPreInitializedApplication(); + if(internal) + { + // pre-initialized application + internal->SetCommandLineOptions(argc, argv); + if(argc && (*argc > 0)) + { + internal->GetWindow().SetClass((*argv)[0], ""); + } + internal->SetStyleSheet(stylesheet); + + internal->GetWindow().SetTransparency((windowMode == Application::OPAQUE ? false : true)); + + //Store only the value before adaptor is created + internal->StoreWindowPositionSize(positionSize); + } + else + { + internal = Internal::Adaptor::Application::New(argc, argv, stylesheet, windowMode, positionSize, Internal::Adaptor::Framework::NORMAL, WindowType::NORMAL, useUiThread); } return Application(internal.Get()); } @@ -229,6 +254,41 @@ Application::LowMemorySignalType& Application::LowMemorySignal() return Internal::Adaptor::GetImplementation(*this).LowMemorySignal(); } +Application::AppSignalType& Application::TaskInitSignal() +{ + return Internal::Adaptor::GetImplementation(*this).TaskInitSignal(); +} + +Application::AppSignalType& Application::TaskTerminateSignal() +{ + return Internal::Adaptor::GetImplementation(*this).TaskTerminateSignal(); +} + +Application::AppControlSignalType& Application::TaskAppControlSignal() +{ + return Internal::Adaptor::GetImplementation(*this).TaskAppControlSignal(); +} + +Application::AppSignalType& Application::TaskLanguageChangedSignal() +{ + return Internal::Adaptor::GetImplementation(*this).TaskLanguageChangedSignal(); +} + +Application::AppSignalType& Application::TaskRegionChangedSignal() +{ + return Internal::Adaptor::GetImplementation(*this).TaskRegionChangedSignal(); +} + +Application::LowBatterySignalType& Application::TaskLowBatterySignal() +{ + return Internal::Adaptor::GetImplementation(*this).TaskLowBatterySignal(); +} + +Application::LowMemorySignalType& Application::TaskLowMemorySignal() +{ + return Internal::Adaptor::GetImplementation(*this).TaskLowMemorySignal(); +} + Application::Application(Internal::Adaptor::Application* application) : BaseHandle(application) { diff --git a/dali/public-api/adaptor-framework/application.h b/dali/public-api/adaptor-framework/application.h index 90ed7b5..4861e71 100644 --- a/dali/public-api/adaptor-framework/application.h +++ b/dali/public-api/adaptor-framework/application.h @@ -90,6 +90,22 @@ class Application; * app.ResumeSignal().Connect(&app, &MyApplication::Resume); * @endcode * + * + * #### UI thread + * There is the UI thread feature. + * UI thread is an additional thread that an Application object creates. The thread is for UI events. + * + * When the UI thread feature is enabled, you can use the task signals(TaskInit, TaskTerminate, TaskAppControl, TaskLanguageChanged, TaskLowBattery, and TaskLowMemory). + * The task signals are emitted on the main thread, + * and the normal signals(Init, Terminate, Pause, Resume, Reset, AppControl, LanguageChanged, Region, LowBattery, and LowMemory) are emitted on the UI thread. + * + * If you want to handle windows or actors in cases like when the memory level of the device is low, you have to use the normal signals, not the task signals. + * Callbacks of all signals in DALi except the task signals are emitted on the UI thread. (e.g., Timer callbacks are emitted on the UI thread.) + * + * To enable the UI Thread, you can use this method. you have to set True to the useUiThread. + * Dali::Application::New(int *argc, char **argv[], const std::string &stylesheet, Application::WINDOW_MODE windowMode, PositionSize positionSize, bool useUiThread) + * + * * This class accepts command line arguments as well. The following options are supported: * * @code @@ -188,6 +204,25 @@ public: static Application New(int* argc, char** argv[], const std::string& stylesheet, Application::WINDOW_MODE windowMode, PositionSize positionSize); /** + * @brief This is the constructor for applications. + * + * @SINCE_2_1.20 + * @PRIVLEVEL_PUBLIC + * @PRIVILEGE_DISPLAY + * @param[in,out] argc A pointer to the number of arguments + * @param[in,out] argv A pointer to the argument list + * @param[in] stylesheet The path to user defined theme file + * @param[in] windowMode A member of WINDOW_MODE + * @param[in] positionSize A position and a size of the window + * @param[in] useUiThread True if the application would create a UI thread + * @return A handle to the Application + * @note If the stylesheet is not specified, then the library's default stylesheet will not be overridden.
+ * UI thread is an additional thread that DALi creates for UI events. + * The UI thread isn't blocked from the system events(AppControl, LanguageChanged, RegionChanged, LowMemory, LowBattery task signals). + */ + static Application New(int* argc, char** argv[], const std::string& stylesheet, Application::WINDOW_MODE windowMode, PositionSize positionSize, bool useUiThread); + + /** * @brief Constructs an empty handle. * @SINCE_1_0.0 */ @@ -322,6 +357,8 @@ public: // Signals /** * @brief The user should connect to this signal to determine when they should initialize * their application. + * Only when the user uses the UiThread, this signal is emitted on the UI thread. + * Otherwise, it is emitted on the main thread. * @SINCE_1_0.0 * @return The signal to connect to */ @@ -330,6 +367,8 @@ public: // Signals /** * @brief The user should connect to this signal to determine when they should terminate * their application. + * Only when the user uses the UiThread, this signal is emitted on the UI thread. + * Otherwise, it is emitted on the main thread. * @SINCE_1_0.0 * @return The signal to connect to */ @@ -338,6 +377,8 @@ public: // Signals /** * @brief The user should connect to this signal if they need to perform any special * activities when the application is about to be paused. + * Only when the user uses the UiThread, this signal is emitted on the UI thread. + * Otherwise, it is emitted on the main thread. * @SINCE_1_0.0 * @return The signal to connect to */ @@ -346,6 +387,8 @@ public: // Signals /** * @brief The user should connect to this signal if they need to perform any special * activities when the application has resumed. + * Only when the user uses the UiThread, this signal is emitted on the UI thread. + * Otherwise, it is emitted on the main thread. * @SINCE_1_0.0 * @return The signal to connect to */ @@ -353,37 +396,47 @@ public: // Signals /** * @brief This signal is sent when the system requires the user to reinitialize itself. + * Only when the user uses the UiThread, this signal is emitted on the UI thread. + * Otherwise, it is emitted on the main thread. * @SINCE_1_0.0 * @return The signal to connect to */ AppSignalType& ResetSignal(); /** - * @brief This signal is emitted when another application sends a launch request to the application. - * - * When the application is launched, this signal is emitted after the main loop of the application starts up. - * The passed parameter describes the launch request and contains the information about why the application is launched. - * @SINCE_1_0.0 - * @return The signal to connect to - */ + * @brief This signal is emitted when another application sends a launch request to the application. + * + * When the application is launched, this signal is emitted after the main loop of the application starts up. + * The passed parameter describes the launch request and contains the information about why the application is launched. + * Only when the user uses the UiThread, this signal is emitted on the UI thread. + * Otherwise, it is emitted on the main thread. + * @SINCE_1_0.0 + * @return The signal to connect to + */ AppControlSignalType& AppControlSignal(); /** * @brief This signal is emitted when the language is changed on the device. + * Only when the user uses the UiThread, this signal is emitted on the UI thread. + * Otherwise, it is emitted on the main thread. * @SINCE_1_0.0 * @return The signal to connect to */ AppSignalType& LanguageChangedSignal(); /** - * @brief This signal is emitted when the region of the device is changed. - * @SINCE_1_0.0 - * @return The signal to connect to - */ + * @brief This signal is emitted when the region of the device is changed. + * Only when the user uses the UiThread, this signal is emitted on the UI thread. + * Otherwise, it is emitted on the main thread. + * @SINCE_1_0.0 + * @return The signal to connect to + */ AppSignalType& RegionChangedSignal(); /** * @brief This signal is emitted when the battery level of the device is low. + * Only when the user uses the UiThread, this signal is emitted on the UI thread. + * Otherwise, it is emitted on the main thread. * @SINCE_1_2.62 * @return The signal to connect to */ @@ -391,11 +444,75 @@ public: // Signals /** * @brief This signal is emitted when the memory level of the device is low. + * Only when the user uses the UiThread, this signal is emitted on the UI thread. + * Otherwise, it is emitted on the main thread. * @SINCE_1_2.62 * @return The signal to connect to */ LowMemorySignalType& LowMemorySignal(); + // TaskSignal + /** + * @brief The user should connect to this signal to determine when they should initialize + * their application. + * Only when the user uses the UiThread, this signal is emitted on the main thread. + * Otherwise, it is not emitted at all. + * @return The signal to connect to + */ + AppSignalType& TaskInitSignal(); + + /** + * @brief The user should connect to this signal to determine when they should terminate + * their application. + * Only when the user uses the UiThread, this signal is emitted on the main thread. + * Otherwise, it is not emitted at all. + * @return The signal to connect to + */ + AppSignalType& TaskTerminateSignal(); + + /** + * @brief This signal is emitted when another application sends a launch request to the application. + * + * When the application is launched, this signal is emitted after the main loop of the application starts up. + * The passed parameter describes the launch request and contains the information about why the application is launched. + * Only when the user uses the UiThread, this signal is emitted on the main thread. + * Otherwise, it is not emitted at all. + * @return The signal to connect to + */ + AppControlSignalType& TaskAppControlSignal(); + + /** + * @brief This signal is emitted when the language is changed on the device. + * Only when the user uses the UiThread, this signal is emitted on the main thread. + * Otherwise, it is not emitted at all. + * @return The signal to connect to + */ + AppSignalType& TaskLanguageChangedSignal(); + + /** + * @brief This signal is emitted when the region of the device is changed. + * Only when the user uses the UiThread, this signal is emitted on the main thread. + * Otherwise, it is not emitted at all. + * @return The signal to connect to + */ + AppSignalType& TaskRegionChangedSignal(); + + /** + * @brief This signal is emitted when the battery level of the device is low. + * Only when the user uses the UiThread, this signal is emitted on the main thread. + * Otherwise, it is not emitted at all. + * @return The signal to connect to + */ + LowBatterySignalType& TaskLowBatterySignal(); + + /** + * @brief This signal is emitted when the memory level of the device is low. + * Only when the user uses the UiThread, this signal is emitted on the main thread. + * Otherwise, it is not emitted at all. + * @return The signal to connect to + */ + LowMemorySignalType& TaskLowMemorySignal(); + public: // Not intended for application developers /// @cond internal /**