[Prevent] Handle unhandled exceptions in wrt-client.
[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
546     FOREACH(it, windowModes)
547     {
548         std::string viewMode = DPL::ToUTF8String(*it);
549         if (viewMode == VIEWMODE_TYPE_FULLSCREEN) {
550             fullscreen = true;
551             break;
552         } else if (viewMode == VIEWMODE_TYPE_MAXIMIZED) {
553             break;
554         }
555     }
556
557     WrtDB::WidgetLocalizedInfo localizedInfo =
558             W3CFileLocalization::getLocalizedInfo(m_dao);
559     std::string name = "";
560     if (!(localizedInfo.name.IsNull())) {
561         name = DPL::ToUTF8String(*(localizedInfo.name));
562     }
563     LogInfo("initializeWindowModes " << m_debugMode);
564 #if 1
565     m_windowData->m_debugMode = FALSE;
566 #else
567     if(m_debugMode) {
568         m_windowData->m_debugMode = TRUE;
569     }
570     else {
571         m_windowData->m_debugMode = FALSE;
572     }
573 #endif
574     WindowData::CtxMenuItems ctxMenuItems;
575
576     WindowData::CtxMenuItem ctxMenuBackword;
577     ctxMenuBackword.label = WRT_OPTION_LABEL_BACKWARD;
578     ctxMenuBackword.icon = WRT_OPTION_ICON_BACKWARD;
579     ctxMenuBackword.callback = backwardCallback;
580     ctxMenuBackword.data = this;
581     ctxMenuItems.push_back(ctxMenuBackword);
582
583     WindowData::CtxMenuItem ctxMenuReload;
584     ctxMenuReload.label = WRT_OPTION_LABEL_RELOAD;
585     ctxMenuReload.icon = WRT_OPTION_ICON_RELOAD;
586     ctxMenuReload.callback = reloadCallback;
587     ctxMenuReload.data = this;
588     ctxMenuItems.push_back(ctxMenuReload);
589
590     WindowData::CtxMenuItem ctxMenuForward;
591     ctxMenuForward.label = WRT_OPTION_LABEL_FORWARD;
592     ctxMenuForward.icon = WRT_OPTION_ICON_FORWARD;
593     ctxMenuForward.callback = forwardCallback;
594     ctxMenuForward.data = this;
595     ctxMenuItems.push_back(ctxMenuForward);
596
597     m_windowData->setViewMode(name.c_str(),
598             fullscreen,
599             backbutton,
600             ctxMenuItems);
601 }
602
603 void WrtClient::backButtonCallback(void* data,
604                                      Evas_Object * /*obj*/,
605                                      void * /*event_info*/)
606 {
607     LogInfo("BackButtonCallback");
608     Assert(data);
609
610     WrtClient* This = static_cast<WrtClient*>(data);
611
612     This->m_widget->Backward();
613 }
614
615 void WrtClient::backwardCallback(void *data,
616         Evas_Object */*obj*/,
617         void */*event_info*/)
618 {
619     LogInfo("BackButtonCallback");
620     Assert(data);
621
622     WrtClient* This = static_cast<WrtClient*>(data);
623
624     This->m_widget->Backward();
625     This->m_windowData->initFullViewMode();
626 }
627
628 void WrtClient::reloadCallback(void *data,
629         Evas_Object */*obj*/,
630         void */*event_info*/)
631 {
632     LogInfo("reloadCallback");
633
634     WrtClient* This = static_cast<WrtClient*>(data);
635
636     This->m_widget->Reload();
637     This->m_windowData->initFullViewMode();
638 }
639
640 void WrtClient::forwardCallback(void *data,
641         Evas_Object */*obj*/,
642         void */*event_info*/)
643 {
644     LogInfo("forwardCallback");
645
646     WrtClient* This = static_cast<WrtClient*>(data);
647
648     This->m_widget->Forward();
649     This->m_windowData->initFullViewMode();
650 }
651
652
653 void WrtClient::connectElmCallback()
654 {
655     Assert(m_windowData);
656     Assert(m_dao);
657     if (m_dao->getWidgetType().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
658         WidgetSettings widgetSettings;
659         m_dao->getWidgetSettings(widgetSettings);
660         WidgetSettingList settings(widgetSettings);
661         if (settings.getBackButtonPresence() == BackButton_Enable) {
662             m_windowData->addFloatBackButtonCallback(
663             "clicked",
664             &WrtClient::backButtonCallback,
665             this);
666         }
667
668         WidgetSettingScreenLock rotationValue = settings.getRotationValue();
669         if (rotationValue == Screen_Portrait) {
670             elm_win_rotation_with_resize_set(m_windowData->m_win, 0);
671         } else if (rotationValue == Screen_Landscape) {
672             elm_win_rotation_with_resize_set(m_windowData->m_win, 270);
673         } else {
674             elm_win_rotation_with_resize_set(m_windowData->m_win, 0);
675         }
676     }
677 }
678
679 void WrtClient::setLayout(Evas_Object* newBuffer) {
680     LogDebug("add new webkit buffer to window");
681     Assert(newBuffer);
682     elm_object_content_set(m_windowData->m_conformant, newBuffer);
683     evas_object_show(newBuffer);
684     evas_object_focus_set(newBuffer, EINA_TRUE);
685 }
686
687 void WrtClient::unsetLayout(Evas_Object* currentBuffer) {
688     LogDebug("remove current webkit buffer from window");
689     Assert(currentBuffer);
690     evas_object_hide(currentBuffer);
691     elm_object_content_unset(m_windowData->m_conformant);
692 }
693
694 void WrtClient::shutdownStep()
695 {
696     LogDebug("Closing Wrt connection ...");
697     if (m_initialized && m_widget) {
698         m_widgetState = WidgetState_Stopped;
699         m_widget->Hide();
700         m_widget.reset();
701         m_windowData.reset();
702         WRT::CoreModuleSingleton::Instance().Terminate();
703         m_initialized = false;
704     }
705     Quit();
706 }
707
708 int WrtClient::languageChangedCallback(void *data)
709 {
710     LogDebug("Language Changed");
711     if(!data)
712         return 0;
713     WrtClient* wrtClient = static_cast<WrtClient*>(data);
714     if(!(wrtClient->m_dao))
715         return 0;
716
717     // reset function fetches system locales and recreates language tags
718     LanguageTagsProviderSingleton::Instance().resetLanguageTags();
719     // widget default locales are added to language tags below
720     DPL::OptionalString defloc = wrtClient->m_dao->getDefaultlocale();
721     if(!defloc.IsNull())
722     {
723         LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(*defloc);
724     }
725
726     if (wrtClient->m_launched &&
727             wrtClient->m_widgetState != WidgetState_Stopped) {
728         wrtClient->m_widget->ReloadStartPage();
729     }
730     return 0;
731 }
732
733 void WrtClient::Quit()
734 {
735     ewk_shutdown();
736     DPL::Application::Quit();
737 }
738
739 int main(int argc,
740          char *argv[])
741 {
742     UNHANDLED_EXCEPTION_HANDLER_BEGIN
743     {
744         ADD_PROFILING_POINT("main-entered", "point");
745
746         // Output on stdout will be flushed after every newline character,
747         // even if it is redirected to a pipe. This is useful for running
748         // from a script and parsing output.
749         // (Standard behavior of stdlib is to use full buffering when
750         // redirected to a pipe, which means even after an end of line
751         // the output may not be flushed).
752         setlinebuf(stdout);
753
754         // set evas backend type
755         if (!getenv("ELM_ENGINE")) {
756             if (!setenv("ELM_ENGINE", "gl", 1)) {
757                     LogDebug("Enable backend");
758             }
759         }
760         else {
761             LogDebug("ELM_ENGINE : " << getenv("ELM_ENGINE"));
762         }
763
764     #ifndef TIZEN_PUBLIC
765         setenv("COREGL_FASTPATH", "1", 1);
766     #endif
767         setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
768         setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1);
769         setenv("ELM_IMAGE_CACHE", "0", 1);
770
771         // Set log tagging
772         DPL::Log::LogSystemSingleton::Instance().SetTag("WRT-CLIENT");
773
774         WrtClient app(argc, argv);
775
776         ADD_PROFILING_POINT("Before appExec", "point");
777         int ret = app.Exec();
778         LogDebug("App returned: " << ret);
779         ret = app.getReturnStatus();
780         LogDebug("WrtClient returned: " << ret);
781         return ret;
782     }
783     UNHANDLED_EXCEPTION_HANDLER_END
784 }