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