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