[HOTFIX] Delay main_loop shutdown to avoid deadlock
[platform/framework/web/crosswalk-tizen.git] / runtime / browser / runtime_process.cc
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 #include <EWebKit.h>
18 #include <EWebKit_internal.h>
19
20 #include <Elementary.h>
21
22 #ifdef WATCH_FACE_FEATURE_SUPPORT
23 #include <bundle_internal.h>
24 #include <Ecore_Wayland.h>
25 #endif  // WATCH_FACE_FEATURE_SUPPORT
26
27 #include "common/application_data.h"
28 #include "common/command_line.h"
29 #include "common/logger.h"
30 #include "common/profiler.h"
31 #include "runtime/browser/runtime.h"
32 #include "runtime/common/constants.h"
33 #include "runtime/browser/prelauncher.h"
34 #include "runtime/browser/preload_manager.h"
35
36 bool g_prelaunch = false;
37
38 #ifdef IME_FEATURE_SUPPORT
39 static Ecore_Timer* timeout = NULL;
40
41 static Eina_Bool terminateDelayCallback(void* data) {
42   timeout = NULL;
43   ecore_main_loop_quit();
44   return ECORE_CALLBACK_CANCEL;
45 }
46 #endif
47 #ifdef WATCH_FACE_FEATURE_SUPPORT
48 static int setWatchEnv(int argc, char **argv) {
49   bundle *kb = NULL;
50   char *wayland_display = NULL;
51   char *xdg_runtime_dir = NULL;
52   char *width_str = NULL;
53   char *height_str = NULL;
54
55   if (argc <= 0 || argv == NULL) {
56     errno = EINVAL;
57     LOGGER(ERROR) << "argument are invalid";
58     return -1;
59   }
60
61   kb = bundle_import_from_argv(argc, argv);
62   if (kb) {
63     bundle_get_str(kb, "XDG_RUNTIME_DIR", &xdg_runtime_dir);
64     bundle_get_str(kb, "WAYLAND_DISPLAY", &wayland_display);
65     bundle_get_str(kb, "WATCH_WIDTH", &width_str);
66     bundle_get_str(kb, "WATCH_HEIGHT", &height_str);
67
68     if (xdg_runtime_dir) {
69       LOGGER(DEBUG) << "senenv: " << xdg_runtime_dir;
70       setenv("XDG_RUNTIME_DIR", xdg_runtime_dir, 1);
71     } else {
72       LOGGER(ERROR) << "failed to get xdgruntimedir";
73     }
74
75     if (wayland_display) {
76       LOGGER(DEBUG) << "setenv: " << wayland_display;
77       setenv("WAYLAND_DISPLAY", wayland_display, 1);
78     } else {
79       LOGGER(ERROR) << "failed to get waylanddisplay";
80     }
81     bundle_free(kb);
82   } else {
83     LOGGER(ERROR) << "failed to get launch argv";
84   }
85   return 0;
86 }
87 #endif  // WATCH_FACE_FEATURE_SUPPORT
88
89 int real_main(int argc, char* argv[]) {
90   STEP_PROFILE_START("Start -> Launch Completed");
91   STEP_PROFILE_START("Start -> OnCreate");
92   // Parse commandline.
93   common::CommandLine::Init(argc, argv);
94
95   common::CommandLine* cmd = common::CommandLine::ForCurrentProcess();
96   std::string appid = cmd->GetAppIdFromCommandLine(runtime::kRuntimeExecName);
97
98   // Load Manifest
99   auto appdata_manager = common::ApplicationDataManager::GetInstance();
100   common::ApplicationData* appdata = appdata_manager->GetApplicationData(appid);
101   if (!appdata->LoadManifestData()) {
102     return false;
103   }
104
105 #ifdef WATCH_FACE_FEATURE_SUPPORT
106   if (appdata->app_type() == common::ApplicationData::WATCH) {
107     setWatchEnv(argc, argv);
108   }
109 #endif  // WATCH_FACE_FEATURE_SUPPORT
110
111   // Default behavior, run as runtime.
112   LOGGER(INFO) << "Runtime process has been created.";
113   if (!g_prelaunch) {
114     ewk_init();
115     char* chromium_arg_options[] = {
116       argv[0],
117       const_cast<char*>("--no-sandbox"),
118       const_cast<char*>("--enable-file-cookies"),
119       const_cast<char*>("--allow-file-access-from-files"),
120       const_cast<char*>("--allow-universal-access-from-files"),
121       const_cast<char*>("--single-process")
122     };
123     const int chromium_arg_cnt =
124         sizeof(chromium_arg_options) / sizeof(chromium_arg_options[0]);
125     ewk_set_arguments(chromium_arg_cnt, chromium_arg_options);
126 #ifdef WATCH_FACE_FEATURE_SUPPORT
127   } else {
128     if (appdata->app_type() == common::ApplicationData::WATCH) {
129       // Below code will be enabled after testing
130       //ecore_wl_shutdown();
131       //ecore_wl_init(NULL);
132     }
133 #endif  // WATCH_FACE_FEATURE_SUPPORT
134   }
135
136   int ret = 0;
137   // Runtime's destructor should be called before ewk_shutdown()
138   {
139     std::unique_ptr<runtime::Runtime> runtime =
140         runtime::Runtime::MakeRuntime(appdata);
141     ret = runtime->Exec(argc, argv);
142     runtime.reset();
143   }
144 #ifdef IME_FEATURE_SUPPORT
145   if (appdata->app_type() == common::ApplicationData::IME) {
146     timeout = ecore_timer_add(0.5, terminateDelayCallback, NULL);
147     // This timer is added because of deadlock issue.
148     // If default keyboard is switched from webapp keyboard to tizen keyboard
149     // before webapp keyboard is completely loaded, main loop waits
150     // until webview is closed where webview is waiting to finish load.
151     // This timer delays main loop shutdown until webview load is finished.
152     // FIXME: http://suprem.sec.samsung.net/jira/browse/TSAM-11361
153     ecore_main_loop_begin();
154   }
155 #endif
156   ewk_shutdown();
157   elm_exit();
158
159   return EXIT_SUCCESS;
160 }
161
162 __attribute__((visibility("default")))
163 int main(int argc, char* argv[]) {
164   if (strcmp(argv[0], "/usr/bin/wrt-loader") == 0) {
165     elm_init(argc, argv);
166     elm_config_cache_flush_enabled_set(EINA_TRUE);
167     auto preload = [argv](void) {
168       g_prelaunch = true;
169       ewk_init();
170       char* chromium_arg_options[] = {
171         argv[0],
172         const_cast<char*>("--no-sandbox"),
173         const_cast<char*>("--enable-file-cookies"),
174         const_cast<char*>("--allow-file-access-from-files"),
175         const_cast<char*>("--allow-universal-access-from-files"),
176         const_cast<char*>("--single-process")
177       };
178       const int chromium_arg_cnt =
179           sizeof(chromium_arg_options) / sizeof(chromium_arg_options[0]);
180       ewk_set_arguments(chromium_arg_cnt, chromium_arg_options);
181       runtime::PreloadManager::GetInstance()->CreateCacheComponet();
182     };
183     auto did_launch = [](const std::string& app_path) {
184     };
185     auto prelaunch = runtime::PreLauncher::Prelaunch;
186     return prelaunch(argc, argv, preload, did_launch, real_main);
187   } else {
188     return real_main(argc, argv);
189   }
190 }