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