2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/adaptor/common/framework.h>
22 #include <app_common.h>
23 #include <app_control_internal.h>
25 #include <bundle_internal.h>
28 #include <system_info.h>
29 #include <system_settings.h>
30 #include <widget_base.h>
31 #include <app_core_ui_base.hh>
32 #include <app_event_internal.hh>
34 // CONDITIONAL INCLUDES
35 #ifdef APPCORE_WATCH_AVAILABLE
36 #include <appcore-watch/watch_app.h>
38 #ifdef DALI_ELDBUS_AVAILABLE
40 #endif // DALI_ELDBUS_AVAILABLE
42 #if defined(TIZEN_PLATFORM_CONFIG_SUPPORTED) && TIZEN_PLATFORM_CONFIG_SUPPORTED
43 #include <tzplatform_config.h>
44 #endif // TIZEN_PLATFORM_CONFIG_SUPPORTED
46 #ifdef COMPONENT_APPLICATION_SUPPORT
47 #include <component_based_app_base.h>
50 #include <dali/integration-api/debug.h>
51 #include <dali/integration-api/trace.h>
54 #include <dali/internal/system/common/callback-manager.h>
55 #include <dali/internal/system/linux/dali-ecore.h>
57 using namespace tizen_cpp;
67 #if defined(DEBUG_ENABLED)
68 Integration::Log::Filter* gDBusLogging = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DBUS");
70 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_FRAMEWORK, true);
72 bool IsWidgetFeatureEnabled()
74 static bool feature = false;
75 static bool retrieved = false;
83 ret = system_info_get_platform_bool("http://tizen.org/feature/shell.appwidget", &feature);
84 if(ret != SYSTEM_INFO_ERROR_NONE)
86 DALI_LOG_ERROR("failed to get system info");
94 // Note : tizen appfw don't consider zero-arguments case.
95 // If framework argc & argv is nullptr, We should add at least one argv.
96 const int gTizenDummyArgc = 1;
97 const char* gTizenDummyArgv[1] = {"dali-tizen-app"};
99 } // anonymous namespace
105 LOW_MEMORY, //< The low memory event
106 LOW_BATTERY, //< The low battery event
107 LANGUAGE_CHANGED, //< The system language changed event
108 DEVICE_ORIENTATION_CHANGED, //< The device orientation changed event
109 REGION_FORMAT_CHANGED, //< The region format changed event
110 SUSPENDED_STATE_CHANGED, //< The suspended state changed event of the application
111 UPDATE_REQUESTED, //< The update requested event. This event can occur when an app needs to be updated. It is dependent on target devices.
114 static int AppEventConverter[APPCORE_BASE_EVENT_MAX] =
116 [LOW_MEMORY] = APPCORE_BASE_EVENT_LOW_MEMORY,
117 [LOW_BATTERY] = APPCORE_BASE_EVENT_LOW_BATTERY,
118 [LANGUAGE_CHANGED] = APPCORE_BASE_EVENT_LANG_CHANGE,
119 [DEVICE_ORIENTATION_CHANGED] = APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED,
120 [REGION_FORMAT_CHANGED] = APPCORE_BASE_EVENT_REGION_CHANGE,
121 [SUSPENDED_STATE_CHANGED] = APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE,
130 typedef struct AppEventInfo* AppEventInfoPtr;
132 typedef void (*AppEventCallback)(AppEventInfoPtr eventInfo, void* userData);
134 struct AppEventHandler
142 typedef struct AppEventHandler* AppEventHandlerPtr;
144 int EventCallback(void* event, void* data)
146 AppEventHandlerPtr handler = static_cast<AppEventHandlerPtr>(data);
148 struct AppEventInfo appEvent;
150 appEvent.type = handler->type;
151 appEvent.value = event;
154 handler->cb(&appEvent, handler->data);
159 int AppAddEventHandler(AppEventHandlerPtr* eventHandler, AppEventType eventType, AppEventCallback callback, void* userData)
161 AppEventHandlerPtr handler;
163 handler = static_cast<AppEventHandlerPtr>(calloc(1, sizeof(struct AppEventHandler)));
166 DALI_LOG_ERROR("failed to create handler");
167 return TIZEN_ERROR_UNKNOWN;
171 handler->type = eventType;
172 handler->cb = callback;
173 handler->data = userData;
174 handler->raw = appcore_base_add_event(static_cast<appcore_base_event>(AppEventConverter[static_cast<int>(eventType)]), EventCallback, handler);
176 *eventHandler = handler;
178 return TIZEN_ERROR_NONE;
182 DeviceStatus::Memory::Status GetMemoryStatus(app_event_low_memory_status_e memoryStatus)
186 case APP_EVENT_LOW_MEMORY_SOFT_WARNING: // 0x02
188 return Dali::DeviceStatus::Memory::Status::LOW;
190 case APP_EVENT_LOW_MEMORY_HARD_WARNING: // 0x04
192 return Dali::DeviceStatus::Memory::Status::CRITICALLY_LOW;
194 default: // APP_EVENT_LOW_MEMORY_NORMAL 0x01
196 return Dali::DeviceStatus::Memory::Status::NORMAL;
201 DeviceStatus::Battery::Status GetBatteryStatus(app_event_low_battery_status_e batteryStatus)
203 switch(batteryStatus)
205 case APP_EVENT_LOW_BATTERY_POWER_OFF: // 1
207 return Dali::DeviceStatus::Battery::Status::POWER_OFF;
209 case APP_EVENT_LOW_BATTERY_CRITICAL_LOW: // 2
211 return Dali::DeviceStatus::Battery::Status::CRITICALLY_LOW;
215 return Dali::DeviceStatus::Battery::Status::NORMAL;
220 } // namespace AppCore
223 * Impl to hide EFL data members
225 struct Framework::Impl
227 class UiAppContext : public AppCoreUiBase
230 class Task : public AppCoreTaskBase
233 explicit Task(Framework* framework)
234 : mFramework(framework),
235 mNewBatteryStatus(Dali::DeviceStatus::Battery::Status::NORMAL),
236 mNewMemoryStatus(Dali::DeviceStatus::Memory::NORMAL)
244 int OnCreate() override
246 // On the main thread, the log functions are not set. So print_log() is used directly.
247 print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnCreate() emitted", __MODULE__, __func__, __LINE__);
248 mFramework->mTaskObserver.OnTaskInit();
249 return AppCoreTaskBase::OnCreate();
252 int OnTerminate() override
254 print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnTerminate() emitted", __MODULE__, __func__, __LINE__);
255 mFramework->mTaskObserver.OnTaskTerminate();
256 return AppCoreTaskBase::OnTerminate();
259 int OnControl(tizen_base::Bundle b) override
261 print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnControl() emitted", __MODULE__, __func__, __LINE__);
262 AppCoreTaskBase::OnControl(b);
264 app_control_h appControl = nullptr;
266 auto* bundleData = b.GetHandle();
269 if(app_control_create_event(bundleData, &appControl) != TIZEN_ERROR_NONE)
271 print_log(DLOG_ERROR, "DALI", "%s: %s(%d) > Failed to create an app_control handle with Bundle", __MODULE__, __func__, __LINE__);
276 if(app_control_create(&appControl) != TIZEN_ERROR_NONE)
278 print_log(DLOG_ERROR, "DALI", "%s: %s(%d) > Failed to create an app_control handle", __MODULE__, __func__, __LINE__);
281 mFramework->mTaskObserver.OnTaskAppControl(appControl);
283 app_control_destroy(appControl);
287 void OnUiEvent(AppCoreTaskBase::UiState state) override
289 // This event is emitted when the UI thread is paused or resumed.
290 print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnUiEvent() emitted", __MODULE__, __func__, __LINE__);
292 // Note: This isn't implemented.
293 AppCoreTaskBase::OnUiEvent(state);
296 void OnLowMemory(AppCoreTaskBase::LowMemoryState state) override
298 print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLowMemory() emitted", __MODULE__, __func__, __LINE__);
300 mNewMemoryStatus = AppCore::GetMemoryStatus(static_cast<app_event_low_memory_status_e>(state));
303 [](gpointer userData) -> gboolean {
304 auto* task = static_cast<Task*>(userData);
305 auto* framework = static_cast<Framework*>(task->mFramework);
306 framework->mObserver.OnMemoryLow(task->mNewMemoryStatus);
307 return G_SOURCE_REMOVE;
309 mFramework->mTaskObserver.OnTaskMemoryLow(mNewMemoryStatus);
310 AppCoreTaskBase::OnLowMemory(state);
313 void OnLowBattery(AppCoreTaskBase::LowBatteryState state) override
315 print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLowBattery() emitted", __MODULE__, __func__, __LINE__);
316 mNewBatteryStatus = AppCore::GetBatteryStatus(static_cast<app_event_low_battery_status_e>(state));
319 [](gpointer userData) -> gboolean {
320 auto* task = static_cast<Task*>(userData);
321 auto* framework = static_cast<Framework*>(task->mFramework);
322 framework->mObserver.OnBatteryLow(task->mNewBatteryStatus);
323 return G_SOURCE_REMOVE;
325 mFramework->mTaskObserver.OnTaskBatteryLow(mNewBatteryStatus);
326 AppCoreTaskBase::OnLowBattery(state);
329 void OnLangChanged(const std::string& lang) override
331 print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnLangChanged() emitted", __MODULE__, __func__, __LINE__);
333 mFramework->SetLanguage(mNewLanguage);
336 [](gpointer userData) -> gboolean {
337 auto* task = static_cast<Task*>(userData);
338 auto* framework = static_cast<Framework*>(task->mFramework);
339 framework->mObserver.OnLanguageChanged();
340 return G_SOURCE_REMOVE;
343 mFramework->mTaskObserver.OnTaskLanguageChanged();
344 AppCoreTaskBase::OnLangChanged(lang);
347 void OnRegionChanged(const std::string& region) override
349 print_log(DLOG_INFO, "DALI", "%s: %s(%d) > nRegionChanged() emitted", __MODULE__, __func__, __LINE__);
351 mFramework->SetRegion(mNewRegion);
354 [](gpointer userData) -> gboolean {
355 auto* task = static_cast<Task*>(userData);
356 auto* framework = static_cast<Framework*>(task->mFramework);
357 framework->mObserver.OnRegionChanged();
358 return G_SOURCE_REMOVE;
361 mFramework->mTaskObserver.OnTaskRegionChanged();
362 AppCoreTaskBase::OnRegionChanged(mNewRegion);
365 void OnDeviceOrientationChanged(AppCoreTaskBase::DeviceOrientationState state) override
367 print_log(DLOG_INFO, "DALI", "%s: %s(%d) > OnDeviceOrientationChanged() emitted", __MODULE__, __func__, __LINE__);
368 // Note: This isn't emitted to the App.
369 AppCoreTaskBase::OnDeviceOrientationChanged(state);
373 GMainContext* GetTizenGlibContext()
375 GMainContext* context;
376 const char* env = getenv("TIZEN_GLIB_CONTEXT");
379 context = (GMainContext*)strtoul(env, nullptr, 10);
389 void PostToUiThread(GSourceFunc func)
391 GSource* source = g_idle_source_new();
392 g_source_set_callback(source, func, this, nullptr);
393 g_source_attach(source, GetTizenGlibContext());
394 g_source_unref(source);
398 Framework* mFramework;
399 std::string mNewLanguage;
400 std::string mNewRegion;
401 Dali::DeviceStatus::Battery::Status mNewBatteryStatus;
402 Dali::DeviceStatus::Memory::Status mNewMemoryStatus;
405 explicit UiAppContext(unsigned int hint, Framework* framework)
406 : AppCoreUiBase(hint),
407 mFramework(framework),
410 if(hint & AppCoreUiBase::HINT_DUAL_THREAD)
417 mLanguageChanged = std::make_shared<AppEvent>(IAppCore::IEvent::Type::LANG_CHANGE, OnLanguageChanged, this);
418 AddEvent(mLanguageChanged);
420 mDeviceOrientationChanged = std::make_shared<AppEvent>(IAppCore::IEvent::Type::DEVICE_ORIENTATION_CHANGED, OnDeviceOrientationChanged, this);
421 AddEvent(mDeviceOrientationChanged);
423 mRegionFormatChanged = std::make_shared<AppEvent>(IAppCore::IEvent::Type::REGION_CHANGE, OnRegionFormatChanged, this);
424 AddEvent(mRegionFormatChanged);
426 mLowMemory = std::make_shared<AppEvent>(IAppCore::IEvent::Type::LOW_MEMORY, OnLowMemory, this);
427 AddEvent(mLowMemory);
429 mLowBattery = std::make_shared<AppEvent>(IAppCore::IEvent::Type::LOW_BATTERY, OnLowBattery, this);
430 AddEvent(mLowBattery);
434 virtual ~UiAppContext()
438 RemoveEvent(mLowBattery);
439 RemoveEvent(mLowMemory);
440 RemoveEvent(mRegionFormatChanged);
441 RemoveEvent(mDeviceOrientationChanged);
442 RemoveEvent(mLanguageChanged);
446 std::unique_ptr<AppCoreTaskBase> CreateTask() override
448 return std::unique_ptr<AppCoreTaskBase>(
449 new Task(mFramework));
452 int OnCreate() override
454 AppCoreUiBase::OnCreate();
455 mFramework->Create();
459 int OnTerminate() override
461 AppCoreUiBase::OnTerminate();
462 auto* observer = &mFramework->mObserver;
463 observer->OnTerminate();
467 int OnPause() override
469 AppCoreUiBase::OnPause();
470 auto* observer = &mFramework->mObserver;
475 int OnResume() override
477 AppCoreUiBase::OnResume();
478 auto* observer = &mFramework->mObserver;
479 observer->OnResume();
483 int OnControl(tizen_base::Bundle b) override
485 AppCoreUiBase::OnControl(b);
487 app_control_h appControl = nullptr;
489 auto* bundleData = b.GetHandle();
492 if(app_control_create_event(bundleData, &appControl) != TIZEN_ERROR_NONE)
494 DALI_LOG_ERROR("Failed to create an app_control handle");
500 if(app_control_create(&appControl) != TIZEN_ERROR_NONE)
502 DALI_LOG_ERROR("Failed to create an app_control handle");
507 auto* observer = &mFramework->mObserver;
508 ProcessBundle(mFramework, bundleData);
510 observer->OnAppControl(appControl);
511 app_control_destroy(appControl);
515 void OnLoopInit(int argc, char** argv) override
517 #pragma GCC diagnostic push
518 #pragma GCC diagnostic ignored "-Wold-style-cast"
520 ecore_app_args_set(argc, (const char**)argv);
521 #pragma GCC diagnostic pop
523 #ifdef DALI_ELDBUS_AVAILABLE
524 // Initialize ElDBus.
525 DALI_LOG_INFO(gDBusLogging, Debug::General, "Starting DBus Initialization\n");
530 void OnLoopFinish() override
534 if(getenv("AUL_LOADER_INIT"))
536 setenv("AUL_LOADER_INIT", "0", 1);
540 #ifdef DALI_ELDBUS_AVAILABLE
542 DALI_LOG_INFO(gDBusLogging, Debug::General, "Shutting down DBus\n");
547 void OnLoopRun() override
549 ecore_main_loop_begin();
552 void OnLoopExit() override
554 ecore_main_loop_quit();
558 static void OnLanguageChanged(app_event_info_h event_info, void* user_data)
560 auto* context = static_cast<UiAppContext*>(user_data);
561 auto* framework = context->mFramework;
562 Observer* observer = &framework->mObserver;
564 char* lang = nullptr;
565 app_event_get_language(event_info, &lang);
568 framework->SetLanguage(std::string(lang));
569 observer->OnLanguageChanged();
574 DALI_LOG_ERROR("NULL pointer in Language changed event\n");
578 static void OnDeviceOrientationChanged(app_event_info_h event_info, void* user_data)
582 static void OnRegionFormatChanged(app_event_info_h event_info, void* user_data)
584 auto* context = static_cast<UiAppContext*>(user_data);
585 auto* framework = context->mFramework;
586 Observer* observer = &framework->mObserver;
588 char* region = nullptr;
589 app_event_get_region_format(event_info, ®ion);
592 framework->SetRegion(std::string(region));
593 observer->OnRegionChanged();
598 DALI_LOG_ERROR("NULL pointer in Region changed event\n");
602 static void OnLowBattery(app_event_info_h event_info, void* user_data)
604 auto* context = static_cast<UiAppContext*>(user_data);
605 auto* framework = context->mFramework;
606 Observer* observer = &framework->mObserver;
608 app_event_low_battery_status_e status;
609 app_event_get_low_battery_status(event_info, &status);
610 Dali::DeviceStatus::Battery::Status result = AppCore::GetBatteryStatus(status);
611 observer->OnBatteryLow(result);
614 static void OnLowMemory(app_event_info_h event_info, void* user_data)
616 auto* context = static_cast<UiAppContext*>(user_data);
617 auto* framework = context->mFramework;
618 Observer* observer = &framework->mObserver;
620 app_event_low_memory_status_e status;
621 app_event_get_low_memory_status(event_info, &status);
622 Dali::DeviceStatus::Memory::Status result = AppCore::GetMemoryStatus(status);
623 observer->OnMemoryLow(result);
626 void ProcessBundle(Framework* framework, bundle* bundleData)
628 if(bundleData == nullptr)
634 char* bundleName = const_cast<char*>(bundle_get_val(bundleData, "name"));
635 if(bundleName != nullptr)
637 framework->SetBundleName(bundleName);
641 char* bundleId = const_cast<char*>(bundle_get_val(bundleData, "id"));
642 if(bundleId != nullptr)
644 framework->SetBundleId(bundleId);
649 Framework* mFramework;
650 std::shared_ptr<AppEvent> mLanguageChanged;
651 std::shared_ptr<AppEvent> mDeviceOrientationChanged;
652 std::shared_ptr<AppEvent> mRegionFormatChanged;
653 std::shared_ptr<AppEvent> mLowBattery;
654 std::shared_ptr<AppEvent> mLowMemory;
659 Impl(void* data, Type type, bool useUiThread)
660 : mAbortCallBack(NULL),
661 mCallbackManager(NULL),
662 mUseUiThread(useUiThread)
663 #ifdef APPCORE_WATCH_AVAILABLE
668 mFramework = static_cast<Framework*>(data);
670 #ifndef APPCORE_WATCH_AVAILABLE
673 throw Dali::DaliException("", "Watch Application is not supported.");
676 mApplicationType = type;
677 mCallbackManager = CallbackManager::New();
682 delete mAbortCallBack;
684 // we're quiting the main loop so
685 // mCallbackManager->RemoveAllCallBacks() does not need to be called
686 // to delete our abort handler
687 delete mCallbackManager;
692 // TODO: The app-core-cpp has to be applied to the other app types.
694 switch(mApplicationType)
698 ret = AppNormalMain();
703 ret = AppWidgetMain();
708 ret = AppWatchMain();
711 #ifdef COMPONENT_APPLICATION_SUPPORT
714 ret = AppComponentMain();
724 switch(mApplicationType)
741 #ifdef COMPONENT_APPLICATION_SUPPORT
751 void SetLanguage(const std::string& language)
753 mLanguage = language;
756 void SetRegion(const std::string& region)
761 std::string GetLanguage()
763 if(mLanguage.empty())
765 char* language = nullptr;
766 system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &language);
768 if(language != nullptr)
770 mLanguage = std::string(language);
777 std::string GetRegion()
781 char* region = nullptr;
782 system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY, ®ion);
784 if(region != nullptr)
786 mRegion = std::string(region);
794 Type mApplicationType;
795 CallbackBase* mAbortCallBack;
796 CallbackManager* mCallbackManager;
797 std::string mLanguage{};
798 std::string mRegion{};
800 Framework* mFramework;
801 AppCore::AppEventHandlerPtr handlers[5];
802 std::unique_ptr<UiAppContext> mUiAppContext;
804 #ifdef APPCORE_WATCH_AVAILABLE
805 watch_app_lifecycle_callback_s mWatchCallback;
808 static void ProcessBundle(Framework* framework, bundle* bundleData)
810 if(bundleData == NULL)
816 char* bundleName = const_cast<char*>(bundle_get_val(bundleData, "name"));
817 if(bundleName != NULL)
819 framework->SetBundleName(bundleName);
823 char* bundleId = const_cast<char*>(bundle_get_val(bundleData, "id"));
826 framework->SetBundleId(bundleId);
830 static void AppInit(int argc, char** argv, void* data)
832 #pragma GCC diagnostic push
833 #pragma GCC diagnostic ignored "-Wold-style-cast"
835 ecore_app_args_set(argc, (const char**)argv);
836 #pragma GCC diagnostic pop
838 #ifdef DALI_ELDBUS_AVAILABLE
839 // Initialize ElDBus.
840 DALI_LOG_INFO(gDBusLogging, Debug::General, "Starting DBus Initialization\n");
845 static void AppFinish(void)
849 if(getenv("AUL_LOADER_INIT"))
851 setenv("AUL_LOADER_INIT", "0", 1);
855 #ifdef DALI_ELDBUS_AVAILABLE
857 DALI_LOG_INFO(gDBusLogging, Debug::General, "Shutting down DBus\n");
862 static void AppRun(void* data)
864 ecore_main_loop_begin();
867 static void AppExit(void* data)
869 ecore_main_loop_quit();
872 static void AppLanguageChanged(AppCore::AppEventInfoPtr event, void* data)
874 Framework* framework = static_cast<Framework*>(data);
875 Observer* observer = &framework->mObserver;
877 if(event && event->value)
879 framework->SetLanguage(std::string(static_cast<const char*>(event->value)));
880 observer->OnLanguageChanged();
884 DALI_LOG_ERROR("NULL pointer in Language changed event\n");
888 static void AppDeviceRotated(AppCore::AppEventInfoPtr event_info, void* data)
892 static void AppRegionChanged(AppCore::AppEventInfoPtr event, void* data)
894 Framework* framework = static_cast<Framework*>(data);
895 Observer* observer = &framework->mObserver;
897 if(event && event->value)
899 framework->SetRegion(std::string(static_cast<const char*>(event->value)));
900 observer->OnRegionChanged();
904 DALI_LOG_ERROR("NULL pointer in Region changed event\n");
908 static void AppBatteryLow(AppCore::AppEventInfoPtr event, void* data)
910 Observer* observer = &static_cast<Framework*>(data)->mObserver;
911 int status = *static_cast<int*>(event->value);
912 Dali::DeviceStatus::Battery::Status result = Dali::DeviceStatus::Battery::NORMAL;
914 // convert to dali battery status
919 result = Dali::DeviceStatus::Battery::POWER_OFF;
924 result = Dali::DeviceStatus::Battery::CRITICALLY_LOW;
930 observer->OnBatteryLow(result);
933 static void AppMemoryLow(AppCore::AppEventInfoPtr event, void* data)
935 Observer* observer = &static_cast<Framework*>(data)->mObserver;
936 int status = *static_cast<int*>(event->value);
937 Dali::DeviceStatus::Memory::Status result = Dali::DeviceStatus::Memory::NORMAL;
939 // convert to dali memmory status
944 result = Dali::DeviceStatus::Memory::NORMAL;
949 result = Dali::DeviceStatus::Memory::LOW;
954 result = Dali::DeviceStatus::Memory::CRITICALLY_LOW;
960 observer->OnMemoryLow(result);
965 if(mUiAppContext.get() == nullptr)
967 unsigned int hint = AppCoreUiBase::HINT_WINDOW_GROUP_CONTROL |
968 AppCoreUiBase::HINT_WINDOW_STACK_CONTROL |
969 AppCoreUiBase::HINT_BG_LAUNCH_CONTROL |
970 AppCoreUiBase::HINT_HW_ACC_CONTROL |
971 AppCoreUiBase::HINT_WINDOW_AUTO_CONTROL;
973 // For testing UIThread model, This code turns on the UI Thread feature forcibly.
974 // ex) app_launcher -e [APPID] __K_UI_THREAD enable
975 // This code doesn't change mUseUiThread in Internal::Application
976 bundle* b = bundle_import_from_argv(*mFramework->mArgc, *mFramework->mArgv);
979 const char* val = bundle_get_val(b, "__K_UI_THREAD");
980 if(val != nullptr && strcmp(val, "enable") == 0)
990 hint |= AppCoreUiBase::HINT_DUAL_THREAD;
993 mUiAppContext = std::make_unique<UiAppContext>(hint, mFramework);
996 mUiAppContext->Run(*mFramework->mArgc, *mFramework->mArgv);
997 return TIZEN_ERROR_NONE;
1000 void AppNormalExit()
1002 if(mUiAppContext.get() == nullptr)
1007 mUiAppContext->Exit();
1010 void AppWidgetExit()
1015 static int WidgetAppCreate(void* data)
1017 widget_base_on_create();
1018 return static_cast<int>(static_cast<Framework*>(data)->Create());
1021 static int WidgetAppTerminate(void* data)
1023 Observer* observer = &static_cast<Framework*>(data)->mObserver;
1024 observer->OnTerminate();
1026 widget_base_on_terminate();
1032 if(!IsWidgetFeatureEnabled())
1034 DALI_LOG_ERROR("widget feature is not supported");
1038 AppCore::AppAddEventHandler(&handlers[AppCore::LOW_BATTERY], AppCore::LOW_BATTERY, AppBatteryLow, mFramework);
1039 AppCore::AppAddEventHandler(&handlers[AppCore::LOW_MEMORY], AppCore::LOW_MEMORY, AppMemoryLow, mFramework);
1040 AppCore::AppAddEventHandler(&handlers[AppCore::DEVICE_ORIENTATION_CHANGED], AppCore::DEVICE_ORIENTATION_CHANGED, AppDeviceRotated, mFramework);
1041 AppCore::AppAddEventHandler(&handlers[AppCore::LANGUAGE_CHANGED], AppCore::LANGUAGE_CHANGED, AppLanguageChanged, mFramework);
1042 AppCore::AppAddEventHandler(&handlers[AppCore::REGION_FORMAT_CHANGED], AppCore::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework);
1044 widget_base_ops ops = widget_base_get_default_ops();
1046 /* override methods */
1047 ops.create = WidgetAppCreate;
1048 ops.terminate = WidgetAppTerminate;
1050 ops.finish = AppFinish;
1054 int result = widget_base_init(ops, *mFramework->mArgc, *mFramework->mArgv, mFramework);
1061 #ifdef APPCORE_WATCH_AVAILABLE
1062 static bool WatchAppCreate(int width, int height, void* data)
1064 return static_cast<Framework*>(data)->Create();
1067 static void WatchAppTimeTick(watch_time_h time, void* data)
1069 Observer* observer = &static_cast<Framework*>(data)->mObserver;
1070 WatchTime curTime(time);
1072 observer->OnTimeTick(curTime);
1075 static void WatchAppAmbientTick(watch_time_h time, void* data)
1077 Observer* observer = &static_cast<Framework*>(data)->mObserver;
1078 WatchTime curTime(time);
1080 observer->OnAmbientTick(curTime);
1083 static void WatchAppAmbientChanged(bool ambient, void* data)
1085 Observer* observer = &static_cast<Framework*>(data)->mObserver;
1087 observer->OnAmbientChanged(ambient);
1090 static void WatchAppControl(app_control_h app_control, void* data)
1092 Framework* framework = static_cast<Framework*>(data);
1093 Observer* observer = &framework->mObserver;
1094 bundle* bundleData = NULL;
1096 app_control_to_bundle(app_control, &bundleData);
1097 ProcessBundle(framework, bundleData);
1099 observer->OnReset();
1100 observer->OnAppControl(app_control);
1103 static void WatchAppTerminate(void* data)
1105 Observer* observer = &static_cast<Framework*>(data)->mObserver;
1107 observer->OnTerminate();
1110 static void WatchAppPause(void* data)
1112 Observer* observer = &static_cast<Framework*>(data)->mObserver;
1114 observer->OnPause();
1117 static void WatchAppResume(void* data)
1119 Observer* observer = &static_cast<Framework*>(data)->mObserver;
1121 observer->OnResume();
1130 #ifdef APPCORE_WATCH_AVAILABLE
1131 mWatchCallback.create = WatchAppCreate;
1132 mWatchCallback.app_control = WatchAppControl;
1133 mWatchCallback.terminate = WatchAppTerminate;
1134 mWatchCallback.pause = WatchAppPause;
1135 mWatchCallback.resume = WatchAppResume;
1136 mWatchCallback.time_tick = WatchAppTimeTick;
1137 mWatchCallback.ambient_tick = WatchAppAmbientTick;
1138 mWatchCallback.ambient_changed = WatchAppAmbientChanged;
1140 AppCore::AppAddEventHandler(&handlers[AppCore::LOW_BATTERY], AppCore::LOW_BATTERY, AppBatteryLow, mFramework);
1141 AppCore::AppAddEventHandler(&handlers[AppCore::LOW_MEMORY], AppCore::LOW_MEMORY, AppMemoryLow, mFramework);
1142 AppCore::AppAddEventHandler(&handlers[AppCore::LANGUAGE_CHANGED], AppCore::LANGUAGE_CHANGED, AppLanguageChanged, mFramework);
1143 AppCore::AppAddEventHandler(&handlers[AppCore::REGION_FORMAT_CHANGED], AppCore::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework);
1145 ret = watch_app_main(*mFramework->mArgc, *mFramework->mArgv, &mWatchCallback, mFramework);
1152 #ifdef APPCORE_WATCH_AVAILABLE
1157 #ifdef COMPONENT_APPLICATION_SUPPORT
1158 int AppComponentMain()
1160 /*Crate component_based_app_base_lifecycle_callback*/
1161 component_based_app_base_lifecycle_callback_s callback;
1162 callback.init = AppInit;
1163 callback.run = AppRun;
1164 callback.exit = AppExit;
1165 callback.create = ComponentAppCreate;
1166 callback.terminate = ComponentAppTerminate;
1167 callback.fini = ComponentAppFinish;
1169 return component_based_app_base_main(*mFramework->mArgc, *mFramework->mArgv, &callback, mFramework);
1172 static void* ComponentAppCreate(void* data)
1174 Framework* framework = static_cast<Framework*>(data);
1175 Observer* observer = &framework->mObserver;
1178 return Dali::AnyCast<void*>(observer->OnCreate());
1181 static void ComponentAppTerminate(void* data)
1183 Observer* observer = &static_cast<Framework*>(data)->mObserver;
1184 observer->OnTerminate();
1187 static void ComponentAppFinish(void* data)
1191 if(getenv("AUL_LOADER_INIT"))
1193 setenv("AUL_LOADER_INIT", "0", 1);
1198 void AppComponentExit()
1200 component_based_app_base_exit();
1207 Impl(const Impl& impl);
1210 Impl& operator=(const Impl& impl);
1213 Framework::Framework(Framework::Observer& observer, Framework::TaskObserver& taskObserver, int* argc, char*** argv, Type type, bool useUiThread)
1214 : mObserver(observer),
1215 mTaskObserver(taskObserver),
1216 mInitialised(false),
1223 mAbortHandler(MakeCallback(this, &Framework::AbortCallback)),
1226 if(mArgc == nullptr || mArgv == nullptr)
1228 mArgc = const_cast<int*>(&gTizenDummyArgc);
1229 mArgv = const_cast<char***>(reinterpret_cast<const char***>(&gTizenDummyArgv));
1232 bool featureFlag = true;
1233 system_info_get_platform_bool("tizen.org/feature/opengles.version.2_0", &featureFlag);
1235 if(featureFlag == false)
1237 set_last_result(TIZEN_ERROR_NOT_SUPPORTED);
1242 mImpl = new Impl(this, type, useUiThread);
1245 Framework::~Framework()
1255 bool Framework::Create()
1257 mInitialised = true;
1262 void Framework::Run()
1267 DALI_TRACE_BEGIN(gTraceFilter, "DALI_APPMAIN");
1268 ret = mImpl->AppMain();
1269 DALI_TRACE_END(gTraceFilter, "DALI_APPMAIN");
1270 if(ret != APP_ERROR_NONE)
1272 DALI_LOG_ERROR("Framework::Run(), ui_app_main() is failed. err = %d\n", ret);
1277 void Framework::Quit()
1282 bool Framework::IsMainLoopRunning()
1287 void Framework::AddAbortCallback(CallbackBase* callback)
1289 mImpl->mAbortCallBack = callback;
1292 std::string Framework::GetBundleName() const
1297 void Framework::SetBundleName(const std::string& name)
1302 std::string Framework::GetBundleId() const
1307 std::string Framework::GetResourcePath()
1309 std::string resourcePath = "";
1310 #if defined(TIZEN_PLATFORM_CONFIG_SUPPORTED) && TIZEN_PLATFORM_CONFIG_SUPPORTED
1311 char* app_rsc_path = app_get_resource_path();
1314 resourcePath = app_rsc_path;
1317 #else // For backwards compatibility with older Tizen versions
1319 // "DALI_APPLICATION_PACKAGE" is used to get the already configured Application package path.
1320 const char* environmentVariable = "DALI_APPLICATION_PACKAGE";
1321 char* value = getenv(environmentVariable);
1324 resourcePath = value;
1327 if(resourcePath.back() != '/')
1329 resourcePath += "/";
1332 #endif // TIZEN_PLATFORM_CONFIG_SUPPORTED
1334 return resourcePath;
1337 std::string Framework::GetDataPath()
1340 char* dataPath = app_get_data_path();
1349 void Framework::SetBundleId(const std::string& id)
1354 void Framework::AbortCallback()
1356 // if an abort call back has been installed run it.
1357 if(mImpl->mAbortCallBack)
1359 CallbackBase::Execute(*mImpl->mAbortCallBack);
1367 void Framework::InitThreads()
1371 void Framework::SetLanguage(const std::string& language)
1373 mImpl->SetLanguage(language);
1376 void Framework::SetRegion(const std::string& region)
1378 mImpl->SetRegion(region);
1381 std::string Framework::GetLanguage() const
1383 return mImpl->GetLanguage();
1386 std::string Framework::GetRegion() const
1388 return mImpl->GetRegion();
1391 } // namespace Adaptor
1393 } // namespace Internal