Add a new sub moudle for creating children processes 80/317080/28
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 3 Sep 2024 23:32:29 +0000 (08:32 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Thu, 19 Sep 2024 01:32:55 +0000 (10:32 +0900)
Currently, the launchpad-process-pool has a problem about using threads.
It causes the deadlock issue of children processes.
The 'Lux' is added. It operates as a single thread and is responsible for
creating child processes.

Change-Id: Ie768efba1877069a968f367e2553cd5c0ad6f286
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
143 files changed:
CMakeLists.txt
packaging/launchpad.manifest
packaging/launchpad.spec
src/app-defined-loader/CMakeLists.txt
src/launchpad-loader/CMakeLists.txt
src/launchpad-process-pool/CMakeLists.txt
src/launchpad-process-pool/app_defined_loader_info_manager.cc
src/launchpad-process-pool/app_defined_loader_info_manager.hh
src/launchpad-process-pool/app_executor.cc [new file with mode: 0644]
src/launchpad-process-pool/app_executor.hh [new file with mode: 0644]
src/launchpad-process-pool/app_labels_monitor.cc
src/launchpad-process-pool/config.cc
src/launchpad-process-pool/config.hh
src/launchpad-process-pool/cpu_checker.cc
src/launchpad-process-pool/dbus.cc
src/launchpad-process-pool/debug.cc [new file with mode: 0644]
src/launchpad-process-pool/debug.hh [new file with mode: 0644]
src/launchpad-process-pool/debugger_info.cc [new file with mode: 0644]
src/launchpad-process-pool/debugger_info.hh [new file with mode: 0644]
src/launchpad-process-pool/executor.cc [new file with mode: 0644]
src/launchpad-process-pool/executor.hh [new file with mode: 0644]
src/launchpad-process-pool/file_monitor.cc [new file with mode: 0644]
src/launchpad-process-pool/file_monitor.hh [new file with mode: 0644]
src/launchpad-process-pool/hydra_loader_context.cc
src/launchpad-process-pool/hydra_sigchld_event.cc
src/launchpad-process-pool/hydra_sigchld_event.hh
src/launchpad-process-pool/launcher_info.cc [new file with mode: 0644]
src/launchpad-process-pool/launcher_info.hh [new file with mode: 0644]
src/launchpad-process-pool/launchpad.cc
src/launchpad-process-pool/launchpad.hh
src/launchpad-process-pool/launchpad_args.cc [new file with mode: 0644]
src/launchpad-process-pool/launchpad_args.hh [new file with mode: 0644]
src/launchpad-process-pool/loader_context.cc
src/launchpad-process-pool/loader_context.hh
src/launchpad-process-pool/loader_executor.cc [new file with mode: 0644]
src/launchpad-process-pool/loader_executor.hh [new file with mode: 0644]
src/launchpad-process-pool/loader_factory.cc
src/launchpad-process-pool/loader_factory.hh
src/launchpad-process-pool/loader_info.cc [new file with mode: 0644]
src/launchpad-process-pool/loader_info.hh [new file with mode: 0644]
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/log.cc
src/launchpad-process-pool/logger.cc
src/launchpad-process-pool/lux_manager.cc [new file with mode: 0644]
src/launchpad-process-pool/lux_manager.hh [new file with mode: 0644]
src/launchpad-process-pool/memory_monitor.cc
src/launchpad-process-pool/memory_monitor.hh
src/launchpad-process-pool/process_pool.cc [new file with mode: 0644]
src/launchpad-process-pool/process_pool.hh [new file with mode: 0644]
src/launchpad-process-pool/request.cc
src/launchpad-process-pool/sequencer.cc
src/launchpad-process-pool/sigchld_event.cc
src/launchpad-process-pool/sigchld_manager.cc [new file with mode: 0644]
src/launchpad-process-pool/sigchld_manager.hh [new file with mode: 0644]
src/launchpad-process-pool/signal_manager.cc
src/launchpad-process-pool/signal_manager.hh
src/launchpad-process-pool/tracer.hh
src/launchpad-process-pool/worker.cc
src/lib/CMakeLists.txt
src/lib/launchpad-common/aul_keys.hh
src/lib/launchpad-common/types.hh
src/lib/launchpad-core/CMakeLists.txt
src/lib/launchpad-core/app_executor.cc [deleted file]
src/lib/launchpad-core/app_executor.hh [deleted file]
src/lib/launchpad-core/app_executor_internal.cc [new file with mode: 0644]
src/lib/launchpad-core/app_executor_internal.hh [new file with mode: 0644]
src/lib/launchpad-core/app_info.cc [new file with mode: 0644]
src/lib/launchpad-core/app_info.hh [new file with mode: 0644]
src/lib/launchpad-core/debug.cc [deleted file]
src/lib/launchpad-core/debug.hh [deleted file]
src/lib/launchpad-core/debug_internal.cc [new file with mode: 0644]
src/lib/launchpad-core/debug_internal.hh [new file with mode: 0644]
src/lib/launchpad-core/debugger_info.cc [deleted file]
src/lib/launchpad-core/debugger_info.hh [deleted file]
src/lib/launchpad-core/executor.cc [deleted file]
src/lib/launchpad-core/executor.hh [deleted file]
src/lib/launchpad-core/file_monitor.cc [deleted file]
src/lib/launchpad-core/file_monitor.hh [deleted file]
src/lib/launchpad-core/hw_acceleration_config.cc [new file with mode: 0644]
src/lib/launchpad-core/hw_acceleration_config.hh [new file with mode: 0644]
src/lib/launchpad-core/include/launchpad_core.h [new file with mode: 0644]
src/lib/launchpad-core/io_channel.cc [new file with mode: 0644]
src/lib/launchpad-core/io_channel.hh [new file with mode: 0644]
src/lib/launchpad-core/language_config.cc [new file with mode: 0644]
src/lib/launchpad-core/language_config.hh [new file with mode: 0644]
src/lib/launchpad-core/launcher_info.cc [deleted file]
src/lib/launchpad-core/launcher_info.hh [deleted file]
src/lib/launchpad-core/launchpad_args.cc [deleted file]
src/lib/launchpad-core/launchpad_args.hh [deleted file]
src/lib/launchpad-core/launchpad_core.cc [new file with mode: 0644]
src/lib/launchpad-core/loader_executor.cc [deleted file]
src/lib/launchpad-core/loader_executor.hh [deleted file]
src/lib/launchpad-core/loader_executor_internal.cc [new file with mode: 0644]
src/lib/launchpad-core/loader_executor_internal.hh [new file with mode: 0644]
src/lib/launchpad-core/loader_info.cc [deleted file]
src/lib/launchpad-core/loader_info.hh [deleted file]
src/lib/launchpad-core/log_private.hh
src/lib/launchpad-core/plugin.cc [new file with mode: 0644]
src/lib/launchpad-core/plugin.hh [new file with mode: 0644]
src/lib/launchpad-core/process_pool.cc [deleted file]
src/lib/launchpad-core/process_pool.hh [deleted file]
src/lib/launchpad-core/process_pool_internal.cc [new file with mode: 0644]
src/lib/launchpad-core/process_pool_internal.hh [new file with mode: 0644]
src/lib/launchpad-core/rec_mutex.hh [deleted file]
src/lib/launchpad-core/region_format_config.cc [new file with mode: 0644]
src/lib/launchpad-core/region_format_config.hh [new file with mode: 0644]
src/lib/launchpad-core/sigchld_manager.cc [deleted file]
src/lib/launchpad-core/sigchld_manager.hh [deleted file]
src/lib/launchpad-core/util.cc [new file with mode: 0644]
src/lib/launchpad-core/util.hh [new file with mode: 0644]
src/lib/launchpad-core/vconf.cc [new file with mode: 0644]
src/lib/launchpad-core/vconf.hh [new file with mode: 0644]
src/lib/launchpad-glib/CMakeLists.txt [deleted file]
src/lib/launchpad-glib/app_info.cc [deleted file]
src/lib/launchpad-glib/app_info.hh [deleted file]
src/lib/launchpad-glib/hw_acceleration_config.cc [deleted file]
src/lib/launchpad-glib/hw_acceleration_config.hh [deleted file]
src/lib/launchpad-glib/io_channel.cc [deleted file]
src/lib/launchpad-glib/io_channel.hh [deleted file]
src/lib/launchpad-glib/language_config.cc [deleted file]
src/lib/launchpad-glib/language_config.hh [deleted file]
src/lib/launchpad-glib/log_private.hh [deleted file]
src/lib/launchpad-glib/pkgconfig/liblaunchpad-glib.pc.in [deleted file]
src/lib/launchpad-glib/plugin.cc [deleted file]
src/lib/launchpad-glib/plugin.hh [deleted file]
src/lib/launchpad-glib/region_format_config.cc [deleted file]
src/lib/launchpad-glib/region_format_config.hh [deleted file]
src/lib/launchpad-glib/util.cc [deleted file]
src/lib/launchpad-glib/util.hh [deleted file]
src/lib/launchpad-glib/vconf.cc [deleted file]
src/lib/launchpad-glib/vconf.hh [deleted file]
src/lib/launchpad/CMakeLists.txt
src/lux/Cargo.toml [new file with mode: 0644]
src/lux/src/dlog_wrapper.rs [new file with mode: 0644]
src/lux/src/lux/app_labels_monitor.rs [new file with mode: 0644]
src/lux/src/lux/mod.rs [new file with mode: 0644]
src/lux/src/lux/sigchld_manager.rs [new file with mode: 0644]
src/lux/src/main.rs [new file with mode: 0644]
tests/launchpad-process-pool-unittest/CMakeLists.txt
tests/launchpad-process-pool-unittest/src/test_launchpad.cc

index 8d74456933671f8636975cc001f60b62501a1ddc..42d47ba357a95164ece24c7b7a4e2ba2aac79341 100644 (file)
@@ -38,12 +38,12 @@ 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")
 SET(TARGET_LAUNCHPAD_PARSER "launchpad-parser")
 SET(TARGET_LAUNCHPAD_PROCESS_POOL "launchpad-process-pool")
 SET(TARGET_LAUNCHPAD_PROCESS_POOL_UNITTEST "launchpad-process-pool-unittest")
+SET(TARGET_LUX "lux")
 
 SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
   "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
index 169d436649be33e038d6291f92007799706fa019..91c1fbb0218b38e69455401fef07147c86986617 100644 (file)
@@ -4,5 +4,6 @@
        </request>
        <assign>
                <filesystem path="/usr/bin/launchpad-process-pool" label="User" exec_label="System::Privileged" />
+               <filesystem path="/usr/bin/lux" label="User" exec_label="System::Privileged" />
        </assign>
 </manifest>
index c3cf546b61bde98dede4268226454f8007395e1f..2190e2a5524d19931b2f85ce5133fb3748f95337 100644 (file)
@@ -38,6 +38,12 @@ BuildRequires:  pkgconfig(tizen-shared-queue)
 BuildRequires:  pkgconfig(ttrace)
 BuildRequires:  pkgconfig(vconf)
 
+BuildRequires:  rust
+BuildRequires:  rust-libc
+BuildRequires:  rust-glib-sys
+BuildRequires:  rust-tizen-bundle
+BuildRequires:  rust-tizen-parcel
+
 Requires(post): /sbin/ldconfig
 Requires(post): /usr/bin/systemctl
 Requires(postun): /sbin/ldconfig
@@ -46,6 +52,9 @@ Requires(preun): /usr/bin/systemctl
 Requires(posttrans): /usr/bin/echo
 Requires(posttrans): /usr/bin/sed
 
+Requires:  rust-tizen-bundle
+Requires:  rust-tizen-parcel
+
 Provides: app-launchpad
 
 %define tizen_feature_priority_change 0
@@ -67,6 +76,9 @@ Provides: app-launchpad
 %define tizen_feature_prelink 0
 %endif
 
+%global real_crate_name rust_lux
+%global rustc_edition 2021
+
 %description
 Launchpad for launching applications
 
@@ -155,6 +167,14 @@ MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
        .
 %__make %{?_smp_mflags}
 
+export LD_LIBRARY_PATH="./src/lib/launchpad-common/:./src/lib/launchpad-glib:./src/lib/launchpad-core"
+%{rustc_std_build} --crate-type=bin \
+       --crate-name=%{real_crate_name} \
+       -L native="./src/lib/launchpad-core" \
+       %{?rustc_edition:--edition=%{rustc_edition}} \
+       %rust_dylib_extern libc \
+       ./src/lux/src/main.rs
+
 %check
 export LD_LIBRARY_PATH="../../src/lib/launchpad-common/:../../src/lib/launchpad-glib:../../src/lib/launchpad-core"
 ctest --verbose %{?_smp_mflags}
@@ -162,7 +182,6 @@ ctest --verbose %{?_smp_mflags}
 %install
 rm -rf %{buildroot}
 
-
 %make_install
 mkdir -p %{buildroot}%{_userunitdir}/basic.target.wants
 mkdir -p %{buildroot}%{_userunitdir}/sockets.target.wants
@@ -171,6 +190,9 @@ install -m 0644 %SOURCE102 %{buildroot}%{_userunitdir}/launchpad-process-pool.so
 ln -sf ../launchpad-process-pool.socket %{buildroot}%{_userunitdir}/sockets.target.wants/launchpad-process-pool.socket
 ln -sf ../launchpad-process-pool.service %{buildroot}%{_userunitdir}/basic.target.wants/launchpad-process-pool.service
 
+install -d -m 0755 %{buildroot}%{_bindir}
+install -m 0755 ./%{real_crate_name} %{buildroot}%{_bindir}/lux
+
 %post
 ln -sf /usr/bin/false /usr/bin/process-pool
 
@@ -196,20 +218,17 @@ fi
 %{_sysconfdir}/package-manager/parserlib/liblaunchpad-parser.so
 %{_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.*
+%caps(cap_dac_override,cap_setgid,cap_sys_chroot,cap_sys_admin,cap_sys_nice,cap_mac_admin=ei) %{_bindir}/lux
 
 %files devel
 %{_includedir}/launchpad/*.h
 %{_includedir}/launchpad-common/*.hh
-%{_includedir}/launchpad-core/*.hh
-%{_includedir}/launchpad-glib/*.hh
+%{_includedir}/launchpad-core/*
 %{_libdir}/*.so
 %{_libdir}/pkgconfig/launchpad.pc
 %attr(0644,root,root) %{_libdir}/liblaunchpad-common.so
 %{_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
 
index 8edd568020ae1739e10f8293eade1d3793d94b9e..09a003964bcb7e27b310451806d99c8a1ab21ae3 100644 (file)
@@ -32,7 +32,7 @@ APPLY_PKG_CONFIG(${TARGET_APP_DEFINED_LOADER} PUBLIC
 )
 
 TARGET_LINK_LIBRARIES(${TARGET_APP_DEFINED_LOADER} PRIVATE
-  ${TARGET_LAUNCHPAD} ${TARGET_LAUNCHPAD_GLIB})
+  ${TARGET_LAUNCHPAD} ${TARGET_LAUNCHPAD_CORE})
 
 # To support 2.x applications which use their own shared libraries.
 # Since we cannot set LD_LIBRARY_PATH directly by security issue, we make the
index 890a26695bd7fcee1e2c2cd1a36e2beabf2b1294..a0dfb8a36a38a90a5a94439038ec71c5565060b7 100644 (file)
@@ -35,7 +35,7 @@ APPLY_PKG_CONFIG(${TARGET_LAUNCHPAD_LOADER} PUBLIC
 )
 
 TARGET_LINK_LIBRARIES(${TARGET_LAUNCHPAD_LOADER} PRIVATE
-  ${TARGET_LAUNCHPAD} ${TARGET_LAUNCHPAD_GLIB})
+  ${TARGET_LAUNCHPAD} ${TARGET_LAUNCHPAD_CORE})
 
 # To support 2.x applications which use their own shared libraries.
 # Since we cannot set LD_LIBRARY_PATH directly by security issue, we make the
index 84e6098d4730ff15ed96fb7cbf42d97309f8fd14..3d861cc6724770164b3059a6ccc04ea2f22c5f78 100644 (file)
@@ -15,7 +15,7 @@ TARGET_INCLUDE_DIRECTORIES(${TARGET_LAUNCHPAD_PROCESS_POOL} PUBLIC
   ${CMAKE_CURRENT_SOURCE_DIR}/../lib/common/inc
   ${CMAKE_CURRENT_SOURCE_DIR}/../lib/launchpad-common
   ${CMAKE_CURRENT_SOURCE_DIR}/../lib/launchpad-core
-  ${CMAKE_CURRENT_SOURCE_DIR}/../lib/launchpad-glib  
+  ${CMAKE_CURRENT_SOURCE_DIR}/../lib/launchpad-glib
 )
 
 IF(_TIZEN_FEATURE_PRELINK)
index 8905303995f6d6135f6b465836512b1410d27cfa..f129d05d97c4fee02a077d019a63b9109e865be6 100644 (file)
@@ -43,26 +43,22 @@ void AppDefinedLoaderInfoManager::SetEventListener(
 }
 
 void AppDefinedLoaderInfoManager::OnFileChanged(const std::string_view name,
-    FileMonitor::Event event) {
+                                                FileMonitor::Event event) {
   auto pos = name.rfind('.');
-  if (pos == std::string_view::npos)
-    return;
+  if (pos == std::string_view::npos) return;
 
   std::string_view filename = name.substr(0, pos);
   std::string_view extension = name.substr(pos + 1);
-  if (extension != "loader")
-    return;
+  if (extension != "loader") return;
 
   _W("name: %s, event: %d", name.data(), static_cast<int>(event));
   if (event == FileMonitor::Event::Created) {
     info_manager_->LoadFile(name);
     UpdateLoaderInfo();
-    if (listener_ != nullptr)
-      listener_->OnLoaderInfoAdded(filename);
+    if (listener_ != nullptr) listener_->OnLoaderInfoAdded(filename);
   } else if (event == FileMonitor::Event::Deleted) {
     info_manager_->Unload(filename);
-    if (listener_ != nullptr)
-      listener_->OnLoaderInfoRemoved(filename);
+    if (listener_ != nullptr) listener_->OnLoaderInfoRemoved(filename);
   }
 }
 
@@ -71,12 +67,12 @@ void AppDefinedLoaderInfoManager::UpdateLoaderInfo() {
     auto& loader_info = const_cast<std::shared_ptr<LoaderInfo>&>(loader);
     loader_info->SetType(LoaderType::Dynamic);
     loader_info->SetExe(kAppDefinedLoaderPath);
-    loader_info->SetDetectionMethod(
-        LoaderMethod::Timeout | LoaderMethod::Visibility);
-    loader_info->SetActivationMethod(
-        LoaderMethod::Request | LoaderMethod::AvailableMemory);
-    loader_info->SetDeactivationMethod(
-        LoaderMethod::TimeToLive | LoaderMethod::OutOfMemory);
+    loader_info->SetDetectionMethod(LoaderMethod::Timeout |
+                                    LoaderMethod::Visibility);
+    loader_info->SetActivationMethod(LoaderMethod::Request |
+                                     LoaderMethod::AvailableMemory);
+    loader_info->SetDeactivationMethod(LoaderMethod::TimeToLive |
+                                       LoaderMethod::OutOfMemory);
     loader_info->SetTimeout(2000);
     loader_info->SetAppInstalled(true);
   }
index 7a2cdd6e6ae366e89230a8c105ddb2fb21573181..7c60c3073dc055dd33f3ecfb2815dac169ea40fd 100644 (file)
@@ -20,8 +20,8 @@
 #include <memory>
 #include <string_view>
 
-#include <file_monitor.hh>
-#include <loader_info.hh>
+#include "launchpad-process-pool/file_monitor.hh"
+#include "launchpad-process-pool/loader_info.hh"
 
 namespace launchpad {
 
@@ -41,7 +41,7 @@ class AppDefinedLoaderInfoManager : public FileMonitor::IEvent {
 
  private:
   void OnFileChanged(const std::string_view name,
-      FileMonitor::Event event) override;
+                     FileMonitor::Event event) override;
   void UpdateLoaderInfo();
 
  private:
diff --git a/src/launchpad-process-pool/app_executor.cc b/src/launchpad-process-pool/app_executor.cc
new file mode 100644 (file)
index 0000000..c226250
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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-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 <string>
+#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/lux_manager.hh"
+
+namespace launchpad {
+namespace fs = std::filesystem;
+
+AppExecutor::AppExecutor() {
+  LauncherInfoInflator inflator;
+  launcher_infos_ = inflator.Inflate("/usr/share/aul");
+  auto& config = Config::GetInst().GetProcessPool();
+  process_pool_ = std::unique_ptr<ProcessPool>(
+      new ProcessPool("app", config.GetNumberOfProcesses()));
+}
+
+pid_t AppExecutor::Execute(const AppInfo* app_info) {
+  auto& b = const_cast<tizen_base::Bundle&>(app_info->GetBundle());
+  if (b.GetType(kAulSdk) != BUNDLE_TYPE_NONE)
+    Debug::GetInst().PrepareDebugger(b);
+
+  auto app_args =
+      CreateAppArgv(app_info->GetAppPath(), b, app_info->GetAppType());
+  b.Add(kAulAppArgs, app_args);
+  b.Add(kAulLuxCmd, std::to_string(static_cast<int>(LuxCmd::ExecuteApp)));
+
+  tizen_base::Parcel parcel = Util::CreateParcelFromBundle(&b);
+  if (process_pool_->IsPrepared()) {
+    pid_t pid = process_pool_->Execute(parcel);
+    if (pid > 0) return pid;
+  }
+
+  return LuxManager::GetInst().SendAndReceive(parcel);
+}
+
+void AppExecutor::DisposeCandidateProcess() {
+  process_pool_->Dispose();
+  process_pool_->SetTimer();
+}
+
+void AppExecutor::HandleSigchld(pid_t pid) {
+  process_pool_->HandleSigchld(pid);
+}
+
+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
new file mode 100644 (file)
index 0000000..7ce8585
--- /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.
+ */
+
+#ifndef LAUNCHPAD_PROCESS_POOL_APP_EXECUTOR_HH_
+#define LAUNCHPAD_PROCESS_POOL_APP_EXECUTOR_HH_
+
+#include <bundle_cpp.h>
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <app_info.hh>
+
+#include "launchpad-process-pool/launcher_info.hh"
+#include "launchpad-process-pool/process_pool.hh"
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class AppExecutor {
+ public:
+  AppExecutor();
+
+  pid_t Execute(const AppInfo* app_info);
+  void DisposeCandidateProcess();
+  void HandleSigchld(pid_t pid);
+
+ private:
+  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:
+  std::vector<LauncherInfoPtr> launcher_infos_;
+  std::unique_ptr<ProcessPool> process_pool_;
+};
+
+}  // namespace launchpad
+
+#endif  // LAUNCHPAD_PROCESS_POOL_APP_EXECUTOR_HH_
index 7382376e7a69b203f4428b1d27440a156c1ffa6f..c4736e810ef62bd0debbb373dc69d33bd3e27419 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <exception.hh>
 
-#include "launchpad-process-pool/log.hh"
 #include "launchpad-process-pool/log_private.hh"
 
 namespace launchpad {
@@ -28,13 +27,10 @@ AppLabelsMonitor& AppLabelsMonitor::GetInst() {
   return inst;
 }
 
-AppLabelsMonitor::~AppLabelsMonitor() {
-  Dispose();
-}
+AppLabelsMonitor::~AppLabelsMonitor() { Dispose(); }
 
 void AppLabelsMonitor::Init() {
-  if (!disposed_)
-    return;
+  if (!disposed_) return;
 
   app_labels_monitor* monitor = nullptr;
   int ret = security_manager_app_labels_monitor_init(&monitor);
@@ -45,8 +41,8 @@ void AppLabelsMonitor::Init() {
 
   auto monitor_auto =
       std::unique_ptr<app_labels_monitor,
-          decltype(security_manager_app_labels_monitor_finish)*>(
-              monitor, security_manager_app_labels_monitor_finish);
+                      decltype(security_manager_app_labels_monitor_finish)*>(
+          monitor, security_manager_app_labels_monitor_finish);
 
   ret = security_manager_app_labels_monitor_process(monitor);
   if (ret != SECURITY_MANAGER_SUCCESS) {
@@ -61,15 +57,14 @@ void AppLabelsMonitor::Init() {
     return;
   }
 
-  channel_ = std::make_unique<IOChannel>(fd, IOChannel::IOCondition::IO_IN,
-      this);
+  channel_ =
+      std::make_unique<IOChannel>(fd, IOChannel::IOCondition::IO_IN, this);
   handle_ = monitor_auto.release();
   disposed_ = false;
 }
 
 void AppLabelsMonitor::Dispose() {
-  if (disposed_)
-    return;
+  if (disposed_) return;
 
   security_manager_app_labels_monitor_finish(handle_);
   handle_ = nullptr;
@@ -80,17 +75,12 @@ void AppLabelsMonitor::SetEventListener(IEvent* listener) {
   listener_ = listener;
 }
 
-bool AppLabelsMonitor::IsDisposed() const {
-  return disposed_;
-}
+bool AppLabelsMonitor::IsDisposed() const { return disposed_; }
 
 void AppLabelsMonitor::OnIOEventReceived(int fd, int condition) {
   _D("fd(%d), condition(%d)", fd, condition);
-  Log::Print("[APP_LABELS]", "fd(%d), condition(%d)", fd, condition);
   security_manager_app_labels_monitor_process(handle_);
-
-  if (listener_ != nullptr)
-    listener_->OnAppLabelsChanged();
+  if (listener_ != nullptr) listener_->OnAppLabelsChanged();
 }
 
 }  // namespace launchpad
index efac39ddd0564e24271b723ab8873782c2934e19..135cd1c2555e4e7665f98cf4d92821ef4c762983 100644 (file)
@@ -45,6 +45,11 @@ 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";
@@ -57,51 +62,38 @@ constexpr const char kValueModeAlwaysLoaderWithLowPriority[] =
 
 }  // namespace
 
-const std::string& Config::MemoryStatus::GetLowKey() const {
-  return low_key_;
-}
+const std::string& Config::MemoryStatus::GetLowKey() const { return low_key_; }
 
-const int Config::MemoryStatus::GetLowValue() const {
-  return low_value_;
-}
+const int Config::MemoryStatus::GetLowValue() const { return low_value_; }
 
 const std::string& Config::MemoryStatus::GetNormalKey() const {
   return normal_key_;
 }
 
-const int Config::MemoryStatus::GetNormalValue() const {
-  return normal_value_;
-}
+const int Config::MemoryStatus::GetNormalValue() const { return normal_value_; }
 
 Config::MemoryStatus::MemoryStatus(const IniParser& parser) {
   auto low_key = parser.Get(kTagMemoryStatus, kKeyMemoryStatusLowKey);
-  if (!low_key.empty())
-    low_key_ = std::move(low_key);
+  if (!low_key.empty()) low_key_ = std::move(low_key);
 
   auto low_value = parser.Get(kTagMemoryStatus, kKeyMemoryStatusLowValue);
   if (!low_value.empty() && std::isdigit(low_value[0]))
     low_value_ = std::stoi(low_value);
 
   auto normal_key = parser.Get(kTagMemoryStatus, kKeyMemoryStatusNormalKey);
-  if (!normal_key.empty())
-    normal_key_ = std::move(normal_key);
+  if (!normal_key.empty()) normal_key_ = std::move(normal_key);
 
-  auto normal_value = parser.Get(kTagMemoryStatus,
-      kKeyMemoryStatusNormalValue);
+  auto normal_value = parser.Get(kTagMemoryStatus, kKeyMemoryStatusNormalValue);
   if (!normal_value.empty() && std::isdigit(normal_value[0]))
     normal_value_ = std::stoi(normal_value);
 
-  _W("[MemoryStatus] Low: %s:%d, Normal: %s:%d",
-      low_key_.c_str(), low_value_, normal_key_.c_str(), normal_value_);
+  _W("[MemoryStatus] Low: %s:%d, Normal: %s:%d", low_key_.c_str(), low_value_,
+     normal_key_.c_str(), normal_value_);
 }
 
-const int Config::MemoryMonitor::GetThreshold() const {
-  return threshold_;
-}
+const int Config::MemoryMonitor::GetThreshold() const { return threshold_; }
 
-const int Config::MemoryMonitor::GetInterval() const {
-  return interval_;
-}
+const int Config::MemoryMonitor::GetInterval() const { return interval_; }
 
 Config::MemoryMonitor::MemoryMonitor(const IniParser& parser) {
   auto threshold = parser.Get(kTagMemoryMonitor, kKeyMemoryMonitorThreshold);
@@ -115,9 +107,7 @@ Config::MemoryMonitor::MemoryMonitor(const IniParser& parser) {
   _W("[MemoryMonitor] thrshold: %d, interval: %d", threshold_, interval_);
 }
 
-const int Config::CPUChecker::GetMaxCount() const {
-  return max_count_;
-}
+const int Config::CPUChecker::GetMaxCount() const { return max_count_; }
 
 Config::CPUChecker::CPUChecker(const IniParser& parser) {
   auto max_count = parser.Get(kTagCpuChecker, kKeyCpuCheckerMaxCount);
@@ -130,33 +120,50 @@ Config::CPUChecker::CPUChecker(const IniParser& parser) {
   else if (enable == "1" || enable == "true")
     enable_ = true;
 
-  _W("[CPUChecker] max_count: %d, enable: %s",
-      max_count_, enable_ ? "true" : "false");
+  _W("[CPUChecker] max_count: %d, enable: %s", max_count_,
+     enable_ ? "true" : "false");
 }
 
-const bool Config::CPUChecker::IsEnabled() const {
-  return enable_;
-}
+const bool Config::CPUChecker::IsEnabled() const { return enable_; }
 
-const std::string& Config::Logger::GetPath() const {
-  return path_;
-}
+const std::string& Config::Logger::GetPath() const { return path_; }
 
-const bool Config::Logger::IsEnabled() const {
-  return enable_;
-}
+const bool Config::Logger::IsEnabled() const { return enable_; }
 
 Config::Logger::Logger(const IniParser& parser) {
   auto path = parser.Get(kTagLogger, kKeyLoggerPath);
-  if (!path.empty())
-    path_ = std::move(path);
+  if (!path.empty()) path_ = std::move(path);
 
   auto enable = parser.Get(kTagLogger, kKeyLoggerEnable);
   if (!enable.empty() && std::isdigit(enable[0]))
     enable_ = std::stoi(enable) ? true : false;
 
-  _W("[Logger] path: %s, enable: %s",
-      path_.c_str(), enable_ ? "true" : "false");
+  _W("[Logger] path: %s, enable: %s", 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) {
@@ -193,8 +200,8 @@ Config::Config()
       memory_monitor_(Config::MemoryMonitor(parser_)),
       cpu_checker_(Config::CPUChecker(parser_)),
       logger_(Config::Logger(parser_)),
-      launch_mode_(Config::LaunchMode(parser_)) {
-}
+      process_pool_(Config::ProcessPool(parser_)),
+      launch_mode_(Config::LaunchMode(parser_)) {}
 
 const Config::MemoryStatus& Config::GetMemoryStatus() const {
   return memory_status_;
@@ -204,16 +211,14 @@ const Config::MemoryMonitor& Config::GetMemoryMonitor() const {
   return memory_monitor_;
 }
 
-const Config::CPUChecker& Config::GetCPUChecker() const {
-  return cpu_checker_;
-}
+const Config::CPUChecker& Config::GetCPUChecker() const { return cpu_checker_; }
 
-const Config::Logger& Config::GetLogger() const {
-  return logger_;
-}
+const Config::Logger& Config::GetLogger() const { return logger_; }
 
-const Config::LaunchMode& Config::GetLaunchMode() const {
-  return launch_mode_;
+const Config::ProcessPool& Config::GetProcessPool() const {
+  return process_pool_;
 }
 
+const Config::LaunchMode& Config::GetLaunchMode() const { return launch_mode_; }
+
 }  // namespace launchpad
index 1ab8b3915c5ec9f214c2c63767acbb5202a2ccb7..5b5ef43321efaef18365c9e6d175627cfc1dcf6b 100644 (file)
@@ -79,6 +79,18 @@ 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 {
@@ -98,9 +110,9 @@ class Config {
   };
 
   Config(const Config&) = delete;
-  Config& operator = (const Config&) = delete;
+  Config& operator=(const Config&) = delete;
   Config(Config&&) = delete;
-  Config& operator = (Config&&) = delete;
+  Config& operator=(Config&&) = delete;
 
   static Config& GetInst();
 
@@ -108,6 +120,7 @@ class Config {
   const MemoryMonitor& GetMemoryMonitor() const;
   const CPUChecker& GetCPUChecker() const;
   const Logger& GetLogger() const;
+  const ProcessPool& GetProcessPool() const;
   const LaunchMode& GetLaunchMode() const;
 
  private:
@@ -120,6 +133,7 @@ class Config {
   MemoryMonitor memory_monitor_;
   CPUChecker cpu_checker_;
   Logger logger_;
+  ProcessPool process_pool_;
   LaunchMode launch_mode_;
 };
 
index 3777f1c3a9bbcf4f6ff2729a7a2a362ab42d210b..5508b153b10dcceef43491766792e01938f3e0b8 100644 (file)
@@ -58,8 +58,7 @@ void GetCPUIdle(uint64_t* total, uint64_t* idle) {
     }
 
     sum += value;
-    if (i == 3)
-      idle_value = value;
+    if (i == 3) idle_value = value;
   }
 
   *total = sum;
@@ -77,17 +76,14 @@ float Interpolator(float input, int cpu_max, int cpu_min) {
 }  // namespace
 
 CPUChecker::CPUChecker(int threshold_max, int threshold_min)
-    : threshold_max_(threshold_max),
-      threshold_min_(threshold_min) {
-}
+    : threshold_max_(threshold_max), threshold_min_(threshold_min) {}
 
 bool CPUChecker::IsIdle() {
   uint64_t total;
   uint64_t idle;
   GetCPUIdle(&total, &idle);
 
-  if (total == cpu_total_time_)
-    total++;
+  if (total == cpu_total_time_) total++;
 
   auto percentage = CalculatePercentage(idle, total);
   if (percentage >= threshold_) {
@@ -105,19 +101,15 @@ float CPUChecker::CalculatePercentage(uint64_t idle, uint64_t total) {
   return (idle - cpu_idle_time_) * 100 / (total - cpu_total_time_);
 }
 
-void CPUChecker::UpdateCPUIdleTime(uint64_t idle) {
-  cpu_idle_time_ = idle;
-}
+void CPUChecker::UpdateCPUIdleTime(uint64_t idle) { cpu_idle_time_ = idle; }
 
-void CPUChecker::UpdateCPUTotalTime(uint64_t total) {
-  cpu_total_time_ = total;
-}
+void CPUChecker::UpdateCPUTotalTime(uint64_t total) { cpu_total_time_ = total; }
 
 void CPUChecker::UpdateThreshold(float delta) {
   pos_ = std::clamp(pos_ + delta, 0.0f, 1.0f);
   threshold_ = Interpolator(pos_, threshold_max_, threshold_min_) * 100;
-  _D("[CPU] delta: %f, input cursor: %f, threshold: %f",
-      delta, pos_, threshold_);
+  _D("[CPU] delta: %f, input cursor: %f, threshold: %f", delta, pos_,
+     threshold_);
 }
 
 }  // namespace launchpad
index fd25968881fa0c265a39af345fe8eb59fab79dec..0b2713ed76ebe6524deaa2e154822d4f99f46af6 100644 (file)
 
 #include <chrono>
 #include <memory>
+#include <shared-queue.hpp>
 #include <thread>
 #include <utility>
 
-#include <shared-queue.hpp>
-#include <rec_mutex.hh>
-
 #include "launchpad-process-pool/log_private.hh"
 
 namespace launchpad {
@@ -43,16 +41,17 @@ constexpr const char AUL_DBUS_APPLAUNCH_SIGNAL[] = "app_launch";
 class DBusMessage {
  public:
   DBusMessage(std::string path, std::string interface, std::string signal_name,
-              GVariant *param, std::string log_message)
-      : path_(std::move(path)), interface_(std::move(interface)),
-        signal_name_(std::move(signal_name)), param_(param),
+              GVariant* param, std::string log_message)
+      : path_(std::move(path)),
+        interface_(std::move(interface)),
+        signal_name_(std::move(signal_name)),
+        param_(param),
         log_message_(std::move(log_message)) {}
 
   explicit DBusMessage(bool done) : done_(done) {}
 
   ~DBusMessage() {
-    if (param_ != nullptr)
-      g_variant_unref(param_);
+    if (param_ != nullptr) g_variant_unref(param_);
   }
 
   const std::string& GetPath() const { return path_; }
@@ -62,7 +61,7 @@ class DBusMessage {
   const std::string& GetSignalName() const { return signal_name_; }
 
   GVariant* RemoveParam() {
-    GVariant *param = param_;
+    GVariantparam = param_;
     param_ = nullptr;
     return param;
   }
@@ -76,16 +75,16 @@ class DBusMessage {
   std::string path_;
   std::string interface_;
   std::string signal_name_;
-  GVariant *param_ = nullptr;
+  GVariantparam_ = nullptr;
   std::string log_message_;
 };
 
 class DBusManager {
  public:
   DBusManager(const DBusManager&) = delete;
-  DBusManager& operator = (const DBusManager&) = delete;
+  DBusManager& operator=(const DBusManager&) = delete;
   DBusManager(DBusManager&&) = delete;
-  DBusManager& operator = (DBusManager&&) = delete;
+  DBusManager& operator=(DBusManager&&) = delete;
 
   static DBusManager& GetInst() {
     static DBusManager inst;
@@ -93,8 +92,7 @@ class DBusManager {
   }
 
   void Dispose() {
-    if (disposed_)
-      return;
+    if (disposed_) return;
 
     if (getpid() == pid_) {
       queue_->Push(std::make_shared<DBusMessage>(true));
@@ -118,8 +116,7 @@ class DBusManager {
   }
 
   void Init() {
-    if (!disposed_)
-      return;
+    if (!disposed_) return;
 
     queue_ = new tizen_base::SharedQueue<std::shared_ptr<DBusMessage>>();
     thread_ = std::thread([&]() -> void { WorkerThread(); });
@@ -131,17 +128,15 @@ class DBusManager {
   ~DBusManager() { Dispose(); }
 
   GDBusConnection* GetConnection() {
-    if (conn_)
-      return conn_;
+    if (conn_) return conn_;
 
-    std::lock_guard<std::recursive_mutex> lock(RecMutex::GetInst().GetMutex());
     GError* error = nullptr;
     conn_ = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error);
     if (conn_ == nullptr) {
       error_count_++;
       if (error_count_ < ERROR_THRESHOLD || error_count_ % ERROR_MODULO == 0) {
         _E("g_bus_get_sync() is failed. error(%s)",
-            error ? error->message : "Unknown");
+           error ? error->message : "Unknown");
       }
 
       g_clear_error(&error);
@@ -154,17 +149,18 @@ class DBusManager {
   void EmitSignal(std::shared_ptr<DBusMessage> args) {
     GError* error = nullptr;
     if (!g_dbus_connection_emit_signal(conn_, nullptr, args->GetPath().c_str(),
-            args->GetInterface().c_str(), args->GetSignalName().c_str(),
-            args->RemoveParam(), &error)) {
+                                       args->GetInterface().c_str(),
+                                       args->GetSignalName().c_str(),
+                                       args->RemoveParam(), &error)) {
       _E("g_dbus_connection_emit_signal() is failed. error(%s)",
-          error ? error->message : "Unknown");
+         error ? error->message : "Unknown");
       g_clear_error(&error);
       return;
     }
 
     if (!g_dbus_connection_flush_sync(conn_, nullptr, &error)) {
       _E("g_dbus_connection_flush_sync() is failed. error(%s)",
-          error ? error->message : "Unknown");
+         error ? error->message : "Unknown");
       g_clear_error(&error);
       return;
     }
@@ -184,8 +180,7 @@ class DBusManager {
       }
 
       auto message = queue_->WaitAndPop();
-      if (message->IsDone())
-        break;
+      if (message->IsDone()) break;
 
       EmitSignal(message);
     }
@@ -204,11 +199,10 @@ class DBusManager {
 }  // namespace
 
 void DBus::SendAppLaunchSignal(pid_t pid, const std::string_view appid) {
-  DBusManager::GetInst().Send(
-      std::make_shared<DBusMessage>(
-          AUL_DBUS_PATH, AUL_DBUS_SIGNAL_INTERFACE, AUL_DBUS_APPLAUNCH_SIGNAL,
-          g_variant_new("(us)", pid, appid.data()),
-          "App Launch. " + std::to_string(pid) + ":" + std::string(appid)));
+  DBusManager::GetInst().Send(std::make_shared<DBusMessage>(
+      AUL_DBUS_PATH, AUL_DBUS_SIGNAL_INTERFACE, AUL_DBUS_APPLAUNCH_SIGNAL,
+      g_variant_new("(us)", pid, appid.data()),
+      "App Launch. " + std::to_string(pid) + ":" + std::string(appid)));
 }
 
 void DBus::SendAppDeadSignal(pid_t pid, int status) {
@@ -219,12 +213,8 @@ void DBus::SendAppDeadSignal(pid_t pid, int status) {
           ", status: " + std::to_string(status)));
 }
 
-void DBus::Init() {
-  DBusManager::GetInst().Init();
-}
+void DBus::Init() { DBusManager::GetInst().Init(); }
 
-void DBus::Finish() {
-  DBusManager::GetInst().Dispose();
-}
+void DBus::Finish() { DBusManager::GetInst().Dispose(); }
 
 }  // namespace launchpad
diff --git a/src/launchpad-process-pool/debug.cc b/src/launchpad-process-pool/debug.cc
new file mode 100644 (file)
index 0000000..d71a4c3
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * 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-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) {
+  debugger_info_.reset();
+  debug_argv_.clear();
+
+  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;
+  RemoveFiles(debugger_info_->GetUnlinkList());
+
+  const_cast<tizen_base::Bundle&>(b).Add(kAulDebugExtraEnvList,
+                                         debugger_info_->GetExtraEnvList());
+  auto appid = b.GetString(kAulAppId);
+  if (CheckAsanApp(appid))
+    const_cast<tizen_base::Bundle&>(b).Add(kAulTizenAsanActivation, "true");
+
+  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);
+}
+
+bool Debug::CheckAsanApp(const std::string& appid) {
+  return asan_app_map_.find(appid) != asan_app_map_.end();
+}
+
+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::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);
+  }
+}
+
+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::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
new file mode 100644 (file)
index 0000000..5425395
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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 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);
+
+ private:
+  Debug() = default;
+  ~Debug();
+
+  void RemoveFiles(const std::vector<std::string>& files);
+  void ParseAndAddArgv(const tizen_base::Bundle& b, const std::string& key);
+  void ParseAndAddExtraArgv(const tizen_base::Bundle& b,
+                            const std::string& key);
+  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/launchpad-process-pool/debugger_info.cc b/src/launchpad-process-pool/debugger_info.cc
new file mode 100644 (file)
index 0000000..bbe547c
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * 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-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 <util.hh>
+
+#include "launchpad-process-pool/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/launchpad-process-pool/debugger_info.hh b/src/launchpad-process-pool/debugger_info.hh
new file mode 100644 (file)
index 0000000..28c8a93
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * 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 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
new file mode 100644 (file)
index 0000000..100db5e
--- /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-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/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/launchpad-process-pool/executor.hh b/src/launchpad-process-pool/executor.hh
new file mode 100644 (file)
index 0000000..f8e3562
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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 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
new file mode 100644 (file)
index 0000000..433845a
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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-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
new file mode 100644 (file)
index 0000000..243b45f
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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 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_
index 46bd449dc04f376ffa735398853cc411c35923da..14ca7066aa4a7959b68988a1757eac1c9e2057ea 100644 (file)
@@ -39,7 +39,8 @@ const int kSocketMaxBufferSize = 131071;
 
 HydraLoaderContext::Builder::operator LoaderContext*() {
   return new HydraLoaderContext(std::move(loader_info_), loader_id_,
-      caller_pid_, activated_, std::move(loader_mount_));
+                                caller_pid_, activated_,
+                                std::move(loader_mount_));
 }
 
 HydraLoaderContext::HydraLoaderContext(
@@ -53,18 +54,17 @@ HydraLoaderContext::HydraLoaderContext(
 void HydraLoaderContext::Listen() {
   try {
     std::string socket_path = "/run/aul/daemons/" + std::to_string(getuid()) +
-        "/" + std::string(kHydraLoaderSocketName) + std::to_string(GetType()) +
-        "-" + std::to_string(GetLoaderId());
-    if (fs::exists(socket_path))
-      fs::remove(socket_path);
+                              "/" + std::string(kHydraLoaderSocketName) +
+                              std::to_string(GetType()) + "-" +
+                              std::to_string(GetLoaderId());
+    if (fs::exists(socket_path)) fs::remove(socket_path);
 
     hydra_socket_.reset(new ServerSocket());
     hydra_socket_->Bind(socket_path);
     hydra_socket_->Listen(128);
 
-    hydra_channel_.reset(
-        new IOChannel(
-            hydra_socket_->GetFd(), IOChannel::IOCondition::IO_IN, this));
+    hydra_channel_.reset(new IOChannel(hydra_socket_->GetFd(),
+                                       IOChannel::IOCondition::IO_IN, this));
   } catch (const Exception& e) {
     _E("Exception occurs. error: %s", e.what());
     THROW(e.GetErrorCode());
@@ -72,8 +72,8 @@ void HydraLoaderContext::Listen() {
 }
 
 void HydraLoaderContext::Dispose() {
-  _D("Dispose hydra process. type(%d), loader_name(%s)",
-      GetType(), GetLoaderName().c_str());
+  _D("Dispose hydra process. type(%d), loader_name(%s)", GetType(),
+     GetLoaderName().c_str());
 
   LoaderContext::Dispose();
   if (hydra_pid_ > 0) {
@@ -101,9 +101,7 @@ pid_t HydraLoaderContext::Prepare() {
   return hydra_pid_;
 }
 
-pid_t HydraLoaderContext::GetHydraPid() const {
-  return hydra_pid_;
-}
+pid_t HydraLoaderContext::GetHydraPid() const { return hydra_pid_; }
 
 void HydraLoaderContext::SetHydraPid(pid_t hydra_pid) {
   hydra_pid_ = hydra_pid;
@@ -116,16 +114,15 @@ void HydraLoaderContext::PrepareCandidateProcess() {
   parcel.WriteParcelable(request);
 
   size_t data_size = parcel.GetDataSize();
-  int ret = client_socket_->Send(static_cast<void*>(&data_size),
-      sizeof(data_size));
+  int ret =
+      client_socket_->Send(static_cast<void*>(&data_size), sizeof(data_size));
   if (ret != 0) {
     _E("Send() is failed. error: %d", ret);
     return;
   }
 
   ret = client_socket_->Send(parcel.GetData(), data_size);
-  if (ret != 0)
-    _E("Send() is failed. error: %d", ret);
+  if (ret != 0) _E("Send() is failed. error: %d", ret);
 }
 
 void HydraLoaderContext::HandleHydraLoaderEvent() {
@@ -144,13 +141,13 @@ void HydraLoaderContext::HandleHydraLoaderEvent() {
         return;
       }
 
-      client_channel_.reset(
-          new IOChannel(client_socket_->GetFd(),
-            IOChannel::IOCondition::IO_IN | IOChannel::IOCondition::IO_HUP,
-            this));
+      client_channel_.reset(new IOChannel(
+          client_socket_->GetFd(),
+          IOChannel::IOCondition::IO_IN | IOChannel::IOCondition::IO_HUP,
+          this));
       hydra_prepared_ = true;
-      SECURE_LOGI("Type %d hydra loader was connected. pid: %d",
-          GetType(), GetHydraPid());
+      SECURE_LOGI("Type %d hydra loader was connected. pid: %d", GetType(),
+                  GetHydraPid());
     } catch (const Exception& e) {
       _E("Exception occurs. error: %s", e.what());
       return;
@@ -164,8 +161,8 @@ void HydraLoaderContext::HandleHydraLoaderEvent() {
 void HydraLoaderContext::HandleHydraLoaderClientEvent(int condition) {
   if (condition &
       (IOChannel::IOCondition::IO_HUP | IOChannel::IOCondition::IO_NVAL)) {
-    SECURE_LOGE("Type %d loader was disconnected. pid: %d",
-        GetType(), GetHydraPid());
+    SECURE_LOGE("Type %d loader was disconnected. pid: %d", GetType(),
+                GetHydraPid());
     Dispose();
     Prepare();
     return;
@@ -182,7 +179,7 @@ void HydraLoaderContext::HandleHydraLoaderClientEvent(int condition) {
         SetPid(pid);
         if (RefCount() > 0) {
           CPUBoostController::DoBoost(pid, CPUBoostController::Level::Strong,
-              10000);
+                                      10000);
         }
       }
     }
index dc987f8455552567e893ac37c07a122ccf1f55ae..515f686c93d6bf770608f5597f3dea740fd96498 100644 (file)
@@ -18,9 +18,9 @@
 
 #include <string>
 
-#include <sigchld_info.hh>
 #include <peer_credentials.hh>
 #include <procfs.hh>
+#include <sigchld_info.hh>
 
 #include "launchpad-process-pool/log_private.hh"
 
@@ -33,11 +33,9 @@ const int MAX_RECEIVE_BUFFER = 131071;
 
 int CheckPermission(pid_t pid) {
   std::string attr = Procfs::GetAttrCurrent(pid);
-  if (attr.empty())
-    return -1;
+  if (attr.empty()) return -1;
 
-  if (attr.compare("User") == 0 ||
-      attr.compare("System") == 0 ||
+  if (attr.compare("User") == 0 || attr.compare("System") == 0 ||
       attr.compare("System::Privileged") == 0)
     return 0;
 
@@ -48,34 +46,29 @@ int CheckPermission(pid_t pid) {
 }  // namespace
 
 HydraSigchldEvent::HydraSigchldEvent(IEvent* listener)
-    : listener_(listener),
-      socket_(new ServerSocket()) {
-  std::string endpoint = "/run/aul/daemons/" + std::to_string(getuid()) + "/" +
-      HYDRA_SIGCHLD_SOCK;
+    : listener_(listener), socket_(new ServerSocket()) {
+  std::string endpoint =
+      "/run/aul/daemons/" + std::to_string(getuid()) + "/" + HYDRA_SIGCHLD_SOCK;
   socket_->Bind(endpoint);
   socket_->Listen(MAX_PENDING_CONNECTION);
   socket_->SetReceiveBufferSize(MAX_RECEIVE_BUFFER);
 
-  channel_.reset(new IOChannel(socket_->GetFd(), IOChannel::IOCondition::IO_IN,
-      this));
+  channel_.reset(
+      new IOChannel(socket_->GetFd(), IOChannel::IOCondition::IO_IN, this));
 }
 
 HydraSigchldEvent::~HydraSigchldEvent() {
-  if (getpid() != current_pid_)
-    socket_->RemoveFd();
+  if (getpid() != current_pid_) socket_->RemoveFd();
 }
 
 void HydraSigchldEvent::OnIOEventReceived(int fd, int condition) {
   auto client_socket = socket_->Accept();
-  if (!client_socket)
-    return;
+  if (!client_socket) return;
 
   auto peer_creds = PeerCredentials::Get(client_socket->GetFd());
-  if (!peer_creds)
-    return;
+  if (!peer_creds) return;
 
-  if (CheckPermission(peer_creds->GetPid()) != 0)
-    return;
+  if (CheckPermission(peer_creds->GetPid()) != 0) return;
 
   size_t data_size = 0;
   int ret = client_socket->Receive(&data_size, sizeof(data_size));
index b4bba0e493c4562899f170faa2fd6998bf58f16b..b836894628f2a94b72083025cf6a25a6fe3b74d8 100644 (file)
@@ -22,8 +22,8 @@
 
 #include <memory>
 
-#include <server_socket.hh>
 #include <io_channel.hh>
+#include <server_socket.hh>
 
 namespace launchpad {
 
diff --git a/src/launchpad-process-pool/launcher_info.cc b/src/launchpad-process-pool/launcher_info.cc
new file mode 100644 (file)
index 0000000..f91547c
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * 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-process-pool/launcher_info.hh"
+
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+#include <utility>
+
+#include <util.hh>
+
+#include "launchpad-process-pool/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/launchpad-process-pool/launcher_info.hh b/src/launchpad-process-pool/launcher_info.hh
new file mode 100644 (file)
index 0000000..7856f91
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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 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 355f0e30ea8de66fe340ea6aec2f076f13d10832..4203658eaa489c44cf357ba632beef1b03f665b2 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/loader_manager.hh"
 #include "launchpad-process-pool/log.hh"
 #include "launchpad-process-pool/log_private.hh"
+#include "launchpad-process-pool/lux_manager.hh"
 #include "launchpad-process-pool/memory_monitor.hh"
 #include "launchpad-process-pool/signal_manager.hh"
 #include "launchpad-process-pool/tracer.hh"
@@ -79,12 +78,11 @@ class CleanupInfo : public launchpad::Worker::Job {
 };
 
 int GetLaunchpadFdFromSystemd() {
-  const std::string path = kRunAulDaemonsPath + std::to_string(getuid()) +
-      "/" + std::string(kLaunchpadProcessPoolSock);
+  const std::string path = kRunAulDaemonsPath + std::to_string(getuid()) + "/" +
+                           std::string(kLaunchpadProcessPoolSock);
   int fds = sd_listen_fds(0);
   for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fds; ++fd) {
-    if (sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0) > 0)
-      return fd;
+    if (sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0) > 0) return fd;
   }
 
   _W("There is no socket stream");
@@ -104,15 +102,13 @@ int GetLaunchpadFdFromEnvironment() {
 
 ServerSocket* GetLaunchpadSocket() {
   int fd = GetLaunchpadFdFromSystemd();
-  if (fd < 0)
-    fd = GetLaunchpadFdFromEnvironment();
+  if (fd < 0) fd = GetLaunchpadFdFromEnvironment();
 
-  if (fd > -1)
-    return new ServerSocket(fd);
+  if (fd > -1) return new ServerSocket(fd);
 
   auto* socket = new ServerSocket();
   const std::string endpoint = kRunAulDaemonsPath + std::to_string(getuid()) +
-      "/" + kLaunchpadProcessPoolSock;
+                               "/" + kLaunchpadProcessPoolSock;
   socket->Bind(endpoint);
   socket->SetReceiveBufferSize(kReceivedBufferSize);
   socket->Listen(kMaxPendingConnection);
@@ -131,8 +127,7 @@ void PrintAppInfo(const AppInfo* app_info) {
 
 int CheckCallerPermission(pid_t caller_pid) {
   std::string attr_current = Procfs::GetAttrCurrent(caller_pid);
-  if (attr_current.empty())
-    return -1;
+  if (attr_current.empty()) return -1;
 
   if (attr_current.compare("User") == 0 ||
       attr_current.compare("System") == 0 ||
@@ -144,8 +139,7 @@ int CheckCallerPermission(pid_t caller_pid) {
 
 int GetLoaderIdFromBundle(const tizen_base::Bundle& b) {
   auto loader_id = b.GetString(kAulLoaderId);
-  if (loader_id.empty())
-    return -1;
+  if (loader_id.empty()) return -1;
 
   _W("Requested loader id: %s", loader_id.c_str());
   return std::stoi(loader_id);
@@ -154,74 +148,61 @@ int GetLoaderIdFromBundle(const tizen_base::Bundle& b) {
 }  // namespace
 
 Launchpad::Launchpad(int argc, char** argv)
-    : argc_(argc),
-      argv_(argv),
-      loop_(g_main_loop_new(nullptr, FALSE)) {
+    : argc_(argc), argv_(argv), loop_(g_main_loop_new(nullptr, FALSE)) {
   LaunchpadArgs::GetInst().Set(argc_, argv_);
   handlers_ = {
-    { PadCmd::Visibility,
-      std::bind(&Launchpad::HandleVisibilityRequest, this,
-          std::placeholders::_1) },
-    { PadCmd::AddLoader,
-      std::bind(&Launchpad::HandleAddLoaderRequest, this,
-          std::placeholders::_1) },
-    { PadCmd::RemoveLoader,
-      std::bind(&Launchpad::HandleRemoveLoaderRequest, this,
-          std::placeholders::_1) },
-    { PadCmd::MakeDefaultSlots,
-      std::bind(&Launchpad::HandleMakeDefaultSlotsRequest, this,
-          std::placeholders::_1) },
-    { PadCmd::PrepareAppDefinedLoader,
-      std::bind(&Launchpad::HandlePrepareAppDefinedLoaderRequest, this,
-          std::placeholders::_1) },
-    { PadCmd::Demand,
-      std::bind(&Launchpad::HandleDemandRequest, this,
-          std::placeholders::_1) },
-    { PadCmd::Ping,
-      std::bind(&Launchpad::HandlePingRequest, this,
-          std::placeholders::_1) },
-    { PadCmd::UpdateAppType,
-      std::bind(&Launchpad::HandleUpdateAppTypeRequest, this,
-          std::placeholders::_1) },
-    { PadCmd::Connect,
-      std::bind(&Launchpad::HandleConnectRequest, this,
-          std::placeholders::_1) },
-    { PadCmd::Launch,
-      std::bind(&Launchpad::HandleLaunchRequest, this,
-          std::placeholders::_1) },
-    { PadCmd::KillLoader,
-      std::bind(&Launchpad::HandleKillLoaderRequest, this,
-          std::placeholders::_1) },
-    { PadCmd::RestartLoader,
-      std::bind(&Launchpad::HandleRestartLoaderRequest, this,
-          std::placeholders::_1) },
-    { PadCmd::DisposeLoader,
-      std::bind(&Launchpad::HandleDisposeLoaderRequest, this,
-          std::placeholders::_1) },
+      {PadCmd::Visibility, std::bind(&Launchpad::HandleVisibilityRequest, this,
+                                     std::placeholders::_1)},
+      {PadCmd::AddLoader, std::bind(&Launchpad::HandleAddLoaderRequest, this,
+                                    std::placeholders::_1)},
+      {PadCmd::RemoveLoader, std::bind(&Launchpad::HandleRemoveLoaderRequest,
+                                       this, std::placeholders::_1)},
+      {PadCmd::MakeDefaultSlots,
+       std::bind(&Launchpad::HandleMakeDefaultSlotsRequest, this,
+                 std::placeholders::_1)},
+      {PadCmd::PrepareAppDefinedLoader,
+       std::bind(&Launchpad::HandlePrepareAppDefinedLoaderRequest, this,
+                 std::placeholders::_1)},
+      {PadCmd::Demand,
+       std::bind(&Launchpad::HandleDemandRequest, this, std::placeholders::_1)},
+      {PadCmd::Ping,
+       std::bind(&Launchpad::HandlePingRequest, this, std::placeholders::_1)},
+      {PadCmd::UpdateAppType, std::bind(&Launchpad::HandleUpdateAppTypeRequest,
+                                        this, std::placeholders::_1)},
+      {PadCmd::Connect, std::bind(&Launchpad::HandleConnectRequest, this,
+                                  std::placeholders::_1)},
+      {PadCmd::Launch,
+       std::bind(&Launchpad::HandleLaunchRequest, this, std::placeholders::_1)},
+      {PadCmd::KillLoader, std::bind(&Launchpad::HandleKillLoaderRequest, this,
+                                     std::placeholders::_1)},
+      {PadCmd::RestartLoader, std::bind(&Launchpad::HandleRestartLoaderRequest,
+                                        this, std::placeholders::_1)},
+      {PadCmd::DisposeLoader, std::bind(&Launchpad::HandleDisposeLoaderRequest,
+                                        this, std::placeholders::_1)},
   };
 
   CPUBoostController::Level level;
   int ret = CPUBoostController::GetBoostLevel(getpid(), &level);
-  if (ret != 0)
-    CPUBoostController::Clear(getpid());
+  if (ret != 0) CPUBoostController::Clear(getpid());
 
-  if (ret != 0 ||
-      level == CPUBoostController::Level::None ||
+  if (ret != 0 || level == CPUBoostController::Level::None ||
       level == CPUBoostController::Level::Weak) {
-    CPUBoostController::DoBoost(getpid(), CPUBoostController::Level::Strong,
-        -1, true);
+    CPUBoostController::DoBoost(getpid(), CPUBoostController::Level::Strong, -1,
+                                true);
   }
 
-  g_timeout_add(1000, [](gpointer data) {
+  g_timeout_add(
+      1000,
+      [](gpointer data) {
         CPUBoostController::Clear(getpid());
         return G_SOURCE_REMOVE;
-      }, this);
+      },
+      this);
   mode_ = Config::GetInst().GetLaunchMode().GetMode();
 }
 
 Launchpad::~Launchpad() {
-  if (loop_ != nullptr)
-    g_main_loop_unref(loop_);
+  if (loop_ != nullptr) g_main_loop_unref(loop_);
 }
 
 int Launchpad::Run() {
@@ -233,22 +214,23 @@ int Launchpad::Run() {
 #ifdef TIZEN_FEATURE_PRIORITY_CHANGE
   _set_priority(-12);
 #endif
-  UserTracer::Print(
-      std::string(__FUNCTION__) + "(" + std::to_string(__LINE__) +
-      "): g_main_loop_run()");
+  UserTracer::Print(std::string(__FUNCTION__) + "(" + std::to_string(__LINE__) +
+                    "): g_main_loop_run()");
   g_main_loop_run(loop_);
   OnTerminate();
   return 0;
 }
 
-void Launchpad::Quit() {
-  g_main_loop_quit(loop_);
-}
+void Launchpad::Quit() { g_main_loop_quit(loop_); }
 
 bool Launchpad::OnCreate() {
-  UserTracer user_tracer(
-      std::string(__FUNCTION__) + "(" + std::to_string(__LINE__) + ")");
+  UserTracer user_tracer(std::string(__FUNCTION__) + "(" +
+                         std::to_string(__LINE__) + ")");
   launchpad::SignalManager::GetInst().SetEventListener(this);
+  LoaderManager::GetInst().SetEventListener(this);
+  auto& lux_manager = launchpad::LuxManager::GetInst();
+  lux_manager.Init();
+  lux_manager.SetEventListener(this);
 
   try {
     app_executor_.reset(new AppExecutor());
@@ -264,7 +246,6 @@ bool Launchpad::OnCreate() {
   DBus::Init();
 
   LoaderManager::GetInst().AddDefaultLoaderContexts();
-  LoaderManager::GetInst().SetEventListener(this);
   launchpad::Debug::GetInst().Init();
 
   Util::SendCmdToAmd(AmdCmd::LaunchpadLaunchSignal);
@@ -289,6 +270,7 @@ void Launchpad::OnTerminate() {
   LoaderManager::GetInst().Dispose();
   channel_.reset();
   socket_.reset();
+  launchpad::LuxManager::GetInst().Dispose();
   SignalManager::GetInst().Dispose();
 }
 
@@ -299,8 +281,8 @@ void Launchpad::HandleVisibilityRequest(std::shared_ptr<Request> request) {
 }
 
 void Launchpad::HandleAddLoaderRequest(std::shared_ptr<Request> request) {
-  auto context = LoaderManager::GetInst().AddLoaderContext(
-      request->GetBundle());
+  auto context =
+      LoaderManager::GetInst().AddLoaderContext(request->GetBundle());
   if (context == nullptr) {
     request->SendResult(-1);
     _W("[PAD_CMD_ADD_LOADER] Can not add loader context");
@@ -321,13 +303,13 @@ void Launchpad::HandleRemoveLoaderRequest(std::shared_ptr<Request> request) {
   }
 
   LoaderManager::GetInst().RemoveLoaderContext(LoaderType::Dynamic,
-      std::stoi(loader_id_str));
+                                               std::stoi(loader_id_str));
   request->SendResult(0);
   _W("[PAD_CMD_REMOVE_LOADER]");
 }
 
 void Launchpad::HandleMakeDefaultSlotsRequest(
-  std::shared_ptr<Request> request) {
+    std::shared_ptr<Request> request) {
   LoaderManager::GetInst().AddDefaultLoaderContexts();
   _W("[PAD_CMD_MAKE_DEFAULT_SLOTS]");
 }
@@ -365,12 +347,10 @@ void Launchpad::HandlePingRequest(std::shared_ptr<Request> request) {
   for (auto& iter : fast_launches_) {
     pid_t pid = iter.first;
     auto& appid = iter.second;
-    tizen_base::Bundle b = {
-      { kAulAppId, appid },
-      { kAulPid, std::to_string(pid) }
-    };
+    tizen_base::Bundle b = {{kAulAppId, appid}, {kAulPid, std::to_string(pid)}};
 
-    Util::SendCmdToAmd(AmdCmd::AppRegisterPid, b.GetHandle(),
+    Util::SendCmdToAmd(
+        AmdCmd::AppRegisterPid, b.GetHandle(),
         static_cast<int>(AmdSocketOption::NoReply | AmdSocketOption::Bundle));
   }
   fast_launches_.clear();
@@ -400,15 +380,12 @@ void Launchpad::HandleConnectRequest(std::shared_ptr<Request> request) {
 
 bool Launchpad::CanUseLoaderContext(
     const std::shared_ptr<LoaderContext>& context) {
-  if (context->IsPrepared())
-    return true;
+  if (context->IsPrepared()) return true;
 
-  if (mode_ == Config::LaunchMode::Mode::PreviousOperation)
-    return false;
+  if (mode_ == Config::LaunchMode::Mode::PreviousOperation) return false;
 
   if (mode_ == Config::LaunchMode::Mode::DefaultOperation) {
-    if (context->IsHydraMode())
-      return true;
+    if (context->IsHydraMode()) return true;
 
     return context->GetPid() > 0 && context->RefCount() == 0;
   }
@@ -416,8 +393,7 @@ bool Launchpad::CanUseLoaderContext(
   // Config::LaunchMode::Mode::AlwaysLoader
   // Config::LaunchMode::Mode::AlwaysLoaderWithoutCPUChecker
   // Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority
-  if (context->GetPid() > 0)
-    return true;
+  if (context->GetPid() > 0) return true;
 
   return context->IsLaunchable();
 }
@@ -444,7 +420,7 @@ Launchpad::LaunchResult Launchpad::LaunchRequestPrepare(
     request->SetLoaderId(GetLoaderIdFromBundle(request->GetBundle()));
     if (request->GetLoaderId() > PadLoaderId::DynamicBase) {
       auto context = loader_manager.FindLoaderContext(LoaderType::Dynamic,
-          request->GetLoaderId());
+                                                      request->GetLoaderId());
       if (context != nullptr && CanUseLoaderContext(context))
         request->SetAvailableLoaderContext(std::move(context));
     } else {
@@ -471,7 +447,7 @@ Launchpad::LaunchResult Launchpad::LaunchRequestPrepare(
       }
     } else {
       auto context = loader_manager.FindLoaderContext(LoaderType::Dynamic,
-          request->GetLoaderId());
+                                                      request->GetLoaderId());
       if (context != nullptr && CanUseLoaderContext(context))
         request->SetAvailableLoaderContext(std::move(context));
     }
@@ -483,23 +459,21 @@ Launchpad::LaunchResult Launchpad::LaunchRequestPrepare(
 Launchpad::LaunchResult Launchpad::ForkProcessing(
     std::shared_ptr<Request> request) {
   if (request->GetBundle().GetType(kAulSdk) != BUNDLE_TYPE_NONE) {
-    if (Debug::GetInst().Load())
-      app_executor_->DisposeCandidateProcess();
+    if (Debug::GetInst().Load()) app_executor_->DisposeCandidateProcess();
   }
 
   _W("appid: %s", request->GetAppInfo()->GetAppId().c_str());
   request->SetPid(app_executor_->Execute(request->GetAppInfo()));
   if (request->GetPid() == -1) {
     _E("Failed to create a child process. appid: %s",
-        request->GetAppInfo()->GetAppId().c_str());
+       request->GetAppInfo()->GetAppId().c_str());
   }
 
   request->SendResult(request->GetPid());
-  _W("appid: %s, pid: %d",
-      request->GetAppInfo()->GetAppId().c_str(), request->GetPid());
+  _W("appid: %s, pid: %d", request->GetAppInfo()->GetAppId().c_str(),
+     request->GetPid());
   LoaderManager::GetInst().HandleDirectLaunch(request->GetLoaderContext());
-  if (request->GetPid() == -1)
-    return LaunchResult::Fail;
+  if (request->GetPid() == -1) return LaunchResult::Fail;
 
   return LaunchResult::Success;
 }
@@ -516,8 +490,7 @@ Launchpad::LaunchResult Launchpad::LaunchRequestPend(
 
   _W("Loader context is not prepared");
   loader_context->Ref();
-  if (loader_context->GetPid() <= 0)
-    loader_context->Prepare();
+  if (loader_context->GetPid() <= 0) loader_context->Prepare();
 
   if (loader_context->GetPid() > 0) {
     _W("Send result: %d", loader_context->GetPid());
@@ -544,8 +517,7 @@ Launchpad::LaunchResult Launchpad::LaunchRequestDo(
 
   auto* app_info = request->GetAppInfo();
   _W("Launch %d type process. appid: %s",
-      static_cast<int>(loader_context->GetType()),
-      app_info->GetAppId().c_str());
+     static_cast<int>(loader_context->GetType()), app_info->GetAppId().c_str());
   request->SetPid(loader_context->Deploy(app_info));
 
   if ((mode_ == Config::LaunchMode::Mode::AlwaysLoaderWithoutCPUChecker) ||
@@ -564,20 +536,18 @@ void Launchpad::LaunchRequestComplete(std::shared_ptr<Request> request) {
   if (request->GetPid() > 0) {
     auto* app_info = request->GetAppInfo();
     launchpad::DBus::SendAppLaunchSignal(request->GetPid(),
-        app_info->GetAppId().c_str());
+                                         app_info->GetAppId().c_str());
     pid_map_[request->GetPid()] = app_info->GetAppId();
-    launchpad::Log::Print("[LAUNCH]", "pid(%7d) | appid(%s)",
-        request->GetPid(), app_info->GetAppId().c_str());
+    launchpad::Log::Print("[LAUNCH]", "pid(%7d) | appid(%s)", request->GetPid(),
+                          app_info->GetAppId().c_str());
     if (app_info->IsFastLaunch()) {
       if (ping_received_) {
-        tizen_base::Bundle b = {
-          { kAulAppId, app_info->GetAppId() },
-          { kAulPid, std::to_string(request->GetPid()) }
-        };
+        tizen_base::Bundle b = {{kAulAppId, app_info->GetAppId()},
+                                {kAulPid, std::to_string(request->GetPid())}};
 
         Util::SendCmdToAmd(AmdCmd::AppRegisterPid, b.GetHandle(),
-            static_cast<int>(
-              AmdSocketOption::NoReply | AmdSocketOption::Bundle));
+                           static_cast<int>(AmdSocketOption::NoReply |
+                                            AmdSocketOption::Bundle));
       } else {
         fast_launches_[request->GetPid()] = app_info->GetAppId();
       }
@@ -592,12 +562,11 @@ void Launchpad::HandleLaunchRequest(std::shared_ptr<Request> request) {
     return;
   }
 
-  if (LaunchRequestDo(request) == LaunchResult::Pending)
-    return;
+  if (LaunchRequestDo(request) == LaunchResult::Pending) return;
 
   LaunchRequestComplete(request);
   _W("[PAD_CMD_LAUNCH] appid: %s, result: %d",
-      request->GetAppInfo()->GetAppId().c_str(), request->GetPid());
+     request->GetAppInfo()->GetAppId().c_str(), request->GetPid());
 }
 
 void Launchpad::HandleKillLoaderRequest(std::shared_ptr<Request> request) {
@@ -610,8 +579,7 @@ void Launchpad::HandleKillLoaderRequest(std::shared_ptr<Request> request) {
     return;
   }
 
-  if (loader_context->RefCount() == 0)
-    loader_context->Dispose();
+  if (loader_context->RefCount() == 0) loader_context->Dispose();
 
   _W("[PAD_CMD_KILL_LOADER] loader_name: %s", loader_name.c_str());
 }
@@ -626,14 +594,13 @@ void Launchpad::HandleRestartLoaderRequest(std::shared_ptr<Request> request) {
     return;
   }
 
-  if (loader_context->RefCount() == 0)
-    loader_context->Dispose();
+  if (loader_context->RefCount() == 0) loader_context->Dispose();
 
   if (loader_context->GetPid() < 1 && loader_context->IsLaunchable())
     loader_context->Prepare();
 
-  _W("[PAD_CMD_RESTART_LOADER] loader_name: %s, pid: %d",
-      loader_name.c_str(), loader_context->GetPid());
+  _W("[PAD_CMD_RESTART_LOADER] loader_name: %s, pid: %d", loader_name.c_str(),
+     loader_context->GetPid());
 }
 
 void Launchpad::HandleDisposeLoaderRequest(std::shared_ptr<Request> request) {
@@ -684,7 +651,7 @@ void Launchpad::OnIOEventReceived(int fd, int condition) {
   }
 }
 
-void Launchpad::OnSigchldReceived(pid_t pid) {
+void Launchpad::HandleSigchld(pid_t pid) {
   fast_launches_.erase(pid);
   auto found = pid_map_.find(pid);
   if (found != pid_map_.end()) {
@@ -701,7 +668,7 @@ void Launchpad::OnSigchldReceived(pid_t pid) {
       context->Unref();
       auto* app_info = request->GetAppInfo();
       launchpad::DBus::SendAppLaunchSignal(request->GetPid(),
-        app_info->GetAppId().c_str());
+                                           app_info->GetAppId().c_str());
       pending_requests_.erase(iter);
       break;
     }
@@ -714,11 +681,20 @@ void Launchpad::OnSigchldReceived(pid_t pid) {
   app_executor_->HandleSigchld(pid);
 }
 
+void Launchpad::OnSigchldReceived(pid_t pid) {
+  HandleSigchld(pid);
+  LuxManager::GetInst().HandleSigchld(pid);
+}
+
+void Launchpad::OnLuxSigchld(pid_t pid, int status) {
+  HandleSigchld(pid);
+  SignalManager::GetInst().HandleSigchld(pid, status);
+}
+
 void Launchpad::OnLoaderPrepared(LoaderContext* loader_context) {
   _W("Loader is prepared. name(%s), pid(%d)",
-      loader_context->GetLoaderName().c_str(), loader_context->GetPid());
-  if (loader_context->RefCount() == 0)
-    return;
+     loader_context->GetLoaderName().c_str(), loader_context->GetPid());
+  if (loader_context->RefCount() == 0) return;
 
   auto iter = pending_requests_.begin();
   while (iter != pending_requests_.end()) {
@@ -738,7 +714,7 @@ void Launchpad::OnLoaderPrepared(LoaderContext* loader_context) {
 
 void Launchpad::OnLoaderLaunched(LoaderContext* loader_context) {
   _W("Loader is launched. name(%s), pid(%d)",
-      loader_context->GetLoaderName().c_str(), loader_context->GetPid());
+     loader_context->GetLoaderName().c_str(), loader_context->GetPid());
   if (loader_context->RefCount() == 0) {
     if (mode_ == Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority)
       SchedPriority::Set(loader_context->GetPid(), 19);
@@ -758,8 +734,8 @@ void Launchpad::OnLoaderLaunched(LoaderContext* loader_context) {
 }  // namespace launchpad
 
 int main(int argc, char** argv) {
-  launchpad::UserTracer tracer(
-      std::string(__FUNCTION__) + "(" + std::to_string(__LINE__) + ")");
+  launchpad::UserTracer tracer(std::string(__FUNCTION__) + "(" +
+                               std::to_string(__LINE__) + ")");
   prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0);
   launchpad::Launchpad launchpad(argc, argv);
   return launchpad.Run();
index 0ca5064ffb9fb247636f467178caae2a51b3dcb6..89b72fe93cf42e84df3c6c1c2070bd6d77323a09 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/lux_manager.hh"
 #include "launchpad-process-pool/request.hh"
 #include "launchpad-process-pool/signal_manager.hh"
 
@@ -40,7 +41,8 @@ namespace launchpad {
 
 class Launchpad : public IOChannel::IEvent,
                   public SignalManager::IEvent,
-                  public LoaderManager::IEvent {
+                  public LoaderManager::IEvent,
+                  public LuxManager::IEvent {
  public:
   enum class LaunchResult : int {
     Fail = -1,
@@ -53,9 +55,9 @@ class Launchpad : public IOChannel::IEvent,
   ~Launchpad();
 
   Launchpad(const Launchpad&) = delete;
-  Launchpad& operator = (const Launchpad&) = delete;
+  Launchpad& operator=(const Launchpad&) = delete;
   Launchpad(Launchpad&&) = delete;
-  Launchpad& operator = (Launchpad&&) = delete;
+  Launchpad& operator=(Launchpad&&) = delete;
 
   int Run();
   void Quit();
@@ -86,11 +88,13 @@ class Launchpad : public IOChannel::IEvent,
   LaunchResult LaunchRequestDo(std::shared_ptr<Request> request);
   LaunchResult LaunchRequestPend(std::shared_ptr<Request> request);
   void LaunchRequestComplete(std::shared_ptr<Request> request);
+  void HandleSigchld(pid_t pid);
 
   void OnIOEventReceived(int fd, int condition) override;
   void OnSigchldReceived(pid_t pid) override;
   void OnLoaderPrepared(LoaderContext* loader_context) override;
   void OnLoaderLaunched(LoaderContext* loader_context) override;
+  void OnLuxSigchld(pid_t pid, int status) override;
 
  private:
   int argc_;
diff --git a/src/launchpad-process-pool/launchpad_args.cc b/src/launchpad-process-pool/launchpad_args.cc
new file mode 100644 (file)
index 0000000..cfa976f
--- /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-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
new file mode 100644 (file)
index 0000000..3695dc0
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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 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 ecbf5bb1045520a3b4cb25cdd22486c27ee1b4ee..aa6124687505cbf22ee873dba2843596706881af 100644 (file)
@@ -32,7 +32,6 @@
 #include <utility>
 
 #include <exception.hh>
-#include <loader_executor.hh>
 #include <peer_credentials.hh>
 #include <procfs.hh>
 #include <types.hh>
@@ -43,6 +42,7 @@
 #include "launchpad-process-pool/config.hh"
 #include "launchpad-process-pool/log.hh"
 #include "launchpad-process-pool/log_private.hh"
+#include "launchpad-process-pool/loader_executor.hh"
 #include "launchpad-process-pool/memory_monitor.hh"
 
 namespace fs = std::filesystem;
@@ -56,11 +56,10 @@ const unsigned int kWinScore = 100;
 const float kLoseScoreRate = 0.7f;
 
 int VerifyLoaderCaps(const std::string& executable_file) {
-  std::vector<cap_value_t> values { CAP_SETGID, CAP_MAC_ADMIN };
+  std::vector<cap_value_t> values{CAP_SETGID, CAP_MAC_ADMIN};
 
   // If Dytransition feature is enabled, CAP_MAC_ADMIN is unnecessary.
-  if (!AppLabelsMonitor::GetInst().IsDisposed())
-    values.pop_back();
+  if (!AppLabelsMonitor::GetInst().IsDisposed()) values.pop_back();
 
   _W("Executable file: %s", executable_file.c_str());
   cap_t cap = cap_get_file(executable_file.c_str());
@@ -69,8 +68,9 @@ int VerifyLoaderCaps(const std::string& executable_file) {
     return -1;
   }
 
-  auto cap_auto = std::unique_ptr<std::remove_pointer<cap_t>::type,
-      decltype(cap_free)*>(cap, cap_free);
+  auto cap_auto =
+      std::unique_ptr<std::remove_pointer<cap_t>::type, decltype(cap_free)*>(
+          cap, cap_free);
 
   for (size_t i = 0; i < values.size(); i++) {
     cap_flag_value_t inh_state;
@@ -149,8 +149,8 @@ LoaderContext::LoaderContext(std::shared_ptr<LoaderInfo> loader_info,
   if (executable_file != "null") {
     if (access(executable_file.c_str(), F_OK | X_OK) != 0) {
       int error = -errno;
-      _E("access() is failed. path: %s, errno: %d",
-          executable_file.c_str(), errno);
+      _E("access() is failed. path: %s, errno: %d", executable_file.c_str(),
+         errno);
       THROW(error);
     }
 
@@ -161,24 +161,22 @@ LoaderContext::LoaderContext(std::shared_ptr<LoaderInfo> loader_info,
   condition_path_exists_ = loader_info_->GetConditionPathExists();
 }
 
-LoaderContext::~LoaderContext() {
-  Dispose();
-}
+LoaderContext::~LoaderContext() { Dispose(); }
 
 void LoaderContext::Listen() {
   try {
     std::string socket_path = "/run/aul/daemons/" + std::to_string(getuid()) +
-        "/" + std::string(kLaunchpadType) + std::to_string(GetType()) + "-" +
-        std::to_string(loader_id_);
-    if (fs::exists(socket_path))
-      fs::remove(socket_path);
+                              "/" + std::string(kLaunchpadType) +
+                              std::to_string(GetType()) + "-" +
+                              std::to_string(loader_id_);
+    if (fs::exists(socket_path)) fs::remove(socket_path);
 
     server_socket_.reset(new ServerSocket());
     server_socket_->Bind(socket_path);
     server_socket_->Listen(128);
 
     server_channel_.reset(new IOChannel(server_socket_->GetFd(),
-        IOChannel::IOCondition::IO_IN, this));
+                                        IOChannel::IOCondition::IO_IN, this));
   } catch (const Exception& e) {
     _E("Exception occurs. error: %s", e.what());
     THROW(e.GetErrorCode());
@@ -186,8 +184,8 @@ void LoaderContext::Listen() {
 }
 
 void LoaderContext::Dispose() {
-  _E("Dispose. type(%d), name(%s), pid(%d)",
-      GetType(), GetLoaderName().c_str(), GetPid());
+  _E("Dispose. type(%d), name(%s), pid(%d)", GetType(), GetLoaderName().c_str(),
+     GetPid());
 
   if (pid_ > 0) {
     _D("Kill process(%d)", pid_);
@@ -219,22 +217,21 @@ void LoaderContext::Dispose() {
 
 pid_t LoaderContext::Prepare() {
   bool set_priority = (Config::GetInst().GetLaunchMode().GetMode() !=
-      Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority);
+                       Config::LaunchMode::Mode::AlwaysLoaderWithLowPriority);
   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_);
+  _W("Prepare. type(%d), name(%s), pid(%d)", GetType(), GetLoaderName().c_str(),
+     pid_);
   if (pid_ == -1) {
     _E("Failed to create a child process");
     return -1;
   }
 
-  Log::Print("[CANDIDATE]", "pid(%7d) | type(%d) | loader(%s)",
-      GetPid(), GetLoaderId(), GetLoaderName().c_str());
+  Log::Print("[CANDIDATE]", "pid(%7d) | type(%d) | loader(%s)", GetPid(),
+             GetLoaderId(), GetLoaderName().c_str());
 
-  if (!IsHydraMode())
-    SetLiveTimer();
+  if (!IsHydraMode()) SetLiveTimer();
 
   MemoryMonitor::GetInst().Reset();
   touched_ = true;
@@ -251,8 +248,8 @@ pid_t LoaderContext::Deploy(const AppInfo* app_info) {
   tizen_base::Parcel parcel;
   parcel.WriteParcelable(*app_info);
   size_t data_size = parcel.GetDataSize();
-  int ret = client_socket_->Send(static_cast<void*>(&data_size),
-      sizeof(data_size));
+  int ret =
+      client_socket_->Send(static_cast<void*>(&data_size), sizeof(data_size));
   if (ret != 0) {
     _E("Failed to send request. pid(%d)", pid_);
     return ret;
@@ -264,8 +261,8 @@ pid_t LoaderContext::Deploy(const AppInfo* app_info) {
     return ret;
   }
 
-  _W("Request to the loader process. pid(%d), path(%s)",
-      pid_, app_info->GetAppPath().c_str());
+  _W("Request to the loader process. pid(%d), path(%s)", pid_,
+     app_info->GetAppPath().c_str());
 
   pid_t pid = pid_;
   pid_ = 0;
@@ -287,53 +284,34 @@ int LoaderContext::GetType() const {
   return static_cast<int>(loader_info_->GetType());
 }
 
-bool LoaderContext::IsPrepared() const {
-  return prepared_;
-}
+bool LoaderContext::IsPrepared() const { return prepared_; }
 
-void LoaderContext::SetPrepared(bool prepared) {
-  prepared_ = prepared;
-}
+void LoaderContext::SetPrepared(bool prepared) { prepared_ = prepared; }
 
 int LoaderContext::GetSchedPriority() const {
   return loader_info_->GetSchedPriority();
 }
 
-pid_t LoaderContext::GetPid() const {
-  return pid_;
-}
+pid_t LoaderContext::GetPid() const { return pid_; }
 
 void LoaderContext::SetPid(pid_t pid) {
   pid_ = pid;
   if (pid_ > 0) {
-    if (listener_ != nullptr)
-      listener_->OnLoaderLaunched(this);
+    if (listener_ != nullptr) listener_->OnLoaderLaunched(this);
   }
 }
 
-pid_t LoaderContext::GetCallerPid() const {
-  return caller_pid_;
-}
+pid_t LoaderContext::GetCallerPid() const { return caller_pid_; }
 
-int LoaderContext::GetLoaderId() const {
-  return loader_id_;
-}
+int LoaderContext::GetLoaderId() const { return loader_id_; }
 
-bool LoaderContext::IsHydraMode() const {
-  return loader_info_->IsHydraMode();
-}
+bool LoaderContext::IsHydraMode() const { return loader_info_->IsHydraMode(); }
 
-bool LoaderContext::IsActivated() const {
-  return activated_;
-}
+bool LoaderContext::IsActivated() const { return activated_; }
 
-bool LoaderContext::IsTouched() const {
-  return touched_;
-}
+bool LoaderContext::IsTouched() const { return touched_; }
 
-bool LoaderContext::IsOnBoot() const {
-  return loader_info_->IsOnBoot();
-}
+bool LoaderContext::IsOnBoot() const { return loader_info_->IsOnBoot(); }
 
 int LoaderContext::GetOnBootTimeout() const {
   return loader_info_->GetOnBootTimeout();
@@ -343,9 +321,7 @@ LoaderMethod LoaderContext::GetDetectionMethod() const {
   return loader_info_->GetDetectionMethod();
 }
 
-void LoaderContext::SetLoaderMethod(LoaderMethod method) {
-  method_ = method;
-}
+void LoaderContext::SetLoaderMethod(LoaderMethod method) { method_ = method; }
 
 bool LoaderContext::ShouldCheckAppInstallation() const {
   return loader_info_->ShouldCheckAppInstallation();
@@ -359,9 +335,7 @@ bool LoaderContext::IsAppInstalled() const {
   return loader_info_->IsAppInstalled();
 }
 
-CPUChecker* LoaderContext::GetCPUChecker() const {
-  return cpu_checker_.get();
-}
+CPUChecker* LoaderContext::GetCPUChecker() const { return cpu_checker_.get(); }
 
 void LoaderContext::UnsetTimer() {
   if (timer_ > 0) {
@@ -384,18 +358,15 @@ void LoaderContext::SetTimer() {
   if (static_cast<int>(loader_info_->GetDetectionMethod()) &
       static_cast<int>(LoaderMethod::Timeout)) {
     timer_ = g_timeout_add(loader_info_->GetTimeout(), TimeoutCb, this);
-    if (timer_ == 0)
-      _E("g_timeout_add() is failed");
+    if (timer_ == 0) _E("g_timeout_add() is failed");
   }
 }
 
 void LoaderContext::SetOnBootTimer(int timeout) {
-  if (on_boot_timer_ != 0)
-    return;
+  if (on_boot_timer_ != 0) return;
 
   on_boot_timer_ = g_timeout_add(timeout, OnBootTimeoutCb, this);
-  if (on_boot_timer_ == 0)
-    _E("g_timeout_add() is failed");
+  if (on_boot_timer_ == 0) _E("g_timeout_add() is failed");
 }
 
 bool LoaderContext::ShouldWaitForFileCreation() {
@@ -413,32 +384,21 @@ bool LoaderContext::ShouldWaitForFileCreation() {
   return false;
 }
 
-int LoaderContext::IncreaseCPUCheckCount() {
-  return ++cpu_check_count_;
-}
+int LoaderContext::IncreaseCPUCheckCount() { return ++cpu_check_count_; }
 
-void LoaderContext::ResetCPUCheckCount() {
-  cpu_check_count_ = 0;
-}
+void LoaderContext::ResetCPUCheckCount() { cpu_check_count_ = 0; }
 
-void LoaderContext::UpdatePssMemory() {
-  Procfs::GetPssMemory(pid_, &pss_);
-}
+void LoaderContext::UpdatePssMemory() { Procfs::GetPssMemory(pid_, &pss_); }
 
-uint64_t LoaderContext::GetPssMemory() const {
-  return pss_;
-}
+uint64_t LoaderContext::GetPssMemory() const { return pss_; }
 
-unsigned int LoaderContext::GetScore() const {
-  return score_;
-}
+unsigned int LoaderContext::GetScore() const { return score_; }
 
 gboolean LoaderContext::TimeoutCb(gpointer user_data) {
   auto* context = static_cast<LoaderContext*>(user_data);
   context->timer_ = 0;
   auto* listener = context->listener_;
-  if (listener != nullptr)
-    listener->OnTimeoutEvent(context);
+  if (listener != nullptr) listener->OnTimeoutEvent(context);
 
   return G_SOURCE_REMOVE;
 }
@@ -451,8 +411,8 @@ gboolean LoaderContext::TimeToLiveCb(gpointer user_data) {
 
 gboolean LoaderContext::OnBootTimeoutCb(gpointer user_data) {
   auto* context = static_cast<LoaderContext*>(user_data);
-  _W("type(%d), loader_name(%s)",
-      context->GetType(), context->GetLoaderName().c_str());
+  _W("type(%d), loader_name(%s)", context->GetType(),
+     context->GetLoaderName().c_str());
   context->on_boot_timer_ = 0;
   if (context->GetPid() > 0) {
     _E("Loader is already running. pid(%d)", context->GetPid());
@@ -465,7 +425,7 @@ gboolean LoaderContext::OnBootTimeoutCb(gpointer user_data) {
   }
 
   _W("Loader(%d:%s) is starting by the on-boot timer option",
-      context->GetType(), context->GetLoaderName().c_str());
+     context->GetType(), context->GetLoaderName().c_str());
   context->Prepare();
   return G_SOURCE_REMOVE;
 }
@@ -475,31 +435,26 @@ void LoaderContext::UpdateScore() {
 }
 
 void LoaderContext::Activate() {
-  _W("type(%d), loader_name(%s), activated(%d)",
-      GetType(), GetLoaderName().c_str(), IsActivated());
-  if (IsActivated())
-    return;
+  _W("type(%d), loader_name(%s), activated(%d)", GetType(),
+     GetLoaderName().c_str(), IsActivated());
+  if (IsActivated()) return;
 
   activated_ = true;
-  if (!touched_ && !loader_info_->IsOnBoot())
-    return;
+  if (!touched_ && !loader_info_->IsOnBoot()) return;
 
-  if (pid_ > 0)
-    return;
+  if (pid_ > 0) return;
 
   if (loader_info_->ShouldCheckAppInstallation() &&
       !loader_info_->IsAppInstalled())
     return;
 
-  if (CanActivate(LoaderMethod::Timeout))
-    SetTimer();
+  if (CanActivate(LoaderMethod::Timeout)) SetTimer();
 }
 
 void LoaderContext::Deactivate() {
-  _W("type(%d), loader_name(%s), activated(%d)",
-      GetType(), GetLoaderName().c_str(), IsActivated());
-  if (!IsActivated())
-    return;
+  _W("type(%d), loader_name(%s), activated(%d)", GetType(),
+     GetLoaderName().c_str(), IsActivated());
+  if (!IsActivated()) return;
 
   activated_ = false;
   Dispose();
@@ -507,23 +462,23 @@ void LoaderContext::Deactivate() {
 
 bool LoaderContext::CanBeDetected(LoaderMethod method) const {
   return (static_cast<int>(loader_info_->GetDetectionMethod()) &
-      static_cast<int>(method));
+          static_cast<int>(method));
 }
 
 bool LoaderContext::CanActivate(LoaderMethod method) const {
   return (static_cast<int>(loader_info_->GetActivationMethod()) &
-      static_cast<int>(method));
+          static_cast<int>(method));
 }
 
 bool LoaderContext::CanDeactivate(LoaderMethod method) const {
   return (static_cast<int>(loader_info_->GetDeactivationMethod()) &
-      static_cast<int>(method));
+          static_cast<int>(method));
 }
 
 void LoaderContext::UpdateState(LoaderMethod method, bool force) {
   _W("type(%d), loader_name(%s), activated(%d), method(%d), force(%d)",
-      GetType(), GetLoaderName().c_str(), activated_, static_cast<int>(method),
-      force);
+     GetType(), GetLoaderName().c_str(), activated_, static_cast<int>(method),
+     force);
   SetLoaderMethod(method);
   switch (method) {
     case LoaderMethod::OutOfMemory:
@@ -536,12 +491,10 @@ void LoaderContext::UpdateState(LoaderMethod method, bool force) {
       }
       break;
     case LoaderMethod::TimeToLive:
-      if (force || CanDeactivate(method))
-        Deactivate();
+      if (force || CanDeactivate(method)) Deactivate();
       break;
     case LoaderMethod::AvailableMemory:
-      if (force || CanActivate(method))
-        Activate();
+      if (force || CanActivate(method)) Activate();
       break;
     case LoaderMethod::Request:
       if (force || CanActivate(method))
@@ -577,32 +530,25 @@ bool LoaderContext::IsLaunchable() {
   return true;
 }
 
-void LoaderContext::SetEventListener(IEvent* listener) {
-  listener_ = listener;
-}
+void LoaderContext::SetEventListener(IEvent* listener) { listener_ = listener; }
 
-void LoaderContext::Ref() {
-  ref_count_++;
-}
+void LoaderContext::Ref() { ref_count_++; }
 
 void LoaderContext::Unref() {
-  if (ref_count_ > 0)
-    ref_count_--;
+  if (ref_count_ > 0) ref_count_--;
 }
 
-uint32_t LoaderContext::RefCount() const {
-  return ref_count_;
-}
+uint32_t LoaderContext::RefCount() const { return ref_count_; }
 
 void LoaderContext::SetLiveTimer() {
-  _W("type(%d), loader_name(%s), deactivation_method(%d)",
-      GetType(), GetLoaderName().c_str(),
-      static_cast<int>(loader_info_->GetDeactivationMethod()));
+  _W("type(%d), loader_name(%s), deactivation_method(%d)", GetType(),
+     GetLoaderName().c_str(),
+     static_cast<int>(loader_info_->GetDeactivationMethod()));
   if (static_cast<int>(loader_info_->GetDeactivationMethod()) &
       static_cast<int>(LoaderMethod::TimeToLive)) {
-      if (live_timer_ == 0) {
+    if (live_timer_ == 0) {
       live_timer_ = g_timeout_add_seconds(loader_info_->GetTimeToLive(),
-          TimeToLiveCb, this);
+                                          TimeToLiveCb, this);
     }
   }
 }
@@ -625,20 +571,18 @@ void LoaderContext::HandleLoaderEvent() {
 
       auto peer_cred = PeerCredentials::Get(client_socket_->GetFd());
       if (peer_cred->GetPid() != pid) {
-        _E("The peer information does not match. %d : %d",
-            peer_cred->GetPid(), pid);
+        _E("The peer information does not match. %d : %d", peer_cred->GetPid(),
+           pid);
         client_socket_.reset();
         return;
       }
 
-      client_channel_.reset(
-          new IOChannel(
-              client_socket_->GetFd(),
-              IOChannel::IOCondition::IO_IN | IOChannel::IOCondition::IO_HUP,
-              this));
+      client_channel_.reset(new IOChannel(
+          client_socket_->GetFd(),
+          IOChannel::IOCondition::IO_IN | IOChannel::IOCondition::IO_HUP,
+          this));
 
-      if (IsHydraMode())
-        SetPid(peer_cred->GetPid());
+      if (IsHydraMode()) SetPid(peer_cred->GetPid());
 
       prepared_ = true;
       if (listener_ != nullptr) {
@@ -648,7 +592,7 @@ void LoaderContext::HandleLoaderEvent() {
 
       SECURE_LOGI("Type %d loader was connected. pid: %d", GetType(), pid_);
       UserTracer::Print("Type " + std::to_string(GetType()) +
-          " loader was connected. pid: " + std::to_string(pid_));
+                        " loader was connected. pid: " + std::to_string(pid_));
     } catch (const Exception& e) {
       _E("Exception occurs. error: %s", e.what());
       return;
@@ -666,7 +610,7 @@ void LoaderContext::HandleLoaderClientEvent(int condition) {
     if (!peer_cred) return;
 
     SECURE_LOGE("Type %d loader was disconnected. pid: %d, peer_cred: %d",
-        GetType(), pid_, peer_cred->GetPid());
+                GetType(), pid_, peer_cred->GetPid());
     Dispose();
     Prepare();
   }
@@ -681,11 +625,10 @@ void LoaderContext::OnIOEventReceived(int fd, int condition) {
 }
 
 void LoaderContext::CreateReadyFile() {
-  if (ready_file_created_)
-    return;
+  if (ready_file_created_) return;
 
-  std::string path = "/tmp/." + std::to_string(getuid()) + "-" +
-      GetLoaderName() + ".ready";
+  std::string path =
+      "/tmp/." + std::to_string(getuid()) + "-" + GetLoaderName() + ".ready";
   std::filesystem::path file_path(path);
   if (std::filesystem::exists(file_path)) {
     ready_file_created_ = true;
index 3f7eea8bc651b92ede4c7836b98ce23a637d20d9..e868c810e1a9b15a6465fa766a428ad7aba286cb 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/loader_mount.hh"
 
 namespace launchpad {
diff --git a/src/launchpad-process-pool/loader_executor.cc b/src/launchpad-process-pool/loader_executor.cc
new file mode 100644 (file)
index 0000000..a20a7f9
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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-process-pool/loader_executor.hh"
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <utility>
+
+#include <aul_keys.hh>
+#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/lux_manager.hh"
+
+namespace launchpad {
+
+LoaderExecutor::LoaderExecutor() {
+  auto& config = Config::GetInst().GetProcessPool();
+  process_pool_ = std::unique_ptr<ProcessPool>(
+      new ProcessPool("loader", config.GetNumberOfLoaderProcesses()));
+}
+
+LoaderExecutor& LoaderExecutor::GetInst() {
+  static LoaderExecutor inst;
+  return inst;
+}
+
+pid_t LoaderExecutor::Execute(const LoaderInfo* loader_info, int loader_id,
+                              int priority) {
+  auto loader_args = CreateLoaderArgv(loader_info, loader_id);
+  tizen_base::Bundle b;
+  b.Add(kAulLuxCmd, std::to_string(static_cast<int>(LuxCmd::ExecuteLoader)));
+  b.Add("LOADER_ARGS", loader_args);
+  b.Add("LOADER_PRIORITY", std::to_string(priority));
+  auto parcel = Util::CreateParcelFromBundle(&b);
+
+  if (process_pool_->IsPrepared()) {
+    pid_t pid = process_pool_->Execute(parcel);
+    if (pid > 0) return pid;
+  }
+
+  return LuxManager::GetInst().SendAndReceive(parcel);
+}
+
+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);
+}
+
+std::vector<std::string> LoaderExecutor::CreateLoaderArgv(
+    const LoaderInfo* loader_info, int loader_id) {
+  std::vector<std::string> argv(LoaderArg::Dummy + 1);
+  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());
+  std::string dummy(kLoaderArgLength - 1, ' ');
+  argv[LoaderArg::Dummy] = std::move(dummy);
+  return argv;
+}
+
+}  // namespace launchpad
diff --git a/src/launchpad-process-pool/loader_executor.hh b/src/launchpad-process-pool/loader_executor.hh
new file mode 100644 (file)
index 0000000..9537546
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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 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/loader_info.hh"
+#include "launchpad-process-pool/process_pool.hh"
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API LoaderExecutor {
+ 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;
+
+  std::vector<std::string> CreateLoaderArgv(const LoaderInfo* loader_info,
+                                            int loader_id);
+
+ private:
+  std::unique_ptr<ProcessPool> process_pool_;
+};
+
+}  // namespace launchpad
+
+#endif  // LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_HH_
index 5d9b6044362f3202904641bdcb0a3d4cbf7cecae..12a7ea219ab371a9b704d125c3e8e44d8da0e1dd 100644 (file)
@@ -33,8 +33,7 @@ namespace {
 std::string GetAppTypeString(const std::shared_ptr<LoaderInfo>& info) {
   std::string app_types;
   for (auto& app_type : info->GetAppTypes()) {
-    if (!app_types.empty())
-      app_types += "|";
+    if (!app_types.empty()) app_types += "|";
 
     app_types += app_type;
   }
@@ -44,11 +43,10 @@ std::string GetAppTypeString(const std::shared_ptr<LoaderInfo>& info) {
 
 constexpr char kInfoDirectoryPath[] = "/usr/share/aul";
 
-std::shared_ptr<LoaderInfo> CreateDynamicLoaderInfo(tizen_base::Bundle b,
-    int loader_id, const std::string& caller_pid) {
+std::shared_ptr<LoaderInfo> CreateDynamicLoaderInfo(
+    tizen_base::Bundle b, int loader_id, const std::string& caller_pid) {
   auto loader_path = b.GetString(kAulLoaderPath);
-  if (loader_path.empty())
-    return nullptr;
+  if (loader_path.empty()) return nullptr;
 
   auto loader_name = loader_path + caller_pid + std::to_string(loader_id);
   LoaderInfo::Builder builder;
@@ -57,9 +55,9 @@ std::shared_ptr<LoaderInfo> CreateDynamicLoaderInfo(tizen_base::Bundle b,
   builder.SetExe(std::move(loader_path));
   builder.SetDetectionMethod(LoaderMethod::Timeout | LoaderMethod::Visibility);
   builder.SetActivationMethod(LoaderMethod::Request |
-      LoaderMethod::AvailableMemory);
+                              LoaderMethod::AvailableMemory);
   builder.SetDeactivationMethod(LoaderMethod::TimeToLive |
-      LoaderMethod::OutOfMemory);
+                                LoaderMethod::OutOfMemory);
   builder.SetTimeToLive(600);
   builder.SetTimeout(2000);
   builder.SetOnBoot(false);
@@ -77,61 +75,57 @@ LoaderFactory& LoaderFactory::GetInst() {
 std::shared_ptr<LoaderContext> LoaderFactory::CreateLoaderContext(
     LoaderInfoPtr info, std::shared_ptr<LoaderMount> loader_mount) {
   auto app_types = GetAppTypeString(info);
-  int loader_id = static_cast<int>((info->GetExe() == "null") ?
-      PadLoaderId::Direct : PadLoaderId::Static);
+  int loader_id = static_cast<int>(
+      (info->GetExe() == "null") ? PadLoaderId::Direct : PadLoaderId::Static);
   LoaderContext* context;
   try {
     if (info->IsHydraMode()) {
       context = HydraLoaderContext::Builder()
-        .SetLoaderInfo(std::move(info))
-        .SetLoaderId(loader_id)
-        .SetActive()
-        .SetLoaderMount(std::move(loader_mount));
+                    .SetLoaderInfo(std::move(info))
+                    .SetLoaderId(loader_id)
+                    .SetActive()
+                    .SetLoaderMount(std::move(loader_mount));
     } else {
       context = LoaderContext::Builder()
-        .SetLoaderInfo(std::move(info))
-        .SetLoaderId(loader_id)
-        .SetActive()
-        .SetLoaderMount(std::move(loader_mount));
+                    .SetLoaderInfo(std::move(info))
+                    .SetLoaderId(loader_id)
+                    .SetActive()
+                    .SetLoaderMount(std::move(loader_mount));
     }
   } catch (const Exception& e) {
     _E("Exception occurs. error(%s)", e.what());
     return nullptr;
   }
 
-  if (context == nullptr)
-    return nullptr;
+  if (context == nullptr) return nullptr;
 
   _I("loader_type(%d), loader_id(%d), loader_name(%s), app_type(%s)",
-      context->GetType(), loader_id, context->GetLoaderName().c_str(),
-      app_types.c_str());
+     context->GetType(), loader_id, context->GetLoaderName().c_str(),
+     app_types.c_str());
   UserTracer::Print("candidate slot. app-type(" + app_types + ") loader-type(" +
-      std::to_string(context->GetType()));
+                    std::to_string(context->GetType()));
   return std::shared_ptr<LoaderContext>(context);
 }
 
 std::shared_ptr<LoaderContext> LoaderFactory::CreateLoaderContext(
     tizen_base::Bundle b, std::shared_ptr<LoaderMount> loader_mount) {
   auto caller_pid = b.GetString(kAulCallerPid);
-  if (caller_pid.empty())
-    return nullptr;
+  if (caller_pid.empty()) return nullptr;
 
   int loader_id = MakeDynamicLoaderId();
-  auto loader_info = CreateDynamicLoaderInfo(std::move(b), loader_id,
-      caller_pid);
-  if (loader_info == nullptr)
-    return nullptr;
+  auto loader_info =
+      CreateDynamicLoaderInfo(std::move(b), loader_id, caller_pid);
+  if (loader_info == nullptr) return nullptr;
 
   LoaderContext* context;
   try {
     context = LoaderContext::Builder()
-        .SetLoaderInfo(std::move(loader_info))
-        .SetLoaderId(loader_id)
-        .SetCallerPid(std::stoi(caller_pid))
-        .SetActive()
-        .SetLoaderMount(std::move(loader_mount));
-    if (context == nullptr)
-        return nullptr;
+                  .SetLoaderInfo(std::move(loader_info))
+                  .SetLoaderId(loader_id)
+                  .SetCallerPid(std::stoi(caller_pid))
+                  .SetActive()
+                  .SetLoaderMount(std::move(loader_mount));
+    if (context == nullptr) return nullptr;
   } catch (const Exception& e) {
     _E("Exception occurs. error(%s)", e.what());
     return nullptr;
@@ -147,13 +141,12 @@ std::shared_ptr<LoaderContext> LoaderFactory::CreateLoaderContext(
   LoaderContext* context;
   try {
     context = LoaderContext::Builder()
-        .SetLoaderInfo(std::move(info))
-        .SetLoaderId(loader_id)
-        .SetCallerPid(caller_pid)
-        .SetActive()
-        .SetLoaderMount(std::move(loader_mount));
-    if (context == nullptr)
-      return nullptr;
+                  .SetLoaderInfo(std::move(info))
+                  .SetLoaderId(loader_id)
+                  .SetCallerPid(caller_pid)
+                  .SetActive()
+                  .SetLoaderMount(std::move(loader_mount));
+    if (context == nullptr) return nullptr;
   } catch (const Exception& e) {
     _E("Exception occurs. error(%s)", e.what());
     return nullptr;
@@ -162,8 +155,6 @@ std::shared_ptr<LoaderContext> LoaderFactory::CreateLoaderContext(
   return std::shared_ptr<LoaderContext>(context);
 }
 
-int LoaderFactory::MakeDynamicLoaderId() {
-  return ++dynamic_loader_id_;
-}
+int LoaderFactory::MakeDynamicLoaderId() { return ++dynamic_loader_id_; }
 
 }  // namespace launchpad
index 4d116fa0ac9f9e4499b6ef3ca2bc617280854799..2208c82bac525876c209a2c6466a5baf837df695 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
new file mode 100644 (file)
index 0000000..45c0a37
--- /dev/null
@@ -0,0 +1,713 @@
+/*
+ * 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-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 <util.hh>
+
+#include "launchpad-process-pool/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/launchpad-process-pool/loader_info.hh b/src/launchpad-process-pool/loader_info.hh
new file mode 100644 (file)
index 0000000..2802564
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * 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 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 <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;
+  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 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  // LAUNCHPAD_PROCESS_POOL_LOADER_INFO_HH_
index 20fc128c41145e81c455b258c10d22e1eb1c2797..f7b42713492aec6f876b063b3a456908d42e54b6 100644 (file)
 #include <algorithm>
 #include <utility>
 
-#include <loader_executor.hh>
 #include <types.hh>
 
 #include "launchpad-process-pool/config.hh"
 #include "launchpad-process-pool/loader_factory.hh"
+#include "launchpad-process-pool/loader_executor.hh"
 #include "launchpad-process-pool/log_private.hh"
 
 namespace launchpad {
@@ -40,8 +40,7 @@ LoaderManager& LoaderManager::GetInst() {
 }
 
 void LoaderManager::Dispose() {
-  if (disposed_)
-    return;
+  if (disposed_) return;
 
   loader_mount_.reset();
   hwacc_config_.reset();
@@ -53,8 +52,7 @@ void LoaderManager::Dispose() {
 }
 
 void LoaderManager::Init() {
-  if (!disposed_)
-    return;
+  if (!disposed_) return;
 
   try {
     sequencer_.reset(new Sequencer(this));
@@ -131,17 +129,13 @@ void LoaderManager::ActivateLoaderContexts(LoaderMethod method) {
         context->GetOnBootTimeout() > 0)
       context->SetOnBootTimer(context->GetOnBootTimeout());
 
-    if (!context->IsActivated())
-      continue;
+    if (!context->IsActivated()) continue;
 
-    if (context->GetLoaderPath() == "null")
-      continue;
+    if (context->GetLoaderPath() == "null") continue;
 
-    if (!context->IsTouched() && !context->IsOnBoot())
-      continue;
+    if (!context->IsTouched() && !context->IsOnBoot()) continue;
 
-    if (context->GetPid() > 0)
-      continue;
+    if (context->GetPid() > 0) continue;
 
     if (!context->IsTouched() || context->CanBeDetected(method)) {
       context->UnsetTimer();
@@ -165,16 +159,14 @@ std::shared_ptr<LoaderContext> LoaderManager::PrepareAppDefinedLoaderContext(
     context = LoaderFactory::GetInst().CreateLoaderContext(info, caller_pid,
                                                            loader_mount_);
     if (context == nullptr) {
-      _E("Failed to create loader context. loader_name: %s",
-          name.c_str());
+      _E("Failed to create loader context. loader_name: %s", name.c_str());
       return nullptr;
     }
 
     loader_contexts_.push_back(context);
   }
 
-  if (context->GetPid() < 1)
-    context->Prepare();
+  if (context->GetPid() < 1) context->Prepare();
 
   return context;
 }
@@ -183,8 +175,7 @@ std::shared_ptr<LoaderContext> LoaderManager::AddLoaderContext(
     tizen_base::Bundle b) {
   auto context =
       LoaderFactory::GetInst().CreateLoaderContext(std::move(b), loader_mount_);
-  if (context == nullptr)
-    return nullptr;
+  if (context == nullptr) return nullptr;
 
   context->SetEventListener(this);
   context->SetTimer();
@@ -193,17 +184,14 @@ std::shared_ptr<LoaderContext> LoaderManager::AddLoaderContext(
 }
 
 void LoaderManager::HandleDirectLaunch(std::shared_ptr<LoaderContext> context) {
-  if (context == nullptr)
-    return;
+  if (context == nullptr) return;
 
   if (context->ShouldCheckAppInstallation() && !context->IsAppInstalled())
     return;
 
-  if (context->GetPid() > 0)
-    return;
+  if (context->GetPid() > 0) return;
 
-  if (sequencer_->Exist(context))
-    return;
+  if (sequencer_->Exist(context)) return;
 
   context->UnsetTimer();
   context->UpdateState(LoaderMethod::Request, true);
@@ -211,13 +199,12 @@ void LoaderManager::HandleDirectLaunch(std::shared_ptr<LoaderContext> context) {
 }
 
 void LoaderManager::UpdateAppInstallationStatus(const std::string& app_type,
-    bool app_installed) {
+                                                bool app_installed) {
   for (auto& info : loader_info_manager_->GetLoaderInfoList()) {
-    auto found = std::find_if(info->GetAppTypes().begin(),
-        info->GetAppTypes().end(),
+    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())
-      continue;
+    if (found == info->GetAppTypes().end()) continue;
 
     info->SetAppInstalled(app_installed);
     UpdateLoaderContext(info->GetType());
@@ -227,8 +214,7 @@ void LoaderManager::UpdateAppInstallationStatus(const std::string& app_type,
 std::shared_ptr<LoaderContext> LoaderManager::FindLoaderContextFromPid(
     pid_t pid) {
   for (auto& context : loader_contexts_) {
-    if (context->GetPid() == pid)
-      return context;
+    if (context->GetPid() == pid) return context;
   }
 
   return nullptr;
@@ -239,8 +225,8 @@ LoaderManager::FindHydraLoaderContextFromPid(pid_t pid) {
   for (auto& context : loader_contexts_) {
     auto* hydra_context = dynamic_cast<HydraLoaderContext*>(context.get());
     if (hydra_context != nullptr && hydra_context->GetHydraPid() == pid) {
-        return std::dynamic_pointer_cast<HydraLoaderContext>(
-            hydra_context->shared_from_this());
+      return std::dynamic_pointer_cast<HydraLoaderContext>(
+          hydra_context->shared_from_this());
     }
   }
 
@@ -263,15 +249,14 @@ void LoaderManager::RemoveLoaderContextsByCallerPid(pid_t caller_pid) {
 std::shared_ptr<LoaderContext> LoaderManager::FindLoaderContextFromName(
     const std::string& loader_name) {
   for (auto& context : loader_contexts_) {
-    if (context->GetLoaderName() == loader_name)
-      return context;
+    if (context->GetLoaderName() == loader_name) return context;
   }
 
   return nullptr;
 }
 
 std::shared_ptr<LoaderContext> LoaderManager::FindLoaderContext(LoaderType type,
-    int loader_id) {
+                                                                int loader_id) {
   if (type == LoaderType::Dynamic)
     return FindLoaderContextFromLoaderId(loader_id);
 
@@ -281,8 +266,7 @@ std::shared_ptr<LoaderContext> LoaderManager::FindLoaderContext(LoaderType type,
 std::shared_ptr<LoaderContext> LoaderManager::FindLoaderContextFromLoaderId(
     int loader_id) {
   for (auto& context : loader_contexts_) {
-    if (context->GetLoaderId() == loader_id)
-      return context;
+    if (context->GetLoaderId() == loader_id) return context;
   }
 
   return nullptr;
@@ -290,12 +274,10 @@ std::shared_ptr<LoaderContext> LoaderManager::FindLoaderContextFromLoaderId(
 
 std::shared_ptr<LoaderContext> LoaderManager::FindLoaderContextFromType(
     LoaderType type) {
-  if (type == LoaderType::Dynamic || type == LoaderType::None)
-    return nullptr;
+  if (type == LoaderType::Dynamic || type == LoaderType::None) return nullptr;
 
   for (auto& context : loader_contexts_) {
-    if (context->GetType() == static_cast<int>(type))
-      return context;
+    if (context->GetType() == static_cast<int>(type)) return context;
   }
 
   return nullptr;
@@ -304,7 +286,7 @@ std::shared_ptr<LoaderContext> LoaderManager::FindLoaderContextFromType(
 std::shared_ptr<LoaderContext> LoaderManager::FindAvailableLoaderContext(
     const std::string& hwacc, const std::string& app_type,
     const std::string& loader_name) {
-    LoaderType type = LoaderType::None;
+  LoaderType type = LoaderType::None;
   if (!loader_name.empty()) {
     for (auto& info : loader_info_manager_->GetLoaderInfoList()) {
       if (info->GetName() == loader_name) {
@@ -327,8 +309,7 @@ std::shared_ptr<LoaderContext> LoaderManager::FindAlternativeLoaderContext(
   auto alternative_types = loader_info_manager_->GetAlternativeTypes(type);
   for (auto& alternative_type : alternative_types) {
     auto context = FindLoaderContext(alternative_type, PadLoaderId::Static);
-    if (context == nullptr)
-      continue;
+    if (context == nullptr) continue;
 
     return context;
   }
@@ -346,23 +327,20 @@ bool LoaderManager::IsHwAcceleration(const std::string& hwacc) {
 
 void LoaderManager::UpdateLoaderContext(LoaderType type) {
   auto loader_context = FindLoaderContextFromType(type);
-  if (loader_context == nullptr)
-    return;
+  if (loader_context == nullptr) return;
 
-  _W("type(%d), loader_name(%s), app_installed(%s:%s)",
-      static_cast<int>(type), loader_context->GetLoaderName().c_str(),
-      loader_context->ShouldCheckAppInstallation() ? "yes" : "no",
-      loader_context->IsAppInstalled() ? "yes" : "no");
+  _W("type(%d), loader_name(%s), app_installed(%s:%s)", static_cast<int>(type),
+     loader_context->GetLoaderName().c_str(),
+     loader_context->ShouldCheckAppInstallation() ? "yes" : "no",
+     loader_context->IsAppInstalled() ? "yes" : "no");
   if (loader_context->ShouldCheckAppInstallation() &&
       !loader_context->IsAppInstalled()) {
     loader_context->Dispose();
     sequencer_->Remove(loader_context);
   } else {
-    if (!loader_context->IsActivated())
-      return;
+    if (!loader_context->IsActivated()) return;
 
-    if (!loader_context->IsTouched() && !loader_context->IsOnBoot())
-      return;
+    if (!loader_context->IsTouched() && !loader_context->IsOnBoot()) return;
 
     loader_context->UnsetTimer();
     if (loader_context->GetPid() < 1) {
@@ -417,39 +395,34 @@ void LoaderManager::HandleMemoryStatusChangedEvent(bool low_memory) {
 
 void LoaderManager::UpdatePssMemoryOfLoaderContexts() {
   for (auto& loader_context : loader_contexts_) {
-    if (loader_context->GetPid() > 0)
-      loader_context->UpdatePssMemory();
+    if (loader_context->GetPid() > 0) loader_context->UpdatePssMemory();
   }
 }
 
 void LoaderManager::SortLoaderContexts() {
   std::sort(loader_contexts_.begin(), loader_contexts_.end(),
-      [&](const std::shared_ptr<LoaderContext> context_a,
-          const std::shared_ptr<LoaderContext> context_b) -> bool {
-        if (context_a->IsHydraMode() && !context_b->IsHydraMode())
-          return false;
+            [&](const std::shared_ptr<LoaderContext> context_a,
+                const std::shared_ptr<LoaderContext> context_b) -> bool {
+              if (context_a->IsHydraMode() && !context_b->IsHydraMode())
+                return false;
 
-        if (!context_a->IsHydraMode() && context_b->IsHydraMode())
-          return true;
+              if (!context_a->IsHydraMode() && context_b->IsHydraMode())
+                return true;
 
-        if (context_a->GetScore() > context_b->GetScore())
-          return false;
+              if (context_a->GetScore() > context_b->GetScore()) return false;
 
-        if (context_a->GetScore() < context_b->GetScore())
-          return true;
+              if (context_a->GetScore() < context_b->GetScore()) return true;
 
-        return context_a->GetPssMemory() < context_b->GetPssMemory();
-      });
+              return context_a->GetPssMemory() < context_b->GetPssMemory();
+            });
 }
 
 void LoaderManager::DeactivateLoaderContexts() {
   for (auto& loader_context : loader_contexts_) {
-    if (loader_context->IsHydraMode())
-      continue;
+    if (loader_context->IsHydraMode()) continue;
 
     loader_context->UpdateState(LoaderMethod::OutOfMemory, true);
-    if (!MemoryMonitor::GetInst().IsLowMemory())
-      return;
+    if (!MemoryMonitor::GetInst().IsLowMemory()) return;
   }
 }
 
@@ -460,9 +433,7 @@ void LoaderManager::ActivateLoaderContexts() {
 
 LoaderManager::LoaderManager() : sequencer_(new Sequencer(this)) {}
 
-LoaderManager::~LoaderManager() {
-  Dispose();
-}
+LoaderManager::~LoaderManager() { Dispose(); }
 
 void LoaderManager::OnAppLabelsChanged() {
   _W("BEGIN");
@@ -476,9 +447,8 @@ void LoaderManager::OnAppLabelsChanged() {
       }
     } else if (context->GetPid() > 0) {
       if (context->RefCount() != 0) {
-        _W("Except. type(%d), loader_name(%s), pid(%d)",
-            context->GetType(), context->GetLoaderName().c_str(),
-            context->GetPid());
+        _W("Except. type(%d), loader_name(%s), pid(%d)", context->GetType(),
+           context->GetLoaderName().c_str(), context->GetPid());
         continue;
       }
 
@@ -490,7 +460,7 @@ void LoaderManager::OnAppLabelsChanged() {
 }
 
 void LoaderManager::OnMemoryStatusChanged(bool low_memory,
-    bool should_check_pss) {
+                                          bool should_check_pss) {
   if (should_check_pss)
     HandleMemoryStatusChangedEvent(low_memory);
   else
@@ -507,9 +477,8 @@ void LoaderManager::OnLoaderInfoRemoved(const std::string_view name) {
 }
 
 void LoaderManager::OnTimeoutEvent(LoaderContext* context) {
-  _W("type(%d), loader_name(%s), state(%d)",
-      context->GetType(), context->GetLoaderName().c_str(),
-      context->IsActivated());
+  _W("type(%d), loader_name(%s), state(%d)", context->GetType(),
+     context->GetLoaderName().c_str(), context->IsActivated());
 
   if (context->GetPid() > 0) {
     _W("The loader is already running");
@@ -521,11 +490,10 @@ void LoaderManager::OnTimeoutEvent(LoaderContext* context) {
 }
 
 bool LoaderManager::OnIdleCheck(LoaderContext* context) {
-  _W("Loader(%s), type(%d), pid(%d)",
-      context->GetLoaderName().c_str(), context->GetType(), context->GetPid());
+  _W("Loader(%s), type(%d), pid(%d)", context->GetLoaderName().c_str(),
+     context->GetType(), context->GetPid());
 
-  if (!context->IsLaunchable())
-    return false;
+  if (!context->IsLaunchable()) return false;
 
   if (context->GetCPUChecker()->IsIdle()) {
     context->Prepare();
@@ -542,23 +510,20 @@ bool LoaderManager::OnIdleCheck(LoaderContext* context) {
 }
 
 void LoaderManager::OnLoaderLaunch(LoaderContext* context) {
-  _D("Loader(%s), type(%d), pid(%d)",
-      context->GetLoaderName().c_str(), context->GetType(), context->GetPid());
+  _D("Loader(%s), type(%d), pid(%d)", context->GetLoaderName().c_str(),
+     context->GetType(), context->GetPid());
 
-  if (!context->IsLaunchable())
-    return;
+  if (!context->IsLaunchable()) return;
 
   context->Prepare();
 }
 
 void LoaderManager::OnLoaderPrepared(LoaderContext* context) {
-  if (event_listener_ != nullptr)
-    event_listener_->OnLoaderPrepared(context);
+  if (event_listener_ != nullptr) event_listener_->OnLoaderPrepared(context);
 }
 
 void LoaderManager::OnLoaderLaunched(LoaderContext* context) {
-  if (event_listener_ != nullptr)
-    event_listener_->OnLoaderLaunched(context);
+  if (event_listener_ != nullptr) event_listener_->OnLoaderLaunched(context);
 }
 
 }  // namespace launchpad
index 7d8c93973e01da68e977e78016d17ad7c95fc29b..a433670d81512b1163c474b136311cf4ab1aeb07 100644 (file)
@@ -27,7 +27,6 @@
 #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"
@@ -35,6 +34,7 @@
 #include "launchpad-process-pool/hydra_loader_context.hh"
 #include "launchpad-process-pool/loader_context.hh"
 #include "launchpad-process-pool/loader_mount.hh"
+#include "launchpad-process-pool/loader_info.hh"
 #include "launchpad-process-pool/memory_monitor.hh"
 #include "launchpad-process-pool/sequencer.hh"
 
@@ -71,10 +71,10 @@ class LoaderManager : public AppDefinedLoaderInfoManager::IEvent,
       const std::string& name, pid_t caller_pid);
   std::shared_ptr<LoaderContext> AddLoaderContext(tizen_base::Bundle b);
   void UpdateAppInstallationStatus(const std::string& app_type,
-      bool app_installed);
+                                   bool app_installed);
   void HandleDirectLaunch(std::shared_ptr<LoaderContext> context);
   std::shared_ptr<LoaderContext> FindLoaderContext(LoaderType type,
-      int loader_id);
+                                                   int loader_id);
   std::shared_ptr<LoaderContext> FindAvailableLoaderContext(
       const std::string& hwacc, const std::string& app_type,
       const std::string& loader_name);
index d623ca111ae3b68f9350bd8a55de09124b31769d..62536b15c11ea5d87f0a8b8b6159e525258b008a 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;
@@ -54,8 +54,7 @@ bool IsExceptable(const std::string& path) {
   }
 
   buf[len] = '\0';
-  if (strstr(buf, "log") != nullptr ||
-      strstr(buf, "trace") != nullptr ||
+  if (strstr(buf, "log") != nullptr || strstr(buf, "trace") != nullptr ||
       strstr(buf, "dev") != nullptr)
     return true;
 
@@ -67,8 +66,7 @@ std::vector<int> GetExceptableFds() {
   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;
+      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()))
@@ -182,8 +180,8 @@ void LoaderMount::Prepare() {
   int read_fd = pipe_fd[0];
   write_socket_.reset(new Socket(pipe_fd[1]));
 
-  _W("read_socket=%d, write_socket=%d",
-     read_socket_->GetFd(), write_socket_->GetFd());
+  _W("read_socket=%d, write_socket=%d", read_socket_->GetFd(),
+     write_socket_->GetFd());
   pid_ = Executor::Execute();
   if (pid_ == -1) {
     _E("Failed to fork process. errno(%d)", errno);
@@ -218,7 +216,8 @@ void LoaderMount::HandleSigchld(pid_t pid) {
 int LoaderMount::Mount(pid_t pid, const AppInfo* app_info) {
   auto& b = app_info->GetBundle();
   if (b.GetType(kAulMountGadgetPaths) == BUNDLE_TYPE_NONE &&
-      b.GetType(kAulMountLibDir) == BUNDLE_TYPE_NONE) return 0;
+      b.GetType(kAulMountLibDir) == BUNDLE_TYPE_NONE)
+    return 0;
 
   tizen_base::Parcel parcel;
   Request request(pid, b);
@@ -230,7 +229,7 @@ int LoaderMount::Mount(pid_t pid, const AppInfo* app_info) {
 
   parcel.Clear();
   ret = Read(&parcel);
-  if (ret!= 0) return ret;
+  if (ret != 0) return ret;
 
   _W("receive result");
   Reply reply(&parcel);
@@ -252,7 +251,6 @@ void LoaderMount::OnExecution() {
   exit(ret);
 }
 
-
 int LoaderMount::CreatePipe(int (*pipe_fd)[2]) {
   (*pipe_fd)[0] = -1;
   (*pipe_fd)[1] = -1;
index e783c70ecebc7315505ead6c83ac57c80099d731..6bc2274e9d5b975057dda67fc868170a89bac622 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 {
index 8d22e5be9b54868ef3d12b3ee01ee360192f4e21..0b7a09aa64268d5e73962da76cf3272092f1b775 100644 (file)
@@ -36,7 +36,7 @@ std::unique_ptr<Logger> logger_;
 
 void Log::Init() {
   const std::string log_path = Config::GetInst().GetLogger().GetPath() +
-      std::string("/launchpad/launchpad.log");
+                               std::string("/launchpad/launchpad.log");
   try {
     logger_.reset(new Logger(log_path));
   } catch (const Exception &e) {
@@ -47,8 +47,7 @@ void Log::Init() {
 void Log::Finish() { logger_.reset(); }
 
 void Log::Print(const char *tag, const char *format, ...) {
-  if (!logger_)
-    return;
+  if (!logger_) return;
 
   char buf[256];
   va_list ap;
index 689068cc2a35d4bc3b6f1cbd4159fc64230d1693..137fc2a40085083601e12fd95e0fae8ff8028285 100644 (file)
@@ -50,8 +50,7 @@ int SetSmackLabel(const std::string &path, const std::string &label) {
 }
 
 int CreateDirectory(const std::string &path) {
-  if (std::filesystem::exists(path))
-    return 0;
+  if (std::filesystem::exists(path)) return 0;
 
   try {
     std::filesystem::create_directories(path);
@@ -67,15 +66,12 @@ int CreateDirectory(const std::string &path) {
 int CreateLaunchpadDirectories() {
   const std::string logger_path =
       launchpad::Config::GetInst().GetLogger().GetPath();
-  if (CreateDirectory(logger_path) != 0)
-    return -1;
+  if (CreateDirectory(logger_path) != 0) return -1;
 
-  if (SetSmackLabel(logger_path, SMACK_LABEL_USER_HOME) != 0)
-    return -1;
+  if (SetSmackLabel(logger_path, SMACK_LABEL_USER_HOME) != 0) return -1;
 
   const std::string path = logger_path + "/launchpad";
-  if (CreateDirectory(path) != 0)
-    return -1;
+  if (CreateDirectory(path) != 0) return -1;
 
   return SetSmackLabel(path, SMACK_LABEL_USER);
 }
@@ -88,8 +84,7 @@ Logger::Logger(std::string path) : path_(std::move(path)) {
     return;
   }
 
-  if (CreateLaunchpadDirectories() != 0)
-    THROW(-EIO);
+  if (CreateLaunchpadDirectories() != 0) THROW(-EIO);
 
   stream_.open(path_, std::ios::out | std::ios::app);
   if (!stream_.is_open()) {
@@ -97,15 +92,13 @@ Logger::Logger(std::string path) : path_(std::move(path)) {
     THROW(-EIO);
   }
 
-  if (SetSmackLabel(path_.c_str(), SMACK_LABEL_USER) != 0)
-    THROW(-EIO);
+  if (SetSmackLabel(path_.c_str(), SMACK_LABEL_USER) != 0) THROW(-EIO);
 }
 
 Logger::~Logger() { stream_.close(); }
 
 void Logger::Print(const char *tag, const char *format, ...) {
-  if (disabled_)
-    return;
+  if (disabled_) return;
 
   if (tag == nullptr || format == nullptr) {
     _E("Invalid parameter");
@@ -128,8 +121,7 @@ void Logger::Print(const char *tag, const char *format, ...) {
   localtime_r(&t, &tm);
 
   const int threshold = 1000000;  // 1MB
-  if (stream_.tellp() >= threshold)
-    stream_.seekp(0);
+  if (stream_.tellp() >= threshold) stream_.seekp(0);
 
   char buf[256];
   int len = snprintf(buf, sizeof(buf),
@@ -138,8 +130,7 @@ void Logger::Print(const char *tag, const char *format, ...) {
                      tm.tm_hour, tm.tm_min, tm.tm_sec, tag, format_buf);
 
   stream_.write(buf, len);
-  if (!stream_.good())
-    _E("write() is failed");
+  if (!stream_.good()) _E("write() is failed");
 
   stream_.flush();
   index_ = (index_ + 1) % 2500;
diff --git a/src/launchpad-process-pool/lux_manager.cc b/src/launchpad-process-pool/lux_manager.cc
new file mode 100644 (file)
index 0000000..f3c8850
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * 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-process-pool/lux_manager.hh"
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <exception.hh>
+#include <socket.hh>
+#include <peer_credentials.hh>
+#include <util.hh>
+#include <types.hh>
+
+#include "launchpad-process-pool/log_private.hh"
+
+namespace {
+
+constexpr const char kPathLux[] = "/usr/bin/lux";
+
+}  // namespace
+
+namespace launchpad {
+
+LuxManager& LuxManager::GetInst() {
+  static LuxManager inst;
+  return inst;
+}
+
+void LuxManager::Init() {
+  if (!disposed_) return;
+
+  if (!Prepare()) return;
+
+  try {
+    sigchld_channel_.reset(new IOChannel(sigchld_socket_->GetFd(),
+                                         IOChannel::IOCondition::IO_IN, this));
+  } catch (const Exception& e) {
+    _E("Exception occurs. error=%s", e.what());
+    return;
+  }
+
+  disposed_ = false;
+}
+
+void LuxManager::Dispose() {
+  if (disposed_) return;
+
+  Kill();
+  sigchld_channel_.reset();
+  sigchld_socket_.reset();
+  read_socket_.reset();
+  write_socket_.reset();
+  disposed_ = true;
+}
+
+bool LuxManager::Prepare() {
+  if (pid_ > 0) return false;
+
+  int pipe_fd[2];
+  if (CreatePipe(&pipe_fd) != 0) return false;
+
+  read_socket_.reset(new Socket(pipe_fd[0]));
+  int write_fd = pipe_fd[1];
+
+  if (CreatePipe(&pipe_fd) != 0) {
+    close(write_fd);
+    return false;
+  }
+
+  int read_fd = pipe_fd[0];
+  write_socket_.reset(new Socket(pipe_fd[1]));
+
+  if (CreatePipe(&pipe_fd) != 0) {
+    close(read_fd);
+    close(write_fd);
+    return false;
+  }
+
+  int sigchld_fd = pipe_fd[0];
+  sigchld_socket_.reset(new Socket(pipe_fd[1]));
+
+  _W("read_socket=%d, write_socket=%d, sigchld_socket=%d",
+     read_socket_->GetFd(), write_socket_->GetFd(), sigchld_socket_->GetFd());
+  pid_ = Executor::Execute();
+  if (pid_ < 0) {
+    _E("Failed to execute lux. errno(%d)", errno);
+    close(sigchld_fd);
+    close(read_fd);
+    close(write_fd);
+    return false;
+  }
+
+  _W("Lux process=%d", pid_);
+  sigchld_socket_.reset(new Socket(sigchld_fd));
+  read_socket_.reset(new Socket(read_fd));
+  write_socket_.reset(new Socket(write_fd));
+  return true;
+}
+
+bool LuxManager::IsPrepared() const {
+  return (pid_ > 0);
+}
+
+pid_t LuxManager::SendAndReceive(const tizen_base::Parcel& parcel) {
+  _W("Send a request");
+  size_t data_size = parcel.GetDataSize();
+  int ret =
+      write_socket_->Write(static_cast<void*>(&data_size), sizeof(data_size));
+  if (ret != 0) {
+    _E("Failed to write the data size. error=%d", ret);
+    return ret;
+  }
+
+  ret = write_socket_->Write(parcel.GetData(), data_size);
+  if (ret != 0) {
+    _E("Failed to write the data. error=%d", ret);
+    return ret;
+  }
+
+  pid_t pid = -1;
+  ret = read_socket_->Read(static_cast<void*>(&pid), sizeof(pid));
+  if (ret != 0) {
+    _E("Failed to read the result. error=%d", ret);
+    return ret;
+  }
+
+  return pid;
+}
+
+void LuxManager::HandleSigchld(pid_t pid) {
+  if (pid_ != pid) return;
+
+  sigchld_channel_.reset();
+  sigchld_socket_.reset();
+  read_socket_.reset();
+  write_socket_.reset();
+  pid_ = -1;
+  Prepare();
+}
+
+void LuxManager::SetEventListener(IEvent* listener) { listener_ = listener; }
+
+LuxManager::LuxManager() : Executor(this) {}
+
+LuxManager::~LuxManager() { Dispose(); }
+
+int LuxManager::CreatePipe(int (*pipe_fd)[2]) {
+  (*pipe_fd)[0] = -1;
+  (*pipe_fd)[1] = -1;
+
+  if (pipe(*pipe_fd) == -1) {
+    _E("pipe() is failed. errno(%d)", errno);
+    return -1;
+  }
+
+  if (fcntl((*pipe_fd)[0], F_SETPIPE_SZ, Socket::kSocketMaxBufferSize) == -1)
+    _E("Failed to set pipe size. pipe_fd(%d), errno(%d)", (*pipe_fd)[0], errno);
+
+  if (fcntl((*pipe_fd)[1], F_SETPIPE_SZ, Socket::kSocketMaxBufferSize) == -1)
+    _E("Failed to set pipe size. pipe_fd(%d), errno(%d)", (*pipe_fd)[1], errno);
+
+  return 0;
+}
+
+void LuxManager::Kill() {
+  if (pid_ < 0) return;
+
+  _W("Kill process=%d", pid_);
+  if (kill(pid_, SIGKILL) != 0)
+    _E("kill() is failed. pid=%d, errno=%d", pid_, errno);
+
+  pid_ = -1;
+}
+void LuxManager::OnIOEventReceived(int fd, int condition) {
+  _D("fd=%d, condition=%d", fd, condition);
+  size_t data_size = 0;
+  int ret =
+      sigchld_socket_->Read(static_cast<void*>(&data_size), sizeof(data_size));
+  if (ret != 0) {
+    _E("Failed to receive the data. error=%d", ret);
+    return;
+  }
+
+  std::vector<uint8_t> data(data_size);
+  ret = sigchld_socket_->Read(data.data(), data_size);
+  if (ret != 0) {
+    _E("Failed to receive the data. error=%d", ret);
+    return;
+  }
+
+  tizen_base::Parcel parcel(data.data(), data.size());
+  pid_t pid = -1;
+  parcel.ReadInt32(&pid);
+  int status = 0;
+  parcel.ReadInt32(&status);
+  _W("[SIGCHLD] pid=%d, status=%d", pid, status);
+  if (listener_) listener_->OnLuxSigchld(pid, status);
+}
+
+void LuxManager::OnExecution() {
+  std::vector<int> except_fds{read_socket_->GetFd(), write_socket_->GetFd(),
+                              sigchld_socket_->GetFd()};
+  Util::CloseAllFds(except_fds);
+
+  std::string rfd = std::to_string(read_socket_->RemoveFd());
+  std::string wfd = std::to_string(write_socket_->RemoveFd());
+  std::string sfd = std::to_string(sigchld_socket_->RemoveFd());
+  setenv("LUX_READ_FD", rfd.c_str(), 1);
+  setenv("LUX_WRITE_FD", wfd.c_str(), 1);
+  setenv("LUX_SIGCHLD_FD", sfd.c_str(), 1);
+
+  std::vector<char*> args;
+  args.push_back(const_cast<char*>(kPathLux));
+  args.push_back(nullptr);
+
+  SECURE_LOGW("Execute Lux(%s)", kPathLux);
+  int ret = execv(args[LoaderArg::Path], args.data());
+  if (ret < 0) {
+    char err_buf[1024];
+    fprintf(stderr, "Failed to execute a file. path: %s, errno: %d(%s)\n",
+            kPathLux, errno, strerror_r(errno, err_buf, sizeof(err_buf)));
+  }
+  exit(ret);
+}
+
+}  // namespace launchpad
diff --git a/src/launchpad-process-pool/lux_manager.hh b/src/launchpad-process-pool/lux_manager.hh
new file mode 100644 (file)
index 0000000..0c5ddae
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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 LAUNCHPAD_PROCESS_POOL_LUX_MANAGER_HH_
+#define LAUNCHPAD_PROCESS_POOL_LUX_MANAGER_HH_
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <memory>
+
+#include <socket.hh>
+#include <io_channel.hh>
+#include <parcel.hh>
+
+#include "launchpad-process-pool/executor.hh"
+
+namespace launchpad {
+
+class LuxManager : public IOChannel::IEvent,
+                   public Executor::Delegator,
+                   public Executor {
+ public:
+  class IEvent {
+   public:
+    virtual ~IEvent() = default;
+    virtual void OnLuxSigchld(pid_t pid, int status) = 0;
+  };
+
+  LuxManager(const LuxManager&) = delete;
+  LuxManager& operator=(const LuxManager&) = delete;
+  LuxManager(LuxManager&&) = delete;
+  LuxManager& operator=(LuxManager&&) = delete;
+
+  static LuxManager& GetInst();
+
+  void Init();
+  void Dispose();
+  bool Prepare();
+  bool IsPrepared() const;
+  pid_t SendAndReceive(const tizen_base::Parcel& parcel);
+  void HandleSigchld(pid_t pid);
+  void SetEventListener(IEvent* listener);
+
+ private:
+  LuxManager();
+  ~LuxManager();
+
+  int CreatePipe(int (*pipe_fd)[2]);
+  void Kill();
+  void HandleServerEvent();
+  void HandleClientEvent(int condition);
+  void OnIOEventReceived(int fd, int condition) override;
+  void OnExecution() override;
+
+ private:
+  bool disposed_ = true;
+  pid_t pid_ = -1;
+  IEvent* listener_ = nullptr;
+  std::unique_ptr<Socket> read_socket_;
+  std::unique_ptr<Socket> write_socket_;
+  std::unique_ptr<Socket> sigchld_socket_;
+  std::unique_ptr<IOChannel> sigchld_channel_;
+};
+
+}  // namespace launchpad
+
+#endif  // LAUNCHPAD_PROCESS_POOL_LUX_MANAGER_HH_
index d92de1ff24216e945ac27ada5c405b0cf3cfb9bc..7e0b7c9450b0a77b4567df1b078ed8cacfa42d4d 100644 (file)
@@ -46,13 +46,10 @@ MemoryMonitor::MemoryMonitor()
   interval_ = base_interval_;
 }
 
-MemoryMonitor::~MemoryMonitor() {
-  Dispose();
-}
+MemoryMonitor::~MemoryMonitor() { Dispose(); }
 
 void MemoryMonitor::Dispose() {
-  if (disposed_)
-    return;
+  if (disposed_) return;
 
   Stop();
   disposed_ = true;
@@ -71,17 +68,14 @@ bool MemoryMonitor::IsLowMemory() {
     _E("Exception occurs. error(%s)", e.what());
   }
 
-  if (threshold_ == 100)
-    return false;
+  if (threshold_ == 100) return false;
 
   uint32_t usage = 0;
   Procfs::GetMemoryUsage(&usage);
-  _D("Previous used ratio: %u, current used ratio: %u",
-      previous_usage_, usage);
+  _D("Previous used ratio: %u, current used ratio: %u", previous_usage_, usage);
   previous_usage_ = usage;
 
-  if (usage > threshold_)
-    return true;
+  if (usage > threshold_) return true;
 
   return false;
 }
@@ -95,11 +89,9 @@ void MemoryMonitor::Reset() {
 }
 
 void MemoryMonitor::Start() {
-  if (threshold_ == 100)
-    return;
+  if (threshold_ == 100) return;
 
-  if (timer_ != 0)
-    return;
+  if (timer_ != 0) return;
 
   timer_ = g_timeout_add(interval_, TimeoutCb, this);
   interval_ += interval_ * INTERVAL_BASE_RATE;
@@ -113,8 +105,7 @@ void MemoryMonitor::Stop() {
 }
 
 void MemoryMonitor::Init() {
-  if (!disposed_)
-    return;
+  if (!disposed_) return;
 
   Start();
   disposed_ = false;
index d44905fe415140902e6ec6b74d1ef325729ed790..869da091d48b108ff7f6b095252150a4e65b711e 100644 (file)
@@ -31,13 +31,13 @@ class MemoryMonitor : public Vconf::IEvent {
    public:
     virtual ~IEvent() = default;
     virtual void OnMemoryStatusChanged(bool low_memory,
-        bool should_check_pss) = 0;
+                                       bool should_check_pss) = 0;
   };
 
   MemoryMonitor(const MemoryMonitor&) = delete;
-  MemoryMonitor& operator = (const MemoryMonitor&) = delete;
+  MemoryMonitor& operator=(const MemoryMonitor&) = delete;
   MemoryMonitor(MemoryMonitor&&) = delete;
-  MemoryMonitor& operator = (MemoryMonitor&&) = delete;
+  MemoryMonitor& operator=(MemoryMonitor&&) = delete;
 
   static MemoryMonitor& GetInst();
 
diff --git a/src/launchpad-process-pool/process_pool.cc b/src/launchpad-process-pool/process_pool.cc
new file mode 100644 (file)
index 0000000..bbacd46
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * 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-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 <aul_keys.hh>
+#include <ini_parser.hh>
+#include <peer_credentials.hh>
+#include <socket.hh>
+#include <types.hh>
+#include <util.hh>
+
+#include "launchpad-process-pool/log_private.hh"
+#include "launchpad-process-pool/lux_manager.hh"
+
+namespace fs = std::filesystem;
+
+namespace {
+
+constexpr const char kProcessPoolSock[] = ".process-pool-sock";
+
+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;
+}
+
+}  // namespace
+
+namespace launchpad {
+
+ProcessPool::ProcessPool(std::string name, int num_processes)
+    : name_(std::move(name)), num_processes_(num_processes) {
+  Listen();
+  PrepareProcess();
+}
+
+ProcessPool::~ProcessPool() { Dispose(); }
+
+bool ProcessPool::IsPrepared() const {
+  if (queue_.empty()) return false;
+
+  auto process = queue_.front();
+  return process->GetFd() > -1;
+}
+
+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) : pid_(pid) {}
+
+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 =
+      client_socket_->Send(static_cast<void*>(&data_size), sizeof(data_size));
+  if (ret != 0) {
+    _E("Write() is failed. error(%d)", ret);
+    return ret;
+  }
+
+  return client_socket_->Send(parcel.GetData(), parcel.GetDataSize());
+}
+
+void ProcessPool::Process::Kill() {
+  client_channel_.reset();
+  client_socket_.reset();
+  if (kill(pid_, SIGKILL) == -1) {
+    _E("Failed to send kill signal to the process. pid(%d), errno(%d)", pid_,
+       errno);
+  }
+}
+
+void ProcessPool::Process::SetClientSocket(
+    std::unique_ptr<ClientSocket> client_socket) {
+  client_socket_ = std::move(client_socket);
+}
+
+int ProcessPool::Process::GetFd() const {
+  if (!client_socket_) return -1;
+
+  return client_socket_->GetFd();
+}
+
+void ProcessPool::Process::Listen(IOChannel::IEvent* listener) {
+  if (!client_socket_ || client_socket_->GetFd() < 0) return;
+
+  client_channel_.reset(new IOChannel(client_socket_->GetFd(),
+                                      IOChannel::IOCondition::IO_ERR |
+                                          IOChannel::IOCondition::IO_HUP |
+                                          IOChannel::IOCondition::IO_NVAL,
+                                      listener));
+}
+
+void ProcessPool::PrepareProcess() {
+  tizen_base::Bundle envelope;
+  envelope.Add(kAulLuxCmd,
+               std::to_string(static_cast<int>(LuxCmd::ExecuteProcessPool)));
+  envelope.Add(kAulProcessPoolName, name_);
+  tizen_base::Parcel parcel = CreateParcelFromBundle(&envelope);
+
+  int current_process_count = static_cast<int>(queue_.size());
+  for (int i = current_process_count; i < num_processes_; ++i) {
+    pid_t pid = LuxManager::GetInst().SendAndReceive(parcel);
+    if (pid == -1) {
+      _E("Failed to create process pool. error(%d)", pid);
+      return;
+    }
+
+    queue_.push_back(std::make_shared<Process>(pid));
+  }
+}
+
+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;
+  }
+}
+
+void ProcessPool::Listen() {
+  try {
+    std::string endpoint = "/run/aul/daemons/" + std::to_string(getuid()) +
+                           "/" + std::string(kProcessPoolSock) + "-" + name_;
+    if (access(endpoint.c_str(), F_OK) == 0) unlink(endpoint.c_str());
+
+    server_socket_.reset(new ServerSocket());
+    server_socket_->Bind(endpoint);
+    server_socket_->Listen(128);
+
+    server_channel_.reset(new IOChannel(server_socket_->GetFd(),
+                                        IOChannel::IOCondition::IO_IN, this));
+  } catch (const Exception& e) {
+    _E("Exception occurs. error=%s", e.what());
+    THROW(e.GetErrorCode());
+  }
+}
+
+std::shared_ptr<ProcessPool::Process> ProcessPool::Find(pid_t pid) {
+  for (auto& process : queue_) {
+    if (process->GetPid() == pid) return process;
+  }
+
+  return nullptr;
+}
+
+void ProcessPool::HandleClientEvent(int fd, int condition) {
+  for (auto& process : queue_) {
+    if (process->GetFd() == fd) {
+      _E("socket was disconnected. pid=%d, fd=%d", process->GetPid(), fd);
+    }
+  }
+}
+
+void ProcessPool::HandleServerEvent() {
+  try {
+    auto client_socket = server_socket_->Accept();
+    client_socket->SetReceiveBufferSize(Socket::kSocketMaxBufferSize);
+
+    pid_t pid = -1;
+    int ret = client_socket->Receive(static_cast<void*>(&pid), sizeof(pid));
+    if (ret != 0) {
+      _E("Receive() is failed. error=%d", ret);
+      return;
+    }
+
+    auto peer_cred = PeerCredentials::Get(client_socket->GetFd());
+    if (peer_cred->GetPid() != pid) {
+      _E("The peer information does not match. %d : %d", peer_cred->GetPid(),
+         pid);
+      return;
+    }
+
+    auto process = Find(pid);
+    if (process == nullptr) return;
+
+    process->SetClientSocket(std::move(client_socket));
+    process->Listen(this);
+  } catch (const Exception& e) {
+    _E("Exception occurs. error=%s", e.what());
+    return;
+  }
+}
+
+void ProcessPool::OnIOEventReceived(int fd, int condition) {
+  if (server_socket_->GetFd() == fd) {
+    HandleServerEvent();
+  } else {
+    HandleClientEvent(fd, condition);
+  }
+}
+
+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
new file mode 100644 (file)
index 0000000..0653eb4
--- /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 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 <client_socket.hh>
+#include <io_channel.hh>
+#include <parcel.hh>
+#include <server_socket.hh>
+
+namespace launchpad {
+
+class ProcessPool : public IOChannel::IEvent {
+ public:
+  explicit ProcessPool(std::string name, int num_processes);
+  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:
+    explicit Process(pid_t pid);
+
+    pid_t GetPid() const;
+    int Send(const tizen_base::Parcel& parcel);
+    void Kill();
+    void SetClientSocket(std::unique_ptr<ClientSocket> client_socket);
+    int GetFd() const;
+    void Listen(IOChannel::IEvent* listener);
+
+   private:
+    pid_t pid_;
+    std::unique_ptr<ClientSocket> client_socket_;
+    std::unique_ptr<IOChannel> client_channel_;
+  };
+
+  void Listen();
+  std::shared_ptr<Process> Find(pid_t pid);
+  void UnsetTimer();
+  void PrepareProcess();
+  void HandleClientEvent(int fd, int condition);
+  void HandleServerEvent();
+  void OnIOEventReceived(int fd, int condition) override;
+
+  static gboolean OnTimeout(gpointer user_data);
+
+ private:
+  std::string name_;
+  int num_processes_;
+  guint timer_ = 0;
+  std::vector<std::shared_ptr<Process>> queue_;
+  std::unique_ptr<ServerSocket> server_socket_;
+  std::unique_ptr<IOChannel> server_channel_;
+};
+
+}  // namespace launchpad
+
+#endif  // LAUNCHPAD_PROCESS_POOL_PROCESS_POOL_HH_
index 4dc6049aa2b9f953329cc596c2d582566f16c0ae..4dfe77b0c3bfa18a2e80d6470f285b9577225f9b 100644 (file)
@@ -29,7 +29,9 @@ namespace launchpad {
 Request::Request(std::unique_ptr<ClientSocket> client_socket)
     : client_socket_(std::move(client_socket)),
       peer_cred_(PeerCredentials::Get(client_socket_->GetFd())) {
-  char header[sizeof(int) + sizeof(int) + sizeof(int)] = { 0, };
+  char header[sizeof(int) + sizeof(int) + sizeof(int)] = {
+      0,
+  };
   int ret = client_socket_->Receive(header, sizeof(header));
   if (ret != 0) {
     _E("Failed to receive the packet header. error(%d)", ret);
@@ -51,53 +53,32 @@ Request::Request(std::unique_ptr<ClientSocket> client_socket)
   b_ = tizen_base::Bundle(raw);
 }
 
-ClientSocket* Request::GetClientSocket() const {
-  return client_socket_.get();
-}
+ClientSocket* Request::GetClientSocket() const { return client_socket_.get(); }
 
-const tizen_base::Bundle& Request::GetBundle() const {
-  return b_;
-}
+const tizen_base::Bundle& Request::GetBundle() const { return b_; }
 
 void Request::SetAppInfo(std::unique_ptr<AppInfo> app_info) {
   app_info_ = std::move(app_info);
 }
 
-const AppInfo* Request::GetAppInfo() const {
-  return app_info_.get();
-}
+const AppInfo* Request::GetAppInfo() const { return app_info_.get(); }
 
-int Request::GetCmd() const {
-  return cmd_;
-}
+int Request::GetCmd() const { return cmd_; }
 
-pid_t Request::GetCallerPid() const {
-  return peer_cred_->GetPid();
-}
+pid_t Request::GetCallerPid() const { return peer_cred_->GetPid(); }
 
-uid_t Request::GetCallerUid() const {
-  return peer_cred_->GetUid();
-}
+uid_t Request::GetCallerUid() const { return peer_cred_->GetUid(); }
 
-void Request::SetLoaderId(int loader_id) {
-  loader_id_ = loader_id;
-}
+void Request::SetLoaderId(int loader_id) { loader_id_ = loader_id; }
 
-int Request::GetLoaderId() const {
-  return loader_id_;
-}
+int Request::GetLoaderId() const { return loader_id_; }
 
-void Request::SetPid(int pid) {
-  pid_ = pid;
-}
+void Request::SetPid(int pid) { pid_ = pid; }
 
-pid_t Request::GetPid() const {
-  return pid_;
-}
+pid_t Request::GetPid() const { return pid_; }
 
 void Request::SendResult(int result) {
-  if (client_socket_->IsClosed())
-    return;
+  if (client_socket_->IsClosed()) return;
 
   client_socket_->Send(static_cast<void*>(&result), sizeof(result));
   client_socket_->Close();
index 98305c13d89b1c7f6f3412308189ab1a12b287c7..6ef1a6c383e78242034d07523ea0704a19bec6b9 100644 (file)
@@ -27,15 +27,14 @@ namespace launchpad {
 Sequencer::Sequencer(Sequencer::IEvent* listener) : listener_(listener) {}
 
 Sequencer::~Sequencer() {
-  if (source_ > 0)
-    g_source_remove(source_);
+  if (source_ > 0) g_source_remove(source_);
 
-  if (timer_ > 0)
-    g_source_remove(timer_);
+  if (timer_ > 0) g_source_remove(timer_);
 }
 
 void Sequencer::Add(std::shared_ptr<LoaderContext> context) {
-  auto found = std::find_if(queue_.begin(), queue_.end(),
+  auto found = std::find_if(
+      queue_.begin(), queue_.end(),
       [&](const std::shared_ptr<LoaderContext>& loader_context) -> bool {
         return loader_context == context;
       });
@@ -57,13 +56,11 @@ void Sequencer::Remove(const std::shared_ptr<LoaderContext>& context) {
 }
 
 void Sequencer::Run() {
-  if (timer_)
-    return;
+  if (timer_) return;
 
   guint interval = Config::GetInst().GetCPUChecker().IsEnabled() ? 500 : 100;
   timer_ = g_timeout_add(interval, RunCb, this);
-  if (timer_ == 0)
-    _E("Failed to add sequencer timer");
+  if (timer_ == 0) _E("Failed to add sequencer timer");
 }
 
 void Sequencer::Stop() {
@@ -74,20 +71,19 @@ void Sequencer::Stop() {
 }
 
 bool Sequencer::Exist(const std::shared_ptr<LoaderContext>& context) {
-  auto found = std::find_if(queue_.begin(), queue_.end(),
+  auto found = std::find_if(
+      queue_.begin(), queue_.end(),
       [&](const std::shared_ptr<LoaderContext>& loader_context) -> bool {
         return loader_context == context;
       });
-  if (found != queue_.end())
-    return true;
+  if (found != queue_.end()) return true;
 
   return false;
 }
 
 gboolean Sequencer::RunCb(gpointer user_data) {
   auto* sequencer = static_cast<Sequencer*>(user_data);
-  if (sequencer->source_ > 0)
-      return G_SOURCE_CONTINUE;
+  if (sequencer->source_ > 0) return G_SOURCE_CONTINUE;
 
   if (sequencer->queue_.empty()) {
     sequencer->timer_ = 0;
@@ -99,8 +95,8 @@ gboolean Sequencer::RunCb(gpointer user_data) {
 
   context->UnsetTimer();
   if (context->GetPid() > 0) {
-    _W("The slot(%d) is already running. pid(%d)",
-        context->GetType(), context->GetPid());
+    _W("The slot(%d) is already running. pid(%d)", context->GetType(),
+       context->GetPid());
     return G_SOURCE_CONTINUE;
   }
 
index ac496b8e838e5ea4662b98634a511f5f8499f53d..6ff3f3697f83f85130f1301ab55874ebe621e1c4 100644 (file)
@@ -33,8 +33,7 @@ SigchldEvent::SigchldEvent(int sfd, IEvent* listener)
 }
 
 SigchldEvent::~SigchldEvent() {
-  if (getpid() != current_pid_)
-    socket_->RemoveFd();
+  if (getpid() != current_pid_) socket_->RemoveFd();
 }
 
 void SigchldEvent::OnIOEventReceived(int fd, int condition) {
@@ -45,19 +44,16 @@ void SigchldEvent::OnIOEventReceived(int fd, int condition) {
 
   do {
     ret = socket_->Read(&info, sizeof(info));
-    if (ret < 0)
-      break;
+    if (ret < 0) break;
 
     pid_t child_pgid = getpgid(info.ssi_pid);
-    _E("[SIGCHLD] pid(%d), pgid(%d), status(%d)",
-        info.ssi_pid, child_pgid, info.ssi_status);
+    _E("[SIGCHLD] pid(%d), pgid(%d), status(%d)", info.ssi_pid, child_pgid,
+       info.ssi_status);
 
     while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) {
-      if (child_pid == child_pgid)
-        killpg(child_pgid, SIGKILL);
+      if (child_pid == child_pgid) killpg(child_pgid, SIGKILL);
 
-      if (listener_ != nullptr)
-        listener_->OnSigchld(child_pid, status);
+      if (listener_ != nullptr) listener_->OnSigchld(child_pid, status);
     }
   } while (ret == 0);
 }
diff --git a/src/launchpad-process-pool/sigchld_manager.cc b/src/launchpad-process-pool/sigchld_manager.cc
new file mode 100644 (file)
index 0000000..4aa235a
--- /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-process-pool/sigchld_manager.hh"
+
+#include <signal.h>
+#include <sys/signalfd.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "launchpad-process-pool/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/launchpad-process-pool/sigchld_manager.hh b/src/launchpad-process-pool/sigchld_manager.hh
new file mode 100644 (file)
index 0000000..cb00245
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 LAUNCHPAD_PROCESS_POOL_SIGCHLD_MANAGER_HH_
+#define LAUNCHPAD_PROCESS_POOL_SIGCHLD_MANAGER_HH_
+
+namespace launchpad {
+
+class SigchldManager {
+ public:
+  static int BlockSigchld();
+  static void UnblockSigchld();
+  static int GetSigchldFd();
+};
+
+}  // namespace launchpad
+
+#endif  // LAUNCHPAD_PROCESS_POOL_SIGCHLD_MANAGER_HH_
index 4dbe9845a555bebf5a1257fc0e594abf8d1aa373..5140d0ff7ce76cfb7b64eece642ea2c26c567377 100644 (file)
 #include <string>
 #include <vector>
 
-#include <sigchld_manager.hh>
-
 #include "launchpad-process-pool/dbus.hh"
 #include "launchpad-process-pool/log_private.hh"
+#include "launchpad-process-pool/sigchld_manager.hh"
 
 namespace launchpad {
 namespace {
@@ -45,7 +44,7 @@ class GarbageCollector : public launchpad::Worker::Job {
     _D("pid: %d", pid_);
     try {
       std::string path = "/run/aul/apps/" + std::to_string(getuid()) + "/" +
-          std::to_string(pid_);
+                         std::to_string(pid_);
       DeleteSocketPath(fs::path(path));
 
       DeleteUnusedFiles();
@@ -78,13 +77,11 @@ class GarbageCollector : public launchpad::Worker::Job {
 
   void SocketGarbadgeCollector() {
     std::string path = "/run/aul/apps/" + std::to_string(getuid());
-    for (const auto &entry : fs::directory_iterator(path)) {
-      if (!isdigit(entry.path().filename().string()[0]))
-        continue;
+    for (const auto& entry : fs::directory_iterator(path)) {
+      if (!isdigit(entry.path().filename().string()[0])) continue;
 
       std::string proc_path = "/proc/" + entry.path().filename().string();
-      if (!fs::exists(proc_path))
-        DeleteSocketPath(entry.path());
+      if (!fs::exists(proc_path)) DeleteSocketPath(entry.path());
     }
   }
 
@@ -104,16 +101,15 @@ class GarbageCollector : public launchpad::Worker::Job {
   void DeleteTmpFiles() {
     std::vector<std::string> files = {
         "clr-debug-pipe-" + std::to_string(pid_) + "-",
-        "dotnet-diagnostic-" + std::to_string(pid_) + "-"
-    };
+        "dotnet-diagnostic-" + std::to_string(pid_) + "-"};
 
     fs::path tmp_path = "/tmp";
-    for (const auto &entry : fs::directory_iterator(tmp_path)) {
+    for (const autoentry : fs::directory_iterator(tmp_path)) {
       if (entry.is_directory() || entry.path().filename().string()[0] == '.')
         continue;
 
       bool found = false;
-      for (const auto &file : files) {
+      for (const autofile : files) {
         if (entry.path().filename().string().find(file) == 0) {
           fs::remove(entry.path());
           _W("Removed file: %s", entry.path().c_str());
@@ -122,8 +118,7 @@ class GarbageCollector : public launchpad::Worker::Job {
         }
       }
 
-      if (!found)
-        continue;
+      if (!found) continue;
     }
   }
 
@@ -140,15 +135,13 @@ SignalManager& SignalManager::GetInst() {
 }
 
 void SignalManager::Dispose() {
-  if (disposed_)
-    return;
+  if (disposed_) return;
 
   _W("BEGIN");
   RestoreSignalAction(SIGUSR2);
   RestoreSignalAction(SIGUSR1);
 #ifndef PRELOAD_ACTIVATE
-  for (int signo = 0; signo < _NSIG; ++signo)
-    signal(signo, SIG_DFL);
+  for (int signo = 0; signo < _NSIG; ++signo) signal(signo, SIG_DFL);
 #endif  // PRELOAD_ACTIVATE
 
   recycle_bin_.reset();
@@ -160,39 +153,31 @@ void SignalManager::Dispose() {
 }
 
 void SignalManager::Init() {
-  if (!disposed_)
-    return;
+  if (!disposed_) return;
 
   _W("BEGIN");
-  if (SigchldManager::BlockSigchld() != 0)
-    return;
+  if (SigchldManager::BlockSigchld() != 0) return;
 
   int sfd = SigchldManager::GetSigchldFd();
-  if (sfd < 0)
-    return;
+  if (sfd < 0) return;
 
   sigchld_event_.reset(new SigchldEvent(sfd, this));
   hydra_sigchld_event_.reset(new HydraSigchldEvent(this));
   recycle_bin_.reset(new Worker("RecycleBin+"));
 
   for (int signo = 0; signo < _NSIG; ++signo) {
-    if (signo == SIGQUIT ||
-        signo == SIGILL ||
-        signo == SIGABRT ||
-        signo == SIGBUS ||
-        signo == SIGFPE ||
-        signo == SIGSEGV ||
+    if (signo == SIGQUIT || signo == SIGILL || signo == SIGABRT ||
+        signo == SIGBUS || signo == SIGFPE || signo == SIGSEGV ||
         signo == SIGPIPE)
       continue;
 
     signal(signo, SIG_DFL);
   }
 
-  pthread_atfork(nullptr, nullptr,
-      []() {
-        GarbageCollector gc(getpid());
-        gc.DoAtFork();
-      });
+  pthread_atfork(nullptr, nullptr, []() {
+    GarbageCollector gc(getpid());
+    gc.DoAtFork();
+  });
 
   ChangeSignalAction(SIGUSR1);
   ChangeSignalAction(SIGUSR2);
@@ -205,13 +190,10 @@ void SignalManager::SetEventListener(SignalManager::IEvent* listener) {
   listener_ = listener;
 }
 
-SignalManager::~SignalManager() {
-  Dispose();
-}
+SignalManager::~SignalManager() { Dispose(); }
 
 void SignalManager::HandleSigchld(pid_t pid, int status) {
-  if (listener_ != nullptr)
-    listener_->OnSigchldReceived(pid);
+  if (listener_ != nullptr) listener_->OnSigchldReceived(pid);
 
   DBus::SendAppDeadSignal(pid, status);
   recycle_bin_->Add(std::make_shared<GarbageCollector>(pid));
@@ -228,8 +210,12 @@ void SignalManager::OnHydraSigchld(pid_t pid, int status) {
 }
 
 void SignalManager::ChangeSignalAction(int signo) {
-  struct sigaction old_action = { 0, };
-  struct sigaction action = { 0, };
+  struct sigaction old_action = {
+      0,
+  };
+  struct sigaction action = {
+      0,
+  };
   sigemptyset(&action.sa_mask);
   action.sa_sigaction = UnixSignalHandler;
   action.sa_flags = SA_RESTART | SA_SIGINFO;
@@ -268,7 +254,7 @@ void SignalManager::UnixSignalHandler(int signo, siginfo_t* info, void* arg) {
     _W("[UNIX_SIGNAL_HANDLER] pid: %d, uid: %u", info->si_pid, info->si_uid);
     if (info->si_pid > 0) {
       std::ifstream stream("/proc/" + std::to_string(info->si_pid) +
-          "/cmdline");
+                           "/cmdline");
       if (stream.is_open()) {
         std::string cmdline;
         std::getline(stream, cmdline);
index a5733d630b6cb03b909adb1fe2abc97bbb5c6ffb..4d6a4a202746c70986b3996963dc8424ff99890b 100644 (file)
@@ -44,14 +44,15 @@ class SignalManager : public SigchldEvent::IEvent,
   };
 
   SignalManager(const SignalManager&) = delete;
-  SignalManager& operator = (const SignalManager&) = delete;
+  SignalManager& operator=(const SignalManager&) = delete;
   SignalManager(SignalManager&&) = delete;
-  SignalManager& operator = (SignalManager&&) = delete;
+  SignalManager& operator=(SignalManager&&) = delete;
 
   static SignalManager& GetInst();
   void Dispose();
 
   void SetEventListener(IEvent* listener);
+  void HandleSigchld(pid_t pid, int status);
 
  private:
   class SignalAction {
@@ -74,7 +75,6 @@ class SignalManager : public SigchldEvent::IEvent,
   ~SignalManager();
 
   void Init();
-  void HandleSigchld(pid_t pid, int status);
 
   void OnSigchld(pid_t pid, int status) override;
   void OnHydraSigchld(pid_t pid, int status) override;
index dcb4a0f9e2a5743a9fe6e0373d0bc127219114b0..65f685bde04633d2bdc17085ba0998cde1a8514f 100644 (file)
@@ -29,9 +29,7 @@ class Tracer {
     traceBegin(TTRACE_TAG_APPLICATION_MANAGER, message.data());
   }
 
-  ~Tracer() {
-    traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
-  }
+  ~Tracer() { traceEnd(TTRACE_TAG_APPLICATION_MANAGER); }
 };
 
 }  // namespace launchpad
index 1a2e972534c166a590a0e2ea84586a5ac38fe9ca..5ba6887855ef4c49117aa725f3ff99852d1c377a 100644 (file)
@@ -53,7 +53,7 @@ Worker::~Worker() {
   }
 }
 
-void Worker::Add(std::shared_ptr<Worker::Job >job) {
+void Worker::Add(std::shared_ptr<Worker::Jobjob) {
   queue_->Push(std::move(job));
 }
 
@@ -63,8 +63,7 @@ void Worker::RunThread() {
   while (true) {
     auto job = queue_->WaitAndPop();
     job->Do();
-    if (job->IsDone())
-      break;
+    if (job->IsDone()) break;
   }
   _W("END");
 }
index f989536df59bcf0163187f45842212b5b4683a64..d9b736e81d47124b36b74a8c23b874a178f333e1 100644 (file)
@@ -1,5 +1,4 @@
 ADD_SUBDIRECTORY(launchpad)
 ADD_SUBDIRECTORY(launchpad-common)
 ADD_SUBDIRECTORY(launchpad-core)
-ADD_SUBDIRECTORY(launchpad-glib)
 ADD_SUBDIRECTORY(launchpad-hydra)
index 5606e9462710f4347f732213943e48decbb72ff3..7898e65ba17a887b98fecb3fad6b49f4fd4f64e1 100644 (file)
@@ -56,6 +56,12 @@ constexpr const char kAulWaylandWorkingDir[] = "__AUL_WAYLAND_WORKING_DIR__";
 constexpr const char kAulMountGadgetPaths[] = "__AUL_MOUNT_GADGET_PATHS__";
 constexpr const char kAulMountGadgetPkgIds[] = "__AUL_MOUNT_GADGET_PKGIDS__";
 constexpr const char kAulMountLibDir[] = "__AUL_MOUNT_LIB_DIR__";
+constexpr const char kAulLuxCmd[] = "__AUL_LUX_CMD__";
+constexpr const char kAulProcessPoolName[] = "__AUL_PROCESS_POOL_NAME__";
+constexpr const char kAulAppArgs[] = "__AUL_APP_ARGS__";
+constexpr const char kAulDebugExtraEnvList[] = "__AUL_DEBUG_EXTRA_ENV_LIST__";
+constexpr const char kAulTizenAsanActivation[] =
+    "__AUL_TIZEN_ASAN_ACTIVATION__";
 
 }  // namespace launchpad
 
index c65e1cc826899da0d10b04766ec1427824490570..d86a142934a43b71ca10f1540c03da6e8fd3267c 100644 (file)
@@ -83,6 +83,12 @@ enum class AmdSocketOption : int {
   Bundle = 0x8
 };
 
+enum class LuxCmd : int {
+  ExecuteProcessPool,
+  ExecuteApp,
+  ExecuteLoader,
+};
+
 }  // namespace launchpad
 
 #endif  // LIB_LAUNCHPAD_COMMON_TYPES_HH_
index ab68b558ed9abe751ddc315db44b10be45a9d7ca..98ad95c7bb6dc47ae5a5d27b912477b4a005f843 100644 (file)
@@ -16,6 +16,7 @@ APPLY_PKG_CONFIG(${TARGET_LAUNCHPAD_CORE} PUBLIC
   BUNDLE_DEPS
   DBUS_DEPS
   DLOG_DEPS
+  DLOG_REDIRECT_STDOUT_DEPS
   GIO_DEPS
   LIBTZPLATFORM_CONFIG_DEPS
   SECURITY_MANAGER_DEPS
@@ -24,7 +25,7 @@ APPLY_PKG_CONFIG(${TARGET_LAUNCHPAD_CORE} PUBLIC
 )
 
 TARGET_LINK_LIBRARIES(${TARGET_LAUNCHPAD_CORE} PUBLIC
-${TARGET_LAUNCHPAD_COMMON} ${TARGET_LAUNCHPAD_GLIB} "-ldl")
+${TARGET_LAUNCHPAD_COMMON} "-ldl -lpthread")
 
 INSTALL(TARGETS ${TARGET_LAUNCHPAD_CORE} DESTINATION ${LIB_INSTALL_DIR}
   COMPONENT RuntimeLibraries)
@@ -32,9 +33,16 @@ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
   DESTINATION include/launchpad-core
   FILES_MATCHING
   PATTERN "*_private.hh" EXCLUDE
+  PATTERN "*_internal.hh" EXCLUDE
   PATTERN "*.hh"
 )
 
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include
+  DESTINATION include/launchpad-core
+  FILES_MATCHING
+  PATTERN "*.h"
+)
+
 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
diff --git a/src/lib/launchpad-core/app_executor.cc b/src/lib/launchpad-core/app_executor.cc
deleted file mode 100644 (file)
index 55be4ed..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 5b0f63f..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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/app_executor_internal.cc b/src/lib/launchpad-core/app_executor_internal.cc
new file mode 100644 (file)
index 0000000..bbaa32d
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * 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/app_executor_internal.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 <security-manager.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_internal.hh"
+#include "launchpad-core/log_private.hh"
+
+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
+
+namespace launchpad {
+namespace internal {
+namespace fs = std::filesystem;
+
+AppExecutor::AppExecutor() {
+  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));
+}
+
+void AppExecutor::Execute(tizen_base::Bundle request) {
+  app_info_ = std::unique_ptr<AppInfo>(AppInfo::Create(std::move(request)));
+  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);
+  }
+
+  auto& b = app_info_->GetBundle();
+  std::vector<std::string> argv = b.GetStringArray(kAulAppArgs);
+  std::vector<char*> app_argv(argv.size());
+  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]);
+  }
+  app_argv.push_back(nullptr);
+
+  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.data()) < 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);
+  }
+}
+
+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_.get());
+}
+
+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_.get());
+}
+
+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_.get());
+  return 0;
+}
+
+int AppExecutor::StepWaitTepMount() {
+  return Util::WaitTepMount(app_info_.get());
+}
+
+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_.get());
+}
+
+int AppExecutor::StepSendStartupSignal() {
+  Util::SendCmdToAmd(AmdCmd::AppStartupSignal);
+  return 0;
+}
+
+void AppExecutor::CheckAndPrepareDebugging() {
+  auto& b = app_info_->GetBundle();
+  if (b.GetType(kAulSdk) != BUNDLE_TYPE_NONE)
+     Debug::Prepare(b);
+
+  Debug::CheckWebAppDebugging(b);
+}
+
+}  // namespace internal
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/app_executor_internal.hh b/src/lib/launchpad-core/app_executor_internal.hh
new file mode 100644 (file)
index 0000000..24aceac
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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_APP_EXECUTOR_INTERNAL_HH_
+#define LIB_LAUNCHPAD_CORE_APP_EXECUTOR_INTERNAL_HH_
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include <app_info.hh>
+#include <bundle_cpp.h>
+
+namespace launchpad {
+namespace internal {
+
+class AppExecutor {
+ public:
+  AppExecutor();
+
+  void Execute(tizen_base::Bundle request);
+
+ private:
+  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();
+
+ private:
+  using PrepareFunc = std::function<int()>;
+
+  std::vector<PrepareFunc> prepare_funcs_;
+  std::unique_ptr<AppInfo> app_info_;
+};
+
+}  // namespace internal
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_APP_EXECUTOR_INTERNAL_HH_
diff --git a/src/lib/launchpad-core/app_info.cc b/src/lib/launchpad-core/app_info.cc
new file mode 100644 (file)
index 0000000..082f41a
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * 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-core/app_info.hh"
+
+#include <bundle_internal.h>
+
+#include <utility>
+
+#include <aul_keys.hh>
+
+namespace launchpad {
+
+AppInfo::Builder& AppInfo::Builder::SetAppId(const tizen_base::Bundle& b) {
+  app_id_ = b.GetString(kAulAppId);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetAppPath(const tizen_base::Bundle& b) {
+  app_path_ = b.GetString(kAulExec);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetOriginalAppPath(
+    const tizen_base::Bundle& b) {
+  original_app_path_ = b.GetString(kAulExec);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetPkgType(const tizen_base::Bundle& b) {
+  pkg_type_ = b.GetString(kAulPackageType);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetAppType(const tizen_base::Bundle& b) {
+  app_type_ = b.GetString(kAulAppType);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetHwacc(const tizen_base::Bundle& b) {
+  hwacc_ = b.GetString(kAulHwAcc);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetTaskmanage(const tizen_base::Bundle& b) {
+  taskmanage_ = b.GetString(kAulTaskManage);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetPkgId(const tizen_base::Bundle& b) {
+  pkg_id_ = b.GetString(kAulPkgId);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetCompType(const tizen_base::Bundle& b) {
+  comp_type_ = b.GetString(kAulCompType);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetInternalPool(
+    const tizen_base::Bundle& b) {
+  internal_pool_ = b.GetString(kAulInternalPool);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetRootPath(const tizen_base::Bundle& b) {
+  root_path_ = b.GetString(kAulRootPath);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetLoaderName(const tizen_base::Bundle& b) {
+  loader_name_ = b.GetString(kAulLoaderName);
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetFastLaunch(const tizen_base::Bundle& b) {
+  if (b.GetString(kAulFastLaunch) == "true")
+    fast_launch_ = true;
+  else
+    fast_launch_ = false;
+
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetGlobal(const tizen_base::Bundle& b) {
+  if (b.GetString(kAulIsGlobal) == "true")
+    global_ = true;
+  else
+    global_ = false;
+
+  return *this;
+}
+
+AppInfo::Builder& AppInfo::Builder::SetBundle(tizen_base::Bundle b) {
+  b_ = std::move(b);
+  return *this;
+}
+
+AppInfo::Builder::operator AppInfo*() {
+  return new (std::nothrow) AppInfo(std::move(app_id_), std::move(app_path_),
+      std::move(original_app_path_), std::move(pkg_type_), std::move(app_type_),
+      std::move(hwacc_), std::move(taskmanage_), std::move(pkg_id_),
+      std::move(comp_type_), std::move(internal_pool_), std::move(root_path_),
+      std::move(loader_name_), fast_launch_, global_, std::move(b_));
+}
+
+AppInfo* AppInfo::Create(tizen_base::Bundle b) {
+  return Builder().SetAppId(b)
+      .SetAppPath(b)
+      .SetOriginalAppPath(b)
+      .SetPkgType(b)
+      .SetAppType(b)
+      .SetHwacc(b)
+      .SetTaskmanage(b)
+      .SetPkgId(b)
+      .SetCompType(b)
+      .SetInternalPool(b)
+      .SetRootPath(b)
+      .SetLoaderName(b)
+      .SetFastLaunch(b)
+      .SetGlobal(b)
+      .SetBundle(std::move(b));
+}
+
+const std::string& AppInfo::GetAppId() const {
+  return app_id_;
+}
+
+const std::string& AppInfo::GetAppPath() const {
+  return app_path_;
+}
+
+const std::string& AppInfo::GetOriginalAppPath() const {
+  return original_app_path_;
+}
+
+const std::string& AppInfo::GetPkgType() const {
+  return pkg_type_;
+}
+
+const std::string& AppInfo::GetAppType() const {
+  return app_type_;
+}
+
+const std::string& AppInfo::GetHwacc() const {
+  return hwacc_;
+}
+
+const std::string& AppInfo::GetTaskmanage() const {
+  return taskmanage_;
+}
+
+const std::string& AppInfo::GetPkgId() const {
+  return pkg_id_;
+}
+
+const std::string& AppInfo::GetCompType() const {
+  return comp_type_;
+}
+
+const std::string& AppInfo::GetInternalPool() const {
+  return internal_pool_;
+}
+
+const std::string& AppInfo::GetRootPath() const {
+  return root_path_;
+}
+
+const std::string& AppInfo::GetLoaderName() const {
+  return loader_name_;
+}
+
+const bool AppInfo::IsFastLaunch() const {
+  return fast_launch_;
+}
+
+const bool AppInfo::IsGlobal() const {
+  return global_;
+}
+
+const tizen_base::Bundle& AppInfo::GetBundle() const {
+  return b_;
+}
+
+void AppInfo::WriteToParcel(tizen_base::Parcel* parcel) const {
+  parcel->WriteString(app_id_);
+  parcel->WriteString(app_path_);
+  parcel->WriteString(original_app_path_);
+  parcel->WriteString(pkg_type_);
+  parcel->WriteString(app_type_);
+  parcel->WriteString(hwacc_);
+  parcel->WriteString(taskmanage_);
+  parcel->WriteString(pkg_id_);
+  parcel->WriteString(comp_type_);
+  parcel->WriteString(internal_pool_);
+  parcel->WriteString(root_path_);
+  parcel->WriteString(loader_name_);
+  parcel->WriteBool(fast_launch_);
+  parcel->WriteBool(global_);
+
+  bundle_raw* b_raw = nullptr;
+  int len = 0;
+  bundle_encode(b_.GetHandle(), &b_raw, &len);
+  std::string raw(b_raw != nullptr ? reinterpret_cast<const char*>(b_raw) : "");
+  bundle_free_encoded_rawdata(&b_raw);
+  parcel->WriteString(raw);
+}
+
+void AppInfo::ReadFromParcel(tizen_base::Parcel* parcel) {
+  app_id_ = parcel->ReadString();
+  app_path_ = parcel->ReadString();
+  original_app_path_ = parcel->ReadString();
+  pkg_type_ = parcel->ReadString();
+  app_type_ = parcel->ReadString();
+  hwacc_ = parcel->ReadString();
+  taskmanage_ = parcel->ReadString();
+  pkg_id_ = parcel->ReadString();
+  comp_type_ = parcel->ReadString();
+  internal_pool_ = parcel->ReadString();
+  root_path_ = parcel->ReadString();
+  loader_name_ = parcel->ReadString();
+  parcel->ReadBool(&fast_launch_);
+  parcel->ReadBool(&global_);
+
+  auto raw = parcel->ReadString();
+  if (!raw.empty())
+    b_ = tizen_base::Bundle(raw);
+}
+
+AppInfo::AppInfo(std::string app_id, std::string app_path,
+    std::string original_app_path, std::string pkg_type, std::string app_type,
+    std::string hwacc, std::string taskmanage, std::string pkg_id,
+    std::string comp_type, std::string internal_pool, std::string root_path,
+    std::string loader_name, bool fast_launch, bool global,
+    tizen_base::Bundle b)
+    : app_id_(std::move(app_id)),
+      app_path_(std::move(app_path)),
+      original_app_path_(std::move(original_app_path)),
+      pkg_type_(std::move(pkg_type)),
+      app_type_(std::move(app_type)),
+      hwacc_(std::move(hwacc)),
+      taskmanage_(std::move(taskmanage)),
+      pkg_id_(std::move(pkg_id)),
+      comp_type_(std::move(comp_type)),
+      internal_pool_(std::move(internal_pool)),
+      root_path_(std::move(root_path)),
+      loader_name_(std::move(loader_name)),
+      fast_launch_(fast_launch),
+      global_(global),
+      b_(std::move(b)) {}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/app_info.hh b/src/lib/launchpad-core/app_info.hh
new file mode 100644 (file)
index 0000000..3f57d97
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * 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 LIB_LAUNCHPAD_CORE_APP_INFO_HH_
+#define LIB_LAUNCHPAD_CORE_APP_INFO_HH_
+
+#include <bundle_cpp.h>
+
+#include <memory>
+#include <string>
+
+#include <parcel.hh>
+#include <parcelable.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API AppInfo : public tizen_base::Parcelable {
+ public:
+  class Builder {
+   public:
+    Builder& SetAppId(const tizen_base::Bundle& b);
+    Builder& SetAppPath(const tizen_base::Bundle& b);
+    Builder& SetOriginalAppPath(const tizen_base::Bundle& b);
+    Builder& SetPkgType(const tizen_base::Bundle& b);
+    Builder& SetAppType(const tizen_base::Bundle& b);
+    Builder& SetHwacc(const tizen_base::Bundle& b);
+    Builder& SetTaskmanage(const tizen_base::Bundle& b);
+    Builder& SetPkgId(const tizen_base::Bundle& b);
+    Builder& SetCompType(const tizen_base::Bundle& b);
+    Builder& SetInternalPool(const tizen_base::Bundle& b);
+    Builder& SetRootPath(const tizen_base::Bundle& b);
+    Builder& SetLoaderName(const tizen_base::Bundle& b);
+    Builder& SetFastLaunch(const tizen_base::Bundle& b);
+    Builder& SetGlobal(const tizen_base::Bundle& b);
+    Builder& SetBundle(tizen_base::Bundle b);
+    operator AppInfo*();
+
+   private:
+    std::string app_id_;
+    std::string app_path_;
+    std::string original_app_path_;
+    std::string pkg_type_;
+    std::string app_type_;
+    std::string hwacc_;
+    std::string taskmanage_;
+    std::string pkg_id_;
+    std::string comp_type_;
+    std::string internal_pool_;
+    std::string root_path_;
+    std::string loader_name_;
+    bool fast_launch_ = false;
+    bool global_ = true;
+    tizen_base::Bundle b_;
+  };
+
+  AppInfo() = default;
+  virtual ~AppInfo() = default;
+
+  static AppInfo* Create(tizen_base::Bundle b);
+
+  const std::string& GetAppId() const;
+  const std::string& GetAppPath() const;
+  const std::string& GetOriginalAppPath() const;
+  const std::string& GetPkgType() const;
+  const std::string& GetAppType() const;
+  const std::string& GetHwacc() const;
+  const std::string& GetTaskmanage() const;
+  const std::string& GetPkgId() const;
+  const std::string& GetCompType() const;
+  const std::string& GetInternalPool() const;
+  const std::string& GetRootPath() const;
+  const std::string& GetLoaderName() const;
+  const bool IsFastLaunch() const;
+  const bool IsGlobal() const;
+  const tizen_base::Bundle& GetBundle() const;
+
+  void WriteToParcel(tizen_base::Parcel* parcel) const override;
+  void ReadFromParcel(tizen_base::Parcel* parcel) override;
+
+ private:
+  AppInfo(std::string app_id, std::string app_path,
+      std::string original_app_path, std::string pkg_type, std::string app_type,
+      std::string hwacc, std::string taskmanage, std::string pkg_id,
+      std::string comp_type, std::string internal_pool, std::string root_path,
+      std::string loader_name, bool fast_launch, bool global,
+      tizen_base::Bundle b);
+
+ private:
+  std::string app_id_;
+  std::string app_path_;
+  std::string original_app_path_;
+  std::string pkg_type_;
+  std::string app_type_;
+  std::string hwacc_;
+  std::string taskmanage_;
+  std::string pkg_id_;
+  std::string comp_type_;
+  std::string internal_pool_;
+  std::string root_path_;
+  std::string loader_name_;
+  bool fast_launch_ = false;
+  bool global_ = true;
+  tizen_base::Bundle b_;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_APP_INFO_HH_
diff --git a/src/lib/launchpad-core/debug.cc b/src/lib/launchpad-core/debug.cc
deleted file mode 100644 (file)
index 741f416..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index ba9083c..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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/debug_internal.cc b/src/lib/launchpad-core/debug_internal.cc
new file mode 100644 (file)
index 0000000..c863ab9
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * 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/debug_internal.hh"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+#include <aul_keys.hh>
+
+#include "launchpad-core/log_private.hh"
+
+namespace {
+
+constexpr const char kTizenAsanActivation[] = "TIZEN_ASAN_ACTIVATION";
+constexpr const char kDlpAttachArg[] = "__DLP_ATTACH_ARG__";
+
+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;
+}
+
+pid_t GetCallerPid(const tizen_base::Bundle& b) {
+  auto pid_str = b.GetString(launchpad::kAulOrgCallerPid);
+  if (pid_str.empty()) pid_str = b.GetString(launchpad::kAulCallerPid);
+
+  if (pid_str.empty()) return -1;
+
+  return std::stoi(pid_str);
+}
+
+void 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);
+}
+
+void ParseAndSetEnvironment(const tizen_base::Bundle& b,
+                            const std::string& key) {
+  _D("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("value: %s", env.c_str());
+  setenv(key.c_str(), env.c_str(), 1);
+}
+
+void ParseAndSetTargetPid(const tizen_base::Bundle& b) {
+  std::vector<std::string> values = GetStringArray(b, kDlpAttachArg);
+  if (values.empty()) return;
+
+  for (const auto& arg : values) {
+    if (isdigit(arg[0])) {
+      _D("TARGET_PID=%s", arg.c_str());
+      setenv("TARGET_PID", arg.c_str(), 1);
+    }
+  }
+}
+
+}  // namespace
+
+namespace launchpad {
+namespace internal {
+
+void Debug::Prepare(const tizen_base::Bundle& request) {
+  auto debugger = request.GetString(kAulSdk);
+  if (debugger.empty()) return;
+
+  if (debugger == "ASAN" ||
+      request.GetString(kAulTizenAsanActivation) == "true")
+    setenv(kTizenAsanActivation, "1", 1);
+
+  ParseAndRedirectStandardFds(request);
+
+  for (const auto& extra_env : request.GetStringArray(kAulDebugExtraEnvList))
+    ParseAndSetEnvironment(request, extra_env);
+
+  ParseAndSetTargetPid(request);
+}
+
+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& request) {
+  if (request.GetType(kAulDebug) != BUNDLE_TYPE_NONE)
+    setenv("TIZEN_DEBUGGING_PORT", "1", 1);
+}
+
+}  // namespace internal
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/debug_internal.hh b/src/lib/launchpad-core/debug_internal.hh
new file mode 100644 (file)
index 0000000..ecf6089
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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_DEBUG_INTERNAL_HH_
+#define LIB_LAUNCHPAD_CORE_DEBUG_INTERNAL_HH_
+
+#include <bundle_cpp.h>
+
+namespace launchpad {
+namespace internal {
+
+class Debug {
+ public:
+  static void Prepare(const tizen_base::Bundle& request);
+  static void ChangeMountNamespace();
+  static void CheckWebAppDebugging(const tizen_base::Bundle& request);
+};
+
+}  // namespace internal
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_DEBUG_INTERNAL_HH_
diff --git a/src/lib/launchpad-core/debugger_info.cc b/src/lib/launchpad-core/debugger_info.cc
deleted file mode 100644 (file)
index 4c06962..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 5e30ff5..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 359ce82..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 8b314ca..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 2b212ee..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 66d59d9..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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/hw_acceleration_config.cc b/src/lib/launchpad-core/hw_acceleration_config.cc
new file mode 100644 (file)
index 0000000..82663c6
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * 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-core/hw_acceleration_config.hh"
+
+#include "launchpad-core/log_private.hh"
+
+namespace launchpad {
+
+HWAccelerationConfig::HWAccelerationConfig()
+    : vconf_(Vconf(VCONFKEY_SETAPPL_APP_HW_ACCELERATION)) {
+  vconf_.Listen(this);
+
+  try {
+    hwacc_ = vconf_.Get<int>();
+  } catch (const Exception& e) {
+    _E("Exception occurs. error: %s", e.what());
+    hwacc_ = -1;
+  }
+}
+
+int HWAccelerationConfig::Get() const {
+  return hwacc_;
+}
+
+void HWAccelerationConfig::OnKeyChanged(const Vconf::KeyNode& node) {
+  hwacc_ = node.Get<int>();
+  _W("Hwacc: %d", hwacc_);
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/hw_acceleration_config.hh b/src/lib/launchpad-core/hw_acceleration_config.hh
new file mode 100644 (file)
index 0000000..8c59c0b
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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 LIB_LAUNCHPAD_CORE_HW_ACCELERATION_CONFIG_HH_
+#define LIB_LAUNCHPAD_CORE_HW_ACCELERATION_CONFIG_HH_
+
+#include <vconf.hh>
+
+namespace launchpad {
+
+class HWAccelerationConfig : public Vconf::IEvent {
+ public:
+  HWAccelerationConfig();
+
+  int Get() const;
+
+ private:
+  void OnKeyChanged(const Vconf::KeyNode& node) override;
+
+ private:
+  Vconf vconf_;
+  int hwacc_;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_HW_ACCELERATION_CONFIG_HH_
diff --git a/src/lib/launchpad-core/include/launchpad_core.h b/src/lib/launchpad-core/include/launchpad_core.h
new file mode 100644 (file)
index 0000000..ada4060
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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 __LAUNCHPAD_CORE_H__
+#define __LAUNCHPAD_CORE_H__
+
+#include <bundle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void launchpad_core_execute_app(bundle *request);
+
+void launchpad_core_execute_process_pool(bundle *request);
+
+void launchpad_core_execute_loader(bundle *request);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LAUNCHPAD_CORE_H__ */
diff --git a/src/lib/launchpad-core/io_channel.cc b/src/lib/launchpad-core/io_channel.cc
new file mode 100644 (file)
index 0000000..b4d5993
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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-core/io_channel.hh"
+
+#include <errno.h>
+
+#include <memory>
+
+#include "launchpad-core/log_private.hh"
+
+namespace launchpad {
+
+IOChannel::IOChannel(int fd, int condition, IOChannel::IEvent* listener)
+    : fd_(fd), listener_(listener) {
+  source_id_ = g_unix_fd_add(fd, static_cast<GIOCondition>(condition),
+      UnixFdFunc, this);
+  if (source_id_ == 0) {
+    _E("g_unix_fd_add() is failed");
+    THROW(-ENOMEM);
+  }
+}
+
+IOChannel::~IOChannel() {
+  if (source_id_ != 0)
+    g_source_remove(source_id_);
+}
+
+gboolean IOChannel::UnixFdFunc(gint fd, GIOCondition condition,
+    gpointer user_data) {
+  auto* io_channel = static_cast<IOChannel*>(user_data);
+  if (io_channel->fd_ != fd) {
+    _E("fd(%d) is not equal to fd(%d) of io channel", fd, io_channel->fd_);
+    return G_SOURCE_REMOVE;
+  }
+
+  auto* listener = io_channel->listener_;
+  if (listener != nullptr)
+    listener->OnIOEventReceived(io_channel->fd_, static_cast<int>(condition));
+
+  return G_SOURCE_CONTINUE;
+}
+
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/io_channel.hh b/src/lib/launchpad-core/io_channel.hh
new file mode 100644 (file)
index 0000000..2d517fd
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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 LIB_LAUNCHPAD_CORE_IO_CHANNEL_HH_
+#define LIB_LAUNCHPAD_CORE_IO_CHANNEL_HH_
+
+#include <glib-unix.h>
+
+#include <exception.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API IOChannel {
+ public:
+  enum IOCondition {
+    IO_IN = G_IO_IN,
+    IO_OUT = G_IO_OUT,
+    IO_PRI = G_IO_PRI,
+    IO_ERR = G_IO_ERR,
+    IO_HUP = G_IO_HUP,
+    IO_NVAL = G_IO_NVAL,
+  };
+
+  class IEvent {
+   public:
+    virtual ~IEvent() = default;
+    virtual void OnIOEventReceived(int fd, int condition) = 0;
+  };
+
+  IOChannel(int fd, int condtion, IEvent* listener);
+  virtual ~IOChannel();
+
+  IOChannel(const IOChannel&) = delete;
+  IOChannel& operator = (const IOChannel&) = delete;
+
+ private:
+  static gboolean UnixFdFunc(gint fd, GIOCondition condition,
+      gpointer user_data);
+
+ private:
+  int fd_;
+  IEvent* listener_ = nullptr;
+  guint source_id_ = 0;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_GLIB_IO_CHANNEL_HH_
diff --git a/src/lib/launchpad-core/language_config.cc b/src/lib/launchpad-core/language_config.cc
new file mode 100644 (file)
index 0000000..26b5dc8
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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-core/language_config.hh"
+
+#include <stdlib.h>
+
+#include "launchpad-core/log_private.hh"
+
+namespace launchpad {
+
+LanguageConfig::LanguageConfig() : vconf_(Vconf(VCONFKEY_LANGSET)) {
+  vconf_.Listen(this);
+
+  try {
+    lang_ = vconf_.Get<std::string>();
+    setenv("LANG", lang_.c_str(), 1);
+    _W("Language: %s", lang_.c_str());
+  } catch (const Exception& e) {
+    _E("Exception occurs. error: %s", e.what());
+  }
+}
+
+const std::string& LanguageConfig::Get() const {
+  return lang_;
+}
+
+void LanguageConfig::OnKeyChanged(const Vconf::KeyNode& node) {
+  lang_ = node.Get<std::string>();
+  setenv("LANG", lang_.c_str(), 1);
+  _W("Language: %s", lang_.c_str());
+}
+
+}  // namespace launchpad
+
diff --git a/src/lib/launchpad-core/language_config.hh b/src/lib/launchpad-core/language_config.hh
new file mode 100644 (file)
index 0000000..1ee5b85
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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 LIB_LAUNCHPAD_CORE_LANGUAGE_CONFIG_HH_
+#define LIB_LAUNCHPAD_CORE_LANGUAGE_CONFIG_HH_
+
+#include <string>
+
+#include <vconf.hh>
+
+namespace launchpad {
+
+class LanguageConfig : public Vconf::IEvent {
+ public:
+  LanguageConfig();
+
+  const std::string& Get() const;
+
+ private:
+  void OnKeyChanged(const Vconf::KeyNode& node) override;
+
+ private:
+  Vconf vconf_;
+  std::string lang_;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_LANGUAGE_CONFIG_HH_
diff --git a/src/lib/launchpad-core/launcher_info.cc b/src/lib/launchpad-core/launcher_info.cc
deleted file mode 100644 (file)
index 1b3816e..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 3a97264..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index b19ac77..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 1cb7a8d..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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/launchpad_core.cc b/src/lib/launchpad-core/launchpad_core.cc
new file mode 100644 (file)
index 0000000..5fdf451
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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/include/launchpad_core.h"
+
+#include <bundle.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "launchpad-core/app_executor_internal.hh"
+#include "launchpad-core/loader_executor_internal.hh"
+#include "launchpad-core/log_private.hh"
+#include "launchpad-core/process_pool_internal.hh"
+
+#undef EXPORT
+#define EXPORT __attribute__((visibility("default")))
+
+#undef API
+#define API extern "C" EXPORT
+
+API void launchpad_core_execute_app(bundle* request) {
+  tizen_base::Bundle b(request, false, false);
+  launchpad::internal::AppExecutor executor;
+  executor.Execute(std::move(b));
+}
+
+API void launchpad_core_execute_process_pool(bundle* request) {
+  tizen_base::Bundle b(request, false, false);
+  launchpad::internal::ProcessPool process_pool;
+  process_pool.Execute(std::move(b));
+}
+
+API void launchpad_core_execute_loader(bundle* request) {
+  tizen_base::Bundle b(request, false, false);
+  launchpad::internal::LoaderExecutor executor;
+  executor.Execute(std::move(b));
+}
diff --git a/src/lib/launchpad-core/loader_executor.cc b/src/lib/launchpad-core/loader_executor.cc
deleted file mode 100644 (file)
index 626fb5c..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 09c22ad..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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_executor_internal.cc b/src/lib/launchpad-core/loader_executor_internal.cc
new file mode 100644 (file)
index 0000000..7b409da
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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/loader_executor_internal.hh"
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <sched_priority.hh>
+#include <stdio.hh>
+#include <types.hh>
+#include <util.hh>
+
+#include "launchpad-core/log_private.hh"
+
+namespace launchpad {
+namespace internal {
+
+LoaderExecutor::LoaderExecutor() = default;
+
+void LoaderExecutor::Execute(tizen_base::Bundle request) {
+  int priority = std::stoi(request.GetString("LOADER_PRIORITY"));
+  if (priority != 0)
+    SchedPriority::Set(priority);
+
+  auto loader_args = request.GetStringArray("LOADER_ARGS");
+  std::vector<char*> loader_argv(loader_args.size());
+  int loader_argc = loader_argv.size();
+  for (int i = 0; i < loader_argc; ++i) {
+    loader_argv[i] = const_cast<char*>(loader_args[i].c_str());
+    if ((i + 1) != loader_argc)
+      SECURE_LOGD("loader argument %d : %s##", i, loader_argv[i]);
+  }
+  loader_argv.push_back(nullptr);
+
+  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);
+  }
+}
+
+}  // namespace internal
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/loader_executor_internal.hh b/src/lib/launchpad-core/loader_executor_internal.hh
new file mode 100644 (file)
index 0000000..d0d46d2
--- /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 LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_INTERNAL_HH_
+#define LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_INTERNAL_HH_
+
+#include <sys/types.h>
+
+#include <bundle_cpp.h>
+
+namespace launchpad {
+namespace internal {
+
+class LoaderExecutor {
+ public:
+  LoaderExecutor();
+
+  void Execute(tizen_base::Bundle request);
+};
+
+}  // namespace internal
+}  // namespace launchpad
+
+#endif  // LAUNCHPAD_PROCESS_POOL_LOADER_EXECUTOR_INTERNAL_HH_
diff --git a/src/lib/launchpad-core/loader_info.cc b/src/lib/launchpad-core/loader_info.cc
deleted file mode 100644 (file)
index 1c8b811..0000000
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 93a0190..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * 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_
index 192eaa47ff43bb37f3a83468bd20fb111d3ef7cd..0a26fc64363f029bc2ffb0a2e6711a9be8e910d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ * 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.
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef LIB_LAUNCHPAD_CORE_LOG_PRIVATE_HH_
-#define LIB_LAUNCHPAD_CORE_LOG_PRIVATE_HH_
+#ifndef LIB_LAUNCHPAD_GLIB_LOG_PRIVATE_HH_
+#define LIB_LAUNCHPAD_GLIB_LOG_PRIVATE_HH_
 
 #include <dlog.h>
 
 #define LOG_TAG "LAUNCHPAD"
 
 #undef _E
-#define _E(fmt, ...) LOGE("[CORE] " fmt, ##__VA_ARGS__)
+#define _E(fmt, ...) LOGE("[GLIB] " fmt, ##__VA_ARGS__)
 
 #undef _W
-#define _W(fmt, ...) LOGW("[CORE] " fmt, ##__VA_ARGS__)
+#define _W(fmt, ...) LOGW("[GLIB] " fmt, ##__VA_ARGS__)
 
 #undef _I
-#define _I(fmt, ...) LOGI("[CORE] " fmt, ##__VA_ARGS__)
+#define _I(fmt, ...) LOGI("[GLIB] " fmt, ##__VA_ARGS__)
 
 #undef _D
-#define _D(fmt, ...) LOGD("[CORE] " fmt, ##__VA_ARGS__)
+#define _D(fmt, ...) LOGD("[GLIB] " fmt, ##__VA_ARGS__)
 
-#endif  // LIB_LAUNCHPAD_CORE_LOG_PRIVATE_HH_
+#endif  // LIB_LAUNCHPAD_GLIB_LOG_PRIVATE_HH_
diff --git a/src/lib/launchpad-core/plugin.cc b/src/lib/launchpad-core/plugin.cc
new file mode 100644 (file)
index 0000000..9f3214c
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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-core/plugin.hh"
+
+#include <dlfcn.h>
+
+#include <filesystem>
+
+#include "launchpad-core/log_private.hh"
+
+namespace fs = std::filesystem;
+
+namespace launchpad {
+namespace {
+
+constexpr const char kPathLaunchpadPlugin[] =
+    "/usr/share/aul/plugin/liblaunchpad-plugin.so";
+constexpr const char kTagLaunchpadPluginPrepareApp[] =
+    "LAUNCHPAD_PLUGIN_PREPARE_APP";
+
+}  // namespace
+
+int Plugin::PrepareApp(const std::string& appid, const tizen_base::Bundle& b) {
+  if (!fs::exists(kPathLaunchpadPlugin))
+    return 0;
+
+  void* handle = dlopen(kPathLaunchpadPlugin, RTLD_LAZY | RTLD_LOCAL);
+  if (handle == nullptr) {
+    _W("dlopen() is failed. path(%s), error(%s)",
+        kPathLaunchpadPlugin, dlerror());
+    return 0;
+  }
+
+  auto* prepare_app_func = reinterpret_cast<int(*)(const char*, bundle*)>(
+      dlsym(handle, kTagLaunchpadPluginPrepareApp));
+  if (prepare_app_func == nullptr) {
+    _W("dlsym() is failed. %s", kTagLaunchpadPluginPrepareApp);
+    dlclose(handle);
+    return 0;
+  }
+
+  _W("%s ++", kTagLaunchpadPluginPrepareApp);
+  int ret = prepare_app_func(appid.empty() ? nullptr : appid.c_str(),
+      b.GetHandle());
+  _W("%s --", kTagLaunchpadPluginPrepareApp);
+  return ret;
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/plugin.hh b/src/lib/launchpad-core/plugin.hh
new file mode 100644 (file)
index 0000000..399512c
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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 LIB_LAUNCHPAD_CORE_PLUGIN_HH_
+#define LIB_LAUNCHPAD_CORE_PLUGIN_HH_
+
+#include <bundle_cpp.h>
+
+#include <string>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API Plugin {
+ public:
+  static int PrepareApp(const std::string& appid, const tizen_base::Bundle& b);
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_PLUGIN_HH_
diff --git a/src/lib/launchpad-core/process_pool.cc b/src/lib/launchpad-core/process_pool.cc
deleted file mode 100644 (file)
index df39da0..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index 4a12ea1..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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/process_pool_internal.cc b/src/lib/launchpad-core/process_pool_internal.cc
new file mode 100644 (file)
index 0000000..b98cbe2
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * 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_internal.hh"
+
+#include <stdbool.h>
+#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 <pthread.h>
+
+#include <filesystem>
+#include <utility>
+#include <vector>
+
+#include <aul_keys.hh>
+#include <bundle_cpp.h>
+#include <socket.hh>
+#include <types.hh>
+#include <util.hh>
+
+#include "launchpad-core/app_executor_internal.hh"
+#include "launchpad-core/loader_executor_internal.hh"
+#include "launchpad-core/log_private.hh"
+
+namespace fs = std::filesystem;
+
+namespace {
+
+constexpr const char kProcessPoolSock[] = ".process-pool-sock";
+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
+
+namespace launchpad {
+namespace internal {
+
+ProcessPool::ProcessPool() {}
+
+void ProcessPool::Execute(tizen_base::Bundle request) {
+  name_ = request.GetString(kAulProcessPoolName);
+  _D("Candidate Process. name=%s", name_.c_str());
+  std::string comm = std::string(kProcessPool) + "-" + name_;
+  pthread_setname_np(pthread_self(), comm.c_str());
+  std::vector<int> except_fds = GetExceptableFds();
+  Util::CloseAllFds(except_fds);
+  int ret = ConnectToServer();
+  if (ret != 0) exit(ret);
+
+  ret = WaitForRequest();
+  exit(ret);
+}
+
+int ProcessPool::ConnectToServer() {
+  try {
+    std::string endpoint = "/run/aul/daemons/" + std::to_string(getuid()) +
+                           "/" + std::string(kProcessPoolSock) + "-" + name_;
+    client_socket_.reset(new ClientSocket());
+    client_socket_->Connect(endpoint);
+    client_socket_->SetReceiveBufferSize(Socket::kSocketMaxBufferSize);
+
+    pid_t pid = getpid();
+    int ret = client_socket_->Send(static_cast<void*>(&pid), sizeof(pid));
+    if (ret != 0) {
+      _E("Send() is failed. error=%d", ret);
+      return ret;
+    }
+  } catch (const Exception& e) {
+    _E("Exception occurs. error=%s", e.what());
+    return e.GetErrorCode();
+  }
+
+  return 0;
+}
+
+int ProcessPool::WaitForRequest() {
+  tizen_base::Parcel parcel;
+  size_t data_size = 0;
+  int ret = client_socket_->Receive(static_cast<void*>(&data_size),
+                                    sizeof(data_size));
+  if (ret != 0) {
+    _E("Receive() is failed. error=%d", ret);
+    return -1;
+  }
+
+  std::vector<uint8_t> data(data_size);
+  ret = client_socket_->Receive(data.data(), data.size());
+  if (ret != 0) {
+    _E("Receive() is failed. erorr=%d", ret);
+    return -1;
+  }
+
+  parcel.Write(data.data(), data.size());
+  tizen_base::Bundle request = Util::CreateBundleFromParcel(&parcel);
+  auto cmd_str = request.GetString(kAulLuxCmd);
+  _W("[%d] cmd=%s", getpid(), cmd_str.c_str());
+  int cmd = std::stoi(cmd_str);
+  switch (cmd) {
+    case static_cast<int>(LuxCmd::ExecuteApp): {
+      AppExecutor app_executor;
+      app_executor.Execute(std::move(request));
+      break;
+    }
+    case static_cast<int>(LuxCmd::ExecuteLoader): {
+      LoaderExecutor loader_executor;
+      loader_executor.Execute(std::move(request));
+      break;
+    }
+    default: {
+      _W("Unknown command=%s", cmd_str.c_str());
+      exit(EXIT_FAILURE);
+    }
+  }
+
+  return 0;
+}
+
+}  // namespace internal
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/process_pool_internal.hh b/src/lib/launchpad-core/process_pool_internal.hh
new file mode 100644 (file)
index 0000000..cf82769
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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_PROCESS_POOL_INTERNAL_HH_
+#define LIB_LAUNCHPAD_CORE_PROCESS_POOL_INTERNAL_HH_
+
+#include <glib.h>
+#include <sys/types.h>
+
+#include <memory>
+#include <string>
+
+#include <bundle_cpp.h>
+#include <client_socket.hh>
+
+namespace launchpad {
+namespace internal {
+
+class ProcessPool {
+ public:
+  ProcessPool();
+
+  void Execute(tizen_base::Bundle request);
+
+ private:
+  int ConnectToServer();
+  int WaitForRequest();
+
+ private:
+  std::string name_;
+  std::unique_ptr<ClientSocket> client_socket_;
+};
+
+}  // namespace internal
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_PROCESS_POOL_INTERNAL_HH_
diff --git a/src/lib/launchpad-core/rec_mutex.hh b/src/lib/launchpad-core/rec_mutex.hh
deleted file mode 100644 (file)
index 1e2abaf..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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/region_format_config.cc b/src/lib/launchpad-core/region_format_config.cc
new file mode 100644 (file)
index 0000000..3cebbdb
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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-core/region_format_config.hh"
+
+#include <stdlib.h>
+
+#include "launchpad-core/log_private.hh"
+
+namespace launchpad {
+
+RegionFormatConfig::RegionFormatConfig()
+    : vconf_(Vconf(VCONFKEY_REGIONFORMAT)) {
+  vconf_.Listen(this);
+
+  try {
+    region_ = vconf_.Get<std::string>();
+    setenv("LC_CTYPE", region_.c_str(), 1);
+    _W("Region: %s", region_.c_str());
+  } catch (const Exception& e) {
+    _E("Exception occurs. error: %s", e.what());
+  }
+}
+
+const std::string& RegionFormatConfig::Get() const {
+  return region_;
+}
+
+void RegionFormatConfig::OnKeyChanged(const Vconf::KeyNode& node) {
+  region_ = node.Get<std::string>();
+  setenv("LC_CTYPE", region_.c_str(), 1);
+  _W("Region: %s", region_.c_str());
+}
+
+}  // namespace launchpad
+
diff --git a/src/lib/launchpad-core/region_format_config.hh b/src/lib/launchpad-core/region_format_config.hh
new file mode 100644 (file)
index 0000000..9ba183c
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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 LIB_LAUNCHPAD_CORE_REGION_FORMAT_CONFIG_HH_
+#define LIB_LAUNCHPAD_CORE_REGION_FORMAT_CONFIG_HH_
+
+#include <string>
+
+#include <vconf.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API RegionFormatConfig : public Vconf::IEvent {
+ public:
+  RegionFormatConfig();
+
+  const std::string& Get() const;
+
+ private:
+  void OnKeyChanged(const Vconf::KeyNode& node) override;
+
+ private:
+  Vconf vconf_;
+  std::string region_;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_REGION_FORMAT_CONFIG_HH_
diff --git a/src/lib/launchpad-core/sigchld_manager.cc b/src/lib/launchpad-core/sigchld_manager.cc
deleted file mode 100644 (file)
index 502e4a5..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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
deleted file mode 100644 (file)
index a26902c..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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
diff --git a/src/lib/launchpad-core/util.cc b/src/lib/launchpad-core/util.cc
new file mode 100644 (file)
index 0000000..e1f2b37
--- /dev/null
@@ -0,0 +1,670 @@
+/*
+ * 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-core/util.hh"
+
+#include <bundle_internal.h>
+#include <dbus/dbus.h>
+#include <stdlib.h>
+#include <sys/mount.h>
+#include <sys/personality.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <tzplatform_config.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <cctype>
+#include <filesystem>
+#include <fstream>
+#include <memory>
+#include <regex>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <aul_keys.hh>
+#include <exception.hh>
+#include <parcel.hh>
+#include <parcelable.hh>
+#include <server_socket.hh>
+#include <socket.hh>
+
+#include "launchpad-core/log_private.hh"
+
+#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
+
+namespace fs = std::filesystem;
+
+namespace launchpad {
+namespace {
+
+constexpr const char kDefaultLocale[] = "en_US.UTF-8";
+constexpr const char kTepBusName[] = "org.tizen.system.deviced";
+constexpr const char kTepObjectPath[] = "/Org/Tizen/System/DeviceD/Tzip";
+constexpr const char kTepInterfaceName[] = "org.tizen.system.deviced.Tzip";
+constexpr const char kTepIsMountedMethod[] = "IsMounted";
+const int kMaxTepIsMountRetryCount = 100;
+constexpr const char kApp2sdBusName[] = "org.tizen.app2sd";
+constexpr const char kApp2sdObjectPath[] = "/org/tizen/app2sd";
+constexpr const char kApp2sdInterfaceName[] = "org.tizen.app2sd";
+constexpr const char kApp2sdOndemandSetupInitMethod[] = "OndemandSetupInit";
+const int kApp2sdRetryMax = 5;
+const int kApp2sdWaitUsec = 1000000 / 2;  // 0.5 sec
+
+int aul_listen_fd = -1;
+
+void SetLanguageEnvironments() {
+  const char* lang = getenv("LANG");
+  if (lang == nullptr) {
+    lang = kDefaultLocale;
+    setenv("LANG", lang, 1);
+  }
+
+  setenv("LANGUAGE", lang, 1);
+  setenv("LC_MESSAGES", lang, 1);
+  setenv("LC_ALL", lang, 1);
+}
+
+void SetRegionFormatEnvironments() {
+  const char* region = getenv("LC_CTYPE");
+  if (region == nullptr) {
+    region = kDefaultLocale;
+    setenv("LC_CTYPE", region, 1);
+  }
+
+  setenv("LC_NUMERIC", region, 1);
+  setenv("LC_TIME", region, 1);
+  setenv("LC_COLLATE", region, 1);
+  setenv("LC_MONETARY", region, 1);
+  setenv("LC_PAPER", region, 1);
+  setenv("LC_NAME", region, 1);
+  setenv("LC_ADDRESS", region, 1);
+  setenv("LC_TELEPHONE", region, 1);
+  setenv("LC_MEASUREMENT", region, 1);
+  setenv("LC_IDENTIFICATION", region, 1);
+}
+
+void SetGadgetPkgIdsEnvironments(const tizen_base::Bundle& b) {
+  auto gadget_pkgids = b.GetStringArray(kAulMountGadgetPkgIds);
+  if (gadget_pkgids.empty()) return;
+
+  std::string pkgids;
+  for (auto& pkgid : gadget_pkgids) {
+    if (!pkgids.empty()) pkgids += ":";
+
+    pkgids += pkgid;
+  }
+
+  setenv("GADGET_PKGIDS", pkgids.c_str(), 1);
+}
+
+#ifdef TIZEN_FEATURE_SET_PERSONALITY_32
+static void SetExecutionDomain() {
+  int ret = personality(PER_LINUX32);
+  if (ret < 0) {
+    char err_buf[1024];
+    _E("persionality() is failed. errno: %d(%s)",
+        errno, strerror_r(errno, err_buf, sizeof(err_buf)));
+  }
+}
+#endif  // TIZEN_FEATURE_SET_PERSONALITY_32
+
+class DBus {
+ public:
+  DBus() {
+    DBusError error;
+    dbus_error_init(&error);
+    conn_ = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
+    if (conn_ == nullptr) {
+      _E("Failed to connect to D-Bus Daemon");
+      if (dbus_error_is_set(&error)) {
+        _E("D-Bus error: %s", error.message);
+        dbus_error_free(&error);
+      }
+      THROW(-ENOTCONN);
+    }
+  }
+
+  virtual ~DBus() {
+    if (conn_ != nullptr)
+      dbus_connection_close(conn_);
+  }
+
+  void SendMessage(DBusMessage* message, int timeout, int* result) {
+    if (message == nullptr) {
+      _E("Invalid parameter");
+      THROW(-EINVAL);
+    }
+
+    DBusPendingCall* pending = nullptr;
+    dbus_bool_t ret = dbus_connection_send_with_reply(conn_, message, &pending,
+        timeout);
+    if (!ret || pending == nullptr) {
+      _E("Failed to send message");
+      THROW(-EIO);
+    }
+
+    dbus_connection_flush(conn_);
+    dbus_pending_call_block(pending);
+    auto* reply = dbus_pending_call_steal_reply(pending);
+    dbus_pending_call_unref(pending);
+    if (reply == nullptr) {
+      _E("Failed to get reply message");
+      THROW(-EIO);
+    }
+
+    auto reply_auto =
+        std::unique_ptr<DBusMessage, decltype(dbus_message_unref)*>(
+            reply, dbus_message_unref);
+    DBusMessageIter iter;
+    if (!dbus_message_iter_init(reply, &iter)) {
+      _E("Message ha no argument");
+      THROW(-EIO);
+    }
+
+    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
+      _E("Argument is not interger. type(%d)",
+          dbus_message_iter_get_arg_type(&iter));
+      THROW(-EIO);
+    }
+
+    dbus_int32_t res;
+    dbus_message_iter_get_basic(&iter, &res);
+    *result = static_cast<int>(res);
+    _D("Result: %d", *result);
+  }
+
+ private:
+  DBusConnection* conn_ = nullptr;
+};
+
+class TepMountChecker : public DBus {
+ public:
+  explicit TepMountChecker(std::vector<std::string> paths)
+      : paths_(std::move(paths)) {}
+
+  bool IsMounted() {
+    for (auto& path : paths_) {
+      if (CheckTepMount(path) != 0)
+        return false;
+    }
+
+    return true;
+  }
+
+ private:
+  DBusMessage* CreateTepMountMessage(const std::string& path) {
+    DBusMessage* message = dbus_message_new_method_call(kTepBusName,
+        kTepObjectPath, kTepInterfaceName, kTepIsMountedMethod);
+    if (message == nullptr) {
+      _E("dbus_message_new_method_call() is failed");
+      return nullptr;
+    }
+
+    DBusMessageIter iter;
+    dbus_message_iter_init_append(message, &iter);
+    auto* tep_path = path.c_str();
+    auto ret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
+        &tep_path);
+    if (!ret) {
+      _E("dbus_message_iter_append_basic() is failed");
+      dbus_message_unref(message);
+      return nullptr;
+    }
+
+    return message;
+  }
+
+  int IsTepMountDone(const std::string& path) {
+    int result = -1;
+    auto message = std::unique_ptr<DBusMessage, decltype(dbus_message_unref)*>(
+        CreateTepMountMessage(path), dbus_message_unref);
+    SendMessage(message.get(), 500, &result);
+    return result;
+  }
+
+  int CheckTepMount(const std::string& path) {
+    if (path.empty())
+      return 0;
+
+    int count = 0;
+    while (count < kMaxTepIsMountRetryCount) {
+      if (IsTepMountDone(path) == 1)
+        return 0;
+
+      usleep(50 * 1000);
+      count++;
+    }
+
+    _E("Not able to mount within 5 seconds. path(%s", path.c_str());
+    return -1;
+  }
+
+ private:
+  std::vector<std::string> paths_;
+};
+
+int MountDirectories(const std::vector<std::string>& srcs,
+    const std::string& dest) {
+  if (access(dest.c_str(), F_OK) != 0) return 0;
+
+  std::string opt = "lowerdir=";
+  for (auto& src : srcs)
+    opt += src + ":";
+  opt += dest;
+
+  _D("mount opt: %s", opt.c_str());
+  int ret = mount(nullptr, dest.c_str(), "overlay", MS_RDONLY, opt.c_str());
+  if (ret != 0)
+    _E("mount() is failed. dest(%s), errno(%d)", dest.c_str(), errno);
+
+  return ret;
+}
+
+class ExternalPackage : public DBus {
+ public:
+  ExternalPackage(std::string package, uid_t uid)
+      : package_(std::move(package)), uid_(uid) {
+    _D("package(%s), uid(%u)", package_.c_str(), uid_);
+  }
+
+  void Enable() {
+    int result = -1;
+    int retry_count = 0;
+    auto message = std::unique_ptr<DBusMessage, decltype(dbus_message_unref)*>(
+        CreateApp2sdMessage(), dbus_message_unref);
+    while (retry_count <= kApp2sdRetryMax) {
+      try {
+        SendMessage(message.get(), 500, &result);
+      } catch (const Exception& e) {
+        _E("Exception occurs. error(%s)", e.what());
+        retry_count++;
+        continue;
+      }
+
+      break;
+    }
+
+    _D("Result: %d", result);
+    if (result < 0)
+      THROW(-EIO);
+  }
+
+ private:
+  DBusMessage* CreateApp2sdMessage() {
+    DBusMessage* message = dbus_message_new_method_call(kApp2sdBusName,
+        kApp2sdObjectPath, kApp2sdInterfaceName,
+        kApp2sdOndemandSetupInitMethod);
+    if (message == nullptr) {
+      _E("dbus_message_new_method_call() is failed");
+      return nullptr;
+    }
+
+    DBusMessageIter iter;
+    dbus_message_iter_init_append(message, &iter);
+    const char* package = package_.c_str();
+    if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &package)) {
+      _E("dbus_message_iter_append_basic() is failed");
+      dbus_message_unref(message);
+      return nullptr;
+    }
+
+    if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &uid_)) {
+      _E("dbus_message_iter_append_basic() is failed");
+      dbus_message_unref(message);
+      return nullptr;
+    }
+
+    return message;
+  }
+
+ private:
+  std::string package_;
+  uid_t uid_;
+};
+
+class AmdPacket : public tizen_base::Parcelable {
+ public:
+  explicit AmdPacket(int cmd, bundle* request, int opt)
+      : cmd_(cmd), request_(request), opt_(opt) {}
+
+  void WriteToParcel(tizen_base::Parcel* parcel) const {
+    parcel->WriteInt32(cmd_);
+    if (request_ == nullptr) {
+      parcel->WriteInt32(0);
+      parcel->WriteInt32(opt_);
+    } else {
+      bundle_raw* raw = nullptr;
+      int len = 0;
+      bundle_encode(request_, &raw, &len);
+      parcel->WriteInt32(len);
+      parcel->WriteInt32(opt_);
+      parcel->Write(reinterpret_cast<unsigned char*>(raw), len);
+      bundle_free_encoded_rawdata(&raw);
+    }
+  }
+
+  void ReadFromParcel(tizen_base::Parcel* parcel) {
+    parcel->ReadInt32(&cmd_);
+  }
+
+ private:
+  int cmd_ = -1;
+  bundle* request_ = nullptr;
+  int opt_ = 0;
+};
+
+std::vector<std::string> ValidateAndModifyGadgetPaths(
+    const std::vector<std::string> gadget_paths) {
+  std::vector<std::string> paths;
+  for (const auto& path : gadget_paths) {
+    if (access(path.c_str(), F_OK) == 0)
+      paths.push_back(path);
+    else
+      paths.push_back(fs::path(path).parent_path().string());
+  }
+
+  return paths;
+}
+
+}  // namespace
+
+void Util::SetEnvironments(const AppInfo* app_info) {
+  auto& b = app_info->GetBundle();
+  auto value = b.GetString(kAulStarttime);
+  if (!value.empty())
+    setenv("APP_START_TIME", value.c_str(), 1);
+
+  if (!app_info->GetHwacc().empty())
+    setenv("HWACC", app_info->GetHwacc().c_str(), 1);
+
+  if (!app_info->GetTaskmanage().empty())
+    setenv("TASKMANAGE", app_info->GetTaskmanage().c_str(), 1);
+
+  if (!app_info->GetRootPath().empty())
+    setenv("AUL_ROOT_PATH", app_info->GetRootPath().c_str(), 1);
+
+  if (!app_info->GetAppId().empty()) {
+    auto multiple_instance_app_id = b.GetString(kAulMultipleInstanceAppId);
+    if (!multiple_instance_app_id.empty())
+      setenv("AUL_APPID", multiple_instance_app_id.c_str(), 1);
+    else
+      setenv("AUL_APPID", app_info->GetAppId().c_str(), 1);
+  }
+
+  if (!app_info->GetPkgId().empty())
+    setenv("AUL_PKGID", app_info->GetPkgId().c_str(), 1);
+
+  if (!app_info->GetAppType().empty())
+    setenv("RUNTIME_TYPE", app_info->GetAppType().c_str(), 1);
+
+  value = b.GetString(kAulWaylandDisplay);
+  if (!value.empty())
+    setenv("WAYLAND_DISPLAY", value.c_str(), 1);
+
+  value = b.GetString(kAulWaylandWorkingDir);
+  if (!value.empty())
+    setenv("XDG_RUNTIME_DIR", value.c_str(), 1);
+
+  value = b.GetString(kAulApiVersion);
+  if (!value.empty())
+    setenv("TIZEN_API_VERSION", value.c_str(), 1);
+
+  setenv("AUL_PID", std::to_string(getpid()).c_str(), 1);
+
+  if (getenv("TIZEN_GLIB_CONTEXT") == nullptr)
+    setenv("TIZEN_GLIB_CONTEXT", "0", 1);
+
+  value = b.GetString(kAulFastLaunch);
+  if (!value.empty())
+    setenv("AUL_FAST_LAUNCH", value.c_str(), 1);
+
+  SetLanguageEnvironments();
+  SetRegionFormatEnvironments();
+
+#ifdef TIZEN_FEATURE_SET_PERSONALITY_32
+  SetExecutionDomain();
+#endif  // TIZEN_FEATURE_SET_PERSONALITY_32
+
+  setenv("GCOV_PREFIX", "/tmp", 1);
+  setenv("DALI_DISABLE_PARTIAL_UPDATE", "0", 1);
+  SetGadgetPkgIdsEnvironments(b);
+}
+
+void Util::DeleteSocketPath(pid_t pid, uid_t uid) {
+  std::string path ="/run/aul/apps/" + std::to_string(uid) + "/" +
+      std::to_string(pid);
+  if (!fs::exists(path))
+    return;
+
+  try {
+    fs::remove_all(path);
+  } catch (const std::exception& e) {
+    _E("Exception occurs. error: %s", e.what());
+  }
+}
+
+int Util::EnableExternalPackage(const AppInfo* app_info) {
+  auto installed_storage = app_info->GetBundle().GetString(
+      kAulInstalledStorage);
+  if (installed_storage != "external")
+    return 0;
+
+  try {
+    ExternalPackage external_package(app_info->GetPkgId(),
+        app_info->IsGlobal() ? GLOBAL_USER : getuid());
+    external_package.Enable();
+  } catch (const Exception& e) {
+    _E("Exception occurs. error(%s)", e.what());
+    return -1;
+  }
+
+  return 0;
+}
+
+int Util::MountResourceDirectories(const AppInfo* app_info) {
+  auto& root_path = app_info->GetRootPath();
+  auto& b = app_info->GetBundle();
+  auto global_res_dir = b.GetStringArray(kAulMountGlobalResDir);
+  if (!global_res_dir.empty())
+    MountDirectories(global_res_dir, root_path + "/res/mount/global");
+
+  auto allowed_res_dir = b.GetStringArray(kAulMountAllowedResDir);
+  if (!allowed_res_dir.empty())
+    MountDirectories(allowed_res_dir, root_path + "/res/mount/allowed");
+
+  return 0;
+}
+
+int Util::MountLibraryDirectories(const tizen_base::Bundle& b) {
+  auto lib_dir = b.GetStringArray(kAulMountLibDir);
+  if (!lib_dir.empty()) {
+    auto root_path = b.GetString(kAulRootPath);
+    MountDirectories(lib_dir, root_path + "/lib/");
+  }
+
+  return 0;
+}
+
+int Util::MountGadgetDirectories(const tizen_base::Bundle& b) {
+  auto gadget_paths = b.GetStringArray(kAulMountGadgetPaths);
+  if (!gadget_paths.empty()) {
+    gadget_paths = ValidateAndModifyGadgetPaths(gadget_paths);
+    auto root_path = b.GetString(kAulRootPath);
+    return MountDirectories(gadget_paths, root_path + "/bin");
+  }
+
+  return 0;
+}
+
+int Util::WaitTepMount(const AppInfo* app_info) {
+  if (app_info->GetBundle().GetType(kAulTepPath) == BUNDLE_TYPE_NONE)
+    return 0;
+
+  try {
+    auto paths = app_info->GetBundle().GetStringArray(kAulTepPath);
+    TepMountChecker checker(std::move(paths));
+    if (!checker.IsMounted())
+      return -1;
+  } catch (const Exception& e) {
+    _E("Exception occurs. error(%s)", e.what());
+    return e.GetErrorCode();
+  }
+
+  _I("TEP Mount has been done");
+  return 0;
+}
+
+std::string Util::GetLibDirectory(const std::string& app_path) {
+  std::filesystem::path path(app_path);
+  auto lib_dir = path.parent_path().string() + "/../lib/";
+  if (access(lib_dir.c_str(), F_OK) == 0)
+    return lib_dir;
+
+  return "";
+}
+
+void Util::CloseAllFds(const std::vector<int>& except_fds) {
+  int aul_fd = aul_listen_fd;
+
+  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 (fd < 3 || fd == aul_fd)
+        continue;
+
+      auto found = std::find_if(except_fds.begin(), except_fds.end(),
+          [&](int except_fd) {
+            return except_fd == fd;
+          });
+      if (found != except_fds.end())
+        continue;
+
+      fds.push_back(fd);
+    }
+  } catch (const fs::filesystem_error& e) {
+    _E("Execption occurs. error(%s)", e.what());
+  }
+
+  for (auto fd : fds)
+    close(fd);
+}
+
+int Util::PrepareAppSocket() {
+  try {
+    std::string path = "/run/aul/apps/" + std::to_string(getuid()) + "/" +
+        std::to_string(getpid());
+    if (access(path.c_str(), F_OK) != 0) {
+      std::error_code ec;
+      if (!fs::create_directory(path, ec)) {
+        _E("Failed to create directory. path=%s, error_code=%d(%s)",
+            path.c_str(), ec.value(), ec.message().c_str());
+        return -1;
+      }
+    }
+
+    path += "/.app-sock";
+    ServerSocket socket;
+    socket.Bind(path);
+    socket.Listen(128);
+    socket.SetReceiveBufferSize(Socket::kSocketMaxBufferSize);
+    socket.SetSendBufferSize(Socket::kSocketMaxBufferSize);
+    socket.SetCloseOnExec(false);
+    aul_listen_fd = socket.RemoveFd();
+    setenv("AUL_LISTEN_FD", std::to_string(aul_listen_fd).c_str(), 1);
+  } catch (const Exception& e) {
+    _E("Exception occurs. error(%s)", e.what());
+    return e.GetErrorCode();
+  }
+
+  return 0;
+}
+
+int Util::PrepareAppIdFile(const AppInfo* app_info) {
+  std::string path = "/run/aul/apps/" + std::to_string(getuid()) + "/" +
+      std::to_string(getpid()) + "/" + app_info->GetAppId();
+  std::ofstream stream(path);
+  stream.close();
+  return 0;
+}
+
+int Util::SendCmdToAmd(enum AmdCmd cmd) {
+  return SendCmdToAmd(cmd, nullptr, static_cast<int>(AmdSocketOption::None));
+}
+
+int Util::SendCmdToAmd(enum AmdCmd cmd, bundle* request, int opt) {
+  try {
+    std::string endpoint = "/run/aul/daemons/.amd-sock";
+    ClientSocket socket;
+    socket.Connect(endpoint);
+    socket.SetReceiveBufferSize(Socket::kSocketMaxBufferSize);
+    socket.SetReceiveTimeout(5000);
+
+    AmdPacket packet(static_cast<int>(cmd), request, opt);
+    tizen_base::Parcel parcel;
+    parcel.WriteParcelable(packet);
+
+    int ret = socket.Send(parcel.GetData(), parcel.GetDataSize());
+    if (ret != 0) {
+      _E("Failed to send cmd(%d), error(%d)", static_cast<int>(cmd), ret);
+      return -ECOMM;
+    }
+  } catch (const Exception& e) {
+    _E("Exception occrus. error(%s)", e.what());
+    return e.GetErrorCode();
+  }
+
+  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;
+}
+
+tizen_base::Parcel Util::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 Util::CreateBundleFromParcel(tizen_base::Parcel* parcel) {
+  std::string raw = parcel->ReadString();
+  return tizen_base::Bundle(raw);
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/util.hh b/src/lib/launchpad-core/util.hh
new file mode 100644 (file)
index 0000000..30a9457
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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 LIB_LAUNCHPAD_CORE_UTIL_HH_
+#define LIB_LAUNCHPAD_CORE_UTIL_HH_
+
+#include <bundle.h>
+#include <sys/types.h>
+#include <tzplatform_config.h>
+
+#include <string>
+#include <vector>
+
+#include <app_info.hh>
+#include <bundle_cpp.h>
+#include <types.hh>
+#include <parcel.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+#undef GLOBAL_USER
+#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
+
+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);
+  static void DeleteSocketPath(pid_t pid, uid_t uid);
+  static int EnableExternalPackage(const AppInfo* app_info);
+  static int MountResourceDirectories(const AppInfo* app_info);
+  [[nodiscard]] static int MountGadgetDirectories(const tizen_base::Bundle& b);
+  static int WaitTepMount(const AppInfo* app_info);
+  static std::string GetLibDirectory(const std::string& app_path);
+  static void CloseAllFds(const std::vector<int>& except_fds = {});
+  static int PrepareAppSocket();
+  static int PrepareAppIdFile(const AppInfo* app_info);
+  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);
+  static tizen_base::Parcel CreateParcelFromBundle(tizen_base::Bundle* b);
+  static tizen_base::Bundle CreateBundleFromParcel(tizen_base::Parcel* p);
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_UTIL_HH_
diff --git a/src/lib/launchpad-core/vconf.cc b/src/lib/launchpad-core/vconf.cc
new file mode 100644 (file)
index 0000000..b2efbf8
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * 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-core/vconf.hh"
+
+#include <errno.h>
+
+#include <string>
+#include <type_traits>
+#include <utility>
+
+#include "launchpad-core/log_private.hh"
+
+namespace launchpad {
+
+Vconf::KeyNode::KeyNode(keynode_t* node) : node_(node) {}
+
+std::string Vconf::KeyNode::GetName() const {
+  char* name = vconf_keynode_get_name(node_);
+  return std::string(name != nullptr ? name : "");
+}
+
+template <typename T>
+T Vconf::KeyNode::Get() const {
+  THROW(VCONF_ERROR_WRONG_TYPE);
+}
+
+template <>
+int Vconf::KeyNode::Get<int>() const {
+  return vconf_keynode_get_int(node_);
+}
+
+template <>
+double Vconf::KeyNode::Get<double>() const {
+  return vconf_keynode_get_dbl(node_);
+}
+
+template <>
+std::string Vconf::KeyNode::Get<std::string>() const {
+  char* str = vconf_keynode_get_str(node_);
+  return std::string(str != nullptr ? str : "");
+}
+
+template <>
+bool Vconf::KeyNode::Get<bool>() const {
+  return vconf_keynode_get_bool(node_) ? true : false;
+}
+
+Vconf::KeyNode::Type Vconf::KeyNode::GetType() const {
+  return static_cast < Vconf::KeyNode::Type>(vconf_keynode_get_type(node_));
+}
+
+Vconf::Vconf(std::string key)
+    : key_(std::move(key)) {}
+
+Vconf::~Vconf() {
+  Ignore();
+}
+
+template <typename T>
+T Vconf::Get() {
+  THROW(VCONF_ERROR_WRONG_TYPE);
+}
+
+template <>
+int Vconf::Get<int>() {
+  int result;
+  int ret = vconf_get_int(key_.c_str(), &result);
+  if (ret != VCONF_OK)
+    THROW(ret);
+
+  return result;
+}
+
+template <>
+double Vconf::Get<double>() {
+  double result;
+  int ret = vconf_get_dbl(key_.c_str(), &result);
+  if (ret != VCONF_OK)
+    THROW(ret);
+
+  return result;
+}
+
+template<>
+std::string Vconf::Get<std::string>() {
+  char* str = vconf_get_str(key_.c_str());
+  if (str == nullptr)
+    THROW(vconf_get_ext_errno());
+
+  std::string result(str);
+  std::free(str);
+  return result;
+}
+
+template<>
+bool Vconf::Get<bool>() {
+  int result;
+  int ret = vconf_get_bool(key_.c_str(), &result);
+  if (ret != VCONF_OK)
+    THROW(ret);
+
+  return result ? true : false;
+}
+
+void Vconf::Listen(IEvent* listener) {
+  if (listener == nullptr) {
+    _E("Invalid parameter");
+    THROW(-EINVAL);
+  }
+
+  bool listening = listener_ != nullptr ? true : false;
+  listener_ = listener;
+
+  if (!listening) {
+    int ret = vconf_notify_key_changed(key_.c_str(), VconfCb, this);
+    if (ret != VCONF_OK)
+      _E("vconf_notify_key_changed() is failed. key: %s", key_.c_str());
+  }
+}
+
+void Vconf::Ignore() {
+  if (listener_ != nullptr) {
+    vconf_ignore_key_changed(key_.c_str(), VconfCb);
+    listener_ = nullptr;
+  }
+}
+
+void Vconf::VconfCb(keynode_t* node, void* user_data) {
+  auto* vconf = static_cast<Vconf*>(user_data);
+  auto* listener = vconf->listener_;
+  if (listener != nullptr)
+    listener->OnKeyChanged(Vconf::KeyNode(node));
+}
+
+}  // namespace launchpad
diff --git a/src/lib/launchpad-core/vconf.hh b/src/lib/launchpad-core/vconf.hh
new file mode 100644 (file)
index 0000000..14a9a50
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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 LIB_LAUNCHPAD_CORE_VCONF_HH_
+#define LIB_LAUNCHPAD_CORE_VCONF_HH_
+
+#include <vconf.h>
+
+#include <string>
+
+#include <exception.hh>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace launchpad {
+
+class EXPORT_API Vconf {
+ public:
+  class KeyNode {
+   public:
+    enum class Type {
+      None = VCONF_TYPE_NONE,
+      String = VCONF_TYPE_STRING,
+      Integer = VCONF_TYPE_INT,
+      Double = VCONF_TYPE_DOUBLE,
+      Boolean = VCONF_TYPE_BOOL,
+    };
+
+    explicit KeyNode(keynode_t* node);
+
+    std::string GetName() const;
+
+    template <typename T>
+    T Get() const;
+
+    Type GetType() const;
+
+   private:
+    keynode_t* node_;
+  };
+
+  class IEvent {
+   public:
+    virtual ~IEvent() = default;
+    virtual void OnKeyChanged(const KeyNode& node) = 0;
+  };
+
+  explicit Vconf(std::string key);
+  virtual ~Vconf();
+
+  Vconf(const Vconf& vconf) = delete;
+  Vconf& operator = (const Vconf& vconf) = delete;
+  Vconf(Vconf&& vconf) = delete;
+  Vconf& operator = (Vconf&& vconf) = delete;
+
+  template <typename T>
+  T Get();
+
+  void Listen(IEvent* listener);
+  void Ignore();
+
+ private:
+  static void VconfCb(keynode_t* node, void* user_data);
+
+ private:
+  std::string key_;
+  IEvent* listener_ = nullptr;
+};
+
+}  // namespace launchpad
+
+#endif  // LIB_LAUNCHPAD_CORE_VCONF_HH_
diff --git a/src/lib/launchpad-glib/CMakeLists.txt b/src/lib/launchpad-glib/CMakeLists.txt
deleted file mode 100644 (file)
index 44fa0b5..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ LAUNCHPAD_GLIB_SRCS)
-
-ADD_LIBRARY(${TARGET_LAUNCHPAD_GLIB} SHARED ${LAUNCHPAD_GLIB_SRCS})
-
-SET_TARGET_PROPERTIES(${TARGET_LAUNCHPAD_GLIB} PROPERTIES
-  SOVERSION ${MAJORVER})
-SET_TARGET_PROPERTIES(${TARGET_LAUNCHPAD_GLIB} PROPERTIES
-  VERSION ${VERSION})
-
-TARGET_INCLUDE_DIRECTORIES(${TARGET_LAUNCHPAD_GLIB} PUBLIC
-  ${CMAKE_CURRENT_SOURCE_DIR}
-  ${CMAKE_CURRENT_SOURCE_DIR}/../
-)
-
-APPLY_PKG_CONFIG(${TARGET_LAUNCHPAD_GLIB} PUBLIC
-  BUNDLE_DEPS
-  DBUS_DEPS
-  DLOG_DEPS
-  GIO_DEPS
-  LIBTZPLATFORM_CONFIG_DEPS
-  VCONF_DEPS
-)
-
-TARGET_LINK_LIBRARIES(${TARGET_LAUNCHPAD_GLIB} PUBLIC
-  ${TARGET_LAUNCHPAD_COMMON} "-ldl")
-
-INSTALL(TARGETS ${TARGET_LAUNCHPAD_GLIB} DESTINATION ${LIB_INSTALL_DIR}
-  COMPONENT RuntimeLibraries)
-INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
-  DESTINATION include/launchpad-glib
-  FILES_MATCHING
-  PATTERN "*_private.hh" EXCLUDE
-  PATTERN "*.hh"
-)
-
-CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/liblaunchpad-glib.pc.in
-  ${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/liblaunchpad-glib.pc @ONLY)
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/liblaunchpad-glib.pc
-  DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
diff --git a/src/lib/launchpad-glib/app_info.cc b/src/lib/launchpad-glib/app_info.cc
deleted file mode 100644 (file)
index 7e95f69..0000000
+++ /dev/null
@@ -1,265 +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-glib/app_info.hh"
-
-#include <bundle_internal.h>
-
-#include <utility>
-
-#include <aul_keys.hh>
-
-namespace launchpad {
-
-AppInfo::Builder& AppInfo::Builder::SetAppId(const tizen_base::Bundle& b) {
-  app_id_ = b.GetString(kAulAppId);
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetAppPath(const tizen_base::Bundle& b) {
-  app_path_ = b.GetString(kAulExec);
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetOriginalAppPath(
-    const tizen_base::Bundle& b) {
-  original_app_path_ = b.GetString(kAulExec);
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetPkgType(const tizen_base::Bundle& b) {
-  pkg_type_ = b.GetString(kAulPackageType);
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetAppType(const tizen_base::Bundle& b) {
-  app_type_ = b.GetString(kAulAppType);
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetHwacc(const tizen_base::Bundle& b) {
-  hwacc_ = b.GetString(kAulHwAcc);
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetTaskmanage(const tizen_base::Bundle& b) {
-  taskmanage_ = b.GetString(kAulTaskManage);
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetPkgId(const tizen_base::Bundle& b) {
-  pkg_id_ = b.GetString(kAulPkgId);
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetCompType(const tizen_base::Bundle& b) {
-  comp_type_ = b.GetString(kAulCompType);
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetInternalPool(
-    const tizen_base::Bundle& b) {
-  internal_pool_ = b.GetString(kAulInternalPool);
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetRootPath(const tizen_base::Bundle& b) {
-  root_path_ = b.GetString(kAulRootPath);
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetLoaderName(const tizen_base::Bundle& b) {
-  loader_name_ = b.GetString(kAulLoaderName);
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetFastLaunch(const tizen_base::Bundle& b) {
-  if (b.GetString(kAulFastLaunch) == "true")
-    fast_launch_ = true;
-  else
-    fast_launch_ = false;
-
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetGlobal(const tizen_base::Bundle& b) {
-  if (b.GetString(kAulIsGlobal) == "true")
-    global_ = true;
-  else
-    global_ = false;
-
-  return *this;
-}
-
-AppInfo::Builder& AppInfo::Builder::SetBundle(tizen_base::Bundle b) {
-  b_ = std::move(b);
-  return *this;
-}
-
-AppInfo::Builder::operator AppInfo*() {
-  return new (std::nothrow) AppInfo(std::move(app_id_), std::move(app_path_),
-      std::move(original_app_path_), std::move(pkg_type_), std::move(app_type_),
-      std::move(hwacc_), std::move(taskmanage_), std::move(pkg_id_),
-      std::move(comp_type_), std::move(internal_pool_), std::move(root_path_),
-      std::move(loader_name_), fast_launch_, global_, std::move(b_));
-}
-
-AppInfo* AppInfo::Create(tizen_base::Bundle b) {
-  return Builder().SetAppId(b)
-      .SetAppPath(b)
-      .SetOriginalAppPath(b)
-      .SetPkgType(b)
-      .SetAppType(b)
-      .SetHwacc(b)
-      .SetTaskmanage(b)
-      .SetPkgId(b)
-      .SetCompType(b)
-      .SetInternalPool(b)
-      .SetRootPath(b)
-      .SetLoaderName(b)
-      .SetFastLaunch(b)
-      .SetGlobal(b)
-      .SetBundle(std::move(b));
-}
-
-const std::string& AppInfo::GetAppId() const {
-  return app_id_;
-}
-
-const std::string& AppInfo::GetAppPath() const {
-  return app_path_;
-}
-
-const std::string& AppInfo::GetOriginalAppPath() const {
-  return original_app_path_;
-}
-
-const std::string& AppInfo::GetPkgType() const {
-  return pkg_type_;
-}
-
-const std::string& AppInfo::GetAppType() const {
-  return app_type_;
-}
-
-const std::string& AppInfo::GetHwacc() const {
-  return hwacc_;
-}
-
-const std::string& AppInfo::GetTaskmanage() const {
-  return taskmanage_;
-}
-
-const std::string& AppInfo::GetPkgId() const {
-  return pkg_id_;
-}
-
-const std::string& AppInfo::GetCompType() const {
-  return comp_type_;
-}
-
-const std::string& AppInfo::GetInternalPool() const {
-  return internal_pool_;
-}
-
-const std::string& AppInfo::GetRootPath() const {
-  return root_path_;
-}
-
-const std::string& AppInfo::GetLoaderName() const {
-  return loader_name_;
-}
-
-const bool AppInfo::IsFastLaunch() const {
-  return fast_launch_;
-}
-
-const bool AppInfo::IsGlobal() const {
-  return global_;
-}
-
-const tizen_base::Bundle& AppInfo::GetBundle() const {
-  return b_;
-}
-
-void AppInfo::WriteToParcel(tizen_base::Parcel* parcel) const {
-  parcel->WriteString(app_id_);
-  parcel->WriteString(app_path_);
-  parcel->WriteString(original_app_path_);
-  parcel->WriteString(pkg_type_);
-  parcel->WriteString(app_type_);
-  parcel->WriteString(hwacc_);
-  parcel->WriteString(taskmanage_);
-  parcel->WriteString(pkg_id_);
-  parcel->WriteString(comp_type_);
-  parcel->WriteString(internal_pool_);
-  parcel->WriteString(root_path_);
-  parcel->WriteString(loader_name_);
-  parcel->WriteBool(fast_launch_);
-  parcel->WriteBool(global_);
-
-  bundle_raw* b_raw = nullptr;
-  int len = 0;
-  bundle_encode(b_.GetHandle(), &b_raw, &len);
-  std::string raw(b_raw != nullptr ? reinterpret_cast<const char*>(b_raw) : "");
-  bundle_free_encoded_rawdata(&b_raw);
-  parcel->WriteString(raw);
-}
-
-void AppInfo::ReadFromParcel(tizen_base::Parcel* parcel) {
-  app_id_ = parcel->ReadString();
-  app_path_ = parcel->ReadString();
-  original_app_path_ = parcel->ReadString();
-  pkg_type_ = parcel->ReadString();
-  app_type_ = parcel->ReadString();
-  hwacc_ = parcel->ReadString();
-  taskmanage_ = parcel->ReadString();
-  pkg_id_ = parcel->ReadString();
-  comp_type_ = parcel->ReadString();
-  internal_pool_ = parcel->ReadString();
-  root_path_ = parcel->ReadString();
-  loader_name_ = parcel->ReadString();
-  parcel->ReadBool(&fast_launch_);
-  parcel->ReadBool(&global_);
-
-  auto raw = parcel->ReadString();
-  if (!raw.empty())
-    b_ = tizen_base::Bundle(raw);
-}
-
-AppInfo::AppInfo(std::string app_id, std::string app_path,
-    std::string original_app_path, std::string pkg_type, std::string app_type,
-    std::string hwacc, std::string taskmanage, std::string pkg_id,
-    std::string comp_type, std::string internal_pool, std::string root_path,
-    std::string loader_name, bool fast_launch, bool global,
-    tizen_base::Bundle b)
-    : app_id_(std::move(app_id)),
-      app_path_(std::move(app_path)),
-      original_app_path_(std::move(original_app_path)),
-      pkg_type_(std::move(pkg_type)),
-      app_type_(std::move(app_type)),
-      hwacc_(std::move(hwacc)),
-      taskmanage_(std::move(taskmanage)),
-      pkg_id_(std::move(pkg_id)),
-      comp_type_(std::move(comp_type)),
-      internal_pool_(std::move(internal_pool)),
-      root_path_(std::move(root_path)),
-      loader_name_(std::move(loader_name)),
-      fast_launch_(fast_launch),
-      global_(global),
-      b_(std::move(b)) {}
-
-}  // namespace launchpad
diff --git a/src/lib/launchpad-glib/app_info.hh b/src/lib/launchpad-glib/app_info.hh
deleted file mode 100644 (file)
index bfafe73..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 LIB_LAUNCHPAD_GLIB_APP_INFO_HH_
-#define LIB_LAUNCHPAD_GLIB_APP_INFO_HH_
-
-#include <bundle_cpp.h>
-
-#include <memory>
-#include <string>
-
-#include <parcel.hh>
-#include <parcelable.hh>
-
-#undef EXPORT_API
-#define EXPORT_API __attribute__((visibility("default")))
-
-namespace launchpad {
-
-class EXPORT_API AppInfo : public tizen_base::Parcelable {
- public:
-  class Builder {
-   public:
-    Builder& SetAppId(const tizen_base::Bundle& b);
-    Builder& SetAppPath(const tizen_base::Bundle& b);
-    Builder& SetOriginalAppPath(const tizen_base::Bundle& b);
-    Builder& SetPkgType(const tizen_base::Bundle& b);
-    Builder& SetAppType(const tizen_base::Bundle& b);
-    Builder& SetHwacc(const tizen_base::Bundle& b);
-    Builder& SetTaskmanage(const tizen_base::Bundle& b);
-    Builder& SetPkgId(const tizen_base::Bundle& b);
-    Builder& SetCompType(const tizen_base::Bundle& b);
-    Builder& SetInternalPool(const tizen_base::Bundle& b);
-    Builder& SetRootPath(const tizen_base::Bundle& b);
-    Builder& SetLoaderName(const tizen_base::Bundle& b);
-    Builder& SetFastLaunch(const tizen_base::Bundle& b);
-    Builder& SetGlobal(const tizen_base::Bundle& b);
-    Builder& SetBundle(tizen_base::Bundle b);
-    operator AppInfo*();
-
-   private:
-    std::string app_id_;
-    std::string app_path_;
-    std::string original_app_path_;
-    std::string pkg_type_;
-    std::string app_type_;
-    std::string hwacc_;
-    std::string taskmanage_;
-    std::string pkg_id_;
-    std::string comp_type_;
-    std::string internal_pool_;
-    std::string root_path_;
-    std::string loader_name_;
-    bool fast_launch_ = false;
-    bool global_ = true;
-    tizen_base::Bundle b_;
-  };
-
-  AppInfo() = default;
-  virtual ~AppInfo() = default;
-
-  static AppInfo* Create(tizen_base::Bundle b);
-
-  const std::string& GetAppId() const;
-  const std::string& GetAppPath() const;
-  const std::string& GetOriginalAppPath() const;
-  const std::string& GetPkgType() const;
-  const std::string& GetAppType() const;
-  const std::string& GetHwacc() const;
-  const std::string& GetTaskmanage() const;
-  const std::string& GetPkgId() const;
-  const std::string& GetCompType() const;
-  const std::string& GetInternalPool() const;
-  const std::string& GetRootPath() const;
-  const std::string& GetLoaderName() const;
-  const bool IsFastLaunch() const;
-  const bool IsGlobal() const;
-  const tizen_base::Bundle& GetBundle() const;
-
-  void WriteToParcel(tizen_base::Parcel* parcel) const override;
-  void ReadFromParcel(tizen_base::Parcel* parcel) override;
-
- private:
-  AppInfo(std::string app_id, std::string app_path,
-      std::string original_app_path, std::string pkg_type, std::string app_type,
-      std::string hwacc, std::string taskmanage, std::string pkg_id,
-      std::string comp_type, std::string internal_pool, std::string root_path,
-      std::string loader_name, bool fast_launch, bool global,
-      tizen_base::Bundle b);
-
- private:
-  std::string app_id_;
-  std::string app_path_;
-  std::string original_app_path_;
-  std::string pkg_type_;
-  std::string app_type_;
-  std::string hwacc_;
-  std::string taskmanage_;
-  std::string pkg_id_;
-  std::string comp_type_;
-  std::string internal_pool_;
-  std::string root_path_;
-  std::string loader_name_;
-  bool fast_launch_ = false;
-  bool global_ = true;
-  tizen_base::Bundle b_;
-};
-
-}  // namespace launchpad
-
-#endif  // LIB_LAUNCHPAD_GLIB_APP_INFO_HH_
diff --git a/src/lib/launchpad-glib/hw_acceleration_config.cc b/src/lib/launchpad-glib/hw_acceleration_config.cc
deleted file mode 100644 (file)
index 24c1ab3..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.
- */
-
-#include "launchpad-glib/hw_acceleration_config.hh"
-
-#include "launchpad-glib/log_private.hh"
-
-namespace launchpad {
-
-HWAccelerationConfig::HWAccelerationConfig()
-    : vconf_(Vconf(VCONFKEY_SETAPPL_APP_HW_ACCELERATION)) {
-  vconf_.Listen(this);
-
-  try {
-    hwacc_ = vconf_.Get<int>();
-  } catch (const Exception& e) {
-    _E("Exception occurs. error: %s", e.what());
-    hwacc_ = -1;
-  }
-}
-
-int HWAccelerationConfig::Get() const {
-  return hwacc_;
-}
-
-void HWAccelerationConfig::OnKeyChanged(const Vconf::KeyNode& node) {
-  hwacc_ = node.Get<int>();
-  _W("Hwacc: %d", hwacc_);
-}
-
-}  // namespace launchpad
diff --git a/src/lib/launchpad-glib/hw_acceleration_config.hh b/src/lib/launchpad-glib/hw_acceleration_config.hh
deleted file mode 100644 (file)
index 9c2e293..0000000
+++ /dev/null
@@ -1,40 +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_GLIB_HW_ACCELERATION_CONFIG_HH_
-#define LAUNCHPAD_GLIB_HW_ACCELERATION_CONFIG_HH_
-
-#include <vconf.hh>
-
-namespace launchpad {
-
-class HWAccelerationConfig : public Vconf::IEvent {
- public:
-  HWAccelerationConfig();
-
-  int Get() const;
-
- private:
-  void OnKeyChanged(const Vconf::KeyNode& node) override;
-
- private:
-  Vconf vconf_;
-  int hwacc_;
-};
-
-}  // namespace launchpad
-
-#endif  // LAUNCHPAD_GLIB_HW_ACCELERATION_CONFIG_HH_
diff --git a/src/lib/launchpad-glib/io_channel.cc b/src/lib/launchpad-glib/io_channel.cc
deleted file mode 100644 (file)
index 9ff02f0..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-glib/io_channel.hh"
-
-#include <errno.h>
-
-#include <memory>
-
-#include "launchpad-glib/log_private.hh"
-
-namespace launchpad {
-
-IOChannel::IOChannel(int fd, int condition, IOChannel::IEvent* listener)
-    : fd_(fd), listener_(listener) {
-  source_id_ = g_unix_fd_add(fd, static_cast<GIOCondition>(condition),
-      UnixFdFunc, this);
-  if (source_id_ == 0) {
-    _E("g_unix_fd_add() is failed");
-    THROW(-ENOMEM);
-  }
-}
-
-IOChannel::~IOChannel() {
-  if (source_id_ != 0)
-    g_source_remove(source_id_);
-}
-
-gboolean IOChannel::UnixFdFunc(gint fd, GIOCondition condition,
-    gpointer user_data) {
-  auto* io_channel = static_cast<IOChannel*>(user_data);
-  if (io_channel->fd_ != fd) {
-    _E("fd(%d) is not equal to fd(%d) of io channel", fd, io_channel->fd_);
-    return G_SOURCE_REMOVE;
-  }
-
-  auto* listener = io_channel->listener_;
-  if (listener != nullptr)
-    listener->OnIOEventReceived(io_channel->fd_, static_cast<int>(condition));
-
-  return G_SOURCE_CONTINUE;
-}
-
-
-}  // namespace launchpad
diff --git a/src/lib/launchpad-glib/io_channel.hh b/src/lib/launchpad-glib/io_channel.hh
deleted file mode 100644 (file)
index 0d891d6..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 LIB_LAUNCHPAD_GLIB_IO_CHANNEL_HH_
-#define LIB_LAUNCHPAD_GLIB_IO_CHANNEL_HH_
-
-#include <glib-unix.h>
-
-#include <exception.hh>
-
-#undef EXPORT_API
-#define EXPORT_API __attribute__((visibility("default")))
-
-namespace launchpad {
-
-class EXPORT_API IOChannel {
- public:
-  enum IOCondition {
-    IO_IN = G_IO_IN,
-    IO_OUT = G_IO_OUT,
-    IO_PRI = G_IO_PRI,
-    IO_ERR = G_IO_ERR,
-    IO_HUP = G_IO_HUP,
-    IO_NVAL = G_IO_NVAL,
-  };
-
-  class IEvent {
-   public:
-    virtual ~IEvent() = default;
-    virtual void OnIOEventReceived(int fd, int condition) = 0;
-  };
-
-  IOChannel(int fd, int condtion, IEvent* listener);
-  virtual ~IOChannel();
-
-  IOChannel(const IOChannel&) = delete;
-  IOChannel& operator = (const IOChannel&) = delete;
-
- private:
-  static gboolean UnixFdFunc(gint fd, GIOCondition condition,
-      gpointer user_data);
-
- private:
-  int fd_;
-  IEvent* listener_ = nullptr;
-  guint source_id_ = 0;
-};
-
-}  // namespace launchpad
-
-#endif  // LIB_LAUNCHPAD_GLIB_IO_CHANNEL_HH_
diff --git a/src/lib/launchpad-glib/language_config.cc b/src/lib/launchpad-glib/language_config.cc
deleted file mode 100644 (file)
index 030fb33..0000000
+++ /dev/null
@@ -1,48 +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-glib/language_config.hh"
-
-#include <stdlib.h>
-
-#include "launchpad-glib/log_private.hh"
-
-namespace launchpad {
-
-LanguageConfig::LanguageConfig() : vconf_(Vconf(VCONFKEY_LANGSET)) {
-  vconf_.Listen(this);
-
-  try {
-    lang_ = vconf_.Get<std::string>();
-    setenv("LANG", lang_.c_str(), 1);
-    _W("Language: %s", lang_.c_str());
-  } catch (const Exception& e) {
-    _E("Exception occurs. error: %s", e.what());
-  }
-}
-
-const std::string& LanguageConfig::Get() const {
-  return lang_;
-}
-
-void LanguageConfig::OnKeyChanged(const Vconf::KeyNode& node) {
-  lang_ = node.Get<std::string>();
-  setenv("LANG", lang_.c_str(), 1);
-  _W("Language: %s", lang_.c_str());
-}
-
-}  // namespace launchpad
-
diff --git a/src/lib/launchpad-glib/language_config.hh b/src/lib/launchpad-glib/language_config.hh
deleted file mode 100644 (file)
index e00ee65..0000000
+++ /dev/null
@@ -1,42 +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 LIB_LAUNCHPAD_GLIB_LANGUAGE_CONFIG_HH_
-#define LIB_LAUNCHPAD_GLIB_LANGUAGE_CONFIG_HH_
-
-#include <string>
-
-#include <vconf.hh>
-
-namespace launchpad {
-
-class LanguageConfig : public Vconf::IEvent {
- public:
-  LanguageConfig();
-
-  const std::string& Get() const;
-
- private:
-  void OnKeyChanged(const Vconf::KeyNode& node) override;
-
- private:
-  Vconf vconf_;
-  std::string lang_;
-};
-
-}  // namespace launchpad
-
-#endif  // LIB_LAUNCHPAD_GLIB_LANGUAGE_CONFIG_HH_
diff --git a/src/lib/launchpad-glib/log_private.hh b/src/lib/launchpad-glib/log_private.hh
deleted file mode 100644 (file)
index 0a26fc6..0000000
+++ /dev/null
@@ -1,37 +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 LIB_LAUNCHPAD_GLIB_LOG_PRIVATE_HH_
-#define LIB_LAUNCHPAD_GLIB_LOG_PRIVATE_HH_
-
-#include <dlog.h>
-
-#undef LOG_TAG
-#define LOG_TAG "LAUNCHPAD"
-
-#undef _E
-#define _E(fmt, ...) LOGE("[GLIB] " fmt, ##__VA_ARGS__)
-
-#undef _W
-#define _W(fmt, ...) LOGW("[GLIB] " fmt, ##__VA_ARGS__)
-
-#undef _I
-#define _I(fmt, ...) LOGI("[GLIB] " fmt, ##__VA_ARGS__)
-
-#undef _D
-#define _D(fmt, ...) LOGD("[GLIB] " fmt, ##__VA_ARGS__)
-
-#endif  // LIB_LAUNCHPAD_GLIB_LOG_PRIVATE_HH_
diff --git a/src/lib/launchpad-glib/pkgconfig/liblaunchpad-glib.pc.in b/src/lib/launchpad-glib/pkgconfig/liblaunchpad-glib.pc.in
deleted file mode 100644 (file)
index 5f27cae..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# Package Information for pkg-config
-
-prefix=/usr
-exec_prefix=@EXEC_PREFIX@
-libdir=@LIB_INSTALL_DIR@
-includedir=@INCLUDE_INSTALL_DIR@
-
-Name: liblaunchpad-glib
-Description: launchpad glib library
-Version: @VERSION@
-Requires: bundle dlog parcel launchpad-common
-Libs: -L${libdir} -llaunchpad-glib
-Cflags: -I${includedir} -I${includedir}/launchpad-glib
diff --git a/src/lib/launchpad-glib/plugin.cc b/src/lib/launchpad-glib/plugin.cc
deleted file mode 100644 (file)
index 5caa740..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.
- */
-
-#include "launchpad-glib/plugin.hh"
-
-#include <dlfcn.h>
-
-#include <filesystem>
-
-#include "launchpad-glib/log_private.hh"
-
-namespace fs = std::filesystem;
-
-namespace launchpad {
-namespace {
-
-constexpr const char kPathLaunchpadPlugin[] =
-    "/usr/share/aul/plugin/liblaunchpad-plugin.so";
-constexpr const char kTagLaunchpadPluginPrepareApp[] =
-    "LAUNCHPAD_PLUGIN_PREPARE_APP";
-
-}  // namespace
-
-int Plugin::PrepareApp(const std::string& appid, const tizen_base::Bundle& b) {
-  if (!fs::exists(kPathLaunchpadPlugin))
-    return 0;
-
-  void* handle = dlopen(kPathLaunchpadPlugin, RTLD_LAZY | RTLD_LOCAL);
-  if (handle == nullptr) {
-    _W("dlopen() is failed. path(%s), error(%s)",
-        kPathLaunchpadPlugin, dlerror());
-    return 0;
-  }
-
-  auto* prepare_app_func = reinterpret_cast<int(*)(const char*, bundle*)>(
-      dlsym(handle, kTagLaunchpadPluginPrepareApp));
-  if (prepare_app_func == nullptr) {
-    _W("dlsym() is failed. %s", kTagLaunchpadPluginPrepareApp);
-    dlclose(handle);
-    return 0;
-  }
-
-  _W("%s ++", kTagLaunchpadPluginPrepareApp);
-  int ret = prepare_app_func(appid.empty() ? nullptr : appid.c_str(),
-      b.GetHandle());
-  _W("%s --", kTagLaunchpadPluginPrepareApp);
-  return ret;
-}
-
-}  // namespace launchpad
diff --git a/src/lib/launchpad-glib/plugin.hh b/src/lib/launchpad-glib/plugin.hh
deleted file mode 100644 (file)
index 29fc215..0000000
+++ /dev/null
@@ -1,36 +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 LIB_LAUNCHPAD_GLIB_PLUGIN_HH_
-#define LIB_LAUNCHPAD_GLIB_PLUGIN_HH_
-
-#include <bundle_cpp.h>
-
-#include <string>
-
-#undef EXPORT_API
-#define EXPORT_API __attribute__((visibility("default")))
-
-namespace launchpad {
-
-class EXPORT_API Plugin {
- public:
-  static int PrepareApp(const std::string& appid, const tizen_base::Bundle& b);
-};
-
-}  // namespace launchpad
-
-#endif  // LIB_LAUNCHPAD_GLIB_PLUGIN_HH_
diff --git a/src/lib/launchpad-glib/region_format_config.cc b/src/lib/launchpad-glib/region_format_config.cc
deleted file mode 100644 (file)
index a084172..0000000
+++ /dev/null
@@ -1,49 +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-glib/region_format_config.hh"
-
-#include <stdlib.h>
-
-#include "launchpad-glib/log_private.hh"
-
-namespace launchpad {
-
-RegionFormatConfig::RegionFormatConfig()
-    : vconf_(Vconf(VCONFKEY_REGIONFORMAT)) {
-  vconf_.Listen(this);
-
-  try {
-    region_ = vconf_.Get<std::string>();
-    setenv("LC_CTYPE", region_.c_str(), 1);
-    _W("Region: %s", region_.c_str());
-  } catch (const Exception& e) {
-    _E("Exception occurs. error: %s", e.what());
-  }
-}
-
-const std::string& RegionFormatConfig::Get() const {
-  return region_;
-}
-
-void RegionFormatConfig::OnKeyChanged(const Vconf::KeyNode& node) {
-  region_ = node.Get<std::string>();
-  setenv("LC_CTYPE", region_.c_str(), 1);
-  _W("Region: %s", region_.c_str());
-}
-
-}  // namespace launchpad
-
diff --git a/src/lib/launchpad-glib/region_format_config.hh b/src/lib/launchpad-glib/region_format_config.hh
deleted file mode 100644 (file)
index 50b4e21..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 LIB_LAUNCHPAD_GLIB_REGION_FORMAT_CONFIG_HH_
-#define LIB_LAUNCHPAD_GLIB_REGION_FORMAT_CONFIG_HH_
-
-#include <string>
-
-#include <vconf.hh>
-
-#undef EXPORT_API
-#define EXPORT_API __attribute__((visibility("default")))
-
-namespace launchpad {
-
-class EXPORT_API RegionFormatConfig : public Vconf::IEvent {
- public:
-  RegionFormatConfig();
-
-  const std::string& Get() const;
-
- private:
-  void OnKeyChanged(const Vconf::KeyNode& node) override;
-
- private:
-  Vconf vconf_;
-  std::string region_;
-};
-
-}  // namespace launchpad
-
-#endif  // LIB_LAUNCHPAD_GLIB_REGION_FORMAT_CONFIG_HH_
diff --git a/src/lib/launchpad-glib/util.cc b/src/lib/launchpad-glib/util.cc
deleted file mode 100644 (file)
index 2f387f0..0000000
+++ /dev/null
@@ -1,657 +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-glib/util.hh"
-
-#include <bundle_internal.h>
-#include <dbus/dbus.h>
-#include <stdlib.h>
-#include <sys/mount.h>
-#include <sys/personality.h>
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <tzplatform_config.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <cctype>
-#include <filesystem>
-#include <fstream>
-#include <memory>
-#include <regex>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <aul_keys.hh>
-#include <exception.hh>
-#include <parcel.hh>
-#include <parcelable.hh>
-#include <server_socket.hh>
-#include <socket.hh>
-
-#include "launchpad-glib/log_private.hh"
-
-#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
-
-namespace fs = std::filesystem;
-
-namespace launchpad {
-namespace {
-
-constexpr const char kDefaultLocale[] = "en_US.UTF-8";
-constexpr const char kTepBusName[] = "org.tizen.system.deviced";
-constexpr const char kTepObjectPath[] = "/Org/Tizen/System/DeviceD/Tzip";
-constexpr const char kTepInterfaceName[] = "org.tizen.system.deviced.Tzip";
-constexpr const char kTepIsMountedMethod[] = "IsMounted";
-const int kMaxTepIsMountRetryCount = 100;
-constexpr const char kApp2sdBusName[] = "org.tizen.app2sd";
-constexpr const char kApp2sdObjectPath[] = "/org/tizen/app2sd";
-constexpr const char kApp2sdInterfaceName[] = "org.tizen.app2sd";
-constexpr const char kApp2sdOndemandSetupInitMethod[] = "OndemandSetupInit";
-const int kApp2sdRetryMax = 5;
-const int kApp2sdWaitUsec = 1000000 / 2;  // 0.5 sec
-
-int aul_listen_fd = -1;
-
-void SetLanguageEnvironments() {
-  const char* lang = getenv("LANG");
-  if (lang == nullptr) {
-    lang = kDefaultLocale;
-    setenv("LANG", lang, 1);
-  }
-
-  setenv("LANGUAGE", lang, 1);
-  setenv("LC_MESSAGES", lang, 1);
-  setenv("LC_ALL", lang, 1);
-}
-
-void SetRegionFormatEnvironments() {
-  const char* region = getenv("LC_CTYPE");
-  if (region == nullptr) {
-    region = kDefaultLocale;
-    setenv("LC_CTYPE", region, 1);
-  }
-
-  setenv("LC_NUMERIC", region, 1);
-  setenv("LC_TIME", region, 1);
-  setenv("LC_COLLATE", region, 1);
-  setenv("LC_MONETARY", region, 1);
-  setenv("LC_PAPER", region, 1);
-  setenv("LC_NAME", region, 1);
-  setenv("LC_ADDRESS", region, 1);
-  setenv("LC_TELEPHONE", region, 1);
-  setenv("LC_MEASUREMENT", region, 1);
-  setenv("LC_IDENTIFICATION", region, 1);
-}
-
-void SetGadgetPkgIdsEnvironments(const tizen_base::Bundle& b) {
-  auto gadget_pkgids = b.GetStringArray(kAulMountGadgetPkgIds);
-  if (gadget_pkgids.empty()) return;
-
-  std::string pkgids;
-  for (auto& pkgid : gadget_pkgids) {
-    if (!pkgids.empty()) pkgids += ":";
-
-    pkgids += pkgid;
-  }
-
-  setenv("GADGET_PKGIDS", pkgids.c_str(), 1);
-}
-
-#ifdef TIZEN_FEATURE_SET_PERSONALITY_32
-static void SetExecutionDomain() {
-  int ret = personality(PER_LINUX32);
-  if (ret < 0) {
-    char err_buf[1024];
-    _E("persionality() is failed. errno: %d(%s)",
-        errno, strerror_r(errno, err_buf, sizeof(err_buf)));
-  }
-}
-#endif  // TIZEN_FEATURE_SET_PERSONALITY_32
-
-class DBus {
- public:
-  DBus() {
-    DBusError error;
-    dbus_error_init(&error);
-    conn_ = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
-    if (conn_ == nullptr) {
-      _E("Failed to connect to D-Bus Daemon");
-      if (dbus_error_is_set(&error)) {
-        _E("D-Bus error: %s", error.message);
-        dbus_error_free(&error);
-      }
-      THROW(-ENOTCONN);
-    }
-  }
-
-  virtual ~DBus() {
-    if (conn_ != nullptr)
-      dbus_connection_close(conn_);
-  }
-
-  void SendMessage(DBusMessage* message, int timeout, int* result) {
-    if (message == nullptr) {
-      _E("Invalid parameter");
-      THROW(-EINVAL);
-    }
-
-    DBusPendingCall* pending = nullptr;
-    dbus_bool_t ret = dbus_connection_send_with_reply(conn_, message, &pending,
-        timeout);
-    if (!ret || pending == nullptr) {
-      _E("Failed to send message");
-      THROW(-EIO);
-    }
-
-    dbus_connection_flush(conn_);
-    dbus_pending_call_block(pending);
-    auto* reply = dbus_pending_call_steal_reply(pending);
-    dbus_pending_call_unref(pending);
-    if (reply == nullptr) {
-      _E("Failed to get reply message");
-      THROW(-EIO);
-    }
-
-    auto reply_auto =
-        std::unique_ptr<DBusMessage, decltype(dbus_message_unref)*>(
-            reply, dbus_message_unref);
-    DBusMessageIter iter;
-    if (!dbus_message_iter_init(reply, &iter)) {
-      _E("Message ha no argument");
-      THROW(-EIO);
-    }
-
-    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
-      _E("Argument is not interger. type(%d)",
-          dbus_message_iter_get_arg_type(&iter));
-      THROW(-EIO);
-    }
-
-    dbus_int32_t res;
-    dbus_message_iter_get_basic(&iter, &res);
-    *result = static_cast<int>(res);
-    _D("Result: %d", *result);
-  }
-
- private:
-  DBusConnection* conn_ = nullptr;
-};
-
-class TepMountChecker : public DBus {
- public:
-  explicit TepMountChecker(std::vector<std::string> paths)
-      : paths_(std::move(paths)) {}
-
-  bool IsMounted() {
-    for (auto& path : paths_) {
-      if (CheckTepMount(path) != 0)
-        return false;
-    }
-
-    return true;
-  }
-
- private:
-  DBusMessage* CreateTepMountMessage(const std::string& path) {
-    DBusMessage* message = dbus_message_new_method_call(kTepBusName,
-        kTepObjectPath, kTepInterfaceName, kTepIsMountedMethod);
-    if (message == nullptr) {
-      _E("dbus_message_new_method_call() is failed");
-      return nullptr;
-    }
-
-    DBusMessageIter iter;
-    dbus_message_iter_init_append(message, &iter);
-    auto* tep_path = path.c_str();
-    auto ret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
-        &tep_path);
-    if (!ret) {
-      _E("dbus_message_iter_append_basic() is failed");
-      dbus_message_unref(message);
-      return nullptr;
-    }
-
-    return message;
-  }
-
-  int IsTepMountDone(const std::string& path) {
-    int result = -1;
-    auto message = std::unique_ptr<DBusMessage, decltype(dbus_message_unref)*>(
-        CreateTepMountMessage(path), dbus_message_unref);
-    SendMessage(message.get(), 500, &result);
-    return result;
-  }
-
-  int CheckTepMount(const std::string& path) {
-    if (path.empty())
-      return 0;
-
-    int count = 0;
-    while (count < kMaxTepIsMountRetryCount) {
-      if (IsTepMountDone(path) == 1)
-        return 0;
-
-      usleep(50 * 1000);
-      count++;
-    }
-
-    _E("Not able to mount within 5 seconds. path(%s", path.c_str());
-    return -1;
-  }
-
- private:
-  std::vector<std::string> paths_;
-};
-
-int MountDirectories(const std::vector<std::string>& srcs,
-    const std::string& dest) {
-  if (access(dest.c_str(), F_OK) != 0) return 0;
-
-  std::string opt = "lowerdir=";
-  for (auto& src : srcs)
-    opt += src + ":";
-  opt += dest;
-
-  _D("mount opt: %s", opt.c_str());
-  int ret = mount(nullptr, dest.c_str(), "overlay", MS_RDONLY, opt.c_str());
-  if (ret != 0)
-    _E("mount() is failed. dest(%s), errno(%d)", dest.c_str(), errno);
-
-  return ret;
-}
-
-class ExternalPackage : public DBus {
- public:
-  ExternalPackage(std::string package, uid_t uid)
-      : package_(std::move(package)), uid_(uid) {
-    _D("package(%s), uid(%u)", package_.c_str(), uid_);
-  }
-
-  void Enable() {
-    int result = -1;
-    int retry_count = 0;
-    auto message = std::unique_ptr<DBusMessage, decltype(dbus_message_unref)*>(
-        CreateApp2sdMessage(), dbus_message_unref);
-    while (retry_count <= kApp2sdRetryMax) {
-      try {
-        SendMessage(message.get(), 500, &result);
-      } catch (const Exception& e) {
-        _E("Exception occurs. error(%s)", e.what());
-        retry_count++;
-        continue;
-      }
-
-      break;
-    }
-
-    _D("Result: %d", result);
-    if (result < 0)
-      THROW(-EIO);
-  }
-
- private:
-  DBusMessage* CreateApp2sdMessage() {
-    DBusMessage* message = dbus_message_new_method_call(kApp2sdBusName,
-        kApp2sdObjectPath, kApp2sdInterfaceName,
-        kApp2sdOndemandSetupInitMethod);
-    if (message == nullptr) {
-      _E("dbus_message_new_method_call() is failed");
-      return nullptr;
-    }
-
-    DBusMessageIter iter;
-    dbus_message_iter_init_append(message, &iter);
-    const char* package = package_.c_str();
-    if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &package)) {
-      _E("dbus_message_iter_append_basic() is failed");
-      dbus_message_unref(message);
-      return nullptr;
-    }
-
-    if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &uid_)) {
-      _E("dbus_message_iter_append_basic() is failed");
-      dbus_message_unref(message);
-      return nullptr;
-    }
-
-    return message;
-  }
-
- private:
-  std::string package_;
-  uid_t uid_;
-};
-
-class AmdPacket : public tizen_base::Parcelable {
- public:
-  explicit AmdPacket(int cmd, bundle* request, int opt)
-      : cmd_(cmd), request_(request), opt_(opt) {}
-
-  void WriteToParcel(tizen_base::Parcel* parcel) const {
-    parcel->WriteInt32(cmd_);
-    if (request_ == nullptr) {
-      parcel->WriteInt32(0);
-      parcel->WriteInt32(opt_);
-    } else {
-      bundle_raw* raw = nullptr;
-      int len = 0;
-      bundle_encode(request_, &raw, &len);
-      parcel->WriteInt32(len);
-      parcel->WriteInt32(opt_);
-      parcel->Write(reinterpret_cast<unsigned char*>(raw), len);
-      bundle_free_encoded_rawdata(&raw);
-    }
-  }
-
-  void ReadFromParcel(tizen_base::Parcel* parcel) {
-    parcel->ReadInt32(&cmd_);
-  }
-
- private:
-  int cmd_ = -1;
-  bundle* request_ = nullptr;
-  int opt_ = 0;
-};
-
-std::vector<std::string> ValidateAndModifyGadgetPaths(
-    const std::vector<std::string> gadget_paths) {
-  std::vector<std::string> paths;
-  for (const auto& path : gadget_paths) {
-    if (access(path.c_str(), F_OK) == 0)
-      paths.push_back(path);
-    else
-      paths.push_back(fs::path(path).parent_path().string());
-  }
-
-  return paths;
-}
-
-}  // namespace
-
-void Util::SetEnvironments(const AppInfo* app_info) {
-  auto& b = app_info->GetBundle();
-  auto value = b.GetString(kAulStarttime);
-  if (!value.empty())
-    setenv("APP_START_TIME", value.c_str(), 1);
-
-  if (!app_info->GetHwacc().empty())
-    setenv("HWACC", app_info->GetHwacc().c_str(), 1);
-
-  if (!app_info->GetTaskmanage().empty())
-    setenv("TASKMANAGE", app_info->GetTaskmanage().c_str(), 1);
-
-  if (!app_info->GetRootPath().empty())
-    setenv("AUL_ROOT_PATH", app_info->GetRootPath().c_str(), 1);
-
-  if (!app_info->GetAppId().empty()) {
-    auto multiple_instance_app_id = b.GetString(kAulMultipleInstanceAppId);
-    if (!multiple_instance_app_id.empty())
-      setenv("AUL_APPID", multiple_instance_app_id.c_str(), 1);
-    else
-      setenv("AUL_APPID", app_info->GetAppId().c_str(), 1);
-  }
-
-  if (!app_info->GetPkgId().empty())
-    setenv("AUL_PKGID", app_info->GetPkgId().c_str(), 1);
-
-  if (!app_info->GetAppType().empty())
-    setenv("RUNTIME_TYPE", app_info->GetAppType().c_str(), 1);
-
-  value = b.GetString(kAulWaylandDisplay);
-  if (!value.empty())
-    setenv("WAYLAND_DISPLAY", value.c_str(), 1);
-
-  value = b.GetString(kAulWaylandWorkingDir);
-  if (!value.empty())
-    setenv("XDG_RUNTIME_DIR", value.c_str(), 1);
-
-  value = b.GetString(kAulApiVersion);
-  if (!value.empty())
-    setenv("TIZEN_API_VERSION", value.c_str(), 1);
-
-  setenv("AUL_PID", std::to_string(getpid()).c_str(), 1);
-
-  if (getenv("TIZEN_GLIB_CONTEXT") == nullptr)
-    setenv("TIZEN_GLIB_CONTEXT", "0", 1);
-
-  value = b.GetString(kAulFastLaunch);
-  if (!value.empty())
-    setenv("AUL_FAST_LAUNCH", value.c_str(), 1);
-
-  SetLanguageEnvironments();
-  SetRegionFormatEnvironments();
-
-#ifdef TIZEN_FEATURE_SET_PERSONALITY_32
-  SetExecutionDomain();
-#endif  // TIZEN_FEATURE_SET_PERSONALITY_32
-
-  setenv("GCOV_PREFIX", "/tmp", 1);
-  setenv("DALI_DISABLE_PARTIAL_UPDATE", "0", 1);
-  SetGadgetPkgIdsEnvironments(b);
-}
-
-void Util::DeleteSocketPath(pid_t pid, uid_t uid) {
-  std::string path ="/run/aul/apps/" + std::to_string(uid) + "/" +
-      std::to_string(pid);
-  if (!fs::exists(path))
-    return;
-
-  try {
-    fs::remove_all(path);
-  } catch (const std::exception& e) {
-    _E("Exception occurs. error: %s", e.what());
-  }
-}
-
-int Util::EnableExternalPackage(const AppInfo* app_info) {
-  auto installed_storage = app_info->GetBundle().GetString(
-      kAulInstalledStorage);
-  if (installed_storage != "external")
-    return 0;
-
-  try {
-    ExternalPackage external_package(app_info->GetPkgId(),
-        app_info->IsGlobal() ? GLOBAL_USER : getuid());
-    external_package.Enable();
-  } catch (const Exception& e) {
-    _E("Exception occurs. error(%s)", e.what());
-    return -1;
-  }
-
-  return 0;
-}
-
-int Util::MountResourceDirectories(const AppInfo* app_info) {
-  auto& root_path = app_info->GetRootPath();
-  auto& b = app_info->GetBundle();
-  auto global_res_dir = b.GetStringArray(kAulMountGlobalResDir);
-  if (!global_res_dir.empty())
-    MountDirectories(global_res_dir, root_path + "/res/mount/global");
-
-  auto allowed_res_dir = b.GetStringArray(kAulMountAllowedResDir);
-  if (!allowed_res_dir.empty())
-    MountDirectories(allowed_res_dir, root_path + "/res/mount/allowed");
-
-  return 0;
-}
-
-int Util::MountLibraryDirectories(const tizen_base::Bundle& b) {
-  auto lib_dir = b.GetStringArray(kAulMountLibDir);
-  if (!lib_dir.empty()) {
-    auto root_path = b.GetString(kAulRootPath);
-    MountDirectories(lib_dir, root_path + "/lib/");
-  }
-
-  return 0;
-}
-
-int Util::MountGadgetDirectories(const tizen_base::Bundle& b) {
-  auto gadget_paths = b.GetStringArray(kAulMountGadgetPaths);
-  if (!gadget_paths.empty()) {
-    gadget_paths = ValidateAndModifyGadgetPaths(gadget_paths);
-    auto root_path = b.GetString(kAulRootPath);
-    return MountDirectories(gadget_paths, root_path + "/bin");
-  }
-
-  return 0;
-}
-
-int Util::WaitTepMount(const AppInfo* app_info) {
-  if (app_info->GetBundle().GetType(kAulTepPath) == BUNDLE_TYPE_NONE)
-    return 0;
-
-  try {
-    auto paths = app_info->GetBundle().GetStringArray(kAulTepPath);
-    TepMountChecker checker(std::move(paths));
-    if (!checker.IsMounted())
-      return -1;
-  } catch (const Exception& e) {
-    _E("Exception occurs. error(%s)", e.what());
-    return e.GetErrorCode();
-  }
-
-  _I("TEP Mount has been done");
-  return 0;
-}
-
-std::string Util::GetLibDirectory(const std::string& app_path) {
-  std::filesystem::path path(app_path);
-  auto lib_dir = path.parent_path().string() + "/../lib/";
-  if (access(lib_dir.c_str(), F_OK) == 0)
-    return lib_dir;
-
-  return "";
-}
-
-void Util::CloseAllFds(const std::vector<int>& except_fds) {
-  int aul_fd = aul_listen_fd;
-
-  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 (fd < 3 || fd == aul_fd)
-        continue;
-
-      auto found = std::find_if(except_fds.begin(), except_fds.end(),
-          [&](int except_fd) {
-            return except_fd == fd;
-          });
-      if (found != except_fds.end())
-        continue;
-
-      fds.push_back(fd);
-    }
-  } catch (const fs::filesystem_error& e) {
-    _E("Execption occurs. error(%s)", e.what());
-  }
-
-  for (auto fd : fds)
-    close(fd);
-}
-
-int Util::PrepareAppSocket() {
-  try {
-    std::string path = "/run/aul/apps/" + std::to_string(getuid()) + "/" +
-        std::to_string(getpid());
-    if (access(path.c_str(), F_OK) != 0) {
-      std::error_code ec;
-      if (!fs::create_directory(path, ec)) {
-        _E("Failed to create directory. path=%s, error_code=%d(%s)",
-            path.c_str(), ec.value(), ec.message().c_str());
-        return -1;
-      }
-    }
-
-    path += "/.app-sock";
-    ServerSocket socket;
-    socket.Bind(path);
-    socket.Listen(128);
-    socket.SetReceiveBufferSize(Socket::kSocketMaxBufferSize);
-    socket.SetSendBufferSize(Socket::kSocketMaxBufferSize);
-    socket.SetCloseOnExec(false);
-    aul_listen_fd = socket.RemoveFd();
-    setenv("AUL_LISTEN_FD", std::to_string(aul_listen_fd).c_str(), 1);
-  } catch (const Exception& e) {
-    _E("Exception occurs. error(%s)", e.what());
-    return e.GetErrorCode();
-  }
-
-  return 0;
-}
-
-int Util::PrepareAppIdFile(const AppInfo* app_info) {
-  std::string path = "/run/aul/apps/" + std::to_string(getuid()) + "/" +
-      std::to_string(getpid()) + "/" + app_info->GetAppId();
-  std::ofstream stream(path);
-  stream.close();
-  return 0;
-}
-
-int Util::SendCmdToAmd(enum AmdCmd cmd) {
-  return SendCmdToAmd(cmd, nullptr, static_cast<int>(AmdSocketOption::None));
-}
-
-int Util::SendCmdToAmd(enum AmdCmd cmd, bundle* request, int opt) {
-  try {
-    std::string endpoint = "/run/aul/daemons/.amd-sock";
-    ClientSocket socket;
-    socket.Connect(endpoint);
-    socket.SetReceiveBufferSize(Socket::kSocketMaxBufferSize);
-    socket.SetReceiveTimeout(5000);
-
-    AmdPacket packet(static_cast<int>(cmd), request, opt);
-    tizen_base::Parcel parcel;
-    parcel.WriteParcelable(packet);
-
-    int ret = socket.Send(parcel.GetData(), parcel.GetDataSize());
-    if (ret != 0) {
-      _E("Failed to send cmd(%d), error(%d)", static_cast<int>(cmd), ret);
-      return -ECOMM;
-    }
-  } catch (const Exception& e) {
-    _E("Exception occrus. error(%s)", e.what());
-    return e.GetErrorCode();
-  }
-
-  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
diff --git a/src/lib/launchpad-glib/util.hh b/src/lib/launchpad-glib/util.hh
deleted file mode 100644 (file)
index 5750c1f..0000000
+++ /dev/null
@@ -1,75 +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 LIB_LAUNCHPAD_GLIB_UTIL_HH_
-#define LIB_LAUNCHPAD_GLIB_UTIL_HH_
-
-#include <bundle.h>
-#include <sys/types.h>
-#include <tzplatform_config.h>
-
-#include <string>
-#include <vector>
-
-#include <app_info.hh>
-#include <types.hh>
-
-#undef EXPORT_API
-#define EXPORT_API __attribute__((visibility("default")))
-
-#undef GLOBAL_USER
-#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
-
-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);
-  static void DeleteSocketPath(pid_t pid, uid_t uid);
-  static int EnableExternalPackage(const AppInfo* app_info);
-  static int MountResourceDirectories(const AppInfo* app_info);
-  [[nodiscard]] static int MountGadgetDirectories(const tizen_base::Bundle& b);
-  static int WaitTepMount(const AppInfo* app_info);
-  static std::string GetLibDirectory(const std::string& app_path);
-  static void CloseAllFds(const std::vector<int>& except_fds = {});
-  static int PrepareAppSocket();
-  static int PrepareAppIdFile(const AppInfo* app_info);
-  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
-
-#endif  // LIB_LAUNCHPAD_GLIB_UTIL_HH_
diff --git a/src/lib/launchpad-glib/vconf.cc b/src/lib/launchpad-glib/vconf.cc
deleted file mode 100644 (file)
index 88320dc..0000000
+++ /dev/null
@@ -1,149 +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-glib/vconf.hh"
-
-#include <errno.h>
-
-#include <string>
-#include <type_traits>
-#include <utility>
-
-#include "launchpad-glib/log_private.hh"
-
-namespace launchpad {
-
-Vconf::KeyNode::KeyNode(keynode_t* node) : node_(node) {}
-
-std::string Vconf::KeyNode::GetName() const {
-  char* name = vconf_keynode_get_name(node_);
-  return std::string(name != nullptr ? name : "");
-}
-
-template <typename T>
-T Vconf::KeyNode::Get() const {
-  THROW(VCONF_ERROR_WRONG_TYPE);
-}
-
-template <>
-int Vconf::KeyNode::Get<int>() const {
-  return vconf_keynode_get_int(node_);
-}
-
-template <>
-double Vconf::KeyNode::Get<double>() const {
-  return vconf_keynode_get_dbl(node_);
-}
-
-template <>
-std::string Vconf::KeyNode::Get<std::string>() const {
-  char* str = vconf_keynode_get_str(node_);
-  return std::string(str != nullptr ? str : "");
-}
-
-template <>
-bool Vconf::KeyNode::Get<bool>() const {
-  return vconf_keynode_get_bool(node_) ? true : false;
-}
-
-Vconf::KeyNode::Type Vconf::KeyNode::GetType() const {
-  return static_cast < Vconf::KeyNode::Type>(vconf_keynode_get_type(node_));
-}
-
-Vconf::Vconf(std::string key)
-    : key_(std::move(key)) {}
-
-Vconf::~Vconf() {
-  Ignore();
-}
-
-template <typename T>
-T Vconf::Get() {
-  THROW(VCONF_ERROR_WRONG_TYPE);
-}
-
-template <>
-int Vconf::Get<int>() {
-  int result;
-  int ret = vconf_get_int(key_.c_str(), &result);
-  if (ret != VCONF_OK)
-    THROW(ret);
-
-  return result;
-}
-
-template <>
-double Vconf::Get<double>() {
-  double result;
-  int ret = vconf_get_dbl(key_.c_str(), &result);
-  if (ret != VCONF_OK)
-    THROW(ret);
-
-  return result;
-}
-
-template<>
-std::string Vconf::Get<std::string>() {
-  char* str = vconf_get_str(key_.c_str());
-  if (str == nullptr)
-    THROW(vconf_get_ext_errno());
-
-  std::string result(str);
-  std::free(str);
-  return result;
-}
-
-template<>
-bool Vconf::Get<bool>() {
-  int result;
-  int ret = vconf_get_bool(key_.c_str(), &result);
-  if (ret != VCONF_OK)
-    THROW(ret);
-
-  return result ? true : false;
-}
-
-void Vconf::Listen(IEvent* listener) {
-  if (listener == nullptr) {
-    _E("Invalid parameter");
-    THROW(-EINVAL);
-  }
-
-  bool listening = listener_ != nullptr ? true : false;
-  listener_ = listener;
-
-  if (!listening) {
-    int ret = vconf_notify_key_changed(key_.c_str(), VconfCb, this);
-    if (ret != VCONF_OK)
-      _E("vconf_notify_key_changed() is failed. key: %s", key_.c_str());
-  }
-}
-
-void Vconf::Ignore() {
-  if (listener_ != nullptr) {
-    vconf_ignore_key_changed(key_.c_str(), VconfCb);
-    listener_ = nullptr;
-  }
-}
-
-void Vconf::VconfCb(keynode_t* node, void* user_data) {
-  auto* vconf = static_cast<Vconf*>(user_data);
-  auto* listener = vconf->listener_;
-  if (listener != nullptr)
-    listener->OnKeyChanged(Vconf::KeyNode(node));
-}
-
-}  // namespace launchpad
diff --git a/src/lib/launchpad-glib/vconf.hh b/src/lib/launchpad-glib/vconf.hh
deleted file mode 100644 (file)
index 0242b2b..0000000
+++ /dev/null
@@ -1,86 +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 LIB_LAUNCHPAD_GLIB_VCONF_HH_
-#define LIB_LAUNCHPAD_GLIB_VCONF_HH_
-
-#include <vconf.h>
-
-#include <string>
-
-#include <exception.hh>
-
-#undef EXPORT_API
-#define EXPORT_API __attribute__((visibility("default")))
-
-namespace launchpad {
-
-class EXPORT_API Vconf {
- public:
-  class KeyNode {
-   public:
-    enum class Type {
-      None = VCONF_TYPE_NONE,
-      String = VCONF_TYPE_STRING,
-      Integer = VCONF_TYPE_INT,
-      Double = VCONF_TYPE_DOUBLE,
-      Boolean = VCONF_TYPE_BOOL,
-    };
-
-    explicit KeyNode(keynode_t* node);
-
-    std::string GetName() const;
-
-    template <typename T>
-    T Get() const;
-
-    Type GetType() const;
-
-   private:
-    keynode_t* node_;
-  };
-
-  class IEvent {
-   public:
-    virtual ~IEvent() = default;
-    virtual void OnKeyChanged(const KeyNode& node) = 0;
-  };
-
-  explicit Vconf(std::string key);
-  virtual ~Vconf();
-
-  Vconf(const Vconf& vconf) = delete;
-  Vconf& operator = (const Vconf& vconf) = delete;
-  Vconf(Vconf&& vconf) = delete;
-  Vconf& operator = (Vconf&& vconf) = delete;
-
-  template <typename T>
-  T Get();
-
-  void Listen(IEvent* listener);
-  void Ignore();
-
- private:
-  static void VconfCb(keynode_t* node, void* user_data);
-
- private:
-  std::string key_;
-  IEvent* listener_ = nullptr;
-};
-
-}  // namespace launchpad
-
-#endif  // LIB_LAUNCHPAD_GLIB_VCONF_HH_
index 87614995924efbe4bc74ce3b55c79c98d5b3372d..9bc5a5d028c849839589f57bae567f8ce0afc721 100644 (file)
@@ -28,7 +28,7 @@ APPLY_PKG_CONFIG(${TARGET_LAUNCHPAD} PUBLIC
 )
 
 TARGET_LINK_LIBRARIES(${TARGET_LAUNCHPAD} PUBLIC
-  ${TARGET_LAUNCHPAD_COMMON} ${TARGET_LAUNCHPAD_GLIB} "-ldl")
+  ${TARGET_LAUNCHPAD_COMMON} ${TARGET_LAUNCHPAD_CORE} "-ldl")
 
 INSTALL(TARGETS ${TARGET_LAUNCHPAD} DESTINATION ${LIB_INSTALL_DIR}
   COMPONENT RuntimeLibraries)
diff --git a/src/lux/Cargo.toml b/src/lux/Cargo.toml
new file mode 100644 (file)
index 0000000..134a6bd
--- /dev/null
@@ -0,0 +1,8 @@
+[package]
+name = "lux"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+glib-sys = "0.20.2"
+libc = "0.2.158"
diff --git a/src/lux/src/dlog_wrapper.rs b/src/lux/src/dlog_wrapper.rs
new file mode 100644 (file)
index 0000000..fbcd0dd
--- /dev/null
@@ -0,0 +1,54 @@
+macro_rules! DLOG_DEBUG {
+    () => {
+        3
+    };
+}
+macro_rules! DLOG_INFO {
+    () => {
+        4
+    };
+}
+macro_rules! DLOG_WARN {
+    () => {
+        5
+    };
+}
+macro_rules! DLOG_ERROR {
+    () => {
+        6
+    };
+}
+
+macro_rules! DLOG {
+    ($prio:expr, $($arg:tt)*) => {{
+        use std::ffi::c_int;
+
+        #[link(name = "dlog")]
+        extern "C" {
+            pub fn __dlog_print(
+                log_id: c_int,
+                ...
+            ) -> c_int;
+        }
+
+        fn f() {}
+        fn type_name_of<T>(_: T) -> &'static str {
+            std::any::type_name::<T>()
+        }
+        let prio = $prio;
+        let full_func_name = type_name_of(f).strip_suffix("::f").unwrap();
+        let func_name = &full_func_name[full_func_name.rfind("::").unwrap()+2..];
+        let file_path = std::path::PathBuf::from(file!());
+        let file_name = file_path.file_name().unwrap().to_str().unwrap();
+        let total_log = format!("{}: {}({}): {}\0", file_name, func_name, line!(), format_args!($($arg)*).to_string());
+        unsafe { __dlog_print(0, prio, "Lux\0".as_ptr(), total_log.as_ptr()); }
+    }}
+}
+
+macro_rules! debug { ($($arg:tt)*) => {{ DLOG!(DLOG_DEBUG!(), $($arg)*); }} }
+
+macro_rules! info { ($($arg:tt)*) => {{ DLOG!(DLOG_INFO!(), $($arg)*); }} }
+
+macro_rules! warn { ($($arg:tt)*) => {{ DLOG!(DLOG_WARN!(), $($arg)*); }} }
+
+macro_rules! error { ($($arg:tt)*) => {{ DLOG!(DLOG_ERROR!(), $($arg)*); }} }
diff --git a/src/lux/src/lux/app_labels_monitor.rs b/src/lux/src/lux/app_labels_monitor.rs
new file mode 100644 (file)
index 0000000..30d6fb2
--- /dev/null
@@ -0,0 +1,114 @@
+extern crate glib_sys;
+extern crate libc;
+extern crate tizen_parcel;
+
+use glib_sys::*;
+use libc::*;
+use std::mem;
+use tizen_parcel::*;
+use std::ptr;
+
+const SECURITY_MANAGER_SUCCESS: i32 = 0;
+
+#[link(name="security-manager-client")]
+extern "C" {
+  fn security_manager_app_labels_monitor_init(handle: *mut *mut c_void) -> c_int;
+  fn security_manager_app_labels_monitor_process(handle: *mut c_void) -> c_int;
+  fn security_manager_app_labels_monitor_get_fd(handle: *mut c_void, fd: *mut c_int) -> c_int;
+  fn security_manager_app_labels_monitor_finish(handle: *mut c_void) -> c_int;
+}
+
+pub struct AppLabelsMonitor {
+    handle: *mut c_void,
+    source_id: c_uint,
+    disposed: bool,
+}
+
+impl Drop for AppLabelsMonitor {
+    fn drop(&mut self) {
+        self.dispose();
+    }
+}
+
+extern "C" fn app_labels_monitor_callback(
+    fd: c_int,
+    cond: c_uint,
+    data: *mut c_void,
+) -> glib_sys::gboolean {
+    unsafe {
+        let handle: &mut AppLabelsMonitor = &mut *(data as *mut AppLabelsMonitor);
+        handle.process();
+        G_SOURCE_CONTINUE
+    }
+}
+
+impl AppLabelsMonitor {
+    pub fn new() -> Self {
+        AppLabelsMonitor { handle: ptr::null_mut(), source_id: 0, disposed: true }
+    }
+
+    pub fn init(&mut self) -> Result<(), ()> {
+        if !self.disposed {
+            return Ok(());
+        }
+
+        let mut fd: i32 = -1;
+        let ret = unsafe { security_manager_app_labels_monitor_init(&mut self.handle) };
+        if ret != SECURITY_MANAGER_SUCCESS {
+            error!("Failed to initialize app labels monitor. error={}", ret);
+            return Err(());
+        }
+
+        let ret = unsafe { security_manager_app_labels_monitor_process(self.handle) };
+        if ret != SECURITY_MANAGER_SUCCESS {
+            error!("Failed to process app labels monitor. error={}", ret);
+            unsafe { security_manager_app_labels_monitor_finish(self.handle) };
+            return Err(());
+        }
+
+        let mut fd: i32 = -1;
+        let ret = unsafe { security_manager_app_labels_monitor_get_fd(self.handle, &mut fd) };
+        if ret != SECURITY_MANAGER_SUCCESS {
+            error!("Failed to get file descriptor. error={}", ret);
+            unsafe { security_manager_app_labels_monitor_finish(self.handle) };
+            return Err(());
+        }
+
+        self.source_id = unsafe {
+            g_unix_fd_add(
+                fd,
+                G_IO_IN,
+                Some(app_labels_monitor_callback),
+                self as *mut _ as *mut c_void
+            )
+        };
+
+        self.disposed = false;
+        Ok(())
+    }
+
+    pub fn dispose(&mut self) {
+        if self.disposed {
+            return;
+        }
+
+        if self.source_id != 0 {
+            unsafe {
+                g_source_remove(self.source_id);
+                self.source_id = 0;
+            }
+        }
+
+        if !self.handle.is_null() {
+            unsafe {
+              security_manager_app_labels_monitor_finish(self.handle);
+              self.handle = ptr::null_mut();
+            }
+        }
+        self.disposed = true;
+    }
+
+    fn process(&mut self) {
+        unsafe { security_manager_app_labels_monitor_process(self.handle) };
+    }
+}
diff --git a/src/lux/src/lux/mod.rs b/src/lux/src/lux/mod.rs
new file mode 100644 (file)
index 0000000..8f2aa38
--- /dev/null
@@ -0,0 +1,217 @@
+extern crate glib_sys;
+extern crate libc;
+extern crate tizen_bundle;
+extern crate tizen_parcel;
+
+mod app_labels_monitor;
+mod sigchld_manager;
+
+use glib_sys::*;
+use libc::*;
+use std::mem;
+use tizen_bundle::*;
+use tizen_parcel::*;
+
+use self::app_labels_monitor::*;
+use self::sigchld_manager::*;
+
+const AUL_K_LUX_CMD: &str = "__AUL_LUX_CMD__";
+const LUX_CMD_EXECUTE_PROCESS_POOL: i32 = 0;
+const LUX_CMD_EXECUTE_APP: i32 = 1;
+const LUX_CMD_EXECUTE_LOADER: i32 = 2;
+
+#[link(name = "launchpad-core")]
+extern "C" {
+    fn launchpad_core_execute_app(request: *mut c_void);
+    fn launchpad_core_execute_process_pool(request: *mut c_void);
+    fn launchpad_core_execute_loader(request: *mut c_void);
+}
+
+#[link(name = "security-manager-client")]
+extern "C" {
+    fn security_manager_prepare_app_candidate() -> c_int;
+}
+
+pub struct Lux {
+    mainloop: *mut GMainLoop,
+    app_labels_monitor: AppLabelsMonitor,
+    sigchld_manager: SigchldManager,
+    read_fd: i32,
+    read_source_id: c_uint,
+    write_fd: i32,
+}
+
+extern "C" fn g_unix_fd_func(fd: c_int, cond: c_uint, data: *mut c_void) -> glib_sys::gboolean {
+    unsafe {
+        let handle: &mut Lux = &mut *(data as *mut Lux);
+        handle.handle_event_received();
+        G_SOURCE_CONTINUE
+    }
+}
+
+impl Drop for Lux {
+    fn drop(&mut self) {
+        if self.read_fd > -1 {
+            unsafe {
+                close(self.read_fd);
+                self.read_fd = -1;
+            }
+        }
+
+        if self.read_source_id != 0 {
+            unsafe {
+                g_source_remove(self.read_source_id);
+                self.read_source_id = 0;
+            }
+        }
+
+        if self.write_fd > -1 {
+            unsafe {
+                close(self.write_fd);
+                self.write_fd = -1;
+            }
+        }
+
+        if !self.mainloop.is_null() {
+            unsafe {
+                g_main_loop_unref(self.mainloop);
+                self.mainloop = std::ptr::null_mut() as *mut GMainLoop;
+            }
+        }
+    }
+}
+
+impl Lux {
+    pub fn new() -> Self {
+        Self {
+            mainloop: unsafe { g_main_loop_new(g_main_context_default(), false as gboolean) },
+            app_labels_monitor: AppLabelsMonitor::new(),
+            sigchld_manager: SigchldManager::new(),
+            read_fd: -1,
+            read_source_id: 0,
+            write_fd: -1,
+        }
+    }
+
+    pub fn run(&mut self, read_fd: i32, write_fd: i32, sigchld_fd: i32) -> Result<(), ()> {
+        self.read_fd = read_fd;
+        self.write_fd = write_fd;
+        self.sigchld_manager.init(sigchld_fd);
+        self.read_source_id = unsafe {
+            g_unix_fd_add(
+                self.read_fd,
+                G_IO_IN,
+                Some(g_unix_fd_func),
+                self as *mut _ as *mut c_void,
+            )
+        };
+        if self.read_source_id == 0 {
+            error!("g_unix_fd_add() is failed");
+            return Err(());
+        }
+
+        self.app_labels_monitor.init();
+        unsafe { g_main_loop_run(self.mainloop) }
+        self.app_labels_monitor.dispose();
+        Ok(())
+    }
+
+    pub fn quit(&mut self) {
+        if !self.mainloop.is_null() {
+            unsafe {
+                g_main_loop_quit(self.mainloop);
+            }
+        }
+    }
+
+    fn handle_event_received(&mut self) {
+        match self.read_parcel() {
+            Ok(mut parcel) => {
+                self.process_request(&mut parcel);
+            }
+            Err(_) => {
+                error!("Error occurs");
+            }
+        }
+    }
+
+    fn process_request(&mut self, parcel: &mut Parcel) {
+        let raw = parcel.read_string().unwrap();
+        let mut envelope = Bundle::decode(&raw).unwrap();
+        let pid = unsafe { fork() };
+        if pid == 0 {
+            unsafe { setsid() };
+            self.sigchld_manager.unblock();
+
+            let result = unsafe { security_manager_prepare_app_candidate() };
+            if result != 0 {
+                error!("Failed to prepare app candidate process. error={}", result);
+                std::process::exit(1);
+            }
+
+            let cmd_str = envelope.get_str(AUL_K_LUX_CMD).unwrap();
+            let cmd = cmd_str.parse().unwrap();
+            match cmd {
+                LUX_CMD_EXECUTE_PROCESS_POOL => unsafe {
+                    warn!("[EXECUTE_PROCESS_POOL]");
+                    launchpad_core_execute_process_pool(envelope.get_raw_handle())
+                },
+                LUX_CMD_EXECUTE_APP => unsafe {
+                    warn!("[EXECUTE_APP]");
+                    launchpad_core_execute_app(envelope.get_raw_handle())
+                },
+                LUX_CMD_EXECUTE_LOADER => unsafe {
+                    warn!("[EXECUTE_LOADER]");
+                    launchpad_core_execute_loader(envelope.get_raw_handle())
+                },
+                _ => panic!("Unexpected command {}", cmd),
+            }
+        } else {
+            self.write_result(pid as i32);
+            warn!("children process={}", pid);
+        }
+    }
+
+    fn read_parcel(&mut self) -> Result<Parcel, ()> {
+        let mut data_size: c_ulong = 0;
+        let nbytes = unsafe {
+            read(
+                self.read_fd,
+                (&mut data_size as *mut c_ulong).cast::<u8>() as *mut c_void,
+                mem::size_of::<c_ulong>(),
+            )
+        };
+        if nbytes <= 0 {
+            error!("Failed to read data size");
+            return Err(());
+        }
+
+        let mut data: Vec<u8> = vec![0; data_size as usize];
+        let nbytes = unsafe { read(self.read_fd, data.as_mut_ptr() as *mut _, data.len()) };
+        if nbytes <= 0 {
+            error!("Failed to read data");
+            return Err(());
+        }
+
+        let mut parcel = Parcel::new();
+        parcel.write(data.as_ref()).unwrap();
+        Ok(parcel)
+    }
+
+    fn write_result(&mut self, result: i32) -> Result<(), ()> {
+        let mut data: i32 = result;
+        let nbytes = unsafe {
+            write(
+                self.write_fd,
+                (&mut data as *mut c_int).cast::<u8>() as *mut c_void,
+                mem::size_of::<c_int>(),
+            )
+        };
+        if nbytes < 0 {
+            error!("Failed to write result");
+            return Err(());
+        }
+
+        Ok(())
+    }
+}
diff --git a/src/lux/src/lux/sigchld_manager.rs b/src/lux/src/lux/sigchld_manager.rs
new file mode 100644 (file)
index 0000000..41681a1
--- /dev/null
@@ -0,0 +1,164 @@
+extern crate glib_sys;
+extern crate libc;
+extern crate tizen_parcel;
+
+use glib_sys::*;
+use libc::*;
+use std::mem;
+use tizen_parcel::*;
+
+pub struct SigchldManager {
+    mask: sigset_t,
+    old_mask: sigset_t,
+    sfd: i32,
+    write_fd: i32,
+    source_id: c_uint,
+}
+
+impl Drop for SigchldManager {
+    fn drop(&mut self) {
+        self.unblock();
+        if self.sfd > -1 {
+            unsafe {
+                close(self.sfd);
+                self.sfd = -1;
+            }
+        }
+
+        if self.source_id != 0 {
+            unsafe {
+                g_source_remove(self.source_id);
+                self.source_id = 0;
+            }
+        }
+
+        if self.write_fd > -1 {
+            unsafe {
+                close(self.write_fd);
+                self.write_fd = -1;
+            }
+        }
+    }
+}
+
+extern "C" fn sigchld_event_callback(
+    fd: c_int,
+    cond: c_uint,
+    data: *mut c_void,
+) -> glib_sys::gboolean {
+    unsafe {
+        let handle: &mut SigchldManager = &mut *(data as *mut SigchldManager);
+        let mut info: signalfd_siginfo = std::mem::zeroed();
+        let mut status: c_int = 0;
+        let mut child_pid: pid_t;
+        let nbytes = read(
+            fd,
+            (&mut info as *mut signalfd_siginfo).cast::<u8>() as *mut c_void,
+            mem::size_of::<signalfd_siginfo>(),
+        );
+        if nbytes <= 0 {
+            error!("Failed to read signchld info");
+            return G_SOURCE_CONTINUE;
+        }
+
+        let child_pgid = getpgid(info.ssi_pid as i32);
+        loop {
+            child_pid = waitpid(-1, &mut status, WNOHANG);
+            if child_pid <= 0 {
+                break;
+            }
+
+            if child_pid == child_pgid {
+                killpg(child_pgid, SIGKILL);
+            }
+
+            handle.handle_sigchld(child_pid, status);
+        }
+
+        G_SOURCE_CONTINUE
+    }
+}
+
+impl SigchldManager {
+    pub fn new() -> Self {
+        unsafe {
+            let mut mask: sigset_t = std::mem::zeroed();
+            sigemptyset(&mut mask);
+            let mut old_mask: sigset_t = std::mem::zeroed();
+            sigemptyset(&mut old_mask);
+            SigchldManager { mask, old_mask, sfd: -1, write_fd: -1, source_id: 0 }
+        }
+    }
+
+    pub fn init(&mut self, write_fd: i32) {
+        self.block().unwrap();
+        self.write_fd = write_fd;
+        self.sfd = self.get_fd();
+        self.source_id = unsafe {
+            g_unix_fd_add(
+                self.sfd,
+                G_IO_IN,
+                Some(sigchld_event_callback),
+                self as *mut _ as *mut c_void
+            )
+        };
+    }
+
+    fn block(&mut self) -> Result<(), ()> {
+        let result = unsafe {
+            sigaddset(&mut self.mask, libc::SIGCHLD);
+            sigprocmask(SIG_BLOCK, &mut self.mask, &mut self.old_mask)
+        };
+        if result != 0 {
+            Err(())
+        } else {
+            Ok(())
+        }
+    }
+
+    pub fn unblock(&mut self) -> Result<(), ()> {
+        let result = unsafe { sigprocmask(SIG_SETMASK, &mut self.old_mask, std::ptr::null_mut()) };
+        if result != 0 {
+            Err(())
+        } else {
+            Ok(())
+        }
+    }
+
+    fn get_fd(&mut self) -> i32 {
+        let result = unsafe { signalfd(-1, &mut self.mask, SFD_NONBLOCK | SFD_CLOEXEC) };
+        result as i32
+    }
+
+    fn handle_sigchld(&mut self, pid: i32, status: i32) {
+        error!("pid={}, status={}", pid, status);
+        let mut parcel = Parcel::new();
+        parcel.write_i32(pid);
+        parcel.write_i32(status);
+        self.write_parcel(&mut parcel);
+    }
+
+    fn write_parcel(&mut self, parcel: &mut Parcel) -> Result<(), ()> {
+        let mut data = parcel.get_raw_data().unwrap();
+        let mut data_size: c_ulong = (data.len() as usize).try_into().unwrap();
+        let nbytes = unsafe {
+            write(
+                self.write_fd,
+                (&mut data_size as *mut c_ulong).cast::<u8>() as *mut c_void,
+                mem::size_of::<c_ulong>(),
+            )
+        };
+        if nbytes < 0 {
+            error!("Failed to write data size");
+            return Err(());
+        }
+
+        let nbytes = unsafe { write(self.write_fd, data.as_mut_ptr() as *mut _, data.len()) };
+        if nbytes < 0 {
+            error!("Failed to write data");
+            return Err(());
+        }
+
+        Ok(())
+    }
+}
diff --git a/src/lux/src/main.rs b/src/lux/src/main.rs
new file mode 100644 (file)
index 0000000..c360bf2
--- /dev/null
@@ -0,0 +1,35 @@
+extern crate glib_sys;
+extern crate libc;
+
+#[macro_use]
+mod dlog_wrapper;
+mod lux;
+
+use lux::*;
+use std::env;
+use std::vec::Vec;
+
+fn main() {
+    debug!("main");
+    let read_fd = env::var("LUX_READ_FD")
+        .ok()
+        .and_then(|fd| fd.parse::<i32>().ok())
+        .unwrap_or(-1);
+    let write_fd = env::var("LUX_WRITE_FD")
+        .ok()
+        .and_then(|fd| fd.parse::<i32>().ok())
+        .unwrap_or(-1);
+    let sigchld_fd = env::var("LUX_SIGCHLD_FD")
+        .ok()
+        .and_then(|fd| fd.parse::<i32>().ok())
+        .unwrap_or(-1);
+
+    if read_fd < 0 || write_fd < 0 || sigchld_fd < 0 {
+        print!("Failed to find read/write fds. {read_fd} : {write_fd} : {sigchld_fd}");
+        std::process::exit(-1);
+    }
+
+    debug!("read_fd={}, write_fd={}, sigchld_fd={}", read_fd, write_fd, sigchld_fd);
+    let mut lux = Lux::new();
+    lux.run(read_fd, write_fd, sigchld_fd);
+}
index 6c4a7994c06a35f300361496b30676acd09712bd..4cf769f1bab6ed0e2675548b9fbb0b7c1a649695 100644 (file)
@@ -22,7 +22,6 @@ TARGET_INCLUDE_DIRECTORIES(${TARGET_LAUNCHPAD_PROCESS_POOL_UNITTEST} PUBLIC
   ${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
 )
 
 APPLY_PKG_CONFIG(${TARGET_LAUNCHPAD_PROCESS_POOL_UNITTEST} PUBLIC
@@ -47,7 +46,6 @@ 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_CORE} ${TARGET_LAUNCHPAD_GLIB}
-  "-ldl")
+  ${TARGET_LAUNCHPAD_COMMON} ${TARGET_LAUNCHPAD_CORE} "-ldl")
 
 INSTALL(TARGETS ${TARGET_LAUNCHPAD_PROCESS_POOL_UNITTEST} DESTINATION /usr/bin/)
index 2de5f852c28d72f74eb40fc26e28a0a58628f123..36f92336a795baa51f16d795a30591c514a6d49a 100644 (file)
@@ -23,9 +23,9 @@
 #include <fstream>
 #include <string>
 
-#include "launchpad-core/debugger_info.hh"
-#include "launchpad-core/launcher_info.hh"
-#include "launchpad-core/loader_info.hh"
+#include "launchpad-process-pool/debugger_info.hh"
+#include "launchpad-process-pool/launcher_info.hh"
+#include "launchpad-process-pool/loader_info.hh"
 
 using ::testing::AtLeast;
 using namespace launchpad;