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