Merge "Direct Rendering" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / tizen-wayland / framework-tizen.cpp
index b4efe3d..3f638d8 100644 (file)
 // EXTERNAL INCLUDES
 #include <app_common.h>
 #include <app_control_internal.h>
-#include <appcore_ui_base.h>
 #include <bundle.h>
-#include <dali/internal/system/linux/dali-ecore.h>
-
 #include <bundle_internal.h>
+#include <dlog.h>
+#include <glib.h>
 #include <system_info.h>
 #include <system_settings.h>
 #include <widget_base.h>
+#include <app_core_ui_base.hh>
+#include <app_event_internal.hh>
+
 // CONDITIONAL INCLUDES
 #ifdef APPCORE_WATCH_AVAILABLE
 #include <appcore-watch/watch_app.h>
@@ -50,6 +52,9 @@
 
 // INTERNAL INCLUDES
 #include <dali/internal/system/common/callback-manager.h>
+#include <dali/internal/system/linux/dali-ecore.h>
+
+using namespace tizen_cpp;
 
 namespace Dali
 {
@@ -169,6 +174,44 @@ int AppAddEventHandler(AppEventHandlerPtr* eventHandler, AppEventType eventType,
   }
 }
 
+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;
+    }
+  }
+}
+
 } // namespace AppCore
 
 /**
@@ -176,10 +219,446 @@ int AppAddEventHandler(AppEventHandlerPtr* eventHandler, AppEventType eventType,
  */
 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<app_event_low_memory_status_e>(state));
+
+        PostToUiThread(
+          [](gpointer userData) -> gboolean
+          {
+            auto* task      = static_cast<Task*>(userData);
+            auto* framework = static_cast<Framework*>(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<app_event_low_battery_status_e>(state));
+
+        PostToUiThread(
+          [](gpointer userData) -> gboolean
+          {
+            auto* task      = static_cast<Task*>(userData);
+            auto* framework = static_cast<Framework*>(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<Task*>(userData);
+            auto* framework = static_cast<Framework*>(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<Task*>(userData);
+            auto* framework = static_cast<Framework*>(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),
+      mUseUiThread(false)
+    {
+      if(hint & AppCoreUiBase::HINT_DUAL_THREAD)
+      {
+        mUseUiThread = true;
+      }
+
+      if(!mUseUiThread)
+      {
+        mLanguageChanged = std::make_shared<AppEvent>(IAppCore::IEvent::Type::LANG_CHANGE, OnLanguageChanged, this);
+        AddEvent(mLanguageChanged);
+
+        mDeviceOrientationChanged = std::make_shared<AppEvent>(IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED, OnDeviceOrientationChanged, this);
+        AddEvent(mDeviceOrientationChanged);
+
+        mRegionFormatChanged = std::make_shared<AppEvent>(IAppCore::IEvent::Type::REGION_CHANGE, OnRegionFormatChanged, this);
+        AddEvent(mRegionFormatChanged);
+
+        mLowMemory = std::make_shared<AppEvent>(IAppCore::IEvent::Type::LOW_MEMORY, OnLowMemory, this);
+        AddEvent(mLowMemory);
+
+        mLowBattery = std::make_shared<AppEvent>(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<AppCoreTaskBase> CreateTask() override
+    {
+      return std::unique_ptr<AppCoreTaskBase>(
+        new Task(mFramework));
+    }
+
+    int OnCreate() override
+    {
+      AppCoreUiBase::OnCreate();
+      mFramework->Create();
+      return 0;
+    }
+
+    int OnTerminate() override
+    {
+      AppCoreUiBase::OnTerminate();
+      auto* observer = &mFramework->mObserver;
+      observer->OnTerminate();
+      return 0;
+    }
+
+    int OnPause() override
+    {
+      AppCoreUiBase::OnPause();
+      auto* observer = &mFramework->mObserver;
+      observer->OnPause();
+      return 0;
+    }
+
+    int OnResume() override
+    {
+      AppCoreUiBase::OnResume();
+      auto* observer = &mFramework->mObserver;
+      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->mObserver;
+      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<UiAppContext*>(user_data);
+      auto*     framework = context->mFramework;
+      Observer* observer  = &framework->mObserver;
+
+      char* lang = nullptr;
+      app_event_get_language(event_info, &lang);
+      if(lang)
+      {
+        framework->SetLanguage(std::string(lang));
+        observer->OnLanguageChanged();
+        free(lang);
+      }
+      else
+      {
+        DALI_LOG_ERROR("NULL pointer in Language changed event\n");
+      }
+    }
+
+    static void OnDeviceOrientationChanged(app_event_info_h event_info, void* user_data)
+    {
+    }
+
+    static void OnRegionFormatChanged(app_event_info_h event_info, void* user_data)
+    {
+      auto*     context   = static_cast<UiAppContext*>(user_data);
+      auto*     framework = context->mFramework;
+      Observer* observer  = &framework->mObserver;
+
+      char* region = nullptr;
+      app_event_get_region_format(event_info, &region);
+      if(region)
+      {
+        framework->SetRegion(std::string(region));
+        observer->OnRegionChanged();
+        free(region);
+      }
+      else
+      {
+        DALI_LOG_ERROR("NULL pointer in Region changed event\n");
+      }
+    }
+
+    static void OnLowBattery(app_event_info_h event_info, void* user_data)
+    {
+      auto*     context   = static_cast<UiAppContext*>(user_data);
+      auto*     framework = context->mFramework;
+      Observer* observer  = &framework->mObserver;
+
+      app_event_low_battery_status_e status;
+      app_event_get_low_battery_status(event_info, &status);
+      Dali::DeviceStatus::Battery::Status result = AppCore::GetBatteryStatus(status);
+      observer->OnBatteryLow(result);
+    }
+
+    static void OnLowMemory(app_event_info_h event_info, void* user_data)
+    {
+      auto*     context   = static_cast<UiAppContext*>(user_data);
+      auto*     framework = context->mFramework;
+      Observer* observer  = &framework->mObserver;
+
+      app_event_low_memory_status_e status;
+      app_event_get_low_memory_status(event_info, &status);
+      Dali::DeviceStatus::Memory::Status result = AppCore::GetMemoryStatus(status);
+      observer->OnMemoryLow(result);
+    }
+
+    void ProcessBundle(Framework* framework, bundle* bundleData)
+    {
+      if(bundleData == nullptr)
+      {
+        return;
+      }
+
+      // get bundle name
+      char* bundleName = const_cast<char*>(bundle_get_val(bundleData, "name"));
+      if(bundleName != nullptr)
+      {
+        framework->SetBundleName(bundleName);
+      }
+
+      // get bundle? id
+      char* bundleId = const_cast<char*>(bundle_get_val(bundleData, "id"));
+      if(bundleId != nullptr)
+      {
+        framework->SetBundleId(bundleId);
+      }
+    }
+
+  private:
+    Framework*                mFramework;
+    std::shared_ptr<AppEvent> mLanguageChanged;
+    std::shared_ptr<AppEvent> mDeviceOrientationChanged;
+    std::shared_ptr<AppEvent> mRegionFormatChanged;
+    std::shared_ptr<AppEvent> mLowBattery;
+    std::shared_ptr<AppEvent> 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()
@@ -195,23 +674,6 @@ struct Framework::Impl
 #endif
     mApplicationType = type;
     mCallbackManager = CallbackManager::New();
-
-    char* region   = nullptr;
-    char* language = nullptr;
-    system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY, &region);
-    system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &language);
-
-    if(region != nullptr)
-    {
-      mRegion = std::string(region);
-      free(region);
-    }
-
-    if(language != nullptr)
-    {
-      mLanguage = std::string(language);
-      free(language);
-    }
   }
 
   ~Impl()
@@ -226,6 +688,7 @@ struct Framework::Impl
 
   int AppMain()
   {
+    // TODO: The app-core-cpp has to be applied to the other app types.
     int ret;
     switch(mApplicationType)
     {
@@ -294,13 +757,35 @@ struct Framework::Impl
     mRegion = region;
   }
 
-  std::string GetLanguage() const
+  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() const
+  std::string GetRegion()
   {
+    if(mRegion.empty())
+    {
+      char* region = nullptr;
+      system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY, &region);
+
+      if(region != nullptr)
+      {
+        mRegion = std::string(region);
+        free(region);
+      }
+    }
     return mRegion;
   }
 
@@ -308,52 +793,18 @@ struct Framework::Impl
   Type             mApplicationType;
   CallbackBase*    mAbortCallBack;
   CallbackManager* mCallbackManager;
-  std::string      mLanguage;
-  std::string      mRegion;
+  std::string      mLanguage{};
+  std::string      mRegion{};
 
-  Framework*                  mFramework;
-  AppCore::AppEventHandlerPtr handlers[5];
+  Framework*                    mFramework;
+  AppCore::AppEventHandlerPtr   handlers[5];
+  std::unique_ptr<UiAppContext> mUiAppContext;
+  bool                          mUseUiThread;
 #ifdef APPCORE_WATCH_AVAILABLE
   watch_app_lifecycle_callback_s mWatchCallback;
   app_event_handler_h            watchHandlers[5];
 #endif
 
-  static int AppCreate(void* data)
-  {
-    appcore_ui_base_on_create();
-    return static_cast<int>(static_cast<Framework*>(data)->Create());
-  }
-
-  static int AppTerminate(void* data)
-  {
-    appcore_ui_base_on_terminate();
-    Observer* observer = &static_cast<Framework*>(data)->mObserver;
-
-    observer->OnTerminate();
-
-    return 0;
-  }
-
-  static int AppPause(void* data)
-  {
-    appcore_ui_base_on_pause();
-    Observer* observer = &static_cast<Framework*>(data)->mObserver;
-
-    observer->OnPause();
-
-    return 0;
-  }
-
-  static int AppResume(void* data)
-  {
-    appcore_ui_base_on_resume();
-    Observer* observer = &static_cast<Framework*>(data)->mObserver;
-
-    observer->OnResume();
-
-    return 0;
-  }
-
   static void ProcessBundle(Framework* framework, bundle* bundleData)
   {
     if(bundleData == NULL)
@@ -376,53 +827,19 @@ struct Framework::Impl
     }
   }
 
-  /**
-   * Called by AppCore when the application is launched from another module (e.g. homescreen).
-   * @param[in] b the bundle data which the launcher module sent
-   */
-  static int AppControl(bundle* bundleData, void* data)
-  {
-    app_control_h appControl = NULL;
-
-    appcore_ui_base_on_control(bundleData);
-
-    if(bundleData)
-    {
-      if(app_control_create_event(bundleData, &appControl) != TIZEN_ERROR_NONE)
-      {
-        DALI_LOG_ERROR("Failed to create an app_control handle");
-      }
-    }
-    else
-    {
-      if(app_control_create(&appControl) != TIZEN_ERROR_NONE)
-      {
-        DALI_LOG_ERROR("Failed to create an app_control handle");
-      }
-    }
-
-    Framework* framework = static_cast<Framework*>(data);
-    Observer*  observer  = &framework->mObserver;
-
-    ProcessBundle(framework, bundleData);
-
-    observer->OnReset();
-    observer->OnAppControl(appControl);
-
-    app_control_destroy(appControl);
-
-    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)
@@ -434,6 +851,12 @@ struct Framework::Impl
       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)
@@ -539,40 +962,49 @@ struct Framework::Impl
 
   int AppNormalMain()
   {
-    int ret;
-
-    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, AppDeviceRotated, 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);
-
-    appcore_ui_base_ops ops = appcore_ui_base_get_default_ops();
-
-    /* override methods */
-    ops.base.create    = AppCreate;
-    ops.base.control   = AppControl;
-    ops.base.terminate = AppTerminate;
-    ops.pause          = AppPause;
-    ops.resume         = AppResume;
-    ops.base.init      = AppInit;
-    ops.base.finish    = AppFinish;
-    ops.base.run       = AppRun;
-    ops.base.exit      = AppExit;
+    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;
+
+      // 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;
+        }
 
-    ret = appcore_ui_base_init(ops, *mFramework->mArgc, *mFramework->mArgv, mFramework, APPCORE_UI_BASE_HINT_WINDOW_GROUP_CONTROL | APPCORE_UI_BASE_HINT_WINDOW_STACK_CONTROL | APPCORE_UI_BASE_HINT_BG_LAUNCH_CONTROL | APPCORE_UI_BASE_HINT_HW_ACC_CONTROL | APPCORE_UI_BASE_HINT_WINDOW_AUTO_CONTROL);
+        bundle_free(b);
+      }
 
-    if(ret != TIZEN_ERROR_NONE)
-      return ret;
+      if(mUseUiThread)
+      {
+        hint |= AppCoreUiBase::HINT_DUAL_THREAD;
+      }
 
-    appcore_ui_base_fini();
+      mUiAppContext = std::make_unique<UiAppContext>(hint, mFramework);
+    }
 
+    mUiAppContext->Run(*mFramework->mArgc, *mFramework->mArgv);
     return TIZEN_ERROR_NONE;
   }
 
   void AppNormalExit()
   {
-    appcore_ui_base_exit();
+    if(mUiAppContext.get() == nullptr)
+    {
+      return;
+    }
+
+    mUiAppContext->Exit();
   }
 
   void AppWidgetExit()
@@ -779,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),
@@ -798,14 +1231,10 @@ Framework::Framework(Framework::Observer& observer, int* argc, char*** argv, Typ
   {
     set_last_result(TIZEN_ERROR_NOT_SUPPORTED);
   }
-#ifdef DALI_ELDBUS_AVAILABLE
-  // Initialize ElDBus.
-  DALI_LOG_INFO(gDBusLogging, Debug::General, "Starting DBus Initialization\n");
-  eldbus_init();
-#endif
+
   InitThreads();
 
-  mImpl = new Impl(this, type);
+  mImpl = new Impl(this, type, useUiThread);
 }
 
 Framework::~Framework()
@@ -815,12 +1244,6 @@ Framework::~Framework()
     Quit();
   }
 
-#ifdef DALI_ELDBUS_AVAILABLE
-  // Shutdown ELDBus.
-  DALI_LOG_INFO(gDBusLogging, Debug::General, "Shutting down DBus\n");
-  eldbus_shutdown();
-#endif
-
   delete mImpl;
 }
 
@@ -901,7 +1324,7 @@ std::string Framework::GetResourcePath()
     resourcePath += "/";
   }
 
-#endif //TIZEN_PLATFORM_CONFIG_SUPPORTED
+#endif // TIZEN_PLATFORM_CONFIG_SUPPORTED
 
   return resourcePath;
 }