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 <common/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>
44 #include "client_service_support.h"
47 //W3C PACKAGING enviroment variable name
48 #define W3C_DEBUG_ENV_VARIABLE "DEBUG_LOAD_FINISH"
50 // window signal callback
51 const char *EDJE_SHOW_BACKWARD_SIGNAL = "show,backward,signal";
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),
83 m_returnStatus(ReturnStatus::Succeeded),
84 m_widgetState(WidgetState::WidgetState_Stopped),
85 m_initialViewMode(VIEWMODE_TYPE_MAXIMIZED),
86 m_currentViewMode(VIEWMODE_TYPE_MAXIMIZED),
87 m_isWebkitFullscreen(false)
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 LogInfo("Stopping Dummy Client");
108 void WrtClient::OnCreate()
110 LogInfo("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");
132 m_widgetState = WidgetState_Suspended;
135 void WrtClient::OnReset(bundle *b)
138 // bundle argument is freed after OnReset() is returned
139 // So bundle duplication is needed
140 ApplicationDataSingleton::Instance().setBundle(bundle_dup(b));
141 ApplicationDataSingleton::Instance().setEncodedBundle(b);
143 if (true == m_initializing) {
144 LogDebug("can not handle reset event");
147 if (true == m_launched) {
148 if (m_widgetState == WidgetState_Stopped) {
149 LogError("Widget is not running to be reset");
153 m_windowData->emitSignalForUserLayout(EDJE_SHOW_BACKWARD_SIGNAL, "");
154 m_widgetState = WidgetState_Running;
156 if (true == checkArgument()) {
163 // low memory callback set
164 appcore_set_event_callback(
165 APPCORE_EVENT_LOW_MEMORY,
166 WrtClient::appcoreLowMemoryCallback,
170 void WrtClient::OnTerminate()
172 LogDebug("Wrt Shutdown now");
176 void WrtClient::showHelpAndQuit()
178 printf("Usage: wrt-client [OPTION]... [WIDGET: ID]...\n"
180 "Mandatory arguments to long options are mandatory for short "
182 " -h, --help show this help\n"
184 "launch widget with given tizen ID\n"
186 "launch widget with given tizen ID\n"
192 bool WrtClient::checkArgument()
194 std::string tizenId = getTizenIdFromArgument(m_argc, m_argv);
196 if (tizenId.empty()) {
201 tizenId.find(WrtDB::AppControlPrefix::PROCESS_PREFIX);
202 if (pos != std::string::npos) {
203 std::string id = tizenId.substr(pos);
204 id.erase(strlen(WrtDB::AppControlPrefix::PROCESS_PREFIX));
205 std::stringstream s(id);
206 unsigned int appControlIndex;
207 s >> appControlIndex;
208 m_appControlIndex = appControlIndex;
210 LogDebug("app-control execute-index : " << appControlIndex);
213 LogDebug("Tizen id: " << m_tizenId);
218 std::string WrtClient::getTizenIdFromArgument(int argc, char **argv)
220 LogInfo("checkArgument");
221 std::string arg = argv[0];
227 if (arg.find("wrt-client") != std::string::npos) {
234 if (arg == "-h" || arg == "--help") {
236 } else if (arg == "-l" || arg == "--launch" ||
237 arg == "-t" || arg == "--tizen")
247 // Launch widget based on application basename
248 size_t pos = arg.find_last_of('/');
250 if (pos != std::string::npos) {
251 arg = arg.erase(0, pos + 1);
258 void WrtClient::setStep()
262 AddStep(&WrtClient::initStep);
264 setSdkLauncherDebugData();
266 AddStep(&WrtClient::launchStep);
267 AddStep(&WrtClient::shutdownStep);
269 m_initializing = true;
271 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
274 void WrtClient::setSdkLauncherDebugData()
276 LogDebug("setSdkLauncherDebugData");
278 /* check bundle from sdk launcher */
279 bundle *bundleFromSdkLauncher;
280 bundleFromSdkLauncher = bundle_import_from_argv(m_argc, m_argv);
281 const char *bundle_debug = bundle_get_val(bundleFromSdkLauncher, "debug");
282 const char *bundle_pid = bundle_get_val(bundleFromSdkLauncher, "pid");
283 if (bundle_debug != NULL && bundle_pid != NULL) {
284 if (strcmp(bundle_debug, "true") == 0) {
286 m_sdkLauncherPid = atoi(bundle_pid);
291 bundle_free(bundleFromSdkLauncher);
294 bool WrtClient::checkDebugMode(SDKDebugData* debugData)
296 LogError("Checking for debug mode");
299 bool debugMode = debugData->debugMode;
301 LogInfo("[DEBUG_MODE] Widget is launched in " <<
302 (debugMode ? "DEBUG" : "RETAIL") <<
308 void WrtClient::OnEventReceived(const NextStepEvent& /*event*/)
310 LogDebug("Executing next step");
314 void WrtClient::initStep()
317 if (WRT::CoreModuleSingleton::Instance().Init()) {
318 m_initialized = true;
320 m_returnStatus = ReturnStatus::Failed;
321 SwitchToStep(&WrtClient::shutdownStep);
324 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
327 void WrtClient::loadFinishCallback(Evas_Object* webview)
329 ADD_PROFILING_POINT("loadFinishCallback", "start");
332 if (m_splashScreen && m_splashScreen->isShowing())
334 m_splashScreen->stopSplashScreenBuffered();
337 SDKDebugData* debug = new SDKDebugData;
338 debug->debugMode = m_debugMode;
339 debug->pid = new unsigned long(getpid());
341 LogInfo("Post result of launch");
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)) {
348 ewk_view_inspector_server_start(m_widget->GetCurrentWebview(), 0);
349 if (debug->portnum == 0) {
350 LogWarning("Failed to get portnum");
352 LogInfo("Assigned port number for inspector : "
356 LogDebug("Debug mode is disabled");
359 //w3c packaging test debug (message on 4>)
360 const char * makeScreen = getenv(W3C_DEBUG_ENV_VARIABLE);
361 if (makeScreen != NULL && strcmp(makeScreen, "1") == 0) {
362 FILE* doutput = fdopen(4, "w");
363 fprintf(doutput, "didFinishLoadForFrameCallback: ready\n");
368 LogDebug("Launch succesfull");
371 m_initializing = false;
373 ADD_PROFILING_POINT("loadFinishCallback", "stop");
374 printf("launched\n");
379 m_returnStatus = ReturnStatus::Failed;
381 DPL::Event::ControllerEventHandler<NextStepEvent>::
382 PostEvent(NextStepEvent());
385 if (debug->debugMode) {
386 LogDebug("Send RT signal to wrt-launcher(pid: " << m_sdkLauncherPid);
388 /* send real time signal with result to wrt-launcher */
390 LogDebug("userData->portnum : " << debug->portnum);
391 sv.sival_int = debug->portnum;
396 bundle* request = NULL;
397 appsvc_create_result_bundle(
398 ApplicationDataSingleton::Instance().getBundle(),
400 char port[10] = {0,};
401 sprintf(port, "%d", debug->portnum);
402 appsvc_add_data(request, "port", port);
403 appsvc_send_result(request, APPSVC_RES_OK);
406 ApplicationDataSingleton::Instance().freeBundle();
408 LogDebug("Cleaning wrtClient launch resources...");
413 void WrtClient::resetCallback(bool result)
416 LogDebug("Fail to handle reset event");
418 ApplicationDataSingleton::Instance().freeBundle();
422 void WrtClient::progressStartedCallback()
424 if (m_settingList->getProgressBarPresence() == ProgressBar_Enable ||
425 m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
427 m_windowData->emitSignalForUserLayout(EDJE_SHOW_PROGRESS_SIGNAL, "");
428 m_windowData->updateProgress(0);
432 void WrtClient::loadProgressCallback(Evas_Object* /*webview*/, double value)
434 if (m_settingList->getProgressBarPresence() == ProgressBar_Enable ||
435 m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
437 m_windowData->updateProgress(value);
441 void WrtClient::progressFinishCallback()
443 if (m_settingList->getProgressBarPresence() == ProgressBar_Enable ||
444 m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
446 m_windowData->emitSignalForUserLayout(EDJE_HIDE_PROGRESS_SIGNAL, "");
450 void WrtClient::webkitExitCallback()
452 LogDebug("window close called, terminating app");
453 SwitchToStep(&WrtClient::shutdownStep);
454 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
458 void WrtClient::webCrashCallback()
460 LogError("webProcess crashed");
461 SwitchToStep(&WrtClient::shutdownStep);
462 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
466 void WrtClient::toggleFullscreenCallback(bool fullscreen)
468 LogError("toggleFullscreen");
472 m_windowData->toggleFullscreen(true);
473 m_currentViewMode = VIEWMODE_TYPE_FULLSCREEN;
474 m_isWebkitFullscreen = true;
477 m_windowData->toggleFullscreen(false);
478 m_currentViewMode = m_initialViewMode;
479 m_isWebkitFullscreen = false;
483 void WrtClient::launchStep()
485 ADD_PROFILING_POINT("launchStep", "start");
486 LogDebug("Launching widget ...");
488 ADD_PROFILING_POINT("getRunnableWidgetObject", "start");
489 m_widget = WRT::CoreModuleSingleton::Instance()
490 .getRunnableWidgetObject(m_tizenId, m_appControlIndex);
491 ADD_PROFILING_POINT("getRunnableWidgetObject", "stop");
494 LogError("RunnableWidgetObject is NULL, stop launchStep");
495 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
500 if (m_widgetState == WidgetState_Running) {
501 LogWarning("Widget already running, stop launchStep");
502 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
507 if (m_widgetState == WidgetState_Authorizing) {
508 LogWarning("Widget already authorizing, stop launchStep");
509 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
514 m_dao.reset(new WrtDB::WidgetDAOReadOnly(DPL::FromASCIIString(m_tizenId)));
515 WrtDB::WidgetSettings widgetSettings;
516 m_dao->getWidgetSettings(widgetSettings);
517 m_settingList.reset(new WidgetSettingList(widgetSettings));
519 DPL::Optional<DPL::String> defloc = m_dao->getDefaultlocale();
520 if (!defloc.IsNull()) {
521 LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(
525 setInitialViewMode();
526 PrepareExternalStorageSingleton::Instance().Initialize(m_dao->getTizenPkgId());
528 /* remove language change callback */
530 LocalizationSetting::SetLanguageChangedCallback(
531 languageChangedCallback, this);
534 ADD_PROFILING_POINT("CreateWindow", "start");
535 if (s_preparedWindowData == NULL) {
536 m_windowData.reset(new WindowData(static_cast<unsigned long>(getpid()), true));
538 m_windowData.reset(s_preparedWindowData);
539 s_preparedWindowData = NULL;
541 ADD_PROFILING_POINT("CreateWindow", "stop");
543 // rotate window to initial value
544 setWindowInitialOrientation();
547 WRT::UserDelegatesPtr cbs(new WRT::UserDelegates);
549 ADD_PROFILING_POINT("Create splash screen", "start");
550 DPL::OptionalString splashImgSrc = m_dao->getSplashImgSrc();
551 if (!splashImgSrc.IsNull())
553 m_splashScreen.reset(new SplashScreenSupport(m_windowData->m_win,
554 (DPL::ToUTF8String(*splashImgSrc)).c_str(),
555 m_currentViewMode != VIEWMODE_TYPE_FULLSCREEN,
556 m_settingList->getRotationValue() == Screen_Landscape));
557 m_splashScreen->startSplashScreen();
559 ADD_PROFILING_POINT("Create splash screen", "stop");
561 DPL::OptionalString startUrl = W3CFileLocalization::getStartFile(m_dao);
562 if (!m_widget->PrepareView(DPL::ToUTF8String(*startUrl),
563 m_windowData->m_win, s_preparedEwkContext))
565 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
569 // send rotate information to ewk
570 setEwkInitialOrientation();
572 //you can't show window with splash screen before PrepareView
573 //ewk_view_add_with_context() in viewLogic breaks window
574 m_windowData->init();
575 m_windowData->focusCallbackAdd("focused", focusedCallback, this);
576 m_windowData->focusCallbackAdd("unfocused", unfocusedCallback, this);
578 WrtDB::WidgetLocalizedInfo localizedInfo =
579 W3CFileLocalization::getLocalizedInfo(m_dao);
580 std::string name = "";
581 if (!(localizedInfo.name.IsNull())) {
582 name = DPL::ToUTF8String(*(localizedInfo.name));
584 elm_win_title_set(m_windowData->m_win, name.c_str());
587 evas_object_show(m_windowData->m_win);
589 initializeWindowModes();
591 m_widgetState = WidgetState_Authorizing;
592 if (!m_widget->CheckBeforeLaunch()) {
593 LogError("CheckBeforeLaunch failed, stop launchStep");
594 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
598 LogInfo("Widget launch accepted. Entering running state");
599 m_widgetState = WidgetState_Running;
601 cbs->progressStarted = DPL::MakeDelegate(this, &WrtClient::progressStartedCallback);
602 cbs->progress = DPL::MakeDelegate(this, &WrtClient::loadProgressCallback);
603 cbs->progressFinish = DPL::MakeDelegate(this, &WrtClient::progressFinishCallback);
604 cbs->loadFinish = DPL::MakeDelegate(this, &WrtClient::loadFinishCallback);
605 cbs->reset = DPL::MakeDelegate(this, &WrtClient::resetCallback);
606 cbs->bufferSet = DPL::MakeDelegate(this, &WrtClient::setLayout);
607 cbs->bufferUnset = DPL::MakeDelegate(this, &WrtClient::unsetLayout);
608 cbs->webkitExit = DPL::MakeDelegate(this, &WrtClient::webkitExitCallback);
609 cbs->webCrash = DPL::MakeDelegate(this, &WrtClient::webCrashCallback);
610 cbs->toggleFullscreen = DPL::MakeDelegate(this, &WrtClient::toggleFullscreenCallback);
611 cbs->setOrientation = DPL::MakeDelegate(this, &WrtClient::setWindowOrientation);
612 cbs->hwkey = DPL::MakeDelegate(this, &WrtClient::hwkeyCallback);
614 m_widget->SetUserDelegates(cbs);
616 m_windowData->emitSignalForUserLayout(EDJE_SHOW_BACKWARD_SIGNAL, "");
618 ADD_PROFILING_POINT("launchStep", "stop");
621 void WrtClient::initializeWindowModes()
623 Assert(m_windowData);
625 (m_settingList->getBackButtonPresence() == BackButton_Enable ||
626 m_currentViewMode == VIEWMODE_TYPE_WINDOWED);
627 m_windowData->setViewMode(m_currentViewMode == VIEWMODE_TYPE_FULLSCREEN,
631 void WrtClient::backButtonCallback(void* data,
632 Evas_Object * /*obj*/,
633 void * /*event_info*/)
635 LogInfo("BackButtonCallback");
638 WrtClient* This = static_cast<WrtClient*>(data);
639 This->m_widget->Backward();
642 Eina_Bool WrtClient::naviframeBackButtonCallback(void* data,
643 Elm_Object_Item* /*it*/)
645 LogInfo("BackButtonCallback");
648 WrtClient* This = static_cast<WrtClient*>(data);
649 This->m_widget->Backward();
653 int WrtClient::appcoreLowMemoryCallback(void* /*data*/)
655 LogInfo("appcoreLowMemoryCallback");
656 //WrtClient* This = static_cast<WrtClient*>(data);
658 // TODO call RunnableWidgetObject API regarding low memory
659 // The API should be implemented
661 // temporary solution because we have no way to get ewk_context from runnable object.
662 if (s_preparedEwkContext)
664 ewk_context_cache_clear(s_preparedEwkContext);
665 ewk_context_notify_low_memory(s_preparedEwkContext);
671 void WrtClient::setInitialViewMode(void)
674 WrtDB::WindowModeList windowModes = m_dao->getWindowModes();
675 FOREACH(it, windowModes) {
676 std::string viewMode = DPL::ToUTF8String(*it);
677 switch(viewMode[0]) {
679 if (viewMode == VIEWMODE_TYPE_FULLSCREEN) {
680 m_initialViewMode = viewMode;
681 m_currentViewMode = m_initialViewMode;
686 if (viewMode == VIEWMODE_TYPE_MAXIMIZED) {
687 m_initialViewMode = viewMode;
688 m_currentViewMode = m_initialViewMode;
693 if (viewMode == VIEWMODE_TYPE_WINDOWED) {
694 m_initialViewMode = viewMode;
695 m_currentViewMode = m_initialViewMode;
705 void WrtClient::setWindowInitialOrientation(void)
707 Assert(m_windowData);
710 WidgetSettingScreenLock rotationValue = m_settingList->getRotationValue();
711 if (rotationValue == Screen_Portrait) {
712 setWindowOrientation(OrientationAngle::Window::Portrait::PRIMARY);
713 } else if (rotationValue == Screen_Landscape) {
714 setWindowOrientation(OrientationAngle::Window::Landscape::PRIMARY);
715 } else if (rotationValue == Screen_AutoRotation) {
716 if (!AutoRotationSupport::setAutoRotation(m_windowData->m_win,
717 autoRotationCallback,
720 LogError("Fail to set auto rotation");
723 setWindowOrientation(OrientationAngle::Window::Portrait::PRIMARY);
727 void WrtClient::setWindowOrientation(int angle)
729 Assert(m_windowData);
730 m_windowData->setOrientation(angle);
733 void WrtClient::unsetWindowOrientation(void)
735 Assert(m_windowData);
738 WidgetSettingScreenLock rotationValue = m_settingList->getRotationValue();
739 if (rotationValue == Screen_AutoRotation) {
740 AutoRotationSupport::unsetAutoRotation(m_windowData->m_win, autoRotationCallback);
744 void WrtClient::setEwkInitialOrientation(void)
749 WidgetSettingScreenLock rotationValue = m_settingList->getRotationValue();
750 if (rotationValue == Screen_Portrait) {
751 ewk_view_orientation_send(
752 m_widget->GetCurrentWebview(),
753 OrientationAngle::W3C::Portrait::PRIMARY);
754 } else if (rotationValue == Screen_Landscape) {
755 ewk_view_orientation_send(
756 m_widget->GetCurrentWebview(),
757 OrientationAngle::W3C::Landscape::PRIMARY);
758 } else if (rotationValue == Screen_AutoRotation) {
759 ewk_view_orientation_send(
760 m_widget->GetCurrentWebview(),
761 OrientationAngle::W3C::Portrait::PRIMARY);
763 ewk_view_orientation_send(
764 m_widget->GetCurrentWebview(),
765 OrientationAngle::W3C::Portrait::PRIMARY);
769 void WrtClient::setCtxpopupItem(void)
771 WindowData::CtxpopupItemDataList data;
774 WindowData::CtxpopupCallbackType shareCallback =
775 DPL::MakeDelegate(this, &WrtClient::ctxpopupShare);
776 WindowData::CtxpopupItemData shareData("Share",
781 WindowData::CtxpopupCallbackType reloadCallback =
782 DPL::MakeDelegate(this, &WrtClient::ctxpopupReload);
783 WindowData::CtxpopupItemData reloadData("Reload",
787 // 3. Open in browser
788 WindowData::CtxpopupCallbackType launchBrowserCallback =
789 DPL::MakeDelegate(this, &WrtClient::ctxpopupLaunchBrowser);
790 WindowData::CtxpopupItemData launchBrowserData("Open in browser",
792 launchBrowserCallback);
793 data.push_back(shareData);
794 data.push_back(reloadData);
795 data.push_back(launchBrowserData);
796 m_windowData->setCtxpopupItemData(data);
799 void WrtClient::ctxpopupShare(void)
802 const char* url = ewk_view_url_get(m_widget->GetCurrentWebview());
804 LogError("url is empty");
807 if (ClientModule::ServiceSupport::launchShareService(
808 elm_win_xwindow_get(m_windowData->m_win),
817 void WrtClient::ctxpopupReload(void)
820 ewk_view_reload(m_widget->GetCurrentWebview());
823 void WrtClient::ctxpopupLaunchBrowser(void)
825 LogDebug("launchBrowser");
826 const char* url = ewk_view_url_get(m_widget->GetCurrentWebview());
828 LogError("url is empty");
831 if (ClientModule::ServiceSupport::launchViewService(
832 elm_win_xwindow_get(m_windowData->m_win),
841 void WrtClient::hwkeyCallback(const std::string& key)
843 if (m_settingList->getBackButtonPresence() == BackButton_Enable
844 || m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
846 if (key == KeyName::BACK) {
847 if (m_isWebkitFullscreen) {
848 ewk_view_fullscreen_exit(m_widget->GetCurrentWebview());
850 m_widget->Backward();
852 } else if (key == KeyName::MENU) {
853 // UX isn't confirmed
854 // m_windowData->showCtxpopup();
859 void WrtClient::setLayout(Evas_Object* newBuffer)
861 LogDebug("add new webkit buffer to window");
863 m_windowData->setEvasObjectForLayout(newBuffer);
864 evas_object_show(newBuffer);
865 evas_object_show(m_windowData->m_win);
868 void WrtClient::unsetLayout(Evas_Object* currentBuffer)
870 LogDebug("remove current webkit buffer from window");
871 Assert(currentBuffer);
872 evas_object_hide(currentBuffer);
873 m_windowData->unsetEvasObjectForLayout();
876 void WrtClient::shutdownStep()
878 LogDebug("Closing Wrt connection ...");
880 if (m_widget && m_widgetState) {
881 m_widgetState = WidgetState_Stopped;
883 // AutoRotation, focusCallback use m_widget pointer internally.
884 // It must be unset before m_widget is released.
885 unsetWindowOrientation();
886 m_windowData->focusCallbackDel("focused", focusedCallback);
887 m_windowData->focusCallbackDel("unfocused", unfocusedCallback);
889 ewk_context_delete(s_preparedEwkContext);
890 PrepareExternalStorageSingleton::Instance().Deinitialize();
891 WRT::CoreModuleSingleton::Instance().Terminate();
894 m_initialized = false;
896 m_windowData.reset();
900 void WrtClient::autoRotationCallback(void* data, Evas_Object* obj, void* /*event*/)
907 WrtClient* This = static_cast<WrtClient*>(data);
909 This->autoRotationSetOrientation(obj);
912 void WrtClient::focusedCallback(void* data,
913 Evas_Object* /*obj*/,
918 WrtClient* This = static_cast<WrtClient*>(data);
919 elm_object_focus_set(This->m_widget->GetCurrentWebview(), EINA_TRUE);
922 void WrtClient::unfocusedCallback(void* data,
923 Evas_Object* /*obj*/,
928 WrtClient* This = static_cast<WrtClient*>(data);
929 elm_object_focus_set(This->m_widget->GetCurrentWebview(), EINA_FALSE);
932 void WrtClient::autoRotationSetOrientation(Evas_Object* obj)
937 AutoRotationSupport::setOrientation(obj, m_widget->GetCurrentWebview(),
938 (m_splashScreen) ? m_splashScreen.get(): NULL);
941 int WrtClient::languageChangedCallback(void *data)
943 LogDebug("Language Changed");
947 WrtClient* wrtClient = static_cast<WrtClient*>(data);
948 if (!(wrtClient->m_dao)) {
952 // reset function fetches system locales and recreates language tags
953 LanguageTagsProviderSingleton::Instance().resetLanguageTags();
954 // widget default locales are added to language tags below
955 DPL::OptionalString defloc = wrtClient->m_dao->getDefaultlocale();
956 if (!defloc.IsNull()) {
957 LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(
961 if (wrtClient->m_launched &&
962 wrtClient->m_widgetState != WidgetState_Stopped)
964 wrtClient->m_widget->ReloadStartPage();
969 void WrtClient::Quit()
972 DPL::Application::Quit();
975 static Eina_Bool proces_pool_fd_handler(void* /*data*/, Ecore_Fd_Handler *handler)
977 int fd = ecore_main_fd_handler_fd_get(handler);
979 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR))
981 LogDebug("ECORE_FD_ERROR");
989 return ECORE_CALLBACK_CANCEL;
992 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ))
994 LogDebug("ECORE_FD_READ");
996 app_pkt_t* pkt = (app_pkt_t*) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
997 memset(pkt, 0, AUL_SOCK_MAXBUFF);
999 int recv_ret = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0);
1008 LogDebug("recv error!");
1011 LogDebug("recv_ret : " << recv_ret << ", pkt->len : " << pkt->len);
1013 ecore_main_fd_handler_del(handler);
1015 process_pool_launchpad_main_loop(pkt, app_argv[0], &app_argc, &app_argv);
1020 ecore_main_loop_quit();
1021 return ECORE_CALLBACK_CANCEL;
1024 return ECORE_CALLBACK_CANCEL;
1027 static void vconf_changed_handler(keynode_t* /*key*/, void* /*data*/)
1029 LogInfo("VCONFKEY_LANGSET vconf-key was changed!");
1031 // When system language is changed, the candidate process will be created again.
1037 // set evas backend type
1038 if (!getenv("ELM_ENGINE"))
1040 if (!setenv("ELM_ENGINE", "gl", 1))
1042 LogDebug("Enable backend");
1047 LogDebug("ELM_ENGINE : " << getenv("ELM_ENGINE"));
1050 #ifndef TIZEN_PUBLIC
1051 setenv("COREGL_FASTPATH", "1", 1);
1053 setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
1054 setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1);
1055 setenv("ELM_IMAGE_CACHE", "0", 1);
1061 // process pool - store arg's value
1065 UNHANDLED_EXCEPTION_HANDLER_BEGIN
1067 ADD_PROFILING_POINT("main-entered", "point");
1070 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
1072 // Set environment variables
1075 if (argc > 1 && argv[1] != NULL && !strcmp(argv[1], "-d"))
1077 LogInfo("Entered dummy process mode");
1078 sprintf(argv[0], "%s ",
1079 DUMMY_PROCESS_PATH);
1081 // Set 'root' home directory
1082 setenv(HOME, ROOT_HOME_PATH, 1);
1084 LogInfo("Prepare ewk_context");
1085 appcore_set_i18n("wrt-client", NULL);
1086 ewk_set_arguments(argc, argv);
1087 setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1);
1088 s_preparedEwkContext = ewk_context_new_with_injected_bundle_path(BUNDLE_PATH);
1090 if (s_preparedEwkContext == NULL)
1092 LogInfo("Creating webkit context was failed!");
1096 int client_fd = __connect_process_pool_server();
1098 if (client_fd == -1)
1100 LogInfo("Connecting process_pool_server was failed!");
1104 // register language changed callback
1105 vconf_notify_key_changed(VCONFKEY_LANGSET, vconf_changed_handler, NULL);
1107 LogInfo("Prepare window_data");
1108 // Temporarily change HOME path to app
1109 // This change is needed for getting elementary profile
1110 // /opt/home/app/.elementary/config/mobile/base.cfg
1111 const char* backupEnv = getenv(HOME);
1112 setenv(HOME, APP_HOME_PATH, 1);
1113 LogInfo("elm_init()");
1114 elm_init(argc, argv);
1115 setenv(HOME, backupEnv, 1);
1117 LogInfo("WindowData()");
1118 s_preparedWindowData = new WindowData(static_cast<unsigned long>(getpid()));
1120 Ecore_Fd_Handler* fd_handler = ecore_main_fd_handler_add(client_fd,
1121 (Ecore_Fd_Handler_Flags)(ECORE_FD_READ|ECORE_FD_ERROR),
1122 proces_pool_fd_handler, NULL, NULL, NULL);
1124 if (fd_handler == NULL)
1126 LogInfo("fd_handler is NULL");
1130 setpriority(PRIO_PROCESS, 0, 0);
1132 LogDebug("ecore_main_loop_begin()");
1133 ecore_main_loop_begin();
1134 LogDebug("ecore_main_loop_begin()_end");
1136 // deregister language changed callback
1137 vconf_ignore_key_changed(VCONFKEY_LANGSET, vconf_changed_handler);
1139 std::string tizenId = WrtClient::getTizenIdFromArgument(argc, argv);
1140 ewk_context_message_post_to_injected_bundle(
1141 s_preparedEwkContext,
1142 MESSAGE_NAME_INITIALIZE,
1148 // This code is to fork a web process without exec.
1149 std::string tizenId = WrtClient::getTizenIdFromArgument(argc, argv);
1150 if (!tizenId.empty()) {
1152 tizenId.find(WrtDB::AppControlPrefix::PROCESS_PREFIX);
1153 if (pos != std::string::npos) {
1157 LogDebug("Launching by fork mode");
1158 // Language env setup
1159 appcore_set_i18n("wrt-client", NULL);
1160 ewk_set_arguments(argc, argv);
1161 setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1);
1162 s_preparedEwkContext = ewk_context_new_with_injected_bundle_path(
1165 if (s_preparedEwkContext == NULL)
1167 LogInfo("Creating webkit context was failed!");
1168 Wrt::Popup::PopupInvoker().showInfo("Error", "Creating webkit context was failed.", "OK");
1173 ewk_context_message_post_to_injected_bundle(
1174 s_preparedEwkContext,
1175 MESSAGE_NAME_INITIALIZE,
1180 // Output on stdout will be flushed after every newline character,
1181 // even if it is redirected to a pipe. This is useful for running
1182 // from a script and parsing output.
1183 // (Standard behavior of stdlib is to use full buffering when
1184 // redirected to a pipe, which means even after an end of line
1185 // the output may not be flushed).
1188 WrtClient app(app_argc, app_argv);
1190 ADD_PROFILING_POINT("Before appExec", "point");
1191 int ret = app.Exec();
1192 LogDebug("App returned: " << ret);
1193 ret = app.getReturnStatus();
1194 LogDebug("WrtClient returned: " << ret);
1197 UNHANDLED_EXCEPTION_HANDLER_END