Make popup message when EwkView is NULL
[platform/framework/web/wrt.git] / src / wrt-client / wrt-client.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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 #include "wrt-client.h"
17 #include <appcore-efl.h>
18 #include <cstdlib>
19 #include <cstdio>
20 #include <string>
21 #include <dpl/log/log.h>
22 #include <dpl/optional_typedefs.h>
23 #include <dpl/exception.h>
24 #include <common/application_data.h>
25 #include <core_module.h>
26 #include <localization_setting.h>
27 #include <widget_deserialize_model.h>
28 #include <EWebKit2.h>
29 #include <dpl/localization/w3c_file_localization.h>
30 #include <dpl/localization/LanguageTagsProvider.h>
31
32 //W3C PACKAGING enviroment variable name
33 #define W3C_DEBUG_ENV_VARIABLE "DEBUG_LOAD_FINISH"
34
35 // window signal callback
36 const char *EDJE_SHOW_BACKWARD_SIGNAL = "show,backward,signal";
37 const std::string VIEWMODE_TYPE_FULLSCREEN = "fullscreen";
38 const std::string VIEWMODE_TYPE_MAXIMIZED = "maximized";
39 char const* const ELM_SWALLOW_CONTENT = "elm.swallow.content";
40 const char* const BUNDLE_PATH = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
41
42 static Ewk_Context* s_ewk_context = NULL;
43
44 WrtClient::WrtClient(int argc, char **argv) :
45     Application(argc, argv, "wrt-client", false),
46     DPL::TaskDecl<WrtClient>(this),
47     m_launched(false),
48     m_initializing(false),
49     m_initialized(false),
50     m_sdkLauncherPid(0),
51     m_debugMode(false),
52     m_debuggerPort(0),
53     m_returnStatus(ReturnStatus::Succeeded),
54     m_widgetState(WidgetState::WidgetState_Stopped)
55 {
56     Touch();
57     LogDebug("App Created");
58 }
59
60 WrtClient::~WrtClient()
61 {
62     LogDebug("App Finished");
63 }
64
65 WrtClient::ReturnStatus::Type WrtClient::getReturnStatus() const
66 {
67     return m_returnStatus;
68 }
69
70 void WrtClient::OnStop()
71 {
72     LogInfo("Stopping Dummy Client");
73 }
74
75
76 void WrtClient::OnCreate()
77 {
78     LogInfo("On Create");
79     ADD_PROFILING_POINT("OnCreate callback", "point");
80     ewk_init();
81 }
82
83
84 void WrtClient::OnResume()
85 {
86     if (m_widgetState != WidgetState_Suspended) {
87         LogWarning("Widget is not suspended, resuming was skipped");
88         return;
89     }
90     m_widget->Resume();
91     m_widgetState = WidgetState_Running;
92 }
93
94
95 void WrtClient::OnPause()
96 {
97     LogDebug("On pause");
98
99     if (m_widgetState != WidgetState_Running) {
100         LogWarning("Widget is not running to be suspended");
101         return;
102     }
103     m_widget->Suspend();
104     m_widgetState = WidgetState_Suspended;
105 }
106
107 void WrtClient::OnReset(bundle *b)
108 {
109     LogDebug("OnReset");
110     // bundle argument is freed after OnReset() is returned
111     // So bundle duplication is needed
112     ApplicationDataSingleton::Instance().setBundle(bundle_dup(b));
113
114     if (true == m_initializing) {
115         LogDebug("can not handle reset event");
116         return;
117     }
118     if (true == m_launched) {
119         if (m_widgetState == WidgetState_Stopped) {
120             LogError("Widget is not running to be reset");
121             return;
122         }
123         m_widget->Reset();
124         m_windowData->emitSignalForUserLayout(EDJE_SHOW_BACKWARD_SIGNAL, "");
125         m_widgetState = WidgetState_Running;
126     } else {
127         if (true == checkArgument())
128         {
129             setStep();
130         }
131         else
132         {
133             showHelpAndQuit();
134         }
135     }
136 }
137
138 void WrtClient::OnTerminate()
139 {
140     LogDebug("Wrt Shutdown now");
141     shutdownStep();
142 }
143
144 void WrtClient::showHelpAndQuit()
145 {
146     printf("Usage: wrt-client [OPTION]... [WIDGET: ID]...\n"
147            "launch widgets.\n"
148            "Mandatory arguments to long options are mandatory for short "
149            "options too.\n"
150            "  -h,    --help                                 show this help\n"
151            "  -l,    --launch                               "
152            "launch widget with given tizen ID\n"
153            "  -t,    --tizen                                "
154            "launch widget with given tizen ID\n"
155            "\n");
156
157     Quit();
158 }
159
160 bool WrtClient::checkArgument()
161 {
162     std::string tizenId = getTizenIdFromArgument(m_argc, m_argv);
163
164     if(tizenId.empty()){
165         // Just show help
166         return false;
167     } else {
168         m_tizenId = tizenId;
169         LogDebug("Tizen id: " << m_tizenId);
170         return true;
171     }
172 }
173
174 std::string WrtClient::getTizenIdFromArgument(int argc, char **argv)
175 {
176     LogInfo("checkArgument");
177     std::string arg = argv[0];
178
179     if (arg.empty()) {
180         return "";
181     }
182
183     if (arg.find("wrt-client") != std::string::npos) {
184         if (argc <= 1) {
185             return "";
186         }
187
188         arg = argv[1];
189
190         if (arg == "-h" || arg == "--help") {
191             return "";
192         } else if (arg == "-l" || arg == "--launch" ||
193                 arg == "-t" || arg == "--tizen") {
194             if (argc != 3) {
195                 return "";
196             }
197             return argv[2];
198         } else {
199             return "";
200         }
201     } else {
202         // Launch widget based on application basename
203         size_t pos = arg.find_last_of('/');
204
205         if (pos != std::string::npos) {
206             arg = arg.erase(0, pos + 1);
207         }
208
209         return arg;
210     }
211
212     return "";
213 }
214
215 void WrtClient::setStep()
216 {
217     LogInfo("setStep");
218
219     AddStep(&WrtClient::initStep);
220
221     setSdkLauncherDebugData();
222
223     AddStep(&WrtClient::launchStep);
224     AddStep(&WrtClient::shutdownStep);
225
226     m_initializing = true;
227
228     DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
229 }
230
231 void WrtClient::setSdkLauncherDebugData()
232 {
233     LogDebug("setSdkLauncherDebugData");
234
235     /* check bundle from sdk launcher */
236     bundle *bundleFromSdkLauncher;
237     bundleFromSdkLauncher = bundle_import_from_argv(m_argc, m_argv);
238     const char *bundle_debug = bundle_get_val(bundleFromSdkLauncher, "debug");
239     const char *bundle_pid = bundle_get_val(bundleFromSdkLauncher, "pid");
240     if (bundle_debug != NULL && bundle_pid != NULL) {
241         if (strcmp(bundle_debug, "true") == 0) {
242             m_debugMode = true;
243             m_sdkLauncherPid = atoi(bundle_pid);
244         } else {
245             m_debugMode = false;
246         }
247     }
248     bundle_free(bundleFromSdkLauncher);
249 }
250
251 bool WrtClient::checkDebugMode(SDKDebugData* debugData)
252 {
253     LogError("Checking for debug mode");
254     Assert(m_dao);
255
256     bool debugMode = debugData->debugMode;
257
258     LogInfo("[DEBUG_MODE] Widget is launched in " <<
259             (debugMode ? "DEBUG" : "RETAIL") <<
260             " mode.");
261
262     if (debugMode == true) {
263         // In WAC widget, only test widgets can use web inspector.
264         // In TIZEN widget,
265         // every launched widgets as debug mode can use it.
266         if (m_dao->getWidgetType().appType == WrtDB::APP_TYPE_WAC20)
267         {
268             bool developerMode = WRT::CoreModuleSingleton::Instance().developerMode();
269             //This code will be activated
270             //after WAC test certificate is used by SDK
271             //bool isTestWidget = view->m_widgetModel->IsTestWidget.Get();
272             //if(!isTestWidget)
273             //{
274             //    LogInfo("This is not WAC Test Widget");
275             //    break;
276             //}
277             if (!developerMode) {
278                 LogInfo("This is not WAC Developer Mode");
279                 debugMode = false;
280             }
281         }
282     }
283     return debugMode;
284 }
285
286 void WrtClient::OnEventReceived(const NextStepEvent& /*event*/)
287 {
288     LogDebug("Executing next step");
289     NextStep();
290 }
291
292 void WrtClient::initStep()
293 {
294     LogDebug("");
295     if (WRT::CoreModuleSingleton::Instance().Init(s_ewk_context)) {
296         m_initialized = true;
297     } else {
298         m_returnStatus = ReturnStatus::Failed;
299         SwitchToStep(&WrtClient::shutdownStep);
300     }
301
302     // ecore_event_jobs are processed sequentially without concession to
303     // other type events. To give a chance of execute to other events,
304     // ecore_timer_add was used.
305     DPL::Event::ControllerEventHandler<NextStepEvent>::PostTimedEvent(
306             NextStepEvent(),0.001);
307 }
308
309 bool WrtClient::checkWACTestCertififedWidget()
310 {
311     // WAC Waikiki Beta Release Core Specification: Widget Runtime
312     // 10 Dec 2010
313     //
314     // WR-4710 The WRT MUST enable debug functions only for WAC test widgets
315     // i.e. the functions must not be usable for normal WAC widgets, even when
316     // a WAC test widget is executing.
317     ADD_PROFILING_POINT("DeveloperModeCheck", "start");
318     Assert(!!m_dao);
319     // WAC test widget
320     // A widget signed with a WAC-issued test certificate as described in
321     // Developer Mode.
322
323     bool developerWidget = m_dao->isTestWidget();
324     bool developerMode = WRT::CoreModuleSingleton::Instance().developerMode();
325
326     LogDebug("Is WAC test widget: " << developerWidget);
327     LogDebug("Is developer Mode: " << developerMode);
328
329     if (developerWidget) {
330         if(!developerMode)
331         {
332             LogError("WAC test certified developer widget is needed for " <<
333                     "developer mode");
334             return false;
335         }else{
336             //TODO: WR-4660 (show popup about developer widget
337             //      during launch
338             LogInfo("POPUP: THIS IS TEST WIDGET!");
339         }
340     }
341     ADD_PROFILING_POINT("DeveloperModeCheck", "stop");
342     return true;
343 }
344
345 void WrtClient::loadFinishCallback(Evas_Object* webview)
346 {
347     ADD_PROFILING_POINT("loadFinishCallback", "start");
348     SDKDebugData* debug = new SDKDebugData;
349     debug->debugMode = m_debugMode;
350     debug->pid = new unsigned long(getpid());
351
352     LogInfo("Post result of launch");
353
354     // Start inspector server, if current mode is debugger mode.
355     // In the WK2 case, ewk_view_inspector_server_start should
356     // be called after WebProcess is created.
357     if (checkDebugMode(debug))
358     {
359         debug->portnum =
360             ewk_view_inspector_server_start(m_widget->GetCurrentWebview(), 0);
361         if (debug->portnum == 0) {
362             LogWarning("Failed to get portnum");
363         } else {
364             LogInfo("Assigned port number for inspector : "
365                     << debug->portnum);
366         }
367     } else {
368         LogDebug("Debug mode is disabled");
369     }
370
371     //w3c packaging test debug (message on 4>)
372     const char * makeScreen = getenv(W3C_DEBUG_ENV_VARIABLE);
373     if(makeScreen != NULL && strcmp(makeScreen, "1") == 0)
374     {
375         FILE* doutput = fdopen(4, "w");
376         fprintf(doutput,"didFinishLoadForFrameCallback: ready\n");
377         fclose(doutput);
378     }
379
380     if (webview) {
381         LogDebug("Launch succesfull");
382
383         m_launched = true;
384         m_initializing = false;
385         setlinebuf(stdout);
386         ADD_PROFILING_POINT("loadFinishCallback", "stop");
387         printf("launched\n");
388         fflush(stdout);
389     } else {
390         printf("failed\n");
391
392         m_returnStatus = ReturnStatus::Failed;
393         //shutdownStep
394         DPL::Event::ControllerEventHandler<NextStepEvent>::
395                 PostEvent(NextStepEvent());
396     }
397
398     if(debug->debugMode)
399     {
400         LogDebug("Send RT signal to wrt-launcher(pid: " << m_sdkLauncherPid);
401         union sigval sv;
402         /* send real time signal with result to wrt-launcher */
403         if(webview) {
404             LogDebug("userData->portnum : " << debug->portnum);
405             sv.sival_int = debug->portnum;
406         } else {
407            sv.sival_int = -1;
408         }
409         sigqueue(m_sdkLauncherPid, SIGRTMIN, sv);
410     }
411
412     ApplicationDataSingleton::Instance().freeBundle();
413
414     LogDebug("Cleaning wrtClient launch resources...");
415     delete debug->pid;
416     delete debug;
417 }
418
419 void WrtClient::progressFinishCallback()
420 {
421     m_splashScreen->stopSplashScreen();
422 }
423
424 void WrtClient::webkitExitCallback()
425 {
426     LogDebug("window close called, terminating app");
427     SwitchToStep(&WrtClient::shutdownStep);
428     DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
429             NextStepEvent());
430 }
431
432 void WrtClient::webCrashCallback()
433 {
434     LogError("webProcess crashed");
435     SwitchToStep(&WrtClient::shutdownStep);
436     DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
437             NextStepEvent());
438 }
439
440
441 void WrtClient::launchStep()
442 {
443     ADD_PROFILING_POINT("launchStep", "start");
444     LogDebug("Launching widget ...");
445
446     ADD_PROFILING_POINT("getRunnableWidgetObject", "start");
447     m_widget = WRT::CoreModuleSingleton::Instance()
448                     .getRunnableWidgetObject(m_tizenId);
449     ADD_PROFILING_POINT("getRunnableWidgetObject", "stop");
450
451     if (!m_widget) {
452         LogError("RunnableWidgetObject is NULL, stop launchStep");
453         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
454                     NextStepEvent());
455         return;
456     }
457
458     if (m_widgetState == WidgetState_Running) {
459         LogWarning("Widget already running, stop launchStep");
460         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
461                     NextStepEvent());
462         return;
463     }
464
465     if (m_widgetState == WidgetState_Authorizing) {
466         LogWarning("Widget already authorizing, stop launchStep");
467         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
468                     NextStepEvent());
469         return;
470     }
471
472     m_dao.reset(new WrtDB::WidgetDAOReadOnly(DPL::FromASCIIString(m_tizenId)));
473     DPL::Optional<DPL::String> defloc = m_dao->getDefaultlocale();
474     if(!defloc.IsNull())
475     {
476         LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(*defloc);
477     }
478
479     // For localizationsetting not changed on widget running
480     //LocalizationSetting::SetLanguageChangedCallback(
481     //        languageChangedCallback, this);
482
483     ADD_PROFILING_POINT("CreateWindow", "start");
484     m_windowData.reset(new WindowData(static_cast<unsigned long>(getpid())));
485     ADD_PROFILING_POINT("CreateWindow", "stop");
486
487     WRT::UserDelegatesPtr cbs(new WRT::UserDelegates);
488     ADD_PROFILING_POINT("Create splash screen", "start");
489     m_splashScreen.reset(
490             new SplashScreenSupport(m_windowData->m_win));
491     if (m_splashScreen->createSplashScreen(m_dao->getSplashImgSrc())) {
492         m_splashScreen->startSplashScreen();
493         cbs->progressFinish = DPL::MakeDelegate(this, &WrtClient::progressFinishCallback);
494     }
495     ADD_PROFILING_POINT("Create splash screen", "stop");
496     DPL::OptionalString startUrl = W3CFileLocalization::getStartFile(m_dao);
497     if (!m_widget->PrepareView(DPL::ToUTF8String(*startUrl),
498             m_windowData->m_win))
499     {
500         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
501                     NextStepEvent());
502         return;
503      }
504     //you can't show window with splash screen before PrepareView
505     //ewk_view_add_with_context() in viewLogic breaks window
506
507     WrtDB::WidgetLocalizedInfo localizedInfo =
508         W3CFileLocalization::getLocalizedInfo(m_dao);
509     std:: string name = "";
510     if (!(localizedInfo.name.IsNull())) {
511         name = DPL::ToUTF8String(*(localizedInfo.name));
512     }
513     elm_win_title_set(m_windowData->m_win, name.c_str());
514     evas_object_show(m_windowData->m_win);
515     initializeWindowModes();
516     connectElmCallback();
517
518     if (!checkWACTestCertififedWidget())
519     {
520         LogWarning("WAC Certificate failed, stop launchStep");
521         return;
522     }
523
524     m_widgetState = WidgetState_Authorizing;
525     if (!m_widget->CheckBeforeLaunch()) {
526         LogError("CheckBeforeLaunch failed, stop launchStep");
527         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
528                     NextStepEvent());
529         return;
530     }
531     LogInfo("Widget launch accepted. Entering running state");
532     m_widgetState = WidgetState_Running;
533
534     cbs->loadFinish = DPL::MakeDelegate(this, &WrtClient::loadFinishCallback);
535     cbs->bufferSet = DPL::MakeDelegate(this, &WrtClient::setLayout);
536     cbs->bufferUnset = DPL::MakeDelegate(this, &WrtClient::unsetLayout);
537     cbs->webkitExit = DPL::MakeDelegate(this, &WrtClient::webkitExitCallback);
538     cbs->webCrash = DPL::MakeDelegate(this, &WrtClient::webCrashCallback);
539     cbs->toggleFullscreen = DPL::MakeDelegate(m_windowData.get(), &WindowData::toggleFullscreen);
540
541     m_widget->SetUserDelegates(cbs);
542     m_widget->Show();
543     m_windowData->emitSignalForUserLayout(EDJE_SHOW_BACKWARD_SIGNAL, "");
544     ADD_PROFILING_POINT("launchStep", "stop");
545 }
546
547 void WrtClient::initializeWindowModes()
548 {
549     Assert(m_windowData);
550     Assert(m_dao);
551     auto windowModes = m_dao->getWindowModes();
552     bool fullscreen = false;
553     bool backbutton = false;
554      if (m_dao->getWidgetType().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
555          WidgetSettings widgetSettings;
556          m_dao->getWidgetSettings(widgetSettings);
557          WidgetSettingList settings(widgetSettings);
558         backbutton =
559             (settings.getBackButtonPresence() == BackButton_Enable);
560      }
561
562     FOREACH(it, windowModes)
563     {
564         std::string viewMode = DPL::ToUTF8String(*it);
565         if (viewMode == VIEWMODE_TYPE_FULLSCREEN) {
566             fullscreen = true;
567             break;
568         } else if (viewMode == VIEWMODE_TYPE_MAXIMIZED) {
569             break;
570         }
571     }
572
573     m_windowData->setViewMode(fullscreen,
574             backbutton);
575 }
576
577 void WrtClient::backButtonCallback(void* data,
578                                      Evas_Object * /*obj*/,
579                                      void * /*event_info*/)
580 {
581     LogInfo("BackButtonCallback");
582     Assert(data);
583
584     WrtClient* This = static_cast<WrtClient*>(data);
585
586     This->m_widget->Backward();
587 }
588
589 void WrtClient::connectElmCallback()
590 {
591     Assert(m_windowData);
592     Assert(m_dao);
593     if (m_dao->getWidgetType().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
594         WidgetSettings widgetSettings;
595         m_dao->getWidgetSettings(widgetSettings);
596         WidgetSettingList settings(widgetSettings);
597         if (settings.getBackButtonPresence() == BackButton_Enable) {
598             m_windowData->addFloatBackButtonCallback(
599             "clicked",
600             &WrtClient::backButtonCallback,
601             this);
602         }
603
604         WidgetSettingScreenLock rotationValue = settings.getRotationValue();
605         if (rotationValue == Screen_Portrait) {
606             elm_win_rotation_with_resize_set(m_windowData->m_win, 0);
607         } else if (rotationValue == Screen_Landscape) {
608             elm_win_rotation_with_resize_set(m_windowData->m_win, 270);
609         } else {
610             elm_win_rotation_with_resize_set(m_windowData->m_win, 0);
611         }
612     }
613 }
614
615 void WrtClient::setLayout(Evas_Object* newBuffer) {
616     LogDebug("add new webkit buffer to window");
617     Assert(newBuffer);
618
619     elm_object_part_content_set(m_windowData->m_user_layout, ELM_SWALLOW_CONTENT, newBuffer);
620
621     evas_object_show(newBuffer);
622 }
623
624 void WrtClient::unsetLayout(Evas_Object* currentBuffer) {
625     LogDebug("remove current webkit buffer from window");
626     Assert(currentBuffer);
627     evas_object_hide(currentBuffer);
628
629     elm_object_part_content_unset(m_windowData->m_user_layout, ELM_SWALLOW_CONTENT);
630 }
631
632 void WrtClient::shutdownStep()
633 {
634     LogDebug("Closing Wrt connection ...");
635
636     if (m_widget && m_widgetState)
637     {
638         m_widgetState = WidgetState_Stopped;
639         m_widget->Hide();
640         m_widget.reset();
641         WRT::CoreModuleSingleton::Instance().Terminate();
642     }
643     if (m_initialized)
644     {
645         m_initialized = false;
646     }
647     m_windowData.reset();
648     Quit();
649 }
650
651 int WrtClient::languageChangedCallback(void *data)
652 {
653     LogDebug("Language Changed");
654     if(!data)
655         return 0;
656     WrtClient* wrtClient = static_cast<WrtClient*>(data);
657     if(!(wrtClient->m_dao))
658         return 0;
659
660     // reset function fetches system locales and recreates language tags
661     LanguageTagsProviderSingleton::Instance().resetLanguageTags();
662     // widget default locales are added to language tags below
663     DPL::OptionalString defloc = wrtClient->m_dao->getDefaultlocale();
664     if(!defloc.IsNull())
665     {
666         LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(*defloc);
667     }
668
669     if (wrtClient->m_launched &&
670             wrtClient->m_widgetState != WidgetState_Stopped) {
671         wrtClient->m_widget->ReloadStartPage();
672     }
673     return 0;
674 }
675
676 void WrtClient::Quit()
677 {
678     ewk_shutdown();
679     DPL::Application::Quit();
680 }
681
682 int main(int argc,
683          char *argv[])
684 {
685     UNHANDLED_EXCEPTION_HANDLER_BEGIN
686     {
687         ADD_PROFILING_POINT("main-entered", "point");
688
689         // Set log tagging
690         DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
691
692         // This code is to fork a web process without exec.
693         std::string tizenId = WrtClient::getTizenIdFromArgument(argc, argv);
694
695         if (!tizenId.empty())
696         {
697             LogDebug("Launching by fork mode");
698             // Language env setup
699             appcore_set_i18n("wrt-client", NULL);
700             ewk_init();
701             ewk_set_arguments(argc, argv);
702             setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1);
703             s_ewk_context = ewk_context_new_with_injected_bundle_path(BUNDLE_PATH);
704         }
705
706         // Output on stdout will be flushed after every newline character,
707         // even if it is redirected to a pipe. This is useful for running
708         // from a script and parsing output.
709         // (Standard behavior of stdlib is to use full buffering when
710         // redirected to a pipe, which means even after an end of line
711         // the output may not be flushed).
712         setlinebuf(stdout);
713
714         // set evas backend type
715         if (!getenv("ELM_ENGINE")) {
716             if (!setenv("ELM_ENGINE", "gl", 1)) {
717                     LogDebug("Enable backend");
718             }
719         }
720         else {
721             LogDebug("ELM_ENGINE : " << getenv("ELM_ENGINE"));
722         }
723
724     #ifndef TIZEN_PUBLIC
725         setenv("COREGL_FASTPATH", "1", 1);
726     #endif
727         setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
728         setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1);
729         setenv("ELM_IMAGE_CACHE", "0", 1);
730
731         WrtClient app(argc, argv);
732
733         ADD_PROFILING_POINT("Before appExec", "point");
734         int ret = app.Exec();
735         LogDebug("App returned: " << ret);
736         ret = app.getReturnStatus();
737         LogDebug("WrtClient returned: " << ret);
738         return ret;
739     }
740     UNHANDLED_EXCEPTION_HANDLER_END
741 }