#include <bundle.h>
#include <bundle_cpp.h>
#include <bundle_internal.h>
+#include <glib.h>
#include <sys/types.h>
#include <cctype>
#include <utility>
#include <vector>
-#include "common/log_private.hh"
#include "lib/amd_app_property.h"
+#include "lib/amd_app_status.h"
+#include "lib/amd_config.h"
#include "lib/amd_cynara.h"
-#include "lib/request/request_manager.hh"
+#include "lib/amd_launch.h"
+#include "lib/amd_login_monitor.h"
+#include "lib/amd_noti.h"
#include "lib/amd_socket.h"
#include "lib/amd_util.h"
+#include "lib/app_info/app_info_manager.hh"
+#include "lib/app_property/app_property_manager.hh"
#include "lib/boot_sequencer/boot_sequencer.hh"
+#include "lib/common/display_state_manager.hh"
+#include "lib/common/log_private.hh"
+#include "lib/request/request_manager.hh"
namespace {
+
constexpr const char METADATA_KEY_ONBOOT_PRIORITY[] =
"http://tizen.org/metadata/on-boot/priority";
+const int kMinPriority = 1;
+const int kMaxPriority = 99;
+const guint kInterval = 500;
std::string GetTimestampString(const time_t& timestamp) {
if (timestamp == time_t {})
return 0;
}
+int GetPriority(amd::AppProperty* app_property, const std::string& appid) {
+ if (app_property == nullptr)
+ return kMinPriority;
+
+ auto tag = std::make_pair(appid, METADATA_KEY_ONBOOT_PRIORITY);
+ auto found = app_property->GetMetadataEntities().find(tag);
+ if (found == app_property->GetMetadataEntities().end())
+ return kMinPriority;
+
+ int priority = kMinPriority;
+ auto& entity = found->second;
+ const auto& value = entity->GetValue();
+ if (std::isdigit(value[0]))
+ priority = std::stoi(value);
+
+ if (priority < kMinPriority)
+ priority = kMinPriority;
+ if (priority > kMaxPriority)
+ priority = kMaxPriority;
+
+ return priority;
+}
+
+class OnBootAppInfo : public std::enable_shared_from_this<OnBootAppInfo> {
+ public:
+ OnBootAppInfo(uid_t uid, int priority, std::shared_ptr<amd::AppInfo> app_info)
+ : uid_(uid), priority_(priority), app_info_(std::move(app_info)) {}
+
+ uid_t GetUid() const { return uid_; }
+
+ int GetPriority() const { return priority_; }
+
+ const std::shared_ptr<amd::AppInfo>& GetAppInfo() const { return app_info_; }
+
+ void RefSelf() { self_ = shared_from_this(); }
+
+ void UnrefSelf() { self_.reset(); }
+
+ private:
+ uid_t uid_;
+ int priority_;
+ std::shared_ptr<amd::AppInfo> app_info_;
+ std::shared_ptr<OnBootAppInfo> self_;
+};
+
+std::list<std::shared_ptr<OnBootAppInfo>> GetOnBootAppInfos(uid_t uid) {
+ auto chunk = amd::AppInfoManager::GetInst().FindAppInfoChunk(uid);
+ if (chunk == nullptr) {
+ _E("Failed to find app info. uid(%u)", uid);
+ return {};
+ }
+
+ auto* app_property = amd::AppPropertyManager::GetInst().Find(uid);
+ if (app_property == nullptr)
+ _E("Failed to find app property. uid(%u)", uid);
+
+ std::list<std::shared_ptr<OnBootAppInfo>> infos;
+ for (auto& iter : chunk->GetAll()) {
+ auto& app_info = iter.second;
+ if (app_info->GetComponentType().compare(APP_TYPE_SERVICE) != 0 ||
+ app_info->GetOnboot() != "true")
+ continue;
+
+ auto app_status =
+ _app_status_find_by_appid(app_info->GetAppId().c_str(), uid);
+ if (_app_status_is_running(app_status) > 0)
+ continue;
+
+ int priority = GetPriority(app_property, app_info->GetAppId());
+ infos.push_back(std::make_shared<OnBootAppInfo>(uid, priority, app_info));
+ }
+
+ return infos;
+}
+
+gboolean StartOnBootAppsCb(gpointer user_data) {
+ auto* app_info = static_cast<OnBootAppInfo*>(user_data);
+ auto& appid = app_info->GetAppInfo()->GetAppId();
+ uid_t uid = app_info->GetUid();
+
+ auto app_status = _app_status_find_by_appid(appid.c_str(), uid);
+ pid_t pid = _app_status_is_running(app_status);
+ if (pid < 0)
+ pid = _launch_start_app_local(uid, appid.c_str());
+
+ _W("appid(%s), pid(%d), uid(%u)", appid.c_str(), pid, uid);
+ app_info->UnrefSelf();
+ return G_SOURCE_REMOVE;
+}
+
+int OnAppInfoInsert(const char* msg, int arg1, int arg2, void* arg3,
+ bundle* arg4) {
+ uid_t uid = static_cast<uid_t>(arg1);
+ if (_login_monitor_get_uid_state(uid) != UID_STATE_ACTIVE)
+ return NOTI_CONTINUE;
+
+ pkgmgrinfo_appinfo_h handle = static_cast<pkgmgrinfo_appinfo_h>(arg3);
+ char* appid;
+ if (pkgmgrinfo_appinfo_get_appid(handle, &appid) != PMINFO_R_OK) {
+ _E("pkgmgrinfo_appinfo_get_appid() is failed");
+ return NOTI_CONTINUE;
+ }
+
+ auto app_info = amd::AppInfoManager::GetInst().FindAppInfo(uid, appid);
+ if (app_info == nullptr) return NOTI_CONTINUE;
+
+ int ret = _launch_start_onboot_app_local(uid, appid, app_info.get());
+ _D("%s : %u : %d", appid, uid, ret);
+ return NOTI_CONTINUE;
+}
+
+int OnAppInfoAppEnabledEnd(const char* msg, int arg1, int arg2, void* arg3,
+ bundle* arg4) {
+ uid_t uid = static_cast<uid_t>(arg1);
+ if (_login_monitor_get_uid_state(uid) != UID_STATE_ACTIVE)
+ return NOTI_CONTINUE;
+
+ const char* appid = static_cast<char*>(arg3);
+ auto app_info = amd::AppInfoManager::GetInst().FindAppInfo(uid, appid);
+ if (app_info == nullptr) return NOTI_CONTINUE;
+
+ if (app_info->GetComponentType().compare(APP_TYPE_SERVICE) != 0 ||
+ app_info->GetOnboot() != "true")
+ return NOTI_CONTINUE;
+
+ int ret = _launch_start_onboot_app_local(uid, appid, app_info.get());
+ _D("%s : %u : %d", appid, uid, ret);
+ return NOTI_CONTINUE;
+}
+
+gboolean RegisterUnlockTimerCb(gpointer user_data) {
+ amd::DisplayStateManager::GetInst().RegisterUnlockTimer();
+ return G_SOURCE_REMOVE;
+}
+
} // namespace
int _boot_manager_start_onboot_apps(uid_t uid) {
- auto& sequencer = amd::boot_sequencer::BootSequencer::GetInst();
- sequencer.Load(uid);
- sequencer.Start(uid);
+ auto infos = GetOnBootAppInfos(uid);
+ if (infos.empty())
+ return 0;
+
+ auto& inst = amd::DisplayStateManager::GetInst();
+ if (inst.IsLocked())
+ inst.UnregisterUnlockTimer();
+ else
+ inst.Lock();
+
+ auto compare = [](std::shared_ptr<OnBootAppInfo> const& a,
+ std::shared_ptr<OnBootAppInfo> const& b) -> bool {
+ return a->GetPriority() > b->GetPriority();
+ };
+ infos.sort(compare);
+
+ guint delay_interval = 0;
+ guint idle_interval =
+ _config_get_onboot_max_interval() - _config_get_onboot_interval();
+ size_t max_size = idle_interval / _config_get_onboot_interval();
+ size_t size = infos.size();
+ if (size > max_size)
+ delay_interval = _config_get_onboot_interval() / (size - max_size);
+
+ guint index = 0;
+ guint interval = 0;
+ for (auto& info : infos) {
+ info->RefSelf();
+ if (interval >= idle_interval)
+ interval += delay_interval;
+ else
+ interval = _config_get_onboot_interval() * index++;
+
+ g_timeout_add(interval, StartOnBootAppsCb, static_cast<void*>(info.get()));
+ }
+ g_timeout_add(interval + kInterval, RegisterUnlockTimerCb, nullptr);
return 0;
}
int _boot_manager_init(void) {
_W("BOOT_MANAGER_INIT");
+ amd::boot_sequencer::BootSequencer::GetInst().Init();
if (_app_property_metadata_add_filter(
METADATA_KEY_ONBOOT_PRIORITY, nullptr) < 0) {
_E("Failed to add metadata filter");
if (_cynara_register_checkers(checkers, ARRAY_SIZE(checkers)) < 0)
return -1;
+ _noti_listen(AMD_NOTI_MSG_APPINFO_INSERT, OnAppInfoInsert);
+ _noti_listen(AMD_NOTI_MSG_APPINFO_APP_ENABLED_END, OnAppInfoAppEnabledEnd);
return 0;
}
void _boot_manager_fini(void) {
_W("BOOT_MANAGER_FINI");
+ amd::boot_sequencer::BootSequencer::GetInst().Dispose();
}
#include <glib.h>
#include <string.h>
-#include <iostream>
#include <fstream>
+#include <iostream>
#include "lib/amd_launch.h"
#include "lib/amd_noti.h"
#include "lib/amd_signal.h"
#include "lib/app_info/app_info_manager.hh"
#include "lib/app_status/app_status_manager.hh"
+#include "lib/common/display_state_manager.hh"
#include "lib/common/log_private.hh"
namespace amd::boot_sequencer {
constexpr const char TAG_INFO_PATH_EXISTS[] = "INFO:PATH_EXISTS";
constexpr const char TAG_INFO_TIMEOUT[] = "INFO:TIMEOUT";
-constexpr const char REQUIRED_API_VERSION[] = "7";
-
} // namespace
BootSequencer::BootSequencer() = default;
BootSequencer& BootSequencer::GetInst() {
static BootSequencer inst;
- if (inst.disposed_)
- inst.Init();
-
return inst;
}
_noti_listen(AMD_NOTI_MSG_APP_STATUS_SET_REAL_PID, OnAppStatusSetRealPid);
_noti_listen(AMD_NOTI_MSG_APP_STATUS_CLEANUP, OnAppStatusCleanup);
_noti_listen(AMD_NOTI_MSG_APP_STATUS_ADD, OnAppStatusAdd);
- _noti_listen(AMD_NOTI_MSG_APPINFO_INSERT, OnAppInfoInsert);
- _noti_listen(AMD_NOTI_MSG_APPINFO_APP_ENABLED_END, OnAppInfoAppEnabledEnd);
+ _noti_listen(AMD_NOTI_MSG_APPINFO_LOAD, OnAppInfoLoad);
_noti_listen(AMD_NOTI_MSG_APPINFO_REMOVE, OnAppInfoRemove);
disposed_ = false;
}
if (ret != AUL_ERROR_NONE)
_E("aul_boot_sequence_foreach_usr() is failed. error(%d)", ret);
- auto appinfo_chunk = AppInfoManager::GetInst().FindAppInfoChunk(uid);
- for (auto& [appid, app_info] : appinfo_chunk->GetAll()) {
- if (app_info->GetOnboot() == "true" && !Contains(appid, uid)) {
- _E("%s does not exists in db", appid.c_str());
- auto app_info = std::make_shared<AppInfo>(appid, uid);
- Insert(app_info, uid);
- QueuePush(std::move(app_info));
- }
- }
-
chunks_[uid]->RefineDependencies();
QueueSort();
}
if (ret != AUL_ERROR_NONE)
_E("aul_boot_sequence_foreach_usr() is failed. error(%d)", ret);
- auto appinfo_chunk = AppInfoManager::GetInst().FindAppInfoChunk(uid);
- for (auto& [appid, app_info] : appinfo_chunk->GetAll()) {
- if (app_info->GetOnboot() == "true" && !Contains(appid, uid)) {
- _E("%s does not exists in db", appid.c_str());
- auto app_info = std::make_shared<AppInfo>(appid, uid);
- Insert(app_info, uid);
- }
- }
-
chunks_[uid]->RefineDependencies();
}
if (source_ != 0)
return;
- _W("Lock display state");
- _signal_send_display_lock_state();
-
+ DisplayStateManager::GetInst().Lock();
source_ = g_timeout_add(100, OnRun, this);
}
gboolean BootSequencer::OnRun(gpointer user_data) {
auto& inst = BootSequencer::GetInst();
if (inst.QueueEmpty()) {
- _W("Unlock display state");
- _signal_send_display_unlock_state();
+ DisplayStateManager::GetInst().RegisterUnlockTimer();
inst.source_ = 0;
return G_SOURCE_REMOVE;
}
return NOTI_CONTINUE;
}
-void BootSequencer::StartLegacyOnbootApp(const char* appid, uid_t uid) {
- auto app_info = AppInfoManager::GetInst().FindAppInfo(uid, appid);
- if (app_info == nullptr)
- return;
-
- if (app_info->GetComponentType() != APP_TYPE_SERVICE ||
- app_info->GetOnboot() != "true")
- return;
-
- _D("%s : %u", appid, uid);
- if (strverscmp(REQUIRED_API_VERSION, app_info->GetApiVersion().c_str()) > 0) {
- int ret = _launch_start_onboot_app_local(uid, appid, app_info.get());
- _W("%s : %u : %d", appid, uid, ret);
- }
-}
-
-int BootSequencer::OnAppInfoInsert(const char* msg, int arg1, int arg2,
- void* arg3, bundle* arg4) {
- uid_t uid = static_cast<uid_t>(arg1);
- pkgmgrinfo_appinfo_h handle = static_cast<pkgmgrinfo_appinfo_h>(arg3);
- char* appid;
- if (pkgmgrinfo_appinfo_get_appid(handle, &appid) != PMINFO_R_OK) {
- _E("pkgmgrinfo_appinfo_get_appid() is failed");
- return NOTI_CONTINUE;
- }
-
- BootSequencer::StartLegacyOnbootApp(appid, uid);
- return NOTI_CONTINUE;
-}
-
-int BootSequencer::OnAppInfoAppEnabledEnd(const char* msg, int arg1, int arg2,
- void* arg3, bundle* arg4) {
+int BootSequencer::OnAppInfoLoad(const char* msg, int arg1, int arg2,
+ void* arg3, bundle* arg4) {
uid_t uid = static_cast<uid_t>(arg1);
- const char* appid = static_cast<char*>(arg3);
- BootSequencer::StartLegacyOnbootApp(appid, uid);
+ auto& inst = BootSequencer::GetInst();
+ inst.Load(uid);
+ inst.Start(uid);
return NOTI_CONTINUE;
}
void Load(uid_t uid);
void Reload(uid_t uid);
void Start(uid_t uid);
+ void Init();
void Dispose();
bool StartApp(uid_t uid, const std::string& appid);
std::shared_ptr<AppInfoChunk> GetBootSequenceApps(uid_t uid);
private:
BootSequencer();
~BootSequencer();
- void Init();
void Insert(std::shared_ptr<AppInfo> app_info, uid_t uid);
bool Contains(const std::string& appid, uid_t uid);
std::shared_ptr<AppInfo> Lookup(const std::string& appid, uid_t uid);
static gboolean OnRun(gpointer user_data);
static int OnAppStatusSetRealPid(const char* msg, int arg1, int arg2,
- void* arg3, bundle* arg4);
- static int OnAppStatusCleanup(const char* msg, int arg1, int arg2,
- void* arg3, bundle* arg4);
- static int OnAppStatusAdd(const char* msg, int arg1, int arg2,
- void* arg3, bundle* arg4);
- static void StartLegacyOnbootApp(const char* appid, uid_t uid);
- static int OnAppInfoInsert(const char* msg, int arg1, int arg2,
- void* arg3, bundle* arg4);
- static int OnAppInfoAppEnabledEnd(const char* msg, int arg1, int arg2,
- void* arg3, bundle* arg4);
- static int OnAppInfoRemove(const char* msg, int arg1, int arg2,
- void* arg3, bundle* arg4);
+ void* arg3, bundle* arg4);
+ static int OnAppStatusCleanup(const char* msg, int arg1, int arg2, void* arg3,
+ bundle* arg4);
+ static int OnAppStatusAdd(const char* msg, int arg1, int arg2, void* arg3,
+ bundle* arg4);
+ static int OnAppInfoLoad(const char* msg, int arg1, int arg2, void* arg3,
+ bundle* arg4);
+ static int OnAppInfoRemove(const char* msg, int arg1, int arg2, void* arg3,
+ bundle* arg4);
static int OnLaunchAppStartEnd(const char* msg, int arg1, int arg2,
- void* arg3, bundle* arg4);
+ void* arg3, bundle* arg4);
+
void PrintLog(const char* tag, const char* format, ...);
void PrintDependencies(const std::shared_ptr<AppInfo>& app_info);
--- /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 "lib/common/display_state_manager.hh"
+
+#include "lib/amd_signal.h"
+#include "lib/common/log_private.hh"
+
+namespace amd {
+
+DisplayStateManager& DisplayStateManager::GetInst() {
+ static DisplayStateManager inst;
+ return inst;
+}
+
+void DisplayStateManager::Lock() {
+ if (locked_)
+ return;
+
+ _W("Lock");
+ _signal_send_display_lock_state();
+ locked_ = true;
+}
+
+void DisplayStateManager::Unlock() {
+ if (!locked_)
+ return;
+
+ _W("Unlock");
+ _signal_send_display_unlock_state();
+ locked_ = false;
+}
+
+void DisplayStateManager::RegisterUnlockTimer() {
+ if (timer_!= 0)
+ return;
+
+ timer_ = g_timeout_add(
+ 5000, [](gpointer user_data) {
+ static_cast<DisplayStateManager*>(user_data)->Unlock();
+ return G_SOURCE_REMOVE;
+ }, this);
+}
+
+void DisplayStateManager::UnregisterUnlockTimer() {
+ if (timer_ == 0) return;
+
+ g_source_remove(timer_);
+ timer_ = 0;
+}
+
+bool DisplayStateManager::IsLocked() const {
+ return locked_;
+}
+
+DisplayStateManager::~DisplayStateManager() {
+ UnregisterUnlockTimer();
+ Unlock();
+}
+
+} // namespace amd
--- /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_COMMON_DISPLAY_STATE_MANAGER_HH_
+#define LIB_COMMON_DISPLAY_STATE_MANAGER_HH_
+
+#include <glib.h>
+
+namespace amd {
+
+class DisplayStateManager {
+ public:
+ static DisplayStateManager& GetInst();
+
+ DisplayStateManager(const DisplayStateManager&) = delete;
+ DisplayStateManager& operator=(const DisplayStateManager&) = delete;
+ DisplayStateManager(DisplayStateManager&&) = delete;
+ DisplayStateManager& operator=(DisplayStateManager&&) = delete;
+
+ void Lock();
+ void Unlock();
+ void RegisterUnlockTimer();
+ void UnregisterUnlockTimer();
+ bool IsLocked() const;
+
+ private:
+ DisplayStateManager() = default;
+ ~DisplayStateManager();
+
+ private:
+ bool locked_ = false;
+ guint timer_ = 0;
+};
+
+} // namespace amd
+
+#endif // LIB_COMMON_DISPLAY_STATE_MANAGER_HH_