diff --git a/frameworks/native/source/system_ability_manager_proxy.cpp b/frameworks/native/source/system_ability_manager_proxy.cpp index 622691679ab0e859003a8b0d8cbdad2de751a1cb..7be2e6c821ba2d498fd47452385fa35a42f6decf 100644 --- a/frameworks/native/source/system_ability_manager_proxy.cpp +++ b/frameworks/native/source/system_ability_manager_proxy.cpp @@ -842,6 +842,111 @@ int32_t SystemAbilityManagerProxy::UnloadAllIdleSystemAbility() return ERR_OK; } +int32_t SystemAbilityManagerProxy::UnloadProcess(const std::vector& processList) +{ + HILOGI("UnloadProcess called"); + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("UnloadProcess remote is nullptr"); + return ERR_INVALID_OPERATION; + } + + MessageParcel data; + if (!data.WriteInterfaceToken(SAMANAGER_INTERFACE_TOKEN)) { + HILOGE("UnloadProcess write interface token failed"); + return ERR_FLATTEN_OBJECT; + } + if (!data.WriteString16Vector(processList)) { + HILOGW("UnloadProcess Write processList failed!"); + return ERR_FLATTEN_OBJECT; + } + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + int32_t err = remote->SendRequest( + static_cast(SamgrInterfaceCode::UNLOAD_IDLE_PROCESS_BYLIST), data, reply, option); + if (err != ERR_NONE) { + HILOGE("UnloadProcess SendRequest error:%{public}d", err); + return err; + } + HILOGD("UnloadProcess SendRequest succeed"); + return ERR_OK; +} + +int32_t SystemAbilityManagerProxy::GetLruIdleSystemAbilityProc(std::vector& procInfos) +{ + HILOGI("GetLruIdleSystempAbilityProc called"); + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("GetLruIdleSystempAbilityProc remote is nullptr"); + return ERR_INVALID_OPERATION; + } + + MessageParcel data; + if (!data.WriteInterfaceToken(SAMANAGER_INTERFACE_TOKEN)) { + HILOGE("GetLruIdleSystempAbilityProc write interface token failed"); + return ERR_FLATTEN_OBJECT; + } + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest( + static_cast(SamgrInterfaceCode::GET_LRU_IDLE_SYSTEM_ABILITY_PROCESS_TRANSACTION), data, reply, option); + if (err != ERR_NONE) { + HILOGE("GetLruIdleSystempAbilityProc SendRequest error:%{public}d", err); + return err; + } + int32_t result = 0; + bool ret = reply.ReadInt32(result); + if (!ret) { + HILOGE("GetLruIdleSystempAbilityProc read resule failed"); + return ERR_FLATTEN_OBJECT; + } + if (result != ERR_OK) { + HILOGE("GetLruIdleSystempAbilityProc failed: %{public}d!", result); + return result; + } + return ReadIdleProcessInfoFromParcel(reply, procInfos); +} + +int32_t SystemAbilityManagerProxy::ReadIdleProcessInfoFromParcel(MessageParcel& reply, + std::vector& procInfos) +{ + int32_t size = 0; + bool ret = reply.ReadInt32(size); + if (!ret) { + HILOGE("ReadIdleProcessInfoFromParcel read size failed"); + return ERR_FLATTEN_OBJECT; + } + procInfos.clear(); + if (size == 0) { + return ERR_OK; + } + if (static_cast(size) > reply.GetReadableBytes() || size < 0) { + HILOGE("Failed to read proc list, size=%{public}d", size); + return ERR_FLATTEN_OBJECT; + } + for (int32_t i = 0; i < size; i++) { + IdleProcessInfo info; + ret = reply.ReadInt32(info.pid); + if (!ret) { + HILOGW("ReadIdleProcessInfoFromParcel Read pid failed!"); + return ERR_FLATTEN_OBJECT; + } + ret = reply.ReadString16(info.processName); + if (!ret) { + HILOGW("ReadIdleProcessInfoFromParcel Read processName failed!"); + return ERR_FLATTEN_OBJECT; + } + ret = reply.ReadInt64(info.lastIdleTime); + if (!ret) { + HILOGW("ReadIdleProcessInfoFromParcel Read uid failed!"); + return ERR_FLATTEN_OBJECT; + } + procInfos.emplace_back(info); + } + return ERR_OK; +} + int32_t SystemAbilityManagerProxy::MarshalSAExtraProp(const SAExtraProp& extraProp, MessageParcel& data) const { if (!data.WriteBool(extraProp.isDistributed)) { 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 f1523911d0688c0abb64a7c3e6e381c113c6ed64..6e6bdfdcbed41c8b4dfb217728edf8e1d5579d95 100644 --- a/interfaces/innerkits/samgr_proxy/include/if_system_ability_manager.h +++ b/interfaces/innerkits/samgr_proxy/include/if_system_ability_manager.h @@ -227,6 +227,31 @@ public: */ virtual int32_t UnloadAllIdleSystemAbility() = 0; + /** + * UnloadProcess, unload process by process name list. + * only support for memmgrservice + * + * @return ERR_OK It means unload all process in list. + */ + virtual int32_t UnloadProcess(const std::vector& processList) + { + (void)processList; + return 0; + } + +/** + * GetSystemProcessInfo, Get process info by said. + * only support for memmgrservice + * + * @param processList, Issue a parameter and return it as a result. + * @return ERR_OK indicates that the get successfully. + */ + virtual int32_t GetLruIdleSystemAbilityProc(std::vector& processInfos) + { + (void)processInfos; + return 0; + } + /** * GetSystemProcessInfo, Get process info by said. * 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 679a05ed5591d81fa363d53e8c76aea7a9dfc486..270fdb7b4cfd12cb21e1b46ae64def87a403cb64 100644 --- a/interfaces/innerkits/samgr_proxy/include/isystem_ability_status_change.h +++ b/interfaces/innerkits/samgr_proxy/include/isystem_ability_status_change.h @@ -21,6 +21,12 @@ #include "iremote_proxy.h" namespace OHOS { +struct IdleProcessInfo { + int32_t pid = -1; + std::u16string processName; + int64_t lastIdleTime = 0; +}; + class ISystemAbilityStatusChange : public IRemoteBroker { public: virtual ~ISystemAbilityStatusChange() = default; diff --git a/interfaces/innerkits/samgr_proxy/include/samgr_ipc_interface_code.h b/interfaces/innerkits/samgr_proxy/include/samgr_ipc_interface_code.h index a37feca4f57c06a6846c7ee57b1e0a42eef2a8fc..9130cc0220bed4737e0726eae227c4e8d359e764 100644 --- a/interfaces/innerkits/samgr_proxy/include/samgr_ipc_interface_code.h +++ b/interfaces/innerkits/samgr_proxy/include/samgr_ipc_interface_code.h @@ -51,6 +51,8 @@ enum class SamgrInterfaceCode : uint32_t { GET_SA_EXTENSION_INFO_TRANSCATION = 35, GET_COMMON_EVENT_EXTRA_ID_LIST_TRANSCATION = 36, GET_LOCAL_ABILITY_MANAGER_PROXY_TRANSCATION = 37, + UNLOAD_IDLE_PROCESS_BYLIST = 38, + GET_LRU_IDLE_SYSTEM_ABILITY_PROCESS_TRANSACTION = 39, }; } // namespace OHOS #endif // !defined(INTERFACES_INNERKITS_SAMGR_INCLUDE_SAMGR_INTERFACE_CODE_H) \ No newline at end of file diff --git a/interfaces/innerkits/samgr_proxy/include/system_ability_manager_proxy.h b/interfaces/innerkits/samgr_proxy/include/system_ability_manager_proxy.h index 506c267e09c5b80eb0e21c7f9d4f58373ac50a24..ffde50a0f6ae00a6b3399ea9a8e97bbc5b5fb9a4 100644 --- a/interfaces/innerkits/samgr_proxy/include/system_ability_manager_proxy.h +++ b/interfaces/innerkits/samgr_proxy/include/system_ability_manager_proxy.h @@ -193,6 +193,23 @@ public: */ int32_t UnloadAllIdleSystemAbility() override; + /** + * UnloadProcess, unload process by process name list. + * only support for memmgrservice + * + * @return ERR_OK It means unload all process in list. + */ + virtual int32_t UnloadProcess(const std::vector& processList) override; + + /** + * GetSystemProcessInfo, Get process info by said. + * only support for memmgrservice + * + * @param processList, Issue a parameter and return it as a result. + * @return ERR_OK indicates that the get successfully. + */ + virtual int32_t GetLruIdleSystemAbilityProc(std::vector& processInfos) override; + /** * GetSystemProcessInfo, Get process info by said. * @@ -286,6 +303,7 @@ private: int32_t RemoveSystemAbilityWrapper(int32_t code, MessageParcel& data); int32_t ReadSystemProcessFromParcel(MessageParcel& reply, std::list& systemProcessInfos); int32_t ReadProcessInfoFromParcel(MessageParcel& reply, SystemProcessInfo& systemProcessInfo); + int32_t ReadIdleProcessInfoFromParcel(MessageParcel& reply, std::vector& procInfos); sptr CheckSystemAbilityTransaction(int32_t systemAbilityId); bool IsOnDemandSystemAbility(int32_t systemAbilityId); int32_t ListExtensionSendReq(const std::string& extension, diff --git a/services/samgr/native/include/collect/device_param_collect.h b/services/samgr/native/include/collect/device_param_collect.h index 5fb5ba5a942702f56cf771e4c330776c0b6ca31c..f4d48ace0094895f5f20d95e1b8d9e10151f70ee 100644 --- a/services/samgr/native/include/collect/device_param_collect.h +++ b/services/samgr/native/include/collect/device_param_collect.h @@ -33,10 +33,12 @@ public: int32_t RemoveUnusedEvent(const OnDemandEvent& event) override; int32_t OnStart() override; int32_t OnStop() override; + const std::vector& GetLowMemPrepareList() override; private: std::mutex paramLock_; std::set pendingParams_; std::set params_; + std::vector lowMemPrepareList_; }; class SystemAbilityStatusChange : public SystemAbilityStatusChangeStub { diff --git a/services/samgr/native/include/collect/device_status_collect_manager.h b/services/samgr/native/include/collect/device_status_collect_manager.h index 3a25de1efc73482a0464f6ceac208039ab770892..602b9331747d21f1717302743582322170b83ade 100644 --- a/services/samgr/native/include/collect/device_status_collect_manager.h +++ b/services/samgr/native/include/collect/device_status_collect_manager.h @@ -52,6 +52,7 @@ public: const std::string& eventName = ""); int32_t IsExistInPluginMap(int32_t eventId); void RemoveWhiteCommonEvent(); + const std::vector& GetLowMemPrepareList(); private: bool NeedPersistOnDemandEvent(const OnDemandEvent& event); void PersistOnDemandEvent(int32_t systemAbilityId, OnDemandPolicyType type, diff --git a/services/samgr/native/include/collect/icollect_plugin.h b/services/samgr/native/include/collect/icollect_plugin.h index 0bd6509d77a0585b3e05d288dd901c61be705a6e..240059a086c7a6723ca5aec18cd4b2a472f16385 100644 --- a/services/samgr/native/include/collect/icollect_plugin.h +++ b/services/samgr/native/include/collect/icollect_plugin.h @@ -75,6 +75,11 @@ public: { return ERR_OK; } + virtual const std::vector& GetLowMemPrepareList() + { + std::vector res; + return res; + } void ReportEvent(const OnDemandEvent& event); void PostTask(std::function callback); void PostDelayTask(std::function callback, int32_t delayTime); diff --git a/services/samgr/native/include/schedule/system_ability_state_context.h b/services/samgr/native/include/schedule/system_ability_state_context.h index f185920ccf2c4ec2e02dac7ac1abbd89b1133744..a569404127d5bbc321f1f63b83364f9e259d8527 100644 --- a/services/samgr/native/include/schedule/system_ability_state_context.h +++ b/services/samgr/native/include/schedule/system_ability_state_context.h @@ -76,6 +76,7 @@ struct SystemProcessContext { int32_t uid = -1; SystemProcessState state = SystemProcessState::NOT_STARTED; bool enableRestart = true; + int64_t lastStopTime = -1; }; struct SystemAbilityContext { @@ -87,6 +88,7 @@ struct SystemAbilityContext { int32_t systemAbilityId = -1; int32_t delayUnloadTime = 0; int64_t lastStartTime = 0; + int64_t lastIdleTime = -1; SystemAbilityState state = SystemAbilityState::NOT_LOADED; PendingEvent pendingEvent = PendingEvent::NO_EVENT; bool isAutoRestart = false; 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 1b9ea3711bc5587ff9aa820b20384014460eea09..842ec7c103b390343866d001036a8ff54206e242 100644 --- a/services/samgr/native/include/schedule/system_ability_state_scheduler.h +++ b/services/samgr/native/include/schedule/system_ability_state_scheduler.h @@ -50,6 +50,7 @@ public: int32_t HandleUnloadAbilityEvent(const std::shared_ptr unloadRequestInfo); int32_t HandleCancelUnloadAbilityEvent(int32_t systemAbilityId); int32_t UnloadAllIdleSystemAbility(); + int32_t UnloadProcess(const std::vector& processList); int32_t SendAbilityStateEvent(int32_t systemAbilityId, AbilityStateEvent event); int32_t SendProcessStateEvent(const ProcessInfo& processInfo, ProcessStateEvent event); bool IsSystemAbilityUnloading(int32_t systemAbilityId); @@ -71,6 +72,9 @@ 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); private: void InitStateContext(const std::list& saProfiles); diff --git a/services/samgr/native/include/system_ability_manager.h b/services/samgr/native/include/system_ability_manager.h index 833f3eacac0a162bbabf62fe411ba8355e8ccb50..9ae8151c82bb4e71f2bd2453cf088983b556534c 100644 --- a/services/samgr/native/include/system_ability_manager.h +++ b/services/samgr/native/include/system_ability_manager.h @@ -183,6 +183,8 @@ public: const nlohmann::json& idleReason, int32_t& delayTime); bool ActiveSystemAbility(int32_t systemAbilityId, const std::u16string& procName, const nlohmann::json& activeReason); + int32_t UnloadProcess(const std::vector& processList) override; + int32_t GetLruIdleSystemAbilityProc(std::vector& processInfos) override; void OnAbilityCallbackDied(const sptr& remoteObject); void OnRemoteCallbackDied(const sptr& remoteObject); sptr GetSystemAbilityFromRemote(int32_t systemAbilityId); diff --git a/services/samgr/native/include/system_ability_manager_stub.h b/services/samgr/native/include/system_ability_manager_stub.h index 837284a5b38bb12441159673a2cff1e5d4dd389b..ddd487d2630a2785263b856ed2a4e928a8222be5 100644 --- a/services/samgr/native/include/system_ability_manager_stub.h +++ b/services/samgr/native/include/system_ability_manager_stub.h @@ -134,6 +134,16 @@ private: { return stub->UnloadAllIdleSystemAbilityInner(data, reply); } + static int32_t LocalUnloadProcess(SystemAbilityManagerStub* stub, + MessageParcel& data, MessageParcel& reply) + { + return stub->UnloadProcessInner(data, reply); + } + static int32_t LocalGetLruIdleSystemAbilityProc(SystemAbilityManagerStub* stub, + MessageParcel& data, MessageParcel& reply) + { + return stub->GetLruIdleSystemAbilityProcInner(data, reply); + } static int32_t LocalGetOnDemandReasonExtraData(SystemAbilityManagerStub* stub, MessageParcel& data, MessageParcel& reply) { @@ -204,6 +214,8 @@ private: int32_t UnloadSystemAbilityInner(MessageParcel& data, MessageParcel& reply); int32_t CancelUnloadSystemAbilityInner(MessageParcel& data, MessageParcel& reply); int32_t UnloadAllIdleSystemAbilityInner(MessageParcel& data, MessageParcel& reply); + int32_t UnloadProcessInner(MessageParcel& data, MessageParcel& reply); + int32_t GetLruIdleSystemAbilityProcInner(MessageParcel& data, MessageParcel& reply); int32_t GetOnDemandReasonExtraDataInner(MessageParcel& data, MessageParcel& reply); int32_t GetOnDemandPolicyInner(MessageParcel& data, MessageParcel& reply); int32_t UpdateOnDemandPolicyInner(MessageParcel& data, MessageParcel& reply); diff --git a/services/samgr/native/source/collect/device_param_collect.cpp b/services/samgr/native/source/collect/device_param_collect.cpp index 0a5c026001f02060d7fab3abf6388f19b6a92622..4c52f0912fd8a1f5203fea9f51524372ba567415 100644 --- a/services/samgr/native/source/collect/device_param_collect.cpp +++ b/services/samgr/native/source/collect/device_param_collect.cpp @@ -26,6 +26,7 @@ using namespace std; namespace OHOS { namespace { constexpr int32_t PARAM_WATCHER_DISTRIBUTED_SERVICE_ID = 3901; +const std::string PARAM_LOW_MEM_PREPARE_NAME = "resourceschedule.memmgr.low.memory.prepare"; } static void DeviceParamCallback(const char* key, const char* value, void* context) { @@ -61,6 +62,9 @@ void DeviceParamCollect::Init(const std::list& saProfiles) } for (auto onDemandEvent : saProfile.stopOnDemand.onDemandEvents) { if (onDemandEvent.eventId == PARAM) { + if (onDemandEvent.name == PARAM_LOW_MEM_PREPARE_NAME) { + lowMemPrepareList_.push_back(saProfile.saId); + } pendingParams_.insert(onDemandEvent.name); } } @@ -133,6 +137,11 @@ int32_t DeviceParamCollect::RemoveUnusedEvent(const OnDemandEvent& event) return ERR_OK; } +const std::vector& DeviceParamCollect::GetLowMemPrepareList() +{ + return lowMemPrepareList_; +} + void SystemAbilityStatusChange::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) { HILOGI("OnAddSystemAbility SA:%{public}d", systemAbilityId); diff --git a/services/samgr/native/source/collect/device_status_collect_manager.cpp b/services/samgr/native/source/collect/device_status_collect_manager.cpp index 66118b7dda2659a374351317115e7558f9bc2082..6803cd337de034a835a2a74de8ef897d590535b2 100644 --- a/services/samgr/native/source/collect/device_status_collect_manager.cpp +++ b/services/samgr/native/source/collect/device_status_collect_manager.cpp @@ -594,4 +594,9 @@ int32_t DeviceStatusCollectManager::UpdateOnDemandEvents(int32_t systemAbilityId } return ERR_OK; } + +const std::vector& DeviceStatusCollectManager::GetLowMemPrepareList() +{ + return collectPluginMap_[PARAM]->GetLowMemPrepareList(); +} } // namespace OHOS diff --git a/services/samgr/native/source/schedule/system_ability_state_machine.cpp b/services/samgr/native/source/schedule/system_ability_state_machine.cpp index 2a83f3a2be723421828276b508715ba4b33ee2ac..e8dc6bf6ea23edfd9062c6b965ca058dc668e4f8 100644 --- a/services/samgr/native/source/schedule/system_ability_state_machine.cpp +++ b/services/samgr/native/source/schedule/system_ability_state_machine.cpp @@ -15,6 +15,7 @@ #include +#include "datetime_ex.h" #include "sam_log.h" #include "string_ex.h" #include "samgr_err_code.h" @@ -176,6 +177,7 @@ bool LoadedStateHandler::CanEnter(SystemAbilityState fromState) void LoadedStateHandler::OnEnter(const std::shared_ptr& context) { + context->lastIdleTime = -1; auto listener = listener_.lock(); if (listener == nullptr) { HILOGE("Scheduler:listener is null"); @@ -191,6 +193,7 @@ bool UnloadableStateHandler::CanEnter(SystemAbilityState fromState) void UnloadableStateHandler::OnEnter(const std::shared_ptr& context) { + context->lastIdleTime = GetTickCount(); auto listener = listener_.lock(); if (listener == nullptr) { HILOGE("Scheduler:listener is null"); @@ -226,6 +229,7 @@ void NotStartedStateHandler::OnEnter(const std::shared_ptr HILOGE("Scheduler:listener is null"); return; } + context->lastStopTime = GetTickCount(); //进程退出 listener->OnProcessNotStartedLocked(context->processName); } 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 ab45a062b5fbc1ba9194cf5a36134ea907e9a1e6..62071a78fe7e756f9ca6b2c7396143644107aa9a 100644 --- a/services/samgr/native/source/schedule/system_ability_state_scheduler.cpp +++ b/services/samgr/native/source/schedule/system_ability_state_scheduler.cpp @@ -54,6 +54,7 @@ constexpr const char *PROCESS_STATE_ENUM_STR[] = { "NOT_STARTED", "STARTED", "STOPPING" }; constexpr const char *PENDINGEVENT_ENUM_STR[] = { "NO_EVENT", "LOAD_ABILITY_EVENT", "UNLOAD_ABILITY_EVENT" }; +const std::string PARAM_LOW_MEM_PREPARE_NAME = "resourceschedule.memmgr.low.memory.prepare"; } void SystemAbilityStateScheduler::Init(const std::list& saProfiles) { @@ -368,7 +369,8 @@ int32_t SystemAbilityStateScheduler::HandleUnloadAbilityEventLocked( result = PendUnloadEventLocked(abilityContext, unloadRequestInfo); break; case SystemAbilityState::LOADED: - if (unloadRequestInfo->unloadEvent.eventId == INTERFACE_CALL) { + if (unloadRequestInfo->unloadEvent.eventId == INTERFACE_CALL || + unloadRequestInfo->unloadEvent.name == PARAM_LOW_MEM_PREPARE_NAME) { result = ProcessDelayUnloadEventLocked(abilityContext->systemAbilityId); } else { result = SendDelayUnloadEventLocked(abilityContext->systemAbilityId, abilityContext->delayUnloadTime); @@ -761,6 +763,33 @@ int32_t SystemAbilityStateScheduler::DoUnloadSystemAbilityLocked( return result; } +int32_t SystemAbilityStateScheduler::UnloadProcess(const std::vector& processList) +{ + HILOGI("Scheduler:UnloadProcess"); + int32_t result = ERR_OK; + std::shared_lock readLock(processMapLock_); + for (auto it : processList) { + if (processContextMap_.count(it) != 0) { + auto& processContext = processContextMap_[it]; + if (processContext == nullptr) { + continue; + } + + int32_t ret = ERR_OK; + std::lock_guard autoLock(processContext->processLock); + if (CanUnloadAllSystemAbilityLocked(processContext)) { + ret = UnloadAllSystemAbilityLocked(processContext); + } + if (ret != ERR_OK) { + result = ret; + HILOGI("Scheduler proc:%{public}s unload fail", + Str16ToStr8(processContext->processName).c_str()); + } + } + } + return result; +} + int32_t SystemAbilityStateScheduler::UnloadAllIdleSystemAbility() { HILOGI("Scheduler:UnloadAllIdleSa"); @@ -1393,6 +1422,30 @@ int32_t SystemAbilityStateScheduler::CheckStopEnableOnce(const OnDemandEvent& ev return result; } +int64_t SystemAbilityStateScheduler::GetSystemAbilityIdleTime(int32_t systemAbilityId) +{ + std::shared_ptr abilityContext; + if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) { + return -1; + } + std::lock_guard autoLock(abilityContext->ownProcessContext->processLock); + return abilityContext->lastIdleTime; +} + +bool SystemAbilityStateScheduler::GetLruIdleSystemAbilityInfo(int32_t systemAbilityId, std::u16string& processName, int64_t& lastStopTime, + int32_t& pid) +{ + std::shared_ptr abilityContext; + if (!GetSystemAbilityContext(systemAbilityId, abilityContext)) { + return false; + } + std::lock_guard autoLock(abilityContext->ownProcessContext->processLock); + processName = abilityContext->ownProcessContext->processName; + pid = abilityContext->ownProcessContext->pid; + lastStopTime = abilityContext->ownProcessContext->lastStopTime; + return true; +} + void SystemAbilityStateScheduler::UnloadEventHandler::ProcessEvent(uint32_t eventId) { int32_t systemAbilityId = static_cast(eventId); diff --git a/services/samgr/native/source/system_ability_manager.cpp b/services/samgr/native/source/system_ability_manager.cpp index 563ea99c6eafe429c523e41071ec7264aad3496a..708a405e83f8ef10cdd926fd066a335d6dbb00a7 100644 --- a/services/samgr/native/source/system_ability_manager.cpp +++ b/services/samgr/native/source/system_ability_manager.cpp @@ -83,6 +83,7 @@ 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 } std::mutex SystemAbilityManager::instanceLock; @@ -1738,6 +1739,52 @@ int32_t SystemAbilityManager::UnloadAllIdleSystemAbility() return abilityStateScheduler_->UnloadAllIdleSystemAbility(); } +int32_t SystemAbilityManager::UnloadProcess(const std::vector& processList) +{ + if (abilityStateScheduler_ == nullptr) { + HILOGE("abilityStateScheduler is nullptr"); + return ERR_INVALID_VALUE; + } + return abilityStateScheduler_->UnloadProcess(processList); +} + +int32_t SystemAbilityManager::GetLruIdleSystemAbilityProc(std::vector& processInfos) +{ + 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)) { + continue; + } + auto procInfo = procInfos.find(info.processName); + if (procInfo == procInfos.end()) { + procInfos[info.processName] = info; + } else if (procInfos[info.processName].lastIdleTime < info.lastIdleTime) { + procInfos[info.processName] = info; + } + } + for (const auto& pair : procInfos) { + if (activeProcess.find(pair.first) == activeProcess.end()) { + processInfos.push_back(pair.second); + } + } + std::sort(processInfos.begin(), processInfos.end(), [](const IdleProcessInfo& a, IdleProcessInfo& b){ + return a.lastIdleTime < b.lastIdleTime; + }); + return ERR_OK; +} + bool SystemAbilityManager::IdleSystemAbility(int32_t systemAbilityId, const std::u16string& procName, const nlohmann::json& idleReason, int32_t& delayTime) { diff --git a/services/samgr/native/source/system_ability_manager_stub.cpp b/services/samgr/native/source/system_ability_manager_stub.cpp index 543aa7f7e44cfad01a406900ccb1cb09084ed949..f10c2ca9f621af8e3cb514e680abc5db85fc6e52 100644 --- a/services/samgr/native/source/system_ability_manager_stub.cpp +++ b/services/samgr/native/source/system_ability_manager_stub.cpp @@ -181,6 +181,10 @@ SystemAbilityManagerStub::SystemAbilityManagerStub() SystemAbilityManagerStub::LocalGetCommonEventExtraDataIdlist; memberFuncMap_[static_cast(SamgrInterfaceCode::GET_LOCAL_ABILITY_MANAGER_PROXY_TRANSCATION)] = SystemAbilityManagerStub::LocalGetLocalAbilityManagerProxy; + memberFuncMap_[static_cast(SamgrInterfaceCode::UNLOAD_IDLE_PROCESS_BYLIST)] = + SystemAbilityManagerStub::LocalUnloadProcess; + memberFuncMap_[static_cast(SamgrInterfaceCode::GET_LRU_IDLE_SYSTEM_ABILITY_PROCESS_TRANSACTION)] = + SystemAbilityManagerStub::LocalGetLruIdleSystemAbilityProc; } int32_t SystemAbilityManagerStub::OnRemoteRequest(uint32_t code, @@ -778,6 +782,66 @@ int32_t SystemAbilityManagerStub::UnloadAllIdleSystemAbilityInner(MessageParcel& return result; } +int32_t SystemAbilityManagerStub::UnloadProcessInner(MessageParcel& data, MessageParcel& reply) +{ + if (!SamgrUtil::CheckCallerProcess("memmgrservice")) { + HILOGE("UnloadProcessInner invalid caller process, only support for memmgrservice"); + return ERR_PERMISSION_DENIED; + } + std::vector processList; + if (!data.ReadString16Vector(&processList)) { + HILOGE("UnloadProcessInner read processList fail"); + return ERR_NULL_OBJECT; + } + int32_t result = UnloadProcess(processList); + HILOGI("UnloadProcessInner result is %{public}d", result); + return result; +} + +int32_t SystemAbilityManagerStub::GetLruIdleSystemAbilityProcInner(MessageParcel& data, MessageParcel& reply) +{ + if (!SamgrUtil::CheckCallerProcess("memmgrservice")) { + HILOGE("GetLruIdleSystemAbilityProcInner invalid caller process, only support for memmgrservice"); + return ERR_PERMISSION_DENIED; + } + HILOGI("GetLruIdleSystemAbilityProcInner called"); + std::vector infos; + int32_t result = GetLruIdleSystemAbilityProc(infos); + bool ret = reply.WriteInt32(result); + if (!ret) { + HILOGE("GetLruIdleSystemAbilityProcInner write reply failed!"); + return ERR_FLATTEN_OBJECT; + } + if (result != ERR_OK) { + HILOGE("GetLruIdleSystemAbilityProc result is %{public}d", result); + return ERR_OK; + } + size_t size = infos.size(); + ret = reply.WriteInt32(size); + if (!ret) { + HILOGE("GetLruIdleSystemAbilityProcInner write size failed!"); + return ERR_FLATTEN_OBJECT; + } + for (auto& systemAbilityProcInfo : infos) { + ret = reply.WriteInt32(systemAbilityProcInfo.pid); + if (!ret) { + HILOGE("GetLruIdleSystemAbilityProcInner write pid failed!"); + return ERR_FLATTEN_OBJECT; + } + ret = reply.WriteString16(systemAbilityProcInfo.processName); + if (!ret) { + HILOGE("GetLruIdleSystemAbilityProcInner write processName failed!"); + return ERR_FLATTEN_OBJECT; + } + ret = reply.WriteInt64(systemAbilityProcInfo.lastIdleTime); + if (!ret) { + HILOGE("GetLruIdleSystemAbilityProcInner write lastIdleTime failed!"); + return ERR_FLATTEN_OBJECT; + } + } + return ERR_OK; +} + int32_t SystemAbilityManagerStub::GetSystemProcessInfoInner(MessageParcel& data, MessageParcel& reply) { HILOGI("GetSystemProcessInfoInner called"); diff --git a/services/samgr/native/test/unittest/src/system_ability_mgr_load_test.cpp b/services/samgr/native/test/unittest/src/system_ability_mgr_load_test.cpp index 1cd777e8ad3d48a43ca9e3867bac196e5ab8dcb7..5c7f8e709b6413c62c892fe780e1653c8ede3466 100644 --- a/services/samgr/native/test/unittest/src/system_ability_mgr_load_test.cpp +++ b/services/samgr/native/test/unittest/src/system_ability_mgr_load_test.cpp @@ -967,4 +967,43 @@ HWTEST_F(SystemAbilityMgrLoadTest, UnloadAllIdleSystemAbility003, TestSize.Level } #endif +/** + * @tc.name: UnloadProcess001 + * @tc.desc: UnloadProcess + * @tc.type: FUNC + * @tc.require: I6NKWX + */ +HWTEST_F(SystemAbilityMgrLoadTest, UnloadProcess001, TestSize.Level3) +{ + DTEST_LOG << "UnloadProcess001 begin" << std::endl; + SamMockPermission::MockProcess("memmgrservice"); + sptr saMgr = new SystemAbilityManager; + InitSaMgr(saMgr); + std::vector processList; + processList.push_back(u"test"); + int32_t ret = saMgr->UnloadProcess(processList); + EXPECT_NE(ret, ERR_INVALID_VALUE); + DTEST_LOG << "UnloadProcess001 end" << std::endl; +} + +/** + * @tc.name: UnloadProcess002 + * @tc.desc: UnloadProcess abilityStateScheduler_ is null + * @tc.type: FUNC + * @tc.require: I6NKWX + */ +HWTEST_F(SystemAbilityMgrLoadTest, UnloadProcess002, TestSize.Level3) +{ + DTEST_LOG << "UnloadProcess002 begin" << std::endl; + SamMockPermission::MockProcess("memmgrservice"); + sptr saMgr = new SystemAbilityManager; + InitSaMgr(saMgr); + saMgr->abilityStateScheduler_ = nullptr; + std::vector processList; + processList.push_back(u"test"); + int32_t ret = saMgr->UnloadProcess(processList); + EXPECT_EQ(ret, ERR_INVALID_VALUE); + DTEST_LOG << "UnloadProcess002 end" << std::endl; +} + } // namespace OHOS \ No newline at end of file diff --git a/services/samgr/native/test/unittest/src/system_ability_mgr_proxy_test.cpp b/services/samgr/native/test/unittest/src/system_ability_mgr_proxy_test.cpp index 1d9c6f59994e67131e40e67937328e0fc4323ed5..18f1d55b856bbd685a1969dd3f41fd8cfeedbf5f 100644 --- a/services/samgr/native/test/unittest/src/system_ability_mgr_proxy_test.cpp +++ b/services/samgr/native/test/unittest/src/system_ability_mgr_proxy_test.cpp @@ -1296,4 +1296,48 @@ HWTEST_F(SystemAbilityMgrProxyTest, GetLocalAbilityManagerProxy003, TestSize.Lev EXPECT_TRUE(ret == nullptr); DTEST_LOG << " GetLocalAbilityManagerProxy003 end " << std::endl; } + +/** + * @tc.name: UnloadProcess001 + * @tc.desc: UnloadProcess + * @tc.type: FUNC + */ +HWTEST_F(SystemAbilityMgrProxyTest, UnloadProcess001, TestSize.Level1) +{ + SamMockPermission::MockProcess("memmgrservice"); + sptr samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + std::vector processList; + processList.push_back(u"test"); + int32_t res = samgrProxy->UnloadProcess(processList); + EXPECT_EQ(res, ERR_OK); +} + + +/** + * @tc.name: GetLruIdleSystemAbilityProc001 + * @tc.desc: GetLruIdleSystemAbilityProc + * @tc.type: FUNC + */ +HWTEST_F(SystemAbilityMgrProxyTest, GetLruIdleSystemAbilityProc001, TestSize.Level1) +{ + SamMockPermission::MockProcess("memmgrservice"); + sptr samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + std::vector procInfos; + int32_t res = samgrProxy->GetLruIdleSystemAbilityProc(procInfos); + EXPECT_EQ(res, ERR_OK); +} + +/** + * @tc.name: GetLruIdleSystemAbilityProc002 + * @tc.desc: GetLruIdleSystemAbilityProc + * @tc.type: FUNC + */ +HWTEST_F(SystemAbilityMgrProxyTest, GetLruIdleSystemAbilityProc002, TestSize.Level1) +{ + sptr samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + std::vector procInfos; + int32_t res = samgrProxy->GetLruIdleSystemAbilityProc(procInfos); + EXPECT_NE(res, ERR_OK); +} + } \ No newline at end of file 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 aa39eee42fca974133cd6fcd631fdc225c970fbe..7f6ae4deb55b2a015ce2605d25713a310c931d90 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 @@ -1885,4 +1885,105 @@ HWTEST_F(SystemAbilityStateSchedulerTest, SetFfrt001, TestSize.Level3) EXPECT_NE(nullptr, systemAbilityStateScheduler->unloadEventHandler_); DTEST_LOG<<"SetFfrt001 END"< systemAbilityStateScheduler = + std::make_shared(); + int32_t invalidSaid = 101; + + int64_t ret = systemAbilityStateScheduler->GetSystemAbilityIdleTime(invalidSaid); + EXPECT_EQ(ret, -1); + DTEST_LOG<<"GetSystemAbilityIdleTime001 END"< systemAbilityStateScheduler = + std::make_shared(); + int said = 401; + + int64_t ret = systemAbilityStateScheduler->GetSystemAbilityIdleTime(said); + EXPECT_EQ(ret, -1); + DTEST_LOG<<"GetSystemAbilityIdleTime002 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"< systemAbilityStateScheduler = + std::make_shared(); + int said = 401; + int64_t lastStopTime = -1; + std::u16string processName; + int32_t pid = -1; + + bool ret = systemAbilityStateScheduler->GetLruIdleSystemAbilityInfo(said, processName, lastStopTime, pid); + EXPECT_NE(lastStopTime, 0); + DTEST_LOG<<"GetLruIdleSystemAbilityInfo002 END"< systemAbilityStateScheduler = + std::make_shared(); + std::list saProfiles; + systemAbilityStateScheduler->Init(saProfiles); + systemAbilityStateScheduler->processContextMap_.clear(); + std::vector processList; + processList.push_back(u"test"); + int32_t ret = systemAbilityStateScheduler->UnloadProcess(processList); + EXPECT_NE(ret, TRANSIT_PROC_STATE_FAIL); + DTEST_LOG<<"UnloadProcess001 END"<