For Desktop Mode
[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 <common/application_data.h>
23 #include <core_module.h>
24 #include <global_logic.h>
25 #include <widget_localize_model.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 std::string VIEWMODE_TYPE_FULLSCREEN = "fullscreen";
37 const std::string VIEWMODE_TYPE_MAXIMIZED = "maximized";
38 char const* const ELM_SWALLOW_CONTENT = "elm.swallow.content";
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 }
77
78
79 void WrtClient::OnResume()
80 {
81     if (m_widgetState != WidgetState_Suspended) {
82         LogWarning("Widget is not suspended, resuming was skipped");
83         return;
84     }
85     m_widget->Resume();
86     evas_object_focus_set(m_widget->GetCurrentWebview(), EINA_TRUE);
87     m_widgetState = WidgetState_Running;
88 }
89
90
91 void WrtClient::OnPause()
92 {
93     if (m_widgetState != WidgetState_Running) {
94         LogWarning("Widget is not running to be suspended");
95         return;
96     }
97     m_widget->Suspend();
98     evas_object_focus_set(m_widget->GetCurrentWebview(), EINA_FALSE);
99     m_widgetState = WidgetState_Suspended;
100 }
101
102 void WrtClient::OnReset(bundle *b)
103 {
104     LogDebug("OnReset");
105     // bundle argument is freed after OnReset() is returned
106     // So bundle duplication is needed
107     ApplicationDataSingleton::Instance().setBundle(bundle_dup(b));
108
109     if (true == m_initializing) {
110         LogDebug("can not handle reset event");
111         return;
112     }
113     if (true == m_launched) {
114         if (m_widgetState == WidgetState_Stopped) {
115             LogError("Widget is not running to be reset");
116             return;
117         }
118         m_widget->Reset();
119         elm_win_raise(m_windowData->m_win);
120         evas_object_focus_set(m_widget->GetCurrentWebview(), EINA_TRUE);
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(bool success)
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 (success) {
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: "
390                 << m_sdkLauncherPid << ", status: " << success);
391         union sigval sv;
392         /* send real time signal with result to wrt-launcher */
393         if(success)
394         {
395             LogDebug("userData->portnum : " << debug->portnum);
396             sv.sival_int = debug->portnum;
397         }
398         else
399         {
400            sv.sival_int = -1;
401         }
402         sigqueue(m_sdkLauncherPid, SIGRTMIN, sv);
403     }
404
405     ApplicationDataSingleton::Instance().freeBundle();
406
407     LogDebug("Cleaning wrtClient launch resources...");
408     delete debug->pid;
409     delete debug;
410 }
411
412 void WrtClient::progressFinishCallback()
413 {
414     m_splashScreen->stopSplashScreen();
415 }
416
417 void WrtClient::windowCloseCallback()
418 {
419     LogDebug("window close called, terminating app");
420     SwitchToStep(&WrtClient::shutdownStep);
421     DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
422             NextStepEvent());
423 }
424
425 void WrtClient::webCrashCallback()
426 {
427     LogError("webProcess crashed");
428     SwitchToStep(&WrtClient::shutdownStep);
429     DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
430             NextStepEvent());
431 }
432
433
434 void WrtClient::launchStep()
435 {
436     ADD_PROFILING_POINT("launchStep", "start");
437     LogDebug("Launching widget ...");
438
439     ADD_PROFILING_POINT("getRunnableWidgetObject", "start");
440     m_widget = WRT::CoreModuleSingleton::Instance()
441                     .getRunnableWidgetObject(m_tizenId);
442     ADD_PROFILING_POINT("getRunnableWidgetObject", "stop");
443
444     if (!m_widget) {
445         LogError("RunnableWidgetObject is NULL, stop launchStep");
446         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
447                     NextStepEvent());
448         return;
449     }
450
451     if (m_widgetState == WidgetState_Running) {
452         LogWarning("Widget already running, stop launchStep");
453         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
454                     NextStepEvent());
455         return;
456     }
457
458     if (m_widgetState == WidgetState_Authorizing) {
459         LogWarning("Widget already authorizing, stop launchStep");
460         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
461                     NextStepEvent());
462         return;
463     }
464
465     ADD_PROFILING_POINT("localizeWidgetModel", "start");
466     m_dao.reset(new WrtDB::WidgetDAOReadOnly(DPL::FromASCIIString(m_tizenId)));
467     Domain::localizeWidgetModel(m_dao->getDefaultlocale());
468     ADD_PROFILING_POINT("localizeWidgetModel", "stop");
469     LocalizationSetting::SetLanguageChangedCallback(
470             languageChangedCallback, this);
471
472     ADD_PROFILING_POINT("CreateWindow", "start");
473     m_windowData.reset(new WindowData(static_cast<unsigned long>(getpid())));
474     ADD_PROFILING_POINT("CreateWindow", "stop");
475
476     WRT::UserDelegatesPtr cbs(new WRT::UserDelegates);
477     ADD_PROFILING_POINT("Create splash screen", "start");
478     m_splashScreen.reset(
479             new SplashScreenSupport(m_windowData->m_win));
480     if (m_splashScreen->createSplashScreen(m_dao->getSplashImgSrc())) {
481         m_splashScreen->startSplashScreen();
482         cbs->progressFinish = DPL::MakeDelegate(this, &WrtClient::progressFinishCallback);
483     }
484     ADD_PROFILING_POINT("Create splash screen", "stop");
485     DPL::OptionalString startUrl = W3CFileLocalization::getStartFile(m_dao);
486     m_widget->PrepareView(DPL::ToUTF8String(*startUrl),
487             m_windowData->m_win);
488     //you can't show window with splash screen before PrepareView
489     //ewk_view_add_with_context() in viewLogic breaks window
490
491     WrtDB::WidgetLocalizedInfo localizedInfo =
492         W3CFileLocalization::getLocalizedInfo(m_dao);
493     std:: string name = "";
494     if (!(localizedInfo.name.IsNull())) {
495         name = DPL::ToUTF8String(*(localizedInfo.name));
496     }
497     elm_win_title_set(m_windowData->m_win, name.c_str());
498     evas_object_show(m_windowData->m_win);
499     initializeWindowModes();
500     connectElmCallback();
501
502     if (!checkWACTestCertififedWidget())
503     {
504         LogWarning("WAC Certificate failed, stop launchStep");
505         return;
506     }
507
508     m_widgetState = WidgetState_Authorizing;
509     if (!m_widget->CheckBeforeLaunch()) {
510         LogError("CheckBeforeLaunch failed, stop launchStep");
511         DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
512                     NextStepEvent());
513         return;
514     }
515     LogInfo("Widget launch accepted. Entering running state");
516     m_widgetState = WidgetState_Running;
517
518     cbs->loadFinish = DPL::MakeDelegate(this, &WrtClient::loadFinishCallback);
519     cbs->bufferSet = DPL::MakeDelegate(this, &WrtClient::setLayout);
520     cbs->bufferUnset = DPL::MakeDelegate(this, &WrtClient::unsetLayout);
521     cbs->windowClose = DPL::MakeDelegate(this, &WrtClient::windowCloseCallback);
522     cbs->webCrash = DPL::MakeDelegate(this, &WrtClient::webCrashCallback);
523     cbs->toggleFullscreen = DPL::MakeDelegate(m_windowData.get(), &WindowData::toggleFullscreen);
524
525     m_widget->SetUserDelegates(cbs);
526     m_widget->Show();
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     FOREACH(it, windowModes)
537     {
538         std::string viewMode = DPL::ToUTF8String(*it);
539         if (viewMode == VIEWMODE_TYPE_FULLSCREEN) {
540             fullscreen = true;
541             break;
542         } else if (viewMode == VIEWMODE_TYPE_MAXIMIZED) {
543             break;
544         }
545     }
546     bool indicator = true;
547     if (m_dao->getWidgetType().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
548         WidgetSettings widgetSettings;
549         m_dao->getWidgetSettings(widgetSettings);
550         WidgetSettingList settings(widgetSettings);
551         indicator = (settings.getIndicatorPresence()
552                 == Indicator_Enable);
553     }
554
555     WrtDB::WidgetLocalizedInfo localizedInfo =
556             W3CFileLocalization::getLocalizedInfo(m_dao);
557     std::string name = "";
558     if (!(localizedInfo.name.IsNull())) {
559         name = DPL::ToUTF8String(*(localizedInfo.name));
560     }
561     LogInfo("initializeWindowModes " << m_debugMode);
562
563     if(m_debugMode) {
564         m_windowData->m_debugMode = TRUE;
565     }
566     else {
567         m_windowData->m_debugMode = FALSE;
568     }
569
570     WindowData::CtxMenuItems ctxMenuItems;
571
572     WindowData::CtxMenuItem ctxMenuBackword;
573     ctxMenuBackword.label = WRT_OPTION_LABEL_BACKWARD;
574     ctxMenuBackword.icon = WRT_OPTION_ICON_BACKWARD;
575     ctxMenuBackword.callback = backwardCallback;
576     ctxMenuBackword.data = this;
577     ctxMenuItems.push_back(ctxMenuBackword);
578
579     WindowData::CtxMenuItem ctxMenuReload;
580     ctxMenuReload.label = WRT_OPTION_LABEL_RELOAD;
581     ctxMenuReload.icon = WRT_OPTION_ICON_RELOAD;
582     ctxMenuReload.callback = reloadCallback;
583     ctxMenuReload.data = this;
584     ctxMenuItems.push_back(ctxMenuReload);
585
586     WindowData::CtxMenuItem ctxMenuForward;
587     ctxMenuForward.label = WRT_OPTION_LABEL_FORWARD;
588     ctxMenuForward.icon = WRT_OPTION_ICON_FORWARD;
589     ctxMenuForward.callback = forwardCallback;
590     ctxMenuForward.data = this;
591     ctxMenuItems.push_back(ctxMenuForward);
592
593     m_windowData->setViewMode(fullscreen,
594                               ctxMenuItems);
595 }
596
597 void WrtClient::backButtonCallback(void* data,
598                                      Evas_Object * /*obj*/,
599                                      void * /*event_info*/)
600 {
601     LogInfo("BackButtonCallback");
602     Assert(data);
603
604     WrtClient* This = static_cast<WrtClient*>(data);
605
606     This->m_widget->Backward();
607 }
608
609 void WrtClient::backwardCallback(void *data,
610         Evas_Object */*obj*/,
611         void */*event_info*/)
612 {
613     LogInfo("BackButtonCallback");
614     Assert(data);
615
616     WrtClient* This = static_cast<WrtClient*>(data);
617
618     This->m_widget->Backward();
619     This->m_windowData->initFullViewMode();
620 }
621
622 void WrtClient::reloadCallback(void *data,
623         Evas_Object */*obj*/,
624         void */*event_info*/)
625 {
626     LogInfo("reloadCallback");
627
628     WrtClient* This = static_cast<WrtClient*>(data);
629
630     This->m_widget->Reload();
631     This->m_windowData->initFullViewMode();
632 }
633
634 void WrtClient::forwardCallback(void *data,
635         Evas_Object */*obj*/,
636         void */*event_info*/)
637 {
638     LogInfo("forwardCallback");
639
640     WrtClient* This = static_cast<WrtClient*>(data);
641
642     This->m_widget->Forward();
643     This->m_windowData->initFullViewMode();
644 }
645
646
647 void WrtClient::connectElmCallback()
648 {
649     Assert(m_windowData);
650     Assert(m_dao);
651     if (m_dao->getWidgetType().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
652         WidgetSettings widgetSettings;
653         m_dao->getWidgetSettings(widgetSettings);
654         WidgetSettingList settings(widgetSettings);
655         WidgetSettingScreenLock rotationValue = settings.getRotationValue();
656         if (rotationValue == Screen_Portrait) {
657             elm_win_rotation_with_resize_set(m_windowData->m_win, 0);
658         } else if (rotationValue == Screen_Landscape) {
659             elm_win_rotation_with_resize_set(m_windowData->m_win, 270);
660         } else {
661             elm_win_rotation_with_resize_set(m_windowData->m_win, 0);
662         }
663     }
664 }
665
666 void WrtClient::setLayout(Evas_Object* newBuffer) {
667     LogDebug("add new webkit buffer to window");
668     Assert(newBuffer);
669
670     elm_object_part_content_set(m_windowData->m_user_layout, ELM_SWALLOW_CONTENT, newBuffer);
671
672     evas_object_show(newBuffer);
673     evas_object_focus_set(newBuffer, EINA_TRUE);
674 }
675
676 void WrtClient::unsetLayout(Evas_Object* currentBuffer) {
677     LogDebug("remove current webkit buffer from window");
678     Assert(currentBuffer);
679     evas_object_hide(currentBuffer);
680
681     elm_object_part_content_unset(m_windowData->m_user_layout, ELM_SWALLOW_CONTENT);
682
683 }
684
685 void WrtClient::shutdownStep()
686 {
687     LogDebug("Closing Wrt connection ...");
688     if (m_initialized && m_widget) {
689         m_widgetState = WidgetState_Stopped;
690         m_widget->Hide();
691         m_widget.reset();
692         m_windowData.reset();
693         WRT::CoreModuleSingleton::Instance().Terminate();
694         m_initialized = false;
695     }
696     Quit();
697 }
698
699 int WrtClient::languageChangedCallback(void *data)
700 {
701     LogDebug("Language Changed");
702     WrtClient* wrtClient = static_cast<WrtClient*>(data);
703
704     LanguageTags oldtags = LanguageTagsProviderSingleton::Instance().getLanguageTags();
705     // reset function fetches system locales and recreates language tags
706     LanguageTagsProviderSingleton::Instance().resetLanguageTags();
707     LanguageTags newtags = LanguageTagsProviderSingleton::Instance().getLanguageTags();
708
709     // check whether LanguageTags changed or not
710     if (oldtags != newtags) {
711         // update localized data
712         Domain::localizeWidgetModel(wrtClient->m_dao->getDefaultlocale());
713
714         if (true == wrtClient->m_launched &&
715                 wrtClient->m_widgetState != WidgetState_Stopped) {
716             wrtClient->m_widget->ReloadStartPage();
717         }
718     }
719     return 0;
720 }
721
722 int main(int argc,
723          char *argv[])
724 {
725     ADD_PROFILING_POINT("main-entered", "point");
726
727     // Output on stdout will be flushed after every newline character,
728     // even if it is redirected to a pipe. This is useful for running
729     // from a script and parsing output.
730     // (Standard behavior of stdlib is to use full buffering when
731     // redirected to a pipe, which means even after an end of line
732     // the output may not be flushed).
733     setlinebuf(stdout);
734
735     // set evas backend type
736     if (!getenv("ELM_ENGINE")) {
737         if (setenv("ELM_ENGINE", "gl", 1)) {
738                 LogDebug("Enable backend");
739         }
740     }
741 #ifndef TIZEN_PUBLIC
742     setenv("COREGL_FASTPATH", "1", 1);
743 #endif
744     setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
745     setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1);
746     setenv("ELM_IMAGE_CACHE", "0", 1);
747
748     // Set log tagging
749     DPL::Log::LogSystemSingleton::Instance().SetTag("WRT-CLIENT");
750
751     WrtClient app(argc, argv);
752
753     ADD_PROFILING_POINT("Before appExec", "point");
754     int ret = app.Exec();
755     LogDebug("App returned: " << ret);
756     ret = app.getReturnStatus();
757     LogDebug("WrtClient returned: " << ret);
758     return ret;
759 }