Merge "Remove the usage of ImageActor from Indicator" 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 #ifndef TIZEN_SDK_2_2_COMPATIBILITY
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
83 #ifdef TIZEN_SDK_2_2_COMPATIBILITY
84     mEventCallback.service = AppService;
85
86     mEventCallback.low_memory = NULL;
87     mEventCallback.low_battery = NULL;
88     mEventCallback.device_orientation = AppDeviceRotated;
89     mEventCallback.language_changed = AppLanguageChanged;
90     mEventCallback.region_format_changed = NULL;
91
92 #else
93     mEventCallback.app_control = AppControl;
94
95     ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, AppBatteryLow, data);
96     ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, AppMemoryLow, data);
97     ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, AppDeviceRotated, data);
98     ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, AppLanguageChanged, data);
99     ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, AppRegionChanged, data);
100 #endif
101
102     mCallbackManager = CallbackManager::New();
103   }
104
105   ~Impl()
106   {
107     delete mAbortCallBack;
108
109     // we're quiting the main loop so
110     // mCallbackManager->RemoveAllCallBacks() does not need to be called
111     // to delete our abort handler
112     delete mCallbackManager;
113   }
114
115   // Data
116
117   CallbackBase* mAbortCallBack;
118   CallbackManager *mCallbackManager;
119
120 #ifdef TIZEN_SDK_2_2_COMPATIBILITY
121   app_event_callback_s mEventCallback;
122 #else
123   ui_app_lifecycle_callback_s mEventCallback;
124   app_event_handler_h handlers[5];
125 #endif
126
127   /**
128    * Called by AppCore on application creation.
129    */
130   static bool AppCreate(void *data)
131   {
132     return static_cast<Framework*>(data)->AppStatusHandler(APP_CREATE, NULL);
133   }
134
135   /**
136    * Called by AppCore when the application should terminate.
137    */
138   static void AppTerminate(void *data)
139   {
140     static_cast<Framework*>(data)->AppStatusHandler(APP_TERMINATE, NULL);
141   }
142
143   /**
144    * Called by AppCore when the application is paused.
145    */
146   static void AppPause(void *data)
147   {
148     static_cast<Framework*>(data)->AppStatusHandler(APP_PAUSE, NULL);
149   }
150
151   /**
152    * Called by AppCore when the application is resumed.
153    */
154   static void AppResume(void *data)
155   {
156     static_cast<Framework*>(data)->AppStatusHandler(APP_RESUME, NULL);
157   }
158
159   static void ProcessBundle(Framework* framework, bundle *bundleData)
160   {
161     if(bundleData == NULL)
162     {
163       return;
164     }
165
166     // get bundle name
167     char* bundleName = const_cast<char*>(bundle_get_val(bundleData, "name"));
168     if(bundleName != NULL)
169     {
170       framework->SetBundleName(bundleName);
171     }
172
173     // get bundle id
174     char* bundleId = const_cast<char*>(bundle_get_val(bundleData, "id"));
175     if(bundleId != NULL)
176     {
177       framework->SetBundleId(bundleId);
178     }
179   }
180
181 #ifdef TIZEN_SDK_2_2_COMPATIBILITY
182   /**
183    * Called by AppCore when the application is launched from another module (e.g. homescreen).
184    * @param[in] b the bundle data which the launcher module sent
185    */
186   static void AppService(service_h service, void *data)
187   {
188     Framework* framework = static_cast<Framework*>(data);
189
190     if(framework == NULL)
191     {
192       return;
193     }
194     bundle *bundleData = NULL;
195
196     service_to_bundle(service, &bundleData);
197     ProcessBundle(framework, bundleData);
198
199     framework->AppStatusHandler(APP_RESET, NULL);
200   }
201
202   static void AppLanguageChanged(void* user_data)
203   {
204     static_cast<Framework*>(user_data)->AppStatusHandler(APP_LANGUAGE_CHANGE, NULL);
205   }
206
207   static void AppDeviceRotated(app_device_orientation_e orientation, void *user_data)
208   {
209     static_cast<Framework*>(user_data)->AppStatusHandler(APP_DEVICE_ROTATED, NULL);
210   }
211 #else
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 #endif
257
258 private:
259   // Undefined
260   Impl( const Impl& impl );
261
262   // Undefined
263   Impl& operator=( const Impl& impl );
264 };
265
266 Framework::Framework( Framework::Observer& observer, int *argc, char ***argv )
267 : mObserver(observer),
268   mInitialised(false),
269   mRunning(false),
270   mArgc(argc),
271   mArgv(argv),
272   mBundleName(""),
273   mBundleId(""),
274   mAbortHandler( MakeCallback( this, &Framework::AbortCallback ) ),
275   mImpl(NULL)
276 {
277
278 #ifndef TIZEN_SDK_2_2_COMPATIBILITY
279   bool featureFlag = true;
280   system_info_get_platform_bool( "tizen.org/feature/opengles.version.2_0", &featureFlag );
281
282   if( featureFlag == false )
283   {
284     set_last_result( TIZEN_ERROR_NOT_SUPPORTED );
285     throw Dali::DaliException( "", "OpenGL ES 2.0 is not supported." );
286   }
287 #endif
288
289   InitThreads();
290   mImpl = new Impl(this);
291 }
292
293 Framework::~Framework()
294 {
295   if (mRunning)
296   {
297     Quit();
298   }
299
300   delete mImpl;
301 }
302
303 void Framework::Run()
304 {
305   mRunning = true;
306
307 #ifdef TIZEN_SDK_2_2_COMPATIBILITY
308   app_efl_main(mArgc, mArgv, &mImpl->mEventCallback, this);
309 #else
310   int ret = ui_app_main(*mArgc, *mArgv, &mImpl->mEventCallback, this);
311   if (ret != APP_ERROR_NONE)
312   {
313     DALI_LOG_ERROR("Framework::Run(), ui_app_main() is failed. err = %d", ret);
314   }
315 #endif
316
317   mRunning = false;
318 }
319
320 void Framework::Quit()
321 {
322 #ifdef TIZEN_SDK_2_2_COMPATIBILITY
323   app_efl_exit();
324 #else
325   ui_app_exit();
326 #endif
327 }
328
329 bool Framework::IsMainLoopRunning()
330 {
331   return mRunning;
332 }
333
334 void Framework::AddAbortCallback( CallbackBase* callback )
335 {
336   mImpl->mAbortCallBack = callback;
337 }
338
339 std::string Framework::GetBundleName() const
340 {
341   return mBundleName;
342 }
343
344 void Framework::SetBundleName(const std::string& name)
345 {
346   mBundleName = name;
347 }
348
349 std::string Framework::GetBundleId() const
350 {
351   return mBundleId;
352 }
353
354 void Framework::SetBundleId(const std::string& id)
355 {
356   mBundleId = id;
357 }
358
359 void Framework::AbortCallback( )
360 {
361   // if an abort call back has been installed run it.
362   if (mImpl->mAbortCallBack)
363   {
364     CallbackBase::Execute( *mImpl->mAbortCallBack );
365   }
366   else
367   {
368     Quit();
369   }
370 }
371
372 bool Framework::AppStatusHandler(int type, void *bundleData)
373 {
374   switch (type)
375   {
376     case APP_CREATE:
377     {
378       mInitialised = true;
379
380       mObserver.OnInit();
381       break;
382     }
383
384     case APP_RESET:
385     {
386       mObserver.OnReset();
387       break;
388     }
389
390     case APP_RESUME:
391     {
392       mObserver.OnResume();
393       break;
394     }
395
396     case APP_TERMINATE:
397     {
398       mObserver.OnTerminate();
399       break;
400     }
401
402     case APP_PAUSE:
403     {
404       mObserver.OnPause();
405       break;
406     }
407
408     case APP_CONTROL:
409     {
410       mObserver.OnAppControl(bundleData);
411       break;
412     }
413
414     case APP_LANGUAGE_CHANGE:
415     {
416       mObserver.OnLanguageChanged();
417       break;
418     }
419
420     case APP_REGION_CHANGED:
421     {
422       mObserver.OnRegionChanged();
423       break;
424     }
425
426     case APP_BATTERY_LOW:
427     {
428       mObserver.OnBatteryLow();
429       break;
430     }
431
432     case APP_MEMORY_LOW:
433     {
434       mObserver.OnMemoryLow();
435       break;
436     }
437
438     default:
439       break;
440   }
441
442   return true;
443 }
444
445 } // namespace Adaptor
446
447 } // namespace Internal
448
449 } // namespace Dali