[Tizen] Add preloader 90/163190/5
authorYoungsoo Choi <kenshin.choi@samsung.com>
Wed, 6 Dec 2017 05:17:35 +0000 (05:17 +0000)
committerSangYong Park <sy302.park@samsung.com>
Fri, 12 Jan 2018 01:03:23 +0000 (01:03 +0000)
This implements initial preloader, using loader life-cycle of launchpad.
Implementation for preloaded modules will be added later.

Change-Id: I75b9b9efde060988066f49e8c07d709d771dc872
Signed-off-by: Youngsoo Choi <kenshin.choi@samsung.com>
atom/app/atom_main.cc
efl/build/system.gyp
electron.gyp
packaging/electron-efl.spec
tizen/loader/loader.gyp
tizen/loader/prelauncher.cc [new file with mode: 0755]
tizen/loader/prelauncher.h [new file with mode: 0755]

index 28959e5..2b33586 100644 (file)
 #endif
 
 #include "atom/app/node_main.h"
+#include "tizen/loader/prelauncher.h"
 #include "atom/common/atom_command_line.h"
 #include "base/at_exit.h"
 #include "base/i18n/icu_util.h"
+#include "base/logging.h"
 
 namespace {
 
@@ -127,10 +129,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
 
 #elif defined(OS_LINUX)  // defined(OS_WIN)
 
-#if defined(OS_TIZEN)
-__attribute__((visibility("default")))
-#endif
-int main(int argc, const char* argv[]) {
+int real_main(int argc, char* argv[]) {
   if (IsEnvSet(kRunAsNode)) {
     base::i18n::InitializeICU();
     base::AtExitManager atexit_manager;
@@ -138,7 +137,7 @@ int main(int argc, const char* argv[]) {
   }
 
 #if defined(USE_EFL)
-  if (efl::Initialize(argc, argv))
+  if (efl::Initialize(argc, const_cast<const char**>(argv)))
     return 1;
 
   // Add params for EFL port
@@ -153,11 +152,29 @@ int main(int argc, const char* argv[]) {
   atom::AtomMainDelegate delegate;
   content::ContentMainParams params(&delegate);
   params.argc = argc;
-  params.argv = argv;
+  params.argv = const_cast<const char**>(argv);
   atom::AtomCommandLine::Init(argc, argv);
   return content::ContentMain(params);
 }
 
+#if defined(OS_TIZEN)
+__attribute__((visibility("default")))
+#endif
+int main(int argc, const char* argv[]) {
+  if (strcmp(argv[0], "/usr/bin/wrt-loader") == 0) {
+    LOG(INFO) << "run with wrt-loader";
+    auto preload = [argv](void) {
+    };
+    auto did_launch = [](const std::string& app_path) {
+    };
+    auto prelaunch = runtime::PreLauncher::Prelaunch;
+    return prelaunch(argc, const_cast<char**>(argv), preload, did_launch, real_main);
+  } else {
+    LOG(INFO) << "run without wrt-loader";
+    return real_main(argc, const_cast<char**>(argv));
+  }
+}
+
 #else  // defined(OS_LINUX)
 
 int main(int argc, const char* argv[]) {
index b35dd83..8934237 100644 (file)
@@ -8,6 +8,27 @@
   },
   'targets': [
     {
+      'target_name': 'ecore',
+      'type': 'none',
+      'conditions': [
+        ['is_tizen==1', {
+          'direct_dependent_settings': {
+            'cflags': [
+              '<!@(<(pkg-config) --cflags ecore)',
+            ],
+          },
+          'link_settings': {
+            'ldflags': [
+              '<!@(<(pkg-config) --libs-only-L --libs-only-other ecore)',
+            ],
+            'libraries': [
+              '<!@(<(pkg-config) --libs-only-l ecore)',
+            ],
+          },
+        }],
+      ],
+    }, # ecore
+    {
       'target_name': 'ecore-x',
       'type': 'none',
       'conditions': [
       ],
     }, # efl-extension
     {
+      'target_name': 'launchpad',
+      'type': 'none',
+      'conditions': [
+        ['is_tizen==1', {
+          'direct_dependent_settings': {
+            'cflags': [
+              '<!@(<(pkg-config) --cflags launchpad)',
+            ],
+          },
+          'link_settings': {
+            'ldflags': [
+              '<!@(<(pkg-config) --libs-only-L --libs-only-other launchpad)',
+            ],
+            'libraries': [
+              '<!@(<(pkg-config) --libs-only-l launchpad)',
+            ],
+          },
+        }],
+      ],
+    }, # launchpad
+    {
       'target_name': 'vd-win-util',
       'type': 'none',
       'conditions': [
index 3cbba15..dda2dff 100644 (file)
           'dependencies': [
             'tizen/common/common.gyp:*',
             'tizen/loader/loader.gyp:*',
+            '<(DEPTH)/efl/build/system.gyp:ecore',
+            '<(DEPTH)/efl/build/system.gyp:launchpad',
           ],
           'ldflags': [
             '-pie',
index 916804f..81b7b06 100755 (executable)
@@ -29,7 +29,9 @@ BuildRequires: pkgconfig(chromium-efl)
 BuildRequires: pkgconfig(cynara-client)
 BuildRequires: pkgconfig(dbus-glib-1)
 BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(ecore)
 BuildRequires: pkgconfig(ecore-evas)
+BuildRequires: pkgconfig(ecore-wayland)
 BuildRequires: pkgconfig(efl-extension)
 BuildRequires: pkgconfig(elementary)
 BuildRequires: pkgconfig(evas)
@@ -37,6 +39,7 @@ BuildRequires: pkgconfig(expat)
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(gmodule-2.0)
 BuildRequires: pkgconfig(icu-i18n)
+BuildRequires: pkgconfig(launchpad)
 # It's added to use TZ_SYS_RO_PACKAGES.
 BuildRequires: pkgconfig(libtzplatform-config)
 BuildRequires: pkgconfig(libwebappenc)
index d8127f6..14d1fdc 100755 (executable)
         ]
       },
     },  # end of target 'wrt-loader'
+    {
+      'target_name': 'prelauncher',
+      'type': 'static_library',
+      'dependencies': [
+        '<(DEPTH)/efl/build/system.gyp:ecore',
+        '<(DEPTH)/efl/build/system.gyp:launchpad',
+      ],
+      'include_dirs': [
+        '<(libchromiumcontent_src_dir)',
+      ],
+      'cflags': [ '-fPIC' ],
+      'cflags_cc': [ '-fPIC' ],
+      'sources': [
+        'prelauncher.cc',
+        'prelauncher.h',
+      ],
+    },  # end of target 'preloader'
   ],
 }
diff --git a/tizen/loader/prelauncher.cc b/tizen/loader/prelauncher.cc
new file mode 100755 (executable)
index 0000000..a302e82
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include "prelauncher.h"
+#include "base/logging.h"
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <launchpad.h>
+
+#include <csignal>
+#include <memory>
+
+namespace runtime {
+
+PreLauncher::PreLauncher() {
+  ecore_init();
+}
+
+PreLauncher::~PreLauncher() {
+  ecore_shutdown();
+}
+
+void PreLauncher::StartMainLoop() {
+  ecore_main_loop_begin();
+}
+
+void PreLauncher::StopMainLoop() {
+  ecore_main_loop_quit();
+}
+
+void PreLauncher::Watch(int fd, std::function<void(int)> readable) {
+  auto callback = [](void *user_data, Ecore_Fd_Handler *fd_handler) {
+    PreLauncher* launcher = static_cast<PreLauncher*>(user_data);
+    if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
+      int fd = ecore_main_fd_handler_fd_get(fd_handler);
+      auto handler = launcher->handlers_[fd_handler];
+      if (handler)
+        handler(fd);
+    }
+    return ECORE_CALLBACK_RENEW;
+  };
+  Ecore_Fd_Handler* handler =
+      ecore_main_fd_handler_add(fd,
+          static_cast<Ecore_Fd_Handler_Flags>(ECORE_FD_READ),
+          callback, this, NULL, NULL);
+  handlers_[handler] = readable;
+  fd_map_[fd] = handler;
+}
+
+void PreLauncher::Unwatch(int fd) {
+  auto found = fd_map_.find(fd);
+  if (found == fd_map_.end())
+    return;
+  auto handle = found->second;
+  ecore_main_fd_handler_del(handle);
+  fd_map_.erase(found);
+  handlers_.erase(handle);
+}
+
+int PreLauncher::Prelaunch(int argc, char* argv[],
+    Preload preload, DidStart didstart, RealMain realmain) {
+  std::unique_ptr<PreLauncher> launcher(new PreLauncher());
+  launcher->preload_ = preload;
+  launcher->didstart_ = didstart;
+  launcher->realmain_ = realmain;
+
+  auto create = [](bundle* extra, int type, void *user_data) {
+    LOG(INFO) << "create";
+    PreLauncher* launcher = static_cast<PreLauncher*>(user_data);
+    launcher->preload_();
+  };
+
+  auto launch = [](int argc, char **argv, const char *app_path,
+                   const char *appid, const char *pkgid,
+                   const char *pkg_type, void *user_data) {
+    LOG(INFO) << "launch";
+    PreLauncher* launcher = static_cast<PreLauncher*>(user_data);
+    launcher->didstart_(app_path);
+    return 0;
+  };
+
+  auto terminate = [](int argc, char **argv, void *user_data) {
+    LOG(INFO) << "terminate";
+    PreLauncher* launcher = static_cast<PreLauncher*>(user_data);
+    return launcher->realmain_(argc, argv);
+  };
+
+  auto start_loop = [](void *user_data) {
+    LOG(INFO) << "start_loop";
+    PreLauncher* launcher = static_cast<PreLauncher*>(user_data);
+    launcher->StartMainLoop();
+  };
+
+  auto stop_loop = [](void *user_data) {
+    LOG(INFO) << "stop_loop";
+    PreLauncher* launcher = static_cast<PreLauncher*>(user_data);
+    launcher->StopMainLoop();
+  };
+
+  auto add_fd = [](void *user_data, int fd, loader_receiver_cb receiver) {
+    LOG(INFO) << "add_fd";
+    PreLauncher* launcher = static_cast<PreLauncher*>(user_data);
+    launcher->Watch(fd, receiver);
+  };
+
+  auto remove_fd = [](void *user_data, int fd) {
+    LOG(INFO) << "remove_fd";
+    PreLauncher* launcher = static_cast<PreLauncher*>(user_data);
+    launcher->Unwatch(fd);
+  };
+
+  loader_lifecycle_callback_s callbacks = {
+    create,
+    launch,
+    terminate
+  };
+
+  loader_adapter_s loop_methods = {
+    start_loop,
+    stop_loop,
+    add_fd,
+    remove_fd
+  };
+
+  LOG(INFO) << "launchpad_loader_main is called !!";
+  return launchpad_loader_main(argc, argv,
+                               &callbacks,
+                               &loop_methods,
+                               launcher.get());
+}
+
+}  // namespace runtime
diff --git a/tizen/loader/prelauncher.h b/tizen/loader/prelauncher.h
new file mode 100755 (executable)
index 0000000..3051c97
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include <Ecore.h>
+
+#include <string>
+#include <functional>
+#include <map>
+
+namespace runtime {
+
+class PreLauncher {
+ public:
+  using Preload = std::function<void(void)>;
+  using DidStart = std::function<void(const std::string& app_path)>;
+  using RealMain = std::function<int(int, char**)>;
+  static int Prelaunch(int argc, char* argv[], Preload, DidStart, RealMain);
+
+  PreLauncher();
+  ~PreLauncher();
+
+ private:
+  void StartMainLoop();
+  void StopMainLoop();
+
+  void Watch(int fd, std::function<void(int)> readable);
+  void Unwatch(int fd);
+
+  Preload preload_;
+  DidStart didstart_;
+  RealMain realmain_;
+
+  std::map<Ecore_Fd_Handler*, std::function<void(int)> > handlers_;
+  std::map<int, Ecore_Fd_Handler*> fd_map_;
+};
+
+}  // namespace runtime