Run Tizen Webapps in single process mode
[platform/framework/web/crosswalk-tizen.git] / tizen / src / wrt_main.cc
1 // Copyright (c) 2013 GitHub, Inc.
2 // Use of this source code is governed by the MIT license that can be
3 // found in the LICENSE file.
4
5 #include "wrt_main.h"
6 #include "tizen/common/env_variables.h"
7
8 #include <stdlib.h>
9 #include "atom/app/atom_main_delegate.h"  // NOLINT
10 #include "content/public/app/content_main.h"
11
12 #include "atom/app/node_main.h"
13 #include "atom/common/atom_command_line.h"
14 #include "base/at_exit.h"
15 #include "base/i18n/icu_util.h"
16
17 #include "efl/init.h"
18
19 #if defined(OS_TIZEN)
20 #include <Elementary.h>
21
22 #include "atom/app/runtime.h"
23 #include "base/logging.h"
24 #include "tizen/common/application_data.h"
25 #include "tizen/common/command_line.h"
26 #include "tizen/loader/prelauncher.h"
27 #include "tizen/browser/preload_manager.h"
28 #endif
29
30 namespace {
31
32 bool block_single_process = false; // set to true to disable single process mode altogether
33
34 // Default command line flags for all profiles and platforms
35 const char* kDefaultCommandLineFlags[] = {
36   "allow-file-access-from-files",
37   "enable-tizen-app-container",
38   "allow-universal-access-from-files",
39   "single-process",
40   "no-sandbox",
41   "no-zygote",
42 };
43
44 const int kElectronArgsCount = 2;
45 const int kTizenWebappArgsCount = 6;
46
47 bool isElectronWebApp() {
48   auto app_data = common::ApplicationDataManager::GetCurrentAppData();
49   if (app_data) {
50     if (app_data->content_info()) {
51       std::string startUrl = app_data->content_info()->src();
52       if (std::string::npos != startUrl.find(".json")) {
53         return true;
54       }
55     }
56   }
57   return false;
58 }
59
60 bool IsBrowserProcess() {
61   auto command_line = base::CommandLine::ForCurrentProcess();
62   std::string process_type = command_line->GetSwitchValueASCII("type");
63   return process_type.empty();
64 }
65
66 }  // namespace
67
68 #define REFERENCE_MODULE(name) \
69   extern "C" void _register_ ## name(void); \
70   void (*wrt_register_ ## name)(void) = _register_ ## name
71 REFERENCE_MODULE(wrt);
72 #undef REFERENCE_MODULE
73
74 #if defined(OS_TIZEN)
75 bool g_initialized_ = false;
76 std::unique_ptr<runtime::Runtime> runtime_;
77
78 // For debug purpose only.
79 // TODO: To be removed later
80 bool hasTizenPackageID(int argc, const char* const* argv) {
81   if (argc > 3) {
82     if (0 == strncmp(argv[0], "/opt/usr/globalapps/", strlen("/opt/usr/globalapps/"))) {
83       return true;
84     }
85     if (0 == strncmp(argv[0], "/opt/usr/apps/", strlen("/opt/usr/apps/"))) {
86       return true;
87     }
88   }
89   return false;
90 }
91
92 int real_main(int argc, char* argv[]) {
93 #else
94 int main(int argc, char* argv[]) {
95 #endif
96   for (int i = 0; i < argc; ++i)
97     LOG(ERROR) << "argv[" << i << "] : " << argv[i];
98
99   if (!common::CommandLine::Init(argc, argv)) {
100     common::CommandLine::Reset();
101     common::CommandLine::Init(argc, argv);
102   }
103
104   if (!base::CommandLine::Init(argc, argv)) {
105     base::CommandLine::Reset();
106     base::CommandLine::Init(argc, argv);
107   }
108
109   common::CommandLine* runtime_cmd = common::CommandLine::ForCurrentProcess();
110   std::string appid = runtime_cmd->GetAppIdFromCommandLine("/usr/bin/wrt");
111
112   // load manifest
113   if (appid != "wrt") { // TODO: Any better way to distinguish?
114     common::ApplicationDataManager::SetCurrentAppID(appid);
115   }
116   if (!g_initialized_) {
117     if (efl::Initialize(argc, const_cast<const char**>(argv)))
118       return 1;
119   }
120
121   // Add params for EFL port
122   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
123
124   int args_count = kElectronArgsCount;
125   if (IsBrowserProcess()) {
126     if (!block_single_process && !isElectronWebApp()) {
127       LOG(ERROR) << "will run in single process mode";
128       tizen::is_single_process = true;
129       args_count = kTizenWebappArgsCount;
130     } else LOG(ERROR) << "will run in non-single process mode";
131   } else LOG(ERROR) << "not a browser process";
132
133   static std::vector<char*> flags;
134   for (int i = 0; i < args_count; ++i)
135     command_line->AppendSwitch(const_cast<char*>(kDefaultCommandLineFlags[i]));
136
137   efl::AppendPortParams(*command_line);
138
139   atom::AtomMainDelegate delegate;
140   content::ContentMainParams params(&delegate);
141   params.argc = argc;
142   params.argv = const_cast<const char**>(argv);
143   atom::AtomCommandLine::Init(argc, argv);
144 #if defined(OS_TIZEN)
145   if (hasTizenPackageID(argc,argv)) { // TODO: Check to be removed later
146     elm_init(argc, argv);
147     if (!g_initialized_) {
148       runtime_ = runtime::Runtime::MakeRuntime(&params);
149     } else {
150       runtime_->SetParam(&params);
151     }
152     return runtime_->Exec();
153   }
154 #endif
155   return content::ContentMain(params);
156 }
157
158 #if defined(OS_TIZEN)
159 __attribute__((visibility("default")))
160 int main(int argc, const char* argv[]) {
161   for (int i = 0; i < argc; ++i)
162     LOG(ERROR) << "argv[" << i << "] : " << argv[i];
163   if (strcmp(argv[0], "/usr/bin/wrt-loader") == 0) {
164     LOG(ERROR) << "run with wrt-loader";
165     auto preload = [argc, argv](void) {
166       g_initialized_ = true;
167       if (efl::Initialize(argc, const_cast<const char**>(argv)))
168         return 1;
169
170       atom::AtomMainDelegate delegate;
171       content::ContentMainParams params(&delegate);
172       params.argc = argc;
173       params.argv = const_cast<const char**>(argv);
174       atom::AtomCommandLine::Init(argc, argv);
175       runtime_ = runtime::Runtime::MakeRuntime(nullptr);
176       tizen::PreloadManager::GetInstance()->CreateCacheComponent();
177       return 0;
178     };
179     auto did_launch = [](const std::string& app_path) {
180     };
181     auto prelaunch = runtime::PreLauncher::Prelaunch;
182     return prelaunch(argc, const_cast<char**>(argv), preload, did_launch, real_main);
183   } else {
184     LOG(ERROR) << "run without wrt-loader";
185     return real_main(argc, const_cast<char**>(argv));
186   }
187 }
188 #endif