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