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