2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include "wrt-client.h"
19 #include <sys/resource.h>
20 #include <appcore-efl.h>
21 #include <appcore-common.h>
25 #include <dpl/log/log.h>
26 #include <dpl/optional_typedefs.h>
27 #include <dpl/exception.h>
28 #include <application_data.h>
29 #include <core_module.h>
30 #include <localization_setting.h>
31 #include <widget_deserialize_model.h>
33 #include <dpl/localization/w3c_file_localization.h>
34 #include <dpl/localization/LanguageTagsProvider.h>
35 #include <popup-runner/PopupInvoker.h>
36 #include <prepare_external_storage.h>
38 #include "auto_rotation_support.h"
40 #include <process_pool.h>
41 #include <process_pool_launchpad_util.h>
43 #include "client_command_line_parser.h"
44 #include "client_ide_support.h"
45 #include "client_service_support.h"
46 #include "client_submode_support.h"
48 //W3C PACKAGING enviroment variable name
49 #define W3C_DEBUG_ENV_VARIABLE "DEBUG_LOAD_FINISH"
51 // window signal callback
52 const char *EDJE_SHOW_PROGRESS_SIGNAL = "show,progress,signal";
53 const char *EDJE_HIDE_PROGRESS_SIGNAL = "hide,progress,signal";
54 const std::string VIEWMODE_TYPE_FULLSCREEN = "fullscreen";
55 const std::string VIEWMODE_TYPE_MAXIMIZED = "maximized";
56 const std::string VIEWMODE_TYPE_WINDOWED = "windowed";
57 char const* const ELM_SWALLOW_CONTENT = "elm.swallow.content";
58 const char* const BUNDLE_PATH = "/usr/lib/libwrt-injected-bundle.so";
59 const char* const MESSAGE_NAME_INITIALIZE = "ToInjectedBundle::INIT";
62 const char* const DUMMY_PROCESS_PATH = "/usr/bin/wrt_launchpad_daemon_candidate";
63 static Ewk_Context* s_preparedEwkContext = NULL;
64 static WindowData* s_preparedWindowData = NULL;
65 static int app_argc = 0;
66 static char** app_argv = NULL;
69 const char* const HOME = "HOME";
70 const char* const APP_HOME_PATH = "/opt/home/app";
71 const char* const ROOT_HOME_PATH = "/opt/home/root";
73 WrtClient::WrtClient(int argc, char **argv) :
74 Application(argc, argv, "wrt-client", false),
75 DPL::TaskDecl<WrtClient>(this),
76 m_appControlIndex(DPL::OptionalUInt()),
78 m_initializing(false),
81 m_returnStatus(ReturnStatus::Succeeded),
82 m_widgetState(WidgetState::WidgetState_Stopped),
83 m_initialViewMode(VIEWMODE_TYPE_MAXIMIZED),
84 m_currentViewMode(VIEWMODE_TYPE_MAXIMIZED),
85 m_isWebkitFullscreen(false),
86 m_isFullscreenByPlatform(false),
87 m_submodeSupport(new ClientModule::SubmodeSupport())
90 LogDebug("App Created");
93 WrtClient::~WrtClient()
95 LogDebug("App Finished");
98 WrtClient::ReturnStatus::Type WrtClient::getReturnStatus() const
100 return m_returnStatus;
103 void WrtClient::OnStop()
105 LogDebug("Stopping Dummy Client");
108 void WrtClient::OnCreate()
110 LogDebug("On Create");
111 ADD_PROFILING_POINT("OnCreate callback", "point");
115 void WrtClient::OnResume()
117 if (m_widgetState != WidgetState_Suspended) {
118 LogWarning("Widget is not suspended, resuming was skipped");
122 m_widgetState = WidgetState_Running;
125 void WrtClient::OnPause()
127 if (m_widgetState != WidgetState_Running) {
128 LogWarning("Widget is not running to be suspended");
131 if (m_submodeSupport->isNeedTerminateOnSuspend()) {
132 LogDebug("Current mode cannot support suspend");
137 m_widgetState = WidgetState_Suspended;
140 void WrtClient::OnReset(bundle *b)
143 // bundle argument is freed after OnReset() is returned
144 // So bundle duplication is needed
145 ApplicationDataSingleton::Instance().setBundle(bundle_dup(b));
146 ApplicationDataSingleton::Instance().setEncodedBundle(b);
148 if (true == m_initializing) {
149 LogDebug("can not handle reset event");
152 if (true == m_launched) {
153 if (m_widgetState == WidgetState_Stopped) {
154 LogError("Widget is not running to be reset");
158 m_widgetState = WidgetState_Running;
161 ClientModule::CommandLineParser::getTizenId(m_argc, m_argv);
162 if (m_tizenId.empty()) {
166 ClientModule::CommandLineParser::getAppControlIndex(m_argc,
173 // low memory callback set
174 appcore_set_event_callback(
175 APPCORE_EVENT_LOW_MEMORY,
176 WrtClient::appcoreLowMemoryCallback,
180 void WrtClient::OnTerminate()
182 LogDebug("Wrt Shutdown now");
186 void WrtClient::showHelpAndQuit()
188 printf("Usage: wrt-client [OPTION]... [WIDGET: ID]...\n"
190 "Mandatory arguments to long options are mandatory for short "
192 " -h, --help show this help\n"
194 "launch widget with given tizen ID\n"
196 "launch widget with given tizen ID\n"
202 void WrtClient::setStep()
206 AddStep(&WrtClient::initStep);
207 AddStep(&WrtClient::launchStep);
208 AddStep(&WrtClient::shutdownStep);
210 m_initializing = true;
212 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
215 void WrtClient::setDebugMode(bundle* b)
217 m_debugMode = ClientModule::IDESupport::getDebugMode(b);
218 LogDebug("debug mode : " << m_debugMode);
221 void WrtClient::OnEventReceived(const NextStepEvent& /*event*/)
223 LogDebug("Executing next step");
227 void WrtClient::initStep()
230 if (WRT::CoreModuleSingleton::Instance().Init()) {
231 m_initialized = true;
233 m_returnStatus = ReturnStatus::Failed;
234 SwitchToStep(&WrtClient::shutdownStep);
237 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
240 void WrtClient::loadFinishCallback(Evas_Object* webview)
242 ADD_PROFILING_POINT("loadFinishCallback", "start");
245 if (m_splashScreen && m_splashScreen->isShowing())
247 m_splashScreen->stopSplashScreenBuffered();
250 LogDebug("Post result of launch");
252 //w3c packaging test debug (message on 4>)
253 const char * makeScreen = getenv(W3C_DEBUG_ENV_VARIABLE);
254 if (makeScreen != NULL && strcmp(makeScreen, "1") == 0) {
255 FILE* doutput = fdopen(4, "w");
256 fprintf(doutput, "didFinishLoadForFrameCallback: ready\n");
261 LogDebug("Launch succesfull");
264 m_initializing = false;
266 ADD_PROFILING_POINT("loadFinishCallback", "stop");
267 printf("launched\n");
272 m_returnStatus = ReturnStatus::Failed;
274 DPL::Event::ControllerEventHandler<NextStepEvent>::
275 PostEvent(NextStepEvent());
279 unsigned int portNum =
280 ewk_view_inspector_server_start(m_widget->GetCurrentWebview(), 0);
281 LogDebug("Port for inspector : " << portNum);
282 bool ret = ClientModule::IDESupport::sendReply(
283 ApplicationDataSingleton::Instance().getBundle(),
286 LogWarning("Fail to send reply");
290 ApplicationDataSingleton::Instance().freeBundle();
293 void WrtClient::resetCallback(bool result)
296 LogDebug("Fail to handle reset event");
298 ApplicationDataSingleton::Instance().freeBundle();
302 void WrtClient::progressStartedCallback()
304 if (m_settingList->getProgressBarPresence() == ProgressBar_Enable ||
305 m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
307 m_windowData->signalEmit(Layer::MAIN_LAYOUT,
308 EDJE_SHOW_PROGRESS_SIGNAL,
310 m_windowData->updateProgress(0);
314 void WrtClient::loadProgressCallback(Evas_Object* /*webview*/, double value)
316 if (m_settingList->getProgressBarPresence() == ProgressBar_Enable ||
317 m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
319 m_windowData->updateProgress(value);
323 void WrtClient::progressFinishCallback()
325 if (m_settingList->getProgressBarPresence() == ProgressBar_Enable ||
326 m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
328 m_windowData->signalEmit(Layer::MAIN_LAYOUT,
329 EDJE_HIDE_PROGRESS_SIGNAL,
334 void WrtClient::webkitExitCallback()
336 LogDebug("window close called, terminating app");
337 SwitchToStep(&WrtClient::shutdownStep);
338 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
342 void WrtClient::webCrashCallback()
344 LogError("webProcess crashed");
345 SwitchToStep(&WrtClient::shutdownStep);
346 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
350 void WrtClient::enterFullscreenCallback(Evas_Object* /*obj*/,
351 bool isFullscreenByPlatform)
354 m_windowData->toggleFullscreen(true);
355 m_currentViewMode = VIEWMODE_TYPE_FULLSCREEN;
356 m_isWebkitFullscreen = true;
357 if (isFullscreenByPlatform) {
358 m_isFullscreenByPlatform = true;
362 void WrtClient::exitFullscreenCallback(Evas_Object* /*obj*/)
365 m_windowData->toggleFullscreen(false);
366 m_currentViewMode = m_initialViewMode;
367 m_isWebkitFullscreen = false;
368 m_isFullscreenByPlatform = false;
371 void WrtClient::launchStep()
373 ADD_PROFILING_POINT("launchStep", "start");
374 LogDebug("Launching widget ...");
376 ADD_PROFILING_POINT("getRunnableWidgetObject", "start");
377 m_widget = WRT::CoreModuleSingleton::Instance()
378 .getRunnableWidgetObject(m_tizenId, m_appControlIndex);
379 ADD_PROFILING_POINT("getRunnableWidgetObject", "stop");
382 LogError("RunnableWidgetObject is NULL, stop launchStep");
383 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
388 if (m_widgetState == WidgetState_Running) {
389 LogWarning("Widget already running, stop launchStep");
390 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
395 if (m_widgetState == WidgetState_Authorizing) {
396 LogWarning("Widget already authorizing, stop launchStep");
397 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
402 m_dao.reset(new WrtDB::WidgetDAOReadOnly(DPL::FromASCIIString(m_tizenId)));
403 WrtDB::WidgetSettings widgetSettings;
404 m_dao->getWidgetSettings(widgetSettings);
405 m_settingList.reset(new WidgetSettingList(widgetSettings));
406 m_submodeSupport->initialize(DPL::FromASCIIString(m_tizenId));
408 DPL::Optional<DPL::String> defloc = m_dao->getDefaultlocale();
409 if (!defloc.IsNull()) {
410 LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(
414 setInitialViewMode();
415 PrepareExternalStorageSingleton::Instance().Initialize(m_dao->getTizenPkgId());
417 /* remove language change callback */
419 LocalizationSetting::SetLanguageChangedCallback(
420 languageChangedCallback, this);
423 ADD_PROFILING_POINT("CreateWindow", "start");
424 if (s_preparedWindowData == NULL) {
425 m_windowData.reset(new WindowData(static_cast<unsigned long>(getpid()), true));
427 m_windowData.reset(s_preparedWindowData);
428 s_preparedWindowData = NULL;
430 ADD_PROFILING_POINT("CreateWindow", "stop");
431 if (!m_windowData->initScreenReaderSupport(
432 m_settingList->getAccessibility() == Accessibility_Enable))
434 LogWarning("Fail to set screen reader support set");
437 // rotate window to initial value
438 setWindowInitialOrientation();
441 WRT::UserDelegatesPtr cbs(new WRT::UserDelegates);
443 ADD_PROFILING_POINT("Create splash screen", "start");
444 DPL::OptionalString splashImgSrc = m_dao->getSplashImgSrc();
445 if (!splashImgSrc.IsNull())
447 m_splashScreen.reset(
448 new SplashScreenSupport(
449 m_windowData->getEvasObject(Layer::WINDOW),
450 (DPL::ToUTF8String(*splashImgSrc)).c_str(),
451 m_currentViewMode != VIEWMODE_TYPE_FULLSCREEN,
452 m_settingList->getRotationValue() == Screen_Landscape));
453 m_splashScreen->startSplashScreen();
455 ADD_PROFILING_POINT("Create splash screen", "stop");
457 DPL::OptionalString startUrl = W3CFileLocalization::getStartFile(m_dao);
458 if (!m_widget->PrepareView(
459 DPL::ToUTF8String(*startUrl),
460 m_windowData->getEvasObject(Layer::WINDOW),
461 s_preparedEwkContext))
463 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
467 // send rotate information to ewk
468 setEwkInitialOrientation();
470 //you can't show window with splash screen before PrepareView
471 //ewk_view_add_with_context() in viewLogic breaks window
472 m_windowData->init();
474 if (m_submodeSupport->isInlineMode()) {
475 if (m_submodeSupport->transientWindow(
477 m_windowData->getEvasObject(Layer::WINDOW))))
479 LogDebug("Success to set submode");
481 LogWarning("Fail to set submode");
485 m_windowData->smartCallbackAdd(Layer::FOCUS,
489 m_windowData->smartCallbackAdd(Layer::FOCUS,
494 WrtDB::WidgetLocalizedInfo localizedInfo =
495 W3CFileLocalization::getLocalizedInfo(m_dao);
496 std::string name = "";
497 if (!(localizedInfo.name.IsNull())) {
498 name = DPL::ToUTF8String(*(localizedInfo.name));
500 elm_win_title_set(m_windowData->getEvasObject(Layer::WINDOW),
504 evas_object_show(m_windowData->getEvasObject(Layer::WINDOW));
506 initializeWindowModes();
508 m_widgetState = WidgetState_Authorizing;
509 if (!m_widget->CheckBeforeLaunch()) {
510 LogError("CheckBeforeLaunch failed, stop launchStep");
511 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
515 LogDebug("Widget launch accepted. Entering running state");
516 m_widgetState = WidgetState_Running;
518 cbs->progressStarted = DPL::MakeDelegate(this, &WrtClient::progressStartedCallback);
519 cbs->progress = DPL::MakeDelegate(this, &WrtClient::loadProgressCallback);
520 cbs->progressFinish = DPL::MakeDelegate(this, &WrtClient::progressFinishCallback);
521 cbs->loadFinish = DPL::MakeDelegate(this, &WrtClient::loadFinishCallback);
522 cbs->reset = DPL::MakeDelegate(this, &WrtClient::resetCallback);
523 cbs->bufferSet = DPL::MakeDelegate(this, &WrtClient::setLayout);
524 cbs->bufferUnset = DPL::MakeDelegate(this, &WrtClient::unsetLayout);
525 cbs->webkitExit = DPL::MakeDelegate(this, &WrtClient::webkitExitCallback);
526 cbs->webCrash = DPL::MakeDelegate(this, &WrtClient::webCrashCallback);
527 cbs->enterFullscreen = DPL::MakeDelegate(this, &WrtClient::enterFullscreenCallback);
528 cbs->exitFullscreen = DPL::MakeDelegate(this, &WrtClient::exitFullscreenCallback);
529 cbs->setOrientation = DPL::MakeDelegate(this, &WrtClient::setWindowOrientation);
530 cbs->hwkey = DPL::MakeDelegate(this, &WrtClient::hwkeyCallback);
532 m_widget->SetUserDelegates(cbs);
535 ADD_PROFILING_POINT("launchStep", "stop");
538 void WrtClient::initializeWindowModes()
540 Assert(m_windowData);
542 (m_settingList->getBackButtonPresence() == BackButton_Enable ||
543 m_currentViewMode == VIEWMODE_TYPE_WINDOWED);
544 m_windowData->setViewMode(m_currentViewMode == VIEWMODE_TYPE_FULLSCREEN,
548 Eina_Bool WrtClient::naviframeBackButtonCallback(void* data,
549 Elm_Object_Item* /*it*/)
551 LogDebug("BackButtonCallback");
554 WrtClient* This = static_cast<WrtClient*>(data);
555 This->m_widget->Backward();
559 int WrtClient::appcoreLowMemoryCallback(void* /*data*/)
561 LogDebug("appcoreLowMemoryCallback");
562 //WrtClient* This = static_cast<WrtClient*>(data);
564 // TODO call RunnableWidgetObject API regarding low memory
565 // The API should be implemented
567 // temporary solution because we have no way to get ewk_context from runnable object.
568 if (s_preparedEwkContext)
570 ewk_context_cache_clear(s_preparedEwkContext);
571 ewk_context_notify_low_memory(s_preparedEwkContext);
577 void WrtClient::setInitialViewMode(void)
580 WrtDB::WindowModeList windowModes = m_dao->getWindowModes();
581 FOREACH(it, windowModes) {
582 std::string viewMode = DPL::ToUTF8String(*it);
583 switch(viewMode[0]) {
585 if (viewMode == VIEWMODE_TYPE_FULLSCREEN) {
586 m_initialViewMode = viewMode;
587 m_currentViewMode = m_initialViewMode;
592 if (viewMode == VIEWMODE_TYPE_MAXIMIZED) {
593 m_initialViewMode = viewMode;
594 m_currentViewMode = m_initialViewMode;
599 if (viewMode == VIEWMODE_TYPE_WINDOWED) {
600 m_initialViewMode = viewMode;
601 m_currentViewMode = m_initialViewMode;
611 void WrtClient::setWindowInitialOrientation(void)
613 Assert(m_windowData);
616 WidgetSettingScreenLock rotationValue = m_settingList->getRotationValue();
617 if (rotationValue == Screen_Portrait) {
618 setWindowOrientation(OrientationAngle::Window::Portrait::PRIMARY);
619 } else if (rotationValue == Screen_Landscape) {
620 setWindowOrientation(OrientationAngle::Window::Landscape::PRIMARY);
621 } else if (rotationValue == Screen_AutoRotation) {
622 if (!AutoRotationSupport::setAutoRotation(
623 m_windowData->getEvasObject(Layer::WINDOW),
624 autoRotationCallback,
627 LogError("Fail to set auto rotation");
630 setWindowOrientation(OrientationAngle::Window::Portrait::PRIMARY);
634 void WrtClient::setWindowOrientation(int angle)
636 Assert(m_windowData);
637 m_windowData->setOrientation(angle);
640 void WrtClient::unsetWindowOrientation(void)
642 Assert(m_windowData);
645 WidgetSettingScreenLock rotationValue = m_settingList->getRotationValue();
646 if (rotationValue == Screen_AutoRotation) {
647 AutoRotationSupport::unsetAutoRotation(
648 m_windowData->getEvasObject(Layer::WINDOW),
649 autoRotationCallback);
653 void WrtClient::setEwkInitialOrientation(void)
658 WidgetSettingScreenLock rotationValue = m_settingList->getRotationValue();
659 if (rotationValue == Screen_Portrait) {
660 ewk_view_orientation_send(
661 m_widget->GetCurrentWebview(),
662 OrientationAngle::W3C::Portrait::PRIMARY);
663 } else if (rotationValue == Screen_Landscape) {
664 ewk_view_orientation_send(
665 m_widget->GetCurrentWebview(),
666 OrientationAngle::W3C::Landscape::PRIMARY);
667 } else if (rotationValue == Screen_AutoRotation) {
668 ewk_view_orientation_send(
669 m_widget->GetCurrentWebview(),
670 OrientationAngle::W3C::Portrait::PRIMARY);
672 ewk_view_orientation_send(
673 m_widget->GetCurrentWebview(),
674 OrientationAngle::W3C::Portrait::PRIMARY);
678 void WrtClient::setCtxpopupItem(void)
680 WindowData::CtxpopupItemDataList data;
683 WindowData::CtxpopupCallbackType shareCallback =
684 DPL::MakeDelegate(this, &WrtClient::ctxpopupShare);
685 WindowData::CtxpopupItemData shareData("Share",
690 WindowData::CtxpopupCallbackType reloadCallback =
691 DPL::MakeDelegate(this, &WrtClient::ctxpopupReload);
692 WindowData::CtxpopupItemData reloadData("Reload",
696 // 3. Open in browser
697 WindowData::CtxpopupCallbackType launchBrowserCallback =
698 DPL::MakeDelegate(this, &WrtClient::ctxpopupLaunchBrowser);
699 WindowData::CtxpopupItemData launchBrowserData("Open in browser",
701 launchBrowserCallback);
702 data.push_back(shareData);
703 data.push_back(reloadData);
704 data.push_back(launchBrowserData);
705 m_windowData->setCtxpopupItemData(data);
708 void WrtClient::ctxpopupShare(void)
711 const char* url = ewk_view_url_get(m_widget->GetCurrentWebview());
713 LogError("url is empty");
716 if (ClientModule::ServiceSupport::launchShareService(
717 elm_win_xwindow_get(m_windowData->getEvasObject(Layer::WINDOW)),
726 void WrtClient::ctxpopupReload(void)
729 ewk_view_reload(m_widget->GetCurrentWebview());
732 void WrtClient::ctxpopupLaunchBrowser(void)
734 LogDebug("launchBrowser");
735 const char* url = ewk_view_url_get(m_widget->GetCurrentWebview());
737 LogError("url is empty");
740 if (ClientModule::ServiceSupport::launchViewService(
741 elm_win_xwindow_get(m_windowData->getEvasObject(Layer::WINDOW)),
750 void WrtClient::hwkeyCallback(const std::string& key)
752 if (m_settingList->getBackButtonPresence() == BackButton_Enable
753 || m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
755 // windowed UX - hosted application
756 if (key == KeyName::BACK) {
757 if (m_isWebkitFullscreen) {
758 ewk_view_fullscreen_exit(m_widget->GetCurrentWebview());
760 m_widget->Backward();
762 } else if (key == KeyName::MENU) {
763 // UX isn't confirmed
764 // m_windowData->showCtxpopup();
767 // packaged application
768 if (key == KeyName::BACK) {
769 if (m_isFullscreenByPlatform) {
770 ewk_view_fullscreen_exit(m_widget->GetCurrentWebview());
776 void WrtClient::setLayout(Evas_Object* webview)
778 LogDebug("add new webkit buffer to window");
780 m_windowData->setWebview(webview);
781 evas_object_show(webview);
782 evas_object_show(m_windowData->getEvasObject(Layer::WINDOW));
785 void WrtClient::unsetLayout(Evas_Object* webview)
787 LogDebug("remove current webkit buffer from window");
789 evas_object_hide(webview);
790 m_windowData->unsetWebview();
793 void WrtClient::shutdownStep()
795 LogDebug("Closing Wrt connection ...");
797 if (m_widget && m_widgetState) {
798 m_widgetState = WidgetState_Stopped;
800 // AutoRotation, focusCallback use m_widget pointer internally.
801 // It must be unset before m_widget is released.
802 m_submodeSupport->deinitialize();
803 unsetWindowOrientation();
804 m_windowData->smartCallbackDel(Layer::FOCUS,
807 m_windowData->smartCallbackDel(Layer::FOCUS,
811 ewk_context_delete(s_preparedEwkContext);
812 PrepareExternalStorageSingleton::Instance().Deinitialize();
813 WRT::CoreModuleSingleton::Instance().Terminate();
816 m_initialized = false;
818 m_windowData.reset();
822 void WrtClient::autoRotationCallback(void* data, Evas_Object* obj, void* /*event*/)
829 WrtClient* This = static_cast<WrtClient*>(data);
830 This->autoRotationSetOrientation(obj);
833 void WrtClient::focusedCallback(void* data,
834 Evas_Object* /*obj*/,
839 WrtClient* This = static_cast<WrtClient*>(data);
840 elm_object_focus_set(This->m_widget->GetCurrentWebview(), EINA_TRUE);
843 void WrtClient::unfocusedCallback(void* data,
844 Evas_Object* /*obj*/,
849 WrtClient* This = static_cast<WrtClient*>(data);
850 elm_object_focus_set(This->m_widget->GetCurrentWebview(), EINA_FALSE);
853 void WrtClient::autoRotationSetOrientation(Evas_Object* obj)
858 AutoRotationSupport::setOrientation(obj, m_widget->GetCurrentWebview(),
859 (m_splashScreen) ? m_splashScreen.get(): NULL);
862 int WrtClient::languageChangedCallback(void *data)
864 LogDebug("Language Changed");
868 WrtClient* wrtClient = static_cast<WrtClient*>(data);
869 if (!(wrtClient->m_dao)) {
873 // reset function fetches system locales and recreates language tags
874 LanguageTagsProviderSingleton::Instance().resetLanguageTags();
875 // widget default locales are added to language tags below
876 DPL::OptionalString defloc = wrtClient->m_dao->getDefaultlocale();
877 if (!defloc.IsNull()) {
878 LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(
882 if (wrtClient->m_launched &&
883 wrtClient->m_widgetState != WidgetState_Stopped)
885 wrtClient->m_widget->ReloadStartPage();
890 void WrtClient::Quit()
893 DPL::Application::Quit();
896 static Eina_Bool proces_pool_fd_handler(void* /*data*/, Ecore_Fd_Handler *handler)
898 int fd = ecore_main_fd_handler_fd_get(handler);
900 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR))
902 LogDebug("ECORE_FD_ERROR");
910 return ECORE_CALLBACK_CANCEL;
913 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ))
915 LogDebug("ECORE_FD_READ");
917 app_pkt_t* pkt = (app_pkt_t*) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
918 memset(pkt, 0, AUL_SOCK_MAXBUFF);
920 int recv_ret = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0);
929 LogDebug("recv error!");
932 LogDebug("recv_ret : " << recv_ret << ", pkt->len : " << pkt->len);
934 ecore_main_fd_handler_del(handler);
936 process_pool_launchpad_main_loop(pkt, app_argv[0], &app_argc, &app_argv);
941 ecore_main_loop_quit();
942 return ECORE_CALLBACK_CANCEL;
945 return ECORE_CALLBACK_CANCEL;
948 static void vconf_changed_handler(keynode_t* /*key*/, void* /*data*/)
950 LogDebug("VCONFKEY_LANGSET vconf-key was changed!");
952 // When system language is changed, the candidate process will be created again.
958 // set evas backend type
959 if (!getenv("ELM_ENGINE"))
961 if (!setenv("ELM_ENGINE", "gl", 1))
963 LogDebug("Enable backend");
968 LogDebug("ELM_ENGINE : " << getenv("ELM_ENGINE"));
972 setenv("COREGL_FASTPATH", "1", 1);
974 setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
975 setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1);
976 setenv("ELM_IMAGE_CACHE", "0", 1);
982 // process pool - store arg's value
986 UNHANDLED_EXCEPTION_HANDLER_BEGIN
988 ADD_PROFILING_POINT("main-entered", "point");
991 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
993 // Set environment variables
996 if (argc > 1 && argv[1] != NULL && !strcmp(argv[1], "-d"))
998 LogDebug("Entered dummy process mode");
999 sprintf(argv[0], "%s ",
1000 DUMMY_PROCESS_PATH);
1002 // Set 'root' home directory
1003 setenv(HOME, ROOT_HOME_PATH, 1);
1005 LogDebug("Prepare ewk_context");
1006 appcore_set_i18n("wrt-client", NULL);
1007 ewk_set_arguments(argc, argv);
1008 setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1);
1009 s_preparedEwkContext = ewk_context_new_with_injected_bundle_path(BUNDLE_PATH);
1011 if (s_preparedEwkContext == NULL)
1013 LogDebug("Creating webkit context was failed!");
1017 int client_fd = __connect_process_pool_server();
1019 if (client_fd == -1)
1021 LogDebug("Connecting process_pool_server was failed!");
1025 // register language changed callback
1026 vconf_notify_key_changed(VCONFKEY_LANGSET, vconf_changed_handler, NULL);
1028 LogDebug("Prepare window_data");
1029 // Temporarily change HOME path to app
1030 // This change is needed for getting elementary profile
1031 // /opt/home/app/.elementary/config/mobile/base.cfg
1032 const char* backupEnv = getenv(HOME);
1033 setenv(HOME, APP_HOME_PATH, 1);
1034 LogDebug("elm_init()");
1035 elm_init(argc, argv);
1036 setenv(HOME, backupEnv, 1);
1038 LogDebug("WindowData()");
1039 s_preparedWindowData = new WindowData(static_cast<unsigned long>(getpid()));
1041 Ecore_Fd_Handler* fd_handler = ecore_main_fd_handler_add(client_fd,
1042 (Ecore_Fd_Handler_Flags)(ECORE_FD_READ|ECORE_FD_ERROR),
1043 proces_pool_fd_handler, NULL, NULL, NULL);
1045 if (fd_handler == NULL)
1047 LogDebug("fd_handler is NULL");
1051 setpriority(PRIO_PROCESS, 0, 0);
1053 LogDebug("ecore_main_loop_begin()");
1054 ecore_main_loop_begin();
1055 LogDebug("ecore_main_loop_begin()_end");
1057 // deregister language changed callback
1058 vconf_ignore_key_changed(VCONFKEY_LANGSET, vconf_changed_handler);
1060 std::string tizenId =
1061 ClientModule::CommandLineParser::getTizenId(argc, argv);
1062 ewk_context_message_post_to_injected_bundle(
1063 s_preparedEwkContext,
1064 MESSAGE_NAME_INITIALIZE,
1070 // This code is to fork a web process without exec.
1071 std::string tizenId =
1072 ClientModule::CommandLineParser::getTizenId(argc, argv);
1074 if (!tizenId.empty()) {
1075 LogDebug("Launching by fork mode");
1076 // Language env setup
1077 appcore_set_i18n("wrt-client", NULL);
1078 ewk_set_arguments(argc, argv);
1079 setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1);
1080 s_preparedEwkContext = ewk_context_new_with_injected_bundle_path(
1083 if (s_preparedEwkContext == NULL)
1085 LogDebug("Creating webkit context was failed!");
1086 Wrt::Popup::PopupInvoker().showInfo("Error", "Creating webkit context was failed.", "OK");
1091 ewk_context_message_post_to_injected_bundle(
1092 s_preparedEwkContext,
1093 MESSAGE_NAME_INITIALIZE,
1098 // Output on stdout will be flushed after every newline character,
1099 // even if it is redirected to a pipe. This is useful for running
1100 // from a script and parsing output.
1101 // (Standard behavior of stdlib is to use full buffering when
1102 // redirected to a pipe, which means even after an end of line
1103 // the output may not be flushed).
1106 WrtClient app(app_argc, app_argv);
1108 ADD_PROFILING_POINT("Before appExec", "point");
1109 int ret = app.Exec();
1110 LogDebug("App returned: " << ret);
1111 ret = app.getReturnStatus();
1112 LogDebug("WrtClient returned: " << ret);
1115 UNHANDLED_EXCEPTION_HANDLER_END