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