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