mirror of
https://gitee.com/openharmony/ability_ability_runtime
synced 2024-11-27 01:10:52 +00:00
feat: add killProcessesInBatch
Signed-off-by: yangxuguang-huawei <yangxuguang3@huawei.com>
This commit is contained in:
parent
360bb87f4f
commit
158a439bb5
@ -125,6 +125,11 @@ public:
|
||||
GET_CB_INFO_AND_CALL(env, info, JsAppManager, OnKillProcessWithAccount);
|
||||
}
|
||||
|
||||
static napi_value KillProcessesInBatch(napi_env env, napi_callback_info info)
|
||||
{
|
||||
GET_CB_INFO_AND_CALL(env, info, JsAppManager, OnKillProcessesInBatch);
|
||||
}
|
||||
|
||||
static napi_value KillProcessesByBundleName(napi_env env, napi_callback_info info)
|
||||
{
|
||||
GET_CB_INFO_AND_CALL(env, info, JsAppManager, OnKillProcessesByBundleName);
|
||||
@ -1124,6 +1129,45 @@ private:
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value OnKillProcessesInBatch(napi_env env, size_t argc, napi_value* argv)
|
||||
{
|
||||
TAG_LOGD(AAFwkTag::APPMGR, "called");
|
||||
if (argc < ARGC_ONE) {
|
||||
TAG_LOGE(AAFwkTag::APPMGR, "Params mismatch");
|
||||
ThrowTooFewParametersError(env);
|
||||
return CreateJsUndefined(env);
|
||||
}
|
||||
std::vector<int32_t> pids;
|
||||
if (!AppExecFwk::UnwrapArrayInt32FromJS(env, argv[INDEX_ZERO], pids)) {
|
||||
TAG_LOGE(AAFwkTag::APPMGR, "Parse pids failed");
|
||||
ThrowInvalidParamError(env, "Parse param pids failed, must be array of numbers.");
|
||||
return CreateJsUndefined(env);
|
||||
}
|
||||
auto innerErrorCode = std::make_shared<int32_t>(ERR_OK);
|
||||
NapiAsyncTask::ExecuteCallback execute = [pids, appManager = appManager_, innerErrorCode]() {
|
||||
if (appManager == nullptr || appManager->GetAmsMgr() == nullptr) {
|
||||
TAG_LOGW(AAFwkTag::APPMGR, "null appManager or amsMgr");
|
||||
*innerErrorCode = static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER);
|
||||
return;
|
||||
}
|
||||
*innerErrorCode = appManager->GetAmsMgr()->KillProcessesInBatch(pids);
|
||||
};
|
||||
NapiAsyncTask::CompleteCallback complete =
|
||||
[innerErrorCode](napi_env env, NapiAsyncTask &task, int32_t status) {
|
||||
if (*innerErrorCode == ERR_OK) {
|
||||
task.ResolveWithNoError(env, CreateJsUndefined(env));
|
||||
return;
|
||||
}
|
||||
TAG_LOGE(AAFwkTag::APPMGR, "KillProcessesInBatch failed:%{public}d", *innerErrorCode);
|
||||
task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrorCode));
|
||||
};
|
||||
|
||||
napi_value result = nullptr;
|
||||
NapiAsyncTask::ScheduleHighQos("JSAppManager::OnKillProcessesInBatch",
|
||||
env, CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), &result));
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value OnGetAppMemorySize(napi_env env, size_t argc, napi_value* argv)
|
||||
{
|
||||
napi_value lastParam = (argc > ARGC_ZERO) ? argv[INDEX_ZERO] : nullptr;
|
||||
@ -1680,6 +1724,7 @@ napi_value JsAppManagerInit(napi_env env, napi_value exportObj)
|
||||
JsAppManager::GetRunningProcessInformation);
|
||||
BindNativeFunction(env, exportObj, "isRunningInStabilityTest", moduleName, JsAppManager::IsRunningInStabilityTest);
|
||||
BindNativeFunction(env, exportObj, "killProcessWithAccount", moduleName, JsAppManager::KillProcessWithAccount);
|
||||
BindNativeFunction(env, exportObj, "killProcessesInBatch", moduleName, JsAppManager::KillProcessesInBatch);
|
||||
BindNativeFunction(env, exportObj, "killProcessesByBundleName", moduleName,
|
||||
JsAppManager::KillProcessesByBundleName);
|
||||
BindNativeFunction(env, exportObj, "clearUpApplicationData", moduleName, JsAppManager::ClearUpApplicationData);
|
||||
|
@ -129,6 +129,15 @@ public:
|
||||
virtual int KillProcessWithAccount(const std::string &bundleName, const int accountId,
|
||||
const bool clearPageStack = false, int32_t appIndex = 0) = 0;
|
||||
|
||||
/**
|
||||
* KillProcessesInBatch, kill processes in batch, call KillProcessesInBatch() through proxy object;
|
||||
* the killed bundle won't be started by the watcher.
|
||||
*
|
||||
* @param pids, the pid list of processes are going to be killed.
|
||||
* @return ERR_OK, return back success, others fail.
|
||||
*/
|
||||
virtual int32_t KillProcessesInBatch(const std::vector<int32_t> &pids) = 0;
|
||||
|
||||
/**
|
||||
* UpdateApplicationInfoInstalled, call UpdateApplicationInfoInstalled() through proxy object,
|
||||
* update the application info after new module installed.
|
||||
@ -511,6 +520,7 @@ public:
|
||||
ENABLE_START_PROCESS_FLAG_BY_USER_ID,
|
||||
SET_APP_EXCEPTION_CALLBACK,
|
||||
SET_KEEP_ALIVE_DKV,
|
||||
KILL_PROCESSES_IN_BATCH,
|
||||
// Add enumeration values above
|
||||
END
|
||||
};
|
||||
|
@ -119,6 +119,15 @@ public:
|
||||
virtual int32_t KillProcessWithAccount(const std::string &bundleName, const int accountId,
|
||||
const bool clearPageStack = false, int32_t appIndex = 0) override;
|
||||
|
||||
/**
|
||||
* KillProcessesInBatch, kill processes in batch, call KillProcessesInBatch() through proxy object;
|
||||
* the killed bundle won't be started by the watcher.
|
||||
*
|
||||
* @param pids, the pid list of processes are going to be killed.
|
||||
* @return ERR_OK, return back success, others fail.
|
||||
*/
|
||||
virtual int32_t KillProcessesInBatch(const std::vector<int32_t> &pids) override;
|
||||
|
||||
/**
|
||||
* UpdateApplicationInfoInstalled, call UpdateApplicationInfoInstalled() through proxy object,
|
||||
* update the application info after new module installed.
|
||||
|
@ -54,6 +54,7 @@ private:
|
||||
int32_t HandleKillProcessesByPids(MessageParcel &data, MessageParcel &reply);
|
||||
int32_t HandleAttachPidToParent(MessageParcel &data, MessageParcel &reply);
|
||||
int32_t HandleKillProcessWithAccount(MessageParcel &data, MessageParcel &reply);
|
||||
int32_t HandleKillProcessesInBatch(MessageParcel &data, MessageParcel &reply);
|
||||
int32_t HandleKillApplication(MessageParcel &data, MessageParcel &reply);
|
||||
int32_t HandleForceKillApplication(MessageParcel &data, MessageParcel &reply);
|
||||
int32_t HandleKillProcessesByAccessTokenId(MessageParcel &data, MessageParcel &reply);
|
||||
|
@ -355,6 +355,36 @@ int32_t AmsMgrProxy::KillProcessWithAccount(
|
||||
return reply.ReadInt32();
|
||||
}
|
||||
|
||||
int32_t AmsMgrProxy::KillProcessesInBatch(const std::vector<int32_t> &pids)
|
||||
{
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option(MessageOption::TF_SYNC);
|
||||
if (!WriteInterfaceToken(data)) {
|
||||
return ERR_INVALID_DATA;
|
||||
}
|
||||
|
||||
if (!data.WriteUint32(pids.size())) {
|
||||
TAG_LOGE(AAFwkTag::APPMGR, "Write size failed");
|
||||
return ERR_FLATTEN_OBJECT;
|
||||
}
|
||||
for (const auto &pid: pids) {
|
||||
if (!data.WriteInt32(pid)) {
|
||||
TAG_LOGE(AAFwkTag::APPMGR, "Write pid failed");
|
||||
return ERR_FLATTEN_OBJECT;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ret = SendTransactCmd(static_cast<uint32_t>(IAmsMgr::Message::KILL_PROCESSES_IN_BATCH),
|
||||
data, reply, option);
|
||||
if (ret != NO_ERROR) {
|
||||
TAG_LOGW(AAFwkTag::APPMGR, "SendRequest err: %{public}d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return reply.ReadInt32();
|
||||
}
|
||||
|
||||
int32_t AmsMgrProxy::KillApplication(const std::string &bundleName, bool clearPageStack, int32_t appIndex)
|
||||
{
|
||||
TAG_LOGI(AAFwkTag::APPMGR, "start");
|
||||
|
@ -217,6 +217,8 @@ int32_t AmsMgrStub::OnRemoteRequestInnerFourth(uint32_t code, MessageParcel &dat
|
||||
return HandleIsCallerKilling(data, reply);
|
||||
case static_cast<uint32_t>(IAmsMgr::Message::SET_KEEP_ALIVE_DKV):
|
||||
return HandleSetKeepAliveDkv(data, reply);
|
||||
case static_cast<uint32_t>(IAmsMgr::Message::KILL_PROCESSES_IN_BATCH):
|
||||
return HandleKillProcessesInBatch(data, reply);
|
||||
}
|
||||
return AAFwk::ERR_CODE_NOT_EXIST;
|
||||
}
|
||||
@ -356,6 +358,31 @@ ErrCode AmsMgrStub::HandleKillProcessWithAccount(MessageParcel &data, MessagePar
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
ErrCode AmsMgrStub::HandleKillProcessesInBatch(MessageParcel &data, MessageParcel &reply)
|
||||
{
|
||||
TAG_LOGI(AAFwkTag::APPMGR, "enter");
|
||||
|
||||
HITRACE_METER(HITRACE_TAG_APP);
|
||||
|
||||
auto size = data.ReadUint32();
|
||||
TAG_LOGI(AAFwkTag::APPMGR, "pids.size=%{public}d", size);
|
||||
if (size == 0 || size > MAX_KILL_PROCESS_PID_COUNT) {
|
||||
TAG_LOGE(AAFwkTag::APPMGR, "Invalid size");
|
||||
return ERR_INVALID_VALUE;
|
||||
}
|
||||
std::vector<int32_t> pids;
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
pids.emplace_back(data.ReadInt32());
|
||||
}
|
||||
|
||||
int32_t result = KillProcessesInBatch(pids);
|
||||
reply.WriteInt32(result);
|
||||
|
||||
TAG_LOGI(AAFwkTag::APPMGR, "end");
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
ErrCode AmsMgrStub::HandleKillApplication(MessageParcel &data, MessageParcel &reply)
|
||||
{
|
||||
HITRACE_METER(HITRACE_TAG_APP);
|
||||
|
@ -133,6 +133,15 @@ public:
|
||||
virtual int32_t KillProcessWithAccount(const std::string &bundleName, const int accountId,
|
||||
const bool clearPageStack = false, int32_t appIndex = 0) override;
|
||||
|
||||
/**
|
||||
* KillProcessesInBatch, kill processes in batch, call KillProcessesInBatch() through proxy object;
|
||||
* the killed bundle won't be started by the watcher.
|
||||
*
|
||||
* @param pids, the pid list of processes are going to be killed.
|
||||
* @return ERR_OK, return back success, others fail.
|
||||
*/
|
||||
virtual int32_t KillProcessesInBatch(const std::vector<int32_t> &pids) override;
|
||||
|
||||
/**
|
||||
* UpdateApplicationInfoInstalled, call UpdateApplicationInfoInstalled() through proxy object,
|
||||
* update the application info after new module installed.
|
||||
|
@ -195,6 +195,15 @@ public:
|
||||
*/
|
||||
virtual void KillProcessesByPids(std::vector<int32_t> &pids);
|
||||
|
||||
/**
|
||||
* KillProcessesInBatch, kill processes in batch;
|
||||
* the killed bundle won't be started by the watcher.
|
||||
*
|
||||
* @param pids, the pid list of processes are going to be killed.
|
||||
* @return ERR_OK, return back success, others fail.
|
||||
*/
|
||||
virtual int32_t KillProcessesInBatch(const std::vector<int32_t> &pids);
|
||||
|
||||
/**
|
||||
* Set child and parent relationship
|
||||
* @param token child process
|
||||
@ -1922,6 +1931,8 @@ private:
|
||||
std::atomic<int32_t> willKillPidsNum_ = 0;
|
||||
std::shared_ptr<AAFwk::TaskHandlerWrap> delayKillTaskHandler_;
|
||||
std::unordered_set<std::string> nwebPreloadSet_ {};
|
||||
ffrt::mutex killedBundleSetMutex_;
|
||||
std::set<std::string> killedBundleSet_;
|
||||
};
|
||||
} // namespace AppExecFwk
|
||||
} // namespace OHOS
|
||||
|
@ -291,6 +291,15 @@ int32_t AmsMgrScheduler::KillProcessWithAccount(
|
||||
"KillProcessWithAccount");
|
||||
}
|
||||
|
||||
int32_t AmsMgrScheduler::KillProcessesInBatch(const std::vector<int32_t> &pids)
|
||||
{
|
||||
TAG_LOGI(AAFwkTag::APPMGR, "pids.size=%{public}zu", pids.size());
|
||||
if (!IsReady()) {
|
||||
return ERR_INVALID_OPERATION;
|
||||
}
|
||||
return amsMgrServiceInner_->KillProcessesInBatch(pids);
|
||||
}
|
||||
|
||||
void AmsMgrScheduler::AbilityAttachTimeOut(const sptr<IRemoteObject> &token)
|
||||
{
|
||||
TAG_LOGI(AAFwkTag::APPMGR, "call");
|
||||
|
@ -628,6 +628,13 @@ void AppMgrServiceInner::LoadAbility(std::shared_ptr<AbilityInfo> abilityInfo, s
|
||||
TAG_LOGE(AAFwkTag::APPMGR, "checkLoadAbilityConditions fail");
|
||||
return;
|
||||
}
|
||||
{
|
||||
std::lock_guard lock(killedBundleSetMutex_);
|
||||
if (killedBundleSet_.find(abilityInfo->bundleName) != killedBundleSet_.end()) {
|
||||
TAG_LOGW(AAFwkTag::APPMGR, "%{public}s is being killed", abilityInfo->bundleName.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (abilityInfo->type == AbilityType::PAGE) {
|
||||
AbilityRuntime::FreezeUtil::LifecycleFlow flow = {loadParam->token,
|
||||
AbilityRuntime::FreezeUtil::TimeoutState::LOAD};
|
||||
@ -2902,6 +2909,40 @@ void AppMgrServiceInner::KillProcessesByUserId(int32_t userId)
|
||||
}
|
||||
}
|
||||
|
||||
int32_t AppMgrServiceInner::KillProcessesInBatch(const std::vector<int32_t> &pids)
|
||||
{
|
||||
CHECK_CALLER_IS_SYSTEM_APP;
|
||||
if (!AAFwk::PermissionVerification::GetInstance()->VerifyCallingPermission(
|
||||
AAFwk::PermissionConstants::PERMISSION_KILL_APP_PROCESSES)) {
|
||||
TAG_LOGE(AAFwkTag::APPMGR, "verify permission failed.");
|
||||
return ERR_PERMISSION_DENIED;
|
||||
}
|
||||
if (!AAFwk::AppUtils::GetInstance().IsStartOptionsWithAnimation()) {
|
||||
TAG_LOGE(AAFwkTag::APPMGR, "not supported.");
|
||||
return AAFwk::ERR_CAPABILITY_NOT_SUPPORT;
|
||||
}
|
||||
std::vector<int32_t> killPids;
|
||||
for (const auto& pid: pids) {
|
||||
auto appRecord = GetAppRunningRecordByPid(pid);
|
||||
if (appRecord == nullptr) {
|
||||
TAG_LOGE(AAFwkTag::APPMGR, "appRecord null");
|
||||
continue;
|
||||
}
|
||||
killPids.emplace_back(pid);
|
||||
std::string bundleName = appRecord->GetBundleName();
|
||||
{
|
||||
std::lock_guard lock(killedBundleSetMutex_);
|
||||
killedBundleSet_.insert(bundleName);
|
||||
}
|
||||
}
|
||||
std::lock_guard lock(killedBundleSetMutex_);
|
||||
for (const auto& pid: killPids) {
|
||||
(void)KillProcessByPid(pid, "KillProcessesInBatch");
|
||||
}
|
||||
killedBundleSet_.clear();
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void AppMgrServiceInner::KillProcessesByPids(std::vector<int32_t> &pids)
|
||||
{
|
||||
for (const auto& pid: pids) {
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
MOCK_METHOD1(KillProcessByAbilityToken, void(const sptr<IRemoteObject>& token));
|
||||
MOCK_METHOD1(KillProcessesByUserId, void(int32_t userId));
|
||||
MOCK_METHOD4(KillProcessWithAccount, int(const std::string&, const int, const bool clearPageStack, int32_t));
|
||||
MOCK_METHOD1(KillProcessesInBatch, int(const std::vector<int32_t> &pids));
|
||||
MOCK_METHOD2(UpdateApplicationInfoInstalled, int(const std::string&, const int uid));
|
||||
MOCK_METHOD3(ForceKillApplication, int32_t(const std::string& appName, const int userId, const int appIndex));
|
||||
MOCK_METHOD3(KillApplication, int32_t(const std::string& bundleName, const bool clearPageStack, int32_t appIndex));
|
||||
|
Loading…
Reference in New Issue
Block a user