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