Fix emulator service file issue 55/317355/4 accepted/tizen_unified_dev accepted/tizen_unified_toolchain accepted/tizen/9.0/unified/20241030.234516 accepted/tizen/unified/20240910.112408 accepted/tizen/unified/dev/20240913.055510 accepted/tizen/unified/toolchain/20241004.101416 accepted/tizen/unified/x/20240911.015701 accepted/tizen/unified/x/asan/20241013.235732 tizen_9.0_m2_release
authorYoungHun Kim <yh8004.kim@samsung.com>
Mon, 9 Sep 2024 08:44:08 +0000 (17:44 +0900)
committerYoungHun Kim <yh8004.kim@samsung.com>
Mon, 9 Sep 2024 08:52:58 +0000 (17:52 +0900)
 - Add systemd-tmpfiles-setup.service dependency
 - Remove CRLF
 - Update spec file using %{name}

Change-Id: Ic12cf9d39958c0dc2048a0149890f76fcd10b6d6

13 files changed:
packaging/rscmgr-msgq.service
packaging/rscmgr-service.spec
src/manager/CCache.cpp
src/manager/CConsumer.cpp
src/manager/CConsumerContainer.cpp
src/manager/CDebugUtils.cpp
src/manager/CLockController.cpp
src/manager/CPriority.cpp
src/manager/CResource.cpp
src/manager/CResourceCategory.cpp
src/manager/CResourceDB.cpp
src/manager/CVideoController.cpp
src/manager/CVirtualResource.cpp

index 22ac4345f00beff04f9666ef667374f715165568..b2cfdd7880d7d3ea96dd5d0beef6225228fe4a6f 100644 (file)
@@ -1,6 +1,6 @@
 [Unit]
 Description=Generate RM Message Queue
-DefaultDependencies=no
+After=systemd-tmpfiles-setup.service
 
 [Service]
 Type=oneshot
index e275779d631866a461a46f65f3999b6de9ef6ba4..7fe386e48f1441d9583feeb46080d4d151d8ecc6 100644 (file)
@@ -1,7 +1,7 @@
 Name: rscmgr-service
 Summary: Daemon for resource manager
 Version: 0.1
-Release: 10
+Release: 11
 Group:   Multimedia/Libraries
 License: Apache-2.0
 Source0: %{name}-%{version}.tar.gz
@@ -81,7 +81,7 @@ cp %SOURCE4 %{buildroot}%{_sysconfdir}/dbus-1/system.d
 rm -rf %{buildroot}
 
 %files
-%manifest rscmgr-service.manifest
+%manifest %{name}.manifest
 %license LICENSE.APLv2
 %{TZ_SYS_BIN}/gen_rm_msgq
 %{TZ_SYS_BIN}/%{name}
index adde21f51e118bf219456d30b73e82d3f12013d1..7d8efbe2e70221c6f54fee9b36831b12742ff41e 100644 (file)
@@ -1,45 +1,45 @@
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <CCache.h>\r
-\r
-CCache *CCache::m_instance = NULL;\r
-\r
-CCache *CCache::getInstance(void)\r
-{\r
-       if (!m_instance) {\r
-               m_instance = new(std::nothrow) CCache;\r
-       }\r
-\r
-       return m_instance;\r
-}\r
-\r
-void CCache::SetAppStatus(std::string app_id, int status)\r
-{\r
-       m_visibility.insert(std::pair<std::string, int>(app_id, status));\r
-}\r
-\r
-int CCache::GetAppStatus(std::string app_id)\r
-{\r
-       auto it = m_visibility.find(app_id);\r
-\r
-       return (it == m_visibility.end()) ? -1 : it->second;\r
-}\r
-\r
-void CCache::Drop(void)\r
-{\r
-       m_visibility.clear();\r
-}\r
+/*
+ * 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 <CCache.h>
+
+CCache *CCache::m_instance = NULL;
+
+CCache *CCache::getInstance(void)
+{
+       if (!m_instance) {
+               m_instance = new(std::nothrow) CCache;
+       }
+
+       return m_instance;
+}
+
+void CCache::SetAppStatus(std::string app_id, int status)
+{
+       m_visibility.insert(std::pair<std::string, int>(app_id, status));
+}
+
+int CCache::GetAppStatus(std::string app_id)
+{
+       auto it = m_visibility.find(app_id);
+
+       return (it == m_visibility.end()) ? -1 : it->second;
+}
+
+void CCache::Drop(void)
+{
+       m_visibility.clear();
+}
index 12bac796fb9477ef0c9deedc7db4033c125ffdf3..9585e46ebcc4ae4fca0ee7251e7a508b34755498 100644 (file)
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <trace.h>\r
-#include <stdlib.h>\r
-#include <iostream>\r
-#include <vconf.h>\r
-#include <aul.h>\r
-#include <system_info.h>\r
-#include <unistd.h>\r
-\r
-#include <rms_debug.h>\r
-#include <rms_type.h>\r
-#include <CConsumer.h>\r
-#include <CDebugUtils.h>\r
-#include <CCache.h>\r
-\r
-CConsumer::CConsumer(IN const rms_consumer_s *consumer)\r
-{\r
-       m_consumerID = consumer->consumer_id;\r
-       m_priority = consumer->priority;\r
-       m_pid = consumer->process_id;\r
-       m_app_id.assign(consumer->app_id);\r
-\r
-       SetCmdName(m_pid);\r
-}\r
-\r
-void CConsumer::SetCmdName(long pid)\r
-{\r
-       char cmd_name[RMS_NAME_BUF_SIZE] = {0, };\r
-       std::string delimiter = "/";\r
-\r
-       rms_get_cmd_name(m_pid, cmd_name, RMS_NAME_BUF_SIZE);\r
-       m_cmd_name.assign(cmd_name);\r
-       SERVER_WARN("pid %ld cmd name %s", m_pid, cmd_name);\r
-       m_cmd_name = m_cmd_name.substr(m_cmd_name.find_last_of(delimiter) + 1, m_cmd_name.length());\r
-       SERVER_WARN("m_cmd_name %s", m_cmd_name.c_str());\r
-}\r
-\r
-bool CConsumer::AddResource(IN int device_id)\r
-{\r
-       if (IsUsingResource(device_id)) {\r
-               SERVER_INFO("already registered device id(%d) in Consumer(%d)", device_id, m_consumerID);\r
-               return false;\r
-       }\r
-\r
-       m_resources.insert(device_id);\r
-       return true;\r
-}\r
-\r
-int CConsumer::ReleaseResource(IN int device_id)\r
-{\r
-       if (!IsUsingResource(device_id)) {\r
-               SERVER_WARN("CID[%d] / DevID[%d] the consumer does not use this device", m_consumerID, device_id);\r
-               return RMS_ERROR;\r
-       }\r
-\r
-       m_resources.erase(device_id);\r
-\r
-       return RMS_OK;\r
-}\r
-\r
-bool CConsumer::IsUsingResource(IN int device_id)\r
-{\r
-       auto it = m_resources.find(device_id);\r
-\r
-       return (it != m_resources.end());\r
-}\r
-\r
-void CConsumer::SetAppID(IN const char *app_id)\r
-{\r
-       m_app_id.assign(app_id);\r
-}\r
-\r
-std::string CConsumer::GetAppId(int pid)\r
-{\r
-       char app_id[RMS_NAME_BUF_SIZE] ={0, };\r
-       std::string result;\r
-\r
-       if (aul_app_get_appid_bypid(pid, app_id, sizeof(app_id)) != AUL_R_OK) {\r
-               SERVER_ERR("failed to get appid of %d", pid);\r
-               return result;\r
-       }\r
-\r
-       result.assign(app_id);\r
-\r
-       return result;\r
-}\r
-\r
-rms_error_type_e CConsumer::ComparePriority(CConsumer *requester)\r
-{\r
-       std::string app_id = requester->GetAppID();\r
-\r
-       m_app_id = (m_app_id.empty()) ? GetAppId((int) m_pid) : m_app_id;\r
-\r
-       if (!CheckVisibility(app_id)) {\r
-               SERVER_ERR("The application is not visible. cannot take resource");\r
-               return RMS_ERR_TYPE_REQUEST_OF_INVISIBLE_PROCESS;\r
-       }\r
-\r
-       rms_priority_s requester_priority = requester->GetPriority();\r
-\r
-       if (!ComparePriority(requester_priority, m_priority)) {\r
-               char cmd[RMS_NAME_BUF_SIZE] = {0,};\r
-               rms_get_cmd_name(m_pid, cmd, sizeof(cmd));\r
-               SERVER_ERR("rqs_priority(%d/%d) - user_priority(%s-%d/%d)", requester_priority.main, requester_priority.sub, cmd, m_priority.main, m_priority.sub);\r
-               return RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;\r
-       }\r
-\r
-       return RMS_ERR_TYPE_NONE;\r
-}\r
-\r
-bool CConsumer::ComparePriority(IN rms_priority_s priority1, IN rms_priority_s priority2)\r
-{\r
-       if (priority1.main > priority2.main) {\r
-               return true;\r
-       } else if (priority1.main == priority2.main) {\r
-               return priority1.sub >= priority2.sub;\r
-       } else {\r
-               return false;\r
-       }\r
-}\r
-\r
-bool CConsumer::CheckVisibility(IN std::string app_id_requester)\r
-{\r
-       if (app_id_requester.empty()) {\r
-               SERVER_INFO("requester app id : (null)");\r
-               return true;\r
-       }\r
-\r
-       bool visibility_consumer = (m_app_id.empty()) ? true : GetAppVisibility(m_app_id, false);\r
-       bool visibility_requester = GetAppVisibility(app_id_requester, true);\r
-\r
-       if (visibility_requester) {\r
-               SERVER_INFO("requester is visible(%s)", app_id_requester.c_str());\r
-               return true;\r
-       }\r
-\r
-       if (!visibility_consumer) {\r
-               SERVER_INFO("current consumer(%d) is invisible(%s)", m_consumerID, m_app_id.c_str());\r
-               return true;\r
-       }\r
-\r
-       SERVER_ERR("current consumer(%s)- visibility:(%d)", (m_app_id.empty()) ? "null" : m_app_id.c_str(), visibility_consumer);\r
-       SERVER_ERR("requester(%s)- visibility:(%d)", app_id_requester.c_str(), visibility_requester);\r
-\r
-       return false;\r
-}\r
-\r
-int CConsumer::UpdateAppStatus(std::string app_id)\r
-{\r
-       char buf[RMS_NAME_BUF_SIZE];\r
-       int status;\r
-       int n_max = 4;\r
-       snprintf(buf, RMS_NAME_BUF_SIZE, "Get visibility of application '%s'", app_id.c_str());\r
-\r
-       for (int i = 0; i < n_max; i++) {\r
-               usleep(50*1000);\r
-\r
-               trace_begin(buf);\r
-               status = aul_app_get_status(app_id.c_str());\r
-               trace_end();\r
-               SERVER_INFO("app(%s) / status(%d) / (%d)", app_id.c_str(), status, i);\r
-\r
-               if (IsVisibleStatus(status)) {\r
-                       SERVER_ERR("status %d", status);\r
-                       return status;\r
-               }\r
-       }\r
-       return status;\r
-}\r
-\r
-bool CConsumer::NeedStatusUpdate(std::string app_id)\r
-{\r
-       return false;\r
-}\r
-\r
-bool CConsumer::IsVisibleStatus(int status)\r
-{\r
-       return (status == STATUS_FOCUS || status == STATUS_VISIBLE);\r
-}\r
-\r
-bool CConsumer::GetAppVisibility(std::string app_id, bool requester)\r
-{\r
-       CCache *cache = CCache::getInstance();\r
-       int status = cache->GetAppStatus(app_id);\r
-\r
-       if (status == -1) {\r
-               status = aul_app_get_status(app_id.c_str());\r
-\r
-               if (!IsVisibleStatus(status) && requester && NeedStatusUpdate(app_id))\r
-                       status = UpdateAppStatus(app_id);\r
-\r
-               cache->SetAppStatus(app_id, status);\r
-       }\r
-\r
-       return IsVisibleStatus(status);\r
-}\r
-\r
-bool CConsumer::CheckWebAppState(IN std::string app_id_requesting)\r
-{\r
-       if (app_id_requesting.length() == 0)\r
-               return false;\r
-\r
-       std::string webapp_vconf_key = std::string("rtc/memory/WebApp/") + app_id_requesting;\r
-\r
-       char *status = vconf_get_str(webapp_vconf_key.c_str());\r
-       if (!status) {\r
-               SERVER_INFO("%s is not webapp", app_id_requesting.c_str());\r
-               return false;\r
-       }\r
-\r
-       std::string webapp_status(status);\r
-       if (webapp_status.compare("resume")) {\r
-               SERVER_INFO("%s is not in resume status (%s)", app_id_requesting.c_str(), webapp_status.c_str());\r
-               free(status);\r
-               return false;\r
-       }\r
-\r
-       SERVER_INFO("%s is in resume status (%s)", app_id_requesting.c_str(), webapp_status.c_str());\r
-       free(status);\r
-\r
-       return true;\r
-}\r
+/*
+ * 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 <trace.h>
+#include <stdlib.h>
+#include <iostream>
+#include <vconf.h>
+#include <aul.h>
+#include <system_info.h>
+#include <unistd.h>
+
+#include <rms_debug.h>
+#include <rms_type.h>
+#include <CConsumer.h>
+#include <CDebugUtils.h>
+#include <CCache.h>
+
+CConsumer::CConsumer(IN const rms_consumer_s *consumer)
+{
+       m_consumerID = consumer->consumer_id;
+       m_priority = consumer->priority;
+       m_pid = consumer->process_id;
+       m_app_id.assign(consumer->app_id);
+
+       SetCmdName(m_pid);
+}
+
+void CConsumer::SetCmdName(long pid)
+{
+       char cmd_name[RMS_NAME_BUF_SIZE] = {0, };
+       std::string delimiter = "/";
+
+       rms_get_cmd_name(m_pid, cmd_name, RMS_NAME_BUF_SIZE);
+       m_cmd_name.assign(cmd_name);
+       SERVER_WARN("pid %ld cmd name %s", m_pid, cmd_name);
+       m_cmd_name = m_cmd_name.substr(m_cmd_name.find_last_of(delimiter) + 1, m_cmd_name.length());
+       SERVER_WARN("m_cmd_name %s", m_cmd_name.c_str());
+}
+
+bool CConsumer::AddResource(IN int device_id)
+{
+       if (IsUsingResource(device_id)) {
+               SERVER_INFO("already registered device id(%d) in Consumer(%d)", device_id, m_consumerID);
+               return false;
+       }
+
+       m_resources.insert(device_id);
+       return true;
+}
+
+int CConsumer::ReleaseResource(IN int device_id)
+{
+       if (!IsUsingResource(device_id)) {
+               SERVER_WARN("CID[%d] / DevID[%d] the consumer does not use this device", m_consumerID, device_id);
+               return RMS_ERROR;
+       }
+
+       m_resources.erase(device_id);
+
+       return RMS_OK;
+}
+
+bool CConsumer::IsUsingResource(IN int device_id)
+{
+       auto it = m_resources.find(device_id);
+
+       return (it != m_resources.end());
+}
+
+void CConsumer::SetAppID(IN const char *app_id)
+{
+       m_app_id.assign(app_id);
+}
+
+std::string CConsumer::GetAppId(int pid)
+{
+       char app_id[RMS_NAME_BUF_SIZE] ={0, };
+       std::string result;
+
+       if (aul_app_get_appid_bypid(pid, app_id, sizeof(app_id)) != AUL_R_OK) {
+               SERVER_ERR("failed to get appid of %d", pid);
+               return result;
+       }
+
+       result.assign(app_id);
+
+       return result;
+}
+
+rms_error_type_e CConsumer::ComparePriority(CConsumer *requester)
+{
+       std::string app_id = requester->GetAppID();
+
+       m_app_id = (m_app_id.empty()) ? GetAppId((int) m_pid) : m_app_id;
+
+       if (!CheckVisibility(app_id)) {
+               SERVER_ERR("The application is not visible. cannot take resource");
+               return RMS_ERR_TYPE_REQUEST_OF_INVISIBLE_PROCESS;
+       }
+
+       rms_priority_s requester_priority = requester->GetPriority();
+
+       if (!ComparePriority(requester_priority, m_priority)) {
+               char cmd[RMS_NAME_BUF_SIZE] = {0,};
+               rms_get_cmd_name(m_pid, cmd, sizeof(cmd));
+               SERVER_ERR("rqs_priority(%d/%d) - user_priority(%s-%d/%d)", requester_priority.main, requester_priority.sub, cmd, m_priority.main, m_priority.sub);
+               return RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS;
+       }
+
+       return RMS_ERR_TYPE_NONE;
+}
+
+bool CConsumer::ComparePriority(IN rms_priority_s priority1, IN rms_priority_s priority2)
+{
+       if (priority1.main > priority2.main) {
+               return true;
+       } else if (priority1.main == priority2.main) {
+               return priority1.sub >= priority2.sub;
+       } else {
+               return false;
+       }
+}
+
+bool CConsumer::CheckVisibility(IN std::string app_id_requester)
+{
+       if (app_id_requester.empty()) {
+               SERVER_INFO("requester app id : (null)");
+               return true;
+       }
+
+       bool visibility_consumer = (m_app_id.empty()) ? true : GetAppVisibility(m_app_id, false);
+       bool visibility_requester = GetAppVisibility(app_id_requester, true);
+
+       if (visibility_requester) {
+               SERVER_INFO("requester is visible(%s)", app_id_requester.c_str());
+               return true;
+       }
+
+       if (!visibility_consumer) {
+               SERVER_INFO("current consumer(%d) is invisible(%s)", m_consumerID, m_app_id.c_str());
+               return true;
+       }
+
+       SERVER_ERR("current consumer(%s)- visibility:(%d)", (m_app_id.empty()) ? "null" : m_app_id.c_str(), visibility_consumer);
+       SERVER_ERR("requester(%s)- visibility:(%d)", app_id_requester.c_str(), visibility_requester);
+
+       return false;
+}
+
+int CConsumer::UpdateAppStatus(std::string app_id)
+{
+       char buf[RMS_NAME_BUF_SIZE];
+       int status;
+       int n_max = 4;
+       snprintf(buf, RMS_NAME_BUF_SIZE, "Get visibility of application '%s'", app_id.c_str());
+
+       for (int i = 0; i < n_max; i++) {
+               usleep(50*1000);
+
+               trace_begin(buf);
+               status = aul_app_get_status(app_id.c_str());
+               trace_end();
+               SERVER_INFO("app(%s) / status(%d) / (%d)", app_id.c_str(), status, i);
+
+               if (IsVisibleStatus(status)) {
+                       SERVER_ERR("status %d", status);
+                       return status;
+               }
+       }
+       return status;
+}
+
+bool CConsumer::NeedStatusUpdate(std::string app_id)
+{
+       return false;
+}
+
+bool CConsumer::IsVisibleStatus(int status)
+{
+       return (status == STATUS_FOCUS || status == STATUS_VISIBLE);
+}
+
+bool CConsumer::GetAppVisibility(std::string app_id, bool requester)
+{
+       CCache *cache = CCache::getInstance();
+       int status = cache->GetAppStatus(app_id);
+
+       if (status == -1) {
+               status = aul_app_get_status(app_id.c_str());
+
+               if (!IsVisibleStatus(status) && requester && NeedStatusUpdate(app_id))
+                       status = UpdateAppStatus(app_id);
+
+               cache->SetAppStatus(app_id, status);
+       }
+
+       return IsVisibleStatus(status);
+}
+
+bool CConsumer::CheckWebAppState(IN std::string app_id_requesting)
+{
+       if (app_id_requesting.length() == 0)
+               return false;
+
+       std::string webapp_vconf_key = std::string("rtc/memory/WebApp/") + app_id_requesting;
+
+       char *status = vconf_get_str(webapp_vconf_key.c_str());
+       if (!status) {
+               SERVER_INFO("%s is not webapp", app_id_requesting.c_str());
+               return false;
+       }
+
+       std::string webapp_status(status);
+       if (webapp_status.compare("resume")) {
+               SERVER_INFO("%s is not in resume status (%s)", app_id_requesting.c_str(), webapp_status.c_str());
+               free(status);
+               return false;
+       }
+
+       SERVER_INFO("%s is in resume status (%s)", app_id_requesting.c_str(), webapp_status.c_str());
+       free(status);
+
+       return true;
+}
index 3e75cb51ecbe81a83c3758ae248b1cf855408f92..7dfdadcebcf7f43ce67493e38cd0894d68d760ef 100644 (file)
@@ -1,84 +1,84 @@
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <assert.h>\r
-#include <CConsumer.h>\r
-#include <CConsumerContainer.h>\r
-\r
-CConsumerContainer *CConsumerContainer::m_instance = NULL;\r
-\r
-CConsumerContainer *CConsumerContainer::getInstance(void)\r
-{\r
-       if (!m_instance) {\r
-               m_instance = new(std::nothrow) CConsumerContainer;\r
-               assert(m_instance);\r
-       }\r
-\r
-       return m_instance;\r
-}\r
-\r
-CConsumer *CConsumerContainer::findConsumer(int consumer_id)\r
-{\r
-       std::map<int, CConsumer*>::iterator it = m_consumers.find(consumer_id);\r
-\r
-       return (it == m_consumers.end()) ? NULL : (*it).second;\r
-}\r
-\r
-bool CConsumerContainer::AddConsumer(int consumer_id, CConsumer *consumer)\r
-{\r
-       std::map<int, CConsumer*>::iterator it = m_consumers.find(consumer_id);\r
-\r
-       if (it != m_consumers.end())\r
-               return false;\r
-\r
-       m_consumers.insert(std::pair<int, CConsumer*>(consumer_id, consumer));\r
-       return true;\r
-}\r
-\r
-void CConsumerContainer::RemoveConsumer(int consumer_id)\r
-{\r
-       m_consumers.erase(consumer_id);\r
-}\r
-\r
-std::map<int, CConsumer*> CConsumerContainer::findConsumers(int pid)\r
-{\r
-       std::map<int, CConsumer*> result;\r
-\r
-       for (auto const &it : m_consumers) {\r
-               CConsumer *consumer = it.second;\r
-\r
-               if (consumer->GetPid() != pid)\r
-                       continue;\r
-\r
-               result.insert(std::pair<int, CConsumer*>(it.first, it.second));\r
-       }\r
-\r
-       return result;\r
-}\r
-\r
-std::map<int, CConsumer*> CConsumerContainer::FindConsumers(std::string app_id)\r
-{\r
-       std::map<int, CConsumer*> result;\r
-       for (auto const &it : m_consumers) {\r
-               CConsumer *consumer = it.second;\r
-               if (app_id.compare(consumer->GetAppID()))\r
-                       continue;\r
-\r
-               result.insert(std::pair<int, CConsumer*>(it.first, it.second));\r
-       }\r
-\r
-       return result;\r
-}\r
+/*
+ * 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 <assert.h>
+#include <CConsumer.h>
+#include <CConsumerContainer.h>
+
+CConsumerContainer *CConsumerContainer::m_instance = NULL;
+
+CConsumerContainer *CConsumerContainer::getInstance(void)
+{
+       if (!m_instance) {
+               m_instance = new(std::nothrow) CConsumerContainer;
+               assert(m_instance);
+       }
+
+       return m_instance;
+}
+
+CConsumer *CConsumerContainer::findConsumer(int consumer_id)
+{
+       std::map<int, CConsumer*>::iterator it = m_consumers.find(consumer_id);
+
+       return (it == m_consumers.end()) ? NULL : (*it).second;
+}
+
+bool CConsumerContainer::AddConsumer(int consumer_id, CConsumer *consumer)
+{
+       std::map<int, CConsumer*>::iterator it = m_consumers.find(consumer_id);
+
+       if (it != m_consumers.end())
+               return false;
+
+       m_consumers.insert(std::pair<int, CConsumer*>(consumer_id, consumer));
+       return true;
+}
+
+void CConsumerContainer::RemoveConsumer(int consumer_id)
+{
+       m_consumers.erase(consumer_id);
+}
+
+std::map<int, CConsumer*> CConsumerContainer::findConsumers(int pid)
+{
+       std::map<int, CConsumer*> result;
+
+       for (auto const &it : m_consumers) {
+               CConsumer *consumer = it.second;
+
+               if (consumer->GetPid() != pid)
+                       continue;
+
+               result.insert(std::pair<int, CConsumer*>(it.first, it.second));
+       }
+
+       return result;
+}
+
+std::map<int, CConsumer*> CConsumerContainer::FindConsumers(std::string app_id)
+{
+       std::map<int, CConsumer*> result;
+       for (auto const &it : m_consumers) {
+               CConsumer *consumer = it.second;
+               if (app_id.compare(consumer->GetAppID()))
+                       continue;
+
+               result.insert(std::pair<int, CConsumer*>(it.first, it.second));
+       }
+
+       return result;
+}
index 9d5d0a85488c6900a3243e77f7d67d67087cba50..4f7813bc6ec7d0a30fa27691ec5c505ec42459e0 100644 (file)
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <unistd.h>\r
-#include <sys/stat.h>\r
-#include <fcntl.h>\r
-#include <glib.h>\r
-#include <stdlib.h>\r
-\r
-#include <vconf.h>\r
-#include <stdio.h>\r
-#include <system_info.h>\r
-#include <sys/types.h>\r
-#include <signal.h>\r
-#include <vconf.h>\r
-#include <tzplatform_config.h>\r
-#include <dlfcn.h>\r
-\r
-#include <CDebugUtils.h>\r
-#include <rms_debug.h>\r
-#include <bundle.h>\r
-#include <bundle_internal.h>\r
-#include <syspopup_caller.h>\r
-\r
-\r
-static bool product_type_init = false;\r
-static int product_type = 0; //SYSTEM_INFO_PRODUCT_TYPE_TV;\r
-\r
-// The process list which is killed by resource manager\r
-static GHashTable *process_htable = NULL;\r
-\r
-#define RMS_IS_DEBUG_IMAGE (access("/etc/debug", F_OK) == 0)\r
-\r
-const char *rm_convert_state_enum_to_string(rms_resource_internal_state_e state_enum)\r
-{\r
-       switch (state_enum) {\r
-               case RMS_INTERNAL_STATE_FREE:\r
-                       return "FREE";\r
-               case RMS_INTERNAL_STATE_SHARABLE:\r
-                       return "SHARABLE";\r
-               case RMS_INTERNAL_STATE_SHARED:\r
-                       return "SHARED";\r
-               case RMS_INTERNAL_STATE_EXCLUSIVE:\r
-                       return "EXCLUSIVE";\r
-               case RMS_INTERNAL_STATE_ERROR:\r
-               default:\r
-                       return "NONE";\r
-       }\r
-}\r
-\r
-const char *rm_convert_requested_state_enum_to_string(rms_requests_resource_state_e state_enum)\r
-{\r
-       switch (state_enum) {\r
-               case RMS_STATE_PASSIVE:\r
-                       return "PASSIVE";\r
-               case RMS_STATE_SHARABLE:\r
-                       return "SHARABLE";\r
-               case RMS_STATE_EXCLUSIVE:\r
-                       return "EXCLUSIVE";\r
-               case RMS_STATE_EXCLUSIVE_CONDITIONAL:\r
-                       return "EXCLUSIVE_CONDITIONAL";\r
-               case RMS_STATE_EXCLUSIVE_AUTO:\r
-                       return "EXCLUSIVE_AUTO";\r
-               case RMS_STATE_EXCLUSIVE_PREFERENCE:\r
-                       return "EXCLUSIVE_PREFERENCE";\r
-               default:\r
-                       return "NONE";\r
-       }\r
-}\r
-\r
-const char *rm_convert_category_enum_to_string(rms_rsc_category_e category_enum)\r
-{\r
-       switch (category_enum) {\r
-               case RMS_CATEGORY_NONE:\r
-                       return "NONE";\r
-               case RMS_CATEGORY_AUDIO_DECODER:\r
-                       return "Audio_Decoder";\r
-               case RMS_CATEGORY_AUDIO_SPDIF_ES_OUTPUT:\r
-                       return "Not Defined Yet";\r
-               case RMS_CATEGORY_VIDEO_DECODER:\r
-                       return "Video_Decoder";\r
-               case RMS_CATEGORY_DEMUX:\r
-                       return "Demux_Main";\r
-               case RMS_CATEGORY_AUDIO_ENCODER:\r
-                       return "Audio_Encoder";\r
-               case RMS_CATEGORY_VIDEO_ENCODER:\r
-                       return "Video_Encoder";\r
-               case RMS_CATEGORY_SCALER:\r
-                       return "Video_Scaler";\r
-               case RMS_CATEGORY_TUNER:\r
-                       return "Tuner";\r
-               case RMS_CATEGORY_AUDIO_MAIN_OUT:\r
-                       return "Audio_Main_Out";\r
-               case RMS_CATEGORY_AUDIO_REMOTE_OUT:\r
-                       return "Audio_Remote_Out";\r
-               case RMS_CATEGORY_AUDIO_SCART_OUT:\r
-                       return "Audio_Scart_Out";\r
-               case RMS_CATEGORY_MM_PCM_OUT:\r
-                       return "MM_PCM_playback";\r
-               case RMS_CATEGORY_AUDIO_DECODER_SUB:\r
-                       return "Audio_Decorder_Sub";\r
-               case RMS_CATEGORY_JPEG_DECODER:\r
-                       return "JPEG_Decoder";\r
-               case RMS_CATEGORY_MJPEG_DECODER:\r
-                       return "MJPEG_Decoder";\r
-               case RMS_CATEGORY_SCALER_SUB:\r
-                       return "Video_Scaler_Sub";\r
-               case RMS_CATEGORY_EXT_VIDEO_SRC:\r
-                       return "Ext_Video_Src";\r
-               case RMS_CATEGORY_EXT_AUDIO_SRC:\r
-                       return "Ext_Audio_Src";\r
-               case RMS_CATEGORY_EXT_HDMI_SRC:\r
-                       return "Ext_HDMI_Src";\r
-               case RMS_CATEGORY_VIDEO_DECODER_SUB:\r
-                       return "Video_Decoder_Sub";\r
-               case RMS_CATEGORY_CAMERA:\r
-                       return "Camera";\r
-               case RMS_CATEGORY_DEMUX_REC:\r
-                       return "Demux_Rec";\r
-               case RMS_CATEGORY_TUNER_SUB:\r
-                       return "Tuner_Sub";\r
-               case RMS_CATEGORY_VIDEO_DECODER_UHD:\r
-                       return "Video_Decoder UHD";\r
-               case RMS_CATEGORY_INPUT_SRC_DTV:\r
-                       return "Input_Src_DTV";\r
-               case RMS_CATEGORY_INPUT_SRC_ATV:\r
-                       return "Input_Src_ATV";\r
-               case RMS_CATEGORY_INPUT_SRC_HDMI:\r
-                       return "Input_Src_HDMI";\r
-               case RMS_CATEGORY_INPUT_SRC_COMP:\r
-                       return "Input_Src_COMP";\r
-               case RMS_CATEGORY_INPUT_SRC_AV:\r
-                       return "Input_Src_AV";\r
-               case RMS_CATEGORY_INPUT_SRC_SCART:\r
-                       return "Input_Src_SCART";\r
-               case RMS_CATEGORY_MIC:\r
-                       return "Mic";\r
-               case RMS_CATEGORY_SW_DECODER:\r
-                       return "SWDecoder";\r
-               case RMS_CATEGORY_MMP_MEMORY_CLUSTER:\r
-                       return "MMPlayer MemoryCluster";\r
-               case RMS_CATEGORY_JPEG_DECODER_8K:\r
-                       return "JPEG_Decoder 8K";\r
-               case RMS_CATEGORY_SCALER_BG:\r
-                       return "Video_Scaler_BG";\r
-               default:\r
-                       return "";\r
-       }\r
-}\r
-\r
-const char *rm_convert_device_enum_to_string(rms_device_e device_enum)\r
-{\r
-       switch (device_enum) {\r
-               case RMS_DEVICE_NONE:\r
-                       return "NONE";\r
-               case RMS_DEVICE_AUDIO_MAIN_OUT:\r
-                       return "audio_main_out";\r
-               case RMS_DEVICE_AUDIO_REMOTE_OUT:\r
-                       return "audio_remote_out";\r
-               case RMS_DEVICE_AUDIO_SCART_OUT:\r
-                       return "audio_scart_out";\r
-               case RMS_DEVICE_MM_PCM_OUT:\r
-                       return "mm_pcm_out";\r
-               case RMS_DEVICE_JPEG_DECODER:\r
-                       return "jpeg_decoder";\r
-               case RMS_DEVICE_DEMUX0:\r
-                       return "demux0";\r
-               case RMS_DEVICE_DEMUX1:\r
-                       return "demux1";\r
-               case RMS_DEVICE_DEMUX2:\r
-                       return "demux2";\r
-               case RMS_DEVICE_DEMUX3:\r
-                       return "demux3";\r
-               case RMS_DEVICE_AUDIO_ENCODER:\r
-                       return "audio_encoder";\r
-               case RMS_DEVICE_VIDEO_ENCODER:\r
-                       return "video_encoder";\r
-               case RMS_DEVICE_SCALER:\r
-                       return "scaler";\r
-               case RMS_DEVICE_EXT_VIDEO_SRC:\r
-                       return "ext_video_src";\r
-               case RMS_DEVICE_EXT_AUDIO_SRC:\r
-                       return "ext_autio_src";\r
-               case RMS_DEVICE_EXT_HDMI_SRC:\r
-                       return "ext_hdmi_src";\r
-               case RMS_DEVICE_CAMERA:\r
-                       return "camera";\r
-               case RMS_DEVICE_TUNER:\r
-                       return "tuner";\r
-               case RMS_DEVICE_TUNER_SUB:\r
-                       return "tuner_sub";\r
-               case RMS_DEVICE_SCALER_SUB:\r
-                       return "scaler_sub";\r
-               case RMS_DEVICE_AUDIO_DECODER:\r
-                       return "audio_decoder";\r
-               case RMS_DEVICE_AUDIO_DECODER_SUB:\r
-                       return "audio_decoder_sub";\r
-               case RMS_DEVICE_VIDEO_DECODER_MAIN:\r
-                       return "video_decoder_main";\r
-               case RMS_DEVICE_VIDEO_DECODER_SUB:\r
-                       return "video_decoder_sub";\r
-               case RMS_DEVICE_VIDEO_DECODER_UDDEC:\r
-                       return "video_decoder_uddec";\r
-               case RMS_DEVICE_VIDEO_DECODER_UDHEVC:\r
-                       return "video_decoder_udhevc";\r
-               case RMS_DEVICE_AUDIO_SPDIF_ES_OUTPUT:\r
-                       return "audio_spdif_es_output";\r
-               case RMS_DEVICE_MIC:\r
-                       return "mic";\r
-               case RMS_DEVICE_EXT_COMP_SRC:\r
-                       return "ext_comp_src";\r
-               case RMS_DEVICE_EXT_AV_SRC:\r
-                       return "av_src";\r
-               case RMS_DEVICE_MJPEG_DECODER:\r
-                       return "mjpeg_decoder";\r
-               case RMS_DEVICE_JPEG_DECODER_UHD:\r
-                       return "jpeg_decoder_uhd";\r
-               case RMS_DEVICE_MJPEG_DECODER_UHD:\r
-                       return "mjpeg_decoder_uhd";\r
-               case RMS_DEVICE_SW_DECODER:\r
-                       return "sw_decoder";\r
-               default:\r
-                       return "";\r
-       }\r
-}\r
-\r
-const char *rm_print_allocation_failure_reason(int ret_value)\r
-{\r
-       switch (ret_value) {\r
-               case RMS_OK:\r
-                       return "OK";\r
-               case RMS_ERROR:\r
-                       return "Cannot Allocate Resources";\r
-               case RMS_ERROR_TAKE_RESOURCE_FROM_OTHER_CONSUMER:\r
-                       return "RESOURCE CONFLICT - Other Consumer Is Using";\r
-               case RMS_OK_UHD_RESOURCE_CONFLICT:\r
-                       return "UHD RESOURCE CONFLICT - Other Consumer Is Using";\r
-               default:\r
-                       return "";\r
-       }\r
-}\r
-void rms_create_popup(const char *title, const char *text)\r
-{\r
-       bundle *(*bundle_create_fp) (void);\r
-       int (*bundle_add_fp)(bundle*, const char*, const char*);\r
-       const char *(*bundle_get_val_fp) (bundle*, const char*);\r
-       int (*bundle_free_fp) (bundle*);\r
-       int (*syspopup_launch_fp) (char*, bundle*);\r
-       void *libsyspopup_handle = NULL;\r
-       void *libbundle_handle = NULL;\r
-       bundle *b = NULL;\r
-       char *error;\r
-\r
-       libsyspopup_handle = dlopen(LIBDIR"/libsyspopup_caller.so.0.1.0", RTLD_LAZY);\r
-       if (!libsyspopup_handle) {\r
-               SERVER_ERR("failed to load syspopup library");\r
-               goto end;\r
-       }\r
-\r
-       libbundle_handle = dlopen(LIBDIR"/libbundle.so.0", RTLD_LAZY);\r
-\r
-       if (!libbundle_handle) {\r
-               SERVER_ERR("failed to load bundle library");\r
-               goto end;\r
-       }\r
-\r
-       error = NULL;\r
-\r
-       bundle_create_fp = (bundle *(*)(void)) dlsym(libbundle_handle, "bundle_create");\r
-\r
-       if ((error = dlerror()) != NULL) {\r
-               SERVER_ERR("failed to find bundle_create");\r
-               goto end;\r
-\r
-       }\r
-\r
-       bundle_add_fp = (int (*)(bundle*, const char*, const char*)) dlsym(libbundle_handle, "bundle_add");\r
-\r
-       if ((error = dlerror()) != NULL) {\r
-               SERVER_ERR("failed to find bundle_add");\r
-               goto end;\r
-       }\r
-\r
-       bundle_get_val_fp = (const char *(*)(bundle*, const char*)) dlsym(libbundle_handle, "bundle_get_val");\r
-\r
-       if ((error = dlerror()) != NULL) {\r
-               SERVER_ERR("failed to find bundle_get_val");\r
-               goto end;\r
-       }\r
-\r
-       bundle_free_fp = (int (*)(bundle*)) dlsym(libbundle_handle, "bundle_free");\r
-\r
-       if ((error = dlerror()) != NULL) {\r
-               SERVER_ERR("failed to find bundle_free");\r
-               goto end;\r
-       }\r
-\r
-       syspopup_launch_fp = (int (*)(char*, bundle*)) dlsym(libsyspopup_handle, "syspopup_launch");\r
-\r
-       if ((error = dlerror()) != NULL) {\r
-               SERVER_ERR("failed to find alert-syspopup");\r
-               goto end;\r
-       }\r
-\r
-       b = bundle_create_fp();\r
-       if (!b) {\r
-               SERVER_ERR("failed to create bundle");\r
-               goto end;\r
-       }\r
-\r
-       bundle_add_fp(b, "type", "title_message_1button");\r
-       bundle_add_fp(b, "title", title);\r
-       bundle_add_fp(b, "text", text);\r
-\r
-       bundle_get_val_fp(b, "type");\r
-       bundle_get_val_fp(b, "title");\r
-       bundle_get_val_fp(b, "text");\r
-\r
-       syspopup_launch_fp((char*)"alert-syspopup", b);\r
-       bundle_free_fp(b);\r
-\r
-end:\r
-       if (libsyspopup_handle)\r
-               dlclose(libsyspopup_handle);\r
-\r
-       if (libbundle_handle)\r
-               dlclose(libbundle_handle);\r
-}\r
-\r
-int rms_get_cmd_name(pid_t pid, char *name_out, int size)\r
-{\r
-       char name[RMS_NAME_BUF_SIZE] = {0,};\r
-       FILE *f;\r
-       size_t sz;\r
-\r
-       snprintf(name, sizeof(name), "/proc/%d/cmdline", pid);\r
-       // Check if the process exists and is accessible\r
-       if (access(name, R_OK) != 0) {\r
-               SERVER_ERR("failed to access (%s) : %d", name, errno);\r
-               return RMS_ERROR;\r
-       }\r
-\r
-       f = fopen(name, "r");\r
-       if (!f) {\r
-               SERVER_ERR("failed to open cmdline(%s) : %d", name, errno);\r
-               return RMS_ERROR;\r
-       }\r
-\r
-       sz = fread(name, sizeof(char), sizeof(name)-1, f);\r
-       name[sz] = '\0';\r
-       fclose(f);\r
-\r
-       snprintf(name_out, size, "%s", name);\r
-\r
-       return RMS_OK;\r
-}\r
-\r
-void rms_print_log_console(char *buf)\r
-{\r
-       int fd, ret;\r
-       char output[RMS_CONSOLE_BUF_SIZE] ={0,};\r
-\r
-       struct timespec tnow;\r
-\r
-       fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);\r
-\r
-       if (fd < 0) {\r
-               SERVER_ERR("console device open fail");\r
-               return;\r
-       }\r
-\r
-       if (is_symlink_file("/dev/console")) {\r
-               SERVER_ERR("%s is symbolic link file", "/dev/console");\r
-               close(fd);\r
-               return;\r
-       }\r
-\r
-       ret = clock_gettime(CLOCK_MONOTONIC, &tnow);\r
-       snprintf(output, RMS_CONSOLE_BUF_SIZE, "[RMS][%ld.%6ld] %s", tnow.tv_sec, tnow.tv_nsec/1000, buf);\r
-       ret = write(fd, output, strlen(output));\r
-\r
-       if (ret < 0) {\r
-               SERVER_ERR("Fail to write on console directly");\r
-       }\r
-\r
-       close(fd);\r
-}\r
-\r
-int rm_get_product_type(void)\r
-{\r
-       if (product_type_init)\r
-               return product_type;\r
-\r
-       int type = 0; /* SYSTEM_INFO_PRODUCT_TYPE_TV */\r
-\r
-       if (system_info_get_custom_int("com.samsung/featureconf/product.product_type", &type) != SYSTEM_INFO_ERROR_NONE) {\r
-               SERVER_ERR("Failed to get com.samsung/featureconf/product.product_type");\r
-       }\r
-\r
-       product_type_init = true;\r
-       product_type = type;\r
-\r
-       return product_type;\r
-}\r
-\r
-int rm_is_valid_pid(int pid)\r
-{\r
-       if (kill((pid_t) pid, 0) == 0) {\r
-               SERVER_INFO("pid(%d) is alive", pid);\r
-               return 1;\r
-       }\r
-\r
-       SERVER_ERR("pid(%d) / errno(%d)", pid, errno);\r
-\r
-       return (errno == ESRCH) ? 0 : 1;\r
-}\r
-\r
-static void process_htable_destory_key(gpointer key)\r
-{\r
-       if (key)\r
-               free(key);\r
-}\r
-\r
-static void process_htable_create(void)\r
-{\r
-       if (process_htable) {\r
-               SERVER_ERR("hash table already created");\r
-               return;\r
-       }\r
-\r
-       process_htable = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)process_htable_destory_key, NULL);\r
-\r
-       SERVER_INFO("process hash table created");\r
-}\r
-\r
-static void process_htable_clear(void)\r
-{\r
-       SERVER_INFO("clear process hash table");\r
-\r
-       if (!process_htable)\r
-               return;\r
-\r
-       g_hash_table_remove_all(process_htable);\r
-}\r
-\r
-static void process_htable_insert(const char *name)\r
-{\r
-       const int PROCESS_DATA_LIMIT = 100; // The maxinum size is (RMS_NAME_BUF_SIZE * PROCESS_DATA_LIMIT)\r
-\r
-       if (!process_htable)\r
-               process_htable_create();\r
-\r
-       if (g_hash_table_contains(process_htable, name))\r
-               return;\r
-\r
-       if (g_hash_table_size(process_htable) >= PROCESS_DATA_LIMIT)\r
-               process_htable_clear();\r
-\r
-       char *key_name = (char*) strndup(name, strlen(name));\r
-\r
-       g_hash_table_insert(process_htable, key_name, (gpointer) 1);\r
-\r
-       SERVER_ERR("process info (%s) inserted to hash table (%d)", name, g_hash_table_size(process_htable));\r
-}\r
-\r
-\r
-bool process_htable_contains(const char *name)\r
-{\r
-       bool result = false;\r
-\r
-       if (!process_htable) {\r
-               SERVER_INFO("(%s) - no table", name);\r
-               return false;\r
-       }\r
-\r
-       if (g_hash_table_size(process_htable) == 0) {\r
-               SERVER_INFO("(%s) - empty", name);\r
-               return false;\r
-       }\r
-\r
-       result = g_hash_table_contains(process_htable, name);\r
-\r
-       SERVER_INFO("(%s) - result(%d)", name, result);\r
-\r
-       // resource manager is supposed to clear data once it's checked by application\r
-       process_htable_clear();\r
-\r
-       return result;\r
-}\r
-\r
-int rms_report_emergency(IN int cid, IN int pid, IN int requester)\r
-{\r
-       const char *vconf_request_cold_poweroff = "memory/boot/cold_poweroff_request_pkg";\r
-       int retry = 25; // 20ms * 25 times => 500ms\r
-       int ret = 0;\r
-\r
-       SERVER_ERR("consumer is not responding....CID[%d]/PID[%d]/Requester(%d) - set cold power off mode", cid, pid, requester);\r
-\r
-       if (vconf_set_str(vconf_request_cold_poweroff, "resource-manager") != 0) {\r
-               SERVER_ERR("Failed to set request cold power off");\r
-       } else {\r
-               SERVER_ERR("memory/boot/cold_poweroff_request_pkg set as resource-manager");\r
-       }\r
-\r
-       char process_name[RMS_NAME_BUF_SIZE] = {0,};\r
-\r
-       if (rms_get_cmd_name(pid, process_name, RMS_NAME_BUF_SIZE) == RMS_OK) {\r
-               process_htable_insert(process_name);\r
-       }\r
-\r
-       SERVER_ERR("kill PID(%d)", pid);\r
-\r
-       int signal = SIGKILL;\r
-\r
-       if (RMS_IS_DEBUG_IMAGE) {\r
-               signal = SIGABRT;\r
-               retry = 250; // 20ms * 250 times => 5 sec\r
-       }\r
-\r
-       ret = kill(pid, signal);\r
-\r
-       if (ret!=0) {\r
-               SERVER_ERR("Failed to kill(%d), errno(%d)", pid, errno);\r
-       }\r
-\r
-       // wait until process is really terminated for 500ms\r
-       while (retry > 0 && rm_is_valid_pid(pid)) {\r
-               retry--;\r
-               SERVER_ERR("pid(%d) still alive(%d)", pid, retry);\r
-               usleep(20*1000);\r
-               continue;\r
-       }\r
-\r
-       if (RMS_IS_DEBUG_IMAGE && retry <= 0) {\r
-               //process didn't get terminated for 5 seconds\r
-               SERVER_ERR("pid(%d) is not terminated.", pid);\r
-               return RMS_ERROR;\r
-       }\r
-\r
-       return RMS_OK;\r
-}\r
-\r
-void rms_display_timeout_error_popup(rms_alarm_reason_e reason, rms_consumer_tobe_returned_s info)\r
-{\r
-       const char *title = "Resource Allocation Failure";\r
-       const char *style_notification_msg = "<font_size=30 color=#00FF00>";\r
-       const char *style_process_name = "<font_size=25 color=#C90000>";\r
-       const char *indent = "                             ";\r
-       const char *notification_msg = "Please contact the owner(s) of process(es) below<br>";\r
-       const char *reason0 = " Resource allocation failed because there is no callback response from below process(es)<br> ";\r
-       const char *reason1 = " Resource allocation failed because below process(es) did not request deallocation<br> ";\r
-\r
-       char name[RMS_NAME_BUF_SIZE] = {0,};\r
-       GString *gstr;\r
-\r
-       if (!RMS_IS_DEBUG_IMAGE) {\r
-               SERVER_ERR("Not debug mode. Timeout alarm popup is not shown. reason(%d)", (int)reason);\r
-               return;\r
-       }\r
-\r
-       SERVER_ERR("timeout alarm");\r
-\r
-       gstr = g_string_new("");\r
-\r
-       if (!gstr) {\r
-               SERVER_ERR("Failed to create debug popup command");\r
-               return;\r
-       }\r
-\r
-       g_string_append_printf(gstr, "%s", style_notification_msg);\r
-\r
-       switch (reason) {\r
-               case RMS_ALARM_NO_CALLBACK_RESPONSE:\r
-                       g_string_append_printf(gstr, "%s%s", indent, reason0);\r
-                       break;\r
-               case RMS_ALARM_NO_DEALLOCATION:\r
-                       g_string_append_printf(gstr, "%s%s", indent, reason1);\r
-                       break;\r
-               default :\r
-                       break;\r
-       }\r
-\r
-       g_string_append_printf(gstr, "%s%s%s", indent, notification_msg, style_process_name);\r
-\r
-       rms_get_cmd_name(info.process_id, name, sizeof(name));\r
-       g_string_append_printf(gstr, "%s%s : %d - %s%s", indent, "pid", (int)(info.process_id), name, " <br>");\r
-\r
-       for (int i = 0; i < info.n_conflicted; i++) {\r
-               g_string_append_printf(gstr, "%s [%d] %s%s", indent, i+1, rm_convert_category_enum_to_string(info.conflicted_resources[i].category_id), " <br>");\r
-       }\r
-       rms_create_popup(title, gstr->str);\r
-       SERVER_ERR("Command: %s", gstr->str);\r
-       g_string_free(gstr, true);\r
-}\r
-\r
-static bool rms_read_index(int *data)\r
-{\r
-       FILE *fp = NULL;\r
-       char str[10] = {0,};\r
-       size_t str_size;\r
-       const char *filename = "/proc/device-tree/rm_tbl_idx";\r
-\r
-       if (!data) {\r
-               SERVER_ERR("invalid input : null data");\r
-               return false;\r
-       }\r
-\r
-       fp = fopen(filename, "rb");\r
-\r
-       if (!fp) {\r
-               SERVER_ERR("failed to open (%s) - errno(%d)", filename, errno);\r
-               return false;\r
-       }\r
-\r
-       str_size = fread(str, sizeof(char), sizeof(str)-1, fp);\r
-\r
-       str[str_size] = '\0';\r
-\r
-       if (str_size == 0) {\r
-               fclose(fp);\r
-               return false;\r
-       }\r
-\r
-       *data = atoi(str);\r
-\r
-       fclose(fp);\r
-       fp = NULL;\r
-\r
-       return true;\r
-}\r
-\r
-void rms_display_resource_table_error_popup(void)\r
-{\r
-       const char *title = "FATAL ERROR!!!";\r
-       const char *reason = " Resource Manager can't find a resource table for this board<br> ";\r
-       const char *style_notification_msg = "<font_size=30 color=#FF0000>";\r
-       const char *indent = "  ";\r
-       const char *notification_msg = "<br>";\r
-\r
-       GString *gstr = g_string_new("");\r
-       char *chipset_info;\r
-       int model_index = -1;\r
-\r
-       if (!gstr) {\r
-               SERVER_ERR("Failed to create debug popup command");\r
-               return;\r
-       }\r
-\r
-       g_string_append_printf(gstr, "%s%s", indent, reason);\r
-       g_string_append_printf(gstr, "%s%s%s", indent, notification_msg, style_notification_msg);\r
-       g_string_append_printf(gstr, "%sProduct type : %d%s", indent, rm_get_product_type(), " <br>");\r
-\r
-       if (system_info_get_custom_string("com.samsung/featureconf/product.chipset", &chipset_info)!= SYSTEM_INFO_ERROR_NONE) {\r
-               SERVER_ERR("Failed to get chipset from system-info");\r
-               goto end;\r
-       }\r
-\r
-       g_string_append_printf(gstr, "%sChipset : %s%s", indent, chipset_info, " <br>");\r
-\r
-       if (!rms_read_index(&model_index)) {\r
-               SERVER_ERR("failed to read model index");\r
-       }\r
-\r
-       g_string_append_printf(gstr, "%sIndex : %d%s", indent, model_index, " <br>");\r
-\r
-       rms_create_popup(title,gstr->str);\r
-\r
-       if (chipset_info) {\r
-               free(chipset_info);\r
-       }\r
-\r
-end:\r
-       g_string_free(gstr, true);\r
-       return;\r
-}\r
-\r
-void rms_print_model_info(void)\r
-{\r
-       static char *chipset_info = NULL;\r
-       static int rm_index = -1;\r
-\r
-       if (!chipset_info) {\r
-               if (system_info_get_custom_string("com.samsung/featureconf/product.chipset", &chipset_info)!= SYSTEM_INFO_ERROR_NONE)\r
-                       SERVER_ERR("Failed to get chipset");\r
-       }\r
-\r
-       if (rm_index == -1) {\r
-               if (!rms_read_index(&rm_index))\r
-                       SERVER_ERR("failed to read rm index");\r
-       }\r
-\r
-       SERVER_ERR("> chipset(%s)/product_type(%d)/rm_index(%d)", chipset_info? chipset_info:"", rm_get_product_type(), rm_index);\r
-\r
-       char buf[512];\r
-       snprintf(buf, 512, "resource table not loaded! > chipset(%s)/product_type(%d)/rm_index(%d)", chipset_info? chipset_info:"", rm_get_product_type(), rm_index);\r
-       rms_print_log_console(buf);\r
-}\r
-\r
-int is_symlink_file(const char *path)\r
-{\r
-       struct stat st;\r
-       if (lstat(path, &st) == -1) {\r
-               SERVER_ERR("stat error. file path(%s)", path);\r
-               return 0;\r
-       }\r
-\r
-       return (S_ISLNK(st.st_mode)) ? 1 : 0;\r
-}\r
-\r
-const char *rm_convert_error_type_to_string(rms_error_type_e error_type)\r
-{\r
-       switch (error_type) {\r
-               case RMS_ERR_TYPE_NONE:\r
-                       return "None";\r
-               case RMS_ERR_TYPE_REQUEST_OF_INVISIBLE_PROCESS:\r
-                       return "Request of invisible process";\r
-               case RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS:\r
-                       return "Request of low priority process";\r
-               case RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE:\r
-                       return "Not available resource";\r
-               case RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST:\r
-                       return "Requested resource does not exist";\r
-               case RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:\r
-                       return "Take resource from other consumer";\r
-               default:\r
-                       return "";\r
-       }\r
-}\r
+/*
+ * 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 <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <glib.h>
+#include <stdlib.h>
+
+#include <vconf.h>
+#include <stdio.h>
+#include <system_info.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <vconf.h>
+#include <tzplatform_config.h>
+#include <dlfcn.h>
+
+#include <CDebugUtils.h>
+#include <rms_debug.h>
+#include <bundle.h>
+#include <bundle_internal.h>
+#include <syspopup_caller.h>
+
+
+static bool product_type_init = false;
+static int product_type = 0; //SYSTEM_INFO_PRODUCT_TYPE_TV;
+
+// The process list which is killed by resource manager
+static GHashTable *process_htable = NULL;
+
+#define RMS_IS_DEBUG_IMAGE (access("/etc/debug", F_OK) == 0)
+
+const char *rm_convert_state_enum_to_string(rms_resource_internal_state_e state_enum)
+{
+       switch (state_enum) {
+               case RMS_INTERNAL_STATE_FREE:
+                       return "FREE";
+               case RMS_INTERNAL_STATE_SHARABLE:
+                       return "SHARABLE";
+               case RMS_INTERNAL_STATE_SHARED:
+                       return "SHARED";
+               case RMS_INTERNAL_STATE_EXCLUSIVE:
+                       return "EXCLUSIVE";
+               case RMS_INTERNAL_STATE_ERROR:
+               default:
+                       return "NONE";
+       }
+}
+
+const char *rm_convert_requested_state_enum_to_string(rms_requests_resource_state_e state_enum)
+{
+       switch (state_enum) {
+               case RMS_STATE_PASSIVE:
+                       return "PASSIVE";
+               case RMS_STATE_SHARABLE:
+                       return "SHARABLE";
+               case RMS_STATE_EXCLUSIVE:
+                       return "EXCLUSIVE";
+               case RMS_STATE_EXCLUSIVE_CONDITIONAL:
+                       return "EXCLUSIVE_CONDITIONAL";
+               case RMS_STATE_EXCLUSIVE_AUTO:
+                       return "EXCLUSIVE_AUTO";
+               case RMS_STATE_EXCLUSIVE_PREFERENCE:
+                       return "EXCLUSIVE_PREFERENCE";
+               default:
+                       return "NONE";
+       }
+}
+
+const char *rm_convert_category_enum_to_string(rms_rsc_category_e category_enum)
+{
+       switch (category_enum) {
+               case RMS_CATEGORY_NONE:
+                       return "NONE";
+               case RMS_CATEGORY_AUDIO_DECODER:
+                       return "Audio_Decoder";
+               case RMS_CATEGORY_AUDIO_SPDIF_ES_OUTPUT:
+                       return "Not Defined Yet";
+               case RMS_CATEGORY_VIDEO_DECODER:
+                       return "Video_Decoder";
+               case RMS_CATEGORY_DEMUX:
+                       return "Demux_Main";
+               case RMS_CATEGORY_AUDIO_ENCODER:
+                       return "Audio_Encoder";
+               case RMS_CATEGORY_VIDEO_ENCODER:
+                       return "Video_Encoder";
+               case RMS_CATEGORY_SCALER:
+                       return "Video_Scaler";
+               case RMS_CATEGORY_TUNER:
+                       return "Tuner";
+               case RMS_CATEGORY_AUDIO_MAIN_OUT:
+                       return "Audio_Main_Out";
+               case RMS_CATEGORY_AUDIO_REMOTE_OUT:
+                       return "Audio_Remote_Out";
+               case RMS_CATEGORY_AUDIO_SCART_OUT:
+                       return "Audio_Scart_Out";
+               case RMS_CATEGORY_MM_PCM_OUT:
+                       return "MM_PCM_playback";
+               case RMS_CATEGORY_AUDIO_DECODER_SUB:
+                       return "Audio_Decorder_Sub";
+               case RMS_CATEGORY_JPEG_DECODER:
+                       return "JPEG_Decoder";
+               case RMS_CATEGORY_MJPEG_DECODER:
+                       return "MJPEG_Decoder";
+               case RMS_CATEGORY_SCALER_SUB:
+                       return "Video_Scaler_Sub";
+               case RMS_CATEGORY_EXT_VIDEO_SRC:
+                       return "Ext_Video_Src";
+               case RMS_CATEGORY_EXT_AUDIO_SRC:
+                       return "Ext_Audio_Src";
+               case RMS_CATEGORY_EXT_HDMI_SRC:
+                       return "Ext_HDMI_Src";
+               case RMS_CATEGORY_VIDEO_DECODER_SUB:
+                       return "Video_Decoder_Sub";
+               case RMS_CATEGORY_CAMERA:
+                       return "Camera";
+               case RMS_CATEGORY_DEMUX_REC:
+                       return "Demux_Rec";
+               case RMS_CATEGORY_TUNER_SUB:
+                       return "Tuner_Sub";
+               case RMS_CATEGORY_VIDEO_DECODER_UHD:
+                       return "Video_Decoder UHD";
+               case RMS_CATEGORY_INPUT_SRC_DTV:
+                       return "Input_Src_DTV";
+               case RMS_CATEGORY_INPUT_SRC_ATV:
+                       return "Input_Src_ATV";
+               case RMS_CATEGORY_INPUT_SRC_HDMI:
+                       return "Input_Src_HDMI";
+               case RMS_CATEGORY_INPUT_SRC_COMP:
+                       return "Input_Src_COMP";
+               case RMS_CATEGORY_INPUT_SRC_AV:
+                       return "Input_Src_AV";
+               case RMS_CATEGORY_INPUT_SRC_SCART:
+                       return "Input_Src_SCART";
+               case RMS_CATEGORY_MIC:
+                       return "Mic";
+               case RMS_CATEGORY_SW_DECODER:
+                       return "SWDecoder";
+               case RMS_CATEGORY_MMP_MEMORY_CLUSTER:
+                       return "MMPlayer MemoryCluster";
+               case RMS_CATEGORY_JPEG_DECODER_8K:
+                       return "JPEG_Decoder 8K";
+               case RMS_CATEGORY_SCALER_BG:
+                       return "Video_Scaler_BG";
+               default:
+                       return "";
+       }
+}
+
+const char *rm_convert_device_enum_to_string(rms_device_e device_enum)
+{
+       switch (device_enum) {
+               case RMS_DEVICE_NONE:
+                       return "NONE";
+               case RMS_DEVICE_AUDIO_MAIN_OUT:
+                       return "audio_main_out";
+               case RMS_DEVICE_AUDIO_REMOTE_OUT:
+                       return "audio_remote_out";
+               case RMS_DEVICE_AUDIO_SCART_OUT:
+                       return "audio_scart_out";
+               case RMS_DEVICE_MM_PCM_OUT:
+                       return "mm_pcm_out";
+               case RMS_DEVICE_JPEG_DECODER:
+                       return "jpeg_decoder";
+               case RMS_DEVICE_DEMUX0:
+                       return "demux0";
+               case RMS_DEVICE_DEMUX1:
+                       return "demux1";
+               case RMS_DEVICE_DEMUX2:
+                       return "demux2";
+               case RMS_DEVICE_DEMUX3:
+                       return "demux3";
+               case RMS_DEVICE_AUDIO_ENCODER:
+                       return "audio_encoder";
+               case RMS_DEVICE_VIDEO_ENCODER:
+                       return "video_encoder";
+               case RMS_DEVICE_SCALER:
+                       return "scaler";
+               case RMS_DEVICE_EXT_VIDEO_SRC:
+                       return "ext_video_src";
+               case RMS_DEVICE_EXT_AUDIO_SRC:
+                       return "ext_autio_src";
+               case RMS_DEVICE_EXT_HDMI_SRC:
+                       return "ext_hdmi_src";
+               case RMS_DEVICE_CAMERA:
+                       return "camera";
+               case RMS_DEVICE_TUNER:
+                       return "tuner";
+               case RMS_DEVICE_TUNER_SUB:
+                       return "tuner_sub";
+               case RMS_DEVICE_SCALER_SUB:
+                       return "scaler_sub";
+               case RMS_DEVICE_AUDIO_DECODER:
+                       return "audio_decoder";
+               case RMS_DEVICE_AUDIO_DECODER_SUB:
+                       return "audio_decoder_sub";
+               case RMS_DEVICE_VIDEO_DECODER_MAIN:
+                       return "video_decoder_main";
+               case RMS_DEVICE_VIDEO_DECODER_SUB:
+                       return "video_decoder_sub";
+               case RMS_DEVICE_VIDEO_DECODER_UDDEC:
+                       return "video_decoder_uddec";
+               case RMS_DEVICE_VIDEO_DECODER_UDHEVC:
+                       return "video_decoder_udhevc";
+               case RMS_DEVICE_AUDIO_SPDIF_ES_OUTPUT:
+                       return "audio_spdif_es_output";
+               case RMS_DEVICE_MIC:
+                       return "mic";
+               case RMS_DEVICE_EXT_COMP_SRC:
+                       return "ext_comp_src";
+               case RMS_DEVICE_EXT_AV_SRC:
+                       return "av_src";
+               case RMS_DEVICE_MJPEG_DECODER:
+                       return "mjpeg_decoder";
+               case RMS_DEVICE_JPEG_DECODER_UHD:
+                       return "jpeg_decoder_uhd";
+               case RMS_DEVICE_MJPEG_DECODER_UHD:
+                       return "mjpeg_decoder_uhd";
+               case RMS_DEVICE_SW_DECODER:
+                       return "sw_decoder";
+               default:
+                       return "";
+       }
+}
+
+const char *rm_print_allocation_failure_reason(int ret_value)
+{
+       switch (ret_value) {
+               case RMS_OK:
+                       return "OK";
+               case RMS_ERROR:
+                       return "Cannot Allocate Resources";
+               case RMS_ERROR_TAKE_RESOURCE_FROM_OTHER_CONSUMER:
+                       return "RESOURCE CONFLICT - Other Consumer Is Using";
+               case RMS_OK_UHD_RESOURCE_CONFLICT:
+                       return "UHD RESOURCE CONFLICT - Other Consumer Is Using";
+               default:
+                       return "";
+       }
+}
+void rms_create_popup(const char *title, const char *text)
+{
+       bundle *(*bundle_create_fp) (void);
+       int (*bundle_add_fp)(bundle*, const char*, const char*);
+       const char *(*bundle_get_val_fp) (bundle*, const char*);
+       int (*bundle_free_fp) (bundle*);
+       int (*syspopup_launch_fp) (char*, bundle*);
+       void *libsyspopup_handle = NULL;
+       void *libbundle_handle = NULL;
+       bundle *b = NULL;
+       char *error;
+
+       libsyspopup_handle = dlopen(LIBDIR"/libsyspopup_caller.so.0.1.0", RTLD_LAZY);
+       if (!libsyspopup_handle) {
+               SERVER_ERR("failed to load syspopup library");
+               goto end;
+       }
+
+       libbundle_handle = dlopen(LIBDIR"/libbundle.so.0", RTLD_LAZY);
+
+       if (!libbundle_handle) {
+               SERVER_ERR("failed to load bundle library");
+               goto end;
+       }
+
+       error = NULL;
+
+       bundle_create_fp = (bundle *(*)(void)) dlsym(libbundle_handle, "bundle_create");
+
+       if ((error = dlerror()) != NULL) {
+               SERVER_ERR("failed to find bundle_create");
+               goto end;
+
+       }
+
+       bundle_add_fp = (int (*)(bundle*, const char*, const char*)) dlsym(libbundle_handle, "bundle_add");
+
+       if ((error = dlerror()) != NULL) {
+               SERVER_ERR("failed to find bundle_add");
+               goto end;
+       }
+
+       bundle_get_val_fp = (const char *(*)(bundle*, const char*)) dlsym(libbundle_handle, "bundle_get_val");
+
+       if ((error = dlerror()) != NULL) {
+               SERVER_ERR("failed to find bundle_get_val");
+               goto end;
+       }
+
+       bundle_free_fp = (int (*)(bundle*)) dlsym(libbundle_handle, "bundle_free");
+
+       if ((error = dlerror()) != NULL) {
+               SERVER_ERR("failed to find bundle_free");
+               goto end;
+       }
+
+       syspopup_launch_fp = (int (*)(char*, bundle*)) dlsym(libsyspopup_handle, "syspopup_launch");
+
+       if ((error = dlerror()) != NULL) {
+               SERVER_ERR("failed to find alert-syspopup");
+               goto end;
+       }
+
+       b = bundle_create_fp();
+       if (!b) {
+               SERVER_ERR("failed to create bundle");
+               goto end;
+       }
+
+       bundle_add_fp(b, "type", "title_message_1button");
+       bundle_add_fp(b, "title", title);
+       bundle_add_fp(b, "text", text);
+
+       bundle_get_val_fp(b, "type");
+       bundle_get_val_fp(b, "title");
+       bundle_get_val_fp(b, "text");
+
+       syspopup_launch_fp((char*)"alert-syspopup", b);
+       bundle_free_fp(b);
+
+end:
+       if (libsyspopup_handle)
+               dlclose(libsyspopup_handle);
+
+       if (libbundle_handle)
+               dlclose(libbundle_handle);
+}
+
+int rms_get_cmd_name(pid_t pid, char *name_out, int size)
+{
+       char name[RMS_NAME_BUF_SIZE] = {0,};
+       FILE *f;
+       size_t sz;
+
+       snprintf(name, sizeof(name), "/proc/%d/cmdline", pid);
+       // Check if the process exists and is accessible
+       if (access(name, R_OK) != 0) {
+               SERVER_ERR("failed to access (%s) : %d", name, errno);
+               return RMS_ERROR;
+       }
+
+       f = fopen(name, "r");
+       if (!f) {
+               SERVER_ERR("failed to open cmdline(%s) : %d", name, errno);
+               return RMS_ERROR;
+       }
+
+       sz = fread(name, sizeof(char), sizeof(name)-1, f);
+       name[sz] = '\0';
+       fclose(f);
+
+       snprintf(name_out, size, "%s", name);
+
+       return RMS_OK;
+}
+
+void rms_print_log_console(char *buf)
+{
+       int fd, ret;
+       char output[RMS_CONSOLE_BUF_SIZE] ={0,};
+
+       struct timespec tnow;
+
+       fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+
+       if (fd < 0) {
+               SERVER_ERR("console device open fail");
+               return;
+       }
+
+       if (is_symlink_file("/dev/console")) {
+               SERVER_ERR("%s is symbolic link file", "/dev/console");
+               close(fd);
+               return;
+       }
+
+       ret = clock_gettime(CLOCK_MONOTONIC, &tnow);
+       snprintf(output, RMS_CONSOLE_BUF_SIZE, "[RMS][%ld.%6ld] %s", tnow.tv_sec, tnow.tv_nsec/1000, buf);
+       ret = write(fd, output, strlen(output));
+
+       if (ret < 0) {
+               SERVER_ERR("Fail to write on console directly");
+       }
+
+       close(fd);
+}
+
+int rm_get_product_type(void)
+{
+       if (product_type_init)
+               return product_type;
+
+       int type = 0; /* SYSTEM_INFO_PRODUCT_TYPE_TV */
+
+       if (system_info_get_custom_int("com.samsung/featureconf/product.product_type", &type) != SYSTEM_INFO_ERROR_NONE) {
+               SERVER_ERR("Failed to get com.samsung/featureconf/product.product_type");
+       }
+
+       product_type_init = true;
+       product_type = type;
+
+       return product_type;
+}
+
+int rm_is_valid_pid(int pid)
+{
+       if (kill((pid_t) pid, 0) == 0) {
+               SERVER_INFO("pid(%d) is alive", pid);
+               return 1;
+       }
+
+       SERVER_ERR("pid(%d) / errno(%d)", pid, errno);
+
+       return (errno == ESRCH) ? 0 : 1;
+}
+
+static void process_htable_destory_key(gpointer key)
+{
+       if (key)
+               free(key);
+}
+
+static void process_htable_create(void)
+{
+       if (process_htable) {
+               SERVER_ERR("hash table already created");
+               return;
+       }
+
+       process_htable = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)process_htable_destory_key, NULL);
+
+       SERVER_INFO("process hash table created");
+}
+
+static void process_htable_clear(void)
+{
+       SERVER_INFO("clear process hash table");
+
+       if (!process_htable)
+               return;
+
+       g_hash_table_remove_all(process_htable);
+}
+
+static void process_htable_insert(const char *name)
+{
+       const int PROCESS_DATA_LIMIT = 100; // The maxinum size is (RMS_NAME_BUF_SIZE * PROCESS_DATA_LIMIT)
+
+       if (!process_htable)
+               process_htable_create();
+
+       if (g_hash_table_contains(process_htable, name))
+               return;
+
+       if (g_hash_table_size(process_htable) >= PROCESS_DATA_LIMIT)
+               process_htable_clear();
+
+       char *key_name = (char*) strndup(name, strlen(name));
+
+       g_hash_table_insert(process_htable, key_name, (gpointer) 1);
+
+       SERVER_ERR("process info (%s) inserted to hash table (%d)", name, g_hash_table_size(process_htable));
+}
+
+
+bool process_htable_contains(const char *name)
+{
+       bool result = false;
+
+       if (!process_htable) {
+               SERVER_INFO("(%s) - no table", name);
+               return false;
+       }
+
+       if (g_hash_table_size(process_htable) == 0) {
+               SERVER_INFO("(%s) - empty", name);
+               return false;
+       }
+
+       result = g_hash_table_contains(process_htable, name);
+
+       SERVER_INFO("(%s) - result(%d)", name, result);
+
+       // resource manager is supposed to clear data once it's checked by application
+       process_htable_clear();
+
+       return result;
+}
+
+int rms_report_emergency(IN int cid, IN int pid, IN int requester)
+{
+       const char *vconf_request_cold_poweroff = "memory/boot/cold_poweroff_request_pkg";
+       int retry = 25; // 20ms * 25 times => 500ms
+       int ret = 0;
+
+       SERVER_ERR("consumer is not responding....CID[%d]/PID[%d]/Requester(%d) - set cold power off mode", cid, pid, requester);
+
+       if (vconf_set_str(vconf_request_cold_poweroff, "resource-manager") != 0) {
+               SERVER_ERR("Failed to set request cold power off");
+       } else {
+               SERVER_ERR("memory/boot/cold_poweroff_request_pkg set as resource-manager");
+       }
+
+       char process_name[RMS_NAME_BUF_SIZE] = {0,};
+
+       if (rms_get_cmd_name(pid, process_name, RMS_NAME_BUF_SIZE) == RMS_OK) {
+               process_htable_insert(process_name);
+       }
+
+       SERVER_ERR("kill PID(%d)", pid);
+
+       int signal = SIGKILL;
+
+       if (RMS_IS_DEBUG_IMAGE) {
+               signal = SIGABRT;
+               retry = 250; // 20ms * 250 times => 5 sec
+       }
+
+       ret = kill(pid, signal);
+
+       if (ret!=0) {
+               SERVER_ERR("Failed to kill(%d), errno(%d)", pid, errno);
+       }
+
+       // wait until process is really terminated for 500ms
+       while (retry > 0 && rm_is_valid_pid(pid)) {
+               retry--;
+               SERVER_ERR("pid(%d) still alive(%d)", pid, retry);
+               usleep(20*1000);
+               continue;
+       }
+
+       if (RMS_IS_DEBUG_IMAGE && retry <= 0) {
+               //process didn't get terminated for 5 seconds
+               SERVER_ERR("pid(%d) is not terminated.", pid);
+               return RMS_ERROR;
+       }
+
+       return RMS_OK;
+}
+
+void rms_display_timeout_error_popup(rms_alarm_reason_e reason, rms_consumer_tobe_returned_s info)
+{
+       const char *title = "Resource Allocation Failure";
+       const char *style_notification_msg = "<font_size=30 color=#00FF00>";
+       const char *style_process_name = "<font_size=25 color=#C90000>";
+       const char *indent = "                             ";
+       const char *notification_msg = "Please contact the owner(s) of process(es) below<br>";
+       const char *reason0 = " Resource allocation failed because there is no callback response from below process(es)<br> ";
+       const char *reason1 = " Resource allocation failed because below process(es) did not request deallocation<br> ";
+
+       char name[RMS_NAME_BUF_SIZE] = {0,};
+       GString *gstr;
+
+       if (!RMS_IS_DEBUG_IMAGE) {
+               SERVER_ERR("Not debug mode. Timeout alarm popup is not shown. reason(%d)", (int)reason);
+               return;
+       }
+
+       SERVER_ERR("timeout alarm");
+
+       gstr = g_string_new("");
+
+       if (!gstr) {
+               SERVER_ERR("Failed to create debug popup command");
+               return;
+       }
+
+       g_string_append_printf(gstr, "%s", style_notification_msg);
+
+       switch (reason) {
+               case RMS_ALARM_NO_CALLBACK_RESPONSE:
+                       g_string_append_printf(gstr, "%s%s", indent, reason0);
+                       break;
+               case RMS_ALARM_NO_DEALLOCATION:
+                       g_string_append_printf(gstr, "%s%s", indent, reason1);
+                       break;
+               default :
+                       break;
+       }
+
+       g_string_append_printf(gstr, "%s%s%s", indent, notification_msg, style_process_name);
+
+       rms_get_cmd_name(info.process_id, name, sizeof(name));
+       g_string_append_printf(gstr, "%s%s : %d - %s%s", indent, "pid", (int)(info.process_id), name, " <br>");
+
+       for (int i = 0; i < info.n_conflicted; i++) {
+               g_string_append_printf(gstr, "%s [%d] %s%s", indent, i+1, rm_convert_category_enum_to_string(info.conflicted_resources[i].category_id), " <br>");
+       }
+       rms_create_popup(title, gstr->str);
+       SERVER_ERR("Command: %s", gstr->str);
+       g_string_free(gstr, true);
+}
+
+static bool rms_read_index(int *data)
+{
+       FILE *fp = NULL;
+       char str[10] = {0,};
+       size_t str_size;
+       const char *filename = "/proc/device-tree/rm_tbl_idx";
+
+       if (!data) {
+               SERVER_ERR("invalid input : null data");
+               return false;
+       }
+
+       fp = fopen(filename, "rb");
+
+       if (!fp) {
+               SERVER_ERR("failed to open (%s) - errno(%d)", filename, errno);
+               return false;
+       }
+
+       str_size = fread(str, sizeof(char), sizeof(str)-1, fp);
+
+       str[str_size] = '\0';
+
+       if (str_size == 0) {
+               fclose(fp);
+               return false;
+       }
+
+       *data = atoi(str);
+
+       fclose(fp);
+       fp = NULL;
+
+       return true;
+}
+
+void rms_display_resource_table_error_popup(void)
+{
+       const char *title = "FATAL ERROR!!!";
+       const char *reason = " Resource Manager can't find a resource table for this board<br> ";
+       const char *style_notification_msg = "<font_size=30 color=#FF0000>";
+       const char *indent = "  ";
+       const char *notification_msg = "<br>";
+
+       GString *gstr = g_string_new("");
+       char *chipset_info;
+       int model_index = -1;
+
+       if (!gstr) {
+               SERVER_ERR("Failed to create debug popup command");
+               return;
+       }
+
+       g_string_append_printf(gstr, "%s%s", indent, reason);
+       g_string_append_printf(gstr, "%s%s%s", indent, notification_msg, style_notification_msg);
+       g_string_append_printf(gstr, "%sProduct type : %d%s", indent, rm_get_product_type(), " <br>");
+
+       if (system_info_get_custom_string("com.samsung/featureconf/product.chipset", &chipset_info)!= SYSTEM_INFO_ERROR_NONE) {
+               SERVER_ERR("Failed to get chipset from system-info");
+               goto end;
+       }
+
+       g_string_append_printf(gstr, "%sChipset : %s%s", indent, chipset_info, " <br>");
+
+       if (!rms_read_index(&model_index)) {
+               SERVER_ERR("failed to read model index");
+       }
+
+       g_string_append_printf(gstr, "%sIndex : %d%s", indent, model_index, " <br>");
+
+       rms_create_popup(title,gstr->str);
+
+       if (chipset_info) {
+               free(chipset_info);
+       }
+
+end:
+       g_string_free(gstr, true);
+       return;
+}
+
+void rms_print_model_info(void)
+{
+       static char *chipset_info = NULL;
+       static int rm_index = -1;
+
+       if (!chipset_info) {
+               if (system_info_get_custom_string("com.samsung/featureconf/product.chipset", &chipset_info)!= SYSTEM_INFO_ERROR_NONE)
+                       SERVER_ERR("Failed to get chipset");
+       }
+
+       if (rm_index == -1) {
+               if (!rms_read_index(&rm_index))
+                       SERVER_ERR("failed to read rm index");
+       }
+
+       SERVER_ERR("> chipset(%s)/product_type(%d)/rm_index(%d)", chipset_info? chipset_info:"", rm_get_product_type(), rm_index);
+
+       char buf[512];
+       snprintf(buf, 512, "resource table not loaded! > chipset(%s)/product_type(%d)/rm_index(%d)", chipset_info? chipset_info:"", rm_get_product_type(), rm_index);
+       rms_print_log_console(buf);
+}
+
+int is_symlink_file(const char *path)
+{
+       struct stat st;
+       if (lstat(path, &st) == -1) {
+               SERVER_ERR("stat error. file path(%s)", path);
+               return 0;
+       }
+
+       return (S_ISLNK(st.st_mode)) ? 1 : 0;
+}
+
+const char *rm_convert_error_type_to_string(rms_error_type_e error_type)
+{
+       switch (error_type) {
+               case RMS_ERR_TYPE_NONE:
+                       return "None";
+               case RMS_ERR_TYPE_REQUEST_OF_INVISIBLE_PROCESS:
+                       return "Request of invisible process";
+               case RMS_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS:
+                       return "Request of low priority process";
+               case RMS_ERR_TYPE_NOT_AVAILABLE_RESOURCE:
+                       return "Not available resource";
+               case RMS_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST:
+                       return "Requested resource does not exist";
+               case RMS_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER:
+                       return "Take resource from other consumer";
+               default:
+                       return "";
+       }
+}
index b094c2ab4b77ea403ad534240a8847a1eeebd5c3..bc2659a144bb778bfe7c3b5f927ea70c355cd79e 100644 (file)
@@ -1,84 +1,84 @@
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <mutex>\r
-#include <CLockController.h>\r
-\r
-std::mutex m;\r
-CLockController *CLockController::m_instance = nullptr;\r
-\r
-CLockController *CLockController::GetInstance(void)\r
-{\r
-       if (m_instance == nullptr)\r
-       {\r
-               m_instance = new(std::nothrow) CLockController();\r
-       }\r
-\r
-       return m_instance;\r
-}\r
-\r
-void CLockController::Lock(ResourceType rsc_type)\r
-{\r
-       std::unique_lock<std::mutex> lock(m);\r
-       unsigned int count = 0;\r
-       auto it = m_locks.find(rsc_type);\r
-\r
-       count = (it == m_locks.end()) ? 1 : ++it->second;\r
-\r
-       m_locks.insert(std::pair<ResourceType, unsigned int>(rsc_type, count));\r
-}\r
-\r
-void CLockController::Unlock(ResourceType rsc_type)\r
-{\r
-       std::unique_lock<std::mutex> lock(m);\r
-\r
-       auto it = m_locks.find(rsc_type);\r
-       if (it == m_locks.end())\r
-               return;\r
-\r
-       if (it->second == 0)\r
-               return;\r
-\r
-       m_locks.at(rsc_type) = --it->second;\r
-\r
-       if (m_locks.at(rsc_type) == 0)\r
-               NotifyUnlock();\r
-}\r
-\r
-unsigned int CLockController::GetLockCount(void)\r
-{\r
-       std::unique_lock<std::mutex> lock(m);\r
-       unsigned int count = 0;\r
-\r
-       for (auto &it : m_locks)\r
-               count += it.second;\r
-\r
-       return count;\r
-}\r
-\r
-void CLockController::NotifyUnlock(void)\r
-{\r
-       CMessage *msg = new CMessage("NotifyUnlock");\r
-       m_msg_q->push(msg);\r
-}\r
-\r
-bool CLockController::IsLocked(CMessage *msg)\r
-{\r
-       if ((m_locks.at(ResourceType::VIDEO_SCALER) > 0) && msg->IsMsgFor(ResourceType::VIDEO_SCALER))\r
-               return true;\r
-\r
-       return false;\r
-}\r
+/*
+ * 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 <mutex>
+#include <CLockController.h>
+
+std::mutex m;
+CLockController *CLockController::m_instance = nullptr;
+
+CLockController *CLockController::GetInstance(void)
+{
+       if (m_instance == nullptr)
+       {
+               m_instance = new(std::nothrow) CLockController();
+       }
+
+       return m_instance;
+}
+
+void CLockController::Lock(ResourceType rsc_type)
+{
+       std::unique_lock<std::mutex> lock(m);
+       unsigned int count = 0;
+       auto it = m_locks.find(rsc_type);
+
+       count = (it == m_locks.end()) ? 1 : ++it->second;
+
+       m_locks.insert(std::pair<ResourceType, unsigned int>(rsc_type, count));
+}
+
+void CLockController::Unlock(ResourceType rsc_type)
+{
+       std::unique_lock<std::mutex> lock(m);
+
+       auto it = m_locks.find(rsc_type);
+       if (it == m_locks.end())
+               return;
+
+       if (it->second == 0)
+               return;
+
+       m_locks.at(rsc_type) = --it->second;
+
+       if (m_locks.at(rsc_type) == 0)
+               NotifyUnlock();
+}
+
+unsigned int CLockController::GetLockCount(void)
+{
+       std::unique_lock<std::mutex> lock(m);
+       unsigned int count = 0;
+
+       for (auto &it : m_locks)
+               count += it.second;
+
+       return count;
+}
+
+void CLockController::NotifyUnlock(void)
+{
+       CMessage *msg = new CMessage("NotifyUnlock");
+       m_msg_q->push(msg);
+}
+
+bool CLockController::IsLocked(CMessage *msg)
+{
+       if ((m_locks.at(ResourceType::VIDEO_SCALER) > 0) && msg->IsMsgFor(ResourceType::VIDEO_SCALER))
+               return true;
+
+       return false;
+}
index f85ee2129157b23c5b4b85c95ace5faff5ef2368..79f4612a240d15f291338964b2ecca4917e8d640 100644 (file)
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <rms_type.h>\r
-#include <rms_debug.h>\r
-#include <CResource.h>\r
-#include <CConsumer.h>\r
-#include <CResourceDB.h>\r
-#include <CConsumerContainer.h>\r
-#include <CPriority.h>\r
-\r
-int CPriority::compare(int cur_consumer_id, int consumer_id)\r
-{\r
-       CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
-       CConsumer *cur_consumer = c_container->findConsumer(cur_consumer_id);\r
-       if (!cur_consumer)\r
-               return HIGH_PRIORITY;\r
-\r
-       CConsumer *consumer = c_container->findConsumer(consumer_id);\r
-       if (!consumer)\r
-               return LOW_PRIORITY;\r
-\r
-       return (cur_consumer->ComparePriority(consumer) == RMS_ERR_TYPE_NONE) ? HIGH_PRIORITY : LOW_PRIORITY;\r
-}\r
-\r
-int CPriority::compareCurConsumers(int device_id, int consumer_id)\r
-{\r
-       CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
-\r
-       CConsumer *consumer = c_container->findConsumer(consumer_id);\r
-       if (!consumer)\r
-               return LOW_PRIORITY;\r
-\r
-       CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
-       if (!resource)\r
-               return HIGH_PRIORITY;\r
-\r
-       std::set<int> rsc_consumers = resource->GetConsumers();\r
-\r
-       for (auto const &it : rsc_consumers) {\r
-               CConsumer *rsc_consumer = c_container->findConsumer(it);\r
-\r
-               if (!rsc_consumer)\r
-                       continue;\r
-\r
-               if (rsc_consumer->GetId() == consumer_id) {\r
-                       SERVER_WARN("consumer(%d) is already using (%d)", consumer_id, device_id);\r
-                       return SAME_PRIORITY;\r
-               }\r
-\r
-               if (rsc_consumer->ComparePriority(consumer) != RMS_ERR_TYPE_NONE) {\r
-                       SERVER_WARN("LOW PRORITY consumer (%d) device (%d)", consumer_id, device_id);\r
-                       return LOW_PRIORITY;\r
-               }\r
-       }\r
-\r
-       return HIGH_PRIORITY;\r
-}\r
-\r
-int CPriority::getReclaimableConsumersShare(int device_id, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)\r
-{\r
-       CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
-       CConsumer *requester = CConsumerContainer::getInstance()->findConsumer(consumer_id);\r
-\r
-       if (!resource || !requester)\r
-               return RMS_ERROR;\r
-\r
-       if (resource->IsSharableState())\r
-               return RMS_ERROR;\r
-\r
-       std::set<int> consumers = resource->GetConsumers();\r
-\r
-       for (auto const &it : consumers) {\r
-               int cid = it;\r
-\r
-               if (isReclaimableConsumer(cid , consumer_id, err_type)) {\r
-                       reclaimables->insert(std::pair<int, int>(device_id, cid));\r
-                       break;\r
-               }\r
-       }\r
-\r
-       if (reclaimables->empty()) {\r
-               SERVER_ERR("high priority consumer is using device(%d)", device_id);\r
-               return RMS_ERROR;\r
-       }\r
-\r
-       return RMS_OK;\r
-}\r
-\r
-bool CPriority::isReclaimableConsumer(int consumer_id, int requester_id, rms_error_type_e *err_type)\r
-{\r
-       CConsumerContainer *c_container = CConsumerContainer::getInstance();\r
-       CConsumer *consumer = c_container->findConsumer(consumer_id);\r
-       CConsumer *requester = c_container->findConsumer(requester_id);\r
-\r
-       if (!consumer || !requester)\r
-               return false;\r
-\r
-       if (consumer_id == requester_id)\r
-               return false;\r
-\r
-       rms_error_type_e error_type = consumer->ComparePriority(requester);\r
-\r
-       if (error_type != RMS_ERR_TYPE_NONE) {\r
-               if (err_type)\r
-                       *err_type = error_type;\r
-\r
-               return false;\r
-       }\r
-\r
-       return true;\r
-}\r
-\r
-int CPriority::getReclaimableConsumers(int device_id, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)\r
-{\r
-       CResource *resource = CResourceDB::getInstance()->FindResource(device_id);\r
-       CConsumer *requester = CConsumerContainer::getInstance()->findConsumer(consumer_id);\r
-\r
-       if (!resource || !requester)\r
-               return RMS_ERROR;\r
-\r
-       if (resource->IsFreeState())\r
-               return RMS_ERROR;\r
-\r
-       std::set<int> consumers = resource->GetConsumers();\r
-\r
-       for (auto const &it : consumers) {\r
-               int cid = it;\r
-\r
-               if (!isReclaimableConsumer(cid , consumer_id, err_type))\r
-                       continue;\r
-\r
-               reclaimables->insert(std::pair<int, int>(device_id, cid));\r
-       }\r
-\r
-       if (reclaimables->empty())\r
-       {\r
-               SERVER_ERR("high priority consumer is using device(%d)", device_id);\r
-               return RMS_ERROR;\r
-       }\r
-\r
-       return RMS_OK;\r
-}\r
+/*
+ * 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 <rms_type.h>
+#include <rms_debug.h>
+#include <CResource.h>
+#include <CConsumer.h>
+#include <CResourceDB.h>
+#include <CConsumerContainer.h>
+#include <CPriority.h>
+
+int CPriority::compare(int cur_consumer_id, int consumer_id)
+{
+       CConsumerContainer *c_container = CConsumerContainer::getInstance();
+       CConsumer *cur_consumer = c_container->findConsumer(cur_consumer_id);
+       if (!cur_consumer)
+               return HIGH_PRIORITY;
+
+       CConsumer *consumer = c_container->findConsumer(consumer_id);
+       if (!consumer)
+               return LOW_PRIORITY;
+
+       return (cur_consumer->ComparePriority(consumer) == RMS_ERR_TYPE_NONE) ? HIGH_PRIORITY : LOW_PRIORITY;
+}
+
+int CPriority::compareCurConsumers(int device_id, int consumer_id)
+{
+       CConsumerContainer *c_container = CConsumerContainer::getInstance();
+
+       CConsumer *consumer = c_container->findConsumer(consumer_id);
+       if (!consumer)
+               return LOW_PRIORITY;
+
+       CResource *resource = CResourceDB::getInstance()->FindResource(device_id);
+       if (!resource)
+               return HIGH_PRIORITY;
+
+       std::set<int> rsc_consumers = resource->GetConsumers();
+
+       for (auto const &it : rsc_consumers) {
+               CConsumer *rsc_consumer = c_container->findConsumer(it);
+
+               if (!rsc_consumer)
+                       continue;
+
+               if (rsc_consumer->GetId() == consumer_id) {
+                       SERVER_WARN("consumer(%d) is already using (%d)", consumer_id, device_id);
+                       return SAME_PRIORITY;
+               }
+
+               if (rsc_consumer->ComparePriority(consumer) != RMS_ERR_TYPE_NONE) {
+                       SERVER_WARN("LOW PRORITY consumer (%d) device (%d)", consumer_id, device_id);
+                       return LOW_PRIORITY;
+               }
+       }
+
+       return HIGH_PRIORITY;
+}
+
+int CPriority::getReclaimableConsumersShare(int device_id, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)
+{
+       CResource *resource = CResourceDB::getInstance()->FindResource(device_id);
+       CConsumer *requester = CConsumerContainer::getInstance()->findConsumer(consumer_id);
+
+       if (!resource || !requester)
+               return RMS_ERROR;
+
+       if (resource->IsSharableState())
+               return RMS_ERROR;
+
+       std::set<int> consumers = resource->GetConsumers();
+
+       for (auto const &it : consumers) {
+               int cid = it;
+
+               if (isReclaimableConsumer(cid , consumer_id, err_type)) {
+                       reclaimables->insert(std::pair<int, int>(device_id, cid));
+                       break;
+               }
+       }
+
+       if (reclaimables->empty()) {
+               SERVER_ERR("high priority consumer is using device(%d)", device_id);
+               return RMS_ERROR;
+       }
+
+       return RMS_OK;
+}
+
+bool CPriority::isReclaimableConsumer(int consumer_id, int requester_id, rms_error_type_e *err_type)
+{
+       CConsumerContainer *c_container = CConsumerContainer::getInstance();
+       CConsumer *consumer = c_container->findConsumer(consumer_id);
+       CConsumer *requester = c_container->findConsumer(requester_id);
+
+       if (!consumer || !requester)
+               return false;
+
+       if (consumer_id == requester_id)
+               return false;
+
+       rms_error_type_e error_type = consumer->ComparePriority(requester);
+
+       if (error_type != RMS_ERR_TYPE_NONE) {
+               if (err_type)
+                       *err_type = error_type;
+
+               return false;
+       }
+
+       return true;
+}
+
+int CPriority::getReclaimableConsumers(int device_id, int consumer_id, std::multimap<int, int>* reclaimables, rms_error_type_e *err_type)
+{
+       CResource *resource = CResourceDB::getInstance()->FindResource(device_id);
+       CConsumer *requester = CConsumerContainer::getInstance()->findConsumer(consumer_id);
+
+       if (!resource || !requester)
+               return RMS_ERROR;
+
+       if (resource->IsFreeState())
+               return RMS_ERROR;
+
+       std::set<int> consumers = resource->GetConsumers();
+
+       for (auto const &it : consumers) {
+               int cid = it;
+
+               if (!isReclaimableConsumer(cid , consumer_id, err_type))
+                       continue;
+
+               reclaimables->insert(std::pair<int, int>(device_id, cid));
+       }
+
+       if (reclaimables->empty())
+       {
+               SERVER_ERR("high priority consumer is using device(%d)", device_id);
+               return RMS_ERROR;
+       }
+
+       return RMS_OK;
+}
index 1b7fb6111f9e3b86786d9a1863fa187937be01e6..f72f63a7eb6b66f03859909844795bc25a1b4c21 100644 (file)
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <iostream>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <algorithm>\r
-#include <time.h>\r
-\r
-#include <trace.h>\r
-#include <vconf.h>\r
-\r
-#include <CDebugUtils.h>\r
-#include <rms_debug.h>\r
-#include <rms_type.h>\r
-#include <ri-common-type.h>\r
-#include <ri-module-api.h>\r
-\r
-#include <CResourceObserver.h>\r
-#include <CResource.h>\r
-\r
-#define RMS_SUBSCALER_FLAG "memory/rsc_mgr/subscaler_status"\r
-\r
-using namespace std;\r
-void CResource::m_SetSubScalerFlag(int next_state)\r
-{\r
-       if (next_state == RMS_INTERNAL_STATE_ERROR)\r
-               return;\r
-       int value = 0;\r
-       switch (next_state) {\r
-               case RMS_INTERNAL_STATE_FREE:\r
-                       value = 0;\r
-                       break;\r
-               case RMS_INTERNAL_STATE_SHARABLE:\r
-               case RMS_INTERNAL_STATE_SHARED:\r
-               case RMS_INTERNAL_STATE_EXCLUSIVE:\r
-                       value = 1;\r
-                       break;\r
-       }\r
-       if (vconf_set_int(RMS_SUBSCALER_FLAG,value) != 0) {\r
-               SERVER_ERR("Failed to Set vconf key - %s",RMS_SUBSCALER_FLAG);\r
-               return;\r
-       }\r
-       SERVER_INFO("Subscaler flag set to - %d", value);\r
-}\r
-\r
-CResource::CResource(const int device_id, const rms_rsc_category_e category_type, const char *name, const char *path,\r
-                       std::set<unsigned int> mem_cluster, int is_main_device, const char *audio_codec, int sharable_count)\r
-:m_id(device_id), m_device_name(name), m_device_path(path), m_is_main_device(is_main_device), m_sharable_count(sharable_count)\r
-{\r
-       m_mem_clusters = mem_cluster;\r
-\r
-       if (audio_codec)\r
-               m_audio_codec.assign(audio_codec);\r
-\r
-       m_category_type = category_type;\r
-       m_cur_category = category_type;\r
-       m_is_scaler = IsScaler(category_type);\r
-}\r
-\r
-CResource::~CResource()\r
-{\r
-}\r
-\r
-bool CResource::IsScaler(rms_rsc_category_e category)\r
-{\r
-       bool result = false;\r
-\r
-       switch (category) {\r
-               case RMS_CATEGORY_SCALER:\r
-               case RMS_CATEGORY_SCALER_BG:\r
-               case RMS_CATEGORY_SCALER_SUB:\r
-               case RMS_CATEGORY_SCALER_SUB2:\r
-               case RMS_CATEGORY_SCALER_SUB3:\r
-                       result = true;\r
-                       break;\r
-               default:\r
-                       break;\r
-       }\r
-\r
-       return result;\r
-}\r
-\r
-void CResource::UpdateProperties(std::set<unsigned int> mem_clusters, int bw, int category, int category_class, int vrsc_id)\r
-{\r
-       m_mem_clusters = mem_clusters;\r
-       m_occupied_bw = bw;\r
-       m_cur_category = category;\r
-       m_category_class = category_class;\r
-       m_vrsc_id = vrsc_id;\r
-}\r
-\r
-int CResource::ReserveExclusive(int consumer_id)\r
-{\r
-       if (m_is_reserved && (consumer_id != m_reserved_consumer_id)) {\r
-               SERVER_ERR("rsc(%d) already reserved by(%d)", m_id, m_reserved_consumer_id);\r
-               return RMS_ERROR;\r
-       }\r
-\r
-       m_reserved_consumer_id = consumer_id;\r
-       m_is_reserved = true;\r
-\r
-       return RMS_OK;\r
-}\r
-\r
-int CResource::ReserveShared(int consumer_id)\r
-{\r
-       if (m_is_reserved) {\r
-               SERVER_ERR("rsc(%d) already reserved by (%d) with exclusive mode", m_id, m_reserved_consumer_id);\r
-               return RMS_ERROR;\r
-       }\r
-\r
-       m_reserved_count++;\r
-\r
-       if ( (m_shared_count + m_reserved_count) > m_sharable_count) {\r
-               SERVER_ERR("can't reserve(%d) shared(%d), reserved(%d), max(%d)", m_id, m_shared_count, m_reserved_count, m_sharable_count);\r
-               m_reserved_count--;\r
-               return RMS_ERROR;\r
-       }\r
-\r
-       SERVER_INFO("reserve share(%d) shared(%d), reserved(%d), max(%d)", m_id, m_shared_count, m_reserved_count, m_sharable_count);\r
-\r
-       return RMS_OK;\r
-}\r
-\r
-int CResource::Reserve(int consumer_id, rms_requests_resource_state_e state)\r
-{\r
-       return (state == RMS_STATE_SHARABLE) ? ReserveShared(consumer_id):ReserveExclusive(consumer_id);\r
-}\r
-\r
-void CResource::CancelReservation(rms_requests_resource_state_e state)\r
-{\r
-       if (state == RMS_STATE_SHARABLE)\r
-               m_reserved_count = (--m_reserved_count < 0) ? 0 : m_reserved_count;\r
-       else\r
-               m_is_reserved = false;\r
-}\r
-\r
-void CResource::AddConsumer(IN const int consumer_id, IN rms_requests_resource_state_e state)\r
-{\r
-       if (IsRegisteredConsumer(consumer_id)) {\r
-               IncreaseRefCount(consumer_id);\r
-               m_shared_count++;\r
-               SERVER_INFO("[rsc(%d)]increase ref count of (%d), shared(%d) by consumers(%zu)", m_id, consumer_id, m_shared_count, m_shared_consumers.size());\r
-               return;\r
-       }\r
-\r
-       m_consumers.insert(std::pair<int, int>(consumer_id, 1));\r
-       m_consumer_ids.insert(consumer_id);\r
-\r
-       if (state == RMS_STATE_SHARABLE) {\r
-               m_shared_consumers.insert(consumer_id);\r
-               m_shared_count++;\r
-               SERVER_INFO("[rsc(%d)] consumer(%d) shares resource, shared(%d) by consumers(%zu)", m_id, consumer_id, m_shared_count, m_shared_consumers.size());\r
-       }\r
-\r
-       return;\r
-}\r
-\r
-void CResource::ResetConsumer(std::set<int> new_consumers)\r
-{\r
-       m_consumers.clear();\r
-       m_consumer_ids.clear();\r
-       m_shared_consumers.clear();\r
-       m_shared_count = 0;\r
-\r
-       for (auto &it : new_consumers) {\r
-               AddConsumer(it, RMS_STATE_EXCLUSIVE);\r
-       }\r
-}\r
-\r
-bool CResource::IsRegisteredConsumer(int consumer_id)\r
-{\r
-       std::map<int, int>::iterator it = m_consumers.find(consumer_id);\r
-\r
-       return (it != m_consumers.end());\r
-}\r
-\r
-int CResource::IncreaseRefCount(int consumer_id)\r
-{\r
-       int ref_count = 0;\r
-       std::map<int, int>::iterator it = m_consumers.find(consumer_id);\r
-\r
-       if (it == m_consumers.end())\r
-               return 0;\r
-\r
-       ref_count = it->second;\r
-       m_consumers[consumer_id] = ++ref_count;\r
-\r
-       return ref_count;\r
-}\r
-\r
-int CResource::DecreaseRefCount(int consumer_id)\r
-{\r
-       int ref_count = 0;\r
-       std::map<int, int>::iterator it = m_consumers.find(consumer_id);\r
-\r
-       if (it == m_consumers.end())\r
-               return 0;\r
-\r
-       ref_count = it->second;\r
-       --ref_count;\r
-       ref_count = (ref_count < 0) ? 0 : ref_count;\r
-       m_consumers[consumer_id] = ref_count;\r
-\r
-       return ref_count;\r
-}\r
-\r
-int CResource::RemoveConsumer(IN int consumer_id, IN bool force)\r
-{\r
-       if (!IsRegisteredConsumer(consumer_id)) {\r
-               SERVER_ERR("[rsc(%d)] consumer(%d) is not found in list", m_id, consumer_id);\r
-               return 0;\r
-       }\r
-\r
-       int ref_count = DecreaseRefCount(consumer_id);\r
-\r
-       if (m_state == RMS_INTERNAL_STATE_SHARABLE || m_state == RMS_INTERNAL_STATE_SHARED) {\r
-               m_shared_count = (--m_shared_count < 0) ? 0 : m_shared_count;\r
-\r
-               if (force)\r
-                       m_shared_count = ((m_shared_count -= ref_count) < 0) ? 0 : m_shared_count;\r
-       }\r
-\r
-       if (ref_count > 0 && !force) {\r
-               SERVER_INFO("consumer(%d) is still sharing resource(%d), ref(%d)", consumer_id, m_id, ref_count);\r
-               return ref_count;\r
-       }\r
-\r
-       m_consumer_ids.erase(consumer_id);\r
-       m_consumers.erase(consumer_id);\r
-       ChangeStateByRelease(consumer_id);\r
-\r
-       return 0;\r
-}\r
-\r
-void CResource::ChangeState(rms_resource_internal_state_e next_state)\r
-{\r
-       if (m_state == next_state)\r
-               return;\r
-\r
-       SERVER_INFO("state changed (%s : %s) - (%s -> %s)",\r
-               rm_convert_category_enum_to_string(m_category_type),\r
-               m_device_name,\r
-               rm_convert_state_enum_to_string(m_state),\r
-               rm_convert_state_enum_to_string(next_state));\r
-\r
-       m_state = next_state;\r
-\r
-       if (m_category_type == RMS_CATEGORY_SCALER_SUB)\r
-               m_SetSubScalerFlag(next_state);\r
-}\r
-\r
-bool CResource::ChangeStateByAllocation(IN rms_requests_resource_state_e requested_state, const int consumer_id, int mv_zone_id)\r
-{\r
-       if (requested_state == RMS_STATE_EXCLUSIVE_CONDITIONAL || requested_state == RMS_STATE_EXCLUSIVE_AUTO || requested_state == RMS_STATE_EXCLUSIVE_PREFERENCE)\r
-               requested_state = RMS_STATE_EXCLUSIVE;\r
-\r
-       rms_resource_internal_state_e allocation_resource_state_matrix[4][3] =\r
-                                                               {{RMS_INTERNAL_STATE_ERROR, RMS_INTERNAL_STATE_SHARABLE, RMS_INTERNAL_STATE_EXCLUSIVE},\r
-                                                               {RMS_INTERNAL_STATE_SHARABLE, RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_ERROR},\r
-                                                               {RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_ERROR},\r
-                                                               {RMS_INTERNAL_STATE_EXCLUSIVE, RMS_INTERNAL_STATE_ERROR, RMS_INTERNAL_STATE_ERROR}};\r
-\r
-       bool need_notify_by_alloc_matrix[4][3] = {{false, true, true},\r
-                                                                       {false, true, false},\r
-                                                                       {false, true, false},\r
-                                                                       {false, false, true}};\r
-\r
-       rms_resource_internal_state_e next_state = allocation_resource_state_matrix[m_state][requested_state];\r
-       SERVER_INFO("m_state %d requested_state %d next_state %d", m_state, requested_state, next_state);\r
-\r
-       bool need_notify = need_notify_by_alloc_matrix[m_state][requested_state];\r
-\r
-       m_is_reserved = false;\r
-       m_reserved_consumer_id = 0;\r
-\r
-       if (next_state == RMS_INTERNAL_STATE_ERROR) {\r
-               SERVER_ERR("state change error! device(%d) (%s) to (%s)", m_id, rm_convert_state_enum_to_string(m_state), rm_convert_state_enum_to_string(next_state));\r
-               return false;\r
-       }\r
-\r
-       m_state = next_state;\r
-\r
-       if (m_category_type == RMS_CATEGORY_SCALER_SUB)\r
-               m_SetSubScalerFlag(next_state);\r
-\r
-       if (mv_zone_id > 0) {\r
-               m_mv_zone_id = mv_zone_id;\r
-               SERVER_INFO("(%d) > zone_id(%d)", m_id, m_mv_zone_id);\r
-       }\r
-\r
-       if (need_notify)\r
-               NotifyObservers(UPDATED_BY_ALLOC, consumer_id);\r
-\r
-       return true;\r
-}\r
-\r
-bool CResource::ChangeStateByRelease(int consumer_id)\r
-{\r
-       rms_resource_internal_state_e current_state = m_state;\r
-       rms_resource_internal_state_e next_state = RMS_INTERNAL_STATE_ERROR;\r
-\r
-       bool need_notify = false;\r
-\r
-       SERVER_INFO("current_state %d m_shared_count %d", current_state, m_shared_count);\r
-\r
-       switch (current_state) {\r
-               case RMS_INTERNAL_STATE_SHARED:\r
-                       m_shared_consumers.erase(consumer_id);\r
-                       need_notify = true;\r
-\r
-                       if (m_shared_count > 1) {\r
-                               next_state = RMS_INTERNAL_STATE_SHARED;\r
-                       } else if (m_shared_count == 1) {\r
-                               next_state = RMS_INTERNAL_STATE_SHARABLE;\r
-                       } else {\r
-                               next_state = RMS_INTERNAL_STATE_FREE;\r
-                       }\r
-                       break;\r
-               case RMS_INTERNAL_STATE_EXCLUSIVE:\r
-               case RMS_INTERNAL_STATE_SHARABLE:\r
-                       next_state = RMS_INTERNAL_STATE_FREE;\r
-                       need_notify = true;\r
-                       break;\r
-               case RMS_INTERNAL_STATE_FREE:\r
-               default:\r
-                       SERVER_ERR("unexpected resource state (%d)", current_state);\r
-                       next_state = RMS_INTERNAL_STATE_FREE;\r
-                       break;\r
-       }\r
-\r
-       m_state = next_state;\r
-       SERVER_INFO("m_state %d need notify %d", m_state, need_notify);\r
-\r
-       if (m_category_type == RMS_CATEGORY_SCALER_SUB)\r
-               m_SetSubScalerFlag(next_state);\r
-\r
-       if (need_notify) {\r
-               m_mv_zone_id = -1;\r
-               NotifyObservers(UPDATED_BY_RELEASE, consumer_id);\r
-       }\r
-\r
-       return true;\r
-}\r
-\r
-bool CResource::IsAllocatableState(IN rms_requests_resource_state_e requested_state)\r
-{\r
-       bool can_allocation_matrix[4][6] =\r
-                                               /*requested_state*/ /* PASSIVE */ /*SHARABLE*/ /*EXCLUSIVE*/ /* EXCLUSIVE CON */ /* EXCLUSIVE AUTO */ /* EXCLUSIVE PREFERENCE */\r
-                       /* m_state */ /* FREE */{ {false, true, true, true, true, true },\r
-                                               /* SHARABLE */ { true, true, false, false, false, false },\r
-                                               /* SHARED */ { true, true, false, false, false, false },\r
-                                               /* EXCLUSIVE */ { true, false, false, false, false, false } };\r
-\r
-       SERVER_INFO("Status - DevID[%d:%s] / CatID[%d] / CurState[%s] / ReqState[%s]",\r
-               m_id, m_device_name, m_category_type, rm_convert_state_enum_to_string(m_state), rm_convert_requested_state_enum_to_string(requested_state));\r
-\r
-       /* check requested_state is valid */\r
-       if ((requested_state < RMS_STATE_PASSIVE) || (requested_state > RMS_STATE_EXCLUSIVE_PREFERENCE)) {\r
-               SERVER_ERR("rquested state is invalid");\r
-               return false;\r
-       }\r
-\r
-       return can_allocation_matrix[m_state][requested_state];\r
-}\r
-\r
-void CResource::SetDefaultBW(unsigned int bw)\r
-{\r
-       m_default_bw = bw;\r
-       m_occupied_bw = bw;\r
-}\r
-void CResource::SetAllocatedTime(void)\r
-{\r
-       struct timespec t;\r
-       clock_gettime(CLOCK_MONOTONIC, &t);\r
-       unsigned long sec = t.tv_sec * 1000;\r
-       unsigned long nsec = t.tv_nsec / 1000000;\r
-       m_allocated_time = sec + nsec;\r
-}\r
-\r
-void CResource::RegisterObserver(CResourceObserver *observer)\r
-{\r
-       if (!observer) {\r
-               SERVER_ERR("observer NULL");\r
-               return;\r
-       }\r
-\r
-       m_observers.push_back(observer);\r
-}\r
-\r
-void CResource::UnregisterObserver(CResourceObserver *observer)\r
-{\r
-       auto it = std::find(m_observers.begin(), m_observers.end(), observer);\r
-\r
-       if (it == m_observers.end()) {\r
-               SERVER_ERR("not registered observer");\r
-               return;\r
-       }\r
-\r
-       m_observers.erase(it);\r
-\r
-       SERVER_INFO("observer removed");\r
-}\r
-\r
-void CResource::NotifyObservers(resource_update_type_e type, const int consumer_id)\r
-{\r
-       for (CResourceObserver *observer : m_observers) {\r
-               observer->Update(type, m_id, consumer_id);\r
-       }\r
-}\r
-\r
-bool CResource::Allocate(const int consumer_id, rms_requests_resource_state_e state, int mv_zone_id)\r
-{\r
-       if (!ChangeStateByAllocation(state, consumer_id, mv_zone_id))\r
-               return false;\r
-\r
-       AddConsumer(consumer_id, state);\r
-       return true;\r
-}\r
-\r
-void CResource::SetZoneId(int zone_id)\r
-{\r
-       SERVER_INFO("(%d) > zone_id(%d)", m_id, zone_id);\r
-       m_mv_zone_id = zone_id;\r
-}\r
-\r
-void CResource::UpdateAudioCodec(std::string codec_name)\r
-{\r
-       m_audio_codec = codec_name;\r
-}\r
-\r
-bool CResource::IsAudioDevice(void)\r
-{\r
-       if (m_category_type == RMS_CATEGORY_AUDIO_DECODER)\r
-               return true;\r
-       if (m_category_type == RMS_CATEGORY_AUDIO_DECODER_SUB)\r
-               return true;\r
-       if (m_category_type == RMS_CATEGORY_AUDIO_DECODER_PRIMARY)\r
-               return true;\r
-       if ((m_category_type > RMS_CATEGORY_AUDIO_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_AUDIO_DECODER_OPTION_MAX))\r
-               return true;\r
-\r
-       return false;\r
-}\r
-\r
-bool CResource::IsVideoDecoder(void)\r
-{\r
-       if (m_category_type == RMS_CATEGORY_VIDEO_DECODER)\r
-               return true;\r
-       if (m_category_type == RMS_CATEGORY_VIDEO_DECODER_SUB)\r
-               return true;\r
-       if ((m_category_type > RMS_CATEGORY_VIDEO_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_VIDEO_DECODER_OPTION_MAX))\r
-               return true;\r
-       if (m_category_type == RMS_CATEGORY_MJPEG_DECODER)\r
-               return true;\r
-       if ((m_category_type > RMS_CATEGORY_MJPEG_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_MJPEG_DECODER_OPTION_MAX))\r
-               return true;\r
-\r
-       return false;\r
-}\r
-\r
-int CResource::GetFirstConsumer(void)\r
-{\r
-       if (m_consumer_ids.empty())\r
-               return -1;\r
-\r
-       auto it = m_consumer_ids.begin();\r
-       return *it;\r
-}\r
-\r
-int CResource::GetVirtualDeviceId(void)\r
-{\r
-       return (m_virtual_id < RI_VIRTUAL_ID_SCALER) ? m_id : m_virtual_id;\r
-}\r
-\r
-bool CResource::IsJpegDecoder(void)\r
-{\r
-       if (m_category_type == RMS_CATEGORY_JPEG_DECODER)\r
-               return true;\r
-       if ((m_category_type > RMS_CATEGORY_JPEG_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_JPEG_DECODER_OPTION_MAX))\r
-               return true;\r
-\r
-       return false;\r
-}\r
+/*
+ * 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 <iostream>
+#include <string.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <time.h>
+
+#include <trace.h>
+#include <vconf.h>
+
+#include <CDebugUtils.h>
+#include <rms_debug.h>
+#include <rms_type.h>
+#include <ri-common-type.h>
+#include <ri-module-api.h>
+
+#include <CResourceObserver.h>
+#include <CResource.h>
+
+#define RMS_SUBSCALER_FLAG "memory/rsc_mgr/subscaler_status"
+
+using namespace std;
+void CResource::m_SetSubScalerFlag(int next_state)
+{
+       if (next_state == RMS_INTERNAL_STATE_ERROR)
+               return;
+       int value = 0;
+       switch (next_state) {
+               case RMS_INTERNAL_STATE_FREE:
+                       value = 0;
+                       break;
+               case RMS_INTERNAL_STATE_SHARABLE:
+               case RMS_INTERNAL_STATE_SHARED:
+               case RMS_INTERNAL_STATE_EXCLUSIVE:
+                       value = 1;
+                       break;
+       }
+       if (vconf_set_int(RMS_SUBSCALER_FLAG,value) != 0) {
+               SERVER_ERR("Failed to Set vconf key - %s",RMS_SUBSCALER_FLAG);
+               return;
+       }
+       SERVER_INFO("Subscaler flag set to - %d", value);
+}
+
+CResource::CResource(const int device_id, const rms_rsc_category_e category_type, const char *name, const char *path,
+                       std::set<unsigned int> mem_cluster, int is_main_device, const char *audio_codec, int sharable_count)
+:m_id(device_id), m_device_name(name), m_device_path(path), m_is_main_device(is_main_device), m_sharable_count(sharable_count)
+{
+       m_mem_clusters = mem_cluster;
+
+       if (audio_codec)
+               m_audio_codec.assign(audio_codec);
+
+       m_category_type = category_type;
+       m_cur_category = category_type;
+       m_is_scaler = IsScaler(category_type);
+}
+
+CResource::~CResource()
+{
+}
+
+bool CResource::IsScaler(rms_rsc_category_e category)
+{
+       bool result = false;
+
+       switch (category) {
+               case RMS_CATEGORY_SCALER:
+               case RMS_CATEGORY_SCALER_BG:
+               case RMS_CATEGORY_SCALER_SUB:
+               case RMS_CATEGORY_SCALER_SUB2:
+               case RMS_CATEGORY_SCALER_SUB3:
+                       result = true;
+                       break;
+               default:
+                       break;
+       }
+
+       return result;
+}
+
+void CResource::UpdateProperties(std::set<unsigned int> mem_clusters, int bw, int category, int category_class, int vrsc_id)
+{
+       m_mem_clusters = mem_clusters;
+       m_occupied_bw = bw;
+       m_cur_category = category;
+       m_category_class = category_class;
+       m_vrsc_id = vrsc_id;
+}
+
+int CResource::ReserveExclusive(int consumer_id)
+{
+       if (m_is_reserved && (consumer_id != m_reserved_consumer_id)) {
+               SERVER_ERR("rsc(%d) already reserved by(%d)", m_id, m_reserved_consumer_id);
+               return RMS_ERROR;
+       }
+
+       m_reserved_consumer_id = consumer_id;
+       m_is_reserved = true;
+
+       return RMS_OK;
+}
+
+int CResource::ReserveShared(int consumer_id)
+{
+       if (m_is_reserved) {
+               SERVER_ERR("rsc(%d) already reserved by (%d) with exclusive mode", m_id, m_reserved_consumer_id);
+               return RMS_ERROR;
+       }
+
+       m_reserved_count++;
+
+       if ( (m_shared_count + m_reserved_count) > m_sharable_count) {
+               SERVER_ERR("can't reserve(%d) shared(%d), reserved(%d), max(%d)", m_id, m_shared_count, m_reserved_count, m_sharable_count);
+               m_reserved_count--;
+               return RMS_ERROR;
+       }
+
+       SERVER_INFO("reserve share(%d) shared(%d), reserved(%d), max(%d)", m_id, m_shared_count, m_reserved_count, m_sharable_count);
+
+       return RMS_OK;
+}
+
+int CResource::Reserve(int consumer_id, rms_requests_resource_state_e state)
+{
+       return (state == RMS_STATE_SHARABLE) ? ReserveShared(consumer_id):ReserveExclusive(consumer_id);
+}
+
+void CResource::CancelReservation(rms_requests_resource_state_e state)
+{
+       if (state == RMS_STATE_SHARABLE)
+               m_reserved_count = (--m_reserved_count < 0) ? 0 : m_reserved_count;
+       else
+               m_is_reserved = false;
+}
+
+void CResource::AddConsumer(IN const int consumer_id, IN rms_requests_resource_state_e state)
+{
+       if (IsRegisteredConsumer(consumer_id)) {
+               IncreaseRefCount(consumer_id);
+               m_shared_count++;
+               SERVER_INFO("[rsc(%d)]increase ref count of (%d), shared(%d) by consumers(%zu)", m_id, consumer_id, m_shared_count, m_shared_consumers.size());
+               return;
+       }
+
+       m_consumers.insert(std::pair<int, int>(consumer_id, 1));
+       m_consumer_ids.insert(consumer_id);
+
+       if (state == RMS_STATE_SHARABLE) {
+               m_shared_consumers.insert(consumer_id);
+               m_shared_count++;
+               SERVER_INFO("[rsc(%d)] consumer(%d) shares resource, shared(%d) by consumers(%zu)", m_id, consumer_id, m_shared_count, m_shared_consumers.size());
+       }
+
+       return;
+}
+
+void CResource::ResetConsumer(std::set<int> new_consumers)
+{
+       m_consumers.clear();
+       m_consumer_ids.clear();
+       m_shared_consumers.clear();
+       m_shared_count = 0;
+
+       for (auto &it : new_consumers) {
+               AddConsumer(it, RMS_STATE_EXCLUSIVE);
+       }
+}
+
+bool CResource::IsRegisteredConsumer(int consumer_id)
+{
+       std::map<int, int>::iterator it = m_consumers.find(consumer_id);
+
+       return (it != m_consumers.end());
+}
+
+int CResource::IncreaseRefCount(int consumer_id)
+{
+       int ref_count = 0;
+       std::map<int, int>::iterator it = m_consumers.find(consumer_id);
+
+       if (it == m_consumers.end())
+               return 0;
+
+       ref_count = it->second;
+       m_consumers[consumer_id] = ++ref_count;
+
+       return ref_count;
+}
+
+int CResource::DecreaseRefCount(int consumer_id)
+{
+       int ref_count = 0;
+       std::map<int, int>::iterator it = m_consumers.find(consumer_id);
+
+       if (it == m_consumers.end())
+               return 0;
+
+       ref_count = it->second;
+       --ref_count;
+       ref_count = (ref_count < 0) ? 0 : ref_count;
+       m_consumers[consumer_id] = ref_count;
+
+       return ref_count;
+}
+
+int CResource::RemoveConsumer(IN int consumer_id, IN bool force)
+{
+       if (!IsRegisteredConsumer(consumer_id)) {
+               SERVER_ERR("[rsc(%d)] consumer(%d) is not found in list", m_id, consumer_id);
+               return 0;
+       }
+
+       int ref_count = DecreaseRefCount(consumer_id);
+
+       if (m_state == RMS_INTERNAL_STATE_SHARABLE || m_state == RMS_INTERNAL_STATE_SHARED) {
+               m_shared_count = (--m_shared_count < 0) ? 0 : m_shared_count;
+
+               if (force)
+                       m_shared_count = ((m_shared_count -= ref_count) < 0) ? 0 : m_shared_count;
+       }
+
+       if (ref_count > 0 && !force) {
+               SERVER_INFO("consumer(%d) is still sharing resource(%d), ref(%d)", consumer_id, m_id, ref_count);
+               return ref_count;
+       }
+
+       m_consumer_ids.erase(consumer_id);
+       m_consumers.erase(consumer_id);
+       ChangeStateByRelease(consumer_id);
+
+       return 0;
+}
+
+void CResource::ChangeState(rms_resource_internal_state_e next_state)
+{
+       if (m_state == next_state)
+               return;
+
+       SERVER_INFO("state changed (%s : %s) - (%s -> %s)",
+               rm_convert_category_enum_to_string(m_category_type),
+               m_device_name,
+               rm_convert_state_enum_to_string(m_state),
+               rm_convert_state_enum_to_string(next_state));
+
+       m_state = next_state;
+
+       if (m_category_type == RMS_CATEGORY_SCALER_SUB)
+               m_SetSubScalerFlag(next_state);
+}
+
+bool CResource::ChangeStateByAllocation(IN rms_requests_resource_state_e requested_state, const int consumer_id, int mv_zone_id)
+{
+       if (requested_state == RMS_STATE_EXCLUSIVE_CONDITIONAL || requested_state == RMS_STATE_EXCLUSIVE_AUTO || requested_state == RMS_STATE_EXCLUSIVE_PREFERENCE)
+               requested_state = RMS_STATE_EXCLUSIVE;
+
+       rms_resource_internal_state_e allocation_resource_state_matrix[4][3] =
+                                                               {{RMS_INTERNAL_STATE_ERROR, RMS_INTERNAL_STATE_SHARABLE, RMS_INTERNAL_STATE_EXCLUSIVE},
+                                                               {RMS_INTERNAL_STATE_SHARABLE, RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_ERROR},
+                                                               {RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_SHARED, RMS_INTERNAL_STATE_ERROR},
+                                                               {RMS_INTERNAL_STATE_EXCLUSIVE, RMS_INTERNAL_STATE_ERROR, RMS_INTERNAL_STATE_ERROR}};
+
+       bool need_notify_by_alloc_matrix[4][3] = {{false, true, true},
+                                                                       {false, true, false},
+                                                                       {false, true, false},
+                                                                       {false, false, true}};
+
+       rms_resource_internal_state_e next_state = allocation_resource_state_matrix[m_state][requested_state];
+       SERVER_INFO("m_state %d requested_state %d next_state %d", m_state, requested_state, next_state);
+
+       bool need_notify = need_notify_by_alloc_matrix[m_state][requested_state];
+
+       m_is_reserved = false;
+       m_reserved_consumer_id = 0;
+
+       if (next_state == RMS_INTERNAL_STATE_ERROR) {
+               SERVER_ERR("state change error! device(%d) (%s) to (%s)", m_id, rm_convert_state_enum_to_string(m_state), rm_convert_state_enum_to_string(next_state));
+               return false;
+       }
+
+       m_state = next_state;
+
+       if (m_category_type == RMS_CATEGORY_SCALER_SUB)
+               m_SetSubScalerFlag(next_state);
+
+       if (mv_zone_id > 0) {
+               m_mv_zone_id = mv_zone_id;
+               SERVER_INFO("(%d) > zone_id(%d)", m_id, m_mv_zone_id);
+       }
+
+       if (need_notify)
+               NotifyObservers(UPDATED_BY_ALLOC, consumer_id);
+
+       return true;
+}
+
+bool CResource::ChangeStateByRelease(int consumer_id)
+{
+       rms_resource_internal_state_e current_state = m_state;
+       rms_resource_internal_state_e next_state = RMS_INTERNAL_STATE_ERROR;
+
+       bool need_notify = false;
+
+       SERVER_INFO("current_state %d m_shared_count %d", current_state, m_shared_count);
+
+       switch (current_state) {
+               case RMS_INTERNAL_STATE_SHARED:
+                       m_shared_consumers.erase(consumer_id);
+                       need_notify = true;
+
+                       if (m_shared_count > 1) {
+                               next_state = RMS_INTERNAL_STATE_SHARED;
+                       } else if (m_shared_count == 1) {
+                               next_state = RMS_INTERNAL_STATE_SHARABLE;
+                       } else {
+                               next_state = RMS_INTERNAL_STATE_FREE;
+                       }
+                       break;
+               case RMS_INTERNAL_STATE_EXCLUSIVE:
+               case RMS_INTERNAL_STATE_SHARABLE:
+                       next_state = RMS_INTERNAL_STATE_FREE;
+                       need_notify = true;
+                       break;
+               case RMS_INTERNAL_STATE_FREE:
+               default:
+                       SERVER_ERR("unexpected resource state (%d)", current_state);
+                       next_state = RMS_INTERNAL_STATE_FREE;
+                       break;
+       }
+
+       m_state = next_state;
+       SERVER_INFO("m_state %d need notify %d", m_state, need_notify);
+
+       if (m_category_type == RMS_CATEGORY_SCALER_SUB)
+               m_SetSubScalerFlag(next_state);
+
+       if (need_notify) {
+               m_mv_zone_id = -1;
+               NotifyObservers(UPDATED_BY_RELEASE, consumer_id);
+       }
+
+       return true;
+}
+
+bool CResource::IsAllocatableState(IN rms_requests_resource_state_e requested_state)
+{
+       bool can_allocation_matrix[4][6] =
+                                               /*requested_state*/ /* PASSIVE */ /*SHARABLE*/ /*EXCLUSIVE*/ /* EXCLUSIVE CON */ /* EXCLUSIVE AUTO */ /* EXCLUSIVE PREFERENCE */
+                       /* m_state */ /* FREE */{ {false, true, true, true, true, true },
+                                               /* SHARABLE */ { true, true, false, false, false, false },
+                                               /* SHARED */ { true, true, false, false, false, false },
+                                               /* EXCLUSIVE */ { true, false, false, false, false, false } };
+
+       SERVER_INFO("Status - DevID[%d:%s] / CatID[%d] / CurState[%s] / ReqState[%s]",
+               m_id, m_device_name, m_category_type, rm_convert_state_enum_to_string(m_state), rm_convert_requested_state_enum_to_string(requested_state));
+
+       /* check requested_state is valid */
+       if ((requested_state < RMS_STATE_PASSIVE) || (requested_state > RMS_STATE_EXCLUSIVE_PREFERENCE)) {
+               SERVER_ERR("rquested state is invalid");
+               return false;
+       }
+
+       return can_allocation_matrix[m_state][requested_state];
+}
+
+void CResource::SetDefaultBW(unsigned int bw)
+{
+       m_default_bw = bw;
+       m_occupied_bw = bw;
+}
+void CResource::SetAllocatedTime(void)
+{
+       struct timespec t;
+       clock_gettime(CLOCK_MONOTONIC, &t);
+       unsigned long sec = t.tv_sec * 1000;
+       unsigned long nsec = t.tv_nsec / 1000000;
+       m_allocated_time = sec + nsec;
+}
+
+void CResource::RegisterObserver(CResourceObserver *observer)
+{
+       if (!observer) {
+               SERVER_ERR("observer NULL");
+               return;
+       }
+
+       m_observers.push_back(observer);
+}
+
+void CResource::UnregisterObserver(CResourceObserver *observer)
+{
+       auto it = std::find(m_observers.begin(), m_observers.end(), observer);
+
+       if (it == m_observers.end()) {
+               SERVER_ERR("not registered observer");
+               return;
+       }
+
+       m_observers.erase(it);
+
+       SERVER_INFO("observer removed");
+}
+
+void CResource::NotifyObservers(resource_update_type_e type, const int consumer_id)
+{
+       for (CResourceObserver *observer : m_observers) {
+               observer->Update(type, m_id, consumer_id);
+       }
+}
+
+bool CResource::Allocate(const int consumer_id, rms_requests_resource_state_e state, int mv_zone_id)
+{
+       if (!ChangeStateByAllocation(state, consumer_id, mv_zone_id))
+               return false;
+
+       AddConsumer(consumer_id, state);
+       return true;
+}
+
+void CResource::SetZoneId(int zone_id)
+{
+       SERVER_INFO("(%d) > zone_id(%d)", m_id, zone_id);
+       m_mv_zone_id = zone_id;
+}
+
+void CResource::UpdateAudioCodec(std::string codec_name)
+{
+       m_audio_codec = codec_name;
+}
+
+bool CResource::IsAudioDevice(void)
+{
+       if (m_category_type == RMS_CATEGORY_AUDIO_DECODER)
+               return true;
+       if (m_category_type == RMS_CATEGORY_AUDIO_DECODER_SUB)
+               return true;
+       if (m_category_type == RMS_CATEGORY_AUDIO_DECODER_PRIMARY)
+               return true;
+       if ((m_category_type > RMS_CATEGORY_AUDIO_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_AUDIO_DECODER_OPTION_MAX))
+               return true;
+
+       return false;
+}
+
+bool CResource::IsVideoDecoder(void)
+{
+       if (m_category_type == RMS_CATEGORY_VIDEO_DECODER)
+               return true;
+       if (m_category_type == RMS_CATEGORY_VIDEO_DECODER_SUB)
+               return true;
+       if ((m_category_type > RMS_CATEGORY_VIDEO_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_VIDEO_DECODER_OPTION_MAX))
+               return true;
+       if (m_category_type == RMS_CATEGORY_MJPEG_DECODER)
+               return true;
+       if ((m_category_type > RMS_CATEGORY_MJPEG_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_MJPEG_DECODER_OPTION_MAX))
+               return true;
+
+       return false;
+}
+
+int CResource::GetFirstConsumer(void)
+{
+       if (m_consumer_ids.empty())
+               return -1;
+
+       auto it = m_consumer_ids.begin();
+       return *it;
+}
+
+int CResource::GetVirtualDeviceId(void)
+{
+       return (m_virtual_id < RI_VIRTUAL_ID_SCALER) ? m_id : m_virtual_id;
+}
+
+bool CResource::IsJpegDecoder(void)
+{
+       if (m_category_type == RMS_CATEGORY_JPEG_DECODER)
+               return true;
+       if ((m_category_type > RMS_CATEGORY_JPEG_DECODER_OPTION) && (m_category_type < RMS_CATEGORY_JPEG_DECODER_OPTION_MAX))
+               return true;
+
+       return false;
+}
index 4cae0b16c703852187f573ed0a202a894d04067e..6d8719697d6a4ba1c8a6fe21bbeaf9c275e92848 100644 (file)
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <stdlib.h>\r
-#include <iostream>\r
-\r
-#include <CResourceCategory.h>\r
-#include <CBandwidth.h>\r
-#include <CRequest.h>\r
-#include <CVirtualResource.h>\r
-#include <CDebugUtils.h>\r
-#include <CDependencyController.h>\r
-#include <CAllocateStrategy.h>\r
-#include <CAllocateStrategyProvider.h>\r
-#include <rms_debug.h>\r
-#include <rms_type.h>\r
-\r
-CResourceCategory::CResourceCategory(IN rms_rsc_category_e resource_category_id, IN int category_class)\r
-:m_categoryID(resource_category_id)\r
-{\r
-       m_alloc_strategy = CAllocateStrategyProvider::getInstance()->GetStrategy(resource_category_id, category_class);\r
-       assert(m_alloc_strategy);\r
-}\r
-\r
-CResourceCategory::~CResourceCategory()\r
-{\r
-       delete m_alloc_strategy;\r
-}\r
-\r
-void CResourceCategory::AddVirtualResource(IN int device_id, IN CVirtualResource *vresource)\r
-{\r
-       std::map<int, CVirtualResource *>::iterator it = m_device_id_to_vresource_map.find(device_id);\r
-\r
-       if (it != m_device_id_to_vresource_map.end())\r
-               return;\r
-\r
-       m_device_id_to_vresource_map.insert(std::pair<int, CVirtualResource *>(device_id, vresource));\r
-}\r
-\r
-CResource *CResourceCategory::ReserveCandidate(CRequest *req, bool apply_promotion)\r
-{\r
-       CVirtualResource *vrsc = m_alloc_strategy->findCandidate(m_device_id_to_vresource_map, req);\r
-\r
-       if (!vrsc)\r
-               return NULL;\r
-\r
-       if (m_alloc_strategy->reserveResource(vrsc, req) != RMS_OK) {\r
-               SERVER_INFO("can't find candidate (%d)", m_categoryID);\r
-               return NULL;\r
-       }\r
-\r
-       SERVER_INFO("candidate found (%d:%d)", m_categoryID, vrsc->GetResource()->GetDeviceID());\r
-\r
-       req->SetResult(RMS_OK);\r
-       req->SetReason(RMS_ERR_TYPE_NONE);\r
-\r
-       return vrsc->GetResource();\r
-}\r
-\r
-bool CResourceCategory::hasFreeStateResource(void)\r
-{\r
-       for (auto& it : m_device_id_to_vresource_map) {\r
-               CVirtualResource *vresource = it.second;\r
-               CResource *resource = vresource->GetResource();\r
-\r
-               if (resource->IsFreeState())\r
-                       return true;\r
-       }\r
-\r
-       return false;\r
-}\r
-\r
-void CResourceCategory::MakeResourceMapSortedByAllocTime(std::multimap<unsigned long, CVirtualResource *> *resource_map)\r
-{\r
-       for (auto& it : m_device_id_to_vresource_map) {\r
-               CVirtualResource *vresource = it.second;\r
-               CResource *rsc = vresource->GetResource();\r
-\r
-               resource_map->insert(std::pair<unsigned long, CVirtualResource *>(rsc->GetAllocatedTime(), vresource));\r
-       }\r
-}\r
-\r
-void CResourceCategory::GetRetirableConsumers(CRequest *req,\r
-                                                                                                       std::multimap<int, int>* return_ids_in_category,\r
-                                                                                                       rms_error_type_e *err_type)\r
-{\r
-       assert(return_ids_in_category);\r
-\r
-       std::multimap<unsigned long, CVirtualResource *> sorted_resource_map;\r
-       MakeResourceMapSortedByAllocTime(&sorted_resource_map);\r
-       m_alloc_strategy->GetRetirableConsumers(sorted_resource_map, req, return_ids_in_category, err_type);\r
-}\r
-\r
-bool CResourceCategory::IsAvailableToUse(rms_requests_resource_state_e request_state)\r
-{\r
-       CResource *resource;\r
-       CDependencyController *dc = CDependencyController::getInstance();\r
-       CBandwidth *bandwidth = CBandwidth::GetInstance();\r
-\r
-       for (auto& it : m_device_id_to_vresource_map) {\r
-               CVirtualResource *vresource = it.second;\r
-               resource = vresource->GetResource();\r
-\r
-               if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {\r
-                       SERVER_ERR("Not available: Mem Cluster is occupied.");\r
-                       continue;\r
-               }\r
-\r
-               if (vresource->GetBW() > bandwidth->GetAvail()) {\r
-                       SERVER_ERR("Not available: BW is insufficient!!");\r
-                       continue;\r
-               }\r
-\r
-               if ((request_state == RMS_STATE_SHARABLE) && (!resource->IsSharableDevice())) {\r
-                       SERVER_ERR("Not available: resource(%d) cannot be shared", resource->GetDeviceID());\r
-                       continue;\r
-               }\r
-\r
-               if (resource->IsAllocatableState(request_state))\r
-                       return true;\r
-       }\r
-\r
-       return false;\r
-}\r
-\r
-void CResourceCategory::GetResources(std::map<int, CResource*> *resource_map)\r
-{\r
-       int i = 0;\r
-       for (auto& it : m_device_id_to_vresource_map) {\r
-               CVirtualResource *vresource = it.second;\r
-               CResource *resource = vresource->GetResource();\r
-               resource_map->insert(std::pair<int, CResource*>(i++, resource));\r
-       }\r
-}\r
-\r
-CResource *CResourceCategory::FindMainResource(void)\r
-{\r
-       for (auto& it : m_device_id_to_vresource_map) {\r
-               CVirtualResource *vresource = it.second;\r
-               CResource *resource = vresource->GetResource();\r
-\r
-               if (resource->IsMainDevice())\r
-                       return resource;\r
-       }\r
-\r
-       return NULL;\r
-}\r
+/*
+ * 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 <stdlib.h>
+#include <iostream>
+
+#include <CResourceCategory.h>
+#include <CBandwidth.h>
+#include <CRequest.h>
+#include <CVirtualResource.h>
+#include <CDebugUtils.h>
+#include <CDependencyController.h>
+#include <CAllocateStrategy.h>
+#include <CAllocateStrategyProvider.h>
+#include <rms_debug.h>
+#include <rms_type.h>
+
+CResourceCategory::CResourceCategory(IN rms_rsc_category_e resource_category_id, IN int category_class)
+:m_categoryID(resource_category_id)
+{
+       m_alloc_strategy = CAllocateStrategyProvider::getInstance()->GetStrategy(resource_category_id, category_class);
+       assert(m_alloc_strategy);
+}
+
+CResourceCategory::~CResourceCategory()
+{
+       delete m_alloc_strategy;
+}
+
+void CResourceCategory::AddVirtualResource(IN int device_id, IN CVirtualResource *vresource)
+{
+       std::map<int, CVirtualResource *>::iterator it = m_device_id_to_vresource_map.find(device_id);
+
+       if (it != m_device_id_to_vresource_map.end())
+               return;
+
+       m_device_id_to_vresource_map.insert(std::pair<int, CVirtualResource *>(device_id, vresource));
+}
+
+CResource *CResourceCategory::ReserveCandidate(CRequest *req, bool apply_promotion)
+{
+       CVirtualResource *vrsc = m_alloc_strategy->findCandidate(m_device_id_to_vresource_map, req);
+
+       if (!vrsc)
+               return NULL;
+
+       if (m_alloc_strategy->reserveResource(vrsc, req) != RMS_OK) {
+               SERVER_INFO("can't find candidate (%d)", m_categoryID);
+               return NULL;
+       }
+
+       SERVER_INFO("candidate found (%d:%d)", m_categoryID, vrsc->GetResource()->GetDeviceID());
+
+       req->SetResult(RMS_OK);
+       req->SetReason(RMS_ERR_TYPE_NONE);
+
+       return vrsc->GetResource();
+}
+
+bool CResourceCategory::hasFreeStateResource(void)
+{
+       for (auto& it : m_device_id_to_vresource_map) {
+               CVirtualResource *vresource = it.second;
+               CResource *resource = vresource->GetResource();
+
+               if (resource->IsFreeState())
+                       return true;
+       }
+
+       return false;
+}
+
+void CResourceCategory::MakeResourceMapSortedByAllocTime(std::multimap<unsigned long, CVirtualResource *> *resource_map)
+{
+       for (auto& it : m_device_id_to_vresource_map) {
+               CVirtualResource *vresource = it.second;
+               CResource *rsc = vresource->GetResource();
+
+               resource_map->insert(std::pair<unsigned long, CVirtualResource *>(rsc->GetAllocatedTime(), vresource));
+       }
+}
+
+void CResourceCategory::GetRetirableConsumers(CRequest *req,
+                                                                                                       std::multimap<int, int>* return_ids_in_category,
+                                                                                                       rms_error_type_e *err_type)
+{
+       assert(return_ids_in_category);
+
+       std::multimap<unsigned long, CVirtualResource *> sorted_resource_map;
+       MakeResourceMapSortedByAllocTime(&sorted_resource_map);
+       m_alloc_strategy->GetRetirableConsumers(sorted_resource_map, req, return_ids_in_category, err_type);
+}
+
+bool CResourceCategory::IsAvailableToUse(rms_requests_resource_state_e request_state)
+{
+       CResource *resource;
+       CDependencyController *dc = CDependencyController::getInstance();
+       CBandwidth *bandwidth = CBandwidth::GetInstance();
+
+       for (auto& it : m_device_id_to_vresource_map) {
+               CVirtualResource *vresource = it.second;
+               resource = vresource->GetResource();
+
+               if (!dc->isAvailableMemClusters(vresource->GetMemClusters())) {
+                       SERVER_ERR("Not available: Mem Cluster is occupied.");
+                       continue;
+               }
+
+               if (vresource->GetBW() > bandwidth->GetAvail()) {
+                       SERVER_ERR("Not available: BW is insufficient!!");
+                       continue;
+               }
+
+               if ((request_state == RMS_STATE_SHARABLE) && (!resource->IsSharableDevice())) {
+                       SERVER_ERR("Not available: resource(%d) cannot be shared", resource->GetDeviceID());
+                       continue;
+               }
+
+               if (resource->IsAllocatableState(request_state))
+                       return true;
+       }
+
+       return false;
+}
+
+void CResourceCategory::GetResources(std::map<int, CResource*> *resource_map)
+{
+       int i = 0;
+       for (auto& it : m_device_id_to_vresource_map) {
+               CVirtualResource *vresource = it.second;
+               CResource *resource = vresource->GetResource();
+               resource_map->insert(std::pair<int, CResource*>(i++, resource));
+       }
+}
+
+CResource *CResourceCategory::FindMainResource(void)
+{
+       for (auto& it : m_device_id_to_vresource_map) {
+               CVirtualResource *vresource = it.second;
+               CResource *resource = vresource->GetResource();
+
+               if (resource->IsMainDevice())
+                       return resource;
+       }
+
+       return NULL;
+}
index ce93b025067df237a5eb30b459c1538b7cf2172b..b72113764f89d29c5a5ed06c602d7f42141743ac 100644 (file)
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <iostream>\r
-#include <assert.h>\r
-#include <stdlib.h>\r
-#include <glib.h>\r
-#include <gio/gio.h>\r
-\r
-#include <ri-module-api.h>\r
-#include <vconf.h>\r
-\r
-#include <rms_debug.h>\r
-#include <rms_type.h>\r
-\r
-#include <CDebugUtils.h>\r
-#include <CAudioCodecCollection.h>\r
-#include <CBandwidth.h>\r
-#include <CVirtualResource.h>\r
-#include <CConsumer.h>\r
-#include <CConsumerContainer.h>\r
-#include <CDependencyController.h>\r
-#include <CResourceDB.h>\r
-#include <CVideoController.h>\r
-#include <CResourceState.h>\r
-\r
-CResourceDB *CResourceDB::m_instance = NULL;\r
-\r
-CResourceDB *CResourceDB::getInstance(void)\r
-{\r
-       if (!m_instance) {\r
-               m_instance = new(std::nothrow) CResourceDB;\r
-               assert(m_instance);\r
-       }\r
-\r
-       return m_instance;\r
-}\r
-\r
-CResourceCategory *CResourceDB::FindResourceCategory(IN rms_rsc_category_e category_id)\r
-{\r
-       std::map<rms_rsc_category_e, CResourceCategory*>::iterator it = m_resourceCategoryMap.find(category_id);\r
-\r
-       if (it == m_resourceCategoryMap.end())\r
-               return NULL;\r
-\r
-       return (*it).second;\r
-}\r
-\r
-CResource *CResourceDB::FindResource(IN const int device_id)\r
-{\r
-       std::map<int, CResource*>::iterator it = m_deviceid_to_rsc.find(device_id);\r
-\r
-       if (it == m_deviceid_to_rsc.end()) {\r
-               SERVER_ERR("no device id(%d) in DB", device_id);\r
-               return NULL;\r
-       }\r
-\r
-       return (*it).second;\r
-}\r
-\r
-CVirtualResource *CResourceDB::FindVirtualResource(const int vid)\r
-{\r
-       auto it = m_v_deviceid_to_rsc.find(vid);\r
-\r
-       return (it == m_v_deviceid_to_rsc.end()) ? nullptr : it->second;\r
-}\r
-\r
-void CResourceDB::AddVirtualDeviceID(IN CVirtualResource *vresource)\r
-{\r
-       int vrsc_id = vresource->GetVResourceID();\r
-\r
-       std::map<int, CVirtualResource *>::iterator it = m_v_deviceid_to_rsc.find(vrsc_id);\r
-\r
-       if (it != m_v_deviceid_to_rsc.end())\r
-               return;\r
-\r
-       m_v_deviceid_to_rsc.insert(std::pair<int, CVirtualResource *>(vrsc_id, vresource));\r
-}\r
-\r
-void CResourceDB::AddDeviceID(IN int device_id, IN CResource *resource)\r
-{\r
-       std::map<int, CResource*>::iterator it = m_deviceid_to_rsc.find(device_id);\r
-       \r
-       if (it != m_deviceid_to_rsc.end())\r
-               return;\r
-\r
-       m_deviceid_to_rsc.insert(std::pair<int, CResource*>(device_id, resource));\r
-}\r
-\r
-void CResourceDB::AddDeviceName(IN const char *device_name, IN CResource *resource)\r
-{\r
-       auto it = m_devicename_to_rsc.find(std::string(device_name));\r
-       \r
-       if (it != m_devicename_to_rsc.end()) {\r
-               SERVER_DBG("already registered device name(%s) in DB", device_name);\r
-               return;\r
-       }\r
-\r
-       m_devicename_to_rsc.insert(std::pair<std::string, CResource*>(std::string(device_name), resource));\r
-}\r
-\r
-void CResourceDB::AddResourceCategory(IN rms_rsc_category_e category_id, IN CResourceCategory *resource_category)\r
-{\r
-       std::map<rms_rsc_category_e, CResourceCategory*>::iterator it = m_resourceCategoryMap.find(category_id);\r
-\r
-       if (it != m_resourceCategoryMap.end())\r
-               return;\r
-\r
-       m_resourceCategoryMap.insert(std::pair<rms_rsc_category_e, CResourceCategory*>(category_id, resource_category));\r
-}\r
-\r
-CResource *CResourceDB::FindResource(const char *device_name)\r
-{\r
-       auto it = m_devicename_to_rsc.find(std::string(device_name));\r
-\r
-       return (it == m_devicename_to_rsc.end()) ? NULL : it->second;\r
-}\r
-\r
-void CResourceDB::AddVirtualResource(IN CVirtualResource *vrsc,\r
-                                                      IN rms_rsc_category_e resource_category_id,\r
-                                                      IN const char *name,\r
-                                                      IN const char *path,\r
-                                                      IN std::set<unsigned int> mem_cluster_info,\r
-                                                      IN unsigned int device_id_unique,\r
-                                                      IN int is_main_device,\r
-                                                      IN const char *audio_codec,\r
-                                                      IN int sharable_count,\r
-                                                      IN int mixing_count,\r
-                                                      IN CResourceObserver *observer)\r
-{\r
-       assert(name);\r
-       assert(path);\r
-\r
-       CResource *rsc = FindResource(name);\r
-\r
-       if (!rsc) {\r
-               rsc = new CResource(device_id_unique, resource_category_id, name, path, mem_cluster_info, is_main_device, audio_codec, sharable_count);\r
-\r
-               AddDeviceName(name, rsc);\r
-               AddDeviceID(device_id_unique, rsc);\r
-\r
-               rsc->RegisterObserver(this);\r
-               rsc->RegisterObserver(observer);\r
-       }\r
-\r
-       vrsc->SetResource(rsc);\r
-\r
-       CAudioCodecCollection::getInstance()->registerAudioCodec(audio_codec, mixing_count);\r
-\r
-       if (rsc->GetDefaultBW() == 0)\r
-               rsc->SetDefaultBW(vrsc->GetBW());\r
-\r
-       AddVirtualDeviceID(vrsc);\r
-}\r
-\r
-void CResourceDB::UpdateBWbyRelease(CResource *rsc)\r
-{\r
-       if (!rsc)\r
-               return;\r
-\r
-       if (rsc->GetBW() == 0)\r
-               return;\r
-\r
-       CBandwidth *bw = CBandwidth::GetInstance();\r
-       bw->RemoveConsumer(rsc->GetDeviceID(), rsc->GetCurCategory(), rsc->GetCategoryClass());\r
-       bw->Increase(rsc->GetBW(), rsc->GetCurCategory(), rsc->GetCategoryClass(), rsc->GetDeviceID());\r
-\r
-       return;\r
-}\r
-\r
-void CResourceDB::UpdateByRelease(CResource *resource, const int device_id, const int consumer_id)\r
-{\r
-       UpdateBWbyRelease(resource);\r
-\r
-       if (resource->IsVideoDecoder())\r
-               RemoveActiveVideoDecoder(device_id, resource->GetCategoryClass());\r
-\r
-       if (resource->IsJpegDecoder())\r
-               RemoveActiveJpegDecoder(device_id);\r
-\r
-       RemoveResourceHasZoneId(resource->GetDeviceID());\r
-}\r
-\r
-void CResourceDB::UpdateBWbyAllocation(const unsigned int bandwidth, CResource *rsc)\r
-{\r
-       CBandwidth *bw = CBandwidth::GetInstance();\r
-       bw->Decrease(bandwidth, rsc->GetCurCategory(), rsc->GetCategoryClass(), rsc->GetDeviceID());\r
-\r
-       //SERVER_INFO("bw updated avail(%d)/max(%d)", bw->GetAvail(), bw->GetMax());\r
-}\r
-\r
-void CResourceDB::UpdateByAllocation(CResource *resource, const int device_id, const int consumer_id)\r
-{\r
-       unsigned int bw = resource->GetBW();\r
-\r
-       if (bw > 0) {\r
-               UpdateBWbyAllocation(bw, resource);\r
-               CBandwidth::GetInstance()->AddConsumer(device_id, consumer_id, resource->GetCurCategory(), resource->GetCategoryClass());\r
-       }\r
-\r
-       if (resource->IsVideoDecoder())\r
-               AddActiveVideoDecoder(device_id, consumer_id, resource->GetCategoryClass());\r
-\r
-       if (resource->IsScaler())\r
-               SetVirtualScalerId(resource);\r
-\r
-       if (resource->IsJpegDecoder())\r
-               AddActiveJpegDecoder(device_id, consumer_id);\r
-\r
-       if (resource->GetZoneId() > 0)\r
-               InsertResourceHasZoneId(resource);\r
-}\r
-\r
-void CResourceDB::SetVirtualScalerId(CResource *resource)\r
-{\r
-       int scaler_id = GetVirtualScalerId(resource);\r
-\r
-       SERVER_INFO("map scaler (%d:%d)", scaler_id, resource->GetDeviceID());\r
-\r
-       resource->SetVirtualDeviceId(scaler_id);\r
-       InsertVirtualScaler(scaler_id, resource);\r
-}\r
-\r
-void CResourceDB::PrintVirtualScalerMap(void)\r
-{\r
-       for (auto &it : m_scaler_map) {\r
-               if (it.second == nullptr) {\r
-                       //SERVER_INFO("[%d : %d (%s)]", it.first, 0, "null");\r
-                       continue;\r
-               }\r
-               //SERVER_INFO("[%d : %d (%s)/(%d)]", it.first, it.second->GetDeviceID(), it.second->GetName().c_str(), it.second->GetVirtualDeviceId());\r
-       }\r
-}\r
-\r
-int CResourceDB::GetVirtualScalerId(CResource *resource)\r
-{\r
-       CResource *rsc = nullptr;\r
-\r
-       for (auto &it : m_scaler_map) {\r
-               rsc = it.second;\r
-               if (rsc == nullptr)\r
-                       continue;\r
-               if (rsc->GetDeviceID() == resource->GetDeviceID())\r
-                       return it.first;\r
-       }\r
-\r
-       return resource->GetDedicatedVirtualDeviceId();\r
-}\r
-\r
-void CResourceDB::AddActiveVideoDecoder(const int device_id, const int consumer_id, const int category_class)\r
-{\r
-       m_active_vdecs.insert(std::pair<int, int>(device_id, consumer_id));\r
-\r
-       if (category_class == RMS_CATEGORY_CLASS_N_DECODING)\r
-               m_active_nvdecs.insert(std::pair<int, int>(device_id, consumer_id));\r
-}\r
-\r
-void CResourceDB::RemoveActiveVideoDecoder(const int device_id, const int category_class)\r
-{\r
-       m_active_vdecs.erase(device_id);\r
-\r
-       if (category_class == RMS_CATEGORY_CLASS_N_DECODING)\r
-               m_active_nvdecs.erase(device_id);\r
-}\r
-\r
-void CResourceDB::AddActiveJpegDecoder(const int device_id, const int consumer_id)\r
-{\r
-       m_active_jdecs.insert(std::pair<int, int>(device_id, consumer_id));\r
-}\r
-\r
-void CResourceDB::RemoveActiveJpegDecoder(const int device_id)\r
-{\r
-       m_active_jdecs.erase(device_id);\r
-}\r
-\r
-int CResourceDB::GetActiveDecoderNum(void)\r
-{\r
-       int num = 0;\r
-\r
-       num += m_active_vdecs.size();\r
-       num += m_active_jdecs.size();\r
-\r
-       return num;\r
-}\r
-\r
-void CResourceDB::PrintVideoDecoderConsumers(void)\r
-{\r
-       for (auto const &it : m_active_vdecs) {\r
-               SERVER_INFO("dev(%d) by (%d)", it.first, it.second);\r
-       }\r
-}\r
-\r
-bool CResourceDB::HasAvailableDecoder(void)\r
-{\r
-       int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;\r
-       int active_vdecs = m_active_vdecs.size();\r
-       int active_ndecs = m_active_nvdecs.size();\r
-\r
-       SERVER_INFO("active(%d) / n_dec(%d) / max(%d / %d)", active_vdecs, active_ndecs, max_vdecs, m_max_vdecs);\r
-\r
-       if (active_ndecs > 0)\r
-               active_vdecs = active_vdecs + (1 - active_ndecs);\r
-\r
-       if (active_vdecs >= max_vdecs)\r
-               PrintVideoDecoderConsumers();\r
-\r
-       return (active_vdecs < max_vdecs);\r
-}\r
-\r
-bool CResourceDB::HasAvailableDecoderNDecoding(void)\r
-{\r
-       int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;\r
-       int active_vdecs = m_active_vdecs.size();\r
-       int active_ndecs = m_active_nvdecs.size();\r
-\r
-       SERVER_INFO("active(%d) / n_dec(%d) / max(%d %d)", active_vdecs, active_ndecs, max_vdecs, m_max_vdecs);\r
-\r
-       if (active_ndecs > 0) {\r
-               active_vdecs = active_vdecs + (1 - active_ndecs);\r
-               return true;\r
-       }\r
-\r
-       if (active_vdecs >= max_vdecs)\r
-               PrintVideoDecoderConsumers();\r
-\r
-       return (active_vdecs < max_vdecs);\r
-}\r
-\r
-bool CResourceDB::HasAvailableDecoder(std::multimap<int, int> retirables)\r
-{\r
-       int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;\r
-       std::map<int, int> retirables_vdecs;\r
-\r
-       SERVER_INFO("max(%d %d)", max_vdecs, m_max_vdecs);\r
-\r
-       for (auto &it : retirables) {\r
-               CResource *rsc = FindResource(it.first);\r
-               if (!rsc)\r
-                       continue;\r
-\r
-               if (rsc->IsVideoDecoder())\r
-                       retirables_vdecs.insert(std::pair<int, int>(it.first, it.second));\r
-       }\r
-\r
-       int active_vdecs = m_active_vdecs.size();\r
-       int active_ndecs = m_active_nvdecs.size();\r
-       int retirable_vdecs = retirables_vdecs.size();\r
-       int retirable_ndecs = CountNDecoders(retirables_vdecs);\r
-\r
-       int remain = 0;\r
-\r
-       if ((active_ndecs - retirable_ndecs) > 0)\r
-               remain = (active_vdecs - retirable_vdecs) + (1 - (active_ndecs - retirable_ndecs));\r
-       else\r
-               remain = active_vdecs - retirable_vdecs;\r
-\r
-       SERVER_INFO("remain(%d)/max(%d), av(%d)/an(%d)/rv(%d)/rn(%d)", remain, max_vdecs, active_vdecs, active_ndecs, retirable_vdecs, retirable_ndecs);\r
-\r
-       if (remain >= max_vdecs)\r
-               PrintVideoDecoderConsumers();\r
-\r
-       return (remain < max_vdecs);\r
-}\r
-\r
-bool CResourceDB::HasAvailableDecoderNDecoding(std::multimap<int, int> retirables)\r
-{\r
-       int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;\r
-       std::map<int, int> retirables_vdecs;\r
-\r
-       SERVER_INFO("max(%d %d)", max_vdecs, m_max_vdecs);\r
-\r
-       for (auto &it : retirables) {\r
-               CResource *rsc = FindResource(it.first);\r
-               if (!rsc)\r
-                       continue;\r
-\r
-               if (rsc->IsVideoDecoder())\r
-                       retirables_vdecs.insert(std::pair<int, int>(it.first, it.second));\r
-       }\r
-\r
-       int active_vdecs = m_active_vdecs.size();\r
-       int active_ndecs = m_active_nvdecs.size();\r
-       int retirable_vdecs = retirables_vdecs.size();\r
-       int retirable_ndecs = CountNDecoders(retirables_vdecs);\r
-\r
-       int remain = 0;\r
-\r
-       if ((active_ndecs - retirable_ndecs) > 0)\r
-               remain = (active_vdecs - retirable_vdecs) + (1 - (active_ndecs - retirable_ndecs));\r
-       else\r
-               remain = active_vdecs - retirable_vdecs;\r
-\r
-       SERVER_INFO("remain(%d)/max(%d), av(%d)/an(%d)/rv(%d)/rn(%d)", remain, max_vdecs, active_vdecs, active_ndecs, retirable_vdecs, retirable_ndecs);\r
-\r
-       if (active_ndecs > 0 && retirable_ndecs > 0)\r
-               return true;\r
-\r
-       if (remain >= max_vdecs)\r
-               PrintVideoDecoderConsumers();\r
-\r
-       return (remain < max_vdecs);\r
-}\r
-\r
-int CResourceDB::CountNDecoders(std::map<int, int> retirables_vdecs)\r
-{\r
-       int ndecs = 0;\r
-       for (auto &it_rsc : retirables_vdecs) {\r
-               auto it_ndec = m_active_nvdecs.find(it_rsc.first);\r
-\r
-               if (it_ndec != m_active_nvdecs.end())\r
-                       ndecs++;\r
-       }\r
-\r
-       SERVER_INFO("ndecs(%d) in retirables(%zu)", ndecs, retirables_vdecs.size());\r
-       return ndecs;\r
-}\r
-\r
-void CResourceDB::Update(resource_update_type_e type, const int device_id, const int consumer_id)\r
-{\r
-       CResource *resource = FindResource(device_id);\r
-\r
-       if (!resource)\r
-               return;\r
-\r
-       switch (type) {\r
-               case UPDATED_BY_ALLOC:\r
-                       SERVER_WARN("UPDATED_BY_ALLOC");\r
-                       UpdateByAllocation(resource, device_id, consumer_id);\r
-                       break;\r
-               case UPDATED_BY_RELEASE:\r
-                       SERVER_WARN("UPDATED_BY_RELEASE");\r
-                       UpdateByRelease(resource, device_id, consumer_id);\r
-                       break;\r
-               default:\r
-                       SERVER_ERR("unexpected update type (%d)", type);\r
-                       break;\r
-       }\r
-\r
-       NotifyResourceStateUpdatedAsync(resource, consumer_id);\r
-}\r
-\r
-void CResourceDB::AddReclaimResources(consumer_reclaim_s *consumers)\r
-{\r
-       for (int i = 0; i < consumers->ret_quantity; i++) {\r
-               for (int j = 0; j < consumers->consumer_info[i].n_conflicted; j++) {\r
-                       SERVER_INFO("add reclaim rsc (%d)", consumers->consumer_info[i].conflicted_resources[j].device_id);\r
-                       m_reclaim_rscs.insert(consumers->consumer_info[i].conflicted_resources[j].device_id);\r
-               }\r
-       }\r
-}\r
-\r
-void CResourceDB::ClearReclaimResources(void)\r
-{\r
-       m_reclaim_rscs.clear();\r
-}\r
-\r
-gboolean CResourceDB::NotifyResourceStateUpdated(gpointer data)\r
-{\r
-       if (!data) {\r
-               SERVER_ERR("invalid data");\r
-               return G_SOURCE_REMOVE;\r
-       }\r
-\r
-       CResourceState *state = (CResourceState*) data;\r
-\r
-       GError *error = NULL;\r
-       GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);\r
-\r
-       if (!connection) {\r
-               SERVER_ERR("failed to get connection (%s)", (error) ? error->message : "unknown");\r
-               goto out;\r
-       }\r
-\r
-       SERVER_INFO("notify state changed (device id %d( type %d) : state %d)", state->GetDeviceId(), state->GetCategoryType(), state->GetState());\r
-\r
-       if (!g_dbus_connection_emit_signal(connection,\r
-                                               NULL,\r
-                                               RM_DBUS_OBJ_PATH,\r
-                                               RM_DBUS_INTERFACE_NAME,\r
-                                               "RscStateChanged",\r
-                                               g_variant_new("(iiiis)", state->GetDeviceId(), state->GetCategoryType(), state->GetState(), state->GetConsumerId(), state->GetAppId().c_str()),\r
-                                               &error))\r
-               SERVER_ERR("failed to send state changed (%d:%s)", state->GetDeviceId(), (error) ? error->message : "unknown");\r
-\r
-out:\r
-       if (error)\r
-               g_error_free(error);\r
-\r
-       delete state;\r
-       return G_SOURCE_REMOVE;\r
-}\r
-\r
-void CResourceDB::NotifyResourceStateUpdatedAsync(CResource *resource, int consumer_id)\r
-{\r
-       int device_id = resource->GetDeviceID();\r
-       CConsumer *consumer = CConsumerContainer::getInstance()->findConsumer(consumer_id);\r
-\r
-       if (!consumer) {\r
-               SERVER_WARN("Consumer %d is not found", consumer_id);\r
-               return;\r
-       }\r
-\r
-       std::string app_id = consumer->GetAppID();\r
-\r
-       if (app_id.empty())\r
-               app_id = consumer->GetCmdName();\r
-\r
-       SERVER_INFO("device id (%d) consumer id (%d)", device_id, consumer_id);\r
-\r
-       if (m_reclaim_rscs.find(device_id) != m_reclaim_rscs.end()) {\r
-               SERVER_DBG("skip to notify state updated (%d)", device_id);\r
-               return;\r
-       }\r
-\r
-       CResourceState *state = new CResourceState(resource->GetDeviceID(), resource->GetCategoryType(), consumer_id, resource->GetState(), app_id);\r
-       g_idle_add(&CResourceDB::NotifyResourceStateUpdated, state);\r
-}\r
-\r
-CResource *CResourceDB::FindMainResource(rms_rsc_category_e category_id)\r
-{\r
-       CResourceCategory *category = FindResourceCategory(category_id);\r
-       if (!category) {\r
-               SERVER_ERR("category(%d) not found", category_id);\r
-               return NULL;\r
-       }\r
-\r
-       return category->FindMainResource();\r
-}\r
-\r
-void CResourceDB::FindMainResources(IN std::map<int, CResource*> *resource_map)\r
-{\r
-       rms_rsc_category_e categories[5] = {RMS_CATEGORY_VIDEO_DECODER,\r
-                                                               RMS_CATEGORY_VIDEO_DECODER_UHD,\r
-                                                               RMS_CATEGORY_SCALER,\r
-                                                               RMS_CATEGORY_AUDIO_DECODER,\r
-                                                               RMS_CATEGORY_AUDIO_MAIN_OUT};\r
-       CResource *resource = NULL;\r
-\r
-       for (int i = 0; i < 5; i++) {\r
-               resource = FindMainResource(categories[i]);\r
-               if (!resource) {\r
-                       SERVER_INFO("no main resource for (%d)", categories[i]);\r
-                       continue;\r
-               }\r
-\r
-               resource_map->insert(std::pair<int, CResource*>(resource->GetDeviceID(), resource));\r
-       }\r
-}\r
-\r
-void CResourceDB::FindActiveVideoDecoders(IN std::map<int, CResource*> *resource_map)\r
-{\r
-       CResource *rsc = nullptr;\r
-       for (auto const &it : m_active_vdecs) {\r
-               rsc = FindResource(it.first);\r
-               if (!rsc)\r
-                       continue;\r
-               resource_map->insert(std::pair<int, CResource*>(it.first, rsc));\r
-       }\r
-}\r
-\r
-void CResourceDB::GetScalerList(std::map<int, CResource*> *scalers)\r
-{\r
-       CResource *rsc = nullptr;\r
-       for (auto &it : m_deviceid_to_rsc) {\r
-               rsc = it.second;\r
-               if (!rsc->IsScaler())\r
-                       continue;\r
-\r
-               scalers->insert(std::pair<int, CResource*>(rsc->GetDeviceID(), rsc));\r
-       }\r
-}\r
-\r
-void CResourceDB::InitScalerTable(void)\r
-{\r
-       CResource *rsc = nullptr;\r
-       int sub_scaler_count = 0;\r
-       int vid = 0;\r
-\r
-       std::map<int, CResource*> scalers;\r
-       GetScalerList(&scalers);\r
-\r
-       for (auto &it : scalers) {\r
-               rsc = it.second;\r
-\r
-               if (!rsc->IsMainDevice())\r
-                       sub_scaler_count++;\r
-\r
-               vid = (rsc->IsMainDevice()) ? RI_VIRTUAL_ID_SCALER : (RI_VIRTUAL_ID_SCALER + sub_scaler_count);\r
-               rsc->SetDedicatedVirtualDeviceId(vid);\r
-               rsc->SetVirtualDeviceId(vid);\r
-               //SERVER_INFO("insert scaler (%d:%d)", vid, rsc->GetDeviceID());\r
-               m_scaler_map.insert(std::pair<int, CResource*>(vid, rsc));\r
-       }\r
-}\r
-\r
-int CResourceDB::FindRealDeviceId(int virtual_id)\r
-{\r
-       auto it = m_scaler_map.find(virtual_id);\r
-\r
-       if (it == m_scaler_map.end())\r
-               return virtual_id;\r
-\r
-       CResource *rsc = it->second;\r
-\r
-       return (rsc == nullptr) ? virtual_id : rsc->GetDeviceID();\r
-}\r
-\r
-CResource *CResourceDB::FindScaler(int virtual_id)\r
-{\r
-       auto it = m_scaler_map.find(virtual_id);\r
-       if (it == m_scaler_map.end())\r
-               return nullptr;\r
-\r
-       return it->second;\r
-}\r
-\r
-int CResourceDB::ToScalerId(int device_id)\r
-{\r
-       const int SCALER_ID_MAIN = 0;\r
-       const int SCALER_ID_SUB = 1;\r
-       const int SCALER_ID_SUB2 = 2;\r
-       const int SCALER_ID_SUB3 = 3;\r
-       const int SCALER_ID_UNKNOWN = 99;\r
-       int source_id = SCALER_ID_UNKNOWN;\r
-\r
-       switch (device_id) {\r
-               case RMS_DEVICE_SCALER:\r
-                       source_id = SCALER_ID_MAIN;\r
-                       break;\r
-               case RMS_DEVICE_SCALER_SUB:\r
-                       source_id = SCALER_ID_SUB;\r
-                       break;\r
-               case RMS_DEVICE_SCALER_SUB2:\r
-                       source_id = SCALER_ID_SUB2;\r
-                       break;\r
-               case RMS_DEVICE_SCALER_SUB3:\r
-                       source_id = SCALER_ID_SUB3;\r
-                       break;\r
-               default:\r
-                       SERVER_ERR("unexpected device_id(%d)", device_id);\r
-                       break;\r
-       }\r
-\r
-       return source_id;\r
-}\r
-\r
-void CResourceDB::UpdateVirtualScalerIds(void)\r
-{\r
-       std::map<int, int> scaler_map;\r
-       for (auto &it : m_scaler_map) {\r
-               if (it.second == nullptr) {\r
-                       SERVER_INFO("[%d : %d (%s)]", it.first, 0, "null");\r
-                       continue;\r
-               }\r
-\r
-               scaler_map.insert(std::pair<int, int>(it.first, ToScalerId(it.second->GetDeviceID())));\r
-               SERVER_INFO("[%d : %d (%s)/(%d)]", it.first, it.second->GetDeviceID(), it.second->GetName().c_str(), it.second->GetVirtualDeviceId());\r
-       }\r
-\r
-       CVideoController::GetInstance()->UpdateVirtualScalerIds(scaler_map);\r
-}\r
-\r
-void CResourceDB::InsertVirtualScaler(int virtual_id, CResource *resource)\r
-{\r
-       m_scaler_map.erase(virtual_id);\r
-       m_scaler_map.insert(std::pair<int, CResource*>(virtual_id, resource));\r
-       PrintVirtualScalerMap();\r
-}\r
-\r
-int CResourceDB::SwapScaler(int id_a, int id_b)\r
-{\r
-       CResource *rsc_a = FindScaler(id_a);\r
-       CResource *rsc_b = FindScaler(id_b);\r
-\r
-       SERVER_INFO("scaler swap (%d <-> %d)", id_a, id_b);\r
-\r
-       if (!rsc_a || !rsc_b) {\r
-               SERVER_ERR("invalid scaler id_a(%d)/id_b(%d)", id_a, id_b);\r
-               return -1;\r
-       }\r
-\r
-       std::set<int> consumers_a = rsc_a->GetConsumers();\r
-       std::set<int> consumers_b = rsc_b->GetConsumers();\r
-\r
-       int zone_a = rsc_a->GetZoneId();\r
-       int zone_b = rsc_b->GetZoneId();\r
-\r
-       rsc_a->SetZoneId(zone_b);\r
-       rsc_b->SetZoneId(zone_a);\r
-\r
-       rms_resource_internal_state_e state_a = (rms_resource_internal_state_e) rsc_a->GetState();\r
-       rms_resource_internal_state_e state_b = (rms_resource_internal_state_e) rsc_b->GetState();\r
-       rsc_a->ChangeState(state_b);\r
-       rsc_b->ChangeState(state_a);\r
-\r
-       UpdateConsumerInfoOfResource(rsc_a, consumers_b, id_b);\r
-       UpdateConsumerInfoOfResource(rsc_b, consumers_a, id_a);\r
-\r
-       // update resource info of each consumer\r
-       SwapResource(consumers_a, rsc_a->GetDeviceID(), rsc_b->GetDeviceID());\r
-       SwapResource(consumers_b, rsc_b->GetDeviceID(), rsc_a->GetDeviceID());\r
-\r
-       // update memcluster owners\r
-       CDependencyController::getInstance()->SwapConsumers(rsc_a->GetDeviceID(), consumers_a, rsc_b->GetDeviceID(), consumers_b);\r
-\r
-       // update virtual scaler table\r
-       InsertVirtualScaler(id_a, rsc_b);\r
-       InsertVirtualScaler(id_b, rsc_a);\r
-       return 0;\r
-}\r
-\r
-void CResourceDB::UpdateConsumerInfoOfResource(CResource *resource, std::set<int> new_consumers, int new_virtual_id)\r
-{\r
-       resource->ResetConsumer(new_consumers);\r
-       resource->SetVirtualDeviceId(new_virtual_id);\r
-}\r
-\r
-void CResourceDB::SwapResource(std::set<int> consumers, int cur_device_id, int new_device_id)\r
-{\r
-       CConsumer *consumer;\r
-       for (auto &it : consumers) {\r
-               consumer = CConsumerContainer::getInstance()->findConsumer(it);\r
-               if (!consumer) {\r
-                       SERVER_ERR("invalid consumer (%d)", it);\r
-                       continue;\r
-               }\r
-\r
-               SERVER_INFO("swap resource (%d) :(%d>%d)", it, cur_device_id, new_device_id);\r
-\r
-               if (consumer->IsUsingResource(new_device_id)) {\r
-                       SERVER_INFO("no need to swap (%d:%d)", it, new_device_id);\r
-                       continue;\r
-               }\r
-               consumer->ReleaseResource(cur_device_id);\r
-               consumer->AddResource(new_device_id);\r
-       }\r
-}\r
-\r
-void CResourceDB::InsertResourceHasZoneId(CResource *rsc)\r
-{\r
-       int device_id = rsc->GetDeviceID();\r
-       auto it = m_rscs_has_zone_id.find(device_id);\r
-\r
-       if (it != m_rscs_has_zone_id.end())\r
-               return;\r
-\r
-       m_rscs_has_zone_id.insert(std::pair<int, CResource*>(device_id, rsc));\r
-       SERVER_INFO("inserted (%d:%d:%zu)", device_id, rsc->GetZoneId(), m_rscs_has_zone_id.size());\r
-}\r
-\r
-void CResourceDB::RemoveResourceHasZoneId(int device_id)\r
-{\r
-       if (m_rscs_has_zone_id.empty())\r
-               return;\r
-\r
-       auto it = m_rscs_has_zone_id.find(device_id);\r
-       if (it != m_rscs_has_zone_id.end())\r
-               return;\r
-\r
-       m_rscs_has_zone_id.erase(device_id);\r
-       SERVER_INFO("removed (%d:%zu)", device_id, m_rscs_has_zone_id.size());\r
-}\r
-\r
-void CResourceDB::ResetZoneIds(void)\r
-{\r
-       CResource *rsc = nullptr;\r
-       SERVER_INFO("Reset zone ids");\r
-\r
-       for (auto &it : m_rscs_has_zone_id) {\r
-               rsc = it.second;\r
-               if (!rsc)\r
-                       continue;\r
-               rsc->SetZoneId(-1);\r
-       }\r
-       m_rscs_has_zone_id.clear();\r
-}\r
+/*
+ * 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 <iostream>
+#include <assert.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <ri-module-api.h>
+#include <vconf.h>
+
+#include <rms_debug.h>
+#include <rms_type.h>
+
+#include <CDebugUtils.h>
+#include <CAudioCodecCollection.h>
+#include <CBandwidth.h>
+#include <CVirtualResource.h>
+#include <CConsumer.h>
+#include <CConsumerContainer.h>
+#include <CDependencyController.h>
+#include <CResourceDB.h>
+#include <CVideoController.h>
+#include <CResourceState.h>
+
+CResourceDB *CResourceDB::m_instance = NULL;
+
+CResourceDB *CResourceDB::getInstance(void)
+{
+       if (!m_instance) {
+               m_instance = new(std::nothrow) CResourceDB;
+               assert(m_instance);
+       }
+
+       return m_instance;
+}
+
+CResourceCategory *CResourceDB::FindResourceCategory(IN rms_rsc_category_e category_id)
+{
+       std::map<rms_rsc_category_e, CResourceCategory*>::iterator it = m_resourceCategoryMap.find(category_id);
+
+       if (it == m_resourceCategoryMap.end())
+               return NULL;
+
+       return (*it).second;
+}
+
+CResource *CResourceDB::FindResource(IN const int device_id)
+{
+       std::map<int, CResource*>::iterator it = m_deviceid_to_rsc.find(device_id);
+
+       if (it == m_deviceid_to_rsc.end()) {
+               SERVER_ERR("no device id(%d) in DB", device_id);
+               return NULL;
+       }
+
+       return (*it).second;
+}
+
+CVirtualResource *CResourceDB::FindVirtualResource(const int vid)
+{
+       auto it = m_v_deviceid_to_rsc.find(vid);
+
+       return (it == m_v_deviceid_to_rsc.end()) ? nullptr : it->second;
+}
+
+void CResourceDB::AddVirtualDeviceID(IN CVirtualResource *vresource)
+{
+       int vrsc_id = vresource->GetVResourceID();
+
+       std::map<int, CVirtualResource *>::iterator it = m_v_deviceid_to_rsc.find(vrsc_id);
+
+       if (it != m_v_deviceid_to_rsc.end())
+               return;
+
+       m_v_deviceid_to_rsc.insert(std::pair<int, CVirtualResource *>(vrsc_id, vresource));
+}
+
+void CResourceDB::AddDeviceID(IN int device_id, IN CResource *resource)
+{
+       std::map<int, CResource*>::iterator it = m_deviceid_to_rsc.find(device_id);
+
+       if (it != m_deviceid_to_rsc.end())
+               return;
+
+       m_deviceid_to_rsc.insert(std::pair<int, CResource*>(device_id, resource));
+}
+
+void CResourceDB::AddDeviceName(IN const char *device_name, IN CResource *resource)
+{
+       auto it = m_devicename_to_rsc.find(std::string(device_name));
+
+       if (it != m_devicename_to_rsc.end()) {
+               SERVER_DBG("already registered device name(%s) in DB", device_name);
+               return;
+       }
+
+       m_devicename_to_rsc.insert(std::pair<std::string, CResource*>(std::string(device_name), resource));
+}
+
+void CResourceDB::AddResourceCategory(IN rms_rsc_category_e category_id, IN CResourceCategory *resource_category)
+{
+       std::map<rms_rsc_category_e, CResourceCategory*>::iterator it = m_resourceCategoryMap.find(category_id);
+
+       if (it != m_resourceCategoryMap.end())
+               return;
+
+       m_resourceCategoryMap.insert(std::pair<rms_rsc_category_e, CResourceCategory*>(category_id, resource_category));
+}
+
+CResource *CResourceDB::FindResource(const char *device_name)
+{
+       auto it = m_devicename_to_rsc.find(std::string(device_name));
+
+       return (it == m_devicename_to_rsc.end()) ? NULL : it->second;
+}
+
+void CResourceDB::AddVirtualResource(IN CVirtualResource *vrsc,
+                                                      IN rms_rsc_category_e resource_category_id,
+                                                      IN const char *name,
+                                                      IN const char *path,
+                                                      IN std::set<unsigned int> mem_cluster_info,
+                                                      IN unsigned int device_id_unique,
+                                                      IN int is_main_device,
+                                                      IN const char *audio_codec,
+                                                      IN int sharable_count,
+                                                      IN int mixing_count,
+                                                      IN CResourceObserver *observer)
+{
+       assert(name);
+       assert(path);
+
+       CResource *rsc = FindResource(name);
+
+       if (!rsc) {
+               rsc = new CResource(device_id_unique, resource_category_id, name, path, mem_cluster_info, is_main_device, audio_codec, sharable_count);
+
+               AddDeviceName(name, rsc);
+               AddDeviceID(device_id_unique, rsc);
+
+               rsc->RegisterObserver(this);
+               rsc->RegisterObserver(observer);
+       }
+
+       vrsc->SetResource(rsc);
+
+       CAudioCodecCollection::getInstance()->registerAudioCodec(audio_codec, mixing_count);
+
+       if (rsc->GetDefaultBW() == 0)
+               rsc->SetDefaultBW(vrsc->GetBW());
+
+       AddVirtualDeviceID(vrsc);
+}
+
+void CResourceDB::UpdateBWbyRelease(CResource *rsc)
+{
+       if (!rsc)
+               return;
+
+       if (rsc->GetBW() == 0)
+               return;
+
+       CBandwidth *bw = CBandwidth::GetInstance();
+       bw->RemoveConsumer(rsc->GetDeviceID(), rsc->GetCurCategory(), rsc->GetCategoryClass());
+       bw->Increase(rsc->GetBW(), rsc->GetCurCategory(), rsc->GetCategoryClass(), rsc->GetDeviceID());
+
+       return;
+}
+
+void CResourceDB::UpdateByRelease(CResource *resource, const int device_id, const int consumer_id)
+{
+       UpdateBWbyRelease(resource);
+
+       if (resource->IsVideoDecoder())
+               RemoveActiveVideoDecoder(device_id, resource->GetCategoryClass());
+
+       if (resource->IsJpegDecoder())
+               RemoveActiveJpegDecoder(device_id);
+
+       RemoveResourceHasZoneId(resource->GetDeviceID());
+}
+
+void CResourceDB::UpdateBWbyAllocation(const unsigned int bandwidth, CResource *rsc)
+{
+       CBandwidth *bw = CBandwidth::GetInstance();
+       bw->Decrease(bandwidth, rsc->GetCurCategory(), rsc->GetCategoryClass(), rsc->GetDeviceID());
+
+       //SERVER_INFO("bw updated avail(%d)/max(%d)", bw->GetAvail(), bw->GetMax());
+}
+
+void CResourceDB::UpdateByAllocation(CResource *resource, const int device_id, const int consumer_id)
+{
+       unsigned int bw = resource->GetBW();
+
+       if (bw > 0) {
+               UpdateBWbyAllocation(bw, resource);
+               CBandwidth::GetInstance()->AddConsumer(device_id, consumer_id, resource->GetCurCategory(), resource->GetCategoryClass());
+       }
+
+       if (resource->IsVideoDecoder())
+               AddActiveVideoDecoder(device_id, consumer_id, resource->GetCategoryClass());
+
+       if (resource->IsScaler())
+               SetVirtualScalerId(resource);
+
+       if (resource->IsJpegDecoder())
+               AddActiveJpegDecoder(device_id, consumer_id);
+
+       if (resource->GetZoneId() > 0)
+               InsertResourceHasZoneId(resource);
+}
+
+void CResourceDB::SetVirtualScalerId(CResource *resource)
+{
+       int scaler_id = GetVirtualScalerId(resource);
+
+       SERVER_INFO("map scaler (%d:%d)", scaler_id, resource->GetDeviceID());
+
+       resource->SetVirtualDeviceId(scaler_id);
+       InsertVirtualScaler(scaler_id, resource);
+}
+
+void CResourceDB::PrintVirtualScalerMap(void)
+{
+       for (auto &it : m_scaler_map) {
+               if (it.second == nullptr) {
+                       //SERVER_INFO("[%d : %d (%s)]", it.first, 0, "null");
+                       continue;
+               }
+               //SERVER_INFO("[%d : %d (%s)/(%d)]", it.first, it.second->GetDeviceID(), it.second->GetName().c_str(), it.second->GetVirtualDeviceId());
+       }
+}
+
+int CResourceDB::GetVirtualScalerId(CResource *resource)
+{
+       CResource *rsc = nullptr;
+
+       for (auto &it : m_scaler_map) {
+               rsc = it.second;
+               if (rsc == nullptr)
+                       continue;
+               if (rsc->GetDeviceID() == resource->GetDeviceID())
+                       return it.first;
+       }
+
+       return resource->GetDedicatedVirtualDeviceId();
+}
+
+void CResourceDB::AddActiveVideoDecoder(const int device_id, const int consumer_id, const int category_class)
+{
+       m_active_vdecs.insert(std::pair<int, int>(device_id, consumer_id));
+
+       if (category_class == RMS_CATEGORY_CLASS_N_DECODING)
+               m_active_nvdecs.insert(std::pair<int, int>(device_id, consumer_id));
+}
+
+void CResourceDB::RemoveActiveVideoDecoder(const int device_id, const int category_class)
+{
+       m_active_vdecs.erase(device_id);
+
+       if (category_class == RMS_CATEGORY_CLASS_N_DECODING)
+               m_active_nvdecs.erase(device_id);
+}
+
+void CResourceDB::AddActiveJpegDecoder(const int device_id, const int consumer_id)
+{
+       m_active_jdecs.insert(std::pair<int, int>(device_id, consumer_id));
+}
+
+void CResourceDB::RemoveActiveJpegDecoder(const int device_id)
+{
+       m_active_jdecs.erase(device_id);
+}
+
+int CResourceDB::GetActiveDecoderNum(void)
+{
+       int num = 0;
+
+       num += m_active_vdecs.size();
+       num += m_active_jdecs.size();
+
+       return num;
+}
+
+void CResourceDB::PrintVideoDecoderConsumers(void)
+{
+       for (auto const &it : m_active_vdecs) {
+               SERVER_INFO("dev(%d) by (%d)", it.first, it.second);
+       }
+}
+
+bool CResourceDB::HasAvailableDecoder(void)
+{
+       int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;
+       int active_vdecs = m_active_vdecs.size();
+       int active_ndecs = m_active_nvdecs.size();
+
+       SERVER_INFO("active(%d) / n_dec(%d) / max(%d / %d)", active_vdecs, active_ndecs, max_vdecs, m_max_vdecs);
+
+       if (active_ndecs > 0)
+               active_vdecs = active_vdecs + (1 - active_ndecs);
+
+       if (active_vdecs >= max_vdecs)
+               PrintVideoDecoderConsumers();
+
+       return (active_vdecs < max_vdecs);
+}
+
+bool CResourceDB::HasAvailableDecoderNDecoding(void)
+{
+       int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;
+       int active_vdecs = m_active_vdecs.size();
+       int active_ndecs = m_active_nvdecs.size();
+
+       SERVER_INFO("active(%d) / n_dec(%d) / max(%d %d)", active_vdecs, active_ndecs, max_vdecs, m_max_vdecs);
+
+       if (active_ndecs > 0) {
+               active_vdecs = active_vdecs + (1 - active_ndecs);
+               return true;
+       }
+
+       if (active_vdecs >= max_vdecs)
+               PrintVideoDecoderConsumers();
+
+       return (active_vdecs < max_vdecs);
+}
+
+bool CResourceDB::HasAvailableDecoder(std::multimap<int, int> retirables)
+{
+       int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;
+       std::map<int, int> retirables_vdecs;
+
+       SERVER_INFO("max(%d %d)", max_vdecs, m_max_vdecs);
+
+       for (auto &it : retirables) {
+               CResource *rsc = FindResource(it.first);
+               if (!rsc)
+                       continue;
+
+               if (rsc->IsVideoDecoder())
+                       retirables_vdecs.insert(std::pair<int, int>(it.first, it.second));
+       }
+
+       int active_vdecs = m_active_vdecs.size();
+       int active_ndecs = m_active_nvdecs.size();
+       int retirable_vdecs = retirables_vdecs.size();
+       int retirable_ndecs = CountNDecoders(retirables_vdecs);
+
+       int remain = 0;
+
+       if ((active_ndecs - retirable_ndecs) > 0)
+               remain = (active_vdecs - retirable_vdecs) + (1 - (active_ndecs - retirable_ndecs));
+       else
+               remain = active_vdecs - retirable_vdecs;
+
+       SERVER_INFO("remain(%d)/max(%d), av(%d)/an(%d)/rv(%d)/rn(%d)", remain, max_vdecs, active_vdecs, active_ndecs, retirable_vdecs, retirable_ndecs);
+
+       if (remain >= max_vdecs)
+               PrintVideoDecoderConsumers();
+
+       return (remain < max_vdecs);
+}
+
+bool CResourceDB::HasAvailableDecoderNDecoding(std::multimap<int, int> retirables)
+{
+       int max_vdecs = (m_max_vdecs > 1) ? m_max_vdecs : 1;
+       std::map<int, int> retirables_vdecs;
+
+       SERVER_INFO("max(%d %d)", max_vdecs, m_max_vdecs);
+
+       for (auto &it : retirables) {
+               CResource *rsc = FindResource(it.first);
+               if (!rsc)
+                       continue;
+
+               if (rsc->IsVideoDecoder())
+                       retirables_vdecs.insert(std::pair<int, int>(it.first, it.second));
+       }
+
+       int active_vdecs = m_active_vdecs.size();
+       int active_ndecs = m_active_nvdecs.size();
+       int retirable_vdecs = retirables_vdecs.size();
+       int retirable_ndecs = CountNDecoders(retirables_vdecs);
+
+       int remain = 0;
+
+       if ((active_ndecs - retirable_ndecs) > 0)
+               remain = (active_vdecs - retirable_vdecs) + (1 - (active_ndecs - retirable_ndecs));
+       else
+               remain = active_vdecs - retirable_vdecs;
+
+       SERVER_INFO("remain(%d)/max(%d), av(%d)/an(%d)/rv(%d)/rn(%d)", remain, max_vdecs, active_vdecs, active_ndecs, retirable_vdecs, retirable_ndecs);
+
+       if (active_ndecs > 0 && retirable_ndecs > 0)
+               return true;
+
+       if (remain >= max_vdecs)
+               PrintVideoDecoderConsumers();
+
+       return (remain < max_vdecs);
+}
+
+int CResourceDB::CountNDecoders(std::map<int, int> retirables_vdecs)
+{
+       int ndecs = 0;
+       for (auto &it_rsc : retirables_vdecs) {
+               auto it_ndec = m_active_nvdecs.find(it_rsc.first);
+
+               if (it_ndec != m_active_nvdecs.end())
+                       ndecs++;
+       }
+
+       SERVER_INFO("ndecs(%d) in retirables(%zu)", ndecs, retirables_vdecs.size());
+       return ndecs;
+}
+
+void CResourceDB::Update(resource_update_type_e type, const int device_id, const int consumer_id)
+{
+       CResource *resource = FindResource(device_id);
+
+       if (!resource)
+               return;
+
+       switch (type) {
+               case UPDATED_BY_ALLOC:
+                       SERVER_WARN("UPDATED_BY_ALLOC");
+                       UpdateByAllocation(resource, device_id, consumer_id);
+                       break;
+               case UPDATED_BY_RELEASE:
+                       SERVER_WARN("UPDATED_BY_RELEASE");
+                       UpdateByRelease(resource, device_id, consumer_id);
+                       break;
+               default:
+                       SERVER_ERR("unexpected update type (%d)", type);
+                       break;
+       }
+
+       NotifyResourceStateUpdatedAsync(resource, consumer_id);
+}
+
+void CResourceDB::AddReclaimResources(consumer_reclaim_s *consumers)
+{
+       for (int i = 0; i < consumers->ret_quantity; i++) {
+               for (int j = 0; j < consumers->consumer_info[i].n_conflicted; j++) {
+                       SERVER_INFO("add reclaim rsc (%d)", consumers->consumer_info[i].conflicted_resources[j].device_id);
+                       m_reclaim_rscs.insert(consumers->consumer_info[i].conflicted_resources[j].device_id);
+               }
+       }
+}
+
+void CResourceDB::ClearReclaimResources(void)
+{
+       m_reclaim_rscs.clear();
+}
+
+gboolean CResourceDB::NotifyResourceStateUpdated(gpointer data)
+{
+       if (!data) {
+               SERVER_ERR("invalid data");
+               return G_SOURCE_REMOVE;
+       }
+
+       CResourceState *state = (CResourceState*) data;
+
+       GError *error = NULL;
+       GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+
+       if (!connection) {
+               SERVER_ERR("failed to get connection (%s)", (error) ? error->message : "unknown");
+               goto out;
+       }
+
+       SERVER_INFO("notify state changed (device id %d( type %d) : state %d)", state->GetDeviceId(), state->GetCategoryType(), state->GetState());
+
+       if (!g_dbus_connection_emit_signal(connection,
+                                               NULL,
+                                               RM_DBUS_OBJ_PATH,
+                                               RM_DBUS_INTERFACE_NAME,
+                                               "RscStateChanged",
+                                               g_variant_new("(iiiis)", state->GetDeviceId(), state->GetCategoryType(), state->GetState(), state->GetConsumerId(), state->GetAppId().c_str()),
+                                               &error))
+               SERVER_ERR("failed to send state changed (%d:%s)", state->GetDeviceId(), (error) ? error->message : "unknown");
+
+out:
+       if (error)
+               g_error_free(error);
+
+       delete state;
+       return G_SOURCE_REMOVE;
+}
+
+void CResourceDB::NotifyResourceStateUpdatedAsync(CResource *resource, int consumer_id)
+{
+       int device_id = resource->GetDeviceID();
+       CConsumer *consumer = CConsumerContainer::getInstance()->findConsumer(consumer_id);
+
+       if (!consumer) {
+               SERVER_WARN("Consumer %d is not found", consumer_id);
+               return;
+       }
+
+       std::string app_id = consumer->GetAppID();
+
+       if (app_id.empty())
+               app_id = consumer->GetCmdName();
+
+       SERVER_INFO("device id (%d) consumer id (%d)", device_id, consumer_id);
+
+       if (m_reclaim_rscs.find(device_id) != m_reclaim_rscs.end()) {
+               SERVER_DBG("skip to notify state updated (%d)", device_id);
+               return;
+       }
+
+       CResourceState *state = new CResourceState(resource->GetDeviceID(), resource->GetCategoryType(), consumer_id, resource->GetState(), app_id);
+       g_idle_add(&CResourceDB::NotifyResourceStateUpdated, state);
+}
+
+CResource *CResourceDB::FindMainResource(rms_rsc_category_e category_id)
+{
+       CResourceCategory *category = FindResourceCategory(category_id);
+       if (!category) {
+               SERVER_ERR("category(%d) not found", category_id);
+               return NULL;
+       }
+
+       return category->FindMainResource();
+}
+
+void CResourceDB::FindMainResources(IN std::map<int, CResource*> *resource_map)
+{
+       rms_rsc_category_e categories[5] = {RMS_CATEGORY_VIDEO_DECODER,
+                                                               RMS_CATEGORY_VIDEO_DECODER_UHD,
+                                                               RMS_CATEGORY_SCALER,
+                                                               RMS_CATEGORY_AUDIO_DECODER,
+                                                               RMS_CATEGORY_AUDIO_MAIN_OUT};
+       CResource *resource = NULL;
+
+       for (int i = 0; i < 5; i++) {
+               resource = FindMainResource(categories[i]);
+               if (!resource) {
+                       SERVER_INFO("no main resource for (%d)", categories[i]);
+                       continue;
+               }
+
+               resource_map->insert(std::pair<int, CResource*>(resource->GetDeviceID(), resource));
+       }
+}
+
+void CResourceDB::FindActiveVideoDecoders(IN std::map<int, CResource*> *resource_map)
+{
+       CResource *rsc = nullptr;
+       for (auto const &it : m_active_vdecs) {
+               rsc = FindResource(it.first);
+               if (!rsc)
+                       continue;
+               resource_map->insert(std::pair<int, CResource*>(it.first, rsc));
+       }
+}
+
+void CResourceDB::GetScalerList(std::map<int, CResource*> *scalers)
+{
+       CResource *rsc = nullptr;
+       for (auto &it : m_deviceid_to_rsc) {
+               rsc = it.second;
+               if (!rsc->IsScaler())
+                       continue;
+
+               scalers->insert(std::pair<int, CResource*>(rsc->GetDeviceID(), rsc));
+       }
+}
+
+void CResourceDB::InitScalerTable(void)
+{
+       CResource *rsc = nullptr;
+       int sub_scaler_count = 0;
+       int vid = 0;
+
+       std::map<int, CResource*> scalers;
+       GetScalerList(&scalers);
+
+       for (auto &it : scalers) {
+               rsc = it.second;
+
+               if (!rsc->IsMainDevice())
+                       sub_scaler_count++;
+
+               vid = (rsc->IsMainDevice()) ? RI_VIRTUAL_ID_SCALER : (RI_VIRTUAL_ID_SCALER + sub_scaler_count);
+               rsc->SetDedicatedVirtualDeviceId(vid);
+               rsc->SetVirtualDeviceId(vid);
+               //SERVER_INFO("insert scaler (%d:%d)", vid, rsc->GetDeviceID());
+               m_scaler_map.insert(std::pair<int, CResource*>(vid, rsc));
+       }
+}
+
+int CResourceDB::FindRealDeviceId(int virtual_id)
+{
+       auto it = m_scaler_map.find(virtual_id);
+
+       if (it == m_scaler_map.end())
+               return virtual_id;
+
+       CResource *rsc = it->second;
+
+       return (rsc == nullptr) ? virtual_id : rsc->GetDeviceID();
+}
+
+CResource *CResourceDB::FindScaler(int virtual_id)
+{
+       auto it = m_scaler_map.find(virtual_id);
+       if (it == m_scaler_map.end())
+               return nullptr;
+
+       return it->second;
+}
+
+int CResourceDB::ToScalerId(int device_id)
+{
+       const int SCALER_ID_MAIN = 0;
+       const int SCALER_ID_SUB = 1;
+       const int SCALER_ID_SUB2 = 2;
+       const int SCALER_ID_SUB3 = 3;
+       const int SCALER_ID_UNKNOWN = 99;
+       int source_id = SCALER_ID_UNKNOWN;
+
+       switch (device_id) {
+               case RMS_DEVICE_SCALER:
+                       source_id = SCALER_ID_MAIN;
+                       break;
+               case RMS_DEVICE_SCALER_SUB:
+                       source_id = SCALER_ID_SUB;
+                       break;
+               case RMS_DEVICE_SCALER_SUB2:
+                       source_id = SCALER_ID_SUB2;
+                       break;
+               case RMS_DEVICE_SCALER_SUB3:
+                       source_id = SCALER_ID_SUB3;
+                       break;
+               default:
+                       SERVER_ERR("unexpected device_id(%d)", device_id);
+                       break;
+       }
+
+       return source_id;
+}
+
+void CResourceDB::UpdateVirtualScalerIds(void)
+{
+       std::map<int, int> scaler_map;
+       for (auto &it : m_scaler_map) {
+               if (it.second == nullptr) {
+                       SERVER_INFO("[%d : %d (%s)]", it.first, 0, "null");
+                       continue;
+               }
+
+               scaler_map.insert(std::pair<int, int>(it.first, ToScalerId(it.second->GetDeviceID())));
+               SERVER_INFO("[%d : %d (%s)/(%d)]", it.first, it.second->GetDeviceID(), it.second->GetName().c_str(), it.second->GetVirtualDeviceId());
+       }
+
+       CVideoController::GetInstance()->UpdateVirtualScalerIds(scaler_map);
+}
+
+void CResourceDB::InsertVirtualScaler(int virtual_id, CResource *resource)
+{
+       m_scaler_map.erase(virtual_id);
+       m_scaler_map.insert(std::pair<int, CResource*>(virtual_id, resource));
+       PrintVirtualScalerMap();
+}
+
+int CResourceDB::SwapScaler(int id_a, int id_b)
+{
+       CResource *rsc_a = FindScaler(id_a);
+       CResource *rsc_b = FindScaler(id_b);
+
+       SERVER_INFO("scaler swap (%d <-> %d)", id_a, id_b);
+
+       if (!rsc_a || !rsc_b) {
+               SERVER_ERR("invalid scaler id_a(%d)/id_b(%d)", id_a, id_b);
+               return -1;
+       }
+
+       std::set<int> consumers_a = rsc_a->GetConsumers();
+       std::set<int> consumers_b = rsc_b->GetConsumers();
+
+       int zone_a = rsc_a->GetZoneId();
+       int zone_b = rsc_b->GetZoneId();
+
+       rsc_a->SetZoneId(zone_b);
+       rsc_b->SetZoneId(zone_a);
+
+       rms_resource_internal_state_e state_a = (rms_resource_internal_state_e) rsc_a->GetState();
+       rms_resource_internal_state_e state_b = (rms_resource_internal_state_e) rsc_b->GetState();
+       rsc_a->ChangeState(state_b);
+       rsc_b->ChangeState(state_a);
+
+       UpdateConsumerInfoOfResource(rsc_a, consumers_b, id_b);
+       UpdateConsumerInfoOfResource(rsc_b, consumers_a, id_a);
+
+       // update resource info of each consumer
+       SwapResource(consumers_a, rsc_a->GetDeviceID(), rsc_b->GetDeviceID());
+       SwapResource(consumers_b, rsc_b->GetDeviceID(), rsc_a->GetDeviceID());
+
+       // update memcluster owners
+       CDependencyController::getInstance()->SwapConsumers(rsc_a->GetDeviceID(), consumers_a, rsc_b->GetDeviceID(), consumers_b);
+
+       // update virtual scaler table
+       InsertVirtualScaler(id_a, rsc_b);
+       InsertVirtualScaler(id_b, rsc_a);
+       return 0;
+}
+
+void CResourceDB::UpdateConsumerInfoOfResource(CResource *resource, std::set<int> new_consumers, int new_virtual_id)
+{
+       resource->ResetConsumer(new_consumers);
+       resource->SetVirtualDeviceId(new_virtual_id);
+}
+
+void CResourceDB::SwapResource(std::set<int> consumers, int cur_device_id, int new_device_id)
+{
+       CConsumer *consumer;
+       for (auto &it : consumers) {
+               consumer = CConsumerContainer::getInstance()->findConsumer(it);
+               if (!consumer) {
+                       SERVER_ERR("invalid consumer (%d)", it);
+                       continue;
+               }
+
+               SERVER_INFO("swap resource (%d) :(%d>%d)", it, cur_device_id, new_device_id);
+
+               if (consumer->IsUsingResource(new_device_id)) {
+                       SERVER_INFO("no need to swap (%d:%d)", it, new_device_id);
+                       continue;
+               }
+               consumer->ReleaseResource(cur_device_id);
+               consumer->AddResource(new_device_id);
+       }
+}
+
+void CResourceDB::InsertResourceHasZoneId(CResource *rsc)
+{
+       int device_id = rsc->GetDeviceID();
+       auto it = m_rscs_has_zone_id.find(device_id);
+
+       if (it != m_rscs_has_zone_id.end())
+               return;
+
+       m_rscs_has_zone_id.insert(std::pair<int, CResource*>(device_id, rsc));
+       SERVER_INFO("inserted (%d:%d:%zu)", device_id, rsc->GetZoneId(), m_rscs_has_zone_id.size());
+}
+
+void CResourceDB::RemoveResourceHasZoneId(int device_id)
+{
+       if (m_rscs_has_zone_id.empty())
+               return;
+
+       auto it = m_rscs_has_zone_id.find(device_id);
+       if (it != m_rscs_has_zone_id.end())
+               return;
+
+       m_rscs_has_zone_id.erase(device_id);
+       SERVER_INFO("removed (%d:%zu)", device_id, m_rscs_has_zone_id.size());
+}
+
+void CResourceDB::ResetZoneIds(void)
+{
+       CResource *rsc = nullptr;
+       SERVER_INFO("Reset zone ids");
+
+       for (auto &it : m_rscs_has_zone_id) {
+               rsc = it.second;
+               if (!rsc)
+                       continue;
+               rsc->SetZoneId(-1);
+       }
+       m_rscs_has_zone_id.clear();
+}
index db9bfc011d7e669372c7ca23fc5c25a982dc12d8..47aa96bd3a6bcee57201a1f831e294b9e8eaa1a3 100644 (file)
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <new>\r
-#include <assert.h>\r
-#include <unistd.h>\r
-#include <trace.h>\r
-#include <rms_debug.h>\r
-#include <CVideoController.h>\r
-\r
-#define LWIPC_WM_READY "/tmp/.wm_ready"\r
-#define LWIPC_TIMEOUT_MS 10000\r
-#define LWIPC_SWAP_DONE "/tmp/.scaler_swap_done"\r
-#define LWIPC_SWAP_DONE_TIMEOUT_MS 3000\r
-#define LWIPC_SWAP_DONE_TIMEOUT_DBG_MS 4000\r
-#define RMS_IS_DEBUG_IMAGE (access("/etc/debug", F_OK) == 0)\r
-\r
-CVideoController *CVideoController::m_instance = nullptr;\r
-\r
-static void registry_handle_global(void *data, struct wl_registry *wl_registry, uint32_t id, const char *interface, uint32_t version)\r
-{\r
-       void **tizen_video_rsc = (void**)data;\r
-\r
-       if (strncmp(interface, "tizen_video_rsc", sizeof("tizen_video_rsc")))\r
-               return;\r
-\r
-       SERVER_INFO("%p : %s", tizen_video_rsc, interface);\r
-       //*tizen_video_rsc = wl_registry_bind(wl_registry, id, &tizen_video_rsc_interface, 1);\r
-}\r
-\r
-static void registry_handle_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name)\r
-{\r
-\r
-}\r
-\r
-void CVideoController::WaylandDisplayCreate(void)\r
-{\r
-       SERVER_INFO("Create Start");\r
-\r
-       SERVER_INFO("%s is created", LWIPC_WM_READY);\r
-       m_wl_display = wl_display_connect(nullptr);\r
-\r
-       if (!m_wl_display) {\r
-               SERVER_ERR("Failed to connect to the wayland display");\r
-               return;\r
-       }\r
-\r
-       m_wl_registry = wl_display_get_registry(m_wl_display);\r
-       wl_registry_add_listener(m_wl_registry, &m_registry_listener, &m_tizen_video_rsc);\r
-       SERVER_INFO("Add listener : %p", &m_tizen_video_rsc);\r
-\r
-       wl_display_roundtrip(m_wl_display);\r
-\r
-       if (!m_tizen_video_rsc)\r
-               SERVER_ERR("Failed to get tizen_video_rsc");\r
-\r
-       SERVER_INFO("Create Done");\r
-}\r
-\r
-void CVideoController::WaylandDisplayDestroy(void)\r
-{\r
-       if (m_tizen_video_rsc) {\r
-               //tizen_video_rsc_destroy(m_tizen_video_rsc);\r
-               m_tizen_video_rsc = nullptr;\r
-       }\r
-\r
-       if (m_wl_registry) {\r
-               wl_registry_destroy(m_wl_registry);\r
-               m_wl_registry = nullptr;\r
-       }\r
-\r
-       SERVER_INFO("Display disconnect");\r
-\r
-       if (m_wl_display) {\r
-               wl_display_roundtrip(m_wl_display);\r
-               wl_display_disconnect(m_wl_display);\r
-               m_wl_display = nullptr;\r
-       }\r
-\r
-       SERVER_INFO("Destroy Done");\r
-}\r
-\r
-CVideoController::CVideoController(void) : m_wl_display(nullptr), m_wl_registry(nullptr), m_tizen_video_rsc(nullptr), m_waiting_thread(nullptr)\r
-{\r
-       m_registry_listener.global = registry_handle_global;\r
-       m_registry_listener.global_remove = registry_handle_global_remove;\r
-       WaylandDisplayCreate();\r
-       m_lock_ctr = CLockController::GetInstance();\r
-\r
-       SERVER_INFO("Initialize Done");\r
-}\r
-\r
-CVideoController::~CVideoController(void)\r
-{\r
-       WaylandDisplayDestroy();\r
-       SERVER_INFO("Finalize Done");\r
-}\r
-\r
-CVideoController *CVideoController::GetInstance(void)\r
-{\r
-       if (m_instance == nullptr)\r
-       {\r
-               m_instance = new(std::nothrow) CVideoController();\r
-               assert(m_instance);\r
-       }\r
-\r
-       return m_instance;\r
-}\r
-\r
-void CVideoController::UpdateVirtualScalerIds(std::map<int, int> scaler_id_map)\r
-{\r
-       struct wl_array mapping_list;\r
-       scaler_id_pair_t *scaler_id_pair = NULL;\r
-\r
-       wl_array_init(&mapping_list);\r
-       SERVER_ERR("Update virtual scaler ids");\r
-\r
-       for (auto it = scaler_id_map.begin(); it != scaler_id_map.end(); it++) {\r
-               scaler_id_pair = (scaler_id_pair_t*)wl_array_add(&mapping_list, sizeof(scaler_id_pair_t));\r
-               scaler_id_pair->virtual_scaler_id = it->first;\r
-               scaler_id_pair->scaler_id = it->second;\r
-               SERVER_ERR("scaler(%d:%d)", it->first, it->second);\r
-       }\r
-\r
-       //tizen_video_rsc_map_scaler_id(m_tizen_video_rsc, &mapping_list);\r
-\r
-       wl_display_roundtrip(m_wl_display);\r
-       wl_array_release(&mapping_list);\r
-\r
-       RunWaitingThread();\r
-}\r
-\r
-gpointer CVideoController::WaitingThread(gpointer data)\r
-{\r
-       assert(data);\r
-       CVideoController *ctr = (CVideoController*) data;\r
-\r
-       ctr->m_lock_ctr->Unlock(ResourceType::VIDEO_SCALER);\r
-       ctr->m_waiting_thread =  nullptr;\r
-       return 0;\r
-}\r
-\r
-void CVideoController::RunWaitingThread(void)\r
-{\r
-       if (m_waiting_thread)\r
-       {\r
-               SERVER_ERR("already created");\r
-               return;\r
-       }\r
-\r
-       m_lock_ctr->Lock(ResourceType::VIDEO_SCALER);\r
-\r
-       m_waiting_thread = g_thread_new("waiting_swap_done", WaitingThread, this);\r
-       if (m_waiting_thread == nullptr) {\r
-               m_lock_ctr->Unlock(ResourceType::VIDEO_SCALER);\r
-               SERVER_ERR("failed to create waiting_swap_done thread");\r
-               return;\r
-       }\r
-\r
-       SERVER_ERR("waiting_swap_done thread created");\r
-}\r
+/*
+ * 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 <new>
+#include <assert.h>
+#include <unistd.h>
+#include <trace.h>
+#include <rms_debug.h>
+#include <CVideoController.h>
+
+#define LWIPC_WM_READY "/tmp/.wm_ready"
+#define LWIPC_TIMEOUT_MS 10000
+#define LWIPC_SWAP_DONE "/tmp/.scaler_swap_done"
+#define LWIPC_SWAP_DONE_TIMEOUT_MS 3000
+#define LWIPC_SWAP_DONE_TIMEOUT_DBG_MS 4000
+#define RMS_IS_DEBUG_IMAGE (access("/etc/debug", F_OK) == 0)
+
+CVideoController *CVideoController::m_instance = nullptr;
+
+static void registry_handle_global(void *data, struct wl_registry *wl_registry, uint32_t id, const char *interface, uint32_t version)
+{
+       void **tizen_video_rsc = (void**)data;
+
+       if (strncmp(interface, "tizen_video_rsc", sizeof("tizen_video_rsc")))
+               return;
+
+       SERVER_INFO("%p : %s", tizen_video_rsc, interface);
+       //*tizen_video_rsc = wl_registry_bind(wl_registry, id, &tizen_video_rsc_interface, 1);
+}
+
+static void registry_handle_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name)
+{
+
+}
+
+void CVideoController::WaylandDisplayCreate(void)
+{
+       SERVER_INFO("Create Start");
+
+       SERVER_INFO("%s is created", LWIPC_WM_READY);
+       m_wl_display = wl_display_connect(nullptr);
+
+       if (!m_wl_display) {
+               SERVER_ERR("Failed to connect to the wayland display");
+               return;
+       }
+
+       m_wl_registry = wl_display_get_registry(m_wl_display);
+       wl_registry_add_listener(m_wl_registry, &m_registry_listener, &m_tizen_video_rsc);
+       SERVER_INFO("Add listener : %p", &m_tizen_video_rsc);
+
+       wl_display_roundtrip(m_wl_display);
+
+       if (!m_tizen_video_rsc)
+               SERVER_ERR("Failed to get tizen_video_rsc");
+
+       SERVER_INFO("Create Done");
+}
+
+void CVideoController::WaylandDisplayDestroy(void)
+{
+       if (m_tizen_video_rsc) {
+               //tizen_video_rsc_destroy(m_tizen_video_rsc);
+               m_tizen_video_rsc = nullptr;
+       }
+
+       if (m_wl_registry) {
+               wl_registry_destroy(m_wl_registry);
+               m_wl_registry = nullptr;
+       }
+
+       SERVER_INFO("Display disconnect");
+
+       if (m_wl_display) {
+               wl_display_roundtrip(m_wl_display);
+               wl_display_disconnect(m_wl_display);
+               m_wl_display = nullptr;
+       }
+
+       SERVER_INFO("Destroy Done");
+}
+
+CVideoController::CVideoController(void) : m_wl_display(nullptr), m_wl_registry(nullptr), m_tizen_video_rsc(nullptr), m_waiting_thread(nullptr)
+{
+       m_registry_listener.global = registry_handle_global;
+       m_registry_listener.global_remove = registry_handle_global_remove;
+       WaylandDisplayCreate();
+       m_lock_ctr = CLockController::GetInstance();
+
+       SERVER_INFO("Initialize Done");
+}
+
+CVideoController::~CVideoController(void)
+{
+       WaylandDisplayDestroy();
+       SERVER_INFO("Finalize Done");
+}
+
+CVideoController *CVideoController::GetInstance(void)
+{
+       if (m_instance == nullptr)
+       {
+               m_instance = new(std::nothrow) CVideoController();
+               assert(m_instance);
+       }
+
+       return m_instance;
+}
+
+void CVideoController::UpdateVirtualScalerIds(std::map<int, int> scaler_id_map)
+{
+       struct wl_array mapping_list;
+       scaler_id_pair_t *scaler_id_pair = NULL;
+
+       wl_array_init(&mapping_list);
+       SERVER_ERR("Update virtual scaler ids");
+
+       for (auto it = scaler_id_map.begin(); it != scaler_id_map.end(); it++) {
+               scaler_id_pair = (scaler_id_pair_t*)wl_array_add(&mapping_list, sizeof(scaler_id_pair_t));
+               scaler_id_pair->virtual_scaler_id = it->first;
+               scaler_id_pair->scaler_id = it->second;
+               SERVER_ERR("scaler(%d:%d)", it->first, it->second);
+       }
+
+       //tizen_video_rsc_map_scaler_id(m_tizen_video_rsc, &mapping_list);
+
+       wl_display_roundtrip(m_wl_display);
+       wl_array_release(&mapping_list);
+
+       RunWaitingThread();
+}
+
+gpointer CVideoController::WaitingThread(gpointer data)
+{
+       assert(data);
+       CVideoController *ctr = (CVideoController*) data;
+
+       ctr->m_lock_ctr->Unlock(ResourceType::VIDEO_SCALER);
+       ctr->m_waiting_thread =  nullptr;
+       return 0;
+}
+
+void CVideoController::RunWaitingThread(void)
+{
+       if (m_waiting_thread)
+       {
+               SERVER_ERR("already created");
+               return;
+       }
+
+       m_lock_ctr->Lock(ResourceType::VIDEO_SCALER);
+
+       m_waiting_thread = g_thread_new("waiting_swap_done", WaitingThread, this);
+       if (m_waiting_thread == nullptr) {
+               m_lock_ctr->Unlock(ResourceType::VIDEO_SCALER);
+               SERVER_ERR("failed to create waiting_swap_done thread");
+               return;
+       }
+
+       SERVER_ERR("waiting_swap_done thread created");
+}
index a9399fefd04e38c888e2c2d4efdd86ebf08a9d6b..9f59ab2680f1ecaf8a39a4e42bd85f403d7e2e09 100644 (file)
@@ -1,33 +1,33 @@
-/*\r
- * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include <CVirtualResource.h>\r
-#include <rms_debug.h>\r
-#include <CResource.h>\r
-\r
-CVirtualResource::CVirtualResource(const int virtual_device_id, const rms_rsc_category_e category_type, unsigned int bw, std::set<unsigned int> dependent, bool is_main_device, const char *audio_codec, int category_class)\r
-:m_vir_rsc_id(virtual_device_id), m_category_type(category_type), m_vir_rsc_bw(bw), m_is_main_device(is_main_device), m_category_class(category_class), m_rsc()\r
-{\r
-       m_mem_clusters = dependent;\r
-\r
-       if (audio_codec)\r
-               m_audio_codec.assign(audio_codec);\r
-}\r
-\r
-void CVirtualResource::SetResource(CResource *resource)\r
-{\r
-       m_rsc = resource;\r
-}\r
+/*
+ * 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 <CVirtualResource.h>
+#include <rms_debug.h>
+#include <CResource.h>
+
+CVirtualResource::CVirtualResource(const int virtual_device_id, const rms_rsc_category_e category_type, unsigned int bw, std::set<unsigned int> dependent, bool is_main_device, const char *audio_codec, int category_class)
+:m_vir_rsc_id(virtual_device_id), m_category_type(category_type), m_vir_rsc_bw(bw), m_is_main_device(is_main_device), m_category_class(category_class), m_rsc()
+{
+       m_mem_clusters = dependent;
+
+       if (audio_codec)
+               m_audio_codec.assign(audio_codec);
+}
+
+void CVirtualResource::SetResource(CResource *resource)
+{
+       m_rsc = resource;
+}