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