[Tizen] Change timing to get system values when needed
[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
198   ~Impl()
199   {
200     delete mAbortCallBack;
201
202     // we're quiting the main loop so
203     // mCallbackManager->RemoveAllCallBacks() does not need to be called
204     // to delete our abort handler
205     delete mCallbackManager;
206   }
207
208   int AppMain()
209   {
210     int ret;
211     switch(mApplicationType)
212     {
213       case NORMAL:
214       {
215         ret = AppNormalMain();
216         break;
217       }
218       case WIDGET:
219       {
220         ret = AppWidgetMain();
221         break;
222       }
223       case WATCH:
224       {
225         ret = AppWatchMain();
226         break;
227       }
228 #ifdef COMPONENT_APPLICATION_SUPPORT
229       case COMPONENT:
230       {
231         ret = AppComponentMain();
232         break;
233       }
234 #endif
235     }
236     return ret;
237   }
238
239   void AppExit()
240   {
241     switch(mApplicationType)
242     {
243       case NORMAL:
244       {
245         AppNormalExit();
246         break;
247       }
248       case WIDGET:
249       {
250         AppWidgetExit();
251         break;
252       }
253       case WATCH:
254       {
255         AppWatchExit();
256         break;
257       }
258 #ifdef COMPONENT_APPLICATION_SUPPORT
259       case COMPONENT:
260       {
261         AppComponentExit();
262         break;
263       }
264 #endif
265     }
266   }
267
268   void SetLanguage(const std::string& language)
269   {
270     mLanguage = language;
271   }
272
273   void SetRegion(const std::string& region)
274   {
275     mRegion = region;
276   }
277
278   std::string GetLanguage()
279   {
280     if(mLanguage.empty())
281     {
282       char* language = nullptr;
283       system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &language);
284
285       if(language != nullptr)
286       {
287         mLanguage = std::string(language);
288         free(language);
289       }
290     }
291     return mLanguage;
292   }
293
294   std::string GetRegion()
295   {
296     if(mRegion.empty())
297     {
298       char* region = nullptr;
299       system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY, &region);
300
301       if(region != nullptr)
302       {
303         mRegion = std::string(region);
304         free(region);
305       }
306     }
307     return mRegion;
308   }
309
310   // Data
311   Type             mApplicationType;
312   CallbackBase*    mAbortCallBack;
313   CallbackManager* mCallbackManager;
314   std::string      mLanguage{};
315   std::string      mRegion{};
316
317   Framework*                  mFramework;
318   AppCore::AppEventHandlerPtr handlers[5];
319 #ifdef APPCORE_WATCH_AVAILABLE
320   watch_app_lifecycle_callback_s mWatchCallback;
321   app_event_handler_h            watchHandlers[5];
322 #endif
323
324   static int AppCreate(void* data)
325   {
326     appcore_ui_base_on_create();
327     return static_cast<int>(static_cast<Framework*>(data)->Create());
328   }
329
330   static int AppTerminate(void* data)
331   {
332     appcore_ui_base_on_terminate();
333     Observer* observer = &static_cast<Framework*>(data)->mObserver;
334
335     observer->OnTerminate();
336
337     return 0;
338   }
339
340   static int AppPause(void* data)
341   {
342     appcore_ui_base_on_pause();
343     Observer* observer = &static_cast<Framework*>(data)->mObserver;
344
345     observer->OnPause();
346
347     return 0;
348   }
349
350   static int AppResume(void* data)
351   {
352     appcore_ui_base_on_resume();
353     Observer* observer = &static_cast<Framework*>(data)->mObserver;
354
355     observer->OnResume();
356
357     return 0;
358   }
359
360   static void ProcessBundle(Framework* framework, bundle* bundleData)
361   {
362     if(bundleData == NULL)
363     {
364       return;
365     }
366
367     // get bundle name
368     char* bundleName = const_cast<char*>(bundle_get_val(bundleData, "name"));
369     if(bundleName != NULL)
370     {
371       framework->SetBundleName(bundleName);
372     }
373
374     // get bundle? id
375     char* bundleId = const_cast<char*>(bundle_get_val(bundleData, "id"));
376     if(bundleId != NULL)
377     {
378       framework->SetBundleId(bundleId);
379     }
380   }
381
382   /**
383    * Called by AppCore when the application is launched from another module (e.g. homescreen).
384    * @param[in] b the bundle data which the launcher module sent
385    */
386   static int AppControl(bundle* bundleData, void* data)
387   {
388     app_control_h appControl = NULL;
389
390     appcore_ui_base_on_control(bundleData);
391
392     if(bundleData)
393     {
394       if(app_control_create_event(bundleData, &appControl) != TIZEN_ERROR_NONE)
395       {
396         DALI_LOG_ERROR("Failed to create an app_control handle");
397       }
398     }
399     else
400     {
401       if(app_control_create(&appControl) != TIZEN_ERROR_NONE)
402       {
403         DALI_LOG_ERROR("Failed to create an app_control handle");
404       }
405     }
406
407     Framework* framework = static_cast<Framework*>(data);
408     Observer*  observer  = &framework->mObserver;
409
410     ProcessBundle(framework, bundleData);
411
412     observer->OnReset();
413     observer->OnAppControl(appControl);
414
415     app_control_destroy(appControl);
416
417     return 0;
418   }
419
420   static void AppInit(int argc, char** argv, void* data)
421   {
422 #pragma GCC diagnostic push
423 #pragma GCC diagnostic ignored "-Wold-style-cast"
424
425     ecore_init();
426     ecore_app_args_set(argc, (const char**)argv);
427
428 #pragma GCC diagnostic pop
429   }
430
431   static void AppFinish(void)
432   {
433     ecore_shutdown();
434
435     if(getenv("AUL_LOADER_INIT"))
436     {
437       setenv("AUL_LOADER_INIT", "0", 1);
438       ecore_shutdown();
439     }
440   }
441
442   static void AppRun(void* data)
443   {
444     ecore_main_loop_begin();
445   }
446
447   static void AppExit(void* data)
448   {
449     ecore_main_loop_quit();
450   }
451
452   static void AppLanguageChanged(AppCore::AppEventInfoPtr event, void* data)
453   {
454     Framework* framework = static_cast<Framework*>(data);
455     Observer*  observer  = &framework->mObserver;
456
457     if(event && event->value)
458     {
459       framework->SetLanguage(std::string(static_cast<const char*>(event->value)));
460       observer->OnLanguageChanged();
461     }
462     else
463     {
464       DALI_LOG_ERROR("NULL pointer in Language changed event\n");
465     }
466   }
467
468   static void AppDeviceRotated(AppCore::AppEventInfoPtr event_info, void* data)
469   {
470   }
471
472   static void AppRegionChanged(AppCore::AppEventInfoPtr event, void* data)
473   {
474     Framework* framework = static_cast<Framework*>(data);
475     Observer*  observer  = &framework->mObserver;
476
477     if(event && event->value)
478     {
479       framework->SetRegion(std::string(static_cast<const char*>(event->value)));
480       observer->OnRegionChanged();
481     }
482     else
483     {
484       DALI_LOG_ERROR("NULL pointer in Region changed event\n");
485     }
486   }
487
488   static void AppBatteryLow(AppCore::AppEventInfoPtr event, void* data)
489   {
490     Observer*                           observer = &static_cast<Framework*>(data)->mObserver;
491     int                                 status   = *static_cast<int*>(event->value);
492     Dali::DeviceStatus::Battery::Status result   = Dali::DeviceStatus::Battery::NORMAL;
493
494     // convert to dali battery status
495     switch(status)
496     {
497       case 1:
498       {
499         result = Dali::DeviceStatus::Battery::POWER_OFF;
500         break;
501       }
502       case 2:
503       {
504         result = Dali::DeviceStatus::Battery::CRITICALLY_LOW;
505         break;
506       }
507       default:
508         break;
509     }
510     observer->OnBatteryLow(result);
511   }
512
513   static void AppMemoryLow(AppCore::AppEventInfoPtr event, void* data)
514   {
515     Observer*                          observer = &static_cast<Framework*>(data)->mObserver;
516     int                                status   = *static_cast<int*>(event->value);
517     Dali::DeviceStatus::Memory::Status result   = Dali::DeviceStatus::Memory::NORMAL;
518
519     // convert to dali memmory status
520     switch(status)
521     {
522       case 1:
523       {
524         result = Dali::DeviceStatus::Memory::NORMAL;
525         break;
526       }
527       case 2:
528       {
529         result = Dali::DeviceStatus::Memory::LOW;
530         break;
531       }
532       case 4:
533       {
534         result = Dali::DeviceStatus::Memory::CRITICALLY_LOW;
535         break;
536       }
537       default:
538         break;
539     }
540     observer->OnMemoryLow(result);
541   }
542
543   int AppNormalMain()
544   {
545     int ret;
546
547     AppCore::AppAddEventHandler(&handlers[AppCore::LOW_BATTERY], AppCore::LOW_BATTERY, AppBatteryLow, mFramework);
548     AppCore::AppAddEventHandler(&handlers[AppCore::LOW_MEMORY], AppCore::LOW_MEMORY, AppMemoryLow, mFramework);
549     AppCore::AppAddEventHandler(&handlers[AppCore::DEVICE_ORIENTATION_CHANGED], AppCore::DEVICE_ORIENTATION_CHANGED, AppDeviceRotated, mFramework);
550     AppCore::AppAddEventHandler(&handlers[AppCore::LANGUAGE_CHANGED], AppCore::LANGUAGE_CHANGED, AppLanguageChanged, mFramework);
551     AppCore::AppAddEventHandler(&handlers[AppCore::REGION_FORMAT_CHANGED], AppCore::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework);
552
553     appcore_ui_base_ops ops = appcore_ui_base_get_default_ops();
554
555     /* override methods */
556     ops.base.create    = AppCreate;
557     ops.base.control   = AppControl;
558     ops.base.terminate = AppTerminate;
559     ops.pause          = AppPause;
560     ops.resume         = AppResume;
561     ops.base.init      = AppInit;
562     ops.base.finish    = AppFinish;
563     ops.base.run       = AppRun;
564     ops.base.exit      = AppExit;
565
566     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);
567
568     if(ret != TIZEN_ERROR_NONE)
569       return ret;
570
571     appcore_ui_base_fini();
572
573     return TIZEN_ERROR_NONE;
574   }
575
576   void AppNormalExit()
577   {
578     appcore_ui_base_exit();
579   }
580
581   void AppWidgetExit()
582   {
583     widget_base_exit();
584   }
585
586   static int WidgetAppCreate(void* data)
587   {
588     widget_base_on_create();
589     return static_cast<int>(static_cast<Framework*>(data)->Create());
590   }
591
592   static int WidgetAppTerminate(void* data)
593   {
594     Observer* observer = &static_cast<Framework*>(data)->mObserver;
595     observer->OnTerminate();
596
597     widget_base_on_terminate();
598     return 0;
599   }
600
601   int AppWidgetMain()
602   {
603     if(!IsWidgetFeatureEnabled())
604     {
605       DALI_LOG_ERROR("widget feature is not supported");
606       return 0;
607     }
608
609     AppCore::AppAddEventHandler(&handlers[AppCore::LOW_BATTERY], AppCore::LOW_BATTERY, AppBatteryLow, mFramework);
610     AppCore::AppAddEventHandler(&handlers[AppCore::LOW_MEMORY], AppCore::LOW_MEMORY, AppMemoryLow, mFramework);
611     AppCore::AppAddEventHandler(&handlers[AppCore::DEVICE_ORIENTATION_CHANGED], AppCore::DEVICE_ORIENTATION_CHANGED, AppDeviceRotated, mFramework);
612     AppCore::AppAddEventHandler(&handlers[AppCore::LANGUAGE_CHANGED], AppCore::LANGUAGE_CHANGED, AppLanguageChanged, mFramework);
613     AppCore::AppAddEventHandler(&handlers[AppCore::REGION_FORMAT_CHANGED], AppCore::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework);
614
615     widget_base_ops ops = widget_base_get_default_ops();
616
617     /* override methods */
618     ops.create    = WidgetAppCreate;
619     ops.terminate = WidgetAppTerminate;
620     ops.init      = AppInit;
621     ops.finish    = AppFinish;
622     ops.run       = AppRun;
623     ops.exit      = AppExit;
624
625     int result = widget_base_init(ops, *mFramework->mArgc, *mFramework->mArgv, mFramework);
626
627     widget_base_fini();
628
629     return result;
630   }
631
632 #ifdef APPCORE_WATCH_AVAILABLE
633   static bool WatchAppCreate(int width, int height, void* data)
634   {
635     return static_cast<Framework*>(data)->Create();
636   }
637
638   static void WatchAppTimeTick(watch_time_h time, void* data)
639   {
640     Observer* observer = &static_cast<Framework*>(data)->mObserver;
641     WatchTime curTime(time);
642
643     observer->OnTimeTick(curTime);
644   }
645
646   static void WatchAppAmbientTick(watch_time_h time, void* data)
647   {
648     Observer* observer = &static_cast<Framework*>(data)->mObserver;
649     WatchTime curTime(time);
650
651     observer->OnAmbientTick(curTime);
652   }
653
654   static void WatchAppAmbientChanged(bool ambient, void* data)
655   {
656     Observer* observer = &static_cast<Framework*>(data)->mObserver;
657
658     observer->OnAmbientChanged(ambient);
659   }
660
661   static void WatchAppControl(app_control_h app_control, void* data)
662   {
663     Framework* framework  = static_cast<Framework*>(data);
664     Observer*  observer   = &framework->mObserver;
665     bundle*    bundleData = NULL;
666
667     app_control_to_bundle(app_control, &bundleData);
668     ProcessBundle(framework, bundleData);
669
670     observer->OnReset();
671     observer->OnAppControl(app_control);
672   }
673
674   static void WatchAppTerminate(void* data)
675   {
676     Observer* observer = &static_cast<Framework*>(data)->mObserver;
677
678     observer->OnTerminate();
679   }
680
681   static void WatchAppPause(void* data)
682   {
683     Observer* observer = &static_cast<Framework*>(data)->mObserver;
684
685     observer->OnPause();
686   }
687
688   static void WatchAppResume(void* data)
689   {
690     Observer* observer = &static_cast<Framework*>(data)->mObserver;
691
692     observer->OnResume();
693   }
694
695 #endif
696
697   int AppWatchMain()
698   {
699     int ret = true;
700
701 #ifdef APPCORE_WATCH_AVAILABLE
702     mWatchCallback.create          = WatchAppCreate;
703     mWatchCallback.app_control     = WatchAppControl;
704     mWatchCallback.terminate       = WatchAppTerminate;
705     mWatchCallback.pause           = WatchAppPause;
706     mWatchCallback.resume          = WatchAppResume;
707     mWatchCallback.time_tick       = WatchAppTimeTick;
708     mWatchCallback.ambient_tick    = WatchAppAmbientTick;
709     mWatchCallback.ambient_changed = WatchAppAmbientChanged;
710
711     AppCore::AppAddEventHandler(&handlers[AppCore::LOW_BATTERY], AppCore::LOW_BATTERY, AppBatteryLow, mFramework);
712     AppCore::AppAddEventHandler(&handlers[AppCore::LOW_MEMORY], AppCore::LOW_MEMORY, AppMemoryLow, mFramework);
713     AppCore::AppAddEventHandler(&handlers[AppCore::LANGUAGE_CHANGED], AppCore::LANGUAGE_CHANGED, AppLanguageChanged, mFramework);
714     AppCore::AppAddEventHandler(&handlers[AppCore::REGION_FORMAT_CHANGED], AppCore::REGION_FORMAT_CHANGED, AppRegionChanged, mFramework);
715
716     ret = watch_app_main(*mFramework->mArgc, *mFramework->mArgv, &mWatchCallback, mFramework);
717 #endif
718     return ret;
719   }
720
721   void AppWatchExit()
722   {
723 #ifdef APPCORE_WATCH_AVAILABLE
724     watch_app_exit();
725 #endif
726   }
727
728 #ifdef COMPONENT_APPLICATION_SUPPORT
729   int AppComponentMain()
730   {
731     /*Crate component_based_app_base_lifecycle_callback*/
732     component_based_app_base_lifecycle_callback_s callback;
733     callback.init      = AppInit;
734     callback.run       = AppRun;
735     callback.exit      = AppExit;
736     callback.create    = ComponentAppCreate;
737     callback.terminate = ComponentAppTerminate;
738     callback.fini      = ComponentAppFinish;
739
740     return component_based_app_base_main(*mFramework->mArgc, *mFramework->mArgv, &callback, mFramework);
741     ;
742   }
743
744   static void* ComponentAppCreate(void* data)
745   {
746     Framework* framework = static_cast<Framework*>(data);
747     Observer*  observer  = &framework->mObserver;
748     observer->OnInit();
749
750     return Dali::AnyCast<void*>(observer->OnCreate());
751   }
752
753   static void ComponentAppTerminate(void* data)
754   {
755     Observer* observer = &static_cast<Framework*>(data)->mObserver;
756     observer->OnTerminate();
757   }
758
759   static void ComponentAppFinish(void* data)
760   {
761     ecore_shutdown();
762
763     if(getenv("AUL_LOADER_INIT"))
764     {
765       setenv("AUL_LOADER_INIT", "0", 1);
766       ecore_shutdown();
767     }
768   }
769
770   void AppComponentExit()
771   {
772     component_based_app_base_exit();
773   }
774
775 #endif
776
777 private:
778   // Undefined
779   Impl(const Impl& impl);
780
781   // Undefined
782   Impl& operator=(const Impl& impl);
783 };
784
785 Framework::Framework(Framework::Observer& observer, int* argc, char*** argv, Type type)
786 : mObserver(observer),
787   mInitialised(false),
788   mPaused(false),
789   mRunning(false),
790   mArgc(argc),
791   mArgv(argv),
792   mBundleName(""),
793   mBundleId(""),
794   mAbortHandler(MakeCallback(this, &Framework::AbortCallback)),
795   mImpl(NULL)
796 {
797   bool featureFlag = true;
798   system_info_get_platform_bool("tizen.org/feature/opengles.version.2_0", &featureFlag);
799
800   if(featureFlag == false)
801   {
802     set_last_result(TIZEN_ERROR_NOT_SUPPORTED);
803   }
804 #ifdef DALI_ELDBUS_AVAILABLE
805   // Initialize ElDBus.
806   DALI_LOG_INFO(gDBusLogging, Debug::General, "Starting DBus Initialization\n");
807   eldbus_init();
808 #endif
809   InitThreads();
810
811   mImpl = new Impl(this, type);
812 }
813
814 Framework::~Framework()
815 {
816   if(mRunning)
817   {
818     Quit();
819   }
820
821 #ifdef DALI_ELDBUS_AVAILABLE
822   // Shutdown ELDBus.
823   DALI_LOG_INFO(gDBusLogging, Debug::General, "Shutting down DBus\n");
824   eldbus_shutdown();
825 #endif
826
827   delete mImpl;
828 }
829
830 bool Framework::Create()
831 {
832   mInitialised = true;
833   mObserver.OnInit();
834   return true;
835 }
836
837 void Framework::Run()
838 {
839   mRunning = true;
840   int ret;
841
842   ret = mImpl->AppMain();
843   if(ret != APP_ERROR_NONE)
844   {
845     DALI_LOG_ERROR("Framework::Run(), ui_app_main() is failed. err = %d\n", ret);
846   }
847   mRunning = false;
848 }
849
850 void Framework::Quit()
851 {
852   mImpl->AppExit();
853 }
854
855 bool Framework::IsMainLoopRunning()
856 {
857   return mRunning;
858 }
859
860 void Framework::AddAbortCallback(CallbackBase* callback)
861 {
862   mImpl->mAbortCallBack = callback;
863 }
864
865 std::string Framework::GetBundleName() const
866 {
867   return mBundleName;
868 }
869
870 void Framework::SetBundleName(const std::string& name)
871 {
872   mBundleName = name;
873 }
874
875 std::string Framework::GetBundleId() const
876 {
877   return mBundleId;
878 }
879
880 std::string Framework::GetResourcePath()
881 {
882   std::string resourcePath = "";
883 #if defined(TIZEN_PLATFORM_CONFIG_SUPPORTED) && TIZEN_PLATFORM_CONFIG_SUPPORTED
884   char* app_rsc_path = app_get_resource_path();
885   if(app_rsc_path)
886   {
887     resourcePath = app_rsc_path;
888     free(app_rsc_path);
889   }
890 #else // For backwards compatibility with older Tizen versions
891
892   // "DALI_APPLICATION_PACKAGE" is used to get the already configured Application package path.
893   const char* environmentVariable = "DALI_APPLICATION_PACKAGE";
894   char*       value               = getenv(environmentVariable);
895   if(value != NULL)
896   {
897     resourcePath = value;
898   }
899
900   if(resourcePath.back() != '/')
901   {
902     resourcePath += "/";
903   }
904
905 #endif //TIZEN_PLATFORM_CONFIG_SUPPORTED
906
907   return resourcePath;
908 }
909
910 std::string Framework::GetDataPath()
911 {
912   std::string result;
913   char*       dataPath = app_get_data_path();
914   if(dataPath)
915   {
916     result = dataPath;
917     free(dataPath);
918   }
919   return result;
920 }
921
922 void Framework::SetBundleId(const std::string& id)
923 {
924   mBundleId = id;
925 }
926
927 void Framework::AbortCallback()
928 {
929   // if an abort call back has been installed run it.
930   if(mImpl->mAbortCallBack)
931   {
932     CallbackBase::Execute(*mImpl->mAbortCallBack);
933   }
934   else
935   {
936     Quit();
937   }
938 }
939
940 void Framework::InitThreads()
941 {
942 }
943
944 void Framework::SetLanguage(const std::string& language)
945 {
946   mImpl->SetLanguage(language);
947 }
948
949 void Framework::SetRegion(const std::string& region)
950 {
951   mImpl->SetRegion(region);
952 }
953
954 std::string Framework::GetLanguage() const
955 {
956   return mImpl->GetLanguage();
957 }
958
959 std::string Framework::GetRegion() const
960 {
961   return mImpl->GetRegion();
962 }
963
964 } // namespace Adaptor
965
966 } // namespace Internal
967
968 } // namespace Dali