* limitations under the License.
*/
#include "wrt-client.h"
+#include <aul.h>
+#include <sys/time.h>
+#include <sys/resource.h>
#include <appcore-efl.h>
#include <appcore-common.h>
#include <cstdlib>
#include <dpl/log/log.h>
#include <dpl/optional_typedefs.h>
#include <dpl/exception.h>
-#include <common/application_data.h>
+#include <application_data.h>
#include <core_module.h>
#include <localization_setting.h>
#include <widget_deserialize_model.h>
#include <EWebKit2.h>
#include <dpl/localization/w3c_file_localization.h>
#include <dpl/localization/LanguageTagsProvider.h>
-#include "webkit/bundles/plugin_module_support.h"
+#include <popup-runner/PopupInvoker.h>
+#include <prepare_external_storage.h>
+#include <vconf.h>
+#include "auto_rotation_support.h"
+
+#include <process_pool.h>
+#include <process_pool_launchpad_util.h>
+
+#include "client_command_line_parser.h"
+#include "client_ide_support.h"
+#include "client_service_support.h"
+#include "client_submode_support.h"
//W3C PACKAGING enviroment variable name
#define W3C_DEBUG_ENV_VARIABLE "DEBUG_LOAD_FINISH"
// window signal callback
-const char *EDJE_SHOW_BACKWARD_SIGNAL = "show,backward,signal";
+const char *EDJE_SHOW_PROGRESS_SIGNAL = "show,progress,signal";
+const char *EDJE_HIDE_PROGRESS_SIGNAL = "hide,progress,signal";
const std::string VIEWMODE_TYPE_FULLSCREEN = "fullscreen";
const std::string VIEWMODE_TYPE_MAXIMIZED = "maximized";
+const std::string VIEWMODE_TYPE_WINDOWED = "windowed";
char const* const ELM_SWALLOW_CONTENT = "elm.swallow.content";
-const char* const BUNDLE_PATH = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
+const char* const BUNDLE_PATH = LIBDIR_PREFIX "/usr/lib/libwrt-injected-bundle.so";
+const char* const MESSAGE_NAME_INITIALIZE = "ToInjectedBundle::INIT";
+
+// process pool
+const char* const DUMMY_PROCESS_PATH = "/usr/bin/wrt_launchpad_daemon_candidate";
+static Ewk_Context* s_preparedEwkContext = NULL;
+static WindowData* s_preparedWindowData = NULL;
+static int app_argc = 0;
+static char** app_argv = NULL;
-static Ewk_Context* s_ewk_context = NULL;
+// env
+const char* const HOME = "HOME";
+const char* const APP_HOME_PATH = "/opt/home/app";
+const char* const ROOT_HOME_PATH = "/opt/home/root";
WrtClient::WrtClient(int argc, char **argv) :
Application(argc, argv, "wrt-client", false),
m_launched(false),
m_initializing(false),
m_initialized(false),
- m_sdkLauncherPid(0),
m_debugMode(false),
- m_debuggerPort(0),
m_returnStatus(ReturnStatus::Succeeded),
- m_widgetState(WidgetState::WidgetState_Stopped)
+ m_widgetState(WidgetState::WidgetState_Stopped),
+ m_initialViewMode(VIEWMODE_TYPE_MAXIMIZED),
+ m_currentViewMode(VIEWMODE_TYPE_MAXIMIZED),
+ m_isWebkitFullscreen(false),
+ m_isFullscreenByPlatform(false),
+ m_submodeSupport(new ClientModule::SubmodeSupport())
{
Touch();
LogDebug("App Created");
void WrtClient::OnStop()
{
- LogInfo("Stopping Dummy Client");
+ LogDebug("Stopping Dummy Client");
}
void WrtClient::OnCreate()
{
- LogInfo("On Create");
+ LogDebug("On Create");
ADD_PROFILING_POINT("OnCreate callback", "point");
ewk_init();
}
void WrtClient::OnPause()
{
- LogDebug("On pause");
-
if (m_widgetState != WidgetState_Running) {
LogWarning("Widget is not running to be suspended");
return;
}
+ if (m_submodeSupport->isNeedTerminateOnSuspend()) {
+ LogDebug("Current mode cannot support suspend");
+ elm_exit();
+ return;
+ }
m_widget->Suspend();
m_widgetState = WidgetState_Suspended;
}
// bundle argument is freed after OnReset() is returned
// So bundle duplication is needed
ApplicationDataSingleton::Instance().setBundle(bundle_dup(b));
+ ApplicationDataSingleton::Instance().setEncodedBundle(b);
if (true == m_initializing) {
LogDebug("can not handle reset event");
return;
}
m_widget->Reset();
- m_windowData->emitSignalForUserLayout(EDJE_SHOW_BACKWARD_SIGNAL, "");
m_widgetState = WidgetState_Running;
} else {
- if (true == checkArgument()) {
- setStep();
- } else {
+ m_tizenId =
+ ClientModule::CommandLineParser::getTizenId(m_argc, m_argv);
+ if (m_tizenId.empty()) {
showHelpAndQuit();
+ } else {
+ setDebugMode(b);
+ setStep();
}
}
Quit();
}
-bool WrtClient::checkArgument()
-{
- std::string tizenId = getTizenIdFromArgument(m_argc, m_argv);
-
- if (tizenId.empty()) {
- // Just show help
- return false;
- } else {
- m_tizenId = tizenId;
- LogDebug("Tizen id: " << m_tizenId);
- return true;
- }
-}
-
-std::string WrtClient::getTizenIdFromArgument(int argc, char **argv)
-{
- LogInfo("checkArgument");
- std::string arg = argv[0];
-
- if (arg.empty()) {
- return "";
- }
-
- if (arg.find("wrt-client") != std::string::npos) {
- if (argc <= 1) {
- return "";
- }
-
- arg = argv[1];
-
- if (arg == "-h" || arg == "--help") {
- return "";
- } else if (arg == "-l" || arg == "--launch" ||
- arg == "-t" || arg == "--tizen")
- {
- if (argc != 3) {
- return "";
- }
- return argv[2];
- } else {
- return "";
- }
- } else {
- // Launch widget based on application basename
- size_t pos = arg.find_last_of('/');
-
- if (pos != std::string::npos) {
- arg = arg.erase(0, pos + 1);
- }
-
- return arg;
- }
-}
-
void WrtClient::setStep()
{
- LogInfo("setStep");
+ LogDebug("setStep");
AddStep(&WrtClient::initStep);
-
- setSdkLauncherDebugData();
-
AddStep(&WrtClient::launchStep);
AddStep(&WrtClient::shutdownStep);
DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
}
-void WrtClient::setSdkLauncherDebugData()
+void WrtClient::setDebugMode(bundle* b)
{
- LogDebug("setSdkLauncherDebugData");
-
- /* check bundle from sdk launcher */
- bundle *bundleFromSdkLauncher;
- bundleFromSdkLauncher = bundle_import_from_argv(m_argc, m_argv);
- const char *bundle_debug = bundle_get_val(bundleFromSdkLauncher, "debug");
- const char *bundle_pid = bundle_get_val(bundleFromSdkLauncher, "pid");
- if (bundle_debug != NULL && bundle_pid != NULL) {
- if (strcmp(bundle_debug, "true") == 0) {
- m_debugMode = true;
- m_sdkLauncherPid = atoi(bundle_pid);
- } else {
- m_debugMode = false;
- }
- }
- bundle_free(bundleFromSdkLauncher);
-}
-
-bool WrtClient::checkDebugMode(SDKDebugData* debugData)
-{
- LogError("Checking for debug mode");
- Assert(m_dao);
-
- bool debugMode = debugData->debugMode;
-
- LogInfo("[DEBUG_MODE] Widget is launched in " <<
- (debugMode ? "DEBUG" : "RETAIL") <<
- " mode.");
-
- if (debugMode == true) {
- // In WAC widget, only test widgets can use web inspector.
- // In TIZEN widget,
- // every launched widgets as debug mode can use it.
- if (m_dao->getWidgetType().appType == WrtDB::APP_TYPE_WAC20) {
- bool developerMode =
- WRT::CoreModuleSingleton::Instance().developerMode();
- //This code will be activated
- //after WAC test certificate is used by SDK
- //bool isTestWidget = view->m_widgetModel->IsTestWidget.Get();
- //if(!isTestWidget)
- //{
- // LogInfo("This is not WAC Test Widget");
- // break;
- //}
- if (!developerMode) {
- LogInfo("This is not WAC Developer Mode");
- debugMode = false;
- }
- }
- }
- return debugMode;
+ m_debugMode = ClientModule::IDESupport::getDebugMode(b);
+ LogDebug("debug mode : " << m_debugMode);
}
void WrtClient::OnEventReceived(const NextStepEvent& /*event*/)
SwitchToStep(&WrtClient::shutdownStep);
}
- // ecore_event_jobs are processed sequentially without concession to
- // other type events. To give a chance of execute to other events,
- // ecore_timer_add was used.
- DPL::Event::ControllerEventHandler<NextStepEvent>::PostTimedEvent(
- NextStepEvent(), 0.001);
-}
-
-bool WrtClient::checkWACTestCertififedWidget()
-{
- // WAC Waikiki Beta Release Core Specification: Widget Runtime
- // 10 Dec 2010
- //
- // WR-4710 The WRT MUST enable debug functions only for WAC test widgets
- // i.e. the functions must not be usable for normal WAC widgets, even when
- // a WAC test widget is executing.
- ADD_PROFILING_POINT("DeveloperModeCheck", "start");
- Assert(!!m_dao);
- // WAC test widget
- // A widget signed with a WAC-issued test certificate as described in
- // Developer Mode.
-
- bool developerWidget = m_dao->isTestWidget();
- bool developerMode = WRT::CoreModuleSingleton::Instance().developerMode();
-
- LogDebug("Is WAC test widget: " << developerWidget);
- LogDebug("Is developer Mode: " << developerMode);
-
- if (developerWidget) {
- if (!developerMode) {
- LogError("WAC test certified developer widget is needed for " <<
- "developer mode");
- return false;
- } else {
- //TODO: WR-4660 (show popup about developer widget
- // during launch
- LogInfo("POPUP: THIS IS TEST WIDGET!");
- }
- }
- ADD_PROFILING_POINT("DeveloperModeCheck", "stop");
- return true;
+ DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(NextStepEvent());
}
void WrtClient::loadFinishCallback(Evas_Object* webview)
{
ADD_PROFILING_POINT("loadFinishCallback", "start");
- SDKDebugData* debug = new SDKDebugData;
- debug->debugMode = m_debugMode;
- debug->pid = new unsigned long(getpid());
- LogInfo("Post result of launch");
-
- // Start inspector server, if current mode is debugger mode.
- // In the WK2 case, ewk_view_inspector_server_start should
- // be called after WebProcess is created.
- if (checkDebugMode(debug)) {
- debug->portnum =
- ewk_view_inspector_server_start(m_widget->GetCurrentWebview(), 0);
- if (debug->portnum == 0) {
- LogWarning("Failed to get portnum");
- } else {
- LogInfo("Assigned port number for inspector : "
- << debug->portnum);
- }
- } else {
- LogDebug("Debug mode is disabled");
+ // Splash screen
+ if (m_splashScreen && m_splashScreen->isShowing())
+ {
+ m_splashScreen->stopSplashScreenBuffered();
}
+ LogDebug("Post result of launch");
+
//w3c packaging test debug (message on 4>)
const char * makeScreen = getenv(W3C_DEBUG_ENV_VARIABLE);
if (makeScreen != NULL && strcmp(makeScreen, "1") == 0) {
PostEvent(NextStepEvent());
}
- if (debug->debugMode) {
- LogDebug("Send RT signal to wrt-launcher(pid: " << m_sdkLauncherPid);
- union sigval sv;
- /* send real time signal with result to wrt-launcher */
- if (webview) {
- LogDebug("userData->portnum : " << debug->portnum);
- sv.sival_int = debug->portnum;
- } else {
- sv.sival_int = -1;
+ if (m_debugMode) {
+ unsigned int portNum =
+ ewk_view_inspector_server_start(m_widget->GetCurrentWebview(), 0);
+ LogDebug("Port for inspector : " << portNum);
+ bool ret = ClientModule::IDESupport::sendReply(
+ ApplicationDataSingleton::Instance().getBundle(),
+ portNum);
+ if (!ret) {
+ LogWarning("Fail to send reply");
}
- sigqueue(m_sdkLauncherPid, SIGRTMIN, sv);
}
ApplicationDataSingleton::Instance().freeBundle();
+}
- LogDebug("Cleaning wrtClient launch resources...");
- delete debug->pid;
- delete debug;
+void WrtClient::resetCallback(bool result)
+{
+ if (!result) {
+ LogDebug("Fail to handle reset event");
+ // free bundle data
+ ApplicationDataSingleton::Instance().freeBundle();
+ }
+}
+
+void WrtClient::progressStartedCallback()
+{
+ if (m_settingList->getProgressBarPresence() == ProgressBar_Enable ||
+ m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
+ {
+ m_windowData->signalEmit(Layer::MAIN_LAYOUT,
+ EDJE_SHOW_PROGRESS_SIGNAL,
+ "");
+ m_windowData->updateProgress(0);
+ }
+}
+
+void WrtClient::loadProgressCallback(Evas_Object* /*webview*/, double value)
+{
+ if (m_settingList->getProgressBarPresence() == ProgressBar_Enable ||
+ m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
+ {
+ m_windowData->updateProgress(value);
+ }
}
void WrtClient::progressFinishCallback()
{
- m_splashScreen->stopSplashScreen();
+ if (m_settingList->getProgressBarPresence() == ProgressBar_Enable ||
+ m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
+ {
+ m_windowData->signalEmit(Layer::MAIN_LAYOUT,
+ EDJE_HIDE_PROGRESS_SIGNAL,
+ "");
+ }
}
void WrtClient::webkitExitCallback()
NextStepEvent());
}
+void WrtClient::enterFullscreenCallback(Evas_Object* /*obj*/,
+ bool isFullscreenByPlatform)
+{
+ // enter fullscreen
+ m_windowData->toggleFullscreen(true);
+ m_currentViewMode = VIEWMODE_TYPE_FULLSCREEN;
+ m_isWebkitFullscreen = true;
+ if (isFullscreenByPlatform) {
+ m_isFullscreenByPlatform = true;
+ }
+}
+
+void WrtClient::exitFullscreenCallback(Evas_Object* /*obj*/)
+{
+ // exit fullscreen
+ m_windowData->toggleFullscreen(false);
+ m_currentViewMode = m_initialViewMode;
+ m_isWebkitFullscreen = false;
+ m_isFullscreenByPlatform = false;
+}
+
void WrtClient::launchStep()
{
ADD_PROFILING_POINT("launchStep", "start");
}
m_dao.reset(new WrtDB::WidgetDAOReadOnly(DPL::FromASCIIString(m_tizenId)));
+ WrtDB::WidgetSettings widgetSettings;
+ m_dao->getWidgetSettings(widgetSettings);
+ m_settingList.reset(new WidgetSettingList(widgetSettings));
+ m_submodeSupport->initialize(DPL::FromASCIIString(m_tizenId));
+
DPL::Optional<DPL::String> defloc = m_dao->getDefaultlocale();
if (!defloc.IsNull()) {
LanguageTagsProviderSingleton::Instance().addWidgetDefaultLocales(
*defloc);
}
- // For localizationsetting not changed on widget running
- //LocalizationSetting::SetLanguageChangedCallback(
- // languageChangedCallback, this);
+ setInitialViewMode();
+ PrepareExternalStorageSingleton::Instance().Initialize(m_dao->getTizenPkgId());
+
+ /* remove language change callback */
+ /*
+ LocalizationSetting::SetLanguageChangedCallback(
+ languageChangedCallback, this);
+ */
ADD_PROFILING_POINT("CreateWindow", "start");
- m_windowData.reset(new WindowData(static_cast<unsigned long>(getpid()),
- true));
+ if (s_preparedWindowData == NULL) {
+ m_windowData.reset(new WindowData(static_cast<unsigned long>(getpid()), true));
+ } else {
+ m_windowData.reset(s_preparedWindowData);
+ s_preparedWindowData = NULL;
+ }
ADD_PROFILING_POINT("CreateWindow", "stop");
+ if (!m_windowData->initScreenReaderSupport(
+ m_settingList->getAccessibility() == Accessibility_Enable))
+ {
+ LogWarning("Fail to set screen reader support set");
+ }
+
+ // rotate window to initial value
+ setWindowInitialOrientation();
+ setCtxpopupItem();
WRT::UserDelegatesPtr cbs(new WRT::UserDelegates);
+
ADD_PROFILING_POINT("Create splash screen", "start");
- m_splashScreen.reset(
- new SplashScreenSupport(m_windowData->m_win));
- if (m_splashScreen->createSplashScreen(m_dao->getSplashImgSrc())) {
+ DPL::OptionalString splashImgSrc = m_dao->getSplashImgSrc();
+ if (!splashImgSrc.IsNull())
+ {
+ m_splashScreen.reset(
+ new SplashScreenSupport(
+ m_windowData->getEvasObject(Layer::WINDOW),
+ (DPL::ToUTF8String(*splashImgSrc)).c_str(),
+ m_currentViewMode != VIEWMODE_TYPE_FULLSCREEN,
+ m_settingList->getRotationValue() == Screen_Landscape));
m_splashScreen->startSplashScreen();
- cbs->progressFinish = DPL::MakeDelegate(
- this,
- &WrtClient::
- progressFinishCallback);
}
ADD_PROFILING_POINT("Create splash screen", "stop");
+
DPL::OptionalString startUrl = W3CFileLocalization::getStartFile(m_dao);
- if (!m_widget->PrepareView(DPL::ToUTF8String(*startUrl),
- m_windowData->m_win, s_ewk_context))
+ if (!m_widget->PrepareView(
+ DPL::ToUTF8String(*startUrl),
+ m_windowData->getEvasObject(Layer::WINDOW),
+ s_preparedEwkContext))
{
DPL::Event::ControllerEventHandler<NextStepEvent>::PostEvent(
NextStepEvent());
return;
}
+ // send rotate information to ewk
+ setEwkInitialOrientation();
+
//you can't show window with splash screen before PrepareView
//ewk_view_add_with_context() in viewLogic breaks window
-
m_windowData->init();
+ m_windowData->postInit();
+
+ // sub-mode support
+ if (m_submodeSupport->isInlineMode()) {
+ if (m_submodeSupport->transientWindow(
+ elm_win_xwindow_get(
+ m_windowData->getEvasObject(Layer::WINDOW))))
+ {
+ LogDebug("Success to set submode");
+ } else {
+ LogWarning("Fail to set submode");
+ }
+ }
+ m_windowData->smartCallbackAdd(Layer::FOCUS,
+ "focused",
+ focusedCallback,
+ this);
+ m_windowData->smartCallbackAdd(Layer::FOCUS,
+ "unfocused",
+ unfocusedCallback,
+ this);
WrtDB::WidgetLocalizedInfo localizedInfo =
W3CFileLocalization::getLocalizedInfo(m_dao);
if (!(localizedInfo.name.IsNull())) {
name = DPL::ToUTF8String(*(localizedInfo.name));
}
- elm_win_title_set(m_windowData->m_win, name.c_str());
- evas_object_show(m_windowData->m_win);
- initializeWindowModes();
- connectElmCallback();
+ elm_win_title_set(m_windowData->getEvasObject(Layer::WINDOW),
+ name.c_str());
- if (!checkWACTestCertififedWidget()) {
- LogWarning("WAC Certificate failed, stop launchStep");
- return;
- }
+ // window show
+ evas_object_show(m_windowData->getEvasObject(Layer::WINDOW));
+
+ initializeWindowModes();
m_widgetState = WidgetState_Authorizing;
if (!m_widget->CheckBeforeLaunch()) {
NextStepEvent());
return;
}
- LogInfo("Widget launch accepted. Entering running state");
+ LogDebug("Widget launch accepted. Entering running state");
m_widgetState = WidgetState_Running;
+ cbs->progressStarted = DPL::MakeDelegate(this, &WrtClient::progressStartedCallback);
+ cbs->progress = DPL::MakeDelegate(this, &WrtClient::loadProgressCallback);
+ cbs->progressFinish = DPL::MakeDelegate(this, &WrtClient::progressFinishCallback);
cbs->loadFinish = DPL::MakeDelegate(this, &WrtClient::loadFinishCallback);
+ cbs->reset = DPL::MakeDelegate(this, &WrtClient::resetCallback);
cbs->bufferSet = DPL::MakeDelegate(this, &WrtClient::setLayout);
cbs->bufferUnset = DPL::MakeDelegate(this, &WrtClient::unsetLayout);
cbs->webkitExit = DPL::MakeDelegate(this, &WrtClient::webkitExitCallback);
cbs->webCrash = DPL::MakeDelegate(this, &WrtClient::webCrashCallback);
- cbs->toggleFullscreen = DPL::MakeDelegate(
- m_windowData.get(), &WindowData::toggleFullscreen);
+ cbs->enterFullscreen = DPL::MakeDelegate(this, &WrtClient::enterFullscreenCallback);
+ cbs->exitFullscreen = DPL::MakeDelegate(this, &WrtClient::exitFullscreenCallback);
+ cbs->setOrientation = DPL::MakeDelegate(this, &WrtClient::setWindowOrientation);
+ cbs->hwkey = DPL::MakeDelegate(this, &WrtClient::hwkeyCallback);
m_widget->SetUserDelegates(cbs);
m_widget->Show();
- m_windowData->emitSignalForUserLayout(EDJE_SHOW_BACKWARD_SIGNAL, "");
+
ADD_PROFILING_POINT("launchStep", "stop");
}
void WrtClient::initializeWindowModes()
{
Assert(m_windowData);
- Assert(m_dao);
- auto windowModes = m_dao->getWindowModes();
- bool fullscreen = false;
- bool backbutton = false;
- if (m_dao->getWidgetType().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
- WidgetSettings widgetSettings;
- m_dao->getWidgetSettings(widgetSettings);
- WidgetSettingList settings(widgetSettings);
- backbutton =
- (settings.getBackButtonPresence() == BackButton_Enable);
- }
-
- FOREACH(it, windowModes)
- {
- std::string viewMode = DPL::ToUTF8String(*it);
- if (viewMode == VIEWMODE_TYPE_FULLSCREEN) {
- fullscreen = true;
- break;
- } else if (viewMode == VIEWMODE_TYPE_MAXIMIZED) {
- break;
- }
- }
-
- m_windowData->setViewMode(fullscreen,
+ bool backbutton =
+ (m_settingList->getBackButtonPresence() == BackButton_Enable ||
+ m_currentViewMode == VIEWMODE_TYPE_WINDOWED);
+ m_windowData->setViewMode(m_currentViewMode == VIEWMODE_TYPE_FULLSCREEN,
backbutton);
}
-void WrtClient::backButtonCallback(void* data,
- Evas_Object * /*obj*/,
- void * /*event_info*/)
+Eina_Bool WrtClient::naviframeBackButtonCallback(void* data,
+ Elm_Object_Item* /*it*/)
{
- LogInfo("BackButtonCallback");
+ LogDebug("BackButtonCallback");
Assert(data);
WrtClient* This = static_cast<WrtClient*>(data);
-
This->m_widget->Backward();
+ return EINA_FALSE;
}
int WrtClient::appcoreLowMemoryCallback(void* /*data*/)
{
- LogInfo("appcoreLowMemoryCallback");
+ LogDebug("appcoreLowMemoryCallback");
//WrtClient* This = static_cast<WrtClient*>(data);
// TODO call RunnableWidgetObject API regarding low memory
// The API should be implemented
+ // temporary solution because we have no way to get ewk_context from runnable object.
+ if (s_preparedEwkContext)
+ {
+ ewk_context_cache_clear(s_preparedEwkContext);
+ ewk_context_notify_low_memory(s_preparedEwkContext);
+ }
+
return 0;
}
-void WrtClient::connectElmCallback()
+void WrtClient::setInitialViewMode(void)
{
- Assert(m_windowData);
Assert(m_dao);
- if (m_dao->getWidgetType().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
- WidgetSettings widgetSettings;
- m_dao->getWidgetSettings(widgetSettings);
- WidgetSettingList settings(widgetSettings);
- if (settings.getBackButtonPresence() == BackButton_Enable) {
- m_windowData->addFloatBackButtonCallback(
- "clicked",
- &WrtClient::backButtonCallback,
- this);
+ WrtDB::WindowModeList windowModes = m_dao->getWindowModes();
+ FOREACH(it, windowModes) {
+ std::string viewMode = DPL::ToUTF8String(*it);
+ switch(viewMode[0]) {
+ case 'f':
+ if (viewMode == VIEWMODE_TYPE_FULLSCREEN) {
+ m_initialViewMode = viewMode;
+ m_currentViewMode = m_initialViewMode;
+ break;
+ }
+ break;
+ case 'm':
+ if (viewMode == VIEWMODE_TYPE_MAXIMIZED) {
+ m_initialViewMode = viewMode;
+ m_currentViewMode = m_initialViewMode;
+ break;
+ }
+ break;
+ case 'w':
+ if (viewMode == VIEWMODE_TYPE_WINDOWED) {
+ m_initialViewMode = viewMode;
+ m_currentViewMode = m_initialViewMode;
+ break;
+ }
+ break;
+ default:
+ break;
}
+ }
+}
- WidgetSettingScreenLock rotationValue = settings.getRotationValue();
- if (rotationValue == Screen_Portrait) {
- elm_win_rotation_with_resize_set(m_windowData->m_win, 0);
- ewk_view_orientation_send(m_widget->GetCurrentWebview(), 0);
- } else if (rotationValue == Screen_Landscape) {
- elm_win_rotation_with_resize_set(m_windowData->m_win, 270);
- ewk_view_orientation_send(m_widget->GetCurrentWebview(), 90);
- } else {
- elm_win_rotation_with_resize_set(m_windowData->m_win, 0);
- ewk_view_orientation_send(m_widget->GetCurrentWebview(), 0);
+void WrtClient::setWindowInitialOrientation(void)
+{
+ Assert(m_windowData);
+ Assert(m_dao);
+
+ WidgetSettingScreenLock rotationValue = m_settingList->getRotationValue();
+ if (rotationValue == Screen_Portrait) {
+ setWindowOrientation(OrientationAngle::Window::Portrait::PRIMARY);
+ } else if (rotationValue == Screen_Landscape) {
+ setWindowOrientation(OrientationAngle::Window::Landscape::PRIMARY);
+ } else if (rotationValue == Screen_AutoRotation) {
+ if (!AutoRotationSupport::setAutoRotation(
+ m_windowData->getEvasObject(Layer::WINDOW),
+ autoRotationCallback,
+ this))
+ {
+ LogError("Fail to set auto rotation");
}
+ } else {
+ setWindowOrientation(OrientationAngle::Window::Portrait::PRIMARY);
}
}
-void WrtClient::setLayout(Evas_Object* newBuffer)
+void WrtClient::setWindowOrientation(int angle)
{
- LogDebug("add new webkit buffer to window");
- Assert(newBuffer);
+ Assert(m_windowData);
+ m_windowData->setOrientation(angle);
+}
- elm_object_part_content_set(m_windowData->m_user_layout,
- ELM_SWALLOW_CONTENT,
- newBuffer);
+void WrtClient::unsetWindowOrientation(void)
+{
+ Assert(m_windowData);
+ Assert(m_dao);
- evas_object_show(newBuffer);
+ WidgetSettingScreenLock rotationValue = m_settingList->getRotationValue();
+ if (rotationValue == Screen_AutoRotation) {
+ AutoRotationSupport::unsetAutoRotation(
+ m_windowData->getEvasObject(Layer::WINDOW),
+ autoRotationCallback);
+ }
}
-void WrtClient::unsetLayout(Evas_Object* currentBuffer)
+void WrtClient::setEwkInitialOrientation(void)
{
- LogDebug("remove current webkit buffer from window");
- Assert(currentBuffer);
- evas_object_hide(currentBuffer);
+ Assert(m_widget);
+ Assert(m_dao);
+
+ WidgetSettingScreenLock rotationValue = m_settingList->getRotationValue();
+ if (rotationValue == Screen_Portrait) {
+ ewk_view_orientation_send(
+ m_widget->GetCurrentWebview(),
+ OrientationAngle::W3C::Portrait::PRIMARY);
+ } else if (rotationValue == Screen_Landscape) {
+ ewk_view_orientation_send(
+ m_widget->GetCurrentWebview(),
+ OrientationAngle::W3C::Landscape::PRIMARY);
+ } else if (rotationValue == Screen_AutoRotation) {
+ ewk_view_orientation_send(
+ m_widget->GetCurrentWebview(),
+ OrientationAngle::W3C::Portrait::PRIMARY);
+ } else {
+ ewk_view_orientation_send(
+ m_widget->GetCurrentWebview(),
+ OrientationAngle::W3C::Portrait::PRIMARY);
+ }
+}
+
+void WrtClient::ExitCallback(void* data,
+ Evas_Object * /*obj*/,
+ void * /*event_info*/)
+{
+ LogInfo("ExitCallback");
+ Assert(data);
+
+ WrtClient* This = static_cast<WrtClient*>(data);
- elm_object_part_content_unset(m_windowData->m_user_layout,
- ELM_SWALLOW_CONTENT);
+ This->OnTerminate();
+}
+
+void WrtClient::setCtxpopupItem(void)
+{
+ WindowData::CtxpopupItemDataList data;
+
+ // 1. share
+ WindowData::CtxpopupCallbackType shareCallback =
+ DPL::MakeDelegate(this, &WrtClient::ctxpopupShare);
+ WindowData::CtxpopupItemData shareData("Share",
+ std::string(),
+ shareCallback);
+
+ // 2. reload
+ WindowData::CtxpopupCallbackType reloadCallback =
+ DPL::MakeDelegate(this, &WrtClient::ctxpopupReload);
+ WindowData::CtxpopupItemData reloadData("Reload",
+ std::string(),
+ reloadCallback);
+
+ // 3. Open in browser
+ WindowData::CtxpopupCallbackType launchBrowserCallback =
+ DPL::MakeDelegate(this, &WrtClient::ctxpopupLaunchBrowser);
+ WindowData::CtxpopupItemData launchBrowserData("Open in browser",
+ std::string(),
+ launchBrowserCallback);
+ data.push_back(shareData);
+ data.push_back(reloadData);
+ data.push_back(launchBrowserData);
+ m_windowData->setCtxpopupItemData(data);
+}
+
+void WrtClient::ctxpopupShare(void)
+{
+ LogDebug("share");
+ const char* url = ewk_view_url_get(m_widget->GetCurrentWebview());
+ if (!url) {
+ LogError("url is empty");
+ return;
+ }
+ if (ClientModule::ServiceSupport::launchShareService(
+ elm_win_xwindow_get(m_windowData->getEvasObject(Layer::WINDOW)),
+ url))
+ {
+ LogDebug("success");
+ } else {
+ LogDebug("fail");
+ }
+ evas_object_smart_callback_add(m_windowData->m_win,
+ "delete,request",
+ &WrtClient::ExitCallback,
+ this);
+}
+
+void WrtClient::ctxpopupReload(void)
+{
+ LogDebug("reload");
+ ewk_view_reload(m_widget->GetCurrentWebview());
+}
+
+void WrtClient::ctxpopupLaunchBrowser(void)
+{
+ LogDebug("launchBrowser");
+ const char* url = ewk_view_url_get(m_widget->GetCurrentWebview());
+ if (!url) {
+ LogError("url is empty");
+ return;
+ }
+ if (ClientModule::ServiceSupport::launchViewService(
+ elm_win_xwindow_get(m_windowData->getEvasObject(Layer::WINDOW)),
+ url))
+ {
+ LogDebug("success");
+ } else {
+ LogDebug("fail");
+ }
+}
+
+void WrtClient::hwkeyCallback(const std::string& key)
+{
+ if (m_settingList->getBackButtonPresence() == BackButton_Enable
+ || m_currentViewMode == VIEWMODE_TYPE_WINDOWED)
+ {
+ // windowed UX - hosted application
+ if (key == KeyName::BACK) {
+ if (m_isWebkitFullscreen) {
+ ewk_view_fullscreen_exit(m_widget->GetCurrentWebview());
+ } else {
+ m_widget->Backward();
+ }
+ } else if (key == KeyName::MENU) {
+ // UX isn't confirmed
+ // m_windowData->showCtxpopup();
+ }
+ } else {
+ // packaged application
+ if (key == KeyName::BACK) {
+ if (m_isFullscreenByPlatform) {
+ ewk_view_fullscreen_exit(m_widget->GetCurrentWebview());
+ }
+ }
+ }
+}
+
+void WrtClient::setLayout(Evas_Object* webview)
+{
+ LogDebug("add new webkit buffer to window");
+ Assert(webview);
+ m_windowData->setWebview(webview);
+ evas_object_show(webview);
+ evas_object_show(m_windowData->getEvasObject(Layer::WINDOW));
+}
+
+void WrtClient::unsetLayout(Evas_Object* webview)
+{
+ LogDebug("remove current webkit buffer from window");
+ Assert(webview);
+ evas_object_hide(webview);
+ m_windowData->unsetWebview();
}
void WrtClient::shutdownStep()
if (m_widget && m_widgetState) {
m_widgetState = WidgetState_Stopped;
m_widget->Hide();
+ // AutoRotation, focusCallback use m_widget pointer internally.
+ // It must be unset before m_widget is released.
+ m_submodeSupport->deinitialize();
+ unsetWindowOrientation();
+ m_windowData->smartCallbackDel(Layer::FOCUS,
+ "focused",
+ focusedCallback);
+ m_windowData->smartCallbackDel(Layer::FOCUS,
+ "unfocused",
+ unfocusedCallback);
m_widget.reset();
- ewk_context_delete(s_ewk_context);
+ ewk_context_delete(s_preparedEwkContext);
+ PrepareExternalStorageSingleton::Instance().Deinitialize();
WRT::CoreModuleSingleton::Instance().Terminate();
}
if (m_initialized) {
Quit();
}
+void WrtClient::autoRotationCallback(void* data, Evas_Object* obj, void* /*event*/)
+{
+ LogDebug("entered");
+
+ Assert(data);
+ Assert(obj);
+
+ WrtClient* This = static_cast<WrtClient*>(data);
+ This->autoRotationSetOrientation(obj);
+}
+
+void WrtClient::focusedCallback(void* data,
+ Evas_Object* /*obj*/,
+ void* /*eventInfo*/)
+{
+ LogDebug("entered");
+ Assert(data);
+ WrtClient* This = static_cast<WrtClient*>(data);
+ elm_object_focus_set(This->m_widget->GetCurrentWebview(), EINA_TRUE);
+}
+
+void WrtClient::unfocusedCallback(void* data,
+ Evas_Object* /*obj*/,
+ void* /*eventInfo*/)
+{
+ LogDebug("entered");
+ Assert(data);
+ WrtClient* This = static_cast<WrtClient*>(data);
+ elm_object_focus_set(This->m_widget->GetCurrentWebview(), EINA_FALSE);
+}
+
+void WrtClient::autoRotationSetOrientation(Evas_Object* obj)
+{
+ LogDebug("entered");
+ Assert(obj);
+
+ AutoRotationSupport::setOrientation(obj, m_widget->GetCurrentWebview(),
+ (m_splashScreen) ? m_splashScreen.get(): NULL);
+}
+
int WrtClient::languageChangedCallback(void *data)
{
LogDebug("Language Changed");
DPL::Application::Quit();
}
+static Eina_Bool proces_pool_fd_handler(void* /*data*/, Ecore_Fd_Handler *handler)
+{
+ int fd = ecore_main_fd_handler_fd_get(handler);
+
+ if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR))
+ {
+ LogDebug("ECORE_FD_ERROR");
+
+ if (fd != -1)
+ {
+ close(fd);
+ }
+
+ exit(-1);
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ))
+ {
+ LogDebug("ECORE_FD_READ");
+ {
+ app_pkt_t* pkt = (app_pkt_t*) malloc(sizeof(char) * AUL_SOCK_MAXBUFF);
+ memset(pkt, 0, AUL_SOCK_MAXBUFF);
+
+ int recv_ret = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0);
+
+ if (fd != -1)
+ {
+ close(fd);
+ }
+
+ if (recv_ret == -1)
+ {
+ LogDebug("recv error!");
+ exit(-1);
+ }
+ LogDebug("recv_ret : " << recv_ret << ", pkt->len : " << pkt->len);
+
+ ecore_main_fd_handler_del(handler);
+
+ process_pool_launchpad_main_loop(pkt, app_argv[0], &app_argc, &app_argv);
+
+ free(pkt);
+ }
+
+ ecore_main_loop_quit();
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void vconf_changed_handler(keynode_t* /*key*/, void* /*data*/)
+{
+ LogDebug("VCONFKEY_LANGSET vconf-key was changed!");
+
+ // When system language is changed, the candidate process will be created again.
+ exit(-1);
+}
+
+void set_env()
+{
+#ifndef TIZEN_PUBLIC
+ setenv("COREGL_FASTPATH", "1", 1);
+#endif
+ setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
+ setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1);
+ setenv("ELM_IMAGE_CACHE", "0", 1);
+}
+
int main(int argc,
char *argv[])
{
+ // process pool - store arg's value
+ app_argc = argc;
+ app_argv = argv;
+
+#ifndef X11
+ // Mesa does a bad job detecting the correct EGL
+ // platform to use, and ends up assuming that the
+ // wrt-client is using X
+ setenv("EGL_PLATFORM", "wayland", 1);
+#endif
+
UNHANDLED_EXCEPTION_HANDLER_BEGIN
{
ADD_PROFILING_POINT("main-entered", "point");
// Set log tagging
DPL::Log::LogSystemSingleton::Instance().SetTag("WRT");
- // set evas backend type
- if (!getenv("ELM_ENGINE")) {
- if (!setenv("ELM_ENGINE", "gl", 1)) {
- LogDebug("Enable backend");
- }
- } else {
- LogDebug("ELM_ENGINE : " << getenv("ELM_ENGINE"));
- }
+ // Set environment variables
+ set_env();
- #ifndef TIZEN_PUBLIC
- setenv("COREGL_FASTPATH", "1", 1);
- #endif
- setenv("CAIRO_GL_COMPOSITOR", "msaa", 1);
- setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1);
- setenv("ELM_IMAGE_CACHE", "0", 1);
+ if (argc > 1 && argv[1] != NULL && !strcmp(argv[1], "-d"))
+ {
+ LogDebug("Entered dummy process mode");
+ sprintf(argv[0], "%s ",
+ DUMMY_PROCESS_PATH);
- // This code is to fork a web process without exec.
- std::string tizenId = WrtClient::getTizenIdFromArgument(argc, argv);
+ // Set 'root' home directory
+ setenv(HOME, ROOT_HOME_PATH, 1);
- if (!tizenId.empty()) {
- LogDebug("Launching by fork mode");
- // Language env setup
+ LogDebug("Prepare ewk_context");
appcore_set_i18n("wrt-client", NULL);
- ewk_init();
ewk_set_arguments(argc, argv);
setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1);
- s_ewk_context = ewk_context_new_with_injected_bundle_path(
- BUNDLE_PATH);
+ s_preparedEwkContext = ewk_context_new_with_injected_bundle_path(BUNDLE_PATH);
+
+ if (s_preparedEwkContext == NULL)
+ {
+ LogDebug("Creating webkit context was failed!");
+ exit(-1);
+ }
+
+ int client_fd = __connect_process_pool_server();
+
+ if (client_fd == -1)
+ {
+ LogDebug("Connecting process_pool_server was failed!");
+ exit(-1);
+ }
+
+ // register language changed callback
+ vconf_notify_key_changed(VCONFKEY_LANGSET, vconf_changed_handler, NULL);
+
+ LogDebug("Prepare window_data");
+ // Temporarily change HOME path to app
+ // This change is needed for getting elementary profile
+ // /opt/home/app/.elementary/config/mobile/base.cfg
+ const char* backupEnv = getenv(HOME);
+ setenv(HOME, APP_HOME_PATH, 1);
+ LogDebug("elm_init()");
+ elm_init(argc, argv);
+ setenv(HOME, backupEnv, 1);
+
+ LogDebug("WindowData()");
+ s_preparedWindowData = new WindowData(static_cast<unsigned long>(getpid()));
+
+ Ecore_Fd_Handler* fd_handler = ecore_main_fd_handler_add(client_fd,
+ (Ecore_Fd_Handler_Flags)(ECORE_FD_READ|ECORE_FD_ERROR),
+ proces_pool_fd_handler, NULL, NULL, NULL);
+
+ if (fd_handler == NULL)
+ {
+ LogDebug("fd_handler is NULL");
+ exit(-1);
+ }
+
+ setpriority(PRIO_PROCESS, 0, 0);
+
+ LogDebug("ecore_main_loop_begin()");
+ ecore_main_loop_begin();
+ LogDebug("ecore_main_loop_begin()_end");
+
+ // deregister language changed callback
+ vconf_ignore_key_changed(VCONFKEY_LANGSET, vconf_changed_handler);
- // plugin init
- PluginModuleSupport::init(s_ewk_context, tizenId);
+ std::string tizenId =
+ ClientModule::CommandLineParser::getTizenId(argc, argv);
+ ewk_context_message_post_to_injected_bundle(
+ s_preparedEwkContext,
+ MESSAGE_NAME_INITIALIZE,
+ tizenId.c_str());
+
+ }
+ else
+ {
+ // This code is to fork a web process without exec.
+ std::string tizenId =
+ ClientModule::CommandLineParser::getTizenId(argc, argv);
+
+ if (!tizenId.empty()) {
+ LogDebug("Launching by fork mode");
+ // Language env setup
+ appcore_set_i18n("wrt-client", NULL);
+ ewk_set_arguments(argc, argv);
+ setenv("WRT_LAUNCHING_PERFORMANCE", "1", 1);
+ s_preparedEwkContext = ewk_context_new_with_injected_bundle_path(
+ BUNDLE_PATH);
+
+ if (s_preparedEwkContext == NULL)
+ {
+ LogDebug("Creating webkit context was failed!");
+ Wrt::Popup::PopupInvoker().showInfo("Error", "Creating webkit context was failed.", "OK");
+ exit(-1);
+ }
+
+ // plugin init
+ ewk_context_message_post_to_injected_bundle(
+ s_preparedEwkContext,
+ MESSAGE_NAME_INITIALIZE,
+ tizenId.c_str());
+ }
}
// Output on stdout will be flushed after every newline character,
// the output may not be flushed).
setlinebuf(stdout);
- WrtClient app(argc, argv);
+ WrtClient app(app_argc, app_argv);
ADD_PROFILING_POINT("Before appExec", "point");
int ret = app.Exec();