Merge "Fix a bug of not working network logging" into devel/master
[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 #ifdef OVER_TIZEN_SDK_2_2
27 #include <system_info.h>
28 #include <app_control_internal.h>
29 // To be removed when 2.2 is no longer supported.
30 #ifndef TIZEN_2_2_COMPATIBILITY
31 #include <bundle_internal.h>
32 #endif
33 #endif
34
35 #include <dali/integration-api/debug.h>
36
37 // INTERNAL INCLUDES
38 #include <callback-manager.h>
39
40 namespace Dali
41 {
42
43 namespace Internal
44 {
45
46 namespace Adaptor
47 {
48
49 namespace
50 {
51
52 /// Application Status Enum
53 enum
54 {
55   APP_CREATE,
56   APP_TERMINATE,
57   APP_PAUSE,
58   APP_RESUME,
59   APP_RESET,
60   APP_CONTROL,
61   APP_LANGUAGE_CHANGE,
62   APP_DEVICE_ROTATED,
63   APP_REGION_CHANGED,
64   APP_BATTERY_LOW,
65   APP_MEMORY_LOW
66 };
67
68 } // Unnamed namespace
69
70 /**
71  * Impl to hide EFL data members
72  */
73 struct Framework::Impl
74 {
75   // Constructor
76
77   Impl(void* data)
78   : mAbortCallBack( NULL ),
79     mCallbackManager( NULL )
80   {
81     mEventCallback.create = AppCreate;
82     mEventCallback.terminate = AppTerminate;
83     mEventCallback.pause = AppPause;
84     mEventCallback.resume = AppResume;
85 #ifndef OVER_TIZEN_SDK_2_2
86     mEventCallback.service = AppService;
87
88     mEventCallback.low_memory = NULL;
89     mEventCallback.low_battery = NULL;
90     mEventCallback.device_orientation = AppDeviceRotated;
91     mEventCallback.language_changed = AppLanguageChanged;
92     mEventCallback.region_format_changed = NULL;
93
94 #else
95     mEventCallback.app_control = AppControl;
96
97     ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, AppBatteryLow, data);
98     ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, AppMemoryLow, data);
99     ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, AppDeviceRotated, data);
100     ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, AppLanguageChanged, data);
101     ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, AppRegionChanged, data);
102
103 #endif
104
105     mCallbackManager = CallbackManager::New();
106   }
107
108   ~Impl()
109   {
110     delete mAbortCallBack;
111
112     // we're quiting the main loop so
113     // mCallbackManager->RemoveAllCallBacks() does not need to be called
114     // to delete our abort handler
115     delete mCallbackManager;
116   }
117
118   // Data
119
120   CallbackBase* mAbortCallBack;
121   CallbackManager *mCallbackManager;
122
123 #ifndef OVER_TIZEN_SDK_2_2
124   app_event_callback_s mEventCallback;
125 #else
126   ui_app_lifecycle_callback_s mEventCallback;
127   app_event_handler_h handlers[5];
128 #endif
129
130   /**
131    * Called by AppCore on application creation.
132    */
133   static bool AppCreate(void *data)
134   {
135     return static_cast<Framework*>(data)->AppStatusHandler(APP_CREATE, NULL);
136   }
137
138   /**
139    * Called by AppCore when the application should terminate.
140    */
141   static void AppTerminate(void *data)
142   {
143     static_cast<Framework*>(data)->AppStatusHandler(APP_TERMINATE, NULL);
144   }
145
146   /**
147    * Called by AppCore when the application is paused.
148    */
149   static void AppPause(void *data)
150   {
151     static_cast<Framework*>(data)->AppStatusHandler(APP_PAUSE, NULL);
152   }
153
154   /**
155    * Called by AppCore when the application is resumed.
156    */
157   static void AppResume(void *data)
158   {
159     static_cast<Framework*>(data)->AppStatusHandler(APP_RESUME, NULL);
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 #ifndef OVER_TIZEN_SDK_2_2
185   /**
186    * Called by AppCore when the application is launched from another module (e.g. homescreen).
187    * @param[in] b the bundle data which the launcher module sent
188    */
189   static void AppService(service_h service, void *data)
190   {
191     Framework* framework = static_cast<Framework*>(data);
192
193     if(framework == NULL)
194     {
195       return;
196     }
197     bundle *bundleData = NULL;
198
199     service_to_bundle(service, &bundleData);
200     ProcessBundle(framework, bundleData);
201
202     framework->AppStatusHandler(APP_RESET, NULL);
203   }
204
205   static void AppLanguageChanged(void* user_data)
206   {
207     static_cast<Framework*>(user_data)->AppStatusHandler(APP_LANGUAGE_CHANGE, NULL);
208   }
209
210   static void AppDeviceRotated(app_device_orientation_e orientation, void *user_data)
211   {
212     static_cast<Framework*>(user_data)->AppStatusHandler(APP_DEVICE_ROTATED, NULL);
213   }
214
215 #else
216
217   /**
218    * Called by AppCore when the application is launched from another module (e.g. homescreen).
219    * @param[in] b the bundle data which the launcher module sent
220    */
221   static void AppControl(app_control_h app_control, void *data)
222   {
223     Framework* framework = static_cast<Framework*>(data);
224     if(framework == NULL)
225     {
226       return;
227     }
228     bundle *bundleData = NULL;
229
230     app_control_to_bundle(app_control, &bundleData);
231     ProcessBundle(framework, bundleData);
232
233     framework->AppStatusHandler(APP_RESET, NULL);
234     framework->AppStatusHandler(APP_CONTROL, app_control);
235   }
236
237   static void AppLanguageChanged(app_event_info_h event_info, void *user_data)
238   {
239     static_cast<Framework*>(user_data)->AppStatusHandler(APP_LANGUAGE_CHANGE, NULL);
240   }
241
242   static void AppDeviceRotated(app_event_info_h event_info, void *user_data)
243   {
244     static_cast<Framework*>(user_data)->AppStatusHandler(APP_DEVICE_ROTATED, NULL);
245   }
246
247   static void AppRegionChanged(app_event_info_h event_info, void *user_data)
248   {
249     static_cast<Framework*>(user_data)->AppStatusHandler(APP_REGION_CHANGED, NULL);
250   }
251
252   static void AppBatteryLow(app_event_info_h event_info, void *user_data)
253   {
254     static_cast<Framework*>(user_data)->AppStatusHandler(APP_BATTERY_LOW, NULL);
255   }
256
257   static void AppMemoryLow(app_event_info_h event_info, void *user_data)
258   {
259     static_cast<Framework*>(user_data)->AppStatusHandler(APP_MEMORY_LOW, NULL);
260   }
261
262 #endif
263
264 private:
265   // Undefined
266   Impl( const Impl& impl );
267
268   // Undefined
269   Impl& operator=( const Impl& impl );
270 };
271
272 Framework::Framework( Framework::Observer& observer, int *argc, char ***argv )
273 : mObserver(observer),
274   mInitialised(false),
275   mRunning(false),
276   mArgc(argc),
277   mArgv(argv),
278   mBundleName(""),
279   mBundleId(""),
280   mAbortHandler( MakeCallback( this, &Framework::AbortCallback ) ),
281   mImpl(NULL)
282 {
283
284 #ifdef OVER_TIZEN_SDK_2_2
285   bool featureFlag = true;
286   system_info_get_platform_bool( "tizen.org/feature/opengles.version.2_0", &featureFlag );
287
288   if( featureFlag == false )
289   {
290     set_last_result( TIZEN_ERROR_NOT_SUPPORTED );
291     throw Dali::DaliException( "", "OpenGL ES 2.0 is not supported." );
292   }
293 #endif
294
295   InitThreads();
296   mImpl = new Impl(this);
297 }
298
299 Framework::~Framework()
300 {
301   if (mRunning)
302   {
303     Quit();
304   }
305
306   delete mImpl;
307 }
308
309 void Framework::Run()
310 {
311   mRunning = true;
312
313 #ifndef OVER_TIZEN_SDK_2_2
314   app_efl_main(mArgc, mArgv, &mImpl->mEventCallback, this);
315
316 #else
317   int ret = ui_app_main(*mArgc, *mArgv, &mImpl->mEventCallback, this);
318   if (ret != APP_ERROR_NONE)
319   {
320     DALI_LOG_ERROR("Framework::Run(), ui_app_main() is failed. err = %d", ret);
321   }
322 #endif
323
324   mRunning = false;
325 }
326
327 void Framework::Quit()
328 {
329 #ifndef OVER_TIZEN_SDK_2_2
330   app_efl_exit();
331 #else
332   ui_app_exit();
333 #endif
334 }
335
336 bool Framework::IsMainLoopRunning()
337 {
338   return mRunning;
339 }
340
341 void Framework::AddAbortCallback( CallbackBase* callback )
342 {
343   mImpl->mAbortCallBack = callback;
344 }
345
346 std::string Framework::GetBundleName() const
347 {
348   return mBundleName;
349 }
350
351 void Framework::SetBundleName(const std::string& name)
352 {
353   mBundleName = name;
354 }
355
356 std::string Framework::GetBundleId() const
357 {
358   return mBundleId;
359 }
360
361 void Framework::SetBundleId(const std::string& id)
362 {
363   mBundleId = id;
364 }
365
366 void Framework::AbortCallback( )
367 {
368   // if an abort call back has been installed run it.
369   if (mImpl->mAbortCallBack)
370   {
371     CallbackBase::Execute( *mImpl->mAbortCallBack );
372   }
373   else
374   {
375     Quit();
376   }
377 }
378
379 bool Framework::AppStatusHandler(int type, void *bundleData)
380 {
381   switch (type)
382   {
383     case APP_CREATE:
384     {
385       mInitialised = true;
386
387       // Connect to abnormal exit signals
388       mAbortHandler.AbortOnSignal( SIGINT );
389       mAbortHandler.AbortOnSignal( SIGQUIT );
390       mAbortHandler.AbortOnSignal( SIGKILL );
391       mAbortHandler.AbortOnSignal( SIGTERM );
392       mAbortHandler.AbortOnSignal( SIGHUP );
393
394       mObserver.OnInit();
395       break;
396     }
397
398     case APP_RESET:
399     {
400       mObserver.OnReset();
401       break;
402     }
403
404     case APP_RESUME:
405     {
406       mObserver.OnResume();
407       break;
408     }
409
410     case APP_TERMINATE:
411     {
412       mObserver.OnTerminate();
413       break;
414     }
415
416     case APP_PAUSE:
417     {
418       mObserver.OnPause();
419       break;
420     }
421
422     case APP_CONTROL:
423     {
424       mObserver.OnAppControl(bundleData);
425       break;
426     }
427
428     case APP_LANGUAGE_CHANGE:
429     {
430       mObserver.OnLanguageChanged();
431       break;
432     }
433
434     case APP_REGION_CHANGED:
435     {
436       mObserver.OnRegionChanged();
437       break;
438     }
439
440     case APP_BATTERY_LOW:
441     {
442       mObserver.OnBatteryLow();
443       break;
444     }
445
446     case APP_MEMORY_LOW:
447     {
448       mObserver.OnMemoryLow();
449       break;
450     }
451
452     default:
453       break;
454   }
455
456   return true;
457 }
458
459 } // namespace Adaptor
460
461 } // namespace Internal
462
463 } // namespace Dali