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