25a1b581ffb601a02610267f395c39182bfce829
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / tizen-wayland / framework-tizen.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/adaptor/common/framework.h>
20
21 // EXTERNAL INCLUDES
22 #include <app_common.h>
23 #include <app_control_internal.h>
24 #include <appcore_ui_base.h>
25 #include <bundle.h>
26 #include <dali/internal/system/linux/dali-ecore.h>
27
28 #include <bundle_internal.h>
29 #include <system_info.h>
30 #include <system_settings.h>
31 #include <widget_base.h>
32 // CONDITIONAL INCLUDES
33 #ifdef APPCORE_WATCH_AVAILABLE
34 #include <appcore-watch/watch_app.h>
35 #endif
36 #ifdef DALI_ELDBUS_AVAILABLE
37 #include <Eldbus.h>
38 #endif // DALI_ELDBUS_AVAILABLE
39
40 #if defined(TIZEN_PLATFORM_CONFIG_SUPPORTED) && TIZEN_PLATFORM_CONFIG_SUPPORTED
41 #include <tzplatform_config.h>
42 #endif // TIZEN_PLATFORM_CONFIG_SUPPORTED
43
44 #ifdef COMPONENT_APPLICATION_SUPPORT
45 #include <component_based_app_base.h>
46 #endif
47
48 #include <dali/integration-api/debug.h>
49
50 // INTERNAL INCLUDES
51 #include <dali/internal/system/common/callback-manager.h>
52
53 namespace Dali
54 {
55 namespace Internal
56 {
57 namespace Adaptor
58 {
59 namespace
60 {
61 #if defined(DEBUG_ENABLED)
62 Integration::Log::Filter* gDBusLogging = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DBUS");
63 #endif
64
65 bool IsWidgetFeatureEnabled()
66 {
67   static bool feature   = false;
68   static bool retrieved = false;
69   int         ret;
70
71   if(retrieved == true)
72   {
73     return feature;
74   }
75
76   ret = system_info_get_platform_bool("http://tizen.org/feature/shell.appwidget", &feature);
77   if(ret != SYSTEM_INFO_ERROR_NONE)
78   {
79     DALI_LOG_ERROR("failed to get system info");
80     return false;
81   }
82
83   retrieved = true;
84   return feature;
85 }
86
87 } // anonymous namespace
88
89 namespace AppCore
90 {
91 typedef enum
92 {
93   LOW_MEMORY,                 //< The low memory event
94   LOW_BATTERY,                //< The low battery event
95   LANGUAGE_CHANGED,           //< The system language changed event
96   DEVICE_ORIENTATION_CHANGED, //< The device orientation changed event
97   REGION_FORMAT_CHANGED,      //< The region format changed event
98   SUSPENDED_STATE_CHANGED,    //< The suspended state changed event of the application
99   UPDATE_REQUESTED,           //< The update requested event. This event can occur when an app needs to be updated. It is dependent on target devices.
100 } AppEventType;
101
102 static int AppEventConverter[APPCORE_BASE_EVENT_MAX] =
103   {
104     [LOW_MEMORY]                 = APPCORE_BASE_EVENT_LOW_MEMORY,
105     [LOW_BATTERY]                = APPCORE_BASE_EVENT_LOW_BATTERY,
106     [LANGUAGE_CHANGED]           = APPCORE_BASE_EVENT_LANG_CHANGE,
107     [DEVICE_ORIENTATION_CHANGED] = APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED,
108     [REGION_FORMAT_CHANGED]      = APPCORE_BASE_EVENT_REGION_CHANGE,
109     [SUSPENDED_STATE_CHANGED]    = APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE,
110 };
111
112 struct AppEventInfo
113 {
114   AppEventType type;
115   void*        value;
116 };
117
118 typedef struct AppEventInfo* AppEventInfoPtr;
119
120 typedef void (*AppEventCallback)(AppEventInfoPtr eventInfo, void* userData);
121
122 struct AppEventHandler
123 {
124   AppEventType     type;
125   AppEventCallback cb;
126   void*            data;
127   void*            raw;
128 };
129
130 typedef struct AppEventHandler* AppEventHandlerPtr;
131
132 int EventCallback(void* event, void* data)
133 {
134   AppEventHandlerPtr handler = static_cast<AppEventHandlerPtr>(data);
135
136   struct AppEventInfo appEvent;
137
138   appEvent.type  = handler->type;
139   appEvent.value = event;
140
141   if(handler->cb)
142     handler->cb(&appEvent, handler->data);
143
144   return 0;
145 }
146
147 int AppAddEventHandler(AppEventHandlerPtr* eventHandler, AppEventType eventType, AppEventCallback callback, void* userData)
148 {
149   AppEventHandlerPtr handler;
150
151   handler = static_cast<AppEventHandlerPtr>(calloc(1, sizeof(struct AppEventHandler)));
152   if(!handler)
153   {
154     DALI_LOG_ERROR("failed to create handler");
155     return TIZEN_ERROR_UNKNOWN;
156   }
157   else
158   {
159     handler->type = eventType;
160     handler->cb   = callback;
161     handler->data = userData;
162     handler->raw  = appcore_base_add_event(static_cast<appcore_base_event>(AppEventConverter[static_cast<int>(eventType)]), EventCallback, handler);
163
164     *eventHandler = handler;
165
166     return TIZEN_ERROR_NONE;
167   }
168 }
169
170 } // namespace AppCore
171
172 /**
173  * Impl to hide EFL data members
174  */
175 struct Framework::Impl
176 {
177   // Constructor
178   Impl(void* data, Type type)
179   : mAbortCallBack(NULL),
180     mCallbackManager(NULL)
181 #ifdef APPCORE_WATCH_AVAILABLE
182     ,
183     mWatchCallback()
184 #endif
185   {
186     mFramework = static_cast<Framework*>(data);
187
188 #ifndef APPCORE_WATCH_AVAILABLE
189     if(type == WATCH)
190     {
191       throw Dali::DaliException("", "Watch Application is not supported.");
192     }
193 #endif
194     mApplicationType = type;
195     mCallbackManager = CallbackManager::New();
196
197     char* region   = nullptr;
198     char* language = nullptr;
199     system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY, &region);
200     system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &language);
201
202     if(region != nullptr)
203     {
204       mRegion = std::string(region);
205       free(region);
206     }
207
208     if(language != nullptr)
209     {
210       mLanguage = std::string(language);
211       free(language);
212     }
213   }
214
215   ~Impl()
216   {
217     delete mAbortCallBack;
218
219     // we're quiting the main loop so
220     // mCallbackManager->RemoveAllCallBacks() does not need to be called
221     // to delete our abort handler
222     delete mCallbackManager;
223   }
224
225   int AppMain()
226   {
227     int ret;
228     switch(mApplicationType)
229     {
230       case NORMAL:
231       {
232         ret = AppNormalMain();
233         break;
234       }
235       case WIDGET:
236       {
237         ret = AppWidgetMain();
238         break;
239       }
240       case WATCH:
241       {
242         ret = AppWatchMain();
243         break;
244       }
245 #ifdef COMPONENT_APPLICATION_SUPPORT
246       case COMPONENT:
247       {
248         ret = AppComponentMain();
249         break;
250       }
251 #endif
252     }
253     return ret;
254   }
255
256   void AppExit()
257   {
258     switch(mApplicationType)
259     {
260       case NORMAL:
261       {
262         AppNormalExit();
263         break;
264       }
265       case WIDGET:
266       {
267         AppWidgetExit();
268         break;
269       }
270       case WATCH:
271       {
272         AppWatchExit();
273         break;
274       }
275 #ifdef COMPONENT_APPLICATION_SUPPORT
276       case COMPONENT:
277       {
278         AppComponentExit();
279         break;
280       }
281 #endif
282     }
283   }
284
285   void SetLanguage(const std::string& language)
286   {
287     mLanguage = language;
288   }
289
290   void SetRegion(const std::string& region)
291   {
292     mRegion = region;
293   }
294
295   std::string GetLanguage() const
296   {
297     return mLanguage;
298   }
299
300   std::string GetRegion() const
301   {
302     return mRegion;
303   }
304
305   // Data
306   Type             mApplicationType;
307   CallbackBase*    mAbortCallBack;
308   CallbackManager* mCallbackManager;
309   std::string      mLanguage;
310   std::string      mRegion;
311
312   Framework*                  mFramework;
313   AppCore::AppEventHandlerPtr handlers[5];
314 #ifdef APPCORE_WATCH_AVAILABLE
315   watch_app_lifecycle_callback_s mWatchCallback;
316   app_event_handler_h            watchHandlers[5];
317 #endif
318
319   static int AppCreate(void* data)
320   {
321     appcore_ui_base_on_create();
322     return static_cast<int>(static_cast<Framework*>(data)->Create());
323   }
324
325   static int AppTerminate(void* data)
326   {
327     appcore_ui_base_on_terminate();
328     Observer* observer = &static_cast<Framework*>(data)->mObserver;
329
330     observer->OnTerminate();
331
332     return 0;
333   }
334
335   static int AppPause(void* data)
336   {
337     appcore_ui_base_on_pause();
338     Observer* observer = &static_cast<Framework*>(data)->mObserver;
339
340     observer->OnPause();
341
342     return 0;
343   }
344
345   static int AppResume(void* data)
346   {
347     appcore_ui_base_on_resume();
348     Observer* observer = &static_cast<Framework*>(data)->mObserver;
349
350     observer->OnResume();
351
352     return 0;
353   }
354
355   static void ProcessBundle(Framework* framework, bundle* bundleData)
356   {
357     if(bundleData == NULL)
358     {
359       return;
360     }
361
362     // get bundle name
363     char* bundleName = const_cast<char*>(bundle_get_val(bundleData, "name"));
364     if(bundleName != NULL)
365     {
366       framework->SetBundleName(bundleName);
367     }
368
369     // get bundle? id
370     char* bundleId = const_cast<char*>(bundle_get_val(bundleData, "id"));
371     if(bundleId != NULL)
372     {
373       framework->SetBundleId(bundleId);
374     }
375   }
376
377   /**
378    * Called by AppCore when the application is launched from another module (e.g. homescreen).
379    * @param[in] b the bundle data which the launcher module sent
380    */
381   static int AppControl(bundle* bundleData, void* data)
382   {
383     app_control_h appControl = NULL;
384
385     appcore_ui_base_on_control(bundleData);
386
387     if(bundleData)
388     {
389       if(app_control_create_event(bundleData, &appControl) != TIZEN_ERROR_NONE)
390       {
391         DALI_LOG_ERROR("Failed to create an app_control handle");
392       }
393     }
394     else
395     {
396       if(app_control_create(&appControl) != TIZEN_ERROR_NONE)
397       {
398         DALI_LOG_ERROR("Failed to create an app_control handle");
399       }
400     }
401
402     Framework* framework = static_cast<Framework*>(data);
403     Observer*  observer  = &framework->mObserver;
404
405     ProcessBundle(framework, bundleData);
406
407     observer->OnReset();
408     observer->OnAppControl(appControl);
409
410     app_control_destroy(appControl);
411
412     return 0;
413   }
414
415   static void AppInit(int argc, char** argv, void* data)
416   {
417 #pragma GCC diagnostic push
418 #pragma GCC diagnostic ignored "-Wold-style-cast"
419
420     ecore_init();
421     ecore_app_args_set(argc, (const char**)argv);
422
423 #pragma GCC diagnostic pop
424   }
425
426   static void AppFinish(void)
427   {
428     ecore_shutdown();
429
430     if(getenv("AUL_LOADER_INIT"))
431     {
432       setenv("AUL_LOADER_INIT", "0", 1);
433       ecore_shutdown();
434     }
435   }
436
437   static void AppRun(void* data)
438   {
439     ecore_main_loop_begin();
440   }
441
442   static void AppExit(void* data)
443   {
444     ecore_main_loop_quit();
445   }
446
447   static void AppLanguageChanged(AppCore::AppEventInfoPtr event, void* data)
448   {
449     Framework* framework = static_cast<Framework*>(data);
450     Observer*  observer  = &framework->mObserver;
451
452     if(event && event->value)
453     {
454       framework->SetLanguage(std::string(static_cast<const char*>(event->value)));
455       observer->OnLanguageChanged();
456     }
457     else
458     {
459       DALI_LOG_ERROR("NULL pointer in Language changed event\n");
460     }
461   }
462
463   static void AppDeviceRotated(AppCore::AppEventInfoPtr event_info, void* data)
464   {
465   }
466
467   static void AppRegionChanged(AppCore::AppEventInfoPtr event, void* data)
468   {
469     Framework* framework = static_cast<Framework*>(data);
470     Observer*  observer  = &framework->mObserver;
471
472     if(event && event->value)
473     {
474       framework->SetRegion(std::string(static_cast<const char*>(event->value)));
475       observer->OnRegionChanged();
476     }
477     else
478     {
479       DALI_LOG_ERROR("NULL pointer in Region changed event\n");
480     }
481   }
482
483   static void AppBatteryLow(AppCore::AppEventInfoPtr event, void* data)
484   {
485     Observer*                           observer = &static_cast<Framework*>(data)->mObserver;
486     int                                 status   = *static_cast<int*>(event->value);
487     Dali::DeviceStatus::Battery::Status result   = Dali::DeviceStatus::Battery::NORMAL;
488
489     // convert to dali battery status
490     switch(status)
491     {
492       case 1:
493       {
494         result = Dali::DeviceStatus::Battery::POWER_OFF;
495         break;
496       }
497       case 2:
498       {
499         result = Dali::DeviceStatus::Battery::CRITICALLY_LOW;
500         break;
501       }
502       default:
503         break;
504     }
505     observer->OnBatteryLow(result);
506   }
507
508   static void AppMemoryLow(AppCore::AppEventInfoPtr event, void* data)
509   {
510     Observer*                          observer = &static_cast<Framework*>(data)->mObserver;
511     int                                status   = *static_cast<int*>(event->value);
512     Dali::DeviceStatus::Memory::Status result   = Dali::DeviceStatus::Memory::NORMAL;
513
514     // convert to dali memmory status
515     switch(status)
516     {
517       case 1:
518       {
519         result = Dali::DeviceStatus::Memory::NORMAL;
520         break;
521       }
522       case 2:
523       {
524         result = Dali::DeviceStatus::Memory::LOW;
525         break;
526       }
527       case 4:
528       {
529         result = Dali::DeviceStatus::Memory::CRITICALLY_LOW;
530         break;
531       }
532       default:
533         break;
534     }
535     observer->OnMemoryLow(result);
536   }
537
538   int AppNormalMain()
539   {
540     int ret;
541
542     AppCore::AppAddEventHandler(&handlers[AppCore::LOW_BATTERY], AppCore::LOW_BATTERY, AppBatteryLow, mFramework);
543     AppCore::AppAddEventHandler(&handlers[AppCore::LOW_MEMORY], AppCore::LOW_MEMORY, AppMemoryLow, mFramework);
544     AppCore::AppAddEventHandler(&handlers[AppCore::DEVICE_ORIENTATION_CHANGED], AppCore::DEVICE_ORIENTATION_CHANGED, AppDeviceRotated, mFramework);
545     AppCore::AppAddEventHandler(&handlers[AppCore::LANGUAGE_CHANGED], AppCore::LANGUAGE_CHANGED, AppLanguageChanged, mFramework);
546     AppCore::AppAddEventHandler(&handlers[AppCore::REGION_FORMAT_CHANGED], AppCore::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework);
547
548     appcore_ui_base_ops ops = appcore_ui_base_get_default_ops();
549
550     /* override methods */
551     ops.base.create    = AppCreate;
552     ops.base.control   = AppControl;
553     ops.base.terminate = AppTerminate;
554     ops.pause          = AppPause;
555     ops.resume         = AppResume;
556     ops.base.init      = AppInit;
557     ops.base.finish    = AppFinish;
558     ops.base.run       = AppRun;
559     ops.base.exit      = AppExit;
560
561     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);
562
563     if(ret != TIZEN_ERROR_NONE)
564       return ret;
565
566     appcore_ui_base_fini();
567
568     return TIZEN_ERROR_NONE;
569   }
570
571   void AppNormalExit()
572   {
573     appcore_ui_base_exit();
574   }
575
576   void AppWidgetExit()
577   {
578     widget_base_exit();
579   }
580
581   static int WidgetAppCreate(void* data)
582   {
583     widget_base_on_create();
584     return static_cast<int>(static_cast<Framework*>(data)->Create());
585   }
586
587   static int WidgetAppTerminate(void* data)
588   {
589     Observer* observer = &static_cast<Framework*>(data)->mObserver;
590     observer->OnTerminate();
591
592     widget_base_on_terminate();
593     return 0;
594   }
595
596   int AppWidgetMain()
597   {
598     if(!IsWidgetFeatureEnabled())
599     {
600       DALI_LOG_ERROR("widget feature is not supported");
601       return 0;
602     }
603
604     AppCore::AppAddEventHandler(&handlers[AppCore::LOW_BATTERY], AppCore::LOW_BATTERY, AppBatteryLow, mFramework);
605     AppCore::AppAddEventHandler(&handlers[AppCore::LOW_MEMORY], AppCore::LOW_MEMORY, AppMemoryLow, mFramework);
606     AppCore::AppAddEventHandler(&handlers[AppCore::DEVICE_ORIENTATION_CHANGED], AppCore::DEVICE_ORIENTATION_CHANGED, AppDeviceRotated, mFramework);
607     AppCore::AppAddEventHandler(&handlers[AppCore::LANGUAGE_CHANGED], AppCore::LANGUAGE_CHANGED, AppLanguageChanged, mFramework);
608     AppCore::AppAddEventHandler(&handlers[AppCore::REGION_FORMAT_CHANGED], AppCore::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework);
609
610     widget_base_ops ops = widget_base_get_default_ops();
611
612     /* override methods */
613     ops.create    = WidgetAppCreate;
614     ops.terminate = WidgetAppTerminate;
615     ops.init      = AppInit;
616     ops.finish    = AppFinish;
617     ops.run       = AppRun;
618     ops.exit      = AppExit;
619
620     int result = widget_base_init(ops, *mFramework->mArgc, *mFramework->mArgv, mFramework);
621
622     widget_base_fini();
623
624     return result;
625   }
626
627 #ifdef APPCORE_WATCH_AVAILABLE
628   static bool WatchAppCreate(int width, int height, void* data)
629   {
630     return static_cast<Framework*>(data)->Create();
631   }
632
633   static void WatchAppTimeTick(watch_time_h time, void* data)
634   {
635     Observer* observer = &static_cast<Framework*>(data)->mObserver;
636     WatchTime curTime(time);
637
638     observer->OnTimeTick(curTime);
639   }
640
641   static void WatchAppAmbientTick(watch_time_h time, void* data)
642   {
643     Observer* observer = &static_cast<Framework*>(data)->mObserver;
644     WatchTime curTime(time);
645
646     observer->OnAmbientTick(curTime);
647   }
648
649   static void WatchAppAmbientChanged(bool ambient, void* data)
650   {
651     Observer* observer = &static_cast<Framework*>(data)->mObserver;
652
653     observer->OnAmbientChanged(ambient);
654   }
655
656   static void WatchAppControl(app_control_h app_control, void* data)
657   {
658     Framework* framework  = static_cast<Framework*>(data);
659     Observer*  observer   = &framework->mObserver;
660     bundle*    bundleData = NULL;
661
662     app_control_to_bundle(app_control, &bundleData);
663     ProcessBundle(framework, bundleData);
664
665     observer->OnReset();
666     observer->OnAppControl(app_control);
667   }
668
669   static void WatchAppTerminate(void* data)
670   {
671     Observer* observer = &static_cast<Framework*>(data)->mObserver;
672
673     observer->OnTerminate();
674   }
675
676   static void WatchAppPause(void* data)
677   {
678     Observer* observer = &static_cast<Framework*>(data)->mObserver;
679
680     observer->OnPause();
681   }
682
683   static void WatchAppResume(void* data)
684   {
685     Observer* observer = &static_cast<Framework*>(data)->mObserver;
686
687     observer->OnResume();
688   }
689
690 #endif
691
692   int AppWatchMain()
693   {
694     int ret = true;
695
696 #ifdef APPCORE_WATCH_AVAILABLE
697     mWatchCallback.create          = WatchAppCreate;
698     mWatchCallback.app_control     = WatchAppControl;
699     mWatchCallback.terminate       = WatchAppTerminate;
700     mWatchCallback.pause           = WatchAppPause;
701     mWatchCallback.resume          = WatchAppResume;
702     mWatchCallback.time_tick       = WatchAppTimeTick;
703     mWatchCallback.ambient_tick    = WatchAppAmbientTick;
704     mWatchCallback.ambient_changed = WatchAppAmbientChanged;
705
706     AppCore::AppAddEventHandler(&handlers[AppCore::LOW_BATTERY], AppCore::LOW_BATTERY, AppBatteryLow, mFramework);
707     AppCore::AppAddEventHandler(&handlers[AppCore::LOW_MEMORY], AppCore::LOW_MEMORY, AppMemoryLow, mFramework);
708     AppCore::AppAddEventHandler(&handlers[AppCore::LANGUAGE_CHANGED], AppCore::LANGUAGE_CHANGED, AppLanguageChanged, mFramework);
709     AppCore::AppAddEventHandler(&handlers[AppCore::REGION_FORMAT_CHANGED], AppCore::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework);
710
711     ret = watch_app_main(*mFramework->mArgc, *mFramework->mArgv, &mWatchCallback, mFramework);
712 #endif
713     return ret;
714   }
715
716   void AppWatchExit()
717   {
718 #ifdef APPCORE_WATCH_AVAILABLE
719     watch_app_exit();
720 #endif
721   }
722
723 #ifdef COMPONENT_APPLICATION_SUPPORT
724   int AppComponentMain()
725   {
726     /*Crate component_based_app_base_lifecycle_callback*/
727     component_based_app_base_lifecycle_callback_s callback;
728     callback.init      = AppInit;
729     callback.run       = AppRun;
730     callback.exit      = AppExit;
731     callback.create    = ComponentAppCreate;
732     callback.terminate = ComponentAppTerminate;
733     callback.fini      = ComponentAppFinish;
734
735     return component_based_app_base_main(*mFramework->mArgc, *mFramework->mArgv, &callback, mFramework);
736     ;
737   }
738
739   static void* ComponentAppCreate(void* data)
740   {
741     Framework* framework = static_cast<Framework*>(data);
742     Observer*  observer  = &framework->mObserver;
743     observer->OnInit();
744
745     return Dali::AnyCast<void*>(observer->OnCreate());
746   }
747
748   static void ComponentAppTerminate(void* data)
749   {
750     Observer* observer = &static_cast<Framework*>(data)->mObserver;
751     observer->OnTerminate();
752   }
753
754   static void ComponentAppFinish(void* data)
755   {
756     ecore_shutdown();
757
758     if(getenv("AUL_LOADER_INIT"))
759     {
760       setenv("AUL_LOADER_INIT", "0", 1);
761       ecore_shutdown();
762     }
763   }
764
765   void AppComponentExit()
766   {
767     component_based_app_base_exit();
768   }
769
770 #endif
771
772 private:
773   // Undefined
774   Impl(const Impl& impl);
775
776   // Undefined
777   Impl& operator=(const Impl& impl);
778 };
779
780 Framework::Framework(Framework::Observer& observer, int* argc, char*** argv, Type type)
781 : mObserver(observer),
782   mInitialised(false),
783   mPaused(false),
784   mRunning(false),
785   mArgc(argc),
786   mArgv(argv),
787   mBundleName(""),
788   mBundleId(""),
789   mAbortHandler(MakeCallback(this, &Framework::AbortCallback)),
790   mImpl(NULL)
791 {
792   bool featureFlag = true;
793   system_info_get_platform_bool("tizen.org/feature/opengles.version.2_0", &featureFlag);
794
795   if(featureFlag == false)
796   {
797     set_last_result(TIZEN_ERROR_NOT_SUPPORTED);
798   }
799 #ifdef DALI_ELDBUS_AVAILABLE
800   // Initialize ElDBus.
801   DALI_LOG_INFO(gDBusLogging, Debug::General, "Starting DBus Initialization\n");
802   eldbus_init();
803 #endif
804   InitThreads();
805
806   mImpl = new Impl(this, type);
807 }
808
809 Framework::~Framework()
810 {
811   if(mRunning)
812   {
813     Quit();
814   }
815
816 #ifdef DALI_ELDBUS_AVAILABLE
817   // Shutdown ELDBus.
818   DALI_LOG_INFO(gDBusLogging, Debug::General, "Shutting down DBus\n");
819   eldbus_shutdown();
820 #endif
821
822   delete mImpl;
823 }
824
825 bool Framework::Create()
826 {
827   mInitialised = true;
828   mObserver.OnInit();
829   return true;
830 }
831
832 void Framework::Run()
833 {
834   mRunning = true;
835   int ret;
836
837   ret = mImpl->AppMain();
838   if(ret != APP_ERROR_NONE)
839   {
840     DALI_LOG_ERROR("Framework::Run(), ui_app_main() is failed. err = %d\n", ret);
841   }
842   mRunning = false;
843 }
844
845 void Framework::Quit()
846 {
847   mImpl->AppExit();
848 }
849
850 bool Framework::IsMainLoopRunning()
851 {
852   return mRunning;
853 }
854
855 void Framework::AddAbortCallback(CallbackBase* callback)
856 {
857   mImpl->mAbortCallBack = callback;
858 }
859
860 std::string Framework::GetBundleName() const
861 {
862   return mBundleName;
863 }
864
865 void Framework::SetBundleName(const std::string& name)
866 {
867   mBundleName = name;
868 }
869
870 std::string Framework::GetBundleId() const
871 {
872   return mBundleId;
873 }
874
875 std::string Framework::GetResourcePath()
876 {
877   std::string resourcePath = "";
878 #if defined(TIZEN_PLATFORM_CONFIG_SUPPORTED) && TIZEN_PLATFORM_CONFIG_SUPPORTED
879   char* app_rsc_path = app_get_resource_path();
880   if(app_rsc_path)
881   {
882     resourcePath = app_rsc_path;
883     free(app_rsc_path);
884   }
885 #else // For backwards compatibility with older Tizen versions
886
887   // "DALI_APPLICATION_PACKAGE" is used to get the already configured Application package path.
888   const char* environmentVariable = "DALI_APPLICATION_PACKAGE";
889   char*       value               = getenv(environmentVariable);
890   if(value != NULL)
891   {
892     resourcePath = value;
893   }
894
895   if(resourcePath.back() != '/')
896   {
897     resourcePath += "/";
898   }
899
900 #endif //TIZEN_PLATFORM_CONFIG_SUPPORTED
901
902   return resourcePath;
903 }
904
905 std::string Framework::GetDataPath()
906 {
907   std::string result;
908   char*       dataPath = app_get_data_path();
909   if(dataPath)
910   {
911     result = dataPath;
912     free(dataPath);
913   }
914   return result;
915 }
916
917 void Framework::SetBundleId(const std::string& id)
918 {
919   mBundleId = id;
920 }
921
922 void Framework::AbortCallback()
923 {
924   // if an abort call back has been installed run it.
925   if(mImpl->mAbortCallBack)
926   {
927     CallbackBase::Execute(*mImpl->mAbortCallBack);
928   }
929   else
930   {
931     Quit();
932   }
933 }
934
935 void Framework::InitThreads()
936 {
937 }
938
939 void Framework::SetLanguage(const std::string& language)
940 {
941   mImpl->SetLanguage(language);
942 }
943
944 void Framework::SetRegion(const std::string& region)
945 {
946   mImpl->SetRegion(region);
947 }
948
949 std::string Framework::GetLanguage() const
950 {
951   return mImpl->GetLanguage();
952 }
953
954 std::string Framework::GetRegion() const
955 {
956   return mImpl->GetRegion();
957 }
958
959 } // namespace Adaptor
960
961 } // namespace Internal
962
963 } // namespace Dali