diff --git a/interfaces/innerkits/samgr_proxy/include/if_system_ability_manager.h b/interfaces/innerkits/samgr_proxy/include/if_system_ability_manager.h index 6e6bdfdcbed41c8b4dfb217728edf8e1d5579d95..e794e80bfd3c0c668c59b4552f12a29ce82fa5c9 100644 --- a/interfaces/innerkits/samgr_proxy/include/if_system_ability_manager.h +++ b/interfaces/innerkits/samgr_proxy/include/if_system_ability_manager.h @@ -29,6 +29,13 @@ #include "system_ability_on_demand_event.h" namespace OHOS { + +struct IdleProcessInfo { + int32_t pid = -1; + std::u16string processName; + int64_t lastIdleTime = 0; +}; + class ISystemAbilityManager : public IRemoteBroker { public: /** @@ -231,7 +238,8 @@ public: * UnloadProcess, unload process by process name list. * only support for memmgrservice * - * @return ERR_OK It means unload all process in list. + * @param processList, Need a processList to unload. + * @return ERR_OK It means unload process in processList success. */ virtual int32_t UnloadProcess(const std::vector& processList) { @@ -239,11 +247,11 @@ public: return 0; } -/** - * GetSystemProcessInfo, Get process info by said. + /** + * GetLruIdleSystemAbilityProc, Get idle process info list. * only support for memmgrservice * - * @param processList, Issue a parameter and return it as a result. + * @param processInfos, Issue a parameter and return it as a result. * @return ERR_OK indicates that the get successfully. */ virtual int32_t GetLruIdleSystemAbilityProc(std::vector& processInfos) diff --git a/interfaces/innerkits/samgr_proxy/include/isystem_ability_status_change.h b/interfaces/innerkits/samgr_proxy/include/isystem_ability_status_change.h index 270fdb7b4cfd12cb21e1b46ae64def87a403cb64..d0691d80da4991944e965f8225c940cef245f264 100644 --- a/interfaces/innerkits/samgr_proxy/include/isystem_ability_status_change.h +++ b/interfaces/innerkits/samgr_proxy/include/isystem_ability_status_change.h @@ -21,11 +21,6 @@ #include "iremote_proxy.h" namespace OHOS { -struct IdleProcessInfo { - int32_t pid = -1; - std::u16string processName; - int64_t lastIdleTime = 0; -}; class ISystemAbilityStatusChange : public IRemoteBroker { public: diff --git a/services/samgr/native/include/schedule/system_ability_state_scheduler.h b/services/samgr/native/include/schedule/system_ability_state_scheduler.h index da80d6d8d45a4b9ab58d971baf660aa3a9ec9fb9..6a727747fa979d85b934d5b886cb1f57647c225e 100644 --- a/services/samgr/native/include/schedule/system_ability_state_scheduler.h +++ b/services/samgr/native/include/schedule/system_ability_state_scheduler.h @@ -22,6 +22,7 @@ #include "ffrt_handler.h" #include "isystem_process_status_change.h" +#include "if_system_ability_manager.h" #include "nlohmann/json.hpp" #include "sa_profiles.h" #include "schedule/system_ability_event_handler.h" @@ -70,9 +71,8 @@ public: int32_t CheckStopEnableOnce(const OnDemandEvent& event, const SaControlInfo& saControl); void UpdateLimitDelayUnloadTime(int32_t systemAbilityId); void UpdateLimitDelayUnloadTimeTask(int32_t systemAbilityId); - int64_t GetSystemAbilityIdleTime(int32_t systemAbilityId); - bool GetLruIdleSystemAbilityInfo(int32_t systemAbilityId, std::u16string& processName, int64_t& lastStopTime, - int32_t& pid); + bool GetIdleProcessInfo(int32_t systemAbilityId, IdleProcessInfo& idleProcessInfo); + bool IsSystemProcessCanUnload(const std::u16string& processName); private: void InitStateContext(const std::list& saProfiles); diff --git a/services/samgr/native/source/schedule/system_ability_state_scheduler.cpp b/services/samgr/native/source/schedule/system_ability_state_scheduler.cpp index db8c03bec1ea6d7e08e1db79d07e9dbe5aa5d58f..f0662a553a5a470e9aa8f26e6bad6d9ddeab37f9 100644 --- a/services/samgr/native/source/schedule/system_ability_state_scheduler.cpp +++ b/services/samgr/native/source/schedule/system_ability_state_scheduler.cpp @@ -41,6 +41,7 @@ constexpr const char* LOCAL_DEVICE = "local"; constexpr int32_t MAX_DELAY_TIME = 5 * 60 * 1000; constexpr int32_t MAX_DURATION = 10 * 60 * 1000; // ms constexpr int32_t ONCE_DELAY_TIME = 10 * 1000; // ms +constexpr int64_t TWO_MINUTES_MS = 120 * 1000; // ms constexpr const char* CANCEL_UNLOAD = "cancelUnload"; constexpr const char* KEY_EVENT_ID = "eventId"; constexpr const char* KEY_NAME = "name"; @@ -1422,28 +1423,37 @@ int32_t SystemAbilityStateScheduler::CheckStopEnableOnce(const OnDemandEvent& ev return result; } -int64_t SystemAbilityStateScheduler::GetSystemAbilityIdleTime(int32_t systemAbilityId) +bool SystemAbilityStateScheduler::GetIdleProcessInfo(int32_t systemAbilityId, IdleProcessInfo& idleProcessInfo) { std::shared_ptr abilityContext; if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) { - return -1; + return false; } std::lock_guard autoLock(abilityContext->ownProcessContext->processLock); - return abilityContext->lastIdleTime; + if (abilityContext->state != SystemAbilityState::UNLOADABLE || + abilityContext->ownProcessContext->state == SystemProcessState::NOT_STARTED) { + HILOGD("GetIdleProcessInfo SA:%{public}d state not idle or proc not started", systemAbilityId); + return false; + } + int64_t lastStopTime = abilityContext->ownProcessContext->lastStopTime; + if (lastStopTime != -1 && (GetTickCount() - lastStopTime < TWO_MINUTES_MS)) { + HILOGD("GetIdleProcessInfo SA:%{public}d lastStopTime less than 2 min", systemAbilityId); + return false; + } + idleProcessInfo.processName = abilityContext->ownProcessContext->processName; + idleProcessInfo.pid = abilityContext->ownProcessContext->pid; + idleProcessInfo.lastIdleTime = abilityContext->lastIdleTime; + return true; } -bool SystemAbilityStateScheduler::GetLruIdleSystemAbilityInfo(int32_t systemAbilityId, std::u16string& processName, - int64_t& lastStopTime, int32_t& pid) +bool SystemAbilityStateScheduler::IsSystemProcessCanUnload(const std::u16string& processName) { - std::shared_ptr abilityContext; - if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) { + std::shared_ptr processContext; + if (!GetSystemProcessContext(processName, processContext)) { return false; } - std::lock_guard autoLock(abilityContext->ownProcessContext->processLock); - processName = abilityContext->ownProcessContext->processName; - pid = abilityContext->ownProcessContext->pid; - lastStopTime = abilityContext->ownProcessContext->lastStopTime; - return true; + std::lock_guard autoLock(processContext->processLock); + return CanUnloadAllSystemAbilityLocked(processContext); } void SystemAbilityStateScheduler::UnloadEventHandler::ProcessEvent(uint32_t eventId) diff --git a/services/samgr/native/source/system_ability_manager.cpp b/services/samgr/native/source/system_ability_manager.cpp index 97b6c73620fb51fbf1a12a436345273b584c037f..96044d573355671be7e4b499aa025a80965cd9f2 100644 --- a/services/samgr/native/source/system_ability_manager.cpp +++ b/services/samgr/native/source/system_ability_manager.cpp @@ -84,7 +84,6 @@ constexpr int64_t CHECK_LOADED_DELAY_TIME = 4 * 1000; // ms #endif constexpr int32_t SOFTBUS_SERVER_SA_ID = 4700; constexpr int32_t FIRST_DUMP_INDEX = 0; -constexpr int64_t TWO_MINUTES_SECONDS = 120 * 1000; // ms } samgr::mutex SystemAbilityManager::instanceLock; @@ -1748,19 +1747,9 @@ int32_t SystemAbilityManager::GetLruIdleSystemAbilityProc(std::vector saIds = collectManager_->GetLowMemPrepareList(); std::map procInfos; - std::set activeProcess; for (const auto& saId : saIds) { IdleProcessInfo info; - int64_t lastStopTime = -1; - if (!abilityStateScheduler_->GetLruIdleSystemAbilityInfo(saId, info.processName, lastStopTime, info.pid)) { - continue; - } - info.lastIdleTime = abilityStateScheduler_->GetSystemAbilityIdleTime(saId); - if (info.lastIdleTime < 0) { - activeProcess.insert(info.processName); - continue; - } - if (lastStopTime != -1 && (GetTickCount() - lastStopTime < TWO_MINUTES_SECONDS)) { + if (!abilityStateScheduler_->GetIdleProcessInfo(saId, info)) { continue; } auto procInfo = procInfos.find(info.processName); @@ -1771,8 +1760,9 @@ int32_t SystemAbilityManager::GetLruIdleSystemAbilityProc(std::vectorIsSystemProcessCanUnload(pair.first)) { processInfos.push_back(pair.second); + HILOGD("GetLruIdle processName:%{public}s", Str16ToStr8(pair.first).c_str()); } } std::sort(processInfos.begin(), processInfos.end(), [](const IdleProcessInfo& a, IdleProcessInfo& b) { diff --git a/services/samgr/native/test/unittest/src/system_ability_state_scheduler_test.cpp b/services/samgr/native/test/unittest/src/system_ability_state_scheduler_test.cpp index 373f05427a02c7d4ceee61d09e26018e51cc802c..d1758bfaf64dddeb7f08300557afcee4055a0706 100644 --- a/services/samgr/native/test/unittest/src/system_ability_state_scheduler_test.cpp +++ b/services/samgr/native/test/unittest/src/system_ability_state_scheduler_test.cpp @@ -23,7 +23,6 @@ #define private public #include "schedule/system_ability_state_scheduler.h" -#include "event_handler.h" #include "system_ability_manager.h" using namespace std; @@ -1887,81 +1886,230 @@ HWTEST_F(SystemAbilityStateSchedulerTest, SetFfrt001, TestSize.Level3) } /** - * @tc.name: GetSystemAbilityIdleTime001 - * @tc.desc: test GetSystemAbilityIdleTime + * @tc.name: GetIdleProcessInfo001 + * @tc.desc: Tests the case where the system ability ID is invalid and GetSystemAbilityContext fails. * @tc.type: FUNC * @tc.require: I7VEPG */ -HWTEST_F(SystemAbilityStateSchedulerTest, GetSystemAbilityIdleTime001, TestSize.Level3) +HWTEST_F(SystemAbilityStateSchedulerTest, GetIdleProcessInfo001, TestSize.Level3) { - DTEST_LOG<<"GetSystemAbilityIdleTime001 BEGIN"< systemAbilityStateScheduler = std::make_shared(); - int32_t invalidSaid = 101; - - int64_t ret = systemAbilityStateScheduler->GetSystemAbilityIdleTime(invalidSaid); - EXPECT_EQ(ret, -1); - DTEST_LOG<<"GetSystemAbilityIdleTime001 END"<GetIdleProcessInfo(invalidSaId, idleInfo); + EXPECT_FALSE(result); + DTEST_LOG<<"GetIdleProcessInfo001 END"< systemAbilityStateScheduler = std::make_shared(); - int said = 401; - - int64_t ret = systemAbilityStateScheduler->GetSystemAbilityIdleTime(said); - EXPECT_EQ(ret, -1); - DTEST_LOG<<"GetSystemAbilityIdleTime002 END"<(); + context->state = SystemAbilityState::LOADED; + context->ownProcessContext = std::make_shared(); + context->ownProcessContext->state = SystemProcessState::STARTED; + systemAbilityStateScheduler->abilityContextMap_[saId] = context; + + bool result = systemAbilityStateScheduler->GetIdleProcessInfo(saId, idleInfo); + EXPECT_FALSE(result); + DTEST_LOG<<"GetIdleProcessInfo002 END"< systemAbilityStateScheduler = std::make_shared(); - int32_t invalidSaid = 101; - int64_t lastStopTime = -1; - std::u16string processName; - int32_t pid = -1; - - bool ret = systemAbilityStateScheduler->GetLruIdleSystemAbilityInfo(invalidSaid, processName, lastStopTime, pid); - EXPECT_EQ(ret, false); - DTEST_LOG<<"GetLruIdleSystemAbilityInfo001 END"<(); + context->state = SystemAbilityState::UNLOADABLE; + context->ownProcessContext = std::make_shared(); + context->ownProcessContext->state = SystemProcessState::NOT_STARTED; + systemAbilityStateScheduler->abilityContextMap_[saId] = context; + + bool result = systemAbilityStateScheduler->GetIdleProcessInfo(saId, idleInfo); + EXPECT_FALSE(result); + DTEST_LOG<<"GetIdleProcessInfo003 END"< systemAbilityStateScheduler = std::make_shared(); - int said = 401; - int64_t lastStopTime = -1; - std::u16string processName; - int32_t pid = -1; - - systemAbilityStateScheduler->GetLruIdleSystemAbilityInfo(said, processName, lastStopTime, pid); - EXPECT_NE(lastStopTime, 0); - DTEST_LOG<<"GetLruIdleSystemAbilityInfo002 END"<(); + context->state = SystemAbilityState::UNLOADABLE; + context->ownProcessContext = std::make_shared(); + context->ownProcessContext->state = SystemProcessState::STARTED; + context->ownProcessContext->lastStopTime = GetTickCount() - 60 * 1000; // 1 minute ago + systemAbilityStateScheduler->abilityContextMap_[saId] = context; + + bool result = systemAbilityStateScheduler->GetIdleProcessInfo(saId, idleInfo); + EXPECT_FALSE(result); + DTEST_LOG<<"GetIdleProcessInfo004 END"< systemAbilityStateScheduler = + std::make_shared(); + IdleProcessInfo idleInfo; + int32_t saId = 123; + std::u16string expectedName = u"test_process"; + int32_t expectedPid = 456; + int64_t expectedIdleTime = 1000; + + // Setup mock to return valid context + auto context = std::make_shared(); + context->state = SystemAbilityState::UNLOADABLE; + context->lastIdleTime = expectedIdleTime; + context->ownProcessContext = std::make_shared(); + context->ownProcessContext->state = SystemProcessState::STARTED; + context->ownProcessContext->lastStopTime = GetTickCount() - 130 * 1000; // > 2 minutes ago + context->ownProcessContext->processName = expectedName; + context->ownProcessContext->pid = expectedPid; + systemAbilityStateScheduler->abilityContextMap_[saId] = context; + + bool result = systemAbilityStateScheduler->GetIdleProcessInfo(saId, idleInfo); + EXPECT_TRUE(result); + EXPECT_EQ(idleInfo.processName, expectedName); + EXPECT_EQ(idleInfo.pid, expectedPid); + EXPECT_EQ(idleInfo.lastIdleTime, expectedIdleTime); + DTEST_LOG<<"GetIdleProcessInfo005 END"< systemAbilityStateScheduler = + std::make_shared(); + IdleProcessInfo idleInfo; + int32_t saId = 123; + + // Setup mock to return context with lastStopTime = -1 + auto context = std::make_shared(); + context->state = SystemAbilityState::UNLOADABLE; + context->ownProcessContext = std::make_shared(); + context->ownProcessContext->state = SystemProcessState::STARTED; + context->ownProcessContext->lastStopTime = -1; + systemAbilityStateScheduler->abilityContextMap_[saId] = context; + + bool result = systemAbilityStateScheduler->GetIdleProcessInfo(saId, idleInfo); + EXPECT_TRUE(result); + DTEST_LOG<<"GetIdleProcessInfo006 END"< systemAbilityStateScheduler = + std::make_shared(); + std::u16string processName = u"test_process"; + bool result = systemAbilityStateScheduler->IsSystemProcessCanUnload(processName); + EXPECT_FALSE(result); + DTEST_LOG<<"IsSystemProcessCanUnload001 END"< systemAbilityStateScheduler = + std::make_shared(); + std::u16string processName = u"test_process"; + + auto processContext = std::make_shared(); + processContext->saList.push_back(123); + processContext->saList.push_back(124); + processContext->saList.push_back(125); + processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED] = 1; + processContext->abilityStateCountMap[SystemAbilityState::UNLOADABLE] = 2; + systemAbilityStateScheduler->processContextMap_[processName] = processContext; + bool result = systemAbilityStateScheduler->IsSystemProcessCanUnload(processName); + EXPECT_TRUE(result); + DTEST_LOG<<"IsSystemProcessCanUnload002 END"< systemAbilityStateScheduler = + std::make_shared(); + std::u16string processName = u"test_process"; + + auto processContext = std::make_shared(); + processContext->saList.push_back(123); + processContext->saList.push_back(124); + processContext->saList.push_back(125); + processContext->abilityStateCountMap[SystemAbilityState::NOT_LOADED] = 0; + processContext->abilityStateCountMap[SystemAbilityState::UNLOADABLE] = 2; + systemAbilityStateScheduler->processContextMap_[processName] = processContext; + bool result = systemAbilityStateScheduler->IsSystemProcessCanUnload(processName); + EXPECT_FALSE(result); + DTEST_LOG<<"IsSystemProcessCanUnload003 END"<