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>
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/")
</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>
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
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
%define tizen_feature_prelink 0
%endif
+%global real_crate_name rust_lux
+%global rustc_edition 2021
+
%description
Launchpad for launching applications
.
%__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}
%install
rm -rf %{buildroot}
-
%make_install
mkdir -p %{buildroot}%{_userunitdir}/basic.target.wants
mkdir -p %{buildroot}%{_userunitdir}/sockets.target.wants
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
%{_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
)
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
)
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
${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)
}
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);
}
}
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);
}
#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 {
private:
void OnFileChanged(const std::string_view name,
- FileMonitor::Event event) override;
+ FileMonitor::Event event) override;
void UpdateLoaderInfo();
private:
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
#include <exception.hh>
-#include "launchpad-process-pool/log.hh"
#include "launchpad-process-pool/log_private.hh"
namespace launchpad {
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);
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) {
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;
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
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";
} // 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);
_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);
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) {
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_;
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
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 {
};
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();
const MemoryMonitor& GetMemoryMonitor() const;
const CPUChecker& GetCPUChecker() const;
const Logger& GetLogger() const;
+ const ProcessPool& GetProcessPool() const;
const LaunchMode& GetLaunchMode() const;
private:
MemoryMonitor memory_monitor_;
CPUChecker cpu_checker_;
Logger logger_;
+ ProcessPool process_pool_;
LaunchMode launch_mode_;
};
}
sum += value;
- if (i == 3)
- idle_value = value;
+ if (i == 3) idle_value = value;
}
*total = sum;
} // 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_) {
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
#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 {
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_; }
const std::string& GetSignalName() const { return signal_name_; }
GVariant* RemoveParam() {
- GVariant *param = param_;
+ GVariant* param = param_;
param_ = nullptr;
return param;
}
std::string path_;
std::string interface_;
std::string signal_name_;
- GVariant *param_ = nullptr;
+ GVariant* param_ = 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;
}
void Dispose() {
- if (disposed_)
- return;
+ if (disposed_) return;
if (getpid() == pid_) {
queue_->Push(std::make_shared<DBusMessage>(true));
}
void Init() {
- if (!disposed_)
- return;
+ if (!disposed_) return;
queue_ = new tizen_base::SharedQueue<std::shared_ptr<DBusMessage>>();
thread_ = std::thread([&]() -> void { WorkerThread(); });
~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);
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;
}
}
auto message = queue_->WaitAndPop();
- if (message->IsDone())
- break;
+ if (message->IsDone()) break;
EmitSignal(message);
}
} // 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) {
", 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
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(
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());
}
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) {
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;
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() {
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;
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;
SetPid(pid);
if (RefCount() > 0) {
CPUBoostController::DoBoost(pid, CPUBoostController::Level::Strong,
- 10000);
+ 10000);
}
}
}
#include <string>
-#include <sigchld_info.hh>
#include <peer_credentials.hh>
#include <procfs.hh>
+#include <sigchld_info.hh>
#include "launchpad-process-pool/log_private.hh"
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;
} // 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));
#include <memory>
-#include <server_socket.hh>
#include <io_channel.hh>
+#include <server_socket.hh>
namespace launchpad {
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
#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"
};
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");
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);
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 ||
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);
} // 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() {
#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());
DBus::Init();
LoaderManager::GetInst().AddDefaultLoaderContexts();
- LoaderManager::GetInst().SetEventListener(this);
launchpad::Debug::GetInst().Init();
Util::SendCmdToAmd(AmdCmd::LaunchpadLaunchSignal);
LoaderManager::GetInst().Dispose();
channel_.reset();
socket_.reset();
+ launchpad::LuxManager::GetInst().Dispose();
SignalManager::GetInst().Dispose();
}
}
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");
}
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]");
}
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();
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;
}
// 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();
}
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 {
}
} else {
auto context = loader_manager.FindLoaderContext(LoaderType::Dynamic,
- request->GetLoaderId());
+ request->GetLoaderId());
if (context != nullptr && CanUseLoaderContext(context))
request->SetAvailableLoaderContext(std::move(context));
}
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;
}
_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());
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) ||
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();
}
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) {
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());
}
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) {
}
}
-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()) {
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;
}
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()) {
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);
} // 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();
#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"
class Launchpad : public IOChannel::IEvent,
public SignalManager::IEvent,
- public LoaderManager::IEvent {
+ public LoaderManager::IEvent,
+ public LuxManager::IEvent {
public:
enum class LaunchResult : int {
Fail = -1,
~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();
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_;
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
#include <utility>
#include <exception.hh>
-#include <loader_executor.hh>
#include <peer_credentials.hh>
#include <procfs.hh>
#include <types.hh>
#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;
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());
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;
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);
}
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());
}
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_);
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;
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;
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;
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();
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();
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) {
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() {
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;
}
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());
}
_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;
}
}
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();
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:
}
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))
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);
}
}
}
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) {
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;
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();
}
}
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;
#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 {
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
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;
}
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;
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);
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;
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;
return std::shared_ptr<LoaderContext>(context);
}
-int LoaderFactory::MakeDynamicLoaderId() {
- return ++dynamic_loader_id_;
-}
+int LoaderFactory::MakeDynamicLoaderId() { return ++dynamic_loader_id_; }
} // namespace launchpad
#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 {
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
#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 {
}
void LoaderManager::Dispose() {
- if (disposed_)
- return;
+ if (disposed_) return;
loader_mount_.reset();
hwacc_config_.reset();
}
void LoaderManager::Init() {
- if (!disposed_)
- return;
+ if (!disposed_) return;
try {
sequencer_.reset(new Sequencer(this));
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();
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;
}
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();
}
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);
}
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());
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;
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());
}
}
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);
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;
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;
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) {
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;
}
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) {
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;
}
}
LoaderManager::LoaderManager() : sequencer_(new Sequencer(this)) {}
-LoaderManager::~LoaderManager() {
- Dispose();
-}
+LoaderManager::~LoaderManager() { Dispose(); }
void LoaderManager::OnAppLabelsChanged() {
_W("BEGIN");
}
} 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;
}
}
void LoaderManager::OnMemoryStatusChanged(bool low_memory,
- bool should_check_pss) {
+ bool should_check_pss) {
if (should_check_pss)
HandleMemoryStatusChangedEvent(low_memory);
else
}
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");
}
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();
}
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
#include <vector>
#include <app_info.hh>
-#include <loader_info.hh>
#include <hw_acceleration_config.hh>
#include "launchpad-process-pool/app_defined_loader_info_manager.hh"
#include "launchpad-process-pool/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"
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);
#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;
}
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;
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()))
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);
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);
parcel.Clear();
ret = Read(&parcel);
- if (ret!= 0) return ret;
+ if (ret != 0) return ret;
_W("receive result");
Reply reply(&parcel);
exit(ret);
}
-
int LoaderMount::CreatePipe(int (*pipe_fd)[2]) {
(*pipe_fd)[0] = -1;
(*pipe_fd)[1] = -1;
#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 {
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) {
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;
}
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);
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);
}
return;
}
- if (CreateLaunchpadDirectories() != 0)
- THROW(-EIO);
+ if (CreateLaunchpadDirectories() != 0) THROW(-EIO);
stream_.open(path_, std::ios::out | std::ios::app);
if (!stream_.is_open()) {
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");
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),
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;
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
interval_ = base_interval_;
}
-MemoryMonitor::~MemoryMonitor() {
- Dispose();
-}
+MemoryMonitor::~MemoryMonitor() { Dispose(); }
void MemoryMonitor::Dispose() {
- if (disposed_)
- return;
+ if (disposed_) return;
Stop();
disposed_ = true;
_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;
}
}
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;
}
void MemoryMonitor::Init() {
- if (!disposed_)
- return;
+ if (!disposed_) return;
Start();
disposed_ = false;
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();
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
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);
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();
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;
});
}
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() {
}
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;
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;
}
}
SigchldEvent::~SigchldEvent() {
- if (getpid() != current_pid_)
- socket_->RemoveFd();
+ if (getpid() != current_pid_) socket_->RemoveFd();
}
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);
}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
#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 {
_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();
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());
}
}
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 auto& entry : 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 auto& file : files) {
if (entry.path().filename().string().find(file) == 0) {
fs::remove(entry.path());
_W("Removed file: %s", entry.path().c_str());
}
}
- if (!found)
- continue;
+ if (!found) continue;
}
}
}
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();
}
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);
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));
}
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;
_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);
};
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 {
~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;
traceBegin(TTRACE_TAG_APPLICATION_MANAGER, message.data());
}
- ~Tracer() {
- traceEnd(TTRACE_TAG_APPLICATION_MANAGER);
- }
+ ~Tracer() { traceEnd(TTRACE_TAG_APPLICATION_MANAGER); }
};
} // namespace launchpad
}
}
-void Worker::Add(std::shared_ptr<Worker::Job >job) {
+void Worker::Add(std::shared_ptr<Worker::Job> job) {
queue_->Push(std::move(job));
}
while (true) {
auto job = queue_->WaitAndPop();
job->Do();
- if (job->IsDone())
- break;
+ if (job->IsDone()) break;
}
_W("END");
}
ADD_SUBDIRECTORY(launchpad)
ADD_SUBDIRECTORY(launchpad-common)
ADD_SUBDIRECTORY(launchpad-core)
-ADD_SUBDIRECTORY(launchpad-glib)
ADD_SUBDIRECTORY(launchpad-hydra)
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
Bundle = 0x8
};
+enum class LuxCmd : int {
+ ExecuteProcessPool,
+ ExecuteApp,
+ ExecuteLoader,
+};
+
} // namespace launchpad
#endif // LIB_LAUNCHPAD_COMMON_TYPES_HH_
BUNDLE_DEPS
DBUS_DEPS
DLOG_DEPS
+ DLOG_REDIRECT_STDOUT_DEPS
GIO_DEPS
LIBTZPLATFORM_CONFIG_DEPS
SECURITY_MANAGER_DEPS
)
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)
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
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
--- /dev/null
+/*
+ * 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));
+}
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
/*
- * 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.
* 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
+++ /dev/null
-/*
- * 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_
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_
+++ /dev/null
-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)
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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
-
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-# 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
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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
-
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
+++ /dev/null
-/*
- * 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
+++ /dev/null
-/*
- * 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_
)
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)
--- /dev/null
+[package]
+name = "lux"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+glib-sys = "0.20.2"
+libc = "0.2.158"
--- /dev/null
+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)*); }} }
--- /dev/null
+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) };
+ }
+}
--- /dev/null
+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(())
+ }
+}
--- /dev/null
+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(())
+ }
+}
--- /dev/null
+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);
+}
${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
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/)
#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;