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 "menu_db_util.h"
42 #include "launchpad_util.h"
45 #include "client_service_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_BACKWARD_SIGNAL = "show,backward,signal";
53 const char *EDJE_SHOW_PROGRESS_SIGNAL = "show,progress,signal";
54 const char *EDJE_HIDE_PROGRESS_SIGNAL = "hide,progress,signal";
55 const std::string VIEWMODE_TYPE_FULLSCREEN = "fullscreen";
56 const std::string VIEWMODE_TYPE_MAXIMIZED = "maximized";
57 const std::string VIEWMODE_TYPE_WINDOWED = "windowed";
58 char const* const ELM_SWALLOW_CONTENT = "elm.swallow.content";
59 const char* const BUNDLE_PATH = "/usr/lib/libwrt-injected-bundle.so";
60 const char* const caCertPath = "/opt/usr/share/certs/ca-certificate.crt";
61 const char* const MESSAGE_NAME_INITIALIZE = "ToInjectedBundle::INIT";
64 const char* const DUMMY_PROCESS_PATH = "/usr/bin/wrt_launchpad_daemon_candidate";
65 static Ewk_Context* s_preparedEwkContext = NULL;
66 static WindowData* s_preparedWindowData = NULL;
67 static int app_argc = 0;
68 static char** app_argv = NULL;
71 const char* const HOME = "HOME";
72 const char* const APP_HOME_PATH = "/opt/home/app";
73 const char* const ROOT_HOME_PATH = "/opt/home/root";
75 WrtClient::WrtClient(int argc, char **argv) :
76 Application(argc, argv, "wrt-client", false),
77 DPL::TaskDecl<WrtClient>(this),
78 m_appControlIndex(DPL::OptionalUInt()),
80 m_initializing(false),
85 m_returnStatus(ReturnStatus::Succeeded),
86 m_widgetState(WidgetState::WidgetState_Stopped),
87 m_initialViewMode(VIEWMODE_TYPE_MAXIMIZED),
88 m_currentViewMode(VIEWMODE_TYPE_MAXIMIZED)
91 LogDebug("App Created");
94 WrtClient::~WrtClient()
96 LogDebug("App Finished");
99 WrtClient::ReturnStatus::Type WrtClient::getReturnStatus() const
101 return m_returnStatus;
104 void WrtClient::OnStop()
106 LogInfo("Stopping Dummy Client");
109 void WrtClient::OnCreate()
111 LogInfo("On Create");
112 ADD_PROFILING_POINT("OnCreate callback", "point");
116 void WrtClient::OnResume()
118 if (m_widgetState != WidgetState_Suspended) {
119 LogWarning("Widget is not suspended, resuming was skipped");
123 m_widgetState = WidgetState_Running;
126 void WrtClient::OnPause()
128 if (m_widgetState != WidgetState_Running) {
129 LogWarning("Widget is not running to be suspended");
133 m_widgetState = WidgetState_Suspended;
136 void WrtClient::OnReset(bundle *b)
139 // bundle argument is freed after OnReset() is returned
140 // So bundle duplication is needed
141 ApplicationDataSingleton::Instance().setBundle(bundle_dup(b));
142 ApplicationDataSingleton::Instance().setEncodedBundle(b);
144 if (true == m_initializing) {
145 LogDebug("can not handle reset event");
148 if (true == m_launched) {
149 if (m_widgetState == WidgetState_Stopped) {
150 LogError("Widget is not running to be reset");
154 m_windowData->emitSignalForUserLayout(EDJE_SHOW_BACKWARD_SIGNAL, "");
155 m_widgetState = WidgetState_Running;
157 if (true == checkArgument()) {
164 // low memory callback set
165 appcore_set_event_callback(
166 APPCORE_EVENT_LOW_MEMORY,
167 WrtClient::appcoreLowMemoryCallback,
171 void WrtClient::OnTerminate()
173 LogDebug("Wrt Shutdown now");
177 void WrtClient::showHelpAndQuit()
179 printf("Usage: wrt-client [OPTION]... [WIDGET: ID]...\n"
181 "Mandatory arguments to long options are mandatory for short "
183 " -h, --help show this help\n"
185 "launch widget with given tizen ID\n"
187 "launch widget with given tizen ID\n"
193 bool WrtClient::checkArgument()
195 std::string tizenId = getTizenIdFromArgument(m_argc, m_argv);
197 if (tizenId.empty()) {
202 tizenId.find(WrtDB::AppControlPrefix::PROCESS_PREFIX);
203 if (pos != std::string::npos) {
204 std::string id = tizenId.substr(pos);
205 id.erase(strlen(WrtDB::AppControlPrefix::PROCESS_PREFIX));
206 std::stringstream s(id);
207 unsigned int appControlIndex;
208 s >> appControlIndex;
209 m_appControlIndex = appControlIndex;
211 LogDebug("app-control execute-index : " << appControlIndex);
214 LogDebug("Tizen id: " << m_tizenId);
219 std::string WrtClient::getTizenIdFromArgument(int argc, char **argv)
221 LogInfo("checkArgument");
222 std::string arg = argv[0];
228 if (arg.find("wrt-client") != std::string::npos) {
235 if (arg == "-h" || arg == "--help") {
237 } else if (arg == "-l" || arg == "--launch" ||
238 arg == "-t" || arg == "--tizen")
248 // Launch widget based on application basename
249 size_t pos = arg.find_last_of('/');
251 if (pos != std::string::npos) {
252 arg = arg.erase(0, pos + 1);
259 void WrtClient::setStep()
263 AddStep(&WrtClient::initStep);
265 setSdkLauncherDebugData();
267 AddStep(&WrtClient::launchStep);
268 AddStep(&WrtClient::shutdownStep);
270 m_initializing = true;
272 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
275 void WrtClient::setSdkLauncherDebugData()
277 LogDebug("setSdkLauncherDebugData");
279 /* check bundle from sdk launcher */
280 bundle *bundleFromSdkLauncher;
281 bundleFromSdkLauncher = bundle_import_from_argv(m_argc, m_argv);
282 const char *bundle_debug = bundle_get_val(bundleFromSdkLauncher, "debug");
283 const char *bundle_pid = bundle_get_val(bundleFromSdkLauncher, "pid");
284 if (bundle_debug != NULL && bundle_pid != NULL) {
285 if (strcmp(bundle_debug, "true") == 0) {
287 m_sdkLauncherPid = atoi(bundle_pid);
292 bundle_free(bundleFromSdkLauncher);
295 bool WrtClient::checkDebugMode(SDKDebugData* debugData)
297 LogError("Checking for debug mode");
300 bool debugMode = debugData->debugMode;
302 LogInfo("[DEBUG_MODE] Widget is launched in " <<
303 (debugMode ? "DEBUG" : "RETAIL") <<
309 void WrtClient::OnEventReceived(const NextStepEvent& /*event*/)
311 LogDebug("Executing next step");
315 void WrtClient::initStep()
318 if (WRT::CoreModuleSingleton::Instance().Init()) {
319 m_initialized = true;
321 m_returnStatus = ReturnStatus::Failed;
322 SwitchToStep(&WrtClient::shutdownStep);
325 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
328 void WrtClient::loadFinishCallback(Evas_Object* webview)
330 ADD_PROFILING_POINT("loadFinishCallback", "start");
333 if (m_splashScreen && m_splashScreen->isShowing())
335 m_splashScreen->stopSplashScreenBuffered();
338 SDKDebugData* debug = new SDKDebugData;
339 debug->debugMode = m_debugMode;
340 debug->pid = new unsigned long(getpid());
342 LogInfo("Post result of launch");
344 // Start inspector server, if current mode is debugger mode.
345 // In the WK2 case, ewk_view_inspector_server_start should
346 // be called after WebProcess is created.
347 if (checkDebugMode(debug)) {
349 ewk_view_inspector_server_start(m_widget->GetCurrentWebview(), 0);
350 if (debug->portnum == 0) {
351 LogWarning("Failed to get portnum");
353 LogInfo("Assigned port number for inspector : "
357 LogDebug("Debug mode is disabled");
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 FILE* doutput = fdopen(4, "w");
364 fprintf(doutput, "didFinishLoadForFrameCallback: ready\n");
369 LogDebug("Launch succesfull");
372 m_initializing = false;
374 ADD_PROFILING_POINT("loadFinishCallback", "stop");
375 printf("launched\n");
380 m_returnStatus = ReturnStatus::Failed;
382 DPL::Event::ControllerEventHandler<NextStepEvent>::
383 PostEvent(NextStepEvent());
386 if (debug->debugMode) {
387 LogDebug("Send RT signal to wrt-launcher(pid: " << m_sdkLauncherPid);
389 /* send real time signal with result to wrt-launcher */
391 LogDebug("userData->portnum : " << debug->portnum);
392 sv.sival_int = debug->portnum;
397 bundle* request = NULL;
398 appsvc_create_result_bundle(
399 ApplicationDataSingleton::Instance().getBundle(),
401 char port[10] = {0,};
402 sprintf(port, "%d", debug->portnum);
403 appsvc_add_data(request, "port", port);
404 appsvc_send_result(request, APPSVC_RES_OK);
407 ApplicationDataSingleton::Instance().freeBundle();
409 LogDebug("Cleaning wrtClient launch resources...");
414 void WrtClient::progressStartedCallback()
416 if (m_settingList->getProgressBarPresence() == ProgressBar_Enable ||
417 m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
419 m_windowData->emitSignalForUserLayout(EDJE_SHOW_PROGRESS_SIGNAL, "");
420 m_windowData->updateProgress(0);
424 void WrtClient::loadProgressCallback(Evas_Object* /*webview*/, double value)
426 if (m_settingList->getProgressBarPresence() == ProgressBar_Enable ||
427 m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
429 m_windowData->updateProgress(value);
433 void WrtClient::progressFinishCallback()
435 if (m_settingList->getProgressBarPresence() == ProgressBar_Enable ||
436 m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
438 m_windowData->emitSignalForUserLayout(EDJE_HIDE_PROGRESS_SIGNAL, "");
442 void WrtClient::webkitExitCallback()
444 LogDebug("window close called, terminating app");
445 SwitchToStep(&WrtClient::shutdownStep);
446 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
450 void WrtClient::webCrashCallback()
452 LogError("webProcess crashed");
453 SwitchToStep(&WrtClient::shutdownStep);
454 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
458 void WrtClient::toggleFullscreenCallback(bool fullscreen)
460 LogError("toggleFullscreen");
464 m_windowData->toggleFullscreen(true);
465 m_currentViewMode = VIEWMODE_TYPE_FULLSCREEN;
468 m_windowData->toggleFullscreen(false);
469 m_currentViewMode = m_initialViewMode;
473 void WrtClient::launchStep()
475 ADD_PROFILING_POINT("launchStep", "start");
476 LogDebug("Launching widget ...");
478 ADD_PROFILING_POINT("getRunnableWidgetObject", "start");
479 m_widget = WRT::CoreModuleSingleton::Instance()
480 .getRunnableWidgetObject(m_tizenId, m_appControlIndex);
481 ADD_PROFILING_POINT("getRunnableWidgetObject", "stop");
484 LogError("RunnableWidgetObject is NULL, stop launchStep");
485 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
490 if (m_widgetState == WidgetState_Running) {
491 LogWarning("Widget already running, stop launchStep");
492 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
497 if (m_widgetState == WidgetState_Authorizing) {
498 LogWarning("Widget already authorizing, stop launchStep");
499 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
504 m_dao.reset(new WrtDB::WidgetDAOReadOnly(DPL::FromASCIIString(m_tizenId)));
505 WrtDB::WidgetSettings widgetSettings;
506 m_dao->getWidgetSettings(widgetSettings);
507 m_settingList.reset(new WidgetSettingList(widgetSettings));
509 DPL::Optional<DPL::String> defloc = m_dao->getDefaultlocale();
510 if (!defloc.IsNull()) {
511 LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(
515 setInitialViewMode();
516 PrepareExternalStorageSingleton::Instance().Initialize(m_dao->getTizenPkgId());
518 /* remove language change callback */
520 LocalizationSetting::SetLanguageChangedCallback(
521 languageChangedCallback, this);
524 ADD_PROFILING_POINT("CreateWindow", "start");
525 if (s_preparedWindowData == NULL) {
526 m_windowData.reset(new WindowData(static_cast<unsigned long>(getpid()), true));
528 m_windowData.reset(s_preparedWindowData);
529 s_preparedWindowData = NULL;
531 ADD_PROFILING_POINT("CreateWindow", "stop");
533 // rotate window to initial value
534 setWindowInitialOrientation();
537 WRT::UserDelegatesPtr cbs(new WRT::UserDelegates);
539 ADD_PROFILING_POINT("Create splash screen", "start");
540 DPL::OptionalString splashImgSrc = m_dao->getSplashImgSrc();
541 if (!splashImgSrc.IsNull())
543 m_splashScreen.reset(new SplashScreenSupport(m_windowData->m_win,
544 (DPL::ToUTF8String(*splashImgSrc)).c_str(),
545 m_currentViewMode != VIEWMODE_TYPE_FULLSCREEN,
546 m_settingList->getRotationValue() == Screen_Landscape));
547 m_splashScreen->startSplashScreen();
549 ADD_PROFILING_POINT("Create splash screen", "stop");
551 DPL::OptionalString startUrl = W3CFileLocalization::getStartFile(m_dao);
552 if (!m_widget->PrepareView(DPL::ToUTF8String(*startUrl),
553 m_windowData->m_win, s_preparedEwkContext))
555 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
559 // send rotate information to ewk
560 setEwkInitialOrientation();
562 //you can't show window with splash screen before PrepareView
563 //ewk_view_add_with_context() in viewLogic breaks window
564 m_windowData->init();
566 WrtDB::WidgetLocalizedInfo localizedInfo =
567 W3CFileLocalization::getLocalizedInfo(m_dao);
568 std::string name = "";
569 if (!(localizedInfo.name.IsNull())) {
570 name = DPL::ToUTF8String(*(localizedInfo.name));
572 elm_win_title_set(m_windowData->m_win, name.c_str());
575 evas_object_show(m_windowData->m_win);
577 initializeWindowModes();
579 m_widgetState = WidgetState_Authorizing;
580 if (!m_widget->CheckBeforeLaunch()) {
581 LogError("CheckBeforeLaunch failed, stop launchStep");
582 DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
586 LogInfo("Widget launch accepted. Entering running state");
587 m_widgetState = WidgetState_Running;
589 cbs->progressStarted = DPL::MakeDelegate(this, &WrtClient::progressStartedCallback);
590 cbs->progress = DPL::MakeDelegate(this, &WrtClient::loadProgressCallback);
591 cbs->progressFinish = DPL::MakeDelegate(this, &WrtClient::progressFinishCallback);
592 cbs->loadFinish = DPL::MakeDelegate(this, &WrtClient::loadFinishCallback);
593 cbs->bufferSet = DPL::MakeDelegate(this, &WrtClient::setLayout);
594 cbs->bufferUnset = DPL::MakeDelegate(this, &WrtClient::unsetLayout);
595 cbs->webkitExit = DPL::MakeDelegate(this, &WrtClient::webkitExitCallback);
596 cbs->webCrash = DPL::MakeDelegate(this, &WrtClient::webCrashCallback);
597 cbs->toggleFullscreen = DPL::MakeDelegate(this, &WrtClient::toggleFullscreenCallback);
598 cbs->setOrientation = DPL::MakeDelegate(this, &WrtClient::setWindowOrientation);
599 cbs->hwkey = DPL::MakeDelegate(this, &WrtClient::hwkeyCallback);
601 m_widget->SetUserDelegates(cbs);
603 m_windowData->emitSignalForUserLayout(EDJE_SHOW_BACKWARD_SIGNAL, "");
605 ADD_PROFILING_POINT("launchStep", "stop");
608 void WrtClient::initializeWindowModes()
610 Assert(m_windowData);
612 (m_settingList->getBackButtonPresence() == BackButton_Enable ||
613 m_currentViewMode == VIEWMODE_TYPE_WINDOWED);
614 m_windowData->setViewMode(m_currentViewMode == VIEWMODE_TYPE_FULLSCREEN,
618 void WrtClient::backButtonCallback(void* data,
619 Evas_Object * /*obj*/,
620 void * /*event_info*/)
622 LogInfo("BackButtonCallback");
625 WrtClient* This = static_cast<WrtClient*>(data);
626 This->m_widget->Backward();
629 Eina_Bool WrtClient::naviframeBackButtonCallback(void* data,
630 Elm_Object_Item* /*it*/)
632 LogInfo("BackButtonCallback");
635 WrtClient* This = static_cast<WrtClient*>(data);
636 This->m_widget->Backward();
640 int WrtClient::appcoreLowMemoryCallback(void* /*data*/)
642 LogInfo("appcoreLowMemoryCallback");
643 //WrtClient* This = static_cast<WrtClient*>(data);
645 // TODO call RunnableWidgetObject API regarding low memory
646 // The API should be implemented
651 void WrtClient::setInitialViewMode(void)
654 WrtDB::WindowModeList windowModes = m_dao->getWindowModes();
655 FOREACH(it, windowModes) {
656 std::string viewMode = DPL::ToUTF8String(*it);
657 switch(viewMode[0]) {
659 if (viewMode == VIEWMODE_TYPE_FULLSCREEN) {
660 m_initialViewMode = viewMode;
661 m_currentViewMode = m_initialViewMode;
666 if (viewMode == VIEWMODE_TYPE_MAXIMIZED) {
667 m_initialViewMode = viewMode;
668 m_currentViewMode = m_initialViewMode;
673 if (viewMode == VIEWMODE_TYPE_WINDOWED) {
674 m_initialViewMode = viewMode;
675 m_currentViewMode = m_initialViewMode;
685 void WrtClient::setWindowInitialOrientation(void)
687 Assert(m_windowData);
690 WidgetSettingScreenLock rotationValue = m_settingList->getRotationValue();
691 if (rotationValue == Screen_Portrait) {
692 setWindowOrientation(OrientationAngle::Window::Portrait::PRIMARY);
693 } else if (rotationValue == Screen_Landscape) {
694 setWindowOrientation(OrientationAngle::Window::Landscape::PRIMARY);
695 } else if (rotationValue == Screen_AutoRotation) {
696 if (!AutoRotationSupport::setAutoRotation(m_windowData->m_win,
697 autoRotationCallback,
700 LogError("Fail to set auto rotation");
703 setWindowOrientation(OrientationAngle::Window::Portrait::PRIMARY);
707 void WrtClient::setWindowOrientation(int angle)
709 Assert(m_windowData);
710 m_windowData->setOrientation(angle);
713 void WrtClient::unsetWindowOrientation(void)
715 Assert(m_windowData);
718 WidgetSettingScreenLock rotationValue = m_settingList->getRotationValue();
719 if (rotationValue == Screen_AutoRotation) {
720 AutoRotationSupport::unsetAutoRotation(m_windowData->m_win, autoRotationCallback);
724 void WrtClient::setEwkInitialOrientation(void)
729 WidgetSettingScreenLock rotationValue = m_settingList->getRotationValue();
730 if (rotationValue == Screen_Portrait) {
731 ewk_view_orientation_send(
732 m_widget->GetCurrentWebview(),
733 OrientationAngle::W3C::Portrait::PRIMARY);
734 } else if (rotationValue == Screen_Landscape) {
735 ewk_view_orientation_send(
736 m_widget->GetCurrentWebview(),
737 OrientationAngle::W3C::Landscape::PRIMARY);
738 } else if (rotationValue == Screen_AutoRotation) {
739 ewk_view_orientation_send(
740 m_widget->GetCurrentWebview(),
741 OrientationAngle::W3C::Portrait::PRIMARY);
743 ewk_view_orientation_send(
744 m_widget->GetCurrentWebview(),
745 OrientationAngle::W3C::Portrait::PRIMARY);
749 void WrtClient::setCtxpopupItem(void)
751 WindowData::CtxpopupItemDataList data;
754 WindowData::CtxpopupCallbackType shareCallback =
755 DPL::MakeDelegate(this, &WrtClient::ctxpopupShare);
756 WindowData::CtxpopupItemData shareData("Share",
761 WindowData::CtxpopupCallbackType reloadCallback =
762 DPL::MakeDelegate(this, &WrtClient::ctxpopupReload);
763 WindowData::CtxpopupItemData reloadData("Reload",
767 // 3. Open in browser
768 WindowData::CtxpopupCallbackType launchBrowserCallback =
769 DPL::MakeDelegate(this, &WrtClient::ctxpopupLaunchBrowser);
770 WindowData::CtxpopupItemData launchBrowserData("Open in browser",
772 launchBrowserCallback);
773 data.push_back(shareData);
774 data.push_back(reloadData);
775 data.push_back(launchBrowserData);
776 m_windowData->setCtxpopupItemData(data);
779 void WrtClient::ctxpopupShare(void)
782 const char* url = ewk_view_url_get(m_widget->GetCurrentWebview());
784 LogError("url is empty");
787 if (ClientModule::ServiceSupport::launchShareService(
788 elm_win_xwindow_get(m_windowData->m_win),
797 void WrtClient::ctxpopupReload(void)
800 ewk_view_reload(m_widget->GetCurrentWebview());
803 void WrtClient::ctxpopupLaunchBrowser(void)
805 LogDebug("launchBrowser");
806 const char* url = ewk_view_url_get(m_widget->GetCurrentWebview());
808 LogError("url is empty");
811 if (ClientModule::ServiceSupport::launchViewService(
812 elm_win_xwindow_get(m_windowData->m_win),
821 void WrtClient::hwkeyCallback(const std::string& key)
823 if (m_settingList->getBackButtonPresence() == BackButton_Enable
824 || m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
827 m_widget->Backward();
828 } else if (key == "menu") {
829 // UX isn't confirmed
830 // m_windowData->showCtxpopup();
835 void WrtClient::setLayout(Evas_Object* newBuffer)
837 LogDebug("add new webkit buffer to window");
840 elm_object_part_content_set(m_windowData->m_user_layout,
844 evas_object_show(newBuffer);
847 void WrtClient::unsetLayout(Evas_Object* currentBuffer)
849 LogDebug("remove current webkit buffer from window");
850 Assert(currentBuffer);
851 evas_object_hide(currentBuffer);
853 elm_object_part_content_unset(m_windowData->m_user_layout,
854 ELM_SWALLOW_CONTENT);
857 void WrtClient::shutdownStep()
859 LogDebug("Closing Wrt connection ...");
861 if (m_widget && m_widgetState) {
862 m_widgetState = WidgetState_Stopped;
864 // AutoRotation use m_widget pointer internally.
865 // It must be unset before m_widget is released.
866 unsetWindowOrientation();
868 ewk_context_delete(s_preparedEwkContext);
869 PrepareExternalStorageSingleton::Instance().Deinitialize();
870 WRT::CoreModuleSingleton::Instance().Terminate();
873 m_initialized = false;
875 m_windowData.reset();
879 void WrtClient::autoRotationCallback(void* data, Evas_Object* obj, void* /*event*/)
886 WrtClient* This = static_cast<WrtClient*>(data);
888 This->autoRotationSetOrientation(obj);
891 void WrtClient::autoRotationSetOrientation(Evas_Object* obj)
896 AutoRotationSupport::setOrientation(obj, m_widget->GetCurrentWebview(),
897 (m_splashScreen) ? m_splashScreen.get(): NULL);
900 int WrtClient::languageChangedCallback(void *data)
902 LogDebug("Language Changed");
906 WrtClient* wrtClient = static_cast<WrtClient*>(data);
907 if (!(wrtClient->m_dao)) {
911 // reset function fetches system locales and recreates language tags
912 LanguageTagsProviderSingleton::Instance().resetLanguageTags();
913 // widget default locales are added to language tags below
914 DPL::OptionalString defloc = wrtClient->m_dao->getDefaultlocale();
915 if (!defloc.IsNull()) {
916 LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(
920 if (wrtClient->m_launched &&
921 wrtClient->m_widgetState != WidgetState_Stopped)
923 wrtClient->m_widget->ReloadStartPage();
928 void WrtClient::Quit()
931 DPL::Application::Quit();
934 static Eina_Bool proces_pool_fd_handler(void* /*data*/, Ecore_Fd_Handler *handler)
936 int fd = ecore_main_fd_handler_fd_get(handler);
938 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR))
940 LogDebug("ECORE_FD_ERROR");
948 return ECORE_CALLBACK_CANCEL;
951 if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ))
953 LogDebug("ECORE_FD_READ");
955 app_pkt_t* pkt = (app_pkt_t*) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
956 memset(pkt, 0, AUL_SOCK_MAXBUFF);
958 int recv_ret = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0);
967 LogDebug("recv error!");
970 LogDebug("recv_ret : " << recv_ret << ", pkt->len : " << pkt->len);
972 ecore_main_fd_handler_del(handler);
974 __wrt_launchpad_main_loop(pkt, app_argv[0], &app_argc, &app_argv);
979 ecore_main_loop_quit();
980 return ECORE_CALLBACK_CANCEL;
983 return ECORE_CALLBACK_CANCEL;
986 static void vconf_changed_handler(keynode_t* /*key*/, void* /*data*/)
988 LogInfo("VCONFKEY_LANGSET vconf-key was changed!");
990 // When system language is changed, the candidate process will be created again.
996 // set evas backend type
997 if (!getenv("ELM_ENGINE"))
999 if (!setenv("ELM_ENGINE", "gl", 1))
1001 LogDebug("Enable backend");
1006 LogDebug("ELM_ENGINE : " << getenv("ELM_ENGINE"));
1009 #ifndef TIZEN_PUBLIC
1010 setenv("COREGL_FASTPATH", "1", 1);
1012 setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
1013 setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1);
1014 setenv("ELM_IMAGE_CACHE", "0", 1);
1020 // process pool - store arg's value
1024 UNHANDLED_EXCEPTION_HANDLER_BEGIN
1026 ADD_PROFILING_POINT("main-entered", "point");
1029 DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
1031 // Set environment variables
1034 if (argc > 1 && argv[1] != NULL && !strcmp(argv[1], "-d"))
1036 LogInfo("Entered dummy process mode");
1037 sprintf(argv[0], "%s ",
1038 DUMMY_PROCESS_PATH);
1040 // Set 'root' home directory
1041 setenv(HOME, ROOT_HOME_PATH, 1);
1043 LogInfo("Prepare ewk_context");
1044 appcore_set_i18n("wrt-client", NULL);
1045 ewk_set_arguments(argc, argv);
1046 setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1);
1047 s_preparedEwkContext = ewk_context_new_with_injected_bundle_path(BUNDLE_PATH);
1049 if (s_preparedEwkContext == NULL)
1051 LogInfo("Creating webkit context was failed!");
1055 int client_fd = __connect_process_pool_server();
1057 if (client_fd == -1)
1059 LogInfo("Connecting process_pool_server was failed!");
1063 // register language changed callback
1064 vconf_notify_key_changed(VCONFKEY_LANGSET, vconf_changed_handler, NULL);
1066 LogInfo("Prepare window_data");
1067 // Temporarily change HOME path to app
1068 // This change is needed for getting elementary profile
1069 // /opt/home/app/.elementary/config/mobile/base.cfg
1070 const char* backupEnv = getenv(HOME);
1071 setenv(HOME, APP_HOME_PATH, 1);
1072 LogInfo("elm_init()");
1073 elm_init(argc, argv);
1074 setenv(HOME, backupEnv, 1);
1076 LogInfo("WindowData()");
1077 s_preparedWindowData = new WindowData(static_cast<unsigned long>(getpid()));
1079 Ecore_Fd_Handler* fd_handler = ecore_main_fd_handler_add(client_fd,
1080 (Ecore_Fd_Handler_Flags)(ECORE_FD_READ|ECORE_FD_ERROR),
1081 proces_pool_fd_handler, NULL, NULL, NULL);
1083 if (fd_handler == NULL)
1085 LogInfo("fd_handler is NULL");
1089 setpriority(PRIO_PROCESS, 0, 0);
1091 LogDebug("ecore_main_loop_begin()");
1092 ecore_main_loop_begin();
1093 LogDebug("ecore_main_loop_begin()_end");
1095 // deregister language changed callback
1096 vconf_ignore_key_changed(VCONFKEY_LANGSET, vconf_changed_handler);
1098 std::string tizenId = WrtClient::getTizenIdFromArgument(argc, argv);
1099 ewk_context_message_post_to_injected_bundle(
1100 s_preparedEwkContext,
1101 MESSAGE_NAME_INITIALIZE,
1106 // This code is to fork a web process without exec.
1107 std::string tizenId = WrtClient::getTizenIdFromArgument(argc, argv);
1108 if (!tizenId.empty()) {
1110 tizenId.find(WrtDB::AppControlPrefix::PROCESS_PREFIX);
1111 if (pos != std::string::npos) {
1115 LogDebug("Launching by fork mode");
1116 // Language env setup
1117 appcore_set_i18n("wrt-client", NULL);
1118 ewk_set_arguments(argc, argv);
1119 setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1);
1120 s_preparedEwkContext = ewk_context_new_with_injected_bundle_path(
1123 if (s_preparedEwkContext == NULL)
1125 LogInfo("Creating webkit context was failed!");
1126 Wrt::Popup::PopupInvoker().showInfo("Error", "Creating webkit context was failed.", "OK");
1131 ewk_context_message_post_to_injected_bundle(
1132 s_preparedEwkContext,
1133 MESSAGE_NAME_INITIALIZE,
1138 // Output on stdout will be flushed after every newline character,
1139 // even if it is redirected to a pipe. This is useful for running
1140 // from a script and parsing output.
1141 // (Standard behavior of stdlib is to use full buffering when
1142 // redirected to a pipe, which means even after an end of line
1143 // the output may not be flushed).
1146 WrtClient app(app_argc, app_argv);
1148 ADD_PROFILING_POINT("Before appExec", "point");
1149 int ret = app.Exec();
1150 LogDebug("App returned: " << ret);
1151 ret = app.getReturnStatus();
1152 LogDebug("WrtClient returned: " << ret);
1155 UNHANDLED_EXCEPTION_HANDLER_END