baeff235747995e5f446f17725884f9575ef133c
[platform/core/uifw/dali-adaptor.git] / adaptors / tizen / framework-tizen.cpp
1 /*
2  * Copyright (c) 2017 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 "framework.h"
20
21 // EXTERNAL INCLUDES
22 #include <app.h>
23 #include <bundle.h>
24 #include <Ecore.h>
25
26 #include <system_info.h>
27 #include <app_control_internal.h>
28 #include <bundle_internal.h>
29
30 // CONDITIONAL INCLUDES
31 #ifdef APPCORE_WATCH_AVAILABLE
32 #include <appcore-watch/watch_app.h>
33 #endif
34 #ifdef DALI_ELDBUS_AVAILABLE
35 #include <Eldbus.h>
36 #endif // DALI_ELDBUS_AVAILABLE
37
38 #if defined( TIZEN_PLATFORM_CONFIG_SUPPORTED ) && TIZEN_PLATFORM_CONFIG_SUPPORTED
39 #include <tzplatform_config.h>
40 #endif // TIZEN_PLATFORM_CONFIG_SUPPORTED
41
42 #include <dali/integration-api/debug.h>
43
44 // INTERNAL INCLUDES
45 #include <callback-manager.h>
46
47 namespace Dali
48 {
49
50 namespace Internal
51 {
52
53 namespace Adaptor
54 {
55
56 #if defined(DEBUG_ENABLED)
57 namespace
58 {
59 Integration::Log::Filter* gDBusLogging = Integration::Log::Filter::New( Debug::NoLogging, false, "LOG_ADAPTOR_EVENTS_DBUS" );
60 } // anonymous namespace
61 #endif
62
63 /**
64  * Impl to hide EFL data members
65  */
66 struct Framework::Impl
67 {
68 // Constructor
69   Impl(void* data, Type type )
70   : mAbortCallBack( NULL ),
71     mCallbackManager( NULL ),
72     mEventCallback()
73   {
74     mFramework = static_cast<Framework*>(data);
75
76 #ifndef APPCORE_WATCH_AVAILABLE
77     if ( type == WATCH )
78     {
79       throw Dali::DaliException( "", "Watch Application is not supported." );
80     }
81 #endif
82     mApplicationType = type;
83     mCallbackManager = CallbackManager::New();
84   }
85
86   ~Impl()
87   {
88     delete mAbortCallBack;
89
90     // we're quiting the main loop so
91     // mCallbackManager->RemoveAllCallBacks() does not need to be called
92     // to delete our abort handler
93     delete mCallbackManager;
94   }
95
96   int AppMain()
97   {
98     int ret;
99
100     if (mApplicationType == NORMAL)
101     {
102       ret = AppNormalMain();
103     }
104     else
105     {
106       ret = AppWatchMain();
107     }
108     return ret;
109   }
110
111   void AppExit()
112   {
113     if (mApplicationType == NORMAL)
114     {
115       AppNormalExit();
116     }
117     else
118     {
119       AppWatchExit();
120     }
121   }
122
123
124   // Data
125   Type mApplicationType;
126   CallbackBase* mAbortCallBack;
127   CallbackManager *mCallbackManager;
128
129   Framework* mFramework;
130   app_event_handler_h handlers[5];
131   ui_app_lifecycle_callback_s mEventCallback;
132 #ifdef APPCORE_WATCH_AVAILABLE
133   watch_app_lifecycle_callback_s mWatchCallback;
134 #endif
135
136   static bool AppCreate(void *data)
137   {
138     return static_cast<Framework*>(data)->Create();
139   }
140
141   static void AppTerminate(void *data)
142   {
143     Observer *observer = &static_cast<Framework*>(data)->mObserver;
144
145     observer->OnTerminate();
146   }
147
148   static void AppPause(void *data)
149   {
150     Observer *observer = &static_cast<Framework*>(data)->mObserver;
151
152     observer->OnPause();
153   }
154
155   static void AppResume(void *data)
156   {
157     Observer *observer = &static_cast<Framework*>(data)->mObserver;
158
159     observer->OnResume();
160   }
161
162   static void ProcessBundle(Framework* framework, bundle *bundleData)
163   {
164     if(bundleData == NULL)
165     {
166       return;
167     }
168
169     // get bundle name
170     char* bundleName = const_cast<char*>(bundle_get_val(bundleData, "name"));
171     if(bundleName != NULL)
172     {
173       framework->SetBundleName(bundleName);
174     }
175
176     // get bundle id
177     char* bundleId = const_cast<char*>(bundle_get_val(bundleData, "id"));
178     if(bundleId != NULL)
179     {
180       framework->SetBundleId(bundleId);
181     }
182   }
183
184   /**
185    * Called by AppCore when the application is launched from another module (e.g. homescreen).
186    * @param[in] b the bundle data which the launcher module sent
187    */
188   static void AppControl(app_control_h app_control, void *data)
189   {
190     Framework* framework = static_cast<Framework*>(data);
191     Observer *observer = &framework->mObserver;
192     bundle *bundleData = NULL;
193
194     app_control_to_bundle(app_control, &bundleData);
195     ProcessBundle(framework, bundleData);
196
197     observer->OnReset();
198     observer->OnAppControl(app_control);
199   }
200
201   int AppNormalMain()
202   {
203     int ret;
204
205     mEventCallback.create = AppCreate;
206     mEventCallback.terminate = AppTerminate;
207     mEventCallback.pause = AppPause;
208     mEventCallback.resume = AppResume;
209     mEventCallback.app_control = AppControl;
210
211     ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, AppBatteryLow, mFramework);
212     ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, AppMemoryLow, mFramework);
213     ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, AppDeviceRotated, mFramework);
214     ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, AppLanguageChanged, mFramework);
215     ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, AppRegionChanged, mFramework);
216
217     ret = ui_app_main(*mFramework->mArgc, *mFramework->mArgv, &mEventCallback, mFramework);
218
219     return ret;
220   }
221
222   void AppNormalExit()
223   {
224       ui_app_exit();
225   }
226
227 #ifdef APPCORE_WATCH_AVAILABLE
228   static bool AppCreateWatch(int width, int height, void *data)
229   {
230     return static_cast<Framework*>(data)->Create();
231   }
232
233   static void AppTimeTick(watch_time_h time, void *data)
234   {
235     Observer *observer = &static_cast<Framework*>(data)->mObserver;
236     WatchTime curTime(time);
237
238     observer->OnTimeTick(curTime);
239   }
240
241   static void AppAmbientTick(watch_time_h time, void *data)
242   {
243     Observer *observer = &static_cast<Framework*>(data)->mObserver;
244     WatchTime curTime(time);
245
246     observer->OnAmbientTick(curTime);
247   }
248
249   static void AppAmbientChanged(bool ambient, void *data)
250   {
251     Observer *observer = &static_cast<Framework*>(data)->mObserver;
252
253     observer->OnAmbientChanged(ambient);
254   }
255 #endif
256
257   int AppWatchMain()
258   {
259     int ret = true;
260
261 #ifdef APPCORE_WATCH_AVAILABLE
262     mWatchCallback.create = AppCreateWatch;
263     mWatchCallback.app_control = AppControl;
264     mWatchCallback.terminate = AppTerminate;
265     mWatchCallback.pause = AppPause;
266     mWatchCallback.resume = AppResume;
267     mWatchCallback.time_tick = AppTimeTick;
268     mWatchCallback.ambient_tick = AppAmbientTick;
269     mWatchCallback.ambient_changed = AppAmbientChanged;
270
271     watch_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, AppBatteryLow, mFramework);
272     watch_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, AppMemoryLow, mFramework);
273     watch_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, AppLanguageChanged, mFramework);
274     watch_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, AppRegionChanged, mFramework);
275
276     ret = watch_app_main(*mFramework->mArgc, *mFramework->mArgv, &mWatchCallback, mFramework);
277 #endif
278     return ret;
279   }
280
281   void AppWatchExit()
282   {
283 #ifdef APPCORE_WATCH_AVAILABLE
284     watch_app_exit();
285 #endif
286   }
287
288   static void AppLanguageChanged(app_event_info_h event, void *data)
289   {
290     Observer *observer = &static_cast<Framework*>(data)->mObserver;
291
292     observer->OnLanguageChanged();
293   }
294
295   static void AppDeviceRotated(app_event_info_h event_info, void *data)
296   {
297   }
298
299   static void AppRegionChanged(app_event_info_h event, void *data)
300   {
301     Observer *observer = &static_cast<Framework*>(data)->mObserver;
302
303     observer->OnRegionChanged();
304   }
305
306   static void AppBatteryLow(app_event_info_h event, void *data)
307   {
308     Observer *observer = &static_cast<Framework*>(data)->mObserver;
309
310     observer->OnBatteryLow();
311   }
312
313   static void AppMemoryLow(app_event_info_h event, void *data)
314   {
315     Observer *observer = &static_cast<Framework*>(data)->mObserver;
316
317     observer->OnMemoryLow();
318   }
319
320 private:
321   // Undefined
322   Impl( const Impl& impl );
323
324   // Undefined
325   Impl& operator=( const Impl& impl );
326 };
327
328 Framework::Framework( Framework::Observer& observer, int *argc, char ***argv, Type type )
329 : mObserver(observer),
330   mInitialised(false),
331   mRunning(false),
332   mArgc(argc),
333   mArgv(argv),
334   mBundleName(""),
335   mBundleId(""),
336   mAbortHandler( MakeCallback( this, &Framework::AbortCallback ) ),
337   mImpl(NULL)
338 {
339   bool featureFlag = true;
340   system_info_get_platform_bool( "tizen.org/feature/opengles.version.2_0", &featureFlag );
341
342   if( featureFlag == false )
343   {
344     set_last_result( TIZEN_ERROR_NOT_SUPPORTED );
345   }
346 #ifdef DALI_ELDBUS_AVAILABLE
347   // Initialize ElDBus.
348   DALI_LOG_INFO( gDBusLogging, Debug::General, "Starting DBus Initialization\n" );
349   eldbus_init();
350 #endif
351   InitThreads();
352
353   mImpl = new Impl(this, type);
354 }
355
356 Framework::~Framework()
357 {
358   if (mRunning)
359   {
360     Quit();
361   }
362
363 #ifdef DALI_ELDBUS_AVAILABLE
364   // Shutdown ELDBus.
365   DALI_LOG_INFO( gDBusLogging, Debug::General, "Shutting down DBus\n" );
366   eldbus_shutdown();
367 #endif
368
369   delete mImpl;
370 }
371
372 bool Framework::Create()
373 {
374   mInitialised = true;
375   mObserver.OnInit();
376   return true;
377 }
378
379 void Framework::Run()
380 {
381   mRunning = true;
382   int ret;
383
384   ret = mImpl->AppMain();
385   if (ret != APP_ERROR_NONE)
386   {
387     DALI_LOG_ERROR("Framework::Run(), ui_app_main() is failed. err = %d\n", ret);
388   }
389   mRunning = false;
390 }
391
392 void Framework::Quit()
393 {
394   mImpl->AppExit();
395 }
396
397 bool Framework::IsMainLoopRunning()
398 {
399   return mRunning;
400 }
401
402 void Framework::AddAbortCallback( CallbackBase* callback )
403 {
404   mImpl->mAbortCallBack = callback;
405 }
406
407 std::string Framework::GetBundleName() const
408 {
409   return mBundleName;
410 }
411
412 void Framework::SetBundleName(const std::string& name)
413 {
414   mBundleName = name;
415 }
416
417 std::string Framework::GetBundleId() const
418 {
419   return mBundleId;
420 }
421
422 std::string Framework::GetResourcePath()
423 {
424   std::string resourcePath = "";
425 #if defined( TIZEN_PLATFORM_CONFIG_SUPPORTED ) && TIZEN_PLATFORM_CONFIG_SUPPORTED
426   resourcePath = app_get_resource_path();
427 #else // For backwards compatibility with older Tizen versions
428
429   // "DALI_APPLICATION_PACKAGE" is used to get the already configured Application package path.
430   const char* environmentVariable = "DALI_APPLICATION_PACKAGE";
431   char* value = getenv( environmentVariable );
432   if ( value != NULL )
433   {
434     resourcePath = value;
435   }
436 #endif //TIZEN_PLATFORM_CONFIG_SUPPORTED
437
438   return resourcePath;
439 }
440
441 void Framework::SetBundleId(const std::string& id)
442 {
443   mBundleId = id;
444 }
445
446 void Framework::AbortCallback( )
447 {
448   // if an abort call back has been installed run it.
449   if (mImpl->mAbortCallBack)
450   {
451     CallbackBase::Execute( *mImpl->mAbortCallBack );
452   }
453   else
454   {
455     Quit();
456   }
457 }
458
459 } // namespace Adaptor
460
461 } // namespace Internal
462
463 } // namespace Dali