From 6112928910107ff81edfa98ab78b8c6107f3ee94 Mon Sep 17 00:00:00 2001 From: hongll Date: Sat, 23 Aug 2025 20:40:40 +0800 Subject: [PATCH] =?UTF-8?q?samgr=20=E4=BB=A3=E7=A0=81=E5=B7=AE=E5=BC=82?= =?UTF-8?q?=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../include/if_system_ability_manager.h | 16 +- .../include/isystem_ability_status_change.h | 5 - .../schedule/system_ability_state_scheduler.h | 6 +- .../system_ability_state_scheduler.cpp | 34 ++- .../native/source/system_ability_manager.cpp | 16 +- .../system_ability_state_scheduler_test.cpp | 233 ++++++++++++++---- 6 files changed, 231 insertions(+), 79 deletions(-) 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 6e6bdfdc..e794e80b 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 270fdb7b..d0691d80 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 da80d6d8..6a727747 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 db8c03be..f0662a55 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 97b6c736..96044d57 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 373f0542..e8aac637 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 @@ -1887,81 +1887,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"<