Separate the library from the launchpad-process-pool 86/316986/6
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 2 Sep 2024 07:00:55 +0000 (16:00 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 2 Sep 2024 07:40:06 +0000 (16:40 +0900)
The launchpad-core library is added. It will be used the sub module.

Change-Id: I57f448e7556743d2cdd73e72256598e56d8d027e
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
72 files changed:
CMakeLists.txt
packaging/launchpad.spec
src/launchpad-process-pool/CMakeLists.txt
src/launchpad-process-pool/app_defined_loader_info_manager.hh
src/launchpad-process-pool/app_executor.cc [deleted file]
src/launchpad-process-pool/app_executor.hh [deleted file]
src/launchpad-process-pool/config.cc
src/launchpad-process-pool/config.hh
src/launchpad-process-pool/dbus.cc
src/launchpad-process-pool/debug.cc [deleted file]
src/launchpad-process-pool/debug.hh [deleted file]
src/launchpad-process-pool/debugger_info.cc [deleted file]
src/launchpad-process-pool/debugger_info.hh [deleted file]
src/launchpad-process-pool/executor.cc [deleted file]
src/launchpad-process-pool/executor.hh [deleted file]
src/launchpad-process-pool/file_monitor.cc [deleted file]
src/launchpad-process-pool/file_monitor.hh [deleted file]
src/launchpad-process-pool/launcher_info.cc [deleted file]
src/launchpad-process-pool/launcher_info.hh [deleted file]
src/launchpad-process-pool/launchpad.cc
src/launchpad-process-pool/launchpad.hh
src/launchpad-process-pool/launchpad_args.cc [deleted file]
src/launchpad-process-pool/launchpad_args.hh [deleted file]
src/launchpad-process-pool/loader_context.cc
src/launchpad-process-pool/loader_context.hh
src/launchpad-process-pool/loader_executor.cc [deleted file]
src/launchpad-process-pool/loader_executor.hh [deleted file]
src/launchpad-process-pool/loader_factory.hh
src/launchpad-process-pool/loader_info.cc [deleted file]
src/launchpad-process-pool/loader_info.hh [deleted file]
src/launchpad-process-pool/loader_manager.cc
src/launchpad-process-pool/loader_manager.hh
src/launchpad-process-pool/loader_mount.cc
src/launchpad-process-pool/loader_mount.hh
src/launchpad-process-pool/process_pool.cc [deleted file]
src/launchpad-process-pool/process_pool.hh [deleted file]
src/launchpad-process-pool/rec_mutex.hh [deleted file]
src/launchpad-process-pool/signal_manager.cc
src/launchpad-process-pool/signal_manager.hh
src/launchpad-process-pool/util.cc [deleted file]
src/launchpad-process-pool/util.hh [deleted file]
src/lib/CMakeLists.txt
src/lib/launchpad-core/CMakeLists.txt [new file with mode: 0644]
src/lib/launchpad-core/app_executor.cc [new file with mode: 0644]
src/lib/launchpad-core/app_executor.hh [new file with mode: 0644]
src/lib/launchpad-core/debug.cc [new file with mode: 0644]
src/lib/launchpad-core/debug.hh [new file with mode: 0644]
src/lib/launchpad-core/debugger_info.cc [new file with mode: 0644]
src/lib/launchpad-core/debugger_info.hh [new file with mode: 0644]
src/lib/launchpad-core/executor.cc [new file with mode: 0644]
src/lib/launchpad-core/executor.hh [new file with mode: 0644]
src/lib/launchpad-core/file_monitor.cc [new file with mode: 0644]
src/lib/launchpad-core/file_monitor.hh [new file with mode: 0644]
src/lib/launchpad-core/launcher_info.cc [new file with mode: 0644]
src/lib/launchpad-core/launcher_info.hh [new file with mode: 0644]
src/lib/launchpad-core/launchpad_args.cc [new file with mode: 0644]
src/lib/launchpad-core/launchpad_args.hh [new file with mode: 0644]
src/lib/launchpad-core/loader_executor.cc [new file with mode: 0644]
src/lib/launchpad-core/loader_executor.hh [new file with mode: 0644]
src/lib/launchpad-core/loader_info.cc [new file with mode: 0644]
src/lib/launchpad-core/loader_info.hh [new file with mode: 0644]
src/lib/launchpad-core/log_private.hh [new file with mode: 0644]
src/lib/launchpad-core/pkgconfig/liblaunchpad-core.pc.in [new file with mode: 0644]
src/lib/launchpad-core/process_pool.cc [new file with mode: 0644]
src/lib/launchpad-core/process_pool.hh [new file with mode: 0644]
src/lib/launchpad-core/rec_mutex.hh [new file with mode: 0644]
src/lib/launchpad-core/sigchld_manager.cc [new file with mode: 0644]
src/lib/launchpad-core/sigchld_manager.hh [new file with mode: 0644]
src/lib/launchpad-glib/util.cc
src/lib/launchpad-glib/util.hh
tests/launchpad-process-pool-unittest/CMakeLists.txt
tests/launchpad-process-pool-unittest/src/test_launchpad.cc

index 67bdb598486d73bb9997b95ed2273f63928191fd..8d74456933671f8636975cc001f60b62501a1ddc 100644 (file)
@@ -37,6 +37,7 @@ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
 SET(TARGET_APP_DEFINED_LOADER "app-defined-loader")
 SET(TARGET_LAUNCHPAD "launchpad")
 SET(TARGET_LAUNCHPAD_COMMON "launchpad-common")
+SET(TARGET_LAUNCHPAD_CORE "launchpad-core")
 SET(TARGET_LAUNCHPAD_GLIB "launchpad-glib")
 SET(TARGET_LAUNCHPAD_HYDRA "launchpad-hydra")
 SET(TARGET_LAUNCHPAD_LOADER "launchpad-loader")
index 80aade3e14fb4bd22180f6b96be0f4d852348110..f07e9d3ea4f81064802d1d23694d2a3577770ec9 100644 (file)
@@ -156,7 +156,7 @@ MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
 %__make %{?_smp_mflags}
 
 %check
-export LD_LIBRARY_PATH="../../src/lib/launchpad-common/:../../src/lib/launchpad-glib"
+export LD_LIBRARY_PATH="../../src/lib/launchpad-common/:../../src/lib/launchpad-glib:../../src/lib/launchpad-core"
 ctest --verbose %{?_smp_mflags}
 
 %install
@@ -197,10 +197,12 @@ fi
 %{_datadir}/parser-plugins/*
 %attr(0644,root,root) %{_libdir}/liblaunchpad-common.so.*
 %attr(0644,root,root) %{_libdir}/liblaunchpad-glib.so.*
+%attr(0644,root,root) %{_libdir}/liblaunchpad-core.so.*
 
 %files devel
 %{_includedir}/launchpad/*.h
 %{_includedir}/launchpad-common/*.hh
+%{_includedir}/launchpad-core/*.hh
 %{_includedir}/launchpad-glib/*.hh
 %{_libdir}/*.so
 %{_libdir}/pkgconfig/launchpad.pc
@@ -208,6 +210,8 @@ fi
 %{_libdir}/pkgconfig/liblaunchpad-common.pc
 %attr(0644,root,root) %{_libdir}/liblaunchpad-glib.so
 %{_libdir}/pkgconfig/liblaunchpad-glib.pc
+%attr(0644,root,root) %{_libdir}/liblaunchpad-core.so
+%{_libdir}/pkgconfig/liblaunchpad-core.pc
 
 %files -n launchpad-loader
 %manifest launchpad-loader.manifest
index 062173ce292d0c0149b8c22c4d4891604408686b..84e6098d4730ff15ed96fb7cbf42d97309f8fd14 100644 (file)
@@ -14,7 +14,8 @@ TARGET_INCLUDE_DIRECTORIES(${TARGET_LAUNCHPAD_PROCESS_POOL} PUBLIC
   ${CMAKE_CURRENT_SOURCE_DIR}/../
   ${CMAKE_CURRENT_SOURCE_DIR}/../lib/common/inc
   ${CMAKE_CURRENT_SOURCE_DIR}/../lib/launchpad-common
-  ${CMAKE_CURRENT_SOURCE_DIR}/../lib/launchpad-glib
+  ${CMAKE_CURRENT_SOURCE_DIR}/../lib/launchpad-core
+  ${CMAKE_CURRENT_SOURCE_DIR}/../lib/launchpad-glib  
 )
 
 IF(_TIZEN_FEATURE_PRELINK)
@@ -46,7 +47,8 @@ APPLY_PKG_CONFIG(${TARGET_LAUNCHPAD_PROCESS_POOL} PUBLIC
 )
 
 TARGET_LINK_LIBRARIES(${TARGET_LAUNCHPAD_PROCESS_POOL} PUBLIC
-  ${TARGET_LAUNCHPAD_COMMON} ${TARGET_LAUNCHPAD_GLIB} "-lm -ldl -lpthread")
+  ${TARGET_LAUNCHPAD_COMMON} ${TARGET_LAUNCHPAD_GLIB} ${TARGET_LAUNCHPAD_CORE}
+  "-lm -ldl -lpthread")
 
 CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/packaging/default.debugger.in
   ${CMAKE_SOURCE_DIR}/packaging/default.debugger @ONLY)
index 9df5ffdacdee890d9be46815fddfa678b05a7656..7a2cdd6e6ae366e89230a8c105ddb2fb21573181 100644 (file)
@@ -20,8 +20,8 @@
 #include <memory>
 #include <string_view>
 
-#include "launchpad-process-pool/file_monitor.hh"
-#include "launchpad-process-pool/loader_info.hh"
+#include <file_monitor.hh>
+#include <loader_info.hh>
 
 namespace launchpad {
 
diff --git a/src/launchpad-process-pool/app_executor.cc b/src/launchpad-process-pool/app_executor.cc
deleted file mode 100644 (file)
index e08b293..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (c) 2023 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 "launchpad-process-pool/app_executor.hh"
-
-#include <errno.h>
-#include <libgen.h>
-#include <malloc.h>
-#include <stdio.h>
-#include <sys/prctl.h>
-#include <trust-anchor.h>
-#include <tzplatform_config.h>
-#include <unistd.h>
-
-#include <filesystem>
-#include <utility>
-
-#include <aul_keys.hh>
-#include <plugin.hh>
-#include <stdio.hh>
-#include <types.hh>
-#include <user_tracer.hh>
-#include <util.hh>
-
-#include "launchpad-process-pool/config.hh"
-#include "launchpad-process-pool/debug.hh"
-#include "launchpad-process-pool/log_private.hh"
-#include "launchpad-process-pool/signal_manager.hh"
-
-namespace launchpad {
-namespace fs = std::filesystem;
-namespace {
-
-void ExecuteEcho(const std::string& app_path, const std::string& error) {
-  char *argv[] = {
-      const_cast<char*>("/usr/bin/echo"),
-      const_cast<char*>("Failed to execute a file. path:"),
-      const_cast<char*>(app_path.c_str()),
-      const_cast<char*>("error:"),
-      const_cast<char*>(error.c_str()),
-      nullptr,
-  };
-
-  execv(argv[0], argv);
-}
-
-}  // namespace
-
-AppExecutor::AppExecutor() : Executor(this) {
-  LauncherInfoInflator inflator;
-  launcher_infos_ = inflator.Inflate("/usr/share/aul");
-
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepPluginPrepareApp, this));
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepEnableExternalPackage, this));
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepEnableTrustAnchor, this));
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepMountResDir, this));
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepChangeMountNamespace, this));
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepSecurityPrepareApp, this));
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepSetupStdio, this));
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepSetDumpable, this));
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepSetProcessName, this));
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepSetEnvironments, this));
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepWaitTepMount, this));
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepPrepareAppSocketAndIdFile, this));
-  prepare_funcs_.push_back(
-      std::bind(&AppExecutor::StepSendStartupSignal, this));
-
-  auto& process_pool_config = Config::GetInst().GetProcessPool();
-  process_pool_ = std::unique_ptr<ProcessPool>(
-      new ProcessPool("app", process_pool_config.GetNumberOfProcesses(), this));
-}
-
-pid_t AppExecutor::Execute(const AppInfo* app_info) {
-  if (process_pool_->IsPrepared()) {
-    tizen_base::Parcel parcel;
-    parcel.WriteParcelable(*app_info);
-    pid_t pid = process_pool_->Execute(parcel);
-    if (pid > 0)
-      return pid;
-  }
-
-  app_info_ = app_info;
-  return Executor::Execute();
-}
-
-void AppExecutor::DisposeCandidateProcess() {
-  process_pool_->Dispose();
-  process_pool_->SetTimer();
-}
-
-void AppExecutor::HandleSigchld(pid_t pid) {
-  process_pool_->HandleSigchld(pid);
-}
-
-void AppExecutor::OnExecution() {
-  UserTracer::Print(std::to_string(getpid()) + "|after calling fork(). " +
-      app_info_->GetAppId());
-  CheckAndPrepareDebugging();
-  SignalManager::GetInst().UnblockSigchld();
-  Util::DeleteSocketPath(getpid(), getuid());
-
-  int ret = Prepare();
-  if (ret < 0) {
-    _E("Failed to prepare executing application(%s)",
-        app_info_->GetAppId().c_str());
-    ExecuteEcho(app_info_->GetAppPath(), std::to_string(ret));
-    exit(ret);
-  }
-
-  std::vector<std::string> argv = CreateAppArgv(app_info_->GetAppPath(),
-      app_info_->GetBundle(), app_info_->GetAppType());
-  char** app_argv = static_cast<char**>(calloc(argv.size() + 1, sizeof(char*)));
-  if (app_argv == nullptr) {
-    _E("Out of memory");
-    ExecuteEcho(app_info_->GetAppPath(), std::to_string(-ENOMEM));
-    exit(-1);
-  }
-
-  int app_argc = argv.size();
-  for (int i = 0; i < app_argc; ++i) {
-    app_argv[i] = const_cast<char*>(argv[i].c_str());
-    SECURE_LOGD("input argument %d : %s##", i, app_argv[i]);
-  }
-
-  auto lib_dir = Util::GetLibDirectory(app_info_->GetAppPath());
-  if (!lib_dir.empty())
-    setenv("LD_LIBRARY_PATH", lib_dir.c_str(), 1);
-
-  Util::CloseAllFds();
-  SECURE_LOGE("Execute application(%s)", app_argv[LoaderArg::Path]);
-  if (execv(app_argv[LoaderArg::Path], app_argv) < 0) {
-    char err_buf[1024];
-    fprintf(stderr, "Failed to execute a file. path: %s, errno: %d(%s)\n",
-        app_info_->GetAppPath().c_str(), errno,
-        strerror_r(errno, err_buf, sizeof(err_buf)));
-    ExecuteEcho(app_info_->GetAppPath(), err_buf);
-    exit(EXIT_FAILURE);
-  }
-}
-
-void AppExecutor::OnRequestReceived(tizen_base::Parcel* parcel) {
-  _W("Request received");
-  AppInfo app_info;
-  parcel->ReadParcelable(&app_info);
-  app_info_ = &app_info;
-  OnExecution();
-}
-
-int AppExecutor::Prepare() {
-  for (auto& func : prepare_funcs_) {
-    if (func() != 0)
-      return -1;
-  }
-
-  return 0;
-}
-
-int AppExecutor::StepPluginPrepareApp() {
-  return Plugin::PrepareApp(app_info_->GetAppId(), app_info_->GetBundle());
-}
-
-int AppExecutor::StepEnableExternalPackage() {
-  return Util::EnableExternalPackage(app_info_);
-}
-
-int AppExecutor::StepEnableTrustAnchor() {
-  int ret = trust_anchor_launch(app_info_->GetPkgId().c_str(),
-      app_info_->IsGlobal() ? GLOBAL_USER : getuid());
-  if (ret != TRUST_ANCHOR_ERROR_NONE &&
-      ret != TRUST_ANCHOR_ERROR_NOT_INSTALLED) {
-    _E("trust_anchor_launch() returns %d", ret);
-    return -2;
-  }
-
-  return 0;
-}
-
-int AppExecutor::StepMountResDir() {
-  int ret = Util::MountGadgetDirectories(app_info_->GetBundle());
-  if (ret != 0) {
-    _E("Failed to mount gadget resources");
-    return ret;
-  }
-
-  Util::MountLibraryDirectories(app_info_->GetBundle());
-  return Util::MountResourceDirectories(app_info_);
-}
-
-int AppExecutor::StepChangeMountNamespace() {
-  if (app_info_->GetBundle().GetType(kAulSdk) != BUNDLE_TYPE_NONE)
-    Debug::ChangeMountNamespace();
-
-  return 0;
-}
-
-int AppExecutor::StepSecurityPrepareApp() {
-  auto enabled_light_user = app_info_->GetBundle().GetString(
-      kAulEnabledLightUser);
-  _W("security_manager_prepare_app2 ++ %s", app_info_->GetAppId().c_str());
-  int ret = security_manager_prepare_app2(app_info_->GetAppId().c_str(),
-      enabled_light_user.empty() ? nullptr : enabled_light_user.c_str());
-  _W("security_manager_prepare_app2 -- %s", app_info_->GetAppId().c_str());
-  if (ret != SECURITY_MANAGER_SUCCESS) {
-    _E("security_manager_prepare_app2() returns %d", ret);
-    return -2;
-  }
-
-  return 0;
-}
-
-int AppExecutor::StepSetupStdio() {
-  if (app_info_->GetBundle().GetType(kAulSdk) == BUNDLE_TYPE_NONE)
-    Stdio::Setup();
-
-  return 0;
-}
-
-int AppExecutor::StepSetDumpable() {
-  prctl(PR_SET_DUMPABLE, 1);
-  return 0;
-}
-
-int AppExecutor::StepSetProcessName() {
-  fs::path file_path(app_info_->GetAppPath());
-  fs::path file_name = file_path.filename();
-  prctl(PR_SET_NAME, file_name.c_str());
-  return 0;
-}
-
-int AppExecutor::StepSetEnvironments() {
-  Util::SetEnvironments(app_info_);
-  return 0;
-}
-
-int AppExecutor::StepWaitTepMount() {
-  return Util::WaitTepMount(app_info_);
-}
-
-int AppExecutor::StepPrepareAppSocketAndIdFile() {
-  if (app_info_->GetBundle().GetType(kAulSdk) != BUNDLE_TYPE_NONE)
-    return 0;
-
-  if (Util::PrepareAppSocket() < 0)
-    return -1;
-
-  return Util::PrepareAppIdFile(app_info_);
-}
-
-int AppExecutor::StepSendStartupSignal() {
-  Util::SendCmdToAmd(AmdCmd::AppStartupSignal);
-  return 0;
-}
-
-void AppExecutor::CheckAndPrepareDebugging() {
-  auto& debug = Debug::GetInst();
-  auto& b = app_info_->GetBundle();
-  if (b.GetType(kAulSdk) != BUNDLE_TYPE_NONE)
-    debug.PrepareDebugger(b);
-
-  debug.CheckAndSetAsanActivation(app_info_->GetAppId());
-  debug.CheckWebAppDebugging(b);
-}
-
-LauncherInfoPtr AppExecutor::FindLauncherInfo(const std::string& app_type) {
-  for (auto& info : launcher_infos_) {
-    for (auto& type : info->GetAppTypes()) {
-      if (type == app_type)
-        return info;
-    }
-  }
-
-  return nullptr;
-}
-
-std::vector<std::string> AppExecutor::GetLauncherArgv(
-  const std::string& app_type) {
-  std::vector<std::string> argv;
-  auto launcher_info = FindLauncherInfo(app_type);
-  if (launcher_info == nullptr) return argv;
-
-  argv.insert(argv.end(), launcher_info->GetExe());
-  argv.insert(argv.end(), launcher_info->GetExtraArgs().begin(),
-      launcher_info->GetExtraArgs().end());
-  return argv;
-}
-
-std::vector<std::string> AppExecutor::CreateAppArgv(const std::string& app_path,
-    const tizen_base::Bundle& b, const std::string& app_type) {
-  auto& inst = launchpad::Debug::GetInst();
-  std::vector<std::string> argv = inst.GetArgv();
-  if (inst.ShouldAttach())
-    return argv;
-
-  bool debug_mode = !argv.empty() ? true : false;
-  auto launcher_argv = GetLauncherArgv(app_type);
-  if (!launcher_argv.empty())
-    argv.insert(argv.end(), launcher_argv.begin(), launcher_argv.end());
-
-  auto exported_argv = b.Export();
-  exported_argv[LoaderArg::Path] = app_path;
-  if (debug_mode &&
-      exported_argv.size() > static_cast<size_t>(LoaderArg::Type))
-    exported_argv[LoaderArg::Type] = "'" + exported_argv[LoaderArg::Type] + "'";
-
-  if (!exported_argv.empty())
-    argv.insert(argv.end(), exported_argv.begin(), exported_argv.end());
-
-  auto extra_argv = inst.GetExtraArgv();
-  if (!extra_argv.empty())
-    argv.insert(argv.end(), extra_argv.begin(), extra_argv.end());
-
-  return argv;
-}
-
-}  // namespace launchpad
diff --git a/src/launchpad-process-pool/app_executor.hh b/src/launchpad-process-pool/app_executor.hh
deleted file mode 100644 (file)
index 4d75f9b..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- */
-
-#ifndef LAUNCHPAD_PROCESS_POOL_APP_EXECUTOR_HH_
-#define LAUNCHPAD_PROCESS_POOL_APP_EXECUTOR_HH_
-
-#include <bundle_cpp.h>
-
-#include <functional>
-#include <string>
-#include <vector>
-#include <memory>
-
-#include <app_info.hh>
-
-#include "launchpad-process-pool/executor.hh"
-#include "launchpad-process-pool/launcher_info.hh"
-#include "launchpad-process-pool/process_pool.hh"
-
-namespace launchpad {
-
-class AppExecutor : public Executor::Delegator,
-                    public Executor,
-                    public ProcessPool::IEvent {
- public:
-  AppExecutor();
-
-  pid_t Execute(const AppInfo* app_info);
-  void DisposeCandidateProcess();
-  void HandleSigchld(pid_t pid);
-
- private:
-  void OnExecution() override;
-  void OnRequestReceived(tizen_base::Parcel* parcel) override;
-
-  int Prepare();
-  int StepPluginPrepareApp();
-  int StepEnableExternalPackage();
-  int StepEnableTrustAnchor();
-  int StepMountResDir();
-  int StepChangeMountNamespace();
-  int StepSecurityPrepareApp();
-  int StepSetupStdio();
-  int StepSetDumpable();
-  int StepSetProcessName();
-  int StepSetEnvironments();
-  int StepWaitTepMount();
-  int StepPrepareAppSocketAndIdFile();
-  int StepSendStartupSignal();
-
-  void CheckAndPrepareDebugging();
-  std::vector<std::string> GetLauncherArgv(const std::string& app_type);
-  std::vector<std::string> CreateAppArgv(const std::string& app_path,
-      const tizen_base::Bundle& b, const std::string& app_type);
-  LauncherInfoPtr FindLauncherInfo(const std::string& app_type);
-
- private:
-  using PrepareFunc = std::function<int()>;
-
-  std::vector<LauncherInfoPtr> launcher_infos_;
-  std::vector<PrepareFunc> prepare_funcs_;
-  std::unique_ptr<ProcessPool> process_pool_;
-  const AppInfo* app_info_ = nullptr;
-};
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_PROCESS_POOL_APP_EXECUTOR_HH_
index 00f76893865dee26e45c63a1a0517432047425f5..efac39ddd0564e24271b723ab8873782c2934e19 100644 (file)
@@ -18,8 +18,9 @@
 
 #include <utility>
 
+#include <util.hh>
+
 #include "launchpad-process-pool/log_private.hh"
-#include "launchpad-process-pool/util.hh"
 
 namespace launchpad {
 namespace {
@@ -44,11 +45,6 @@ constexpr const char kTagLogger[] = "Logger";
 constexpr const char kKeyLoggerPath[] = "Path";
 constexpr const char kKeyLoggerEnable[] = "Enable";
 
-constexpr const char kTagProcessPool[] = "ProcessPool";
-constexpr const char kKeyProcessPoolNumberOfProcesses[] = "NumberOfProcesses";
-constexpr const char kKeyProcessPoolNumberOfLoaderProcesses[] =
-    "NumberOfLoaderProcesses";
-
 constexpr const char kTagLaunchMode[] = "LaunchMode";
 constexpr const char kKeyMode[] = "Mode";
 constexpr const char kValueModePreviousOperation[] = "PREVIOUS_OPERATION";
@@ -163,34 +159,10 @@ Config::Logger::Logger(const IniParser& parser) {
       path_.c_str(), enable_ ? "true" : "false");
 }
 
-Config::ProcessPool::ProcessPool(const IniParser& parser) {
-  auto number_of_processes = parser.Get(kTagProcessPool,
-      kKeyProcessPoolNumberOfProcesses);
-  if (!number_of_processes.empty() && std::isdigit(number_of_processes[0]))
-    number_of_processes_ = std::stoi(number_of_processes);
-
-  auto number_of_loader_processes = parser.Get(kTagProcessPool,
-      kKeyProcessPoolNumberOfLoaderProcesses);
-  if (!number_of_loader_processes.empty() &&
-      std::isdigit(number_of_loader_processes[0]))
-    number_of_loader_processes_ = std::stoi(number_of_loader_processes);
-
-  _W("[ProcessPool] processes: %d, loader processes: %d",
-      number_of_processes_, number_of_loader_processes_);
-}
-
-const int Config::ProcessPool::GetNumberOfProcesses() const {
-  return number_of_processes_;
-}
-
-const int Config::ProcessPool::GetNumberOfLoaderProcesses() const {
-  return number_of_loader_processes_;
-}
-
 Config::LaunchMode::LaunchMode(const IniParser& parser) {
   auto mode = parser.Get(kTagLaunchMode, kKeyMode);
   if (!mode.empty()) {
-    mode = ToUpper(mode);
+    mode = Util::ToUpper(mode);
     if (mode == kValueModePreviousOperation)
       mode_ = LaunchMode::Mode::PreviousOperation;
     else if (mode == kValueModeDefaultOperation)
@@ -221,7 +193,6 @@ Config::Config()
       memory_monitor_(Config::MemoryMonitor(parser_)),
       cpu_checker_(Config::CPUChecker(parser_)),
       logger_(Config::Logger(parser_)),
-      process_pool_(Config::ProcessPool(parser_)),
       launch_mode_(Config::LaunchMode(parser_)) {
 }
 
@@ -241,10 +212,6 @@ const Config::Logger& Config::GetLogger() const {
   return logger_;
 }
 
-const Config::ProcessPool& Config::GetProcessPool() const {
-  return process_pool_;
-}
-
 const Config::LaunchMode& Config::GetLaunchMode() const {
   return launch_mode_;
 }
index 0daf5b224339cb046d0c32932e39fc223a70a5f9..1ab8b3915c5ec9f214c2c63767acbb5202a2ccb7 100644 (file)
@@ -79,18 +79,6 @@ class Config {
     bool enable_ = true;
   };
 
-  class ProcessPool {
-   public:
-    explicit ProcessPool(const IniParser& parser);
-
-    const int GetNumberOfProcesses() const;
-    const int GetNumberOfLoaderProcesses() const;
-
-   private:
-    int number_of_processes_ = 1;
-    int number_of_loader_processes_ = 1;
-  };
-
   class LaunchMode {
    public:
     enum class Mode : int {
@@ -120,7 +108,6 @@ class Config {
   const MemoryMonitor& GetMemoryMonitor() const;
   const CPUChecker& GetCPUChecker() const;
   const Logger& GetLogger() const;
-  const ProcessPool& GetProcessPool() const;
   const LaunchMode& GetLaunchMode() const;
 
  private:
@@ -133,7 +120,6 @@ class Config {
   MemoryMonitor memory_monitor_;
   CPUChecker cpu_checker_;
   Logger logger_;
-  ProcessPool process_pool_;
   LaunchMode launch_mode_;
 };
 
index d08a821fb6ef2beab8136e43dee07e355db4ceb7..fd25968881fa0c265a39af345fe8eb59fab79dec 100644 (file)
@@ -25,9 +25,9 @@
 #include <utility>
 
 #include <shared-queue.hpp>
+#include <rec_mutex.hh>
 
 #include "launchpad-process-pool/log_private.hh"
-#include "launchpad-process-pool/rec_mutex.hh"
 
 namespace launchpad {
 namespace {
diff --git a/src/launchpad-process-pool/debug.cc b/src/launchpad-process-pool/debug.cc
deleted file mode 100644 (file)
index 7785623..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright (c) 2023 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 "launchpad-process-pool/debug.hh"
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <fstream>
-#include <utility>
-
-#include <aul_keys.hh>
-#include <exception.hh>
-
-#include "launchpad-process-pool/log_private.hh"
-
-namespace fs = std::filesystem;
-
-namespace launchpad {
-namespace {
-
-constexpr const char kOptUsrShareAulDebugPath[] = "/opt/usr/share/aul/debug";
-constexpr const char kAsanAppList[] = ".asan_app_list";
-constexpr const char kAsanAppListPath[] =
-    "/opt/usr/share/aul/debug/.asan_app_list";
-constexpr const char kDebuggerInfoPath[] = "/usr/share/aul";
-
-std::vector<std::string> GetStringArray(const tizen_base::Bundle& b,
-    const std::string& key) {
-  std::vector<std::string> values;
-  if (b.GetType(key) & BUNDLE_TYPE_ARRAY) {
-    values = b.GetStringArray(key);
-  } else {
-    std::string value = b.GetString(key);
-    if (!value.empty())
-      values.push_back(std::move(value));
-  }
-
-  return values;
-}
-
-}  // namespace
-
-Debug& Debug::GetInst() {
-  static Debug inst;
-  inst.Init();
-  return inst;
-}
-
-void Debug::Dispose() {
-  if (disposed_)
-    return;
-
-  file_monitor_.reset();
-  disposed_ = true;
-}
-
-bool Debug::Load() {
-  if (!debugger_infos_.empty())
-    return false;
-
-  DebuggerInfoInflator inflator;
-  debugger_infos_ = inflator.Inflate(kDebuggerInfoPath);
-  return true;
-}
-
-void Debug::PrepareDebugger(const tizen_base::Bundle& b) {
-  auto debugger = b.GetString(kAulSdk);
-  if (debugger.empty())
-    return;
-
-  _D("[DEBUG] Debugger: %s", debugger.c_str());
-  auto found = debugger_infos_.find(debugger);
-  if (found == debugger_infos_.end()) {
-    _W("Failed to find debugger(%s)", debugger.c_str());
-    return;
-  }
-
-  debugger_info_ = found->second;
-  if (debugger == "ASAN")
-    setenv("TIZEN_ASAN_ACTIVATION", "1", 1);
-
-  ParseAndRedirectStandardFds(b);
-  RemoveFiles(debugger_info_->GetUnlinkList());
-
-  for (const auto& extra_env : debugger_info_->GetExtraEnvList())
-    ParseAndSetEnvironment(b, extra_env);
-
-  debug_argv_ = debugger_info_->GetDefaultOptList();
-  if (!debugger_info_->GetExe().empty())
-    debug_argv_.insert(debug_argv_.begin(), debugger_info_->GetExe());
-
-  for (const auto& extra_key : debugger_info_->GetExtraKeyList())
-    ParseAndAddArgv(b, extra_key);
-
-  for (const auto& last_extra_key : debugger_info_->GetLastExtraKeyList())
-    ParseAndAddExtraArgv(b, last_extra_key);
-}
-
-void Debug::ChangeMountNamespace() {
-  auto target_pid = std::getenv("TARGET_PID");
-  if (target_pid == nullptr)
-    return;
-
-  std::string mnt_path = "/proc/" + std::string(target_pid) + "/ns/mnt";
-  int fd = open(mnt_path.c_str(), O_RDONLY);
-  if (fd < 0) {
-    _E("open() is failed. path(%s), errno(%d)", mnt_path.c_str(), errno);
-    return;
-  }
-
-  int ret = ::setns(fd, CLONE_NEWNS);
-  close(fd);
-  if (ret != 0) {
-    _E("setns() is failed. errno(%d)", errno);
-    return;
-  }
-
-  _D("setns() is successful");
-}
-
-void Debug::CheckWebAppDebugging(const tizen_base::Bundle& b) {
-  if (b.GetType(kAulDebug) != BUNDLE_TYPE_NONE)
-    setenv("TIZEN_DEBUGGING_PORT", "1", 1);
-}
-
-bool Debug::CheckAsanApp(const std::string& appid) {
-  return asan_app_map_.find(appid) != asan_app_map_.end();
-}
-
-void Debug::CheckAndSetAsanActivation(const std::string& appid) {
-  if (CheckAsanApp(appid)) {
-    _W("Set TIZEN_ASAN_ACTIVATION. appid: %s", appid.c_str());
-    setenv("TIZEN_ASAN_ACTIVATION", "1", 1);
-  }
-}
-
-std::vector<std::string> Debug::GetExtraArgv() const {
-  return extra_argv_;
-}
-
-std::vector<std::string> Debug::GetArgv() const {
-  return debug_argv_;
-}
-
-bool Debug::ShouldAttach() const {
-  if (!debugger_info_)
-    return false;
-
-  return debugger_info_->GetAttachInfo() == "true";
-}
-
-Debug::~Debug() {
-  Dispose();
-}
-
-void Debug::Init() {
-  if (!disposed_)
-    return;
-
-  try {
-    file_monitor_ = std::make_unique<FileMonitor>(
-        kOptUsrShareAulDebugPath, this);
-  } catch (const Exception& e) {
-    _E("Exception occurs. error: %s", e.what());
-    return;
-  }
-
-  if (fs::exists(kAsanAppListPath))
-    LoadAsanAppList();
-
-  disposed_ = false;
-}
-
-void Debug::RemoveFiles(const std::vector<std::string>& files) {
-  for (const auto& file : files) {
-    if (fs::exists(file)) {
-      _D("[DEBUG] file: %s", file.c_str());
-      fs::remove(file);
-    }
-  }
-}
-
-void Debug::ParseAndSetEnvironment(const tizen_base::Bundle& b,
-    const std::string& key) {
-  _D("[DEBUG] key: %s", key.c_str());
-  std::vector<std::string> values = GetStringArray(b, key);
-  if (values.empty())
-    return;
-
-  std::string env;
-  for (const auto& value : values) {
-    if (!env.empty())
-      env += ",";
-
-    env += value;
-  }
-
-  const_cast<tizen_base::Bundle&>(b).Delete(key);
-  _D("[DEBUG] value: %s", env.c_str());
-  setenv(key.c_str(), env.c_str(), 1);
-}
-
-void Debug::ParseAndAddArgv(const tizen_base::Bundle& b,
-    const std::string& key) {
-  _D("[DEBUG] key: %s", key.c_str());
-  std::vector<std::string> values = GetStringArray(b, key);
-  if (values.empty())
-    return;
-
-  for (const auto& arg : values) {
-    debug_argv_.push_back(arg);
-    if (key == "__DLP_ATTACH_ARG__" && isdigit(arg[0])) {
-      _D("[DEBUG] TARGET_PID: %s", arg.c_str());
-      setenv("TARGET_PID", arg.c_str(), 1);
-    }
-  }
-
-  const_cast<tizen_base::Bundle&>(b).Delete(key);
-}
-
-void Debug::ParseAndAddExtraArgv(const tizen_base::Bundle& b,
-    const std::string& key) {
-  _D("[DEBUG] key: %s", key.c_str());
-  std::vector<std::string> values = GetStringArray(b, key);
-  if (values.empty()) return;
-
-  for (const auto& arg : values)
-    extra_argv_.push_back(arg);
-
-  const_cast<tizen_base::Bundle&>(b).Delete(key);
-}
-
-void Debug::ParseAndRedirectStandardFds(const tizen_base::Bundle& b) {
-  pid_t caller_pid = GetCallerPid(b);
-  if (caller_pid < 0)
-    return;
-
-  // stdin
-  std::string path = "/proc/" + std::to_string(caller_pid) + "/fd/";
-  int fd = open((path + std::to_string(STDIN_FILENO)).c_str(), O_RDONLY);
-  if (fd < 0) {
-    _E("Failed to open STDIN file descriptor. errno(%d)", errno);
-    return;
-  }
-
-  dup2(fd, STDIN_FILENO);
-  close(fd);
-
-  // stdout
-  fd = open((path + std::to_string(STDOUT_FILENO)).c_str(), O_WRONLY);
-  if (fd < 0) {
-    _E("Failed to open STDOUT file descriptor. errno(%d)", errno);
-    return;
-  }
-
-  dup2(fd, STDOUT_FILENO);
-  close(fd);
-
-  // stdout
-  fd = open((path + std::to_string(STDERR_FILENO)).c_str(), O_WRONLY);
-  if (fd < 0) {
-    _E("Failed to open STDERR file descriptor. errno(%d)", errno);
-    return;
-  }
-
-  dup2(fd, STDERR_FILENO);
-  close(fd);
-}
-
-pid_t Debug::GetCallerPid(const tizen_base::Bundle& b) {
-  auto pid_str = b.GetString(kAulOrgCallerPid);
-  if (pid_str.empty())
-    pid_str = b.GetString(kAulCallerPid);
-
-  if (pid_str.empty())
-    return -1;
-
-  return std::stoi(pid_str);
-}
-
-void Debug::LoadAsanAppList() {
-  asan_app_map_.clear();
-  std::ifstream if_stream;
-  if_stream.open(kAsanAppListPath);
-  if (!if_stream.is_open()) {
-    _E("Failed to open %s", kAsanAppListPath);
-    return;
-  }
-
-  std::string appid;
-  while (!if_stream.eof()) {
-    if_stream >> appid;
-    asan_app_map_.insert(std::move(appid));
-  }
-}
-
-void Debug::OnFileChanged(const std::string_view name,
-    FileMonitor::Event event) {
-  if (name != kAsanAppList)
-    return;
-
-  _W("%s was changed. event(%d)", kAsanAppList, static_cast<int>(event));
-  LoadAsanAppList();
-}
-
-}  // namespace launchpad
diff --git a/src/launchpad-process-pool/debug.hh b/src/launchpad-process-pool/debug.hh
deleted file mode 100644 (file)
index 28e21b7..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- */
-
-#ifndef LAUNCHPAD_PROCESS_POOL_DEBUG_HH_
-#define LAUNCHPAD_PROCESS_POOL_DEBUG_HH_
-
-#include <bundle_cpp.h>
-
-#include <list>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-#include "launchpad-process-pool/debugger_info.hh"
-#include "launchpad-process-pool/file_monitor.hh"
-
-namespace launchpad {
-
-class Debug : public FileMonitor::IEvent {
- public:
-  Debug(const Debug&) = delete;
-  Debug& operator = (const Debug&) = delete;
-  Debug(Debug&&) = delete;
-  Debug& operator = (Debug&&) = delete;
-
-  static Debug& GetInst();
-  void Init();
-  void Dispose();
-  bool Load();
-  void PrepareDebugger(const tizen_base::Bundle& b);
-  std::vector<std::string> GetExtraArgv() const;
-  std::vector<std::string> GetArgv() const;
-  bool ShouldAttach() const;
-  bool CheckAsanApp(const std::string& appid);
-  void CheckAndSetAsanActivation(const std::string& appid);
-
-  static void ChangeMountNamespace();
-  static void CheckWebAppDebugging(const tizen_base::Bundle& b);
-
- private:
-  Debug() = default;
-  ~Debug();
-
-  void RemoveFiles(const std::vector<std::string>& files);
-  void ParseAndSetEnvironment(
-      const tizen_base::Bundle& b, const std::string& key);
-  void ParseAndAddArgv(const tizen_base::Bundle& b, const std::string& key);
-  void ParseAndAddExtraArgv(const tizen_base::Bundle& b,
-      const std::string& key);
-  void ParseAndRedirectStandardFds(const tizen_base::Bundle& b);
-  pid_t GetCallerPid(const tizen_base::Bundle& b);
-
-  void LoadAsanAppList();
-  void OnFileChanged(const std::string_view name,
-      FileMonitor::Event event) override;
-
- private:
-  bool disposed_ = true;
-  DebuggerInfoPtr debugger_info_;
-  std::unordered_map<std::string, DebuggerInfoPtr> debugger_infos_;
-  std::vector<std::string> debug_argv_;
-  std::vector<std::string> extra_argv_;
-  std::unordered_set<std::string> asan_app_map_;
-  std::unique_ptr<launchpad::FileMonitor> file_monitor_;
-};
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_PROCESS_POOL_DEBUG_HH_
diff --git a/src/launchpad-process-pool/debugger_info.cc b/src/launchpad-process-pool/debugger_info.cc
deleted file mode 100644 (file)
index c611931..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright (c) 2023 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 "launchpad-process-pool/debugger_info.hh"
-
-#include <dirent.h>
-#include <limits.h>
-#include <malloc.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <fstream>
-#include <sstream>
-#include <utility>
-
-#include "launchpad-process-pool/log_private.hh"
-#include "launchpad-process-pool/util.hh"
-
-namespace launchpad {
-namespace {
-
-constexpr const char kTagDebugger[] = "[DEBUGGER]";
-constexpr const char kTagName[] = "NAME";
-constexpr const char kTagExe[] = "EXE";
-constexpr const char kTagAppType[] = "APP_TYPE";
-constexpr const char kTagExtraKey[] = "EXTRA_KEY";
-constexpr const char kTagExtraEnv[] = "EXTRA_ENV";
-constexpr const char kTagUnlink[] = "UNLINK";
-constexpr const char kTagAttach[] = "ATTACH";
-constexpr const char kTagLastExtraKey[] = "LAST_EXTRA_KEY";
-constexpr const char kTagDefaultOpt[] = "DEFAULT_OPT";
-
-}  // namespace
-
-namespace fs = std::filesystem;
-
-DebuggerInfo::Builder& DebuggerInfo::Builder::SetName(std::string name) {
-  name_ = std::move(name);
-  return *this;
-}
-
-DebuggerInfo::Builder& DebuggerInfo::Builder::SetExe(std::string exe) {
-  exe_ = std::move(exe);
-  return *this;
-}
-
-DebuggerInfo::Builder& DebuggerInfo::Builder::AddAppType(std::string app_type) {
-  app_types_.push_back(std::move(app_type));
-  return *this;
-}
-
-DebuggerInfo::Builder& DebuggerInfo::Builder::AddExtraKey(
-  std::string extra_key) {
-  extra_keys_.push_back(std::move(extra_key));
-  return *this;
-}
-DebuggerInfo::Builder& DebuggerInfo::Builder::AddExtraEnv(
-    std::string extra_env) {
-  extra_envs_.push_back(std::move(extra_env));
-  return *this;
-}
-
-DebuggerInfo::Builder& DebuggerInfo::Builder::AddFileToDelete(
-  std::string file) {
-  delete_files_.push_back(std::move(file));
-  return *this;
-}
-
-DebuggerInfo::Builder& DebuggerInfo::Builder::SetAttach(std::string attach) {
-  attach_ = std::move(attach);
-  return *this;
-}
-
-DebuggerInfo::Builder& DebuggerInfo::Builder::AddLastExtraKey(
-    std::string last_extra_key) {
-  last_extra_keys_.push_back(std::move(last_extra_key));
-  return *this;
-}
-
-DebuggerInfo::Builder& DebuggerInfo::Builder::AddDefaultOpt(
-    std::string default_opt) {
-  default_opts_.push_back(std::move(default_opt));
-  return *this;
-}
-
-DebuggerInfo::Builder& DebuggerInfo::Builder::Reset() {
-  name_.clear();
-  exe_.clear();
-  app_types_.clear();
-  extra_keys_.clear();
-  extra_envs_.clear();
-  delete_files_.clear();
-  attach_.clear();
-  last_extra_keys_.clear();
-  default_opts_.clear();
-  return *this;
-}
-
-DebuggerInfo* DebuggerInfo::Builder::Build() {
-  return new DebuggerInfo(std::move(name_), std::move(exe_),
-      std::move(app_types_), std::move(extra_keys_), std::move(extra_envs_),
-      std::move(delete_files_), std::move(attach_),
-      std::move(last_extra_keys_), std::move(default_opts_));
-}
-
-DebuggerInfo::DebuggerInfo(std::string name, std::string exe,
-    std::vector<std::string> app_types,
-    std::vector<std::string> extra_keys,
-    std::vector<std::string> extra_envs,
-    std::vector<std::string> delete_files,
-    std::string attach,
-    std::vector<std::string> last_extra_keys,
-    std::vector<std::string> default_opts)
-    : name_(std::move(name)),
-      exe_(std::move(exe)),
-      app_types_(std::move(app_types)),
-      extra_keys_(std::move(extra_keys)),
-      extra_envs_(std::move(extra_envs)),
-      delete_files_(std::move(delete_files)),
-      attach_(std::move(attach)),
-      last_extra_keys_(std::move(last_extra_keys)),
-      default_opts_(std::move(default_opts)) {}
-
-const std::string& DebuggerInfo::GetName() const {
-  return name_;
-}
-
-const std::string& DebuggerInfo::GetExe() const {
-  return exe_;
-}
-
-const std::vector<std::string>& DebuggerInfo::GetAppTypes() const {
-  return app_types_;
-}
-
-const std::vector<std::string>& DebuggerInfo::GetExtraKeyList() const {
-  return extra_keys_;
-}
-
-const std::vector<std::string>& DebuggerInfo::GetExtraEnvList() const {
-  return extra_envs_;
-}
-
-const std::vector<std::string>& DebuggerInfo::GetUnlinkList() const {
-  return delete_files_;
-}
-
-const std::string& DebuggerInfo::GetAttachInfo() const {
-  return attach_;
-}
-
-const std::vector<std::string>& DebuggerInfo::GetLastExtraKeyList() const {
-  return last_extra_keys_;
-}
-
-const std::vector<std::string>& DebuggerInfo::GetDefaultOptList() const {
-  return default_opts_;
-}
-
-DebuggerInfoInflator::DebuggerInfoInflator() {
-  parsers_ = {
-    { kTagName,
-      std::bind(&DebuggerInfoInflator::ParseName,
-          this, std::placeholders::_1) },
-    { kTagExe,
-      std::bind(&DebuggerInfoInflator::ParseExe,
-          this, std::placeholders::_1) },
-    { kTagAppType,
-      std::bind(&DebuggerInfoInflator::ParseAppType,
-          this, std::placeholders::_1) },
-    { kTagExtraKey,
-      std::bind(&DebuggerInfoInflator::ParseExtraKey,
-          this, std::placeholders::_1) },
-    { kTagExtraEnv,
-      std::bind(&DebuggerInfoInflator::ParseExtraEnv,
-          this, std::placeholders::_1) },
-    { kTagUnlink,
-      std::bind(&DebuggerInfoInflator::ParseUnlink,
-          this, std::placeholders::_1) },
-    { kTagAttach,
-      std::bind(&DebuggerInfoInflator::ParseAttach,
-          this, std::placeholders::_1) },
-    { kTagLastExtraKey,
-      std::bind(&DebuggerInfoInflator::ParseLastExtraKey,
-          this, std::placeholders::_1) },
-    { kTagDefaultOpt,
-      std::bind(&DebuggerInfoInflator::ParseDefaultOpt,
-          this, std::placeholders::_1) },
-  };
-}
-
-std::unordered_map<std::string, DebuggerInfoPtr>
-DebuggerInfoInflator::Inflate(const std::string_view path) {
-  fs::path input_path(path);
-  if (fs::is_directory(input_path) == false)
-    return debugger_infos_;
-
-  try {
-    for (auto& entry : fs::directory_iterator(input_path)) {
-      fs::path file(entry.path());
-      if (file.extension() == ".debugger")
-        Parse(file);
-    }
-  } catch (const fs::filesystem_error& e) {
-    _E("Exception occurs. error(%s:%d)", e.what(), e.code().value());
-  }
-
-  return debugger_infos_;
-}
-
-void DebuggerInfoInflator::ParseName(std::string token) {
-  builder_.SetName(std::move(token));
-}
-
-void DebuggerInfoInflator::ParseExe(std::string token) {
-  builder_.SetExe(std::move(token));
-}
-
-void DebuggerInfoInflator::ParseAppType(std::string token) {
-  std::string line = std::move(token);
-  do {
-    auto tokens = Split(line, " |\t\r\n");
-    for (auto& app_type : tokens) {
-      _D("app-type: %s", app_type.c_str());
-      builder_.AddAppType(app_type);
-    }
-  } while (std::getline(string_stream_, line));
-}
-
-void DebuggerInfoInflator::ParseExtraKey(std::string token) {
-  builder_.AddExtraKey(std::move(token));
-}
-
-void DebuggerInfoInflator::ParseExtraEnv(std::string token) {
-  builder_.AddExtraEnv(std::move(token));
-}
-
-void DebuggerInfoInflator::ParseUnlink(std::string token) {
-  builder_.AddFileToDelete(std::move(token));
-}
-
-void DebuggerInfoInflator::ParseAttach(std::string token) {
-  builder_.SetAttach(std::move(token));
-}
-
-void DebuggerInfoInflator::ParseLastExtraKey(std::string token) {
-  builder_.AddLastExtraKey(std::move(token));
-}
-
-void DebuggerInfoInflator::ParseDefaultOpt(std::string token) {
-  builder_.AddDefaultOpt(std::move(token));
-}
-
-void DebuggerInfoInflator::Parse(const fs::path& path) {
-  std::ifstream input_file(path);
-  if (!input_file.is_open())
-    return;
-
-  bool parsing = false;
-  std::string input;
-  while (std::getline(input_file, input)) {
-    string_stream_ = std::istringstream(input);
-    std::string token1;
-    if (!(string_stream_ >> token1))
-      continue;
-
-    std::string key = ToUpper(std::move(token1));
-    if (key == kTagDebugger) {
-      if (parsing)
-        InsertDebuggerInfo(std::shared_ptr<DebuggerInfo>(builder_.Build()));
-
-      builder_.Reset();
-      parsing = true;
-      continue;
-    }
-
-    if (parsing == false)
-      continue;
-
-    std::string token2;
-    if (!(string_stream_ >> token2))
-      continue;
-
-    auto found = parsers_.find(key);
-    if (found == parsers_.end())
-      continue;
-
-    auto& parser = found->second;
-    parser(std::move(token2));
-  }
-
-  if (parsing)
-    InsertDebuggerInfo(std::shared_ptr<DebuggerInfo>(builder_.Build()));
-
-  input_file.close();
-}
-
-void DebuggerInfoInflator::InsertDebuggerInfo(DebuggerInfoPtr info) {
-  if (debugger_infos_.find(info->name_) != debugger_infos_.end())
-    return;
-
-  _D("name: %s, exe: %s", info->name_.c_str(), info->exe_.c_str());
-  std::string name = info->name_;
-  debugger_infos_[std::move(name)] = std::move(info);
-}
-
-}  // namespace launchpad
diff --git a/src/launchpad-process-pool/debugger_info.hh b/src/launchpad-process-pool/debugger_info.hh
deleted file mode 100644 (file)
index c08fce5..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- */
-
-#ifndef LAUNCHPAD_PROCESS_POOL_DEBUGGER_INFO_HH_
-#define LAUNCHPAD_PROCESS_POOL_DEBUGGER_INFO_HH_
-
-#include <filesystem>
-#include <functional>
-#include <memory>
-#include <string>
-#include <string_view>
-#include <unordered_map>
-#include <vector>
-
-namespace launchpad {
-
-class DebuggerInfo {
- public:
-  class Builder {
-   public:
-    Builder& SetName(std::string name);
-    Builder& SetExe(std::string exe);
-    Builder& AddAppType(std::string app_type);
-    Builder& AddExtraKey(std::string extra_key);
-    Builder& AddExtraEnv(std::string extra_env);
-    Builder& AddFileToDelete(std::string file);
-    Builder& SetAttach(std::string attach);
-    Builder& AddLastExtraKey(std::string last_extra_key);
-    Builder& AddDefaultOpt(std::string default_opt);
-    Builder& Reset();
-
-    DebuggerInfo* Build();
-
-   private:
-    std::string name_;
-    std::string exe_;
-    std::vector<std::string> app_types_;
-    std::vector<std::string> extra_keys_;
-    std::vector<std::string> extra_envs_;
-    std::vector<std::string> delete_files_;
-    std::string attach_;
-    std::vector<std::string> last_extra_keys_;
-    std::vector<std::string> default_opts_;
-  };
-
-  DebuggerInfo(std::string name, std::string exe,
-      std::vector<std::string> app_types,
-      std::vector<std::string> extra_keys,
-      std::vector<std::string> extra_envs,
-      std::vector<std::string> delete_files,
-      std::string attach,
-      std::vector<std::string> last_extra_keys,
-      std::vector<std::string> default_opts);
-
-  const std::string& GetName() const;
-  const std::string& GetExe() const;
-  const std::vector<std::string>& GetAppTypes() const;
-  const std::vector<std::string>& GetExtraKeyList() const;
-  const std::vector<std::string>& GetExtraEnvList() const;
-  const std::vector<std::string>& GetUnlinkList() const;
-  const std::string& GetAttachInfo() const;
-  const std::vector<std::string>& GetLastExtraKeyList() const;
-  const std::vector<std::string>& GetDefaultOptList() const;
-
- private:
-  std::string name_;
-  std::string exe_;
-  std::vector<std::string> app_types_;
-  std::vector<std::string> extra_keys_;
-  std::vector<std::string> extra_envs_;
-  std::vector<std::string> delete_files_;
-  std::string attach_;
-  std::vector<std::string> last_extra_keys_;
-  std::vector<std::string> default_opts_;
-
-  friend class DebuggerInfoInflator;
-};
-
-using DebuggerInfoPtr = std::shared_ptr<DebuggerInfo>;
-
-class DebuggerInfoInflator {
- public:
-  DebuggerInfoInflator();
-
-  std::unordered_map<std::string, DebuggerInfoPtr> Inflate(
-      const std::string_view path);
-
- private:
-  void ParseName(std::string token);
-  void ParseExe(std::string token);
-  void ParseAppType(std::string token);
-  void ParseExtraKey(std::string token);
-  void ParseExtraEnv(std::string token);
-  void ParseUnlink(std::string token);
-  void ParseAttach(std::string token);
-  void ParseLastExtraKey(std::string token);
-  void ParseDefaultOpt(std::string token);
-  void Parse(const std::filesystem::path& path);
-
-  void InsertDebuggerInfo(DebuggerInfoPtr info);
-
- private:
-  std::unordered_map<std::string, std::function<void(std::string)>> parsers_;
-  std::unordered_map<std::string, DebuggerInfoPtr> debugger_infos_;
-  std::istringstream string_stream_;
-  DebuggerInfo::Builder builder_;
-};
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_PROCESS_POOL_DEBUGGER_INFO_HH_
diff --git a/src/launchpad-process-pool/executor.cc b/src/launchpad-process-pool/executor.cc
deleted file mode 100644 (file)
index 31496f7..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2023 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 "launchpad-process-pool/executor.hh"
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <sched_priority.hh>
-
-#include "launchpad-process-pool/log_private.hh"
-#include "launchpad-process-pool/rec_mutex.hh"
-
-namespace launchpad {
-
-Executor::Executor(Executor::Delegator* delegator) : delegator_(delegator) {}
-
-pid_t Executor::Execute(int priority) {
-  std::lock_guard<std::recursive_mutex> lock(RecMutex::GetInst().GetMutex());
-  pid_t pid = fork();
-  if (pid == -1) {
-    _E("Failed to create child process. errno(%d)", errno);
-    return -1;
-  }
-
-  if (pid == 0) {
-    setsid();
-    if (priority != 0)
-      SchedPriority::Set(priority);
-
-    _W("security_manager_prepare_app_candidate ++");
-    int ret = security_manager_prepare_app_candidate();
-    _W("security_manager_prepare_app_candidate --");
-    if (ret != SECURITY_MANAGER_SUCCESS) {
-      _E("Failed to prepare app candidate process. error(%d)", ret);
-      exit(1);
-    }
-
-    delegator_->OnExecution();
-  }
-
-  return pid;
-}
-
-}  // namespace launchpad
diff --git a/src/launchpad-process-pool/executor.hh b/src/launchpad-process-pool/executor.hh
deleted file mode 100644 (file)
index 29078ff..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- */
-
-#ifndef LAUNCHPAD_PROCESS_POOL_EXECUTOR_HH_
-#define LAUNCHPAD_PROCESS_POOL_EXECUTOR_HH_
-
-#include <security-manager.h>
-#include <sys/types.h>
-
-namespace launchpad {
-
-class Executor {
- public:
-  class Delegator {
-   public:
-    virtual ~Delegator() = default;
-    virtual void OnExecution() = 0;
-  };
-
-  explicit Executor(Delegator* delegator);
-  virtual ~Executor() = default;
-
-  pid_t Execute(int priority = 0);
-
- private:
-  Delegator* delegator_;
-};
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_PROCESS_POOL_EXECUTOR_HH_
diff --git a/src/launchpad-process-pool/file_monitor.cc b/src/launchpad-process-pool/file_monitor.cc
deleted file mode 100644 (file)
index ee2d167..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2023 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 "launchpad-process-pool/file_monitor.hh"
-
-#include <errno.h>
-
-#include <exception.hh>
-
-#include "launchpad-process-pool/log_private.hh"
-
-namespace launchpad {
-
-namespace fs = std::filesystem;
-
-void FileMonitor::OnIOEventReceived(int fd, int condition) {
-  alignas(struct inotify_event) char buf[4096];
-  const struct inotify_event* event;
-  ssize_t len;
-  while ((len = read(fd, buf, sizeof(buf))) > 0) {
-    for (const char* ptr = buf; ptr < buf + len;
-         ptr += sizeof(struct inotify_event) + event->len) {
-      event = reinterpret_cast<const struct inotify_event*>(ptr);
-      const char* nptr = ptr + sizeof(struct inotify_event) + event->len;
-      if (nptr > buf + len)
-        break;
-
-      if (event->len) {
-        if (listener_) {
-          if (event->mask & IN_CREATE)
-            listener_->OnFileChanged(event->name, Event::Created);
-          else if (event->mask & IN_MODIFY)
-            listener_->OnFileChanged(event->name, Event::Modified);
-          else if (event->mask & IN_DELETE)
-            listener_->OnFileChanged(event->name, Event::Deleted);
-        }
-      }
-    }
-  }
-}
-
-FileMonitor::FileMonitor(const std::string_view path,
-    FileMonitor::IEvent* listener)
-    : path_(path), listener_(listener) {
-  if (!fs::exists(path_)) {
-    try {
-      if (!fs::create_directories(path_)) {
-        _E("Failed to create directory. %s", path_.c_str());
-        THROW(-EIO);
-      }
-    } catch (const std::exception& e) {
-      _E("Exception has been occurred: %s", e.what());
-      THROW(-EIO);
-    }
-  }
-
-  int fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
-  if (fd < 0) {
-    int error_code = -errno;
-    _E("inotify_init1() is failed. errno: %d", errno);
-    THROW(error_code);
-  }
-
-  int wd = inotify_add_watch(fd, path_.c_str(),
-      IN_CREATE | IN_MODIFY | IN_DELETE);
-  if (wd < 0) {
-    int error_code = -errno;
-    _E("inotify_add_watch() is failed. errno: %d", errno);
-    close(fd);
-    THROW(error_code);
-  }
-
-  channel_ = std::make_unique<IOChannel>(fd, G_IO_IN, this);
-  wd_ = wd;
-  fd_ = fd;
-}
-
-FileMonitor::~FileMonitor() {
-  channel_.reset();
-
-  if (wd_ > 0)
-    inotify_rm_watch(fd_, wd_);
-
-  if (fd_ > 0)
-    close(fd_);
-}
-
-}  // namespace launchpad
diff --git a/src/launchpad-process-pool/file_monitor.hh b/src/launchpad-process-pool/file_monitor.hh
deleted file mode 100644 (file)
index 02a112c..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- */
-
-#ifndef LAUNCHPAD_PROCESS_POOL_FILE_MONITOR_HH_
-#define LAUNCHPAD_PROCESS_POOL_FILE_MONITOR_HH_
-
-#include <sys/inotify.h>
-
-#include <filesystem>
-#include <memory>
-#include <string_view>
-
-#include <io_channel.hh>
-
-namespace launchpad {
-
-class FileMonitor : public IOChannel::IEvent {
- public:
-  enum class Event : int {
-    Created = IN_CREATE,
-    Modified = IN_MODIFY,
-    Deleted = IN_DELETE,
-  };
-
-  class IEvent {
-   public:
-    virtual ~IEvent() = default;
-    virtual void OnFileChanged(const std::string_view name, Event event) = 0;
-  };
-
-  FileMonitor(const std::string_view path, IEvent *listener);
-  virtual ~FileMonitor();
-
-  FileMonitor(const FileMonitor &) = delete;
-  FileMonitor &operator=(const FileMonitor &) = delete;
-
- private:
-  void OnIOEventReceived(int fd, int condition) override;
-
- private:
-  std::filesystem::path path_;
-  IEvent *listener_;
-  int fd_ = 0;
-  int wd_ = 0;
-  std::unique_ptr<IOChannel> channel_;
-};
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_PROCESS_POOL_FILE_MONITOR_HH_
diff --git a/src/launchpad-process-pool/launcher_info.cc b/src/launchpad-process-pool/launcher_info.cc
deleted file mode 100644 (file)
index a94d382..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2023 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 "launchpad-process-pool/launcher_info.hh"
-
-#include <algorithm>
-#include <fstream>
-#include <sstream>
-#include <utility>
-
-#include <util.hh>
-
-#include "launchpad-process-pool/log_private.hh"
-#include "launchpad-process-pool/util.hh"
-
-namespace launchpad {
-namespace {
-
-constexpr const char kTagLauncher[] = "[LAUNCHER]";
-constexpr const char kTagName[] = "NAME";
-constexpr const char kTagExe[] = "EXE";
-constexpr const char kTagAppType[] = "APP_TYPE";
-constexpr const char kTagExtraArg[] = "EXTRA_ARG";
-
-}  // namespace
-
-namespace fs = std::filesystem;
-
-LauncherInfo::Builder& LauncherInfo::Builder::SetName(std::string name) {
-  name_ = std::move(name);
-  return *this;
-}
-
-LauncherInfo::Builder& LauncherInfo::Builder::SetExe(std::string exe) {
-  exe_ = std::move(exe);
-  return *this;
-}
-
-LauncherInfo::Builder& LauncherInfo::Builder::AddAppType(std::string app_type) {
-  app_types_.push_back(std::move(app_type));
-  return *this;
-}
-
-LauncherInfo::Builder& LauncherInfo::Builder::AddExtraArg(
-  std::string extra_arg) {
-  extra_args_.push_back(std::move(extra_arg));
-  return *this;
-}
-
-LauncherInfo::Builder& LauncherInfo::Builder::Reset() {
-  name_.clear();
-  exe_.clear();
-  app_types_.clear();
-  extra_args_.clear();
-  return *this;
-}
-
-LauncherInfo* LauncherInfo::Builder::Build() {
-  return new LauncherInfo(std::move(name_), std::move(exe_),
-      std::move(app_types_), std::move(extra_args_));
-}
-
-LauncherInfo::LauncherInfo(std::string name, std::string exe,
-    std::vector<std::string> app_types, std::vector<std::string> extra_args)
-    : name_(std::move(name)),
-      exe_(std::move(exe)),
-      app_types_(std::move(app_types)),
-      extra_args_(std::move(extra_args)) {
-}
-
-const std::string& LauncherInfo::GetName() const {
-  return name_;
-}
-
-const std::string& LauncherInfo::GetExe() const {
-  return exe_;
-}
-
-const std::vector<std::string>& LauncherInfo::GetAppTypes() const {
-  return app_types_;
-}
-
-const std::vector<std::string>& LauncherInfo::GetExtraArgs() const {
-  return extra_args_;
-}
-
-LauncherInfoInflator::LauncherInfoInflator() {
-  parsers_ = {
-    { kTagName,
-      std::bind(&LauncherInfoInflator::ParseName,
-          this, std::placeholders::_1) },
-    { kTagExe,
-      std::bind(&LauncherInfoInflator::ParseExe,
-          this, std::placeholders::_1) },
-    { kTagAppType,
-      std::bind(&LauncherInfoInflator::ParseAppType,
-          this, std::placeholders::_1) },
-    { kTagExtraArg,
-      std::bind(&LauncherInfoInflator::ParseExtraArg,
-          this, std::placeholders::_1) },
-  };
-}
-
-void LauncherInfoInflator::ParseName(std::string token) {
-  builder_.SetName(std::move(token));
-}
-
-void LauncherInfoInflator::ParseExe(std::string token) {
-  builder_.SetExe(std::move(token));
-}
-
-void LauncherInfoInflator::ParseAppType(std::string token) {
-  std::string line = std::move(token);
-  do {
-    auto tokens = Split(line, " |\t\r\n");
-    for (auto& app_type : tokens)
-      builder_.AddAppType(app_type);
-  } while (std::getline(string_stream_, line));
-}
-
-void LauncherInfoInflator::ParseExtraArg(std::string token) {
-  builder_.AddExtraArg(std::move(token));
-}
-
-void LauncherInfoInflator::Parse(const fs::path& path) {
-  std::ifstream launcher_file;
-  launcher_file.open(path);
-  if (launcher_file.fail())
-    return;
-
-  bool parsing = false;
-  std::string line;
-  while (std::getline(launcher_file, line)) {
-    string_stream_ = std::istringstream(line);
-    std::string token1;
-    if (!(string_stream_ >> token1))
-      continue;
-
-    std::string key = ToUpper(std::move(token1));
-    if (key == kTagLauncher) {
-      if (parsing)
-        Insert();
-
-      builder_.Reset();
-      parsing = true;
-      continue;
-    }
-
-    if (parsing == false)
-      continue;
-
-    std::string token2;
-    if (!(string_stream_ >> token2))
-      continue;
-
-    auto found = parsers_.find(key);
-    if (found == parsers_.end())
-      continue;
-
-    auto& parser = found->second;
-    parser(std::move(token2));
-  }
-
-  if (parsing)
-    Insert();
-
-  launcher_file.close();
-}
-
-void LauncherInfoInflator::Insert() {
-  launcher_infos_.emplace_back(builder_.Build());
-}
-
-std::vector<LauncherInfoPtr> LauncherInfoInflator::Inflate(
-    const std::string_view path) {
-  fs::path dir_path(path);
-  if (fs::is_directory(dir_path) == false)
-    return {};
-
-  try {
-    for (auto& entry : fs::directory_iterator(dir_path)) {
-      fs::path file(entry.path());
-      if (file.extension() == ".launcher") {
-        Parse(file);
-      }
-    }
-  } catch (const fs::filesystem_error& e) {
-    _E("Exception occurs. error(%s:%d)", e.what(), e.code().value());
-  }
-
-  return launcher_infos_;
-}
-
-}  // namespace launchpad
diff --git a/src/launchpad-process-pool/launcher_info.hh b/src/launchpad-process-pool/launcher_info.hh
deleted file mode 100644 (file)
index 975991c..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- */
-
-#ifndef LAUNCHPAD_PROCESS_POOL_LAUNCHER_INFO_HH_
-#define LAUNCHPAD_PROCESS_POOL_LAUNCHER_INFO_HH_
-
-#include <filesystem>
-#include <functional>
-#include <memory>
-#include <string>
-#include <string_view>
-#include <unordered_map>
-#include <vector>
-
-namespace launchpad {
-
-class LauncherInfo {
- public:
-  class Builder {
-   public:
-    Builder& SetName(std::string name);
-    Builder& SetExe(std::string exe);
-    Builder& AddAppType(std::string app_type);
-    Builder& AddExtraArg(std::string extra_arg);
-    Builder& Reset();
-
-    LauncherInfo* Build();
-
-   private:
-    std::string name_;
-    std::string exe_;
-    std::vector<std::string> app_types_;
-    std::vector<std::string> extra_args_;
-  };
-
-  LauncherInfo(std::string name, std::string exe,
-      std::vector<std::string> app_types, std::vector<std::string> extra_args);
-
-  const std::string& GetName() const;
-  const std::string& GetExe() const;
-  const std::vector<std::string>& GetAppTypes() const;
-  const std::vector<std::string>& GetExtraArgs() const;
-
- private:
-  friend class LauncherInfoInflator;
-
-  std::string name_;
-  std::string exe_;
-  std::vector<std::string> app_types_;
-  std::vector<std::string> extra_args_;
-};
-
-using LauncherInfoPtr = std::shared_ptr<LauncherInfo>;
-
-class LauncherInfoInflator {
- public:
-  LauncherInfoInflator();
-
-  std::vector<LauncherInfoPtr> Inflate(const std::string_view path);
-
- private:
-  void Parse(const std::filesystem::path& path);
-
-  void ParseName(std::string token);
-  void ParseExe(std::string token);
-  void ParseAppType(std::string token);
-  void ParseExtraArg(std::string token);
-  void Insert();
-
- private:
-  std::unordered_map<std::string, std::function<void(std::string)>> parsers_;
-  std::istringstream string_stream_;
-  LauncherInfo::Builder builder_;
-  std::vector<std::shared_ptr<LauncherInfo>> launcher_infos_;
-};
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_PROCESS_POOL_LAUNCHER_INFO_HH_
index c2b6f84510b6f5e5407230e2b76177eecc43d684..355f0e30ea8de66fe340ea6aec2f076f13d10832 100644 (file)
 #include <app_info.hh>
 #include <aul_keys.hh>
 #include <cpu_boost_controller.hh>
+#include <debug.hh>
 #include <exception.hh>
 #include <executor.hh>
+#include <launchpad_args.hh>
+#include <loader_executor.hh>
 #include <procfs.hh>
 #include <sched_priority.hh>
 #include <types.hh>
 
 #include "launchpad-process-pool/config.hh"
 #include "launchpad-process-pool/dbus.hh"
-#include "launchpad-process-pool/debug.hh"
-#include "launchpad-process-pool/launcher_info.hh"
-#include "launchpad-process-pool/launchpad_args.hh"
 #include "launchpad-process-pool/loader_manager.hh"
-#include "launchpad-process-pool/loader_executor.hh"
 #include "launchpad-process-pool/log.hh"
 #include "launchpad-process-pool/log_private.hh"
 #include "launchpad-process-pool/memory_monitor.hh"
 #include "launchpad-process-pool/signal_manager.hh"
 #include "launchpad-process-pool/tracer.hh"
-#include "launchpad-process-pool/util.hh"
 #include "launchpad-process-pool/worker.hh"
 
 namespace launchpad {
index 40d20aec2deaffd9fb10c897b37b66a98a6b71e8..0ca5064ffb9fb247636f467178caae2a51b3dcb6 100644 (file)
 #include <unordered_map>
 #include <vector>
 
+#include <app_executor.hh>
 #include <language_config.hh>
 #include <io_channel.hh>
 #include <region_format_config.hh>
 #include <server_socket.hh>
 
-#include "launchpad-process-pool/app_executor.hh"
 #include "launchpad-process-pool/config.hh"
 #include "launchpad-process-pool/loader_manager.hh"
 #include "launchpad-process-pool/request.hh"
diff --git a/src/launchpad-process-pool/launchpad_args.cc b/src/launchpad-process-pool/launchpad_args.cc
deleted file mode 100644 (file)
index bda43bb..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2023 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 "launchpad-process-pool/launchpad_args.hh"
-
-namespace launchpad {
-
-LaunchpadArgs& LaunchpadArgs::GetInst() {
-  static LaunchpadArgs inst;
-  return inst;
-}
-
-void LaunchpadArgs::Set(int argc, char** args) {
-  argc_ = argc;
-  args_ = args;
-}
-
-int LaunchpadArgs::GetArgc() const {
-  return argc_;
-}
-
-char** LaunchpadArgs::GetArgs() const {
-  return args_;
-}
-
-}  // namespace launchpad
diff --git a/src/launchpad-process-pool/launchpad_args.hh b/src/launchpad-process-pool/launchpad_args.hh
deleted file mode 100644 (file)
index 741e949..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- */
-
-#ifndef LAUNCHPAD_PROCESS_POOL_LAUNCHPAD_ARGS_HH_
-#define LAUNCHPAD_PROCESS_POOL_LAUNCHPAD_ARGS_HH_
-
-namespace launchpad {
-
-class LaunchpadArgs {
- public:
-  LaunchpadArgs(const LaunchpadArgs&) = delete;
-  LaunchpadArgs& operator=(const LaunchpadArgs&) = delete;
-
-  static LaunchpadArgs& GetInst();
-
-  void Set(int argc, char** args);
-
-  int GetArgc() const;
-  char** GetArgs() const;
-
- private:
-  LaunchpadArgs() = default;
-  ~LaunchpadArgs() = default;
-
- private:
-  int argc_ = 0;
-  char** args_ = nullptr;
-};
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_PROCESS_POOL_LAUNCHPAD_ARGS_HH_
index 9187988560d0d6ec628bbc93a5701f251f75c0e5..ecbf5bb1045520a3b4cb25cdd22486c27ee1b4ee 100644 (file)
 #include <utility>
 
 #include <exception.hh>
+#include <loader_executor.hh>
 #include <peer_credentials.hh>
 #include <procfs.hh>
+#include <types.hh>
 #include <user_tracer.hh>
 #include <util.hh>
-#include <types.hh>
 
 #include "launchpad-process-pool/app_labels_monitor.hh"
 #include "launchpad-process-pool/config.hh"
-#include "launchpad-process-pool/loader_executor.hh"
 #include "launchpad-process-pool/log.hh"
 #include "launchpad-process-pool/log_private.hh"
 #include "launchpad-process-pool/memory_monitor.hh"
-#include "launchpad-process-pool/util.hh"
 
 namespace fs = std::filesystem;
 
@@ -158,8 +157,6 @@ LoaderContext::LoaderContext(std::shared_ptr<LoaderInfo> loader_info,
     VerifyLoaderCaps(executable_file);
   }
 
-  loader_extra_ = reinterpret_cast<const char*>(
-      loader_info_->GetExtra().ToRaw().first.get());
   Listen();
   condition_path_exists_ = loader_info_->GetConditionPathExists();
 }
@@ -223,7 +220,8 @@ void LoaderContext::Dispose() {
 pid_t LoaderContext::Prepare() {
   bool set_priority = (Config::GetInst().GetLaunchMode().GetMode() !=
       Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority);
-  pid_ = LoaderExecutor::GetInst().Execute(this,
+  pid_ = LoaderExecutor::GetInst().Execute(
+      loader_info_.get(), loader_id_,
       set_priority ? loader_info_->GetSchedPriority() : 0);
   _W("Prepare. type(%d), name(%s), pid(%d)",
       GetType(), GetLoaderName().c_str(), pid_);
@@ -285,10 +283,6 @@ const std::string& LoaderContext::GetLoaderPath() const {
   return loader_info_->GetExe();
 }
 
-const std::string& LoaderContext::GetLoaderExtra() const {
-  return loader_extra_;
-}
-
 int LoaderContext::GetType() const {
   return static_cast<int>(loader_info_->GetType());
 }
index 814ff4b212959abf78227a62c17676b6fad8c484..3f7eea8bc651b92ede4c7836b98ce23a637d20d9 100644 (file)
 #include <app_info.hh>
 #include <client_socket.hh>
 #include <io_channel.hh>
+#include <loader_info.hh>
 #include <server_socket.hh>
 
 #include "launchpad-process-pool/cpu_checker.hh"
-#include "launchpad-process-pool/loader_info.hh"
-#include "launchpad-process-pool/launcher_info.hh"
 #include "launchpad-process-pool/loader_mount.hh"
 
 namespace launchpad {
@@ -79,7 +78,6 @@ class LoaderContext : public std::enable_shared_from_this<LoaderContext>,
 
   const std::string& GetLoaderName() const;
   const std::string& GetLoaderPath() const;
-  const std::string& GetLoaderExtra() const;
   int GetType() const;
   bool IsPrepared() const;
   pid_t GetPid() const;
@@ -143,7 +141,6 @@ class LoaderContext : public std::enable_shared_from_this<LoaderContext>,
   std::shared_ptr<LoaderMount> loader_mount_;
   std::unique_ptr<CPUChecker> cpu_checker_;
   unsigned int score_;
-  std::string loader_extra_;
   std::unique_ptr<ServerSocket> server_socket_;
   std::unique_ptr<IOChannel> server_channel_;
   std::unique_ptr<ClientSocket> client_socket_;
diff --git a/src/launchpad-process-pool/loader_executor.cc b/src/launchpad-process-pool/loader_executor.cc
deleted file mode 100644 (file)
index 37b8198..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2023 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 "launchpad-process-pool/loader_executor.hh"
-
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <utility>
-
-#include <parcel.hh>
-#include <sched_priority.hh>
-#include <stdio.hh>
-#include <types.hh>
-#include <util.hh>
-
-#include "launchpad-process-pool/config.hh"
-#include "launchpad-process-pool/log_private.hh"
-#include "launchpad-process-pool/signal_manager.hh"
-
-namespace launchpad {
-namespace {
-
-tizen_base::Parcel CreateParcelFromBundle(tizen_base::Bundle* b) {
-  auto b_raw = b->ToRaw();
-  std::string raw(reinterpret_cast<const char*>(b_raw.first.get()));
-  tizen_base::Parcel parcel;
-  parcel.WriteString(raw);
-  return parcel;
-}
-
-tizen_base::Bundle CreateBundleFromParcel(tizen_base::Parcel* parcel) {
-  std::string raw = parcel->ReadString();
-  return tizen_base::Bundle(raw);
-}
-
-}  // namespace
-
-LoaderExecutor::LoaderExecutor() : Executor(this) {
-  auto& process_pool_config = Config::GetInst().GetProcessPool();
-  process_pool_ = std::unique_ptr<ProcessPool>(
-      new ProcessPool("loader",
-        process_pool_config.GetNumberOfLoaderProcesses(), this));
-}
-
-LoaderExecutor& LoaderExecutor::GetInst() {
-  static LoaderExecutor inst;
-  return inst;
-}
-
-pid_t LoaderExecutor::Execute(const LoaderContext* loader_context,
-    int priority) {
-  loader_argv_ = CreateLoaderArgv(loader_context);
-  if (process_pool_->IsPrepared()) {
-    tizen_base::Bundle b;
-    b.Add("LOADER_ARGS", loader_argv_);
-    b.Add("LOADER_PRIORITY", std::to_string(priority));
-    auto parcel = CreateParcelFromBundle(&b);
-    pid_t pid = process_pool_->Execute(parcel);
-    if (pid > 0)
-      return pid;
-  }
-
-  return Executor::Execute(priority);
-}
-
-bool LoaderExecutor::HasCandidateProcess() const {
-  return process_pool_->IsPrepared();
-}
-
-void LoaderExecutor::DisposeCandidateProcess() {
-  process_pool_->Dispose();
-  process_pool_->SetTimer();
-}
-
-void LoaderExecutor::HandleSigchld(pid_t pid) {
-  process_pool_->HandleSigchld(pid);
-}
-
-void LoaderExecutor::OnExecution() {
-  std::vector<char*> loader_argv(loader_argv_.size() + 1);
-  int loader_argc = loader_argv_.size();
-  for (int i = 0; i < loader_argc; ++i) {
-    loader_argv[i] = const_cast<char*>(loader_argv_[i].c_str());
-    if ((i + 1) != loader_argc)
-      SECURE_LOGD("loader argument %d : %s##", i, loader_argv[i]);
-  }
-
-  SignalManager::GetInst().UnblockSigchld();
-  Util::CloseAllFds();
-  Stdio::Setup();
-
-  SECURE_LOGE("Execute loader(%s)", loader_argv[LoaderArg::Path]);
-  if (execv(loader_argv[LoaderArg::Path], loader_argv.data()) < 0) {
-    char err_buf[1024];
-    fprintf(stderr, "Failed to execute a file. path: %s, errno: %d:%s\n",
-        loader_argv[LoaderArg::Path], errno,
-        strerror_r(errno, err_buf, sizeof(err_buf)));
-    exit(EXIT_FAILURE);
-  }
-}
-
-void LoaderExecutor::OnRequestReceived(tizen_base::Parcel* parcel) {
-  _W("Request received");
-  tizen_base::Bundle b = CreateBundleFromParcel(parcel);
-  int priority = std::stoi(b.GetString("LOADER_PRIORITY"));
-  if (priority != 0)
-    SchedPriority::Set(priority);
-
-  loader_argv_ = b.GetStringArray("LOADER_ARGS");
-  OnExecution();
-}
-
-std::vector<std::string> LoaderExecutor::CreateLoaderArgv(
-    const LoaderContext* loader_context) {
-  std::string dummy(kLoaderArgLength - 1, ' ');
-  std::vector<std::string> argv(LoaderArg::Dummy + 1);
-  argv[LoaderArg::Dummy] = std::move(dummy);
-  argv[LoaderArg::Path] = loader_context->GetLoaderPath();
-  argv[LoaderArg::Type] = std::to_string(loader_context->GetType());
-  argv[LoaderArg::Id] = std::to_string(loader_context->GetLoaderId());
-  argv[LoaderArg::Hydra] = loader_context->IsHydraMode() ? "1" : "0";
-  argv[LoaderArg::Extra] = loader_context->GetLoaderExtra();
-  return argv;
-}
-
-}  // namespace launchpad
diff --git a/src/launchpad-process-pool/loader_executor.hh b/src/launchpad-process-pool/loader_executor.hh
deleted file mode 100644 (file)
index 9a7c708..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- */
-
-#ifndef LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_HH_
-#define LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_HH_
-
-#include <sys/types.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "launchpad-process-pool/executor.hh"
-#include "launchpad-process-pool/loader_context.hh"
-#include "launchpad-process-pool/process_pool.hh"
-
-namespace launchpad {
-
-class LoaderExecutor : public Executor::Delegator,
-                       public Executor,
-                       public ProcessPool::IEvent {
- public:
-  LoaderExecutor(const LoaderExecutor&) = delete;
-  LoaderExecutor& operator=(const LoaderExecutor&) = delete;
-  LoaderExecutor(LoaderExecutor&&) = delete;
-  LoaderExecutor& operator=(LoaderExecutor&&) = delete;
-
-  static LoaderExecutor& GetInst();
-
-  pid_t Execute(const LoaderContext* loader_context, int priority);
-  bool HasCandidateProcess() const;
-  void DisposeCandidateProcess();
-  void HandleSigchld(pid_t pid);
-
- private:
-  LoaderExecutor();
-  ~LoaderExecutor() = default;
-
-  void OnExecution() override;
-  void OnRequestReceived(tizen_base::Parcel* parcel) override;
-  std::vector<std::string> CreateLoaderArgv(
-      const LoaderContext* loader_context);
-
- private:
-  std::unique_ptr<ProcessPool> process_pool_;
-  std::vector<std::string> loader_argv_;
-};
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_HH_
index 2208c82bac525876c209a2c6466a5baf837df695..4d116fa0ac9f9e4499b6ef3ca2bc617280854799 100644 (file)
 #include <memory>
 #include <vector>
 
+#include <loader_info.hh>
 #include <types.hh>
 
 #include "launchpad-process-pool/loader_context.hh"
-#include "launchpad-process-pool/loader_info.hh"
 
 namespace launchpad {
 
diff --git a/src/launchpad-process-pool/loader_info.cc b/src/launchpad-process-pool/loader_info.cc
deleted file mode 100644 (file)
index 96aa9bd..0000000
+++ /dev/null
@@ -1,787 +0,0 @@
-/*
- * Copyright (c) 2023 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 "launchpad-process-pool/loader_info.hh"
-
-#include <dirent.h>
-#include <malloc.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <algorithm>
-#include <fstream>
-#include <sstream>
-#include <utility>
-
-#include "launchpad-process-pool/log_private.hh"
-#include "launchpad-process-pool/util.hh"
-
-namespace fs = std::filesystem;
-
-namespace launchpad {
-namespace {
-
-constexpr const char kTagLoader[] = "[LOADER]";
-constexpr const char kTagName[] = "NAME";
-constexpr const char kTagExe[] = "EXE";
-constexpr const char kTagAppType[] = "APP_TYPE";
-constexpr const char kTagDetectionMethod[] = "DETECTION_METHOD";
-constexpr const char kTagActivationMethod[] = "ACTIVATION_METHOD";
-constexpr const char kTagDeactivationMethod[] = "DEACTIVATION_METHOD";
-constexpr const char kTagTtl[] = "TTL";
-constexpr const char kTagTimeout[] = "TIMEOUT";
-constexpr const char kTagExtra[] = "EXTRA";
-constexpr const char kTagExtraArray[] = "EXTRA_ARRAY";
-constexpr const char kTagExtraArrayVal[] = "EXTRA_ARRAY_VAL";
-constexpr const char kTagAlternativeLoader[] = "ALTERNATIVE_LOADER";
-constexpr const char kTagHwAcc[] = "HW_ACC";
-constexpr const char kTagCpuThresholdMax[] = "CPU_THRESHOLD_MAX";
-constexpr const char kTagCpuThresholdMin[] = "CPU_THRESHOLD_MIN";
-constexpr const char kTagOnBoot[] = "ON_BOOT";
-constexpr const char kTagHydra[] = "HYDRA";
-constexpr const char kTagAppCheck[] = "APP_CHECK";
-constexpr const char kTagOnBootTimeout[] = "ON_BOOT_TIMEOUT";
-constexpr const char kTagSchedPriority[] = "SCHED_PRIORITY";
-constexpr const char kTagConditionPathExists[] = "CONDITION_PATH_EXISTS";
-
-constexpr const char kValOn[] = "ON";
-constexpr const char kValOff[] = "OFF";
-constexpr const char kValMethodTimeout[] = "TIMEOUT";
-constexpr const char kValMethodDemand[] = "DEMAND";
-constexpr const char kValMethodVisibility[] = "VISIBILITY";
-constexpr const char kValMethodRequest[] = "REQUEST";
-constexpr const char kValMethodAvailableMemory[] = "AVAILABLE_MEMORY";
-constexpr const char kValMethodTtl[] = "TTL";
-constexpr const char kValMethodOutOfMemory[] = "OUT_OF_MEMORY";
-
-LoaderType MakeLoaderType() {
-  static uint32_t user_slot_offset;
-  return static_cast<LoaderType>(
-      static_cast<int>(LoaderType::User) + user_slot_offset++);
-}
-
-}  // namespace
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetType(LoaderType type) {
-  type_ = type;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetName(std::string name) {
-  name_ = std::move(name);
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetExe(std::string exe) {
-  exe_ = std::move(exe);
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::AddAppType(std::string app_type) {
-  app_types_.push_back(std::move(app_type));
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetAppTypes(
-    std::vector<std::string> app_types) {
-  app_types_ = std::move(app_types);
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetDetectionMethod(
-    LoaderMethod method) {
-  detection_method_ = method;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetActivationMethod(
-    LoaderMethod method) {
-  activation_method_ = method;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetDeactivationMethod(
-    LoaderMethod method) {
-  deactivation_method_ = method;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetTimeout(int timeout) {
-  timeout_ = timeout;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetHwAcc(std::string hw_acc) {
-  hw_acc_ = std::move(hw_acc);
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::AddAlternativeLoader(
-    std::string alternative_loader) {
-  alternative_loaders_.push_back(std::move(alternative_loader));
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetAlternativeLoaders(
-    std::vector<std::string> alternative_loaders) {
-  alternative_loaders_ = std::move(alternative_loaders);
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::AddExtraData(std::string key,
-    std::string value) {
-  extra_.Add(std::move(key), std::move(value));
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::AddExtraArrayData(std::string key,
-    std::vector<std::string> value) {
-  extra_.Add(std::move(key), std::move(value));
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetExtra(tizen_base::Bundle extra) {
-  extra_ = std::move(extra);
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetCPUThresholdMax(
-  int cpu_threshold_max) {
-  cpu_threshold_max_ = cpu_threshold_max;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetCPUThresholdMin(
-  int cpu_threshold_min) {
-  cpu_threshold_min_ = cpu_threshold_min;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetOnBoot(bool on_boot) {
-  on_boot_ = on_boot;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetTimeToLive(int time_to_live) {
-  time_to_live_ = time_to_live;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetHydraMode(bool hydra_mode) {
-  hydra_mode_ = hydra_mode;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetAppCheck(bool app_check) {
-  app_check_ = app_check;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetOnBootTimeout(
-  int on_boot_timeout) {
-  on_boot_timeout_ = on_boot_timeout;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetSchedPriority(int sched_priority) {
-  sched_priority_ = sched_priority;
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::AddConditionPathExists(
-    std::string path) {
-  condition_path_exists_.push_back(std::move(path));
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::SetConditionPathExists(
-    std::vector<std::string> condition_path_exists) {
-  condition_path_exists_ = std::move(condition_path_exists);
-  return *this;
-}
-
-LoaderInfo::Builder& LoaderInfo::Builder::Reset() {
-  type_ = LoaderType::None;
-  name_.clear();
-  exe_.clear();
-  app_types_.clear();
-  detection_method_ = LoaderMethod::Timeout | LoaderMethod::Visibility |
-      LoaderMethod::Install;
-  activation_method_ = LoaderMethod::None;
-  deactivation_method_ = LoaderMethod::None;
-  timeout_ = 5000;
-  hw_acc_.clear();
-  alternative_loaders_.clear();
-  extra_ = tizen_base::Bundle();
-  cpu_threshold_max_ = 90;
-  cpu_threshold_min_ = 40;
-  on_boot_ = true;
-  time_to_live_ = 600;
-  hydra_mode_ = false;
-  app_check_ = true;
-  on_boot_timeout_ = 0;
-  sched_priority_ = 0;
-  condition_path_exists_.clear();
-  return *this;
-}
-
-LoaderInfo* LoaderInfo::Builder::Build() {
-  return new LoaderInfo(type_, std::move(name_), std::move(exe_),
-      std::move(app_types_), detection_method_, activation_method_,
-      deactivation_method_, timeout_, std::move(hw_acc_),
-      std::move(alternative_loaders_), std::move(extra_),
-      cpu_threshold_max_, cpu_threshold_min_, on_boot_, time_to_live_,
-      hydra_mode_, app_check_, on_boot_timeout_, sched_priority_,
-      std::move(condition_path_exists_));
-}
-
-LoaderInfo::LoaderInfo(LoaderType type, std::string name, std::string exe,
-    std::vector<std::string> app_types, LoaderMethod detection_method,
-    LoaderMethod activation_method, LoaderMethod deactivation_method,
-    int timeout, std::string hw_acc,
-    std::vector<std::string> alternative_loaders,
-    tizen_base::Bundle extra, int cpu_threshold_max,
-    int cpu_threshold_min, bool on_boot, int time_to_live,
-    bool hydra_mode, bool app_check, int on_boot_timeout,
-    int sched_priority, std::vector<std::string> condition_path_exists)
-    : type_(type),
-      name_(std::move(name)),
-      exe_(std::move(exe)),
-      app_types_(std::move(app_types)),
-      detection_method_(detection_method),
-      activation_method_(activation_method),
-      deactivation_method_(deactivation_method),
-      timeout_(timeout),
-      hw_acc_(std::move(hw_acc)),
-      alternative_loaders_(std::move(alternative_loaders)),
-      extra_(std::move(extra)),
-      cpu_threshold_max_(cpu_threshold_max),
-      cpu_threshold_min_(cpu_threshold_min),
-      on_boot_(on_boot),
-      time_to_live_(time_to_live),
-      hydra_mode_(hydra_mode),
-      app_check_(app_check),
-      on_boot_timeout_(on_boot_timeout),
-      sched_priority_(sched_priority),
-      condition_path_exists_(std::move(condition_path_exists)) {
-  extra_.Add("SCHED_PRIORITY", std::to_string(sched_priority_));
-}
-
-LoaderType LoaderInfo::GetType() const {
-  return type_;
-}
-
-void LoaderInfo::SetType(LoaderType type) {
-  type_ = type;
-}
-
-const std::string& LoaderInfo::GetName() const {
-  return name_;
-}
-
-const std::string& LoaderInfo::GetExe() const {
-  return exe_;
-}
-
-void LoaderInfo::SetExe(std::string exe) {
-  exe_ = std::move(exe);
-}
-
-int LoaderInfo::GetCpuThresholdMax() const {
-  return cpu_threshold_max_;
-}
-
-int LoaderInfo::GetCpuThresholdMin() const {
-  return cpu_threshold_min_;
-}
-
-int LoaderInfo::GetTimeToLive() const {
-  return time_to_live_;
-}
-
-const std::vector<std::string>& LoaderInfo::GetAppTypes() const {
-  return app_types_;
-}
-
-LoaderMethod LoaderInfo::GetDetectionMethod() const {
-  return detection_method_;
-}
-
-void LoaderInfo::SetDetectionMethod(LoaderMethod detection_method) {
-  detection_method_ = detection_method;
-}
-
-LoaderMethod LoaderInfo::GetActivationMethod() const {
-  return activation_method_;
-}
-
-void LoaderInfo::SetActivationMethod(LoaderMethod activation_method) {
-  activation_method_ = activation_method;
-}
-
-LoaderMethod LoaderInfo::GetDeactivationMethod() const {
-  return deactivation_method_;
-}
-
-void LoaderInfo::SetDeactivationMethod(LoaderMethod deactivation_method) {
-  deactivation_method_ = deactivation_method;
-}
-
-const std::string& LoaderInfo::GetHwAcc() const {
-  return hw_acc_;
-}
-
-int LoaderInfo::GetOnBootTimeout() const {
-  return on_boot_timeout_;
-}
-
-int LoaderInfo::GetTimeout() const {
-  return timeout_;
-}
-
-void LoaderInfo::SetTimeout(int timeout) {
-  timeout_ = timeout;
-}
-
-int LoaderInfo::GetSchedPriority() const {
-  return sched_priority_;
-}
-
-bool LoaderInfo::ShouldCheckAppInstallation() const {
-  return app_check_;
-}
-
-bool LoaderInfo::IsOnBoot() const {
-  return on_boot_;
-}
-
-bool LoaderInfo::IsHydraMode() const {
-  return hydra_mode_;
-}
-
-tizen_base::Bundle& LoaderInfo::GetExtra() {
-  return extra_;
-}
-
-void LoaderInfo::SetAppInstalled(bool app_installed) {
-  app_installed_ = app_installed;
-}
-
-bool LoaderInfo::IsAppInstalled() const {
-  return app_installed_;
-}
-
-const std::vector<std::string>& LoaderInfo::GetConditionPathExists() const {
-  return condition_path_exists_;
-}
-
-LoaderInfoInflator::LoaderInfoInflator() {
-  parsers_ = {
-    { kTagName,
-      std::bind(&LoaderInfoInflator::ParseName,
-          this, std::placeholders::_1) },
-    { kTagExe,
-      std::bind(&LoaderInfoInflator::ParseExe,
-          this, std::placeholders::_1) },
-    { kTagAppType,
-      std::bind(&LoaderInfoInflator::ParseAppType,
-          this, std::placeholders::_1) },
-    { kTagDetectionMethod,
-      std::bind(&LoaderInfoInflator::ParseDetectionMethod,
-          this, std::placeholders::_1) },
-    { kTagActivationMethod,
-      std::bind(&LoaderInfoInflator::ParseActivationMethod,
-          this, std::placeholders::_1) },
-    { kTagDeactivationMethod,
-      std::bind(&LoaderInfoInflator::ParseDeativationMethod,
-          this, std::placeholders::_1) },
-    { kTagTtl,
-      std::bind(&LoaderInfoInflator::ParseTimeToLive,
-          this, std::placeholders::_1) },
-    { kTagTimeout,
-      std::bind(&LoaderInfoInflator::ParseTimeout,
-          this, std::placeholders::_1) },
-    { kTagExtra,
-      std::bind(&LoaderInfoInflator::ParseExtra,
-          this, std::placeholders::_1) },
-    { kTagExtraArray,
-      std::bind(&LoaderInfoInflator::ParseExtraArray,
-          this, std::placeholders::_1) },
-    { kTagExtraArrayVal,
-      std::bind(&LoaderInfoInflator::ParseExtraArrayValue,
-          this, std::placeholders::_1) },
-    { kTagHwAcc,
-      std::bind(&LoaderInfoInflator::ParseHwAcc,
-          this, std::placeholders::_1) },
-    { kTagAlternativeLoader,
-      std::bind(&LoaderInfoInflator::ParseAlternativeLoader,
-          this, std::placeholders::_1) },
-    { kTagCpuThresholdMax,
-      std::bind(&LoaderInfoInflator::ParseCPUThresholdMax,
-          this, std::placeholders::_1) },
-    { kTagCpuThresholdMin,
-      std::bind(&LoaderInfoInflator::ParseCPUThresholdMin,
-          this, std::placeholders::_1) },
-    { kTagOnBoot,
-      std::bind(&LoaderInfoInflator::ParseOnBoot,
-          this, std::placeholders::_1) },
-    { kTagHydra,
-      std::bind(&LoaderInfoInflator::ParseHydra,
-          this, std::placeholders::_1) },
-    { kTagAppCheck,
-      std::bind(&LoaderInfoInflator::ParseAppCheck,
-          this, std::placeholders::_1) },
-    { kTagOnBootTimeout,
-      std::bind(&LoaderInfoInflator::ParseOnBootTimeout,
-          this, std::placeholders::_1) },
-    { kTagSchedPriority,
-      std::bind(&LoaderInfoInflator::ParseSchedPriority,
-          this, std::placeholders::_1) },
-    { kTagConditionPathExists,
-      std::bind(&LoaderInfoInflator::ParseConditionPathExists,
-          this, std::placeholders::_1) },
-  };
-}
-
-void LoaderInfoInflator::ParseName(std::string token) {
-  builder_.SetName(std::move(token));
-}
-
-void LoaderInfoInflator::ParseExe(std::string token) {
-  builder_.SetExe(std::move(token));
-}
-
-void LoaderInfoInflator::ParseAppType(std::string token) {
-  std::string line = std::move(token);
-  do {
-    auto tokens = Split(line, " |\t\r\n");
-    for (auto& app_type : tokens)
-      builder_.AddAppType(app_type);
-  } while (std::getline(string_stream_, line));
-}
-
-void LoaderInfoInflator::ParseDetectionMethod(std::string token) {
-  LoaderMethod method = LoaderMethod::None;
-  std::string line = std::move(token);
-  do {
-    auto tokens = Split(line, " |\t\r\n");
-    for (auto& token : tokens) {
-      if (token == kValMethodTimeout)
-        method = method | LoaderMethod::Timeout;
-      else if (token == kValMethodVisibility)
-        method = method | LoaderMethod::Visibility;
-      else if (token == kValMethodDemand)
-        method = method | LoaderMethod::Demand;
-    }
-  } while (std::getline(string_stream_, line));
-
-  method = method | LoaderMethod::Install;
-  builder_.SetDetectionMethod(method);
-  _D("Detection method: %d", static_cast<int>(method));
-}
-
-void LoaderInfoInflator::ParseActivationMethod(std::string token) {
-  LoaderMethod method = LoaderMethod::None;
-  std::string line = std::move(token);
-  do {
-    auto tokens = Split(line, " |\t\r\n");
-    for (auto& token : tokens) {
-      if (token == kValMethodRequest)
-        method = method | LoaderMethod::Request;
-      else if (token == kValMethodAvailableMemory)
-        method = method | LoaderMethod::AvailableMemory;
-    }
-  } while (std::getline(string_stream_, line));
-
-  builder_.SetActivationMethod(method);
-  _D("Activation method: %d", static_cast<int>(method));
-}
-
-void LoaderInfoInflator::ParseDeativationMethod(std::string token) {
-  LoaderMethod method = LoaderMethod::None;
-  std::string line = std::move(token);
-  do {
-    auto tokens = Split(line, " |\t\r\n");
-    for (auto& token : tokens) {
-      if (token == kValMethodTtl)
-        method = method | LoaderMethod::TimeToLive;
-      else if (token == kValMethodOutOfMemory)
-        method = method | LoaderMethod::OutOfMemory;
-    }
-  } while (std::getline(string_stream_, line));
-
-  builder_.SetDeactivationMethod(method);
-  _D("Deactivation method: %d", static_cast<int>(method));
-}
-
-void LoaderInfoInflator::ParseTimeToLive(std::string token) {
-  builder_.SetTimeToLive(std::stoi(token));
-}
-
-void LoaderInfoInflator::ParseTimeout(std::string token) {
-  builder_.SetTimeout(std::stoi(token));
-}
-
-void LoaderInfoInflator::ParseExtra(std::string token) {
-  std::string value;
-  if (string_stream_ >> value)
-    builder_.AddExtraData(std::move(token), std::move(value));
-}
-
-void LoaderInfoInflator::ParseExtraArray(std::string token) {
-  if (!extra_array_key_.empty() && !extra_array_value_.empty()) {
-    builder_.AddExtraArrayData(std::move(extra_array_key_),
-        std::move(extra_array_value_));
-    extra_array_value_.clear();
-  }
-
-  extra_array_key_ = std::move(token);
-}
-
-void LoaderInfoInflator::ParseExtraArrayValue(std::string token) {
-  extra_array_value_.push_back(std::move(token));
-}
-
-void LoaderInfoInflator::ParseHwAcc(std::string token) {
-  builder_.SetHwAcc(std::move(token));
-}
-
-void LoaderInfoInflator::ParseAlternativeLoader(std::string token) {
-  builder_.AddAlternativeLoader(std::move(token));
-}
-
-void LoaderInfoInflator::ParseCPUThresholdMax(std::string token) {
-  builder_.SetCPUThresholdMax(std::stoi(token));
-}
-
-void LoaderInfoInflator::ParseCPUThresholdMin(std::string token) {
-  builder_.SetCPUThresholdMin(std::stoi(token));
-}
-
-void LoaderInfoInflator::ParseOnBoot(std::string token) {
-  if (token == kValOff)
-    builder_.SetOnBoot(false);
-}
-
-void LoaderInfoInflator::ParseHydra(std::string token) {
-  if (token == kValOn)
-    builder_.SetHydraMode(true);
-}
-
-void LoaderInfoInflator::ParseAppCheck(std::string token) {
-  if (token == kValOff)
-    builder_.SetAppCheck(false);
-}
-
-void LoaderInfoInflator::ParseOnBootTimeout(std::string token) {
-  builder_.SetOnBootTimeout(std::stoi(token));
-}
-
-void LoaderInfoInflator::ParseSchedPriority(std::string token) {
-  builder_.SetSchedPriority(std::min(std::max(std::stoi(token), -20), 19));
-}
-
-void LoaderInfoInflator::ParseConditionPathExists(std::string token) {
-  std::string line = std::move(token);
-  do {
-    auto tokens = Split(line, " |\t\r\n");
-    for (auto& token : tokens)
-      builder_.AddConditionPathExists(token);
-  } while (std::getline(string_stream_, line));
-}
-
-void LoaderInfoInflator::Parse(const std::filesystem::path& path,
-    LoaderType type) {
-  std::ifstream loader_file;
-  loader_file.open(path);
-  if (loader_file.fail())
-    return;
-
-  bool parsing = false;
-  std::string line;
-  while (std::getline(loader_file, line)) {
-    string_stream_ = std::istringstream(line);
-    std::string token1;
-    if (!(string_stream_ >> token1))
-      continue;
-
-    std::string key = ToUpper(std::move(token1));
-    if (key == kTagLoader) {
-      if (parsing)
-        Insert(type);
-
-      builder_.Reset();
-      parsing = true;
-      continue;
-    }
-
-    if (parsing == false)
-      continue;
-
-    std::string token2;
-    if (!(string_stream_ >> token2))
-      continue;
-
-    auto found = parsers_.find(key);
-    if (found == parsers_.end())
-      continue;
-
-    auto& parser = found->second;
-    parser(std::move(token2));
-  }
-
-  if (parsing)
-    Insert(type);
-
-  loader_file.close();
-}
-
-void LoaderInfoInflator::Insert(LoaderType type) {
-  if (!extra_array_key_.empty() && !extra_array_value_.empty()) {
-    builder_.AddExtraArrayData(std::move(extra_array_key_),
-        std::move(extra_array_value_));
-    extra_array_value_.clear();
-  }
-
-  if (type != LoaderType::Dynamic)
-    type = MakeLoaderType();
-
-  builder_.SetType(type);
-  loader_infos_.emplace_back(builder_.Build());
-}
-
-std::vector<LoaderInfoPtr> LoaderInfoInflator::Inflate(
-    const std::string_view path) {
-  fs::path input_path(path);
-  if (fs::is_directory(input_path) == false)
-    return {};
-
-  try {
-    for (auto& entry : fs::directory_iterator(input_path)) {
-      fs::path file(entry.path());
-      if (file.extension() == ".loader")
-        Parse(file, LoaderType::User);
-    }
-  } catch (const fs::filesystem_error& e) {
-    _E("Exception occurs. error(%s:%d)", e.what(), e.code().value());
-  }
-
-  return loader_infos_;
-}
-
-LoaderInfoManager::LoaderInfoManager(std::string path): path_(std::move(path)) {
-}
-
-void LoaderInfoManager::Load() {
-  if (!loader_list_.empty())
-    return;
-
-  LoaderInfoInflator inflator;
-  loader_list_ = inflator.Inflate(path_);
-}
-
-void LoaderInfoManager::LoadFile(const std::string_view file) {
-  LoaderInfoInflator inflator;
-  fs::path path(path_);
-  inflator.Parse(path / file, LoaderType::Dynamic);
-}
-
-void LoaderInfoManager::Unload(const std::string_view loader_name) {
-  loader_list_.erase(std::remove_if(loader_list_.begin(), loader_list_.end(),
-      [&](const LoaderInfoPtr& info) -> bool {
-        return info->GetName() == loader_name;
-      }), loader_list_.end());
-}
-
-void LoaderInfoManager::Dispose() {
-  loader_list_.clear();
-}
-
-std::string LoaderInfoManager::FindLoaderPath(
-    const std::string_view loader_name) {
-  for (auto& info : loader_list_) {
-    if (info->GetName() == loader_name)
-      return info->GetExe();
-  }
-
-  return "";
-}
-
-LoaderInfoPtr LoaderInfoManager::FindLoaderInfo(
-    const std::string_view loader_name) {
-  for (auto& info : loader_list_) {
-    if (info->GetName() == loader_name)
-      return info;
-  }
-
-  return nullptr;
-}
-
-LoaderType LoaderInfoManager::FindHwType(const std::string_view app_type) {
-  for (auto& info : loader_list_) {
-    if (info->GetHwAcc().empty() || info->GetHwAcc() == kValOn) {
-      auto found = std::find_if(
-          info->GetAppTypes().begin(), info->GetAppTypes().end(),
-          [&](const std::string& type) -> bool { return type == app_type; });
-      if (found != info->GetAppTypes().end())
-        return info->GetType();
-    }
-  }
-
-  return LoaderType::None;
-}
-
-LoaderType LoaderInfoManager::FindSwType(const std::string_view app_type) {
-  for (auto& info : loader_list_) {
-    if (info->GetHwAcc().empty() || info->GetHwAcc() == kValOff) {
-      auto found = std::find_if(
-          info->GetAppTypes().begin(), info->GetAppTypes().end(),
-          [&](const std::string& type) -> bool { return type == app_type; });
-      if (found != info->GetAppTypes().end())
-        return info->GetType();
-    }
-  }
-
-  return LoaderType::None;
-}
-
-std::vector<LoaderType> LoaderInfoManager::GetAlternativeTypes(
-    LoaderType type) {
-  std::vector<LoaderType> result;
-  for (auto& info : loader_list_) {
-    if (info->GetType() == type) {
-      for (auto& alt_loader : info->alternative_loaders_) {
-        auto found = std::find_if(loader_list_.begin(), loader_list_.end(),
-            [&](const auto& li) -> bool {
-              return li->GetName() == alt_loader;
-            });
-        if (found == loader_list_.end())
-          continue;
-
-        result.push_back((*found)->GetType());
-      }
-    }
-  }
-
-  return result;
-}
-
-const std::vector<LoaderInfoPtr>& LoaderInfoManager::GetLoaderInfoList() const {
-  return loader_list_;
-}
-
-}  // namespace launchpad
diff --git a/src/launchpad-process-pool/loader_info.hh b/src/launchpad-process-pool/loader_info.hh
deleted file mode 100644 (file)
index 2ad1bc0..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- */
-
-#ifndef LAUNCHPAD_PROCESS_POOL_LOADER_INFO_HH_
-#define LAUNCHPAD_PROCESS_POOL_LOADER_INFO_HH_
-
-#include <bundle_cpp.h>
-
-#include <filesystem>
-#include <functional>
-#include <memory>
-#include <string>
-#include <string_view>
-#include <unordered_map>
-#include <vector>
-
-#include <types.hh>
-
-#include "launchpad-process-pool/util.hh"
-
-namespace launchpad {
-
-enum class LoaderMethod : int {
-  None = 0x0000,
-  Timeout = 0x0001,
-  Visibility = 0x0002,
-  Demand = 0x0004,
-  Request = 0x0010,
-  AvailableMemory = 0x0020,
-  TimeToLive = 0x0040,
-  OutOfMemory = 0x0100,
-  Install = 0x0200,
-};
-
-class LoaderInfo {
- public:
-  class Builder {
-   public:
-    Builder& SetType(LoaderType type);
-    Builder& SetName(std::string name);
-    Builder& SetExe(std::string exe);
-    Builder& AddAppType(std::string app_type);
-    Builder& SetAppTypes(std::vector<std::string> app_types);
-    Builder& SetDetectionMethod(launchpad::LoaderMethod method);
-    Builder& SetActivationMethod(launchpad::LoaderMethod method);
-    Builder& SetDeactivationMethod(launchpad::LoaderMethod method);
-    Builder& SetTimeout(int timeout);
-    Builder& SetHwAcc(std::string hw_acc);
-    Builder& AddAlternativeLoader(std::string alternative_loader);
-    Builder& SetAlternativeLoaders(
-        std::vector<std::string> alternative_loaders);
-    Builder& AddExtraData(std::string key, std::string value);
-    Builder& AddExtraArrayData(std::string key, std::vector<std::string> value);
-    Builder& SetExtra(tizen_base::Bundle extra);
-    Builder& SetCPUThresholdMax(int cpu_threshold_max);
-    Builder& SetCPUThresholdMin(int cpu_threshold_min);
-    Builder& SetOnBoot(bool on_boot);
-    Builder& SetTimeToLive(int time_to_live);
-    Builder& SetHydraMode(bool hydra_mode);
-    Builder& SetAppCheck(bool app_check);
-    Builder& SetOnBootTimeout(int on_boot_timeout);
-    Builder& SetSchedPriority(int sched_priority);
-    Builder& AddConditionPathExists(std::string path);
-    Builder& SetConditionPathExists(
-        std::vector<std::string> condition_path_exists);
-    Builder& Reset();
-
-    LoaderInfo* Build();
-
-   private:
-    LoaderType type_ = LoaderType::None;
-    std::string name_;
-    std::string exe_;
-    std::vector<std::string> app_types_;
-    LoaderMethod detection_method_ =
-       LoaderMethod::Timeout | LoaderMethod::Visibility | LoaderMethod::Install;
-    LoaderMethod activation_method_ = LoaderMethod::None;
-    LoaderMethod deactivation_method_ = LoaderMethod::None;
-    int timeout_ = 5000;
-    std::string hw_acc_;
-    std::vector<std::string> alternative_loaders_;
-    tizen_base::Bundle extra_;
-    int cpu_threshold_max_ = 90;
-    int cpu_threshold_min_ = 40;
-    bool on_boot_ = true;
-    int time_to_live_ = 600;
-    bool hydra_mode_ = false;
-    bool app_check_ = true;
-    int on_boot_timeout_ = 0;
-    int sched_priority_ = 0;
-    std::vector<std::string> condition_path_exists_;
-  };
-
-  LoaderInfo(LoaderType type, std::string name, std::string exe,
-      std::vector<std::string> app_types, LoaderMethod detection_method,
-      LoaderMethod activation_method, LoaderMethod deactivation_method,
-      int timeout, std::string hw_acc,
-      std::vector<std::string> alternative_loaders,
-      tizen_base::Bundle extra, int cpu_threshold_max,
-      int cpu_threshold_min, bool on_boot, int time_to_live,
-      bool hydra_mode, bool app_check, int on_boot_timeout,
-      int sched_priority,
-      std::vector<std::string> condition_path_exists);
-
-  LoaderType GetType() const;
-  void SetType(LoaderType type);
-  const std::string& GetName() const;
-  const std::string& GetExe() const;
-  void SetExe(std::string exe);
-  int GetCpuThresholdMax() const;
-  int GetCpuThresholdMin() const;
-  int GetTimeToLive() const;
-  const std::vector<std::string>& GetAppTypes() const;
-  LoaderMethod GetDetectionMethod() const;
-  void SetDetectionMethod(LoaderMethod detection_method);
-  LoaderMethod GetActivationMethod() const;
-  void SetActivationMethod(LoaderMethod activation_method);
-  LoaderMethod GetDeactivationMethod() const;
-  void SetDeactivationMethod(LoaderMethod deactivation_method);
-  const std::string& GetHwAcc() const;
-  int GetOnBootTimeout() const;
-  int GetTimeout() const;
-  void SetTimeout(int timeout);
-  int GetSchedPriority() const;
-  bool ShouldCheckAppInstallation() const;
-  bool IsOnBoot() const;
-  bool IsHydraMode() const;
-  tizen_base::Bundle& GetExtra();
-  const std::vector<std::string>& GetConditionPathExists() const;
-  void SetAppInstalled(bool app_installed);
-  bool IsAppInstalled() const;
-
- private:
-  friend class LoaderInfoManager;
-  friend class LoaderInfoInflator;
-
- private:
-  LoaderType type_;
-  std::string name_;
-  std::string exe_;
-  std::vector<std::string> app_types_;
-  LoaderMethod detection_method_;
-  LoaderMethod activation_method_;
-  LoaderMethod deactivation_method_;
-  int timeout_;
-  std::string hw_acc_;
-  std::vector<std::string> alternative_loaders_;
-  tizen_base::Bundle extra_;
-  int cpu_threshold_max_;
-  int cpu_threshold_min_;
-  bool on_boot_;
-  int time_to_live_;
-  bool hydra_mode_;
-  bool app_check_;
-  int on_boot_timeout_;
-  int sched_priority_;
-  std::vector<std::string> condition_path_exists_;
-  bool app_installed_ = false;
-};
-
-using LoaderInfoPtr = std::shared_ptr<LoaderInfo>;
-
-class LoaderInfoInflator {
- public:
-  LoaderInfoInflator();
-
-  std::vector<LoaderInfoPtr> Inflate(const std::string_view path);
-
-  void Parse(const std::filesystem::path& path, LoaderType type);
-
- private:
-  void ParseName(std::string token);
-  void ParseExe(std::string token);
-  void ParseAppType(std::string token);
-  void ParseDetectionMethod(std::string token);
-  void ParseActivationMethod(std::string token);
-  void ParseDeativationMethod(std::string token);
-  void ParseTimeToLive(std::string token);
-  void ParseTimeout(std::string token);
-  void ParseExtra(std::string token);
-  void ParseExtraArray(std::string token);
-  void ParseExtraArrayValue(std::string token);
-  void ParseHwAcc(std::string token);
-  void ParseAlternativeLoader(std::string token);
-  void ParseCPUThresholdMax(std::string token);
-  void ParseCPUThresholdMin(std::string token);
-  void ParseOnBoot(std::string token);
-  void ParseHydra(std::string token);
-  void ParseAppCheck(std::string token);
-  void ParseOnBootTimeout(std::string token);
-  void ParseSchedPriority(std::string token);
-  void ParseConditionPathExists(std::string token);
-  void Insert(LoaderType type);
-
- private:
-  std::unordered_map<std::string, std::function<void(std::string)>> parsers_;
-  std::istringstream string_stream_;
-  std::string extra_array_key_;
-  std::vector<std::string> extra_array_value_;
-  LoaderInfo::Builder builder_;
-  std::vector<std::shared_ptr<LoaderInfo>> loader_infos_;
-};
-
-class LoaderInfoManager {
- public:
-  explicit LoaderInfoManager(std::string path);
-  LoaderInfoManager(const LoaderInfoManager&) = delete;
-  LoaderInfoManager& operator=(const LoaderInfoManager&) = delete;
-
-  void Load();
-  void LoadFile(const std::string_view file);
-  void Unload(const std::string_view loader_name);
-  void Dispose();
-  LoaderType FindHwType(const std::string_view app_type);
-  LoaderType FindSwType(const std::string_view app_type);
-  std::string FindLoaderPath(const std::string_view loader_name);
-  LoaderInfoPtr FindLoaderInfo(const std::string_view loader_name);
-  std::vector<LoaderType> GetAlternativeTypes(LoaderType type);
-  const std::vector<LoaderInfoPtr>& GetLoaderInfoList() const;
-
- private:
-  std::string path_;
-  std::vector<LoaderInfoPtr> loader_list_;
-};
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_PROCESS_POOL_LOADER_INFO_HH_
index 7632d394d38de544b21ed40721f1a8028c3f685d..20fc128c41145e81c455b258c10d22e1eb1c2797 100644 (file)
 #include <algorithm>
 #include <utility>
 
+#include <loader_executor.hh>
 #include <types.hh>
 
 #include "launchpad-process-pool/config.hh"
-#include "launchpad-process-pool/loader_executor.hh"
 #include "launchpad-process-pool/loader_factory.hh"
 #include "launchpad-process-pool/log_private.hh"
 
index 060c2c30efc16ebd205ebb8056d357c5dcac16fe..7d8c93973e01da68e977e78016d17ad7c95fc29b 100644 (file)
 #include <vector>
 
 #include <app_info.hh>
+#include <loader_info.hh>
 #include <hw_acceleration_config.hh>
 
 #include "launchpad-process-pool/app_defined_loader_info_manager.hh"
 #include "launchpad-process-pool/app_labels_monitor.hh"
 #include "launchpad-process-pool/hydra_loader_context.hh"
 #include "launchpad-process-pool/loader_context.hh"
-#include "launchpad-process-pool/loader_info.hh"
 #include "launchpad-process-pool/loader_mount.hh"
 #include "launchpad-process-pool/memory_monitor.hh"
 #include "launchpad-process-pool/sequencer.hh"
index b6414de952d1a345867176a8da4000354be7fad8..d623ca111ae3b68f9350bd8a55de09124b31769d 100644 (file)
 
 #include <aul_keys.hh>
 #include <exception.hh>
+#include <launchpad_args.hh>
 #include <parcelable.hh>
 #include <util.hh>
 
-#include "launchpad-process-pool/launchpad_args.hh"
 #include "launchpad-process-pool/log_private.hh"
 
 namespace fs = std::filesystem;
index 6bc2274e9d5b975057dda67fc868170a89bac622..e783c70ecebc7315505ead6c83ac57c80099d731 100644 (file)
 #include <vector>
 
 #include <app_info.hh>
+#include <executor.hh>
 #include <parcel.hh>
 #include <socket.hh>
 
-#include "launchpad-process-pool/executor.hh"
-
 namespace launchpad {
 
 class LoaderMount : public Executor::Delegator, public Executor {
diff --git a/src/launchpad-process-pool/process_pool.cc b/src/launchpad-process-pool/process_pool.cc
deleted file mode 100644 (file)
index 81a5c05..0000000
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (c) 2023 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 "launchpad-process-pool/process_pool.hh"
-
-#include <dlog-redirect-stdout.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/limits.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <filesystem>
-#include <utility>
-#include <vector>
-
-#include <util.hh>
-
-#include "launchpad-process-pool/launchpad_args.hh"
-#include "launchpad-process-pool/log_private.hh"
-
-namespace fs = std::filesystem;
-
-namespace launchpad {
-namespace {
-
-constexpr const char kProcessPool[] = "process-pool";
-
-bool IsExceptable(const std::string& path) {
-  static char buf[PATH_MAX];
-  ssize_t len = readlink(path.c_str(), buf, sizeof(buf));
-  if (len < 0) {
-    _E("readlink() is failed. errno: %d", errno);
-    return false;
-  }
-
-  buf[len] = '\0';
-  if (strstr(buf, "log") != nullptr ||
-      strstr(buf, "trace") != nullptr ||
-      strstr(buf, "dev") != nullptr)
-    return true;
-
-  return false;
-}
-
-std::vector<int> GetExceptableFds() {
-  std::vector<int> fds;
-  try {
-    fs::path proc_path("/proc/self/fd");
-    for (const auto& entry : fs::directory_iterator(proc_path)) {
-      if (!isdigit(entry.path().filename().string()[0]))
-        continue;
-
-      int fd = std::stoi(entry.path().filename().string());
-      if (dlog_is_log_fd(fd) || IsExceptable(entry.path().string()))
-        fds.push_back(fd);
-    }
-  } catch (const fs::filesystem_error& e) {
-    _E("Exception occurs. error(%s)", e.what());
-  }
-
-  return fds;
-}
-
-}  // namespace
-
-ProcessPool::ProcessPool(std::string name, int num_processes,
-    IEvent* event_listener = nullptr)
-    : Executor(this),
-      name_(std::move(name)),
-      num_processes_(num_processes),
-      event_listener_(event_listener) {
-  PrepareProcess();
-}
-
-ProcessPool::~ProcessPool() {
-  Dispose();
-}
-
-bool ProcessPool::IsPrepared() const {
-  return !queue_.empty();
-}
-
-pid_t ProcessPool::Execute(const tizen_base::Parcel& parcel) {
-  SetTimer();
-  if (!IsPrepared())
-    return -1;
-
-  auto process = std::move(queue_.front());
-  queue_.erase(queue_.begin());
-  if (process->Send(parcel) < 0)
-    return -1;
-
-  return process->GetPid();
-}
-
-void ProcessPool::Dispose() {
-  for (auto& process : queue_) {
-    process->Kill();
-    _D("Kill process(%d)", process->GetPid());
-  }
-  queue_.clear();
-  UnsetTimer();
-}
-
-void ProcessPool::HandleSigchld(pid_t pid) {
-  auto iter = queue_.begin();
-  while (iter != queue_.end()) {
-    if ((*iter)->GetPid() == pid) {
-      iter = queue_.erase(iter);
-      break;
-    }
-
-    iter++;
-  }
-
-  int current_process_count = static_cast<int>(queue_.size());
-  if (current_process_count != num_processes_)
-    SetTimer();
-}
-
-ProcessPool::Process::Process(pid_t pid, int fd)
-    : pid_(pid), socket_(new Socket(fd)) {
-}
-
-pid_t ProcessPool::Process::GetPid() const {
-  return pid_;
-}
-
-int ProcessPool::Process::Send(const tizen_base::Parcel& parcel) {
-  _W("Send execution request. process ID: %d", pid_);
-  size_t data_size = parcel.GetDataSize();
-  int ret = socket_->Write(static_cast<void*>(&data_size), sizeof(data_size));
-  if (ret != 0) {
-    _E("Write() is failed. error(%d)", ret);
-    return ret;
-  }
-
-  return socket_->Write(parcel.GetData(), parcel.GetDataSize());
-}
-
-void ProcessPool::Process::Kill() {
-  socket_->Close();
-  if (kill(pid_, SIGKILL) == -1) {
-    _E("Failed to send kill signal to the process. pid(%d), errno(%d)",
-        pid_, errno);
-  }
-}
-
-void ProcessPool::OnExecution() {
-  _D("Candidate Process");
-  char** args = LaunchpadArgs::GetInst().GetArgs();
-  size_t length = strlen(args[0]);
-  memset(args[0], '\0', length);
-  snprintf(args[0], length, "/usr/bin/%s <%s>", kProcessPool, name_.c_str());
-
-  close(pipe_fd_[1]);
-  std::vector<int> except_fds = GetExceptableFds();
-  except_fds.push_back(pipe_fd_[0]);
-  Util::CloseAllFds(except_fds);
-  int ret = WaitForRequest(std::make_unique<Socket>(pipe_fd_[0]));
-  exit(ret);
-}
-
-void ProcessPool::PrepareProcess() {
-  int current_process_count = static_cast<int>(queue_.size());
-  for (int i = current_process_count; i < num_processes_; ++i) {
-    pipe_fd_[0] = -1;
-    pipe_fd_[1] = -1;
-    if (pipe(pipe_fd_) == -1) {
-      _E("Failed to create pipe. errno(%d)", errno);
-      return;
-    }
-
-    if (fcntl(pipe_fd_[0], F_SETPIPE_SZ, Socket::kSocketMaxBufferSize) == -1)
-      _E("Failed to set pipe size. errno(%d)", errno);
-
-    if (fcntl(pipe_fd_[1], F_SETPIPE_SZ, Socket::kSocketMaxBufferSize) == -1)
-      _E("Failed to set pipe size. errno(%d)", errno);
-
-    pid_t pid = Executor::Execute();
-    if (pid == -1) {
-      _E("Failed to fork process. errno(%d)", errno);
-      close(pipe_fd_[0]);
-      close(pipe_fd_[1]);
-      return;
-    }
-
-    close(pipe_fd_[0]);
-    queue_.push_back(std::make_shared<Process>(pid, pipe_fd_[1]));
-  }
-}
-
-int ProcessPool::WaitForRequest(std::unique_ptr<Socket> socket) {
-  tizen_base::Parcel parcel;
-  int ret = 0;
-  do {
-    size_t data_size = 0;
-    ret = socket->Read(static_cast<void*>(&data_size), sizeof(data_size));
-    if (ret != 0) {
-      _E("Failed to read from socket. error(%d)", ret);
-      return -1;
-    }
-
-    std::vector<uint8_t> data(data_size);
-    ret = socket->Read(data.data(), data.size());
-    if (ret != 0) {
-      _E("Failed to read from socket. error(%d)", ret);
-      return -1;
-    }
-
-    parcel.Write(data.data(), data.size());
-  } while (ret != 0);
-
-  if (event_listener_ != nullptr)
-    event_listener_->OnRequestReceived(&parcel);
-
-  return 0;
-}
-
-void ProcessPool::SetTimer() {
-  if (timer_ != 0)
-    return;
-
-  timer_ = g_timeout_add(1000, OnTimeout, this);
-}
-
-void ProcessPool::UnsetTimer() {
-  if (timer_ != 0) {
-    g_source_remove(timer_);
-    timer_ = 0;
-  }
-}
-
-gboolean ProcessPool::OnTimeout(gpointer user_data) {
-  auto* process_pool = static_cast<ProcessPool*>(user_data);
-  process_pool->PrepareProcess();
-  process_pool->timer_ = 0;
-  return G_SOURCE_REMOVE;
-}
-
-}  // namespace launchpad
-
diff --git a/src/launchpad-process-pool/process_pool.hh b/src/launchpad-process-pool/process_pool.hh
deleted file mode 100644 (file)
index 7d159c2..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- */
-
-#ifndef LAUNCHPAD_PROCESS_POOL_PROCESS_POOL_HH_
-#define LAUNCHPAD_PROCESS_POOL_PROCESS_POOL_HH_
-
-#include <glib.h>
-#include <sys/types.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include <parcel.hh>
-#include <socket.hh>
-
-#include "launchpad-process-pool/executor.hh"
-
-namespace launchpad {
-
-class ProcessPool : public Executor::Delegator,
-                    public Executor {
- public:
-  class IEvent {
-   public:
-    virtual ~IEvent() = default;
-    virtual void OnRequestReceived(tizen_base::Parcel* parcel) = 0;
-  };
-
-  explicit ProcessPool(std::string name, int num_processes,
-      IEvent* event_listener);
-  virtual ~ProcessPool();
-
-  bool IsPrepared() const;
-  pid_t Execute(const tizen_base::Parcel& parcel);
-  void Dispose();
-  void HandleSigchld(pid_t pid);
-  void SetTimer();
-
- private:
-  class Process {
-   public:
-    Process(pid_t pid, int fd);
-
-    pid_t GetPid() const;
-    int Send(const tizen_base::Parcel& parcel);
-    void Kill();
-
-   private:
-    pid_t pid_;
-    std::unique_ptr<Socket> socket_;
-  };
-
-  void OnExecution() override;
-  void UnsetTimer();
-  void PrepareProcess();
-  int WaitForRequest(std::unique_ptr<Socket> socket);
-  static gboolean OnTimeout(gpointer user_data);
-
- private:
-  std::string name_;
-  int num_processes_;
-  IEvent* event_listener_;
-  int pipe_fd_[2] = { -1, -1 };
-  std::vector<std::shared_ptr<Process>> queue_;
-  guint timer_ = 0;
-};
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_PROCESS_POOL_PROCESS_POOL_HH_
diff --git a/src/launchpad-process-pool/rec_mutex.hh b/src/launchpad-process-pool/rec_mutex.hh
deleted file mode 100644 (file)
index ee0cfda..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- */
-
-#ifndef LAUNCHPAD_PROCESS_POOL_REC_MUTEX_HH_
-#define LAUNCHPAD_PROCESS_POOL_REC_MUTEX_HH_
-
-#include <mutex>
-
-namespace launchpad {
-
-class RecMutex {
- public:
-  static RecMutex& GetInst() {
-    static RecMutex inst;
-    return inst;
-  }
-
-  std::recursive_mutex& GetMutex() const {
-    return mutex_;
-  }
-
- private:
-  RecMutex() = default;
-  ~RecMutex() = default;
-
- private:
-  mutable std::recursive_mutex mutex_;
-};
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_PROCESS_POOL_REC_MUTEX_HH_
index 49bfa71c12471f1135c68c73df216eee12b73464..4dbe9845a555bebf5a1257fc0e594abf8d1aa373 100644 (file)
@@ -27,6 +27,8 @@
 #include <string>
 #include <vector>
 
+#include <sigchld_manager.hh>
+
 #include "launchpad-process-pool/dbus.hh"
 #include "launchpad-process-pool/log_private.hh"
 
@@ -162,10 +164,10 @@ void SignalManager::Init() {
     return;
 
   _W("BEGIN");
-  if (BlockSigchld() != 0)
+  if (SigchldManager::BlockSigchld() != 0)
     return;
 
-  int sfd = GetSigchldFd();
+  int sfd = SigchldManager::GetSigchldFd();
   if (sfd < 0)
     return;
 
@@ -203,37 +205,10 @@ void SignalManager::SetEventListener(SignalManager::IEvent* listener) {
   listener_ = listener;
 }
 
-void SignalManager::UnblockSigchld() {
-  if (sigprocmask(SIG_SETMASK, &old_mask_, nullptr) < 0)
-    _E("sigprocmask(SIG_SETMASK) is failed. errno(%d)", errno);
-}
-
 SignalManager::~SignalManager() {
   Dispose();
 }
 
-int SignalManager::BlockSigchld() {
-  sigemptyset(&mask_);
-  sigaddset(&mask_, SIGCHLD);
-  if (sigprocmask(SIG_BLOCK, &mask_, &old_mask_) < 0) {
-    int ret = -errno;
-    _E("sigprocmask(SIG_BLOCK) is failed. errno(%d)", errno);
-    return ret;
-  }
-
-  return 0;
-}
-
-int SignalManager::GetSigchldFd() {
-  int sfd = signalfd(-1, &mask_, SFD_NONBLOCK | SFD_CLOEXEC);
-  if (sfd < 0) {
-    sfd = -errno;
-    _E("signalfd() is failed. errno(%d)", errno);
-  }
-
-  return sfd;
-}
-
 void SignalManager::HandleSigchld(pid_t pid, int status) {
   if (listener_ != nullptr)
     listener_->OnSigchldReceived(pid);
index c535ee233c5b106f28f6a2e7ed5a67ac72a11730..a5733d630b6cb03b909adb1fe2abc97bbb5c6ffb 100644 (file)
@@ -52,7 +52,6 @@ class SignalManager : public SigchldEvent::IEvent,
   void Dispose();
 
   void SetEventListener(IEvent* listener);
-  void UnblockSigchld();
 
  private:
   class SignalAction {
@@ -76,8 +75,6 @@ class SignalManager : public SigchldEvent::IEvent,
 
   void Init();
   void HandleSigchld(pid_t pid, int status);
-  int GetSigchldFd();
-  int BlockSigchld();
 
   void OnSigchld(pid_t pid, int status) override;
   void OnHydraSigchld(pid_t pid, int status) override;
@@ -89,8 +86,6 @@ class SignalManager : public SigchldEvent::IEvent,
  private:
   bool disposed_ = true;
   IEvent* listener_ = nullptr;
-  sigset_t mask_;
-  sigset_t old_mask_;
   std::unique_ptr<SigchldEvent> sigchld_event_;
   std::unique_ptr<HydraSigchldEvent> hydra_sigchld_event_;
   std::unique_ptr<Worker> recycle_bin_;
diff --git a/src/launchpad-process-pool/util.cc b/src/launchpad-process-pool/util.cc
deleted file mode 100644 (file)
index 99fd9da..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2023 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 "launchpad-process-pool/util.hh"
-
-#include <algorithm>
-#include <cctype>
-#include <regex>
-#include <utility>
-
-namespace launchpad {
-
-std::vector<std::string> Split(const std::string& str,
-  const std::string& delim) {
-  const std::regex deli("[^" + delim + "]+");
-  std::vector<std::string> result;
-  for (auto i = std::sregex_iterator(str.begin(), str.end(), deli);
-       i != std::sregex_iterator(); ++i)
-    result.push_back((*i).str());
-
-  return result;
-}
-
-std::string ToUpper(std::string str) {
-  std::string result = std::move(str);
-  std::transform(result.begin(), result.end(), result.begin(), ::toupper);
-  return result;
-}
-
-}  // namespace launchpad
diff --git a/src/launchpad-process-pool/util.hh b/src/launchpad-process-pool/util.hh
deleted file mode 100644 (file)
index b61ce76..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2023 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.
- */
-
-#ifndef LAUNCHPAD_PROCESS_POOL_UTIL_HH_
-#define LAUNCHPAD_PROCESS_POOL_UTIL_HH_
-
-#include <string>
-#include <vector>
-
-namespace launchpad {
-
-template <typename E>
-E operator|(E a, E b) {
-  return static_cast<E>(static_cast<int>(a) | static_cast<int>(b));
-}
-
-template <typename E>
-bool operator==(E a, int x) {
-  return static_cast<int>(a) == x;
-}
-
-template <typename E>
-int operator&(int a, E b) {
-  return a & static_cast<int>(b);
-}
-
-std::vector<std::string> Split(const std::string& str,
-  const std::string& delim);
-
-std::string ToUpper(std::string str);
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_PROCESS_POOL_UTIL_HH_
index 65cdaca192c4d7e0174222802f9d561c10968eca..f989536df59bcf0163187f45842212b5b4683a64 100644 (file)
@@ -1,4 +1,5 @@
 ADD_SUBDIRECTORY(launchpad)
 ADD_SUBDIRECTORY(launchpad-common)
+ADD_SUBDIRECTORY(launchpad-core)
 ADD_SUBDIRECTORY(launchpad-glib)
 ADD_SUBDIRECTORY(launchpad-hydra)
diff --git a/src/lib/launchpad-core/CMakeLists.txt b/src/lib/launchpad-core/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ab68b55
--- /dev/null
@@ -0,0 +1,41 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ LAUNCHPAD_CORE_SRCS)
+
+ADD_LIBRARY(${TARGET_LAUNCHPAD_CORE} SHARED ${LAUNCHPAD_CORE_SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_LAUNCHPAD_CORE} PROPERTIES
+  SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_LAUNCHPAD_CORE} PROPERTIES
+  VERSION ${VERSION})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_LAUNCHPAD_CORE} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/../
+)
+
+APPLY_PKG_CONFIG(${TARGET_LAUNCHPAD_CORE} PUBLIC
+  BUNDLE_DEPS
+  DBUS_DEPS
+  DLOG_DEPS
+  GIO_DEPS
+  LIBTZPLATFORM_CONFIG_DEPS
+  SECURITY_MANAGER_DEPS
+  TANCHOR_DEPS
+  VCONF_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_LAUNCHPAD_CORE} PUBLIC
+${TARGET_LAUNCHPAD_COMMON} ${TARGET_LAUNCHPAD_GLIB} "-ldl")
+
+INSTALL(TARGETS ${TARGET_LAUNCHPAD_CORE} DESTINATION ${LIB_INSTALL_DIR}
+  COMPONENT RuntimeLibraries)
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
+  DESTINATION include/launchpad-core
+  FILES_MATCHING
+  PATTERN "*_private.hh" EXCLUDE
+  PATTERN "*.hh"
+)
+
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/liblaunchpad-core.pc.in
+  ${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/liblaunchpad-core.pc @ONLY)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/liblaunchpad-core.pc
+  DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
diff --git a/src/lib/launchpad-core/app_executor.cc b/src/lib/launchpad-core/app_executor.cc
new file mode 100644 (file)
index 0000000..55be4ed
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2023 - 2024 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 "launchpad-core/app_executor.hh"
+
+#include <errno.h>
+#include <libgen.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <sys/prctl.h>
+#include <trust-anchor.h>
+#include <tzplatform_config.h>
+#include <unistd.h>
+
+#include <filesystem>
+#include <utility>
+
+#include <aul_keys.hh>
+#include <plugin.hh>
+#include <stdio.hh>
+#include <types.hh>
+#include <user_tracer.hh>
+#include <util.hh>
+
+#include "launchpad-core/debug.hh"
+#include "launchpad-core/log_private.hh"
+
+namespace launchpad {
+namespace fs = std::filesystem;
+namespace {
+
+void ExecuteEcho(const std::string& app_path, const std::string& error) {
+  char *argv[] = {
+      const_cast<char*>("/usr/bin/echo"),
+      const_cast<char*>("Failed to execute a file. path:"),
+      const_cast<char*>(app_path.c_str()),
+      const_cast<char*>("error:"),
+      const_cast<char*>(error.c_str()),
+      nullptr,
+  };
+
+  execv(argv[0], argv);
+}
+
+}  // namespace
+
+AppExecutor::AppExecutor() : Executor(this) {
+  LauncherInfoInflator inflator;
+  launcher_infos_ = inflator.Inflate("/usr/share/aul");
+
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepPluginPrepareApp, this));
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepEnableExternalPackage, this));
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepEnableTrustAnchor, this));
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepMountResDir, this));
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepChangeMountNamespace, this));
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepSecurityPrepareApp, this));
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepSetupStdio, this));
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepSetDumpable, this));
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepSetProcessName, this));
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepSetEnvironments, this));
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepWaitTepMount, this));
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepPrepareAppSocketAndIdFile, this));
+  prepare_funcs_.push_back(
+      std::bind(&AppExecutor::StepSendStartupSignal, this));
+
+  process_pool_ = std::unique_ptr<ProcessPool>(
+      new ProcessPool("app", ProcessPool::GetNumberOfProcesses(), this));
+}
+
+pid_t AppExecutor::Execute(const AppInfo* app_info) {
+  if (process_pool_->IsPrepared()) {
+    tizen_base::Parcel parcel;
+    parcel.WriteParcelable(*app_info);
+    pid_t pid = process_pool_->Execute(parcel);
+    if (pid > 0)
+      return pid;
+  }
+
+  app_info_ = app_info;
+  return Executor::Execute();
+}
+
+void AppExecutor::DisposeCandidateProcess() {
+  process_pool_->Dispose();
+  process_pool_->SetTimer();
+}
+
+void AppExecutor::HandleSigchld(pid_t pid) {
+  process_pool_->HandleSigchld(pid);
+}
+
+void AppExecutor::OnExecution() {
+  UserTracer::Print(std::to_string(getpid()) + "|after calling fork(). " +
+      app_info_->GetAppId());
+  CheckAndPrepareDebugging();
+  Util::DeleteSocketPath(getpid(), getuid());
+
+  int ret = Prepare();
+  if (ret < 0) {
+    _E("Failed to prepare executing application(%s)",
+        app_info_->GetAppId().c_str());
+    ExecuteEcho(app_info_->GetAppPath(), std::to_string(ret));
+    exit(ret);
+  }
+
+  std::vector<std::string> argv = CreateAppArgv(app_info_->GetAppPath(),
+      app_info_->GetBundle(), app_info_->GetAppType());
+  char** app_argv = static_cast<char**>(calloc(argv.size() + 1, sizeof(char*)));
+  if (app_argv == nullptr) {
+    _E("Out of memory");
+    ExecuteEcho(app_info_->GetAppPath(), std::to_string(-ENOMEM));
+    exit(-1);
+  }
+
+  int app_argc = argv.size();
+  for (int i = 0; i < app_argc; ++i) {
+    app_argv[i] = const_cast<char*>(argv[i].c_str());
+    SECURE_LOGD("input argument %d : %s##", i, app_argv[i]);
+  }
+
+  auto lib_dir = Util::GetLibDirectory(app_info_->GetAppPath());
+  if (!lib_dir.empty())
+    setenv("LD_LIBRARY_PATH", lib_dir.c_str(), 1);
+
+  Util::CloseAllFds();
+  SECURE_LOGE("Execute application(%s)", app_argv[LoaderArg::Path]);
+  if (execv(app_argv[LoaderArg::Path], app_argv) < 0) {
+    char err_buf[1024];
+    fprintf(stderr, "Failed to execute a file. path: %s, errno: %d(%s)\n",
+        app_info_->GetAppPath().c_str(), errno,
+        strerror_r(errno, err_buf, sizeof(err_buf)));
+    ExecuteEcho(app_info_->GetAppPath(), err_buf);
+    exit(EXIT_FAILURE);
+  }
+}
+
+void AppExecutor::OnRequestReceived(tizen_base::Parcel* parcel) {
+  _W("Request received");
+  AppInfo app_info;
+  parcel->ReadParcelable(&app_info);
+  app_info_ = &app_info;
+  OnExecution();
+}
+
+int AppExecutor::Prepare() {
+  for (auto& func : prepare_funcs_) {
+    if (func() != 0)
+      return -1;
+  }
+
+  return 0;
+}
+
+int AppExecutor::StepPluginPrepareApp() {
+  return Plugin::PrepareApp(app_info_->GetAppId(), app_info_->GetBundle());
+}
+
+int AppExecutor::StepEnableExternalPackage() {
+  return Util::EnableExternalPackage(app_info_);
+}
+
+int AppExecutor::StepEnableTrustAnchor() {
+  int ret = trust_anchor_launch(app_info_->GetPkgId().c_str(),
+      app_info_->IsGlobal() ? GLOBAL_USER : getuid());
+  if (ret != TRUST_ANCHOR_ERROR_NONE &&
+      ret != TRUST_ANCHOR_ERROR_NOT_INSTALLED) {
+    _E("trust_anchor_launch() returns %d", ret);
+    return -2;
+  }
+
+  return 0;
+}
+
+int AppExecutor::StepMountResDir() {
+  int ret = Util::MountGadgetDirectories(app_info_->GetBundle());
+  if (ret != 0) {
+    _E("Failed to mount gadget resources");
+    return ret;
+  }
+
+  Util::MountLibraryDirectories(app_info_->GetBundle());
+  return Util::MountResourceDirectories(app_info_);
+}
+
+int AppExecutor::StepChangeMountNamespace() {
+  if (app_info_->GetBundle().GetType(kAulSdk) != BUNDLE_TYPE_NONE)
+    Debug::ChangeMountNamespace();
+
+  return 0;
+}
+
+int AppExecutor::StepSecurityPrepareApp() {
+  auto enabled_light_user = app_info_->GetBundle().GetString(
+      kAulEnabledLightUser);
+  _W("security_manager_prepare_app2 ++ %s", app_info_->GetAppId().c_str());
+  int ret = security_manager_prepare_app2(app_info_->GetAppId().c_str(),
+      enabled_light_user.empty() ? nullptr : enabled_light_user.c_str());
+  _W("security_manager_prepare_app2 -- %s", app_info_->GetAppId().c_str());
+  if (ret != SECURITY_MANAGER_SUCCESS) {
+    _E("security_manager_prepare_app2() returns %d", ret);
+    return -2;
+  }
+
+  return 0;
+}
+
+int AppExecutor::StepSetupStdio() {
+  if (app_info_->GetBundle().GetType(kAulSdk) == BUNDLE_TYPE_NONE)
+    Stdio::Setup();
+
+  return 0;
+}
+
+int AppExecutor::StepSetDumpable() {
+  prctl(PR_SET_DUMPABLE, 1);
+  return 0;
+}
+
+int AppExecutor::StepSetProcessName() {
+  fs::path file_path(app_info_->GetAppPath());
+  fs::path file_name = file_path.filename();
+  prctl(PR_SET_NAME, file_name.c_str());
+  return 0;
+}
+
+int AppExecutor::StepSetEnvironments() {
+  Util::SetEnvironments(app_info_);
+  return 0;
+}
+
+int AppExecutor::StepWaitTepMount() {
+  return Util::WaitTepMount(app_info_);
+}
+
+int AppExecutor::StepPrepareAppSocketAndIdFile() {
+  if (app_info_->GetBundle().GetType(kAulSdk) != BUNDLE_TYPE_NONE)
+    return 0;
+
+  if (Util::PrepareAppSocket() < 0)
+    return -1;
+
+  return Util::PrepareAppIdFile(app_info_);
+}
+
+int AppExecutor::StepSendStartupSignal() {
+  Util::SendCmdToAmd(AmdCmd::AppStartupSignal);
+  return 0;
+}
+
+void AppExecutor::CheckAndPrepareDebugging() {
+  auto& debug = Debug::GetInst();
+  auto& b = app_info_->GetBundle();
+  if (b.GetType(kAulSdk) != BUNDLE_TYPE_NONE)
+    debug.PrepareDebugger(b);
+
+  debug.CheckAndSetAsanActivation(app_info_->GetAppId());
+  debug.CheckWebAppDebugging(b);
+}
+
+LauncherInfoPtr AppExecutor::FindLauncherInfo(const std::string& app_type) {
+  for (auto& info : launcher_infos_) {
+    for (auto& type : info->GetAppTypes()) {
+      if (type == app_type)
+        return info;
+    }
+  }
+
+  return nullptr;
+}
+
+std::vector<std::string> AppExecutor::GetLauncherArgv(
+  const std::string& app_type) {
+  std::vector<std::string> argv;
+  auto launcher_info = FindLauncherInfo(app_type);
+  if (launcher_info == nullptr) return argv;
+
+  argv.insert(argv.end(), launcher_info->GetExe());
+  argv.insert(argv.end(), launcher_info->GetExtraArgs().begin(),
+      launcher_info->GetExtraArgs().end());
+  return argv;
+}
+
+std::vector<std::string> AppExecutor::CreateAppArgv(const std::string& app_path,
+    const tizen_base::Bundle& b, const std::string& app_type) {
+  auto& inst = launchpad::Debug::GetInst();
+  std::vector<std::string> argv = inst.GetArgv();
+  if (inst.ShouldAttach())
+    return argv;
+
+  bool debug_mode = !argv.empty() ? true : false;
+  auto launcher_argv = GetLauncherArgv(app_type);
+  if (!launcher_argv.empty())
+    argv.insert(argv.end(), launcher_argv.begin(), launcher_argv.end());
+
+  auto exported_argv = b.Export();
+  exported_argv[LoaderArg::Path] = app_path;
+  if (debug_mode &&
+      exported_argv.size() > static_cast<size_t>(LoaderArg::Type))
+    exported_argv[LoaderArg::Type] = "'" + exported_argv[LoaderArg::Type] + "'";
+
+  if (!exported_argv.empty())
+    argv.insert(argv.end(), exported_argv.begin(), exported_argv.end());
+
+  auto extra_argv = inst.GetExtraArgv();
+  if (!extra_argv.empty())
+    argv.insert(argv.end(), extra_argv.begin(), extra_argv.end());
+
+  return argv;
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/app_executor.hh b/src/lib/launchpad-core/app_executor.hh
new file mode 100644 (file)
index 0000000..5b0f63f
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2023 - 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_APP_EXECUTOR_HH_
+#define LIB_LAUNCHPAD_CORE_APP_EXECUTOR_HH_
+
+#include <bundle_cpp.h>
+
+#include <functional>
+#include <string>
+#include <vector>
+#include <memory>
+
+#include <app_info.hh>
+
+#include "launchpad-core/executor.hh"
+#include "launchpad-core/launcher_info.hh"
+#include "launchpad-core/process_pool.hh"
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API AppExecutor : public Executor::Delegator,
+                               public Executor,
+                               public ProcessPool::IEvent {
+ public:
+  AppExecutor();
+
+  pid_t Execute(const AppInfo* app_info);
+  void DisposeCandidateProcess();
+  void HandleSigchld(pid_t pid);
+
+ private:
+  void OnExecution() override;
+  void OnRequestReceived(tizen_base::Parcel* parcel) override;
+
+  int Prepare();
+  int StepPluginPrepareApp();
+  int StepEnableExternalPackage();
+  int StepEnableTrustAnchor();
+  int StepMountResDir();
+  int StepChangeMountNamespace();
+  int StepSecurityPrepareApp();
+  int StepSetupStdio();
+  int StepSetDumpable();
+  int StepSetProcessName();
+  int StepSetEnvironments();
+  int StepWaitTepMount();
+  int StepPrepareAppSocketAndIdFile();
+  int StepSendStartupSignal();
+
+  void CheckAndPrepareDebugging();
+  std::vector<std::string> GetLauncherArgv(const std::string& app_type);
+  std::vector<std::string> CreateAppArgv(const std::string& app_path,
+      const tizen_base::Bundle& b, const std::string& app_type);
+  LauncherInfoPtr FindLauncherInfo(const std::string& app_type);
+
+ private:
+  using PrepareFunc = std::function<int()>;
+
+  std::vector<LauncherInfoPtr> launcher_infos_;
+  std::vector<PrepareFunc> prepare_funcs_;
+  std::unique_ptr<ProcessPool> process_pool_;
+  const AppInfo* app_info_ = nullptr;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_APP_EXECUTOR_HH_
diff --git a/src/lib/launchpad-core/debug.cc b/src/lib/launchpad-core/debug.cc
new file mode 100644 (file)
index 0000000..741f416
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2023 - 2024 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 "launchpad-core/debug.hh"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <fstream>
+#include <utility>
+
+#include <aul_keys.hh>
+#include <exception.hh>
+
+#include "launchpad-core/log_private.hh"
+
+namespace fs = std::filesystem;
+
+namespace launchpad {
+namespace {
+
+constexpr const char kOptUsrShareAulDebugPath[] = "/opt/usr/share/aul/debug";
+constexpr const char kAsanAppList[] = ".asan_app_list";
+constexpr const char kAsanAppListPath[] =
+    "/opt/usr/share/aul/debug/.asan_app_list";
+constexpr const char kDebuggerInfoPath[] = "/usr/share/aul";
+
+std::vector<std::string> GetStringArray(const tizen_base::Bundle& b,
+    const std::string& key) {
+  std::vector<std::string> values;
+  if (b.GetType(key) & BUNDLE_TYPE_ARRAY) {
+    values = b.GetStringArray(key);
+  } else {
+    std::string value = b.GetString(key);
+    if (!value.empty())
+      values.push_back(std::move(value));
+  }
+
+  return values;
+}
+
+}  // namespace
+
+Debug& Debug::GetInst() {
+  static Debug inst;
+  inst.Init();
+  return inst;
+}
+
+void Debug::Dispose() {
+  if (disposed_)
+    return;
+
+  file_monitor_.reset();
+  disposed_ = true;
+}
+
+bool Debug::Load() {
+  if (!debugger_infos_.empty())
+    return false;
+
+  DebuggerInfoInflator inflator;
+  debugger_infos_ = inflator.Inflate(kDebuggerInfoPath);
+  return true;
+}
+
+void Debug::PrepareDebugger(const tizen_base::Bundle& b) {
+  auto debugger = b.GetString(kAulSdk);
+  if (debugger.empty())
+    return;
+
+  _D("[DEBUG] Debugger: %s", debugger.c_str());
+  auto found = debugger_infos_.find(debugger);
+  if (found == debugger_infos_.end()) {
+    _W("Failed to find debugger(%s)", debugger.c_str());
+    return;
+  }
+
+  debugger_info_ = found->second;
+  if (debugger == "ASAN")
+    setenv("TIZEN_ASAN_ACTIVATION", "1", 1);
+
+  ParseAndRedirectStandardFds(b);
+  RemoveFiles(debugger_info_->GetUnlinkList());
+
+  for (const auto& extra_env : debugger_info_->GetExtraEnvList())
+    ParseAndSetEnvironment(b, extra_env);
+
+  debug_argv_ = debugger_info_->GetDefaultOptList();
+  if (!debugger_info_->GetExe().empty())
+    debug_argv_.insert(debug_argv_.begin(), debugger_info_->GetExe());
+
+  for (const auto& extra_key : debugger_info_->GetExtraKeyList())
+    ParseAndAddArgv(b, extra_key);
+
+  for (const auto& last_extra_key : debugger_info_->GetLastExtraKeyList())
+    ParseAndAddExtraArgv(b, last_extra_key);
+}
+
+void Debug::ChangeMountNamespace() {
+  auto target_pid = std::getenv("TARGET_PID");
+  if (target_pid == nullptr)
+    return;
+
+  std::string mnt_path = "/proc/" + std::string(target_pid) + "/ns/mnt";
+  int fd = open(mnt_path.c_str(), O_RDONLY);
+  if (fd < 0) {
+    _E("open() is failed. path(%s), errno(%d)", mnt_path.c_str(), errno);
+    return;
+  }
+
+  int ret = ::setns(fd, CLONE_NEWNS);
+  close(fd);
+  if (ret != 0) {
+    _E("setns() is failed. errno(%d)", errno);
+    return;
+  }
+
+  _D("setns() is successful");
+}
+
+void Debug::CheckWebAppDebugging(const tizen_base::Bundle& b) {
+  if (b.GetType(kAulDebug) != BUNDLE_TYPE_NONE)
+    setenv("TIZEN_DEBUGGING_PORT", "1", 1);
+}
+
+bool Debug::CheckAsanApp(const std::string& appid) {
+  return asan_app_map_.find(appid) != asan_app_map_.end();
+}
+
+void Debug::CheckAndSetAsanActivation(const std::string& appid) {
+  if (CheckAsanApp(appid)) {
+    _W("Set TIZEN_ASAN_ACTIVATION. appid: %s", appid.c_str());
+    setenv("TIZEN_ASAN_ACTIVATION", "1", 1);
+  }
+}
+
+std::vector<std::string> Debug::GetExtraArgv() const {
+  return extra_argv_;
+}
+
+std::vector<std::string> Debug::GetArgv() const {
+  return debug_argv_;
+}
+
+bool Debug::ShouldAttach() const {
+  if (!debugger_info_)
+    return false;
+
+  return debugger_info_->GetAttachInfo() == "true";
+}
+
+Debug::~Debug() {
+  Dispose();
+}
+
+void Debug::Init() {
+  if (!disposed_)
+    return;
+
+  try {
+    file_monitor_ = std::make_unique<FileMonitor>(
+        kOptUsrShareAulDebugPath, this);
+  } catch (const Exception& e) {
+    _E("Exception occurs. error: %s", e.what());
+    return;
+  }
+
+  if (fs::exists(kAsanAppListPath))
+    LoadAsanAppList();
+
+  disposed_ = false;
+}
+
+void Debug::RemoveFiles(const std::vector<std::string>& files) {
+  for (const auto& file : files) {
+    if (fs::exists(file)) {
+      _D("[DEBUG] file: %s", file.c_str());
+      fs::remove(file);
+    }
+  }
+}
+
+void Debug::ParseAndSetEnvironment(const tizen_base::Bundle& b,
+    const std::string& key) {
+  _D("[DEBUG] key: %s", key.c_str());
+  std::vector<std::string> values = GetStringArray(b, key);
+  if (values.empty())
+    return;
+
+  std::string env;
+  for (const auto& value : values) {
+    if (!env.empty())
+      env += ",";
+
+    env += value;
+  }
+
+  const_cast<tizen_base::Bundle&>(b).Delete(key);
+  _D("[DEBUG] value: %s", env.c_str());
+  setenv(key.c_str(), env.c_str(), 1);
+}
+
+void Debug::ParseAndAddArgv(const tizen_base::Bundle& b,
+    const std::string& key) {
+  _D("[DEBUG] key: %s", key.c_str());
+  std::vector<std::string> values = GetStringArray(b, key);
+  if (values.empty())
+    return;
+
+  for (const auto& arg : values) {
+    debug_argv_.push_back(arg);
+    if (key == "__DLP_ATTACH_ARG__" && isdigit(arg[0])) {
+      _D("[DEBUG] TARGET_PID: %s", arg.c_str());
+      setenv("TARGET_PID", arg.c_str(), 1);
+    }
+  }
+
+  const_cast<tizen_base::Bundle&>(b).Delete(key);
+}
+
+void Debug::ParseAndAddExtraArgv(const tizen_base::Bundle& b,
+    const std::string& key) {
+  _D("[DEBUG] key: %s", key.c_str());
+  std::vector<std::string> values = GetStringArray(b, key);
+  if (values.empty()) return;
+
+  for (const auto& arg : values)
+    extra_argv_.push_back(arg);
+
+  const_cast<tizen_base::Bundle&>(b).Delete(key);
+}
+
+void Debug::ParseAndRedirectStandardFds(const tizen_base::Bundle& b) {
+  pid_t caller_pid = GetCallerPid(b);
+  if (caller_pid < 0)
+    return;
+
+  // stdin
+  std::string path = "/proc/" + std::to_string(caller_pid) + "/fd/";
+  int fd = open((path + std::to_string(STDIN_FILENO)).c_str(), O_RDONLY);
+  if (fd < 0) {
+    _E("Failed to open STDIN file descriptor. errno(%d)", errno);
+    return;
+  }
+
+  dup2(fd, STDIN_FILENO);
+  close(fd);
+
+  // stdout
+  fd = open((path + std::to_string(STDOUT_FILENO)).c_str(), O_WRONLY);
+  if (fd < 0) {
+    _E("Failed to open STDOUT file descriptor. errno(%d)", errno);
+    return;
+  }
+
+  dup2(fd, STDOUT_FILENO);
+  close(fd);
+
+  // stdout
+  fd = open((path + std::to_string(STDERR_FILENO)).c_str(), O_WRONLY);
+  if (fd < 0) {
+    _E("Failed to open STDERR file descriptor. errno(%d)", errno);
+    return;
+  }
+
+  dup2(fd, STDERR_FILENO);
+  close(fd);
+}
+
+pid_t Debug::GetCallerPid(const tizen_base::Bundle& b) {
+  auto pid_str = b.GetString(kAulOrgCallerPid);
+  if (pid_str.empty())
+    pid_str = b.GetString(kAulCallerPid);
+
+  if (pid_str.empty())
+    return -1;
+
+  return std::stoi(pid_str);
+}
+
+void Debug::LoadAsanAppList() {
+  asan_app_map_.clear();
+  std::ifstream if_stream;
+  if_stream.open(kAsanAppListPath);
+  if (!if_stream.is_open()) {
+    _E("Failed to open %s", kAsanAppListPath);
+    return;
+  }
+
+  std::string appid;
+  while (!if_stream.eof()) {
+    if_stream >> appid;
+    asan_app_map_.insert(std::move(appid));
+  }
+}
+
+void Debug::OnFileChanged(const std::string_view name,
+    FileMonitor::Event event) {
+  if (name != kAsanAppList)
+    return;
+
+  _W("%s was changed. event(%d)", kAsanAppList, static_cast<int>(event));
+  LoadAsanAppList();
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/debug.hh b/src/lib/launchpad-core/debug.hh
new file mode 100644 (file)
index 0000000..ba9083c
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2023 - 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_DEBUG_HH_
+#define LIB_LAUNCHPAD_CORE_DEBUG_HH_
+
+#include <bundle_cpp.h>
+
+#include <list>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include <debugger_info.hh>
+#include <file_monitor.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API Debug : public FileMonitor::IEvent {
+ public:
+  Debug(const Debug&) = delete;
+  Debug& operator = (const Debug&) = delete;
+  Debug(Debug&&) = delete;
+  Debug& operator = (Debug&&) = delete;
+
+  static Debug& GetInst();
+  void Init();
+  void Dispose();
+  bool Load();
+  void PrepareDebugger(const tizen_base::Bundle& b);
+  std::vector<std::string> GetExtraArgv() const;
+  std::vector<std::string> GetArgv() const;
+  bool ShouldAttach() const;
+  bool CheckAsanApp(const std::string& appid);
+  void CheckAndSetAsanActivation(const std::string& appid);
+
+  static void ChangeMountNamespace();
+  static void CheckWebAppDebugging(const tizen_base::Bundle& b);
+
+ private:
+  Debug() = default;
+  ~Debug();
+
+  void RemoveFiles(const std::vector<std::string>& files);
+  void ParseAndSetEnvironment(
+      const tizen_base::Bundle& b, const std::string& key);
+  void ParseAndAddArgv(const tizen_base::Bundle& b, const std::string& key);
+  void ParseAndAddExtraArgv(const tizen_base::Bundle& b,
+      const std::string& key);
+  void ParseAndRedirectStandardFds(const tizen_base::Bundle& b);
+  pid_t GetCallerPid(const tizen_base::Bundle& b);
+
+  void LoadAsanAppList();
+  void OnFileChanged(const std::string_view name,
+      FileMonitor::Event event) override;
+
+ private:
+  bool disposed_ = true;
+  DebuggerInfoPtr debugger_info_;
+  std::unordered_map<std::string, DebuggerInfoPtr> debugger_infos_;
+  std::vector<std::string> debug_argv_;
+  std::vector<std::string> extra_argv_;
+  std::unordered_set<std::string> asan_app_map_;
+  std::unique_ptr<launchpad::FileMonitor> file_monitor_;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_DEBUG_HH_
diff --git a/src/lib/launchpad-core/debugger_info.cc b/src/lib/launchpad-core/debugger_info.cc
new file mode 100644 (file)
index 0000000..4c06962
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2023 - 2024 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 "launchpad-core/debugger_info.hh"
+
+#include <dirent.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+#include <utility>
+
+#include <util.hh>
+
+#include "launchpad-core/log_private.hh"
+
+namespace launchpad {
+namespace {
+
+constexpr const char kTagDebugger[] = "[DEBUGGER]";
+constexpr const char kTagName[] = "NAME";
+constexpr const char kTagExe[] = "EXE";
+constexpr const char kTagAppType[] = "APP_TYPE";
+constexpr const char kTagExtraKey[] = "EXTRA_KEY";
+constexpr const char kTagExtraEnv[] = "EXTRA_ENV";
+constexpr const char kTagUnlink[] = "UNLINK";
+constexpr const char kTagAttach[] = "ATTACH";
+constexpr const char kTagLastExtraKey[] = "LAST_EXTRA_KEY";
+constexpr const char kTagDefaultOpt[] = "DEFAULT_OPT";
+
+}  // namespace
+
+namespace fs = std::filesystem;
+
+DebuggerInfo::Builder& DebuggerInfo::Builder::SetName(std::string name) {
+  name_ = std::move(name);
+  return *this;
+}
+
+DebuggerInfo::Builder& DebuggerInfo::Builder::SetExe(std::string exe) {
+  exe_ = std::move(exe);
+  return *this;
+}
+
+DebuggerInfo::Builder& DebuggerInfo::Builder::AddAppType(std::string app_type) {
+  app_types_.push_back(std::move(app_type));
+  return *this;
+}
+
+DebuggerInfo::Builder& DebuggerInfo::Builder::AddExtraKey(
+  std::string extra_key) {
+  extra_keys_.push_back(std::move(extra_key));
+  return *this;
+}
+DebuggerInfo::Builder& DebuggerInfo::Builder::AddExtraEnv(
+    std::string extra_env) {
+  extra_envs_.push_back(std::move(extra_env));
+  return *this;
+}
+
+DebuggerInfo::Builder& DebuggerInfo::Builder::AddFileToDelete(
+  std::string file) {
+  delete_files_.push_back(std::move(file));
+  return *this;
+}
+
+DebuggerInfo::Builder& DebuggerInfo::Builder::SetAttach(std::string attach) {
+  attach_ = std::move(attach);
+  return *this;
+}
+
+DebuggerInfo::Builder& DebuggerInfo::Builder::AddLastExtraKey(
+    std::string last_extra_key) {
+  last_extra_keys_.push_back(std::move(last_extra_key));
+  return *this;
+}
+
+DebuggerInfo::Builder& DebuggerInfo::Builder::AddDefaultOpt(
+    std::string default_opt) {
+  default_opts_.push_back(std::move(default_opt));
+  return *this;
+}
+
+DebuggerInfo::Builder& DebuggerInfo::Builder::Reset() {
+  name_.clear();
+  exe_.clear();
+  app_types_.clear();
+  extra_keys_.clear();
+  extra_envs_.clear();
+  delete_files_.clear();
+  attach_.clear();
+  last_extra_keys_.clear();
+  default_opts_.clear();
+  return *this;
+}
+
+DebuggerInfo* DebuggerInfo::Builder::Build() {
+  return new DebuggerInfo(std::move(name_), std::move(exe_),
+      std::move(app_types_), std::move(extra_keys_), std::move(extra_envs_),
+      std::move(delete_files_), std::move(attach_),
+      std::move(last_extra_keys_), std::move(default_opts_));
+}
+
+DebuggerInfo::DebuggerInfo(std::string name, std::string exe,
+    std::vector<std::string> app_types,
+    std::vector<std::string> extra_keys,
+    std::vector<std::string> extra_envs,
+    std::vector<std::string> delete_files,
+    std::string attach,
+    std::vector<std::string> last_extra_keys,
+    std::vector<std::string> default_opts)
+    : name_(std::move(name)),
+      exe_(std::move(exe)),
+      app_types_(std::move(app_types)),
+      extra_keys_(std::move(extra_keys)),
+      extra_envs_(std::move(extra_envs)),
+      delete_files_(std::move(delete_files)),
+      attach_(std::move(attach)),
+      last_extra_keys_(std::move(last_extra_keys)),
+      default_opts_(std::move(default_opts)) {}
+
+const std::string& DebuggerInfo::GetName() const {
+  return name_;
+}
+
+const std::string& DebuggerInfo::GetExe() const {
+  return exe_;
+}
+
+const std::vector<std::string>& DebuggerInfo::GetAppTypes() const {
+  return app_types_;
+}
+
+const std::vector<std::string>& DebuggerInfo::GetExtraKeyList() const {
+  return extra_keys_;
+}
+
+const std::vector<std::string>& DebuggerInfo::GetExtraEnvList() const {
+  return extra_envs_;
+}
+
+const std::vector<std::string>& DebuggerInfo::GetUnlinkList() const {
+  return delete_files_;
+}
+
+const std::string& DebuggerInfo::GetAttachInfo() const {
+  return attach_;
+}
+
+const std::vector<std::string>& DebuggerInfo::GetLastExtraKeyList() const {
+  return last_extra_keys_;
+}
+
+const std::vector<std::string>& DebuggerInfo::GetDefaultOptList() const {
+  return default_opts_;
+}
+
+DebuggerInfoInflator::DebuggerInfoInflator() {
+  parsers_ = {
+    { kTagName,
+      std::bind(&DebuggerInfoInflator::ParseName,
+          this, std::placeholders::_1) },
+    { kTagExe,
+      std::bind(&DebuggerInfoInflator::ParseExe,
+          this, std::placeholders::_1) },
+    { kTagAppType,
+      std::bind(&DebuggerInfoInflator::ParseAppType,
+          this, std::placeholders::_1) },
+    { kTagExtraKey,
+      std::bind(&DebuggerInfoInflator::ParseExtraKey,
+          this, std::placeholders::_1) },
+    { kTagExtraEnv,
+      std::bind(&DebuggerInfoInflator::ParseExtraEnv,
+          this, std::placeholders::_1) },
+    { kTagUnlink,
+      std::bind(&DebuggerInfoInflator::ParseUnlink,
+          this, std::placeholders::_1) },
+    { kTagAttach,
+      std::bind(&DebuggerInfoInflator::ParseAttach,
+          this, std::placeholders::_1) },
+    { kTagLastExtraKey,
+      std::bind(&DebuggerInfoInflator::ParseLastExtraKey,
+          this, std::placeholders::_1) },
+    { kTagDefaultOpt,
+      std::bind(&DebuggerInfoInflator::ParseDefaultOpt,
+          this, std::placeholders::_1) },
+  };
+}
+
+std::unordered_map<std::string, DebuggerInfoPtr>
+DebuggerInfoInflator::Inflate(const std::string_view path) {
+  fs::path input_path(path);
+  if (fs::is_directory(input_path) == false)
+    return debugger_infos_;
+
+  try {
+    for (auto& entry : fs::directory_iterator(input_path)) {
+      fs::path file(entry.path());
+      if (file.extension() == ".debugger")
+        Parse(file);
+    }
+  } catch (const fs::filesystem_error& e) {
+    _E("Exception occurs. error(%s:%d)", e.what(), e.code().value());
+  }
+
+  return debugger_infos_;
+}
+
+void DebuggerInfoInflator::ParseName(std::string token) {
+  builder_.SetName(std::move(token));
+}
+
+void DebuggerInfoInflator::ParseExe(std::string token) {
+  builder_.SetExe(std::move(token));
+}
+
+void DebuggerInfoInflator::ParseAppType(std::string token) {
+  std::string line = std::move(token);
+  do {
+    auto tokens = Util::Split(line, " |\t\r\n");
+    for (auto& app_type : tokens) {
+      _D("app-type: %s", app_type.c_str());
+      builder_.AddAppType(app_type);
+    }
+  } while (std::getline(string_stream_, line));
+}
+
+void DebuggerInfoInflator::ParseExtraKey(std::string token) {
+  builder_.AddExtraKey(std::move(token));
+}
+
+void DebuggerInfoInflator::ParseExtraEnv(std::string token) {
+  builder_.AddExtraEnv(std::move(token));
+}
+
+void DebuggerInfoInflator::ParseUnlink(std::string token) {
+  builder_.AddFileToDelete(std::move(token));
+}
+
+void DebuggerInfoInflator::ParseAttach(std::string token) {
+  builder_.SetAttach(std::move(token));
+}
+
+void DebuggerInfoInflator::ParseLastExtraKey(std::string token) {
+  builder_.AddLastExtraKey(std::move(token));
+}
+
+void DebuggerInfoInflator::ParseDefaultOpt(std::string token) {
+  builder_.AddDefaultOpt(std::move(token));
+}
+
+void DebuggerInfoInflator::Parse(const fs::path& path) {
+  std::ifstream input_file(path);
+  if (!input_file.is_open())
+    return;
+
+  bool parsing = false;
+  std::string input;
+  while (std::getline(input_file, input)) {
+    string_stream_ = std::istringstream(input);
+    std::string token1;
+    if (!(string_stream_ >> token1))
+      continue;
+
+    std::string key = Util::ToUpper(std::move(token1));
+    if (key == kTagDebugger) {
+      if (parsing)
+        InsertDebuggerInfo(std::shared_ptr<DebuggerInfo>(builder_.Build()));
+
+      builder_.Reset();
+      parsing = true;
+      continue;
+    }
+
+    if (parsing == false)
+      continue;
+
+    std::string token2;
+    if (!(string_stream_ >> token2))
+      continue;
+
+    auto found = parsers_.find(key);
+    if (found == parsers_.end())
+      continue;
+
+    auto& parser = found->second;
+    parser(std::move(token2));
+  }
+
+  if (parsing)
+    InsertDebuggerInfo(std::shared_ptr<DebuggerInfo>(builder_.Build()));
+
+  input_file.close();
+}
+
+void DebuggerInfoInflator::InsertDebuggerInfo(DebuggerInfoPtr info) {
+  if (debugger_infos_.find(info->name_) != debugger_infos_.end())
+    return;
+
+  _D("name: %s, exe: %s", info->name_.c_str(), info->exe_.c_str());
+  std::string name = info->name_;
+  debugger_infos_[std::move(name)] = std::move(info);
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/debugger_info.hh b/src/lib/launchpad-core/debugger_info.hh
new file mode 100644 (file)
index 0000000..5e30ff5
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2023 - 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_DEBUGGER_INFO_HH_
+#define LIB_LAUNCHPAD_CORE_DEBUGGER_INFO_HH_
+
+#include <filesystem>
+#include <functional>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <vector>
+
+namespace launchpad {
+
+class DebuggerInfo {
+ public:
+  class Builder {
+   public:
+    Builder& SetName(std::string name);
+    Builder& SetExe(std::string exe);
+    Builder& AddAppType(std::string app_type);
+    Builder& AddExtraKey(std::string extra_key);
+    Builder& AddExtraEnv(std::string extra_env);
+    Builder& AddFileToDelete(std::string file);
+    Builder& SetAttach(std::string attach);
+    Builder& AddLastExtraKey(std::string last_extra_key);
+    Builder& AddDefaultOpt(std::string default_opt);
+    Builder& Reset();
+
+    DebuggerInfo* Build();
+
+   private:
+    std::string name_;
+    std::string exe_;
+    std::vector<std::string> app_types_;
+    std::vector<std::string> extra_keys_;
+    std::vector<std::string> extra_envs_;
+    std::vector<std::string> delete_files_;
+    std::string attach_;
+    std::vector<std::string> last_extra_keys_;
+    std::vector<std::string> default_opts_;
+  };
+
+  DebuggerInfo(std::string name, std::string exe,
+      std::vector<std::string> app_types,
+      std::vector<std::string> extra_keys,
+      std::vector<std::string> extra_envs,
+      std::vector<std::string> delete_files,
+      std::string attach,
+      std::vector<std::string> last_extra_keys,
+      std::vector<std::string> default_opts);
+
+  const std::string& GetName() const;
+  const std::string& GetExe() const;
+  const std::vector<std::string>& GetAppTypes() const;
+  const std::vector<std::string>& GetExtraKeyList() const;
+  const std::vector<std::string>& GetExtraEnvList() const;
+  const std::vector<std::string>& GetUnlinkList() const;
+  const std::string& GetAttachInfo() const;
+  const std::vector<std::string>& GetLastExtraKeyList() const;
+  const std::vector<std::string>& GetDefaultOptList() const;
+
+ private:
+  std::string name_;
+  std::string exe_;
+  std::vector<std::string> app_types_;
+  std::vector<std::string> extra_keys_;
+  std::vector<std::string> extra_envs_;
+  std::vector<std::string> delete_files_;
+  std::string attach_;
+  std::vector<std::string> last_extra_keys_;
+  std::vector<std::string> default_opts_;
+
+  friend class DebuggerInfoInflator;
+};
+
+using DebuggerInfoPtr = std::shared_ptr<DebuggerInfo>;
+
+class DebuggerInfoInflator {
+ public:
+  DebuggerInfoInflator();
+
+  std::unordered_map<std::string, DebuggerInfoPtr> Inflate(
+      const std::string_view path);
+
+ private:
+  void ParseName(std::string token);
+  void ParseExe(std::string token);
+  void ParseAppType(std::string token);
+  void ParseExtraKey(std::string token);
+  void ParseExtraEnv(std::string token);
+  void ParseUnlink(std::string token);
+  void ParseAttach(std::string token);
+  void ParseLastExtraKey(std::string token);
+  void ParseDefaultOpt(std::string token);
+  void Parse(const std::filesystem::path& path);
+
+  void InsertDebuggerInfo(DebuggerInfoPtr info);
+
+ private:
+  std::unordered_map<std::string, std::function<void(std::string)>> parsers_;
+  std::unordered_map<std::string, DebuggerInfoPtr> debugger_infos_;
+  std::istringstream string_stream_;
+  DebuggerInfo::Builder builder_;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_DEBUGGER_INFO_HH_
diff --git a/src/lib/launchpad-core/executor.cc b/src/lib/launchpad-core/executor.cc
new file mode 100644 (file)
index 0000000..359ce82
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2023 - 2024 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 "launchpad-core/executor.hh"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sched_priority.hh>
+
+#include "launchpad-core/log_private.hh"
+#include "launchpad-core/sigchld_manager.hh"
+
+namespace launchpad {
+
+Executor::Executor(Executor::Delegator* delegator) : delegator_(delegator) {}
+
+pid_t Executor::Execute(int priority) {
+  pid_t pid = fork();
+  if (pid == -1) {
+    _E("Failed to create child process. errno(%d)", errno);
+    return -1;
+  }
+
+  if (pid == 0) {
+    setsid();
+    if (priority != 0)
+      SchedPriority::Set(priority);
+
+    SigchldManager::UnblockSigchld();
+
+    _W("security_manager_prepare_app_candidate ++");
+    int ret = security_manager_prepare_app_candidate();
+    _W("security_manager_prepare_app_candidate --");
+    if (ret != SECURITY_MANAGER_SUCCESS) {
+      _E("Failed to prepare app candidate process. error(%d)", ret);
+      exit(1);
+    }
+
+    delegator_->OnExecution();
+  }
+
+  return pid;
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/executor.hh b/src/lib/launchpad-core/executor.hh
new file mode 100644 (file)
index 0000000..8b314ca
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2023 - 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_EXECUTOR_HH_
+#define LIB_LAUNCHPAD_CORE_EXECUTOR_HH_
+
+#include <security-manager.h>
+#include <sys/types.h>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API Executor {
+ public:
+  class EXPORT_API Delegator {
+   public:
+    virtual ~Delegator() = default;
+    virtual void OnExecution() = 0;
+  };
+
+  explicit Executor(Delegator* delegator);
+  virtual ~Executor() = default;
+
+  pid_t Execute(int priority = 0);
+
+ private:
+  Delegator* delegator_;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_EXECUTOR_HH_
diff --git a/src/lib/launchpad-core/file_monitor.cc b/src/lib/launchpad-core/file_monitor.cc
new file mode 100644 (file)
index 0000000..2b212ee
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2023 - 2024 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 "launchpad-core/file_monitor.hh"
+
+#include <errno.h>
+
+#include <exception.hh>
+
+#include "launchpad-core/log_private.hh"
+
+namespace launchpad {
+
+namespace fs = std::filesystem;
+
+void FileMonitor::OnIOEventReceived(int fd, int condition) {
+  alignas(struct inotify_event) char buf[4096];
+  const struct inotify_event* event;
+  ssize_t len;
+  while ((len = read(fd, buf, sizeof(buf))) > 0) {
+    for (const char* ptr = buf; ptr < buf + len;
+         ptr += sizeof(struct inotify_event) + event->len) {
+      event = reinterpret_cast<const struct inotify_event*>(ptr);
+      const char* nptr = ptr + sizeof(struct inotify_event) + event->len;
+      if (nptr > buf + len)
+        break;
+
+      if (event->len) {
+        if (listener_) {
+          if (event->mask & IN_CREATE)
+            listener_->OnFileChanged(event->name, Event::Created);
+          else if (event->mask & IN_MODIFY)
+            listener_->OnFileChanged(event->name, Event::Modified);
+          else if (event->mask & IN_DELETE)
+            listener_->OnFileChanged(event->name, Event::Deleted);
+        }
+      }
+    }
+  }
+}
+
+FileMonitor::FileMonitor(const std::string_view path,
+    FileMonitor::IEvent* listener)
+    : path_(path), listener_(listener) {
+  if (!fs::exists(path_)) {
+    try {
+      if (!fs::create_directories(path_)) {
+        _E("Failed to create directory. %s", path_.c_str());
+        THROW(-EIO);
+      }
+    } catch (const std::exception& e) {
+      _E("Exception has been occurred: %s", e.what());
+      THROW(-EIO);
+    }
+  }
+
+  int fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
+  if (fd < 0) {
+    int error_code = -errno;
+    _E("inotify_init1() is failed. errno: %d", errno);
+    THROW(error_code);
+  }
+
+  int wd = inotify_add_watch(fd, path_.c_str(),
+      IN_CREATE | IN_MODIFY | IN_DELETE);
+  if (wd < 0) {
+    int error_code = -errno;
+    _E("inotify_add_watch() is failed. errno: %d", errno);
+    close(fd);
+    THROW(error_code);
+  }
+
+  channel_ = std::make_unique<IOChannel>(fd, G_IO_IN, this);
+  wd_ = wd;
+  fd_ = fd;
+}
+
+FileMonitor::~FileMonitor() {
+  channel_.reset();
+
+  if (wd_ > 0)
+    inotify_rm_watch(fd_, wd_);
+
+  if (fd_ > 0)
+    close(fd_);
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/file_monitor.hh b/src/lib/launchpad-core/file_monitor.hh
new file mode 100644 (file)
index 0000000..66d59d9
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023 - 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_FILE_MONITOR_HH_
+#define LIB_LAUNCHPAD_CORE_FILE_MONITOR_HH_
+
+#include <sys/inotify.h>
+
+#include <filesystem>
+#include <memory>
+#include <string_view>
+
+#include <io_channel.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API FileMonitor : public IOChannel::IEvent {
+ public:
+  enum class Event : int {
+    Created = IN_CREATE,
+    Modified = IN_MODIFY,
+    Deleted = IN_DELETE,
+  };
+
+  class IEvent {
+   public:
+    virtual ~IEvent() = default;
+    virtual void OnFileChanged(const std::string_view name, Event event) = 0;
+  };
+
+  FileMonitor(const std::string_view path, IEvent *listener);
+  virtual ~FileMonitor();
+
+  FileMonitor(const FileMonitor &) = delete;
+  FileMonitor &operator=(const FileMonitor &) = delete;
+
+ private:
+  void OnIOEventReceived(int fd, int condition) override;
+
+ private:
+  std::filesystem::path path_;
+  IEvent *listener_;
+  int fd_ = 0;
+  int wd_ = 0;
+  std::unique_ptr<IOChannel> channel_;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_FILE_MONITOR_HH_
diff --git a/src/lib/launchpad-core/launcher_info.cc b/src/lib/launchpad-core/launcher_info.cc
new file mode 100644 (file)
index 0000000..1b3816e
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2023 - 2024 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 "launchpad-core/launcher_info.hh"
+
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+#include <utility>
+
+#include <util.hh>
+
+#include "launchpad-core/log_private.hh"
+
+namespace launchpad {
+namespace {
+
+constexpr const char kTagLauncher[] = "[LAUNCHER]";
+constexpr const char kTagName[] = "NAME";
+constexpr const char kTagExe[] = "EXE";
+constexpr const char kTagAppType[] = "APP_TYPE";
+constexpr const char kTagExtraArg[] = "EXTRA_ARG";
+
+}  // namespace
+
+namespace fs = std::filesystem;
+
+LauncherInfo::Builder& LauncherInfo::Builder::SetName(std::string name) {
+  name_ = std::move(name);
+  return *this;
+}
+
+LauncherInfo::Builder& LauncherInfo::Builder::SetExe(std::string exe) {
+  exe_ = std::move(exe);
+  return *this;
+}
+
+LauncherInfo::Builder& LauncherInfo::Builder::AddAppType(std::string app_type) {
+  app_types_.push_back(std::move(app_type));
+  return *this;
+}
+
+LauncherInfo::Builder& LauncherInfo::Builder::AddExtraArg(
+  std::string extra_arg) {
+  extra_args_.push_back(std::move(extra_arg));
+  return *this;
+}
+
+LauncherInfo::Builder& LauncherInfo::Builder::Reset() {
+  name_.clear();
+  exe_.clear();
+  app_types_.clear();
+  extra_args_.clear();
+  return *this;
+}
+
+LauncherInfo* LauncherInfo::Builder::Build() {
+  return new LauncherInfo(std::move(name_), std::move(exe_),
+      std::move(app_types_), std::move(extra_args_));
+}
+
+LauncherInfo::LauncherInfo(std::string name, std::string exe,
+    std::vector<std::string> app_types, std::vector<std::string> extra_args)
+    : name_(std::move(name)),
+      exe_(std::move(exe)),
+      app_types_(std::move(app_types)),
+      extra_args_(std::move(extra_args)) {
+}
+
+const std::string& LauncherInfo::GetName() const {
+  return name_;
+}
+
+const std::string& LauncherInfo::GetExe() const {
+  return exe_;
+}
+
+const std::vector<std::string>& LauncherInfo::GetAppTypes() const {
+  return app_types_;
+}
+
+const std::vector<std::string>& LauncherInfo::GetExtraArgs() const {
+  return extra_args_;
+}
+
+LauncherInfoInflator::LauncherInfoInflator() {
+  parsers_ = {
+    { kTagName,
+      std::bind(&LauncherInfoInflator::ParseName,
+          this, std::placeholders::_1) },
+    { kTagExe,
+      std::bind(&LauncherInfoInflator::ParseExe,
+          this, std::placeholders::_1) },
+    { kTagAppType,
+      std::bind(&LauncherInfoInflator::ParseAppType,
+          this, std::placeholders::_1) },
+    { kTagExtraArg,
+      std::bind(&LauncherInfoInflator::ParseExtraArg,
+          this, std::placeholders::_1) },
+  };
+}
+
+void LauncherInfoInflator::ParseName(std::string token) {
+  builder_.SetName(std::move(token));
+}
+
+void LauncherInfoInflator::ParseExe(std::string token) {
+  builder_.SetExe(std::move(token));
+}
+
+void LauncherInfoInflator::ParseAppType(std::string token) {
+  std::string line = std::move(token);
+  do {
+    auto tokens = Util::Split(line, " |\t\r\n");
+    for (auto& app_type : tokens)
+      builder_.AddAppType(app_type);
+  } while (std::getline(string_stream_, line));
+}
+
+void LauncherInfoInflator::ParseExtraArg(std::string token) {
+  builder_.AddExtraArg(std::move(token));
+}
+
+void LauncherInfoInflator::Parse(const fs::path& path) {
+  std::ifstream launcher_file;
+  launcher_file.open(path);
+  if (launcher_file.fail())
+    return;
+
+  bool parsing = false;
+  std::string line;
+  while (std::getline(launcher_file, line)) {
+    string_stream_ = std::istringstream(line);
+    std::string token1;
+    if (!(string_stream_ >> token1))
+      continue;
+
+    std::string key = Util::ToUpper(std::move(token1));
+    if (key == kTagLauncher) {
+      if (parsing)
+        Insert();
+
+      builder_.Reset();
+      parsing = true;
+      continue;
+    }
+
+    if (parsing == false)
+      continue;
+
+    std::string token2;
+    if (!(string_stream_ >> token2))
+      continue;
+
+    auto found = parsers_.find(key);
+    if (found == parsers_.end())
+      continue;
+
+    auto& parser = found->second;
+    parser(std::move(token2));
+  }
+
+  if (parsing)
+    Insert();
+
+  launcher_file.close();
+}
+
+void LauncherInfoInflator::Insert() {
+  launcher_infos_.emplace_back(builder_.Build());
+}
+
+std::vector<LauncherInfoPtr> LauncherInfoInflator::Inflate(
+    const std::string_view path) {
+  fs::path dir_path(path);
+  if (fs::is_directory(dir_path) == false)
+    return {};
+
+  try {
+    for (auto& entry : fs::directory_iterator(dir_path)) {
+      fs::path file(entry.path());
+      if (file.extension() == ".launcher") {
+        Parse(file);
+      }
+    }
+  } catch (const fs::filesystem_error& e) {
+    _E("Exception occurs. error(%s:%d)", e.what(), e.code().value());
+  }
+
+  return launcher_infos_;
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/launcher_info.hh b/src/lib/launchpad-core/launcher_info.hh
new file mode 100644 (file)
index 0000000..3a97264
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2023 - 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_LAUNCHER_INFO_HH_
+#define LIB_LAUNCHPAD_CORE_LAUNCHER_INFO_HH_
+
+#include <filesystem>
+#include <functional>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <vector>
+
+namespace launchpad {
+
+class LauncherInfo {
+ public:
+  class Builder {
+   public:
+    Builder& SetName(std::string name);
+    Builder& SetExe(std::string exe);
+    Builder& AddAppType(std::string app_type);
+    Builder& AddExtraArg(std::string extra_arg);
+    Builder& Reset();
+
+    LauncherInfo* Build();
+
+   private:
+    std::string name_;
+    std::string exe_;
+    std::vector<std::string> app_types_;
+    std::vector<std::string> extra_args_;
+  };
+
+  LauncherInfo(std::string name, std::string exe,
+      std::vector<std::string> app_types, std::vector<std::string> extra_args);
+
+  const std::string& GetName() const;
+  const std::string& GetExe() const;
+  const std::vector<std::string>& GetAppTypes() const;
+  const std::vector<std::string>& GetExtraArgs() const;
+
+ private:
+  friend class LauncherInfoInflator;
+
+  std::string name_;
+  std::string exe_;
+  std::vector<std::string> app_types_;
+  std::vector<std::string> extra_args_;
+};
+
+using LauncherInfoPtr = std::shared_ptr<LauncherInfo>;
+
+class LauncherInfoInflator {
+ public:
+  LauncherInfoInflator();
+
+  std::vector<LauncherInfoPtr> Inflate(const std::string_view path);
+
+ private:
+  void Parse(const std::filesystem::path& path);
+
+  void ParseName(std::string token);
+  void ParseExe(std::string token);
+  void ParseAppType(std::string token);
+  void ParseExtraArg(std::string token);
+  void Insert();
+
+ private:
+  std::unordered_map<std::string, std::function<void(std::string)>> parsers_;
+  std::istringstream string_stream_;
+  LauncherInfo::Builder builder_;
+  std::vector<std::shared_ptr<LauncherInfo>> launcher_infos_;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_LAUNCHER_INFO_HH_
diff --git a/src/lib/launchpad-core/launchpad_args.cc b/src/lib/launchpad-core/launchpad_args.cc
new file mode 100644 (file)
index 0000000..b19ac77
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2024 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 "launchpad-core/launchpad_args.hh"
+
+namespace launchpad {
+
+LaunchpadArgs& LaunchpadArgs::GetInst() {
+  static LaunchpadArgs inst;
+  return inst;
+}
+
+void LaunchpadArgs::Set(int argc, char** args) {
+  argc_ = argc;
+  args_ = args;
+}
+
+int LaunchpadArgs::GetArgc() const {
+  return argc_;
+}
+
+char** LaunchpadArgs::GetArgs() const {
+  return args_;
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/launchpad_args.hh b/src/lib/launchpad-core/launchpad_args.hh
new file mode 100644 (file)
index 0000000..1cb7a8d
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_LAUNCHPAD_ARGS_HH_
+#define LIB_LAUNCHPAD_CORE_LAUNCHPAD_ARGS_HH_
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API LaunchpadArgs {
+ public:
+  LaunchpadArgs(const LaunchpadArgs&) = delete;
+  LaunchpadArgs& operator=(const LaunchpadArgs&) = delete;
+
+  static LaunchpadArgs& GetInst();
+
+  void Set(int argc, char** args);
+
+  int GetArgc() const;
+  char** GetArgs() const;
+
+ private:
+  LaunchpadArgs() = default;
+  ~LaunchpadArgs() = default;
+
+ private:
+  int argc_ = 0;
+  char** args_ = nullptr;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_LAUNCHPAD_ARGS_HH_
diff --git a/src/lib/launchpad-core/loader_executor.cc b/src/lib/launchpad-core/loader_executor.cc
new file mode 100644 (file)
index 0000000..626fb5c
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2023 - 2024 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 "launchpad-core/loader_executor.hh"
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <utility>
+
+#include <parcel.hh>
+#include <sched_priority.hh>
+#include <stdio.hh>
+#include <types.hh>
+#include <util.hh>
+
+#include "launchpad-core/log_private.hh"
+
+namespace launchpad {
+namespace {
+
+tizen_base::Parcel CreateParcelFromBundle(tizen_base::Bundle* b) {
+  auto b_raw = b->ToRaw();
+  std::string raw(reinterpret_cast<const char*>(b_raw.first.get()));
+  tizen_base::Parcel parcel;
+  parcel.WriteString(raw);
+  return parcel;
+}
+
+tizen_base::Bundle CreateBundleFromParcel(tizen_base::Parcel* parcel) {
+  std::string raw = parcel->ReadString();
+  return tizen_base::Bundle(raw);
+}
+
+}  // namespace
+
+LoaderExecutor::LoaderExecutor() : Executor(this) {
+  process_pool_ = std::unique_ptr<ProcessPool>(new ProcessPool(
+      "loader", ProcessPool::GetNumberOfLoaderProcesses(), this));
+}
+
+LoaderExecutor& LoaderExecutor::GetInst() {
+  static LoaderExecutor inst;
+  return inst;
+}
+
+pid_t LoaderExecutor::Execute(const LoaderInfo* loader_info, int loader_id,
+                              int priority) {
+  loader_argv_ = CreateLoaderArgv(loader_info, loader_id);
+  if (process_pool_->IsPrepared()) {
+    tizen_base::Bundle b;
+    b.Add("LOADER_ARGS", loader_argv_);
+    b.Add("LOADER_PRIORITY", std::to_string(priority));
+    auto parcel = CreateParcelFromBundle(&b);
+    pid_t pid = process_pool_->Execute(parcel);
+    if (pid > 0) return pid;
+  }
+
+  return Executor::Execute(priority);
+}
+
+bool LoaderExecutor::HasCandidateProcess() const {
+  return process_pool_->IsPrepared();
+}
+
+void LoaderExecutor::DisposeCandidateProcess() {
+  process_pool_->Dispose();
+  process_pool_->SetTimer();
+}
+
+void LoaderExecutor::HandleSigchld(pid_t pid) {
+  process_pool_->HandleSigchld(pid);
+}
+
+void LoaderExecutor::OnExecution() {
+  std::vector<char*> loader_argv(loader_argv_.size() + 1);
+  int loader_argc = loader_argv_.size();
+  for (int i = 0; i < loader_argc; ++i) {
+    loader_argv[i] = const_cast<char*>(loader_argv_[i].c_str());
+    if ((i + 1) != loader_argc)
+      SECURE_LOGD("loader argument %d : %s##", i, loader_argv[i]);
+  }
+
+  Util::CloseAllFds();
+  Stdio::Setup();
+
+  SECURE_LOGE("Execute loader(%s)", loader_argv[LoaderArg::Path]);
+  if (execv(loader_argv[LoaderArg::Path], loader_argv.data()) < 0) {
+    char err_buf[1024];
+    fprintf(stderr, "Failed to execute a file. path: %s, errno: %d:%s\n",
+        loader_argv[LoaderArg::Path], errno,
+        strerror_r(errno, err_buf, sizeof(err_buf)));
+    exit(EXIT_FAILURE);
+  }
+}
+
+void LoaderExecutor::OnRequestReceived(tizen_base::Parcel* parcel) {
+  _W("Request received");
+  tizen_base::Bundle b = CreateBundleFromParcel(parcel);
+  int priority = std::stoi(b.GetString("LOADER_PRIORITY"));
+  if (priority != 0)
+    SchedPriority::Set(priority);
+
+  loader_argv_ = b.GetStringArray("LOADER_ARGS");
+  OnExecution();
+}
+
+std::vector<std::string> LoaderExecutor::CreateLoaderArgv(
+    const LoaderInfo* loader_info, int loader_id) {
+  std::string dummy(kLoaderArgLength - 1, ' ');
+  std::vector<std::string> argv(LoaderArg::Dummy + 1);
+  argv[LoaderArg::Dummy] = std::move(dummy);
+  argv[LoaderArg::Path] = loader_info->GetExe();
+  argv[LoaderArg::Type] = std::to_string(loader_info->GetType());
+  argv[LoaderArg::Id] = std::to_string(loader_id);
+  argv[LoaderArg::Hydra] = loader_info->IsHydraMode() ? "1" : "0";
+  argv[LoaderArg::Extra] = reinterpret_cast<const char*>(
+      const_cast<tizen_base::Bundle&>(loader_info->GetExtra())
+          .ToRaw()
+          .first.get());
+  return argv;
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/loader_executor.hh b/src/lib/launchpad-core/loader_executor.hh
new file mode 100644 (file)
index 0000000..09c22ad
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2023 - 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_LOADER_EXECUTOR_HH_
+#define LIB_LAUNCHPAD_CORE_LOADER_EXECUTOR_HH_
+
+#include <sys/types.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "launchpad-core/executor.hh"
+#include "launchpad-core/loader_info.hh"
+#include "launchpad-core/process_pool.hh"
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API LoaderExecutor : public Executor::Delegator,
+                                  public Executor,
+                                  public ProcessPool::IEvent {
+ public:
+  LoaderExecutor(const LoaderExecutor&) = delete;
+  LoaderExecutor& operator=(const LoaderExecutor&) = delete;
+  LoaderExecutor(LoaderExecutor&&) = delete;
+  LoaderExecutor& operator=(LoaderExecutor&&) = delete;
+
+  static LoaderExecutor& GetInst();
+
+  pid_t Execute(const LoaderInfo* loader_info, int loader_id, int priority);
+  bool HasCandidateProcess() const;
+  void DisposeCandidateProcess();
+  void HandleSigchld(pid_t pid);
+
+ private:
+  LoaderExecutor();
+  ~LoaderExecutor() = default;
+
+  void OnExecution() override;
+  void OnRequestReceived(tizen_base::Parcel* parcel) override;
+  std::vector<std::string> CreateLoaderArgv(const LoaderInfo* loader_info,
+                                            int loader_id);
+
+ private:
+  std::unique_ptr<ProcessPool> process_pool_;
+  std::vector<std::string> loader_argv_;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_LOADER_EXECUTOR_HH_
diff --git a/src/lib/launchpad-core/loader_info.cc b/src/lib/launchpad-core/loader_info.cc
new file mode 100644 (file)
index 0000000..1c8b811
--- /dev/null
@@ -0,0 +1,788 @@
+/*
+ * Copyright (c) 2023 - 2024 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 "launchpad-core/loader_info.hh"
+
+#include <dirent.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+#include <utility>
+
+#include <util.hh>
+
+#include "launchpad-core/log_private.hh"
+
+namespace fs = std::filesystem;
+
+namespace launchpad {
+namespace {
+
+constexpr const char kTagLoader[] = "[LOADER]";
+constexpr const char kTagName[] = "NAME";
+constexpr const char kTagExe[] = "EXE";
+constexpr const char kTagAppType[] = "APP_TYPE";
+constexpr const char kTagDetectionMethod[] = "DETECTION_METHOD";
+constexpr const char kTagActivationMethod[] = "ACTIVATION_METHOD";
+constexpr const char kTagDeactivationMethod[] = "DEACTIVATION_METHOD";
+constexpr const char kTagTtl[] = "TTL";
+constexpr const char kTagTimeout[] = "TIMEOUT";
+constexpr const char kTagExtra[] = "EXTRA";
+constexpr const char kTagExtraArray[] = "EXTRA_ARRAY";
+constexpr const char kTagExtraArrayVal[] = "EXTRA_ARRAY_VAL";
+constexpr const char kTagAlternativeLoader[] = "ALTERNATIVE_LOADER";
+constexpr const char kTagHwAcc[] = "HW_ACC";
+constexpr const char kTagCpuThresholdMax[] = "CPU_THRESHOLD_MAX";
+constexpr const char kTagCpuThresholdMin[] = "CPU_THRESHOLD_MIN";
+constexpr const char kTagOnBoot[] = "ON_BOOT";
+constexpr const char kTagHydra[] = "HYDRA";
+constexpr const char kTagAppCheck[] = "APP_CHECK";
+constexpr const char kTagOnBootTimeout[] = "ON_BOOT_TIMEOUT";
+constexpr const char kTagSchedPriority[] = "SCHED_PRIORITY";
+constexpr const char kTagConditionPathExists[] = "CONDITION_PATH_EXISTS";
+
+constexpr const char kValOn[] = "ON";
+constexpr const char kValOff[] = "OFF";
+constexpr const char kValMethodTimeout[] = "TIMEOUT";
+constexpr const char kValMethodDemand[] = "DEMAND";
+constexpr const char kValMethodVisibility[] = "VISIBILITY";
+constexpr const char kValMethodRequest[] = "REQUEST";
+constexpr const char kValMethodAvailableMemory[] = "AVAILABLE_MEMORY";
+constexpr const char kValMethodTtl[] = "TTL";
+constexpr const char kValMethodOutOfMemory[] = "OUT_OF_MEMORY";
+
+LoaderType MakeLoaderType() {
+  static uint32_t user_slot_offset;
+  return static_cast<LoaderType>(
+      static_cast<int>(LoaderType::User) + user_slot_offset++);
+}
+
+}  // namespace
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetType(LoaderType type) {
+  type_ = type;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetName(std::string name) {
+  name_ = std::move(name);
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetExe(std::string exe) {
+  exe_ = std::move(exe);
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::AddAppType(std::string app_type) {
+  app_types_.push_back(std::move(app_type));
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetAppTypes(
+    std::vector<std::string> app_types) {
+  app_types_ = std::move(app_types);
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetDetectionMethod(
+    LoaderMethod method) {
+  detection_method_ = method;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetActivationMethod(
+    LoaderMethod method) {
+  activation_method_ = method;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetDeactivationMethod(
+    LoaderMethod method) {
+  deactivation_method_ = method;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetTimeout(int timeout) {
+  timeout_ = timeout;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetHwAcc(std::string hw_acc) {
+  hw_acc_ = std::move(hw_acc);
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::AddAlternativeLoader(
+    std::string alternative_loader) {
+  alternative_loaders_.push_back(std::move(alternative_loader));
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetAlternativeLoaders(
+    std::vector<std::string> alternative_loaders) {
+  alternative_loaders_ = std::move(alternative_loaders);
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::AddExtraData(std::string key,
+    std::string value) {
+  extra_.Add(std::move(key), std::move(value));
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::AddExtraArrayData(std::string key,
+    std::vector<std::string> value) {
+  extra_.Add(std::move(key), std::move(value));
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetExtra(tizen_base::Bundle extra) {
+  extra_ = std::move(extra);
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetCPUThresholdMax(
+  int cpu_threshold_max) {
+  cpu_threshold_max_ = cpu_threshold_max;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetCPUThresholdMin(
+  int cpu_threshold_min) {
+  cpu_threshold_min_ = cpu_threshold_min;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetOnBoot(bool on_boot) {
+  on_boot_ = on_boot;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetTimeToLive(int time_to_live) {
+  time_to_live_ = time_to_live;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetHydraMode(bool hydra_mode) {
+  hydra_mode_ = hydra_mode;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetAppCheck(bool app_check) {
+  app_check_ = app_check;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetOnBootTimeout(
+  int on_boot_timeout) {
+  on_boot_timeout_ = on_boot_timeout;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetSchedPriority(int sched_priority) {
+  sched_priority_ = sched_priority;
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::AddConditionPathExists(
+    std::string path) {
+  condition_path_exists_.push_back(std::move(path));
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::SetConditionPathExists(
+    std::vector<std::string> condition_path_exists) {
+  condition_path_exists_ = std::move(condition_path_exists);
+  return *this;
+}
+
+LoaderInfo::Builder& LoaderInfo::Builder::Reset() {
+  type_ = LoaderType::None;
+  name_.clear();
+  exe_.clear();
+  app_types_.clear();
+  detection_method_ = LoaderMethod::Timeout | LoaderMethod::Visibility |
+      LoaderMethod::Install;
+  activation_method_ = LoaderMethod::None;
+  deactivation_method_ = LoaderMethod::None;
+  timeout_ = 5000;
+  hw_acc_.clear();
+  alternative_loaders_.clear();
+  extra_ = tizen_base::Bundle();
+  cpu_threshold_max_ = 90;
+  cpu_threshold_min_ = 40;
+  on_boot_ = true;
+  time_to_live_ = 600;
+  hydra_mode_ = false;
+  app_check_ = true;
+  on_boot_timeout_ = 0;
+  sched_priority_ = 0;
+  condition_path_exists_.clear();
+  return *this;
+}
+
+LoaderInfo* LoaderInfo::Builder::Build() {
+  return new LoaderInfo(type_, std::move(name_), std::move(exe_),
+      std::move(app_types_), detection_method_, activation_method_,
+      deactivation_method_, timeout_, std::move(hw_acc_),
+      std::move(alternative_loaders_), std::move(extra_),
+      cpu_threshold_max_, cpu_threshold_min_, on_boot_, time_to_live_,
+      hydra_mode_, app_check_, on_boot_timeout_, sched_priority_,
+      std::move(condition_path_exists_));
+}
+
+LoaderInfo::LoaderInfo(LoaderType type, std::string name, std::string exe,
+    std::vector<std::string> app_types, LoaderMethod detection_method,
+    LoaderMethod activation_method, LoaderMethod deactivation_method,
+    int timeout, std::string hw_acc,
+    std::vector<std::string> alternative_loaders,
+    tizen_base::Bundle extra, int cpu_threshold_max,
+    int cpu_threshold_min, bool on_boot, int time_to_live,
+    bool hydra_mode, bool app_check, int on_boot_timeout,
+    int sched_priority, std::vector<std::string> condition_path_exists)
+    : type_(type),
+      name_(std::move(name)),
+      exe_(std::move(exe)),
+      app_types_(std::move(app_types)),
+      detection_method_(detection_method),
+      activation_method_(activation_method),
+      deactivation_method_(deactivation_method),
+      timeout_(timeout),
+      hw_acc_(std::move(hw_acc)),
+      alternative_loaders_(std::move(alternative_loaders)),
+      extra_(std::move(extra)),
+      cpu_threshold_max_(cpu_threshold_max),
+      cpu_threshold_min_(cpu_threshold_min),
+      on_boot_(on_boot),
+      time_to_live_(time_to_live),
+      hydra_mode_(hydra_mode),
+      app_check_(app_check),
+      on_boot_timeout_(on_boot_timeout),
+      sched_priority_(sched_priority),
+      condition_path_exists_(std::move(condition_path_exists)) {
+  extra_.Add("SCHED_PRIORITY", std::to_string(sched_priority_));
+}
+
+LoaderType LoaderInfo::GetType() const {
+  return type_;
+}
+
+void LoaderInfo::SetType(LoaderType type) {
+  type_ = type;
+}
+
+const std::string& LoaderInfo::GetName() const {
+  return name_;
+}
+
+const std::string& LoaderInfo::GetExe() const {
+  return exe_;
+}
+
+void LoaderInfo::SetExe(std::string exe) {
+  exe_ = std::move(exe);
+}
+
+int LoaderInfo::GetCpuThresholdMax() const {
+  return cpu_threshold_max_;
+}
+
+int LoaderInfo::GetCpuThresholdMin() const {
+  return cpu_threshold_min_;
+}
+
+int LoaderInfo::GetTimeToLive() const {
+  return time_to_live_;
+}
+
+const std::vector<std::string>& LoaderInfo::GetAppTypes() const {
+  return app_types_;
+}
+
+LoaderMethod LoaderInfo::GetDetectionMethod() const {
+  return detection_method_;
+}
+
+void LoaderInfo::SetDetectionMethod(LoaderMethod detection_method) {
+  detection_method_ = detection_method;
+}
+
+LoaderMethod LoaderInfo::GetActivationMethod() const {
+  return activation_method_;
+}
+
+void LoaderInfo::SetActivationMethod(LoaderMethod activation_method) {
+  activation_method_ = activation_method;
+}
+
+LoaderMethod LoaderInfo::GetDeactivationMethod() const {
+  return deactivation_method_;
+}
+
+void LoaderInfo::SetDeactivationMethod(LoaderMethod deactivation_method) {
+  deactivation_method_ = deactivation_method;
+}
+
+const std::string& LoaderInfo::GetHwAcc() const {
+  return hw_acc_;
+}
+
+int LoaderInfo::GetOnBootTimeout() const {
+  return on_boot_timeout_;
+}
+
+int LoaderInfo::GetTimeout() const {
+  return timeout_;
+}
+
+void LoaderInfo::SetTimeout(int timeout) {
+  timeout_ = timeout;
+}
+
+int LoaderInfo::GetSchedPriority() const {
+  return sched_priority_;
+}
+
+bool LoaderInfo::ShouldCheckAppInstallation() const {
+  return app_check_;
+}
+
+bool LoaderInfo::IsOnBoot() const {
+  return on_boot_;
+}
+
+bool LoaderInfo::IsHydraMode() const {
+  return hydra_mode_;
+}
+
+const tizen_base::Bundle& LoaderInfo::GetExtra() const {
+  return extra_;
+}
+
+void LoaderInfo::SetAppInstalled(bool app_installed) {
+  app_installed_ = app_installed;
+}
+
+bool LoaderInfo::IsAppInstalled() const {
+  return app_installed_;
+}
+
+const std::vector<std::string>& LoaderInfo::GetConditionPathExists() const {
+  return condition_path_exists_;
+}
+
+LoaderInfoInflator::LoaderInfoInflator() {
+  parsers_ = {
+    { kTagName,
+      std::bind(&LoaderInfoInflator::ParseName,
+          this, std::placeholders::_1) },
+    { kTagExe,
+      std::bind(&LoaderInfoInflator::ParseExe,
+          this, std::placeholders::_1) },
+    { kTagAppType,
+      std::bind(&LoaderInfoInflator::ParseAppType,
+          this, std::placeholders::_1) },
+    { kTagDetectionMethod,
+      std::bind(&LoaderInfoInflator::ParseDetectionMethod,
+          this, std::placeholders::_1) },
+    { kTagActivationMethod,
+      std::bind(&LoaderInfoInflator::ParseActivationMethod,
+          this, std::placeholders::_1) },
+    { kTagDeactivationMethod,
+      std::bind(&LoaderInfoInflator::ParseDeativationMethod,
+          this, std::placeholders::_1) },
+    { kTagTtl,
+      std::bind(&LoaderInfoInflator::ParseTimeToLive,
+          this, std::placeholders::_1) },
+    { kTagTimeout,
+      std::bind(&LoaderInfoInflator::ParseTimeout,
+          this, std::placeholders::_1) },
+    { kTagExtra,
+      std::bind(&LoaderInfoInflator::ParseExtra,
+          this, std::placeholders::_1) },
+    { kTagExtraArray,
+      std::bind(&LoaderInfoInflator::ParseExtraArray,
+          this, std::placeholders::_1) },
+    { kTagExtraArrayVal,
+      std::bind(&LoaderInfoInflator::ParseExtraArrayValue,
+          this, std::placeholders::_1) },
+    { kTagHwAcc,
+      std::bind(&LoaderInfoInflator::ParseHwAcc,
+          this, std::placeholders::_1) },
+    { kTagAlternativeLoader,
+      std::bind(&LoaderInfoInflator::ParseAlternativeLoader,
+          this, std::placeholders::_1) },
+    { kTagCpuThresholdMax,
+      std::bind(&LoaderInfoInflator::ParseCPUThresholdMax,
+          this, std::placeholders::_1) },
+    { kTagCpuThresholdMin,
+      std::bind(&LoaderInfoInflator::ParseCPUThresholdMin,
+          this, std::placeholders::_1) },
+    { kTagOnBoot,
+      std::bind(&LoaderInfoInflator::ParseOnBoot,
+          this, std::placeholders::_1) },
+    { kTagHydra,
+      std::bind(&LoaderInfoInflator::ParseHydra,
+          this, std::placeholders::_1) },
+    { kTagAppCheck,
+      std::bind(&LoaderInfoInflator::ParseAppCheck,
+          this, std::placeholders::_1) },
+    { kTagOnBootTimeout,
+      std::bind(&LoaderInfoInflator::ParseOnBootTimeout,
+          this, std::placeholders::_1) },
+    { kTagSchedPriority,
+      std::bind(&LoaderInfoInflator::ParseSchedPriority,
+          this, std::placeholders::_1) },
+    { kTagConditionPathExists,
+      std::bind(&LoaderInfoInflator::ParseConditionPathExists,
+          this, std::placeholders::_1) },
+  };
+}
+
+void LoaderInfoInflator::ParseName(std::string token) {
+  builder_.SetName(std::move(token));
+}
+
+void LoaderInfoInflator::ParseExe(std::string token) {
+  builder_.SetExe(std::move(token));
+}
+
+void LoaderInfoInflator::ParseAppType(std::string token) {
+  std::string line = std::move(token);
+  do {
+    auto tokens = Util::Split(line, " |\t\r\n");
+    for (auto& app_type : tokens)
+      builder_.AddAppType(app_type);
+  } while (std::getline(string_stream_, line));
+}
+
+void LoaderInfoInflator::ParseDetectionMethod(std::string token) {
+  LoaderMethod method = LoaderMethod::None;
+  std::string line = std::move(token);
+  do {
+    auto tokens = Util::Split(line, " |\t\r\n");
+    for (auto& token : tokens) {
+      if (token == kValMethodTimeout)
+        method = method | LoaderMethod::Timeout;
+      else if (token == kValMethodVisibility)
+        method = method | LoaderMethod::Visibility;
+      else if (token == kValMethodDemand)
+        method = method | LoaderMethod::Demand;
+    }
+  } while (std::getline(string_stream_, line));
+
+  method = method | LoaderMethod::Install;
+  builder_.SetDetectionMethod(method);
+  _D("Detection method: %d", static_cast<int>(method));
+}
+
+void LoaderInfoInflator::ParseActivationMethod(std::string token) {
+  LoaderMethod method = LoaderMethod::None;
+  std::string line = std::move(token);
+  do {
+    auto tokens = Util::Split(line, " |\t\r\n");
+    for (auto& token : tokens) {
+      if (token == kValMethodRequest)
+        method = method | LoaderMethod::Request;
+      else if (token == kValMethodAvailableMemory)
+        method = method | LoaderMethod::AvailableMemory;
+    }
+  } while (std::getline(string_stream_, line));
+
+  builder_.SetActivationMethod(method);
+  _D("Activation method: %d", static_cast<int>(method));
+}
+
+void LoaderInfoInflator::ParseDeativationMethod(std::string token) {
+  LoaderMethod method = LoaderMethod::None;
+  std::string line = std::move(token);
+  do {
+    auto tokens = Util::Split(line, " |\t\r\n");
+    for (auto& token : tokens) {
+      if (token == kValMethodTtl)
+        method = method | LoaderMethod::TimeToLive;
+      else if (token == kValMethodOutOfMemory)
+        method = method | LoaderMethod::OutOfMemory;
+    }
+  } while (std::getline(string_stream_, line));
+
+  builder_.SetDeactivationMethod(method);
+  _D("Deactivation method: %d", static_cast<int>(method));
+}
+
+void LoaderInfoInflator::ParseTimeToLive(std::string token) {
+  builder_.SetTimeToLive(std::stoi(token));
+}
+
+void LoaderInfoInflator::ParseTimeout(std::string token) {
+  builder_.SetTimeout(std::stoi(token));
+}
+
+void LoaderInfoInflator::ParseExtra(std::string token) {
+  std::string value;
+  if (string_stream_ >> value)
+    builder_.AddExtraData(std::move(token), std::move(value));
+}
+
+void LoaderInfoInflator::ParseExtraArray(std::string token) {
+  if (!extra_array_key_.empty() && !extra_array_value_.empty()) {
+    builder_.AddExtraArrayData(std::move(extra_array_key_),
+        std::move(extra_array_value_));
+    extra_array_value_.clear();
+  }
+
+  extra_array_key_ = std::move(token);
+}
+
+void LoaderInfoInflator::ParseExtraArrayValue(std::string token) {
+  extra_array_value_.push_back(std::move(token));
+}
+
+void LoaderInfoInflator::ParseHwAcc(std::string token) {
+  builder_.SetHwAcc(std::move(token));
+}
+
+void LoaderInfoInflator::ParseAlternativeLoader(std::string token) {
+  builder_.AddAlternativeLoader(std::move(token));
+}
+
+void LoaderInfoInflator::ParseCPUThresholdMax(std::string token) {
+  builder_.SetCPUThresholdMax(std::stoi(token));
+}
+
+void LoaderInfoInflator::ParseCPUThresholdMin(std::string token) {
+  builder_.SetCPUThresholdMin(std::stoi(token));
+}
+
+void LoaderInfoInflator::ParseOnBoot(std::string token) {
+  if (token == kValOff)
+    builder_.SetOnBoot(false);
+}
+
+void LoaderInfoInflator::ParseHydra(std::string token) {
+  if (token == kValOn)
+    builder_.SetHydraMode(true);
+}
+
+void LoaderInfoInflator::ParseAppCheck(std::string token) {
+  if (token == kValOff)
+    builder_.SetAppCheck(false);
+}
+
+void LoaderInfoInflator::ParseOnBootTimeout(std::string token) {
+  builder_.SetOnBootTimeout(std::stoi(token));
+}
+
+void LoaderInfoInflator::ParseSchedPriority(std::string token) {
+  builder_.SetSchedPriority(std::min(std::max(std::stoi(token), -20), 19));
+}
+
+void LoaderInfoInflator::ParseConditionPathExists(std::string token) {
+  std::string line = std::move(token);
+  do {
+    auto tokens = Util::Split(line, " |\t\r\n");
+    for (auto& token : tokens)
+      builder_.AddConditionPathExists(token);
+  } while (std::getline(string_stream_, line));
+}
+
+void LoaderInfoInflator::Parse(const std::filesystem::path& path,
+    LoaderType type) {
+  std::ifstream loader_file;
+  loader_file.open(path);
+  if (loader_file.fail())
+    return;
+
+  bool parsing = false;
+  std::string line;
+  while (std::getline(loader_file, line)) {
+    string_stream_ = std::istringstream(line);
+    std::string token1;
+    if (!(string_stream_ >> token1))
+      continue;
+
+    std::string key = Util::ToUpper(std::move(token1));
+    if (key == kTagLoader) {
+      if (parsing)
+        Insert(type);
+
+      builder_.Reset();
+      parsing = true;
+      continue;
+    }
+
+    if (parsing == false)
+      continue;
+
+    std::string token2;
+    if (!(string_stream_ >> token2))
+      continue;
+
+    auto found = parsers_.find(key);
+    if (found == parsers_.end())
+      continue;
+
+    auto& parser = found->second;
+    parser(std::move(token2));
+  }
+
+  if (parsing)
+    Insert(type);
+
+  loader_file.close();
+}
+
+void LoaderInfoInflator::Insert(LoaderType type) {
+  if (!extra_array_key_.empty() && !extra_array_value_.empty()) {
+    builder_.AddExtraArrayData(std::move(extra_array_key_),
+        std::move(extra_array_value_));
+    extra_array_value_.clear();
+  }
+
+  if (type != LoaderType::Dynamic)
+    type = MakeLoaderType();
+
+  builder_.SetType(type);
+  loader_infos_.emplace_back(builder_.Build());
+}
+
+std::vector<LoaderInfoPtr> LoaderInfoInflator::Inflate(
+    const std::string_view path) {
+  fs::path input_path(path);
+  if (fs::is_directory(input_path) == false)
+    return {};
+
+  try {
+    for (auto& entry : fs::directory_iterator(input_path)) {
+      fs::path file(entry.path());
+      if (file.extension() == ".loader")
+        Parse(file, LoaderType::User);
+    }
+  } catch (const fs::filesystem_error& e) {
+    _E("Exception occurs. error(%s:%d)", e.what(), e.code().value());
+  }
+
+  return loader_infos_;
+}
+
+LoaderInfoManager::LoaderInfoManager(std::string path): path_(std::move(path)) {
+}
+
+void LoaderInfoManager::Load() {
+  if (!loader_list_.empty())
+    return;
+
+  LoaderInfoInflator inflator;
+  loader_list_ = inflator.Inflate(path_);
+}
+
+void LoaderInfoManager::LoadFile(const std::string_view file) {
+  LoaderInfoInflator inflator;
+  fs::path path(path_);
+  inflator.Parse(path / file, LoaderType::Dynamic);
+}
+
+void LoaderInfoManager::Unload(const std::string_view loader_name) {
+  loader_list_.erase(std::remove_if(loader_list_.begin(), loader_list_.end(),
+      [&](const LoaderInfoPtr& info) -> bool {
+        return info->GetName() == loader_name;
+      }), loader_list_.end());
+}
+
+void LoaderInfoManager::Dispose() {
+  loader_list_.clear();
+}
+
+std::string LoaderInfoManager::FindLoaderPath(
+    const std::string_view loader_name) {
+  for (auto& info : loader_list_) {
+    if (info->GetName() == loader_name)
+      return info->GetExe();
+  }
+
+  return "";
+}
+
+LoaderInfoPtr LoaderInfoManager::FindLoaderInfo(
+    const std::string_view loader_name) {
+  for (auto& info : loader_list_) {
+    if (info->GetName() == loader_name)
+      return info;
+  }
+
+  return nullptr;
+}
+
+LoaderType LoaderInfoManager::FindHwType(const std::string_view app_type) {
+  for (auto& info : loader_list_) {
+    if (info->GetHwAcc().empty() || info->GetHwAcc() == kValOn) {
+      auto found = std::find_if(
+          info->GetAppTypes().begin(), info->GetAppTypes().end(),
+          [&](const std::string& type) -> bool { return type == app_type; });
+      if (found != info->GetAppTypes().end())
+        return info->GetType();
+    }
+  }
+
+  return LoaderType::None;
+}
+
+LoaderType LoaderInfoManager::FindSwType(const std::string_view app_type) {
+  for (auto& info : loader_list_) {
+    if (info->GetHwAcc().empty() || info->GetHwAcc() == kValOff) {
+      auto found = std::find_if(
+          info->GetAppTypes().begin(), info->GetAppTypes().end(),
+          [&](const std::string& type) -> bool { return type == app_type; });
+      if (found != info->GetAppTypes().end())
+        return info->GetType();
+    }
+  }
+
+  return LoaderType::None;
+}
+
+std::vector<LoaderType> LoaderInfoManager::GetAlternativeTypes(
+    LoaderType type) {
+  std::vector<LoaderType> result;
+  for (auto& info : loader_list_) {
+    if (info->GetType() == type) {
+      for (auto& alt_loader : info->alternative_loaders_) {
+        auto found = std::find_if(loader_list_.begin(), loader_list_.end(),
+            [&](const auto& li) -> bool {
+              return li->GetName() == alt_loader;
+            });
+        if (found == loader_list_.end())
+          continue;
+
+        result.push_back((*found)->GetType());
+      }
+    }
+  }
+
+  return result;
+}
+
+const std::vector<LoaderInfoPtr>& LoaderInfoManager::GetLoaderInfoList() const {
+  return loader_list_;
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/loader_info.hh b/src/lib/launchpad-core/loader_info.hh
new file mode 100644 (file)
index 0000000..93a0190
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2023 - 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_LOADER_INFO_HH_
+#define LIB_LAUNCHPAD_CORE_LOADER_INFO_HH_
+
+#include <bundle_cpp.h>
+
+#include <filesystem>
+#include <functional>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <vector>
+
+#include <types.hh>
+#include <util.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+enum class EXPORT_API LoaderMethod : int {
+  None = 0x0000,
+  Timeout = 0x0001,
+  Visibility = 0x0002,
+  Demand = 0x0004,
+  Request = 0x0010,
+  AvailableMemory = 0x0020,
+  TimeToLive = 0x0040,
+  OutOfMemory = 0x0100,
+  Install = 0x0200,
+};
+
+class EXPORT_API LoaderInfo {
+ public:
+  class EXPORT_API Builder {
+   public:
+    Builder& SetType(LoaderType type);
+    Builder& SetName(std::string name);
+    Builder& SetExe(std::string exe);
+    Builder& AddAppType(std::string app_type);
+    Builder& SetAppTypes(std::vector<std::string> app_types);
+    Builder& SetDetectionMethod(launchpad::LoaderMethod method);
+    Builder& SetActivationMethod(launchpad::LoaderMethod method);
+    Builder& SetDeactivationMethod(launchpad::LoaderMethod method);
+    Builder& SetTimeout(int timeout);
+    Builder& SetHwAcc(std::string hw_acc);
+    Builder& AddAlternativeLoader(std::string alternative_loader);
+    Builder& SetAlternativeLoaders(
+        std::vector<std::string> alternative_loaders);
+    Builder& AddExtraData(std::string key, std::string value);
+    Builder& AddExtraArrayData(std::string key, std::vector<std::string> value);
+    Builder& SetExtra(tizen_base::Bundle extra);
+    Builder& SetCPUThresholdMax(int cpu_threshold_max);
+    Builder& SetCPUThresholdMin(int cpu_threshold_min);
+    Builder& SetOnBoot(bool on_boot);
+    Builder& SetTimeToLive(int time_to_live);
+    Builder& SetHydraMode(bool hydra_mode);
+    Builder& SetAppCheck(bool app_check);
+    Builder& SetOnBootTimeout(int on_boot_timeout);
+    Builder& SetSchedPriority(int sched_priority);
+    Builder& AddConditionPathExists(std::string path);
+    Builder& SetConditionPathExists(
+        std::vector<std::string> condition_path_exists);
+    Builder& Reset();
+
+    LoaderInfo* Build();
+
+   private:
+    LoaderType type_ = LoaderType::None;
+    std::string name_;
+    std::string exe_;
+    std::vector<std::string> app_types_;
+    LoaderMethod detection_method_ =
+       LoaderMethod::Timeout | LoaderMethod::Visibility | LoaderMethod::Install;
+    LoaderMethod activation_method_ = LoaderMethod::None;
+    LoaderMethod deactivation_method_ = LoaderMethod::None;
+    int timeout_ = 5000;
+    std::string hw_acc_;
+    std::vector<std::string> alternative_loaders_;
+    tizen_base::Bundle extra_;
+    int cpu_threshold_max_ = 90;
+    int cpu_threshold_min_ = 40;
+    bool on_boot_ = true;
+    int time_to_live_ = 600;
+    bool hydra_mode_ = false;
+    bool app_check_ = true;
+    int on_boot_timeout_ = 0;
+    int sched_priority_ = 0;
+    std::vector<std::string> condition_path_exists_;
+  };
+
+  LoaderInfo(LoaderType type, std::string name, std::string exe,
+      std::vector<std::string> app_types, LoaderMethod detection_method,
+      LoaderMethod activation_method, LoaderMethod deactivation_method,
+      int timeout, std::string hw_acc,
+      std::vector<std::string> alternative_loaders,
+      tizen_base::Bundle extra, int cpu_threshold_max,
+      int cpu_threshold_min, bool on_boot, int time_to_live,
+      bool hydra_mode, bool app_check, int on_boot_timeout,
+      int sched_priority,
+      std::vector<std::string> condition_path_exists);
+
+  LoaderType GetType() const;
+  void SetType(LoaderType type);
+  const std::string& GetName() const;
+  const std::string& GetExe() const;
+  void SetExe(std::string exe);
+  int GetCpuThresholdMax() const;
+  int GetCpuThresholdMin() const;
+  int GetTimeToLive() const;
+  const std::vector<std::string>& GetAppTypes() const;
+  LoaderMethod GetDetectionMethod() const;
+  void SetDetectionMethod(LoaderMethod detection_method);
+  LoaderMethod GetActivationMethod() const;
+  void SetActivationMethod(LoaderMethod activation_method);
+  LoaderMethod GetDeactivationMethod() const;
+  void SetDeactivationMethod(LoaderMethod deactivation_method);
+  const std::string& GetHwAcc() const;
+  int GetOnBootTimeout() const;
+  int GetTimeout() const;
+  void SetTimeout(int timeout);
+  int GetSchedPriority() const;
+  bool ShouldCheckAppInstallation() const;
+  bool IsOnBoot() const;
+  bool IsHydraMode() const;
+  const tizen_base::Bundle& GetExtra() const;
+  const std::vector<std::string>& GetConditionPathExists() const;
+  void SetAppInstalled(bool app_installed);
+  bool IsAppInstalled() const;
+
+ private:
+  friend class LoaderInfoManager;
+  friend class LoaderInfoInflator;
+
+ private:
+  LoaderType type_;
+  std::string name_;
+  std::string exe_;
+  std::vector<std::string> app_types_;
+  LoaderMethod detection_method_;
+  LoaderMethod activation_method_;
+  LoaderMethod deactivation_method_;
+  int timeout_;
+  std::string hw_acc_;
+  std::vector<std::string> alternative_loaders_;
+  tizen_base::Bundle extra_;
+  int cpu_threshold_max_;
+  int cpu_threshold_min_;
+  bool on_boot_;
+  int time_to_live_;
+  bool hydra_mode_;
+  bool app_check_;
+  int on_boot_timeout_;
+  int sched_priority_;
+  std::vector<std::string> condition_path_exists_;
+  bool app_installed_ = false;
+};
+
+using LoaderInfoPtr = std::shared_ptr<LoaderInfo>;
+
+class EXPORT_API LoaderInfoInflator {
+ public:
+  LoaderInfoInflator();
+
+  std::vector<LoaderInfoPtr> Inflate(const std::string_view path);
+
+  void Parse(const std::filesystem::path& path, LoaderType type);
+
+ private:
+  void ParseName(std::string token);
+  void ParseExe(std::string token);
+  void ParseAppType(std::string token);
+  void ParseDetectionMethod(std::string token);
+  void ParseActivationMethod(std::string token);
+  void ParseDeativationMethod(std::string token);
+  void ParseTimeToLive(std::string token);
+  void ParseTimeout(std::string token);
+  void ParseExtra(std::string token);
+  void ParseExtraArray(std::string token);
+  void ParseExtraArrayValue(std::string token);
+  void ParseHwAcc(std::string token);
+  void ParseAlternativeLoader(std::string token);
+  void ParseCPUThresholdMax(std::string token);
+  void ParseCPUThresholdMin(std::string token);
+  void ParseOnBoot(std::string token);
+  void ParseHydra(std::string token);
+  void ParseAppCheck(std::string token);
+  void ParseOnBootTimeout(std::string token);
+  void ParseSchedPriority(std::string token);
+  void ParseConditionPathExists(std::string token);
+  void Insert(LoaderType type);
+
+ private:
+  std::unordered_map<std::string, std::function<void(std::string)>> parsers_;
+  std::istringstream string_stream_;
+  std::string extra_array_key_;
+  std::vector<std::string> extra_array_value_;
+  LoaderInfo::Builder builder_;
+  std::vector<std::shared_ptr<LoaderInfo>> loader_infos_;
+};
+
+class EXPORT_API LoaderInfoManager {
+ public:
+  explicit LoaderInfoManager(std::string path);
+  LoaderInfoManager(const LoaderInfoManager&) = delete;
+  LoaderInfoManager& operator=(const LoaderInfoManager&) = delete;
+
+  void Load();
+  void LoadFile(const std::string_view file);
+  void Unload(const std::string_view loader_name);
+  void Dispose();
+  LoaderType FindHwType(const std::string_view app_type);
+  LoaderType FindSwType(const std::string_view app_type);
+  std::string FindLoaderPath(const std::string_view loader_name);
+  LoaderInfoPtr FindLoaderInfo(const std::string_view loader_name);
+  std::vector<LoaderType> GetAlternativeTypes(LoaderType type);
+  const std::vector<LoaderInfoPtr>& GetLoaderInfoList() const;
+
+ private:
+  std::string path_;
+  std::vector<LoaderInfoPtr> loader_list_;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_LOADER_INFO_HH_
diff --git a/src/lib/launchpad-core/log_private.hh b/src/lib/launchpad-core/log_private.hh
new file mode 100644 (file)
index 0000000..192eaa4
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_LOG_PRIVATE_HH_
+#define LIB_LAUNCHPAD_CORE_LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "LAUNCHPAD"
+
+#undef _E
+#define _E(fmt, ...) LOGE("[CORE] " fmt, ##__VA_ARGS__)
+
+#undef _W
+#define _W(fmt, ...) LOGW("[CORE] " fmt, ##__VA_ARGS__)
+
+#undef _I
+#define _I(fmt, ...) LOGI("[CORE] " fmt, ##__VA_ARGS__)
+
+#undef _D
+#define _D(fmt, ...) LOGD("[CORE] " fmt, ##__VA_ARGS__)
+
+#endif  // LIB_LAUNCHPAD_CORE_LOG_PRIVATE_HH_
diff --git a/src/lib/launchpad-core/pkgconfig/liblaunchpad-core.pc.in b/src/lib/launchpad-core/pkgconfig/liblaunchpad-core.pc.in
new file mode 100644 (file)
index 0000000..73c2dd8
--- /dev/null
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=/usr
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDE_INSTALL_DIR@
+
+Name: liblaunchpad-core
+Description: launchpad core library
+Version: @VERSION@
+Requires: bundle dlog parcel launchpad-common launchpad-glib
+Libs: -L${libdir} -llaunchpad-core
+Cflags: -I${includedir} -I${includedir}/launchpad-core
diff --git a/src/lib/launchpad-core/process_pool.cc b/src/lib/launchpad-core/process_pool.cc
new file mode 100644 (file)
index 0000000..df39da0
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2023 - 2024 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 "launchpad-core/process_pool.hh"
+
+#include <dlog-redirect-stdout.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/limits.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <filesystem>
+#include <utility>
+#include <vector>
+
+#include <ini_parser.hh>
+#include <util.hh>
+
+#include "launchpad-core/launchpad_args.hh"
+#include "launchpad-core/log_private.hh"
+
+namespace fs = std::filesystem;
+
+namespace launchpad {
+namespace {
+
+constexpr const char kProcessPool[] = "process-pool";
+constexpr const char kPathLaunchpadConf[] = "/usr/share/aul/launchpad.conf";
+constexpr const char kTagProcessPool[] = "ProcessPool";
+constexpr const char kKeyProcessPoolNumberOfProcesses[] = "NumberOfProcesses";
+constexpr const char kKeyProcessPoolNumberOfLoaderProcesses[] =
+    "NumberOfLoaderProcesses";
+
+class Config {
+ public:
+  Config() = default;
+
+  void Load() {
+    if (loaded_) return;
+
+    IniParser parser(kPathLaunchpadConf);
+    auto number_of_processes =
+        parser.Get(kTagProcessPool, kKeyProcessPoolNumberOfProcesses);
+    if (!number_of_processes.empty() && std::isdigit(number_of_processes[0]))
+      number_of_processes_ = std::stoi(number_of_processes);
+
+    auto number_of_loader_processes =
+        parser.Get(kTagProcessPool, kKeyProcessPoolNumberOfLoaderProcesses);
+    if (!number_of_loader_processes.empty() &&
+        std::isdigit(number_of_loader_processes[0]))
+      number_of_loader_processes_ = std::stoi(number_of_loader_processes);
+
+    _W("[ProcessPool] processes: %d, loader processes: %d",
+       number_of_processes_, number_of_loader_processes_);
+    loaded_ = true;
+  }
+
+  const int GetNumberOfProcesses() const { return number_of_processes_; }
+
+  const int GetNumberOfLoaderProcesses() const {
+    return number_of_loader_processes_;
+  }
+
+ private:
+  bool loaded_ = false;
+  int number_of_processes_ = 1;
+  int number_of_loader_processes_ = 1;
+};
+
+Config config_;
+
+bool IsExceptable(const std::string& path) {
+  static char buf[PATH_MAX];
+  ssize_t len = readlink(path.c_str(), buf, sizeof(buf));
+  if (len < 0) {
+    _E("readlink() is failed. errno: %d", errno);
+    return false;
+  }
+
+  buf[len] = '\0';
+  if (strstr(buf, "log") != nullptr ||
+      strstr(buf, "trace") != nullptr ||
+      strstr(buf, "dev") != nullptr)
+    return true;
+
+  return false;
+}
+
+std::vector<int> GetExceptableFds() {
+  std::vector<int> fds;
+  try {
+    fs::path proc_path("/proc/self/fd");
+    for (const auto& entry : fs::directory_iterator(proc_path)) {
+      if (!isdigit(entry.path().filename().string()[0]))
+        continue;
+
+      int fd = std::stoi(entry.path().filename().string());
+      if (dlog_is_log_fd(fd) || IsExceptable(entry.path().string()))
+        fds.push_back(fd);
+    }
+  } catch (const fs::filesystem_error& e) {
+    _E("Exception occurs. error(%s)", e.what());
+  }
+
+  return fds;
+}
+
+}  // namespace
+
+ProcessPool::ProcessPool(std::string name, int num_processes,
+    IEvent* event_listener = nullptr)
+    : Executor(this),
+      name_(std::move(name)),
+      num_processes_(num_processes),
+      event_listener_(event_listener) {
+  PrepareProcess();
+}
+
+ProcessPool::~ProcessPool() {
+  Dispose();
+}
+
+bool ProcessPool::IsPrepared() const {
+  return !queue_.empty();
+}
+
+pid_t ProcessPool::Execute(const tizen_base::Parcel& parcel) {
+  SetTimer();
+  if (!IsPrepared())
+    return -1;
+
+  auto process = std::move(queue_.front());
+  queue_.erase(queue_.begin());
+  if (process->Send(parcel) < 0)
+    return -1;
+
+  return process->GetPid();
+}
+
+void ProcessPool::Dispose() {
+  for (auto& process : queue_) {
+    process->Kill();
+    _D("Kill process(%d)", process->GetPid());
+  }
+  queue_.clear();
+  UnsetTimer();
+}
+
+void ProcessPool::HandleSigchld(pid_t pid) {
+  auto iter = queue_.begin();
+  while (iter != queue_.end()) {
+    if ((*iter)->GetPid() == pid) {
+      iter = queue_.erase(iter);
+      break;
+    }
+
+    iter++;
+  }
+
+  int current_process_count = static_cast<int>(queue_.size());
+  if (current_process_count != num_processes_)
+    SetTimer();
+}
+
+ProcessPool::Process::Process(pid_t pid, int fd)
+    : pid_(pid), socket_(new Socket(fd)) {
+}
+
+pid_t ProcessPool::Process::GetPid() const {
+  return pid_;
+}
+
+int ProcessPool::Process::Send(const tizen_base::Parcel& parcel) {
+  _W("Send execution request. process ID: %d", pid_);
+  size_t data_size = parcel.GetDataSize();
+  int ret = socket_->Write(static_cast<void*>(&data_size), sizeof(data_size));
+  if (ret != 0) {
+    _E("Write() is failed. error(%d)", ret);
+    return ret;
+  }
+
+  return socket_->Write(parcel.GetData(), parcel.GetDataSize());
+}
+
+void ProcessPool::Process::Kill() {
+  socket_->Close();
+  if (kill(pid_, SIGKILL) == -1) {
+    _E("Failed to send kill signal to the process. pid(%d), errno(%d)",
+        pid_, errno);
+  }
+}
+
+void ProcessPool::OnExecution() {
+  _D("Candidate Process");
+  char** args = LaunchpadArgs::GetInst().GetArgs();
+  size_t length = strlen(args[0]);
+  memset(args[0], '\0', length);
+  snprintf(args[0], length, "/usr/bin/%s <%s>", kProcessPool, name_.c_str());
+
+  close(pipe_fd_[1]);
+  std::vector<int> except_fds = GetExceptableFds();
+  except_fds.push_back(pipe_fd_[0]);
+  Util::CloseAllFds(except_fds);
+  int ret = WaitForRequest(std::make_unique<Socket>(pipe_fd_[0]));
+  exit(ret);
+}
+
+void ProcessPool::PrepareProcess() {
+  int current_process_count = static_cast<int>(queue_.size());
+  for (int i = current_process_count; i < num_processes_; ++i) {
+    pipe_fd_[0] = -1;
+    pipe_fd_[1] = -1;
+    if (pipe(pipe_fd_) == -1) {
+      _E("Failed to create pipe. errno(%d)", errno);
+      return;
+    }
+
+    if (fcntl(pipe_fd_[0], F_SETPIPE_SZ, Socket::kSocketMaxBufferSize) == -1)
+      _E("Failed to set pipe size. errno(%d)", errno);
+
+    if (fcntl(pipe_fd_[1], F_SETPIPE_SZ, Socket::kSocketMaxBufferSize) == -1)
+      _E("Failed to set pipe size. errno(%d)", errno);
+
+    pid_t pid = Executor::Execute();
+    if (pid == -1) {
+      _E("Failed to fork process. errno(%d)", errno);
+      close(pipe_fd_[0]);
+      close(pipe_fd_[1]);
+      return;
+    }
+
+    close(pipe_fd_[0]);
+    queue_.push_back(std::make_shared<Process>(pid, pipe_fd_[1]));
+  }
+}
+
+int ProcessPool::WaitForRequest(std::unique_ptr<Socket> socket) {
+  tizen_base::Parcel parcel;
+  int ret = 0;
+  do {
+    size_t data_size = 0;
+    ret = socket->Read(static_cast<void*>(&data_size), sizeof(data_size));
+    if (ret != 0) {
+      _E("Failed to read from socket. error(%d)", ret);
+      return -1;
+    }
+
+    std::vector<uint8_t> data(data_size);
+    ret = socket->Read(data.data(), data.size());
+    if (ret != 0) {
+      _E("Failed to read from socket. error(%d)", ret);
+      return -1;
+    }
+
+    parcel.Write(data.data(), data.size());
+  } while (ret != 0);
+
+  if (event_listener_ != nullptr)
+    event_listener_->OnRequestReceived(&parcel);
+
+  return 0;
+}
+
+void ProcessPool::SetTimer() {
+  if (timer_ != 0)
+    return;
+
+  timer_ = g_timeout_add(1000, OnTimeout, this);
+}
+
+void ProcessPool::UnsetTimer() {
+  if (timer_ != 0) {
+    g_source_remove(timer_);
+    timer_ = 0;
+  }
+}
+
+gboolean ProcessPool::OnTimeout(gpointer user_data) {
+  auto* process_pool = static_cast<ProcessPool*>(user_data);
+  process_pool->PrepareProcess();
+  process_pool->timer_ = 0;
+  return G_SOURCE_REMOVE;
+}
+
+int ProcessPool::GetNumberOfProcesses() {
+  config_.Load();
+  return config_.GetNumberOfProcesses();
+}
+
+int ProcessPool::GetNumberOfLoaderProcesses() {
+  config_.Load();
+  return config_.GetNumberOfLoaderProcesses();
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/process_pool.hh b/src/lib/launchpad-core/process_pool.hh
new file mode 100644 (file)
index 0000000..4a12ea1
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2023 - 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_PROCESS_POOL_HH_
+#define LIB_LAUNCHPAD_CORE_PROCESS_POOL_HH_
+
+#include <glib.h>
+#include <sys/types.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <executor.hh>
+#include <parcel.hh>
+#include <socket.hh>
+
+namespace launchpad {
+
+class ProcessPool : public Executor::Delegator,
+                    public Executor {
+ public:
+  class IEvent {
+   public:
+    virtual ~IEvent() = default;
+    virtual void OnRequestReceived(tizen_base::Parcel* parcel) = 0;
+  };
+
+  explicit ProcessPool(std::string name, int num_processes,
+      IEvent* event_listener);
+  virtual ~ProcessPool();
+
+  bool IsPrepared() const;
+  pid_t Execute(const tizen_base::Parcel& parcel);
+  void Dispose();
+  void HandleSigchld(pid_t pid);
+  void SetTimer();
+
+  static int GetNumberOfProcesses();
+  static int GetNumberOfLoaderProcesses();
+
+ private:
+  class Process {
+   public:
+    Process(pid_t pid, int fd);
+
+    pid_t GetPid() const;
+    int Send(const tizen_base::Parcel& parcel);
+    void Kill();
+
+   private:
+    pid_t pid_;
+    std::unique_ptr<Socket> socket_;
+  };
+
+  void OnExecution() override;
+  void UnsetTimer();
+  void PrepareProcess();
+  int WaitForRequest(std::unique_ptr<Socket> socket);
+  static gboolean OnTimeout(gpointer user_data);
+
+ private:
+  std::string name_;
+  int num_processes_;
+  IEvent* event_listener_;
+  int pipe_fd_[2] = { -1, -1 };
+  std::vector<std::shared_ptr<Process>> queue_;
+  guint timer_ = 0;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_PROCESS_POOL_HH_
diff --git a/src/lib/launchpad-core/rec_mutex.hh b/src/lib/launchpad-core/rec_mutex.hh
new file mode 100644 (file)
index 0000000..1e2abaf
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2023 - 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_REC_MUTEX_HH_
+#define LIB_LAUNCHPAD_CORE_REC_MUTEX_HH_
+
+#include <mutex>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API RecMutex {
+ public:
+  static RecMutex& GetInst() {
+    static RecMutex inst;
+    return inst;
+  }
+
+  std::recursive_mutex& GetMutex() const {
+    return mutex_;
+  }
+
+ private:
+  RecMutex() = default;
+  ~RecMutex() = default;
+
+ private:
+  mutable std::recursive_mutex mutex_;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_REC_MUTEX_HH_
diff --git a/src/lib/launchpad-core/sigchld_manager.cc b/src/lib/launchpad-core/sigchld_manager.cc
new file mode 100644 (file)
index 0000000..502e4a5
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2024 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 "launchpad-core/sigchld_manager.hh"
+
+#include <signal.h>
+#include <sys/signalfd.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "launchpad-core/log_private.hh"
+
+namespace {
+
+sigset_t mask_;
+sigset_t old_mask_;
+
+}  // namespace
+
+namespace launchpad {
+
+int SigchldManager::BlockSigchld() {
+  sigemptyset(&mask_);
+  sigaddset(&mask_, SIGCHLD);
+  if (sigprocmask(SIG_BLOCK, &mask_, &old_mask_) < 0) {
+    int ret = -errno;
+    _E("sigprocmask(SIG_BLOCK) is failed. errno(%d)", errno);
+    return ret;
+  }
+
+  return 0;
+}
+
+void SigchldManager::UnblockSigchld() {
+  if (sigprocmask(SIG_SETMASK, &old_mask_, nullptr) < 0)
+    _E("sigprocmask(SIG_SETMASK) is failed. errno(%d)", errno);
+}
+
+int SigchldManager::GetSigchldFd() {
+  int sfd = signalfd(-1, &mask_, SFD_NONBLOCK | SFD_CLOEXEC);
+  if (sfd < 0) {
+    sfd = -errno;
+    _E("signalfd() is failed. errno(%d)", errno);
+  }
+
+  return sfd;
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/sigchld_manager.hh b/src/lib/launchpad-core/sigchld_manager.hh
new file mode 100644 (file)
index 0000000..a26902c
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2024 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.
+ */
+
+#ifndef LIB_LAUNCHPAD_CORE_SIGCHLD_MANAGER_HH_
+#define LIB_LAUNCHPAD_CORE_SIGCHLD_MANAGER_HH_
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API SigchldManager {
+ public:
+  static int BlockSigchld();
+  static void UnblockSigchld();
+  static int GetSigchldFd();
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_SIGCHLD_MANAGER_HH_
\ No newline at end of file
index 46357bf12e2e924dbc95cc035f9a76827f384a9a..a36e12eb0608c14d0e76e4b9b4ee58716d978df1 100644 (file)
 #include <unistd.h>
 
 #include <algorithm>
+#include <cctype>
 #include <filesystem>
 #include <fstream>
 #include <memory>
+#include <regex>
 #include <string>
 #include <utility>
 #include <vector>
@@ -628,4 +630,21 @@ int Util::SendCmdToAmd(enum AmdCmd cmd, bundle* request, int opt) {
   return 0;
 }
 
+std::vector<std::string> Util::Split(const std::string& str,
+                                     const std::string& delim) {
+  const std::regex deli("[^" + delim + "]+");
+  std::vector<std::string> result;
+  for (auto i = std::sregex_iterator(str.begin(), str.end(), deli);
+       i != std::sregex_iterator(); ++i)
+    result.push_back((*i).str());
+
+  return result;
+}
+
+std::string Util::ToUpper(std::string str) {
+  std::string result = std::move(str);
+  std::transform(result.begin(), result.end(), result.begin(), ::toupper);
+  return result;
+}
+
 }  // namespace launchpad
index 9619d63ae91e418c1ccbddd16658a056d3608dd3..5750c1f932668bc3b64c0fc099ab15b9031cc764 100644 (file)
 
 namespace launchpad {
 
+template <typename E>
+E operator|(E a, E b) {
+  return static_cast<E>(static_cast<int>(a) | static_cast<int>(b));
+}
+
+template <typename E>
+bool operator==(E a, int x) {
+  return static_cast<int>(a) == x;
+}
+
+template <typename E>
+int operator&(int a, E b) {
+  return a & static_cast<int>(b);
+}
+
 class EXPORT_API Util {
  public:
   static void SetEnvironments(const AppInfo* app_info);
@@ -50,6 +65,9 @@ class EXPORT_API Util {
   static int SendCmdToAmd(enum AmdCmd cmd);
   static int SendCmdToAmd(enum AmdCmd cmd, bundle* request, int opt);
   static int MountLibraryDirectories(const tizen_base::Bundle& b);
+  static std::vector<std::string> Split(const std::string& str,
+                                        const std::string& delim);
+  static std::string ToUpper(std::string str);
 };
 
 }  // namespace launchpad
index 9dd8db52985fa837ecb0dd9f1e4c3957bbe22c62..6c4a7994c06a35f300361496b30676acd09712bd 100644 (file)
@@ -21,6 +21,7 @@ TARGET_INCLUDE_DIRECTORIES(${TARGET_LAUNCHPAD_PROCESS_POOL_UNITTEST} PUBLIC
   ${CMAKE_CURRENT_SOURCE_DIR}/../../src/lib/common/inc
   ${CMAKE_CURRENT_SOURCE_DIR}/../../src/
   ${CMAKE_CURRENT_SOURCE_DIR}/../../src/lib/launchpad-common
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../src/lib/launchpad-core
   ${CMAKE_CURRENT_SOURCE_DIR}/../../src/lib/launchpad-glib
 )
 
@@ -45,7 +46,8 @@ APPLY_PKG_CONFIG(${TARGET_LAUNCHPAD_PROCESS_POOL_UNITTEST} PUBLIC
 
 SET_TARGET_PROPERTIES(${TARGET_LAUNCHPAD_PROCESS_POOL_UNITTEST}
   PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}")
-TARGET_LINK_LIBRARIES(${TARGET_LAUNCHPAD_PROCESS_POOL_UNITTEST}
-  PUBLIC ${TARGET_LAUNCHPAD_COMMON} ${TARGET_LAUNCHPAD_GLIB} "-ldl")
+TARGET_LINK_LIBRARIES(${TARGET_LAUNCHPAD_PROCESS_POOL_UNITTEST} PUBLIC
+  ${TARGET_LAUNCHPAD_COMMON} ${TARGET_LAUNCHPAD_CORE} ${TARGET_LAUNCHPAD_GLIB}
+  "-ldl")
 
 INSTALL(TARGETS ${TARGET_LAUNCHPAD_PROCESS_POOL_UNITTEST} DESTINATION /usr/bin/)
index 36f92336a795baa51f16d795a30591c514a6d49a..2de5f852c28d72f74eb40fc26e28a0a58628f123 100644 (file)
@@ -23,9 +23,9 @@
 #include <fstream>
 #include <string>
 
-#include "launchpad-process-pool/debugger_info.hh"
-#include "launchpad-process-pool/launcher_info.hh"
-#include "launchpad-process-pool/loader_info.hh"
+#include "launchpad-core/debugger_info.hh"
+#include "launchpad-core/launcher_info.hh"
+#include "launchpad-core/loader_info.hh"
 
 using ::testing::AtLeast;
 using namespace launchpad;