应用查杀记录详细原因

Signed-off-by: zhangyuhang72 <zhangyuhang72@huawei.com>
Change-Id: I4575b702901f9f5cadbc0db924c57508a8537708
This commit is contained in:
zhangyuhang72 2024-01-31 10:09:46 +00:00
parent 2e822d8752
commit 914cacc416
43 changed files with 715 additions and 226 deletions

View File

@ -42,6 +42,7 @@
#include "common_event_manager.h"
#include "context_deal.h"
#include "context_impl.h"
#include "exit_reason.h"
#include "extension_ability_info.h"
#include "extension_module_loader.h"
#include "extension_plugin_info.h"
@ -1389,7 +1390,8 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con
// if app's callback has been registered, let app decide whether exit or not.
HILOG_ERROR("\n%{public}s is about to exit due to RuntimeError\nError type:%{public}s\n%{public}s",
bundleName.c_str(), errorObj.name.c_str(), summary.c_str());
AbilityManagerClient::GetInstance()->RecordAppExitReason(REASON_JS_ERROR);
AAFwk::ExitReason exitReason = { REASON_JS_ERROR, errorObj.name };
AbilityManagerClient::GetInstance()->RecordAppExitReason(exitReason);
appThread->ScheduleProcessSecurityExit();
};
(static_cast<AbilityRuntime::JsRuntime&>(*runtime)).RegisterUncaughtExceptionHandler(uncaughtExceptionInfo);

View File

@ -19,6 +19,7 @@
#include "ability_manager_client.h"
#include "ability_state.h"
#include "app_recovery.h"
#include "exit_reason.h"
#include "ffrt.h"
#include "freeze_util.h"
#include "hilog_wrapper.h"
@ -157,7 +158,8 @@ int AppfreezeInner::AcquireStack(const FaultData& info, bool onlyMainThread)
if (isExit) {
faultData.forceExit = true;
faultData.waitSaveState = AppRecovery::GetInstance().IsEnabled();
AbilityManagerClient::GetInstance()->RecordAppExitReason(REASON_APP_FREEZE);
AAFwk::ExitReason exitReason = { REASON_APP_FREEZE, faultData.errorObject.name };
AbilityManagerClient::GetInstance()->RecordAppExitReason(exitReason);
}
NotifyANR(faultData);
if (isExit) {

View File

@ -77,6 +77,7 @@ napi_value CreateJsLaunchParam(napi_env env, const AAFwk::LaunchParam& launchPar
}
napi_set_named_property(env, object, "launchReason", CreateJsValue(env, launchParam.launchReason));
napi_set_named_property(env, object, "lastExitReason", CreateJsValue(env, launchParam.lastExitReason));
napi_set_named_property(env, object, "lastExitMessage", CreateJsValue(env, launchParam.lastExitMessage));
return object;
}

View File

@ -596,6 +596,7 @@ napi_value SimulatorImpl::CreateJsLaunchParam(napi_env env)
napi_create_object(env, &objValue);
napi_set_named_property(env, objValue, "launchReason", CreateJsValue(env, AAFwk::LAUNCHREASON_UNKNOWN));
napi_set_named_property(env, objValue, "lastExitReason", CreateJsValue(env, AAFwk::LASTEXITREASON_UNKNOWN));
napi_set_named_property(env, objValue, "lastExitMessage", CreateJsValue(env, ""));
return objValue;
}

View File

@ -82,6 +82,7 @@ ohos_shared_library("ability_manager") {
"${ability_runtime_services_path}/abilitymgr/src/auto_startup_info.cpp",
"${ability_runtime_services_path}/abilitymgr/src/caller_info.cpp",
"${ability_runtime_services_path}/abilitymgr/src/dialog_session_info.cpp",
"${ability_runtime_services_path}/abilitymgr/src/exit_reason.cpp",
"${ability_runtime_services_path}/abilitymgr/src/extension_running_info.cpp",
"${ability_runtime_services_path}/abilitymgr/src/image_info.cpp",
"${ability_runtime_services_path}/abilitymgr/src/insight_intent_execute_callback_proxy.cpp",
@ -200,6 +201,7 @@ ohos_shared_library("ability_manager_c") {
libs = []
ldflags = [ "-Wl,--exclude-libs=ALL" ]
deps = [ ":ability_manager" ]
external_deps = [ "c_utils:utils" ]
innerapi_tags = [ "platformsdk" ]
subsystem_name = "ability"
part_name = "ability_runtime"

View File

@ -1217,14 +1217,22 @@ public:
* @param exitReason The reason of app exit.
* @return Returns ERR_OK on success, others on failure.
*/
ErrCode ForceExitApp(const int32_t pid, Reason exitReason);
ErrCode ForceExitApp(const int32_t pid, const ExitReason &exitReason);
/**
* Record app exit reason.
* @param exitReason The reason of app exit.
* @return Returns ERR_OK on success, others on failure.
*/
ErrCode RecordAppExitReason(Reason exitReason);
ErrCode RecordAppExitReason(const ExitReason &exitReason);
/**
* Record the process exit reason before the process being killed.
* @param pid The process id.
* @param exitReason The reason of process exit.
* @return Returns ERR_OK on success, others on failure.
*/
int32_t RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason);
/**
* Set rootSceneSession by SCB.

View File

@ -25,9 +25,10 @@ extern "C" {
/**
* Record app exit reason.
* @param exitReason The reason of app exit. defined in ability_state.h
* @param exitMsg The message of app exit.
* @return Returns ERR_OK on success, others on failure.
*/
int RecordAppExitReason(int exitReason);
int RecordAppExitReason(int exitReason, const char *exitMsg = "");
#ifdef __cplusplus
}

View File

@ -367,6 +367,11 @@ enum {
* Result(2097221) for developer mode.
*/
ERR_NOT_DEVELOPER_MODE,
/**
* Result(2097222) for get active ability list empty when record exit reason.
*/
ERR_GET_ACTIVE_ABILITY_LIST_EMPTY,
};
enum {

View File

@ -29,6 +29,7 @@
#include "ability_state_data.h"
#include "app_debug_listener_interface.h"
#include "auto_startup_info.h"
#include "exit_reason.h"
#include "extension_running_info.h"
#include "free_install_observer_interface.h"
#include "iability_controller.h"
@ -1078,7 +1079,7 @@ public:
* @param exitReason The reason of app exit.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int32_t ForceExitApp(const int32_t pid, Reason exitReason)
virtual int32_t ForceExitApp(const int32_t pid, const ExitReason &exitReason)
{
return 0;
}
@ -1088,7 +1089,18 @@ public:
* @param exitReason The reason of app exit.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int32_t RecordAppExitReason(Reason exitReason)
virtual int32_t RecordAppExitReason(const ExitReason &exitReason)
{
return 0;
}
/**
* Record the process exit reason before the process being killed.
* @param pid The process id.
* @param exitReason The reason of process exit.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int32_t RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason)
{
return 0;
}

View File

@ -447,6 +447,7 @@ enum class AbilityManagerInterfaceCode {
FORCE_EXIT_APP = 6001,
RECORD_APP_EXIT_REASON = 6002,
RECORD_PROCESS_EXIT_REASON = 6003,
// ipc id for register auto startup system callback
REGISTER_AUTO_STARTUP_SYSTEM_CALLBACK = 6101,

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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.
*/
#ifndef OHOS_ABILITY_RUNTIME_EXIT_REASON_H
#define OHOS_ABILITY_RUNTIME_EXIT_REASON_H
#include <string>
#include "ability_state.h"
#include "parcel.h"
namespace OHOS {
namespace AAFwk {
struct ExitReason : public Parcelable {
ExitReason() = default;
ExitReason(const Reason reason, const std::string &exitMsg);
Reason reason = Reason::REASON_UNKNOWN;
std::string exitMsg = "";
bool ReadFromParcel(Parcel &parcel);
virtual bool Marshalling(Parcel &parcel) const override;
static ExitReason *Unmarshalling(Parcel &parcel);
};
} // namespace AAFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_EXIT_REASON_H

View File

@ -16,6 +16,8 @@
#ifndef OHOS_ABILITY_RUNTIME_LAUNCH_PARAM_H
#define OHOS_ABILITY_RUNTIME_LAUNCH_PARAM_H
#include <string>
#include "parcel.h"
namespace OHOS {
@ -70,6 +72,7 @@ enum OnContinueResult {
struct LaunchParam : public Parcelable {
LaunchReason launchReason = LaunchReason::LAUNCHREASON_UNKNOWN;
LastExitReason lastExitReason = LastExitReason::LASTEXITREASON_NORMAL;
std::string lastExitMessage = "";
bool ReadFromParcel(Parcel &parcel);
virtual bool Marshalling(Parcel &parcel) const override;

View File

@ -17,14 +17,19 @@
#include "ability_manager_client.h"
#include "ability_state.h"
#include "exit_reason.h"
int RecordAppExitReason(int exitReason)
int RecordAppExitReason(int exitReason, const char *exitMsg)
{
if (exitReason < static_cast<int>(OHOS::AAFwk::Reason::REASON_MIN) ||
exitReason > static_cast<int>(OHOS::AAFwk::Reason::REASON_MAX)) {
return -1;
}
OHOS::AAFwk::Reason reason = static_cast<OHOS::AAFwk::Reason>(exitReason);
std::string exitMsgStr(exitMsg);
OHOS::AAFwk::ExitReason exitReasonData = { reason, exitMsgStr };
auto instance = OHOS::AAFwk::AbilityManagerClient::GetInstance();
return instance->RecordAppExitReason(static_cast<OHOS::AAFwk::Reason>(exitReason));
return instance->RecordAppExitReason(exitReasonData);
}

View File

@ -31,6 +31,7 @@ abilityms_files = [
"src/ability_scheduler_proxy.cpp",
"src/ability_token_stub.cpp",
"src/app_scheduler.cpp",
"src/app_exit_reason_helper.cpp",
"src/connection_record.cpp",
"src/data_ability_caller_recipient.cpp",
"src/data_ability_manager.cpp",

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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.
*/
#ifndef OHOS_ABILITY_RUNTIME_ABILITY_MANAGER_CONSTANTS
#define OHOS_ABILITY_RUNTIME_ABILITY_MANAGER_CONSTANTS
#include <string>
namespace OHOS {
namespace AAFwk {
constexpr const int32_t NO_PID = -1;
} // namespace AAFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_ABILITY_MANAGER_CONSTANTS

View File

@ -864,14 +864,22 @@ public:
* @param exitReason The reason of app exit.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int32_t ForceExitApp(const int32_t pid, Reason exitReason) override;
virtual int32_t ForceExitApp(const int32_t pid, const ExitReason &exitReason) override;
/**
* Record app exit reason.
* @param exitReason The reason of app exit.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int32_t RecordAppExitReason(Reason exitReason) override;
virtual int32_t RecordAppExitReason(const ExitReason &exitReason) override;
/**
* Record the process exit reason before the process being killed.
* @param pid The process id.
* @param exitReason The reason of process exit.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int32_t RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason) override;
/**
* Set rootSceneSession by SCB.

View File

@ -35,6 +35,7 @@
#include "ability_manager_stub.h"
#include "ams_configuration_parameter.h"
#include "app_debug_listener_interface.h"
#include "app_exit_reason_helper.h"
#include "app_mgr_interface.h"
#include "app_scheduler.h"
#include "auto_startup_info.h"
@ -1161,7 +1162,7 @@ public:
* @param exitReason The reason of app exit.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int32_t RecordAppExitReason(Reason exitReason) override;
virtual int32_t RecordAppExitReason(const ExitReason &exitReason) override;
/**
* Force app exit and record exit reason.
@ -1169,7 +1170,15 @@ public:
* @param exitReason The reason of app exit.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int32_t ForceExitApp(const int32_t pid, Reason exitReason) override;
virtual int32_t ForceExitApp(const int32_t pid, const ExitReason &exitReason) override;
/**
* Record the process exit reason before the process being killed.
* @param pid The process id.
* @param exitReason The reason of process exit.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int32_t RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason) override;
int32_t GetConfiguration(AppExecFwk::Configuration& config);
@ -1796,8 +1805,6 @@ private:
void ReleaseAbilityTokenMap(const sptr<IRemoteObject> &token);
void RecordAppExitReasonAtUpgrade(const AppExecFwk::BundleInfo &bundleInfo);
bool CheckPrepareTerminateEnable();
bool CheckCollaboratorType(int32_t type);
@ -1949,6 +1956,7 @@ private:
std::unordered_map<int32_t, sptr<IAbilityManagerCollaborator>> collaboratorMap_;
std::shared_ptr<AbilityDebugDeal> abilityDebugDeal_;
std::shared_ptr<AppExitReasonHelper> appExitReasonHelper_;
};
} // namespace AAFwk
} // namespace OHOS

View File

@ -235,6 +235,7 @@ private:
int32_t ForceExitAppInner(MessageParcel &data, MessageParcel &reply);
int32_t RecordAppExitReasonInner(MessageParcel &data, MessageParcel &reply);
int32_t RecordProcessExitReasonInner(MessageParcel &data, MessageParcel &reply);
int SetRootSceneSessionInner(MessageParcel &data, MessageParcel &reply);
int CallUIAbilityBySCBInner(MessageParcel &data, MessageParcel &reply);

View File

@ -33,6 +33,7 @@
#include "application_info.h"
#include "bundlemgr/bundle_mgr_interface.h"
#include "call_container.h"
#include "exit_reason.h"
#include "ipc_skeleton.h"
#include "lifecycle_deal.h"
#include "lifecycle_state_info.h"
@ -842,7 +843,7 @@ public:
AppState GetAppState() const;
void SetLaunchReason(const LaunchReason &reason);
void SetLastExitReason(const LastExitReason &reason);
void SetLastExitReason(const ExitReason &exitReason);
void ContinueAbility(const std::string &deviceId, uint32_t versionCode);
void NotifyContinuationResult(int32_t result);
std::shared_ptr<MissionList> GetOwnedMissionList() const;
@ -993,6 +994,7 @@ private:
Want &want, std::vector<std::string> &uriVec, const std::string &targetBundleName, uint32_t tokenId);
bool CheckUriPermission(Uri &uri, uint32_t &flag, uint32_t callerTokenId, bool permission, int32_t userId);
LastExitReason CovertAppExitReasonToLastReason(const Reason exitReason);
void NotifyMissionBindPid();

View File

@ -22,6 +22,7 @@
#include "ability_util.h"
#include "distributed_kv_data_manager.h"
#include "exit_reason.h"
#include "singleton.h"
namespace OHOS {
@ -32,11 +33,11 @@ public:
virtual ~AppExitReasonDataManager();
int32_t SetAppExitReason(
const std::string &bundleName, const std::vector<std::string> &abilityList, const AAFwk::Reason &reason);
int32_t SetAppExitReason(const std::string &bundleName, const std::vector<std::string> &abilityList,
const AAFwk::ExitReason &exitReason);
int32_t GetAppExitReason(
const std::string &bundleName, const std::string &abilityName, bool &isSetReason, AAFwk::Reason &reason);
int32_t GetAppExitReason(const std::string &bundleName, const std::string &abilityName, bool &isSetReason,
AAFwk::ExitReason &exitReason);
int32_t DeleteAppExitReason(const std::string &bundleName);
@ -56,11 +57,11 @@ private:
DistributedKv::Status GetKvStore();
bool CheckKvStore();
DistributedKv::Value ConvertAppExitReasonInfoToValue(
const std::vector<std::string> &abilityList, const AAFwk::Reason &reason);
void ConvertAppExitReasonInfoFromValue(const DistributedKv::Value &value, AAFwk::Reason &reason,
const std::vector<std::string> &abilityList, const AAFwk::ExitReason &exitReason);
void ConvertAppExitReasonInfoFromValue(const DistributedKv::Value &value, AAFwk::ExitReason &exitReason,
int64_t &time_stamp, std::vector<std::string> &abilityList);
void UpdateAppExitReason(
const std::string &bundleName, const std::vector<std::string> &abilityList, const AAFwk::Reason &reason);
void UpdateAppExitReason(const std::string &bundleName, const std::vector<std::string> &abilityList,
const AAFwk::ExitReason &exitReason);
void InnerDeleteAppExitReason(const std::string &bundleName);
void UpdateAbilityRecoverInfo(const std::string &bundleName,

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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.
*/
#ifndef OHOS_ABILITY_RUNTIME_APP_EXIT_REASON_HELPER
#define OHOS_ABILITY_RUNTIME_APP_EXIT_REASON_HELPER
#include <memory>
#include <mutex>
#include "bundle_info.h"
#include "exit_reason.h"
#include "mission_list_manager.h"
#include "scene_board/ui_ability_lifecycle_manager.h"
namespace OHOS {
namespace AAFwk {
class AppExitReasonHelper {
public:
AppExitReasonHelper(std::shared_ptr<UIAbilityLifecycleManager> &uiAbilityLifecycleManager,
std::unordered_map<int, std::shared_ptr<MissionListManager>> &missionListManagers,
ffrt::mutex &managersMutex);
void SetCurrentMissionListManager(const std::shared_ptr<MissionListManager> currentMissionListManager);
int32_t RecordAppExitReason(const ExitReason &exitReason);
int32_t RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason);
int32_t RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason, const std::string bundleName,
const int32_t uid);
private:
void GetActiveAbilityListByU0(const std::string bundleName, std::vector<std::string> &abilityLists,
const int32_t pid);
void GetActiveAbilityListByUser(const std::string bundleName, std::vector<std::string> &abilityLists,
const int32_t targetUserId, const int32_t pid);
std::shared_ptr<MissionListManager> GetListManagerByUserId(const int32_t userId);
bool IsExitReasonValid(const ExitReason &exitReason);
std::shared_ptr<UIAbilityLifecycleManager> &uiAbilityLifecycleManager_;
std::unordered_map<int, std::shared_ptr<MissionListManager>> &missionListManagers_;
std::shared_ptr<MissionListManager> currentMissionListManager_;
ffrt::mutex &managersMutex_;
};
} // namespace AAFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_APP_EXIT_REASON_HELPER

View File

@ -19,6 +19,7 @@
#include <list>
#include <memory>
#include "ability_manager_constants.h"
#include "ability_record.h"
#include "iremote_object.h"
#include "mission.h"
@ -222,7 +223,8 @@ public:
int32_t GetMissionCountByUid(int32_t targetUid) const;
void FindEarliestMission(std::shared_ptr<Mission>& targetMission) const;
int32_t GetMissionCount() const;
void GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList);
void GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList,
int32_t pid = NO_PID);
private:
std::string GetTypeName();

View File

@ -340,7 +340,8 @@ public:
int DoAbilityForeground(std::shared_ptr<AbilityRecord> &abilityRecord, uint32_t flag);
void GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList);
void GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList,
int32_t pid = NO_PID);
void CallRequestDone(const std::shared_ptr<AbilityRecord> &abilityRecord, const sptr<IRemoteObject> &callStub);
@ -509,7 +510,6 @@ private:
int32_t GetMissionIdByAbilityTokenInner(const sptr<IRemoteObject> &token);
std::shared_ptr<AbilityRecord> GetAbilityFromTerminateListInner(const sptr<IRemoteObject> &token);
void SetLastExitReason(std::shared_ptr<AbilityRecord> &abilityRecord);
LastExitReason CovertAppExitReasonToLastReason(const Reason exitReason);
bool IsAppLastAbility(const std::shared_ptr<AbilityRecord> &abilityRecord);
int PrepareClearMissionLocked(int missionId, const std::shared_ptr<Mission> &mission);

View File

@ -23,6 +23,7 @@
#include <unordered_map>
#include "cpp/mutex.h"
#include "ability_manager_constants.h"
#include "ability_record.h"
#include "isession_handler_interface.h"
#include "session/host/include/zidl/session_interface.h"
@ -236,7 +237,8 @@ public:
*/
int32_t GetSessionIdByAbilityToken(const sptr<IRemoteObject> &token);
void GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList);
void GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList,
int32_t pid = NO_PID);
bool PrepareTerminateAbility(const std::shared_ptr<AbilityRecord> &abilityRecord);
void SetSessionHandler(const sptr<ISessionHandler> &handler);
@ -250,7 +252,7 @@ public:
std::shared_ptr<AbilityRecord> GetAbilityRecordsById(int32_t sessionId) const;
void GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList,
int32_t targetUserId) const;
int32_t targetUserId, int32_t pid = NO_PID) const;
void OnAppStateChanged(const AppInfo &info, int32_t targetUserId);
@ -355,7 +357,6 @@ private:
void EraseSpecifiedAbilityRecord(const std::shared_ptr<AbilityRecord> &abilityRecord);
void SetLastExitReason(std::shared_ptr<AbilityRecord> &abilityRecord) const;
LastExitReason CovertAppExitReasonToLastReason(const Reason exitReason) const;
void SetRevicerInfo(const AbilityRequest &abilityRequest, std::shared_ptr<AbilityRecord> &abilityRecord) const;
bool CheckPrepareTerminateEnable(const std::shared_ptr<AbilityRecord> &abilityRecord);
@ -368,6 +369,7 @@ private:
std::shared_ptr<AbilityRecord> uiAbilityRecord) const;
void CheckSpecified(AbilityRequest &abilityRequest, std::shared_ptr<AbilityRecord> uiAbilityRecord);
void SendKeyEvent(AbilityRequest &abilityRequest) const;
bool CheckPid(const std::shared_ptr<AbilityRecord> abilityRecord, const int32_t pid) const;
mutable ffrt::mutex sessionLock_;
std::unordered_map<int32_t, std::shared_ptr<AbilityRecord>> sessionAbilityMap_;

View File

@ -1453,7 +1453,7 @@ ErrCode AbilityManagerClient::ShareDataDone(
return abms->ShareDataDone(token, resultCode, uniqueId, wantParam);
}
ErrCode AbilityManagerClient::ForceExitApp(const int32_t pid, Reason exitReason)
ErrCode AbilityManagerClient::ForceExitApp(const int32_t pid, const ExitReason &exitReason)
{
HILOG_DEBUG("begin.");
auto abms = GetAbilityManager();
@ -1461,14 +1461,24 @@ ErrCode AbilityManagerClient::ForceExitApp(const int32_t pid, Reason exitReason)
return abms->ForceExitApp(pid, exitReason);
}
ErrCode AbilityManagerClient::RecordAppExitReason(Reason exitReason)
ErrCode AbilityManagerClient::RecordAppExitReason(const ExitReason &exitReason)
{
HILOG_DEBUG("begin.");
HILOG_DEBUG("RecordAppExitReason reason:%{public}d, exitMsg: %{public}s", exitReason.reason,
exitReason.exitMsg.c_str());
auto abms = GetAbilityManager();
CHECK_POINTER_RETURN_NOT_CONNECTED(abms);
return abms->RecordAppExitReason(exitReason);
}
ErrCode AbilityManagerClient::RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason)
{
HILOG_DEBUG("RecordProcessExitReason pid:%{public}d, reason:%{public}d, exitMsg: %{public}s",
pid, exitReason.reason, exitReason.exitMsg.c_str());
auto abms = GetAbilityManager();
CHECK_POINTER_RETURN_NOT_CONNECTED(abms);
return abms->RecordProcessExitReason(pid, exitReason);
}
void AbilityManagerClient::SetRootSceneSession(sptr<IRemoteObject> rootSceneSession)
{
HILOG_INFO("call");

View File

@ -3832,7 +3832,7 @@ int32_t AbilityManagerProxy::ShareDataDone(
return reply.ReadInt32();
}
int32_t AbilityManagerProxy::ForceExitApp(const int32_t pid, Reason exitReason)
int32_t AbilityManagerProxy::ForceExitApp(const int32_t pid, const ExitReason &exitReason)
{
HILOG_DEBUG("start.");
MessageParcel data;
@ -3843,16 +3843,8 @@ int32_t AbilityManagerProxy::ForceExitApp(const int32_t pid, Reason exitReason)
HILOG_ERROR("write interface token failed.");
return INNER_ERR;
}
if (!data.WriteInt32(pid)) {
HILOG_ERROR("pid write failed.");
return INNER_ERR;
}
if (!data.WriteInt32(static_cast<int32_t>(exitReason))) {
HILOG_ERROR("Reason write failed.");
return INNER_ERR;
}
PROXY_WRITE_PARCEL_AND_RETURN_IF_FAIL(data, Int32, pid);
PROXY_WRITE_PARCEL_AND_RETURN_IF_FAIL(data, Parcelable, &exitReason);
int32_t error = SendRequest(AbilityManagerInterfaceCode::FORCE_EXIT_APP, data, reply, option);
if (error != NO_ERROR) {
@ -3864,22 +3856,18 @@ int32_t AbilityManagerProxy::ForceExitApp(const int32_t pid, Reason exitReason)
return reply.ReadInt32();
}
int32_t AbilityManagerProxy::RecordAppExitReason(Reason exitReason)
int32_t AbilityManagerProxy::RecordAppExitReason(const ExitReason &exitReason)
{
HILOG_DEBUG("start.");
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_ASYNC);
MessageOption option;
if (!WriteInterfaceToken(data)) {
HILOG_ERROR("write interface token failed.");
return INNER_ERR;
}
if (!data.WriteInt32(static_cast<int32_t>(exitReason))) {
HILOG_ERROR("Reason write failed.");
return INNER_ERR;
}
PROXY_WRITE_PARCEL_AND_RETURN_IF_FAIL(data, Parcelable, &exitReason);
int32_t error = SendRequest(AbilityManagerInterfaceCode::RECORD_APP_EXIT_REASON, data, reply, option);
if (error != NO_ERROR) {
@ -3891,6 +3879,30 @@ int32_t AbilityManagerProxy::RecordAppExitReason(Reason exitReason)
return reply.ReadInt32();
}
int32_t AbilityManagerProxy::RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason)
{
HILOG_DEBUG("start.");
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!WriteInterfaceToken(data)) {
HILOG_ERROR("write interface token failed.");
return INNER_ERR;
}
PROXY_WRITE_PARCEL_AND_RETURN_IF_FAIL(data, Int32, pid);
PROXY_WRITE_PARCEL_AND_RETURN_IF_FAIL(data, Parcelable, &exitReason);
int32_t error = SendRequest(AbilityManagerInterfaceCode::RECORD_PROCESS_EXIT_REASON, data, reply, option);
if (error != NO_ERROR) {
HILOG_ERROR("fail to SendRequest, err: %{public}d.", error);
return error;
}
HILOG_DEBUG("end.");
return reply.ReadInt32();
}
void AbilityManagerProxy::SetRootSceneSession(const sptr<IRemoteObject> &rootSceneSession)
{
MessageParcel data;

View File

@ -34,6 +34,7 @@
#include "ability_debug_deal.h"
#include "ability_info.h"
#include "ability_interceptor.h"
#include "ability_manager_constants.h"
#include "ability_manager_errors.h"
#include "ability_util.h"
#include "accesstoken_kit.h"
@ -393,6 +394,8 @@ bool AbilityManagerService::Init()
InitPushTask();
SubscribeScreenUnlockedEvent();
appExitReasonHelper_ = std::make_shared<AppExitReasonHelper>(uiAbilityLifecycleManager_, missionListManagers_,
managersMutex_);
HILOG_INFO("Init success.");
return true;
}
@ -1749,8 +1752,6 @@ void AbilityManagerService::AppUpgradeCompleted(const std::string &bundleName, i
return;
}
RecordAppExitReasonAtUpgrade(bundleInfo);
if (userId != U0_USER_ID) {
HILOG_ERROR("Application upgrade for non U0 users.");
return;
@ -1769,41 +1770,34 @@ void AbilityManagerService::AppUpgradeCompleted(const std::string &bundleName, i
}
}
int32_t AbilityManagerService::RecordAppExitReason(Reason exitReason)
int32_t AbilityManagerService::RecordAppExitReason(const ExitReason &exitReason)
{
if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled() && !currentMissionListManager_) {
HILOG_ERROR("currentMissionListManager_ is null.");
return ERR_NULL_OBJECT;
}
auto bms = GetBundleManager();
CHECK_POINTER_AND_RETURN(bms, ERR_NULL_OBJECT);
std::string bundleName;
int32_t callerUid = IPCSkeleton::GetCallingUid();
if (IN_PROCESS_CALL(bms->GetNameForUid(callerUid, bundleName)) != ERR_OK) {
HILOG_ERROR("Get Bundle Name failed.");
return ERR_INVALID_VALUE;
}
std::vector<std::string> abilityList;
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
uiAbilityLifecycleManager_->GetActiveAbilityList(bundleName, abilityList);
} else {
currentMissionListManager_->GetActiveAbilityList(bundleName, abilityList);
}
return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(
bundleName, abilityList, exitReason);
HILOG_INFO("RecordAppExitReason reason:%{public}d, exitMsg: %{public}s", exitReason.reason,
exitReason.exitMsg.c_str());
CHECK_POINTER_AND_RETURN(appExitReasonHelper_, ERR_NULL_OBJECT);
return appExitReasonHelper_->RecordAppExitReason(exitReason);
}
int32_t AbilityManagerService::ForceExitApp(const int32_t pid, Reason exitReason)
int32_t AbilityManagerService::RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason)
{
if (exitReason < REASON_UNKNOWN || exitReason > REASON_UPGRADE) {
HILOG_ERROR("Force exit reason invalid.");
return ERR_INVALID_VALUE;
HILOG_INFO("RecordProcessExitReason pid:%{public}d, reason:%{public}d, exitMsg: %{public}s",
pid, exitReason.reason, exitReason.exitMsg.c_str());
if (!AAFwk::PermissionVerification::GetInstance()->IsSACall()) {
HILOG_ERROR("Not sa call");
return ERR_PERMISSION_DENIED;
}
CHECK_POINTER_AND_RETURN(appExitReasonHelper_, ERR_NULL_OBJECT);
return appExitReasonHelper_->RecordProcessExitReason(pid, exitReason);
}
int32_t AbilityManagerService::ForceExitApp(const int32_t pid, const ExitReason &exitReason)
{
HILOG_INFO("ForceExitApp pid:%{public}d, reason:%{public}d, exitMsg: %{public}s",
pid, exitReason.reason, exitReason.exitMsg.c_str());
if (!AAFwk::PermissionVerification::GetInstance()->IsSACall() &&
!AAFwk::PermissionVerification::GetInstance()->IsShellCall()) {
HILOG_ERROR("Not sa or shell call");
@ -1818,34 +1812,10 @@ int32_t AbilityManagerService::ForceExitApp(const int32_t pid, Reason exitReason
return ERR_INVALID_VALUE;
}
int32_t targetUserId = uid / BASE_USER_RANGE;
std::vector<std::string> abilityLists;
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
uiAbilityLifecycleManager_->GetActiveAbilityList(bundleName, abilityLists, targetUserId);
} else if (targetUserId == U0_USER_ID) {
std::lock_guard lock(managersMutex_);
for (auto item: missionListManagers_) {
if (item.second) {
std::vector<std::string> abilityList;
item.second->GetActiveAbilityList(bundleName, abilityList);
if (!abilityList.empty()) {
abilityLists.insert(abilityLists.end(), abilityList.begin(), abilityList.end());
}
}
}
} else {
auto listManager = GetListManagerByUserId(targetUserId);
if (listManager) {
listManager->GetActiveAbilityList(bundleName, abilityLists);
}
}
CHECK_POINTER_AND_RETURN(appExitReasonHelper_, ERR_NULL_OBJECT);
appExitReasonHelper_->RecordProcessExitReason(NO_PID, exitReason, bundleName, uid);
int32_t result = DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(
bundleName, abilityLists, exitReason);
DelayedSingleton<AppScheduler>::GetInstance()->KillApplication(bundleName);
return result;
return DelayedSingleton<AppScheduler>::GetInstance()->KillApplication(bundleName);
}
int32_t AbilityManagerService::GetConfiguration(AppExecFwk::Configuration& config)
@ -5012,6 +4982,9 @@ void AbilityManagerService::InitMissionListManager(int userId, bool switchUser)
if (switchUser) {
DelayedSingleton<MissionInfoMgr>::GetInstance()->Init(userId);
currentMissionListManager_ = iterator->second;
if (appExitReasonHelper_) {
appExitReasonHelper_->SetCurrentMissionListManager(currentMissionListManager_);
}
}
}
}
@ -5022,6 +4995,9 @@ void AbilityManagerService::InitMissionListManager(int userId, bool switchUser)
missionListManagers_.emplace(userId, manager);
if (switchUser) {
currentMissionListManager_ = manager;
if (appExitReasonHelper_) {
appExitReasonHelper_->SetCurrentMissionListManager(currentMissionListManager_);
}
}
}
}
@ -6541,10 +6517,6 @@ void AbilityManagerService::ScheduleRecoverAbility(const sptr<IRemoteObject>& to
return;
}
if (reason == AppExecFwk::StateReason::APP_FREEZE) {
RecordAppExitReason(REASON_APP_FREEZE);
}
AAFwk::Want curWant;
{
std::lock_guard<ffrt::mutex> guard(globalLock_);
@ -8618,26 +8590,6 @@ int32_t AbilityManagerService::NotifySaveAsResult(const Want &want, int resultCo
return ERR_OK;
}
void AbilityManagerService::RecordAppExitReasonAtUpgrade(const AppExecFwk::BundleInfo &bundleInfo)
{
if (bundleInfo.abilityInfos.empty()) {
HILOG_ERROR("abilityInfos is empty.");
return;
}
std::vector<std::string> abilityList;
for (auto abilityInfo : bundleInfo.abilityInfos) {
if (!abilityInfo.name.empty()) {
abilityList.push_back(abilityInfo.name);
}
}
if (!abilityList.empty()) {
DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(
bundleInfo.name, abilityList, REASON_UPGRADE);
}
}
void AbilityManagerService::SetRootSceneSession(const sptr<IRemoteObject> &rootSceneSession)
{
if (!CheckCallingTokenId(BUNDLE_NAME_SCENEBOARD)) {

View File

@ -261,6 +261,8 @@ void AbilityManagerStub::SecondStepInit()
&AbilityManagerStub::ForceExitAppInner;
requestFuncMap_[static_cast<uint32_t>(AbilityManagerInterfaceCode::RECORD_APP_EXIT_REASON)] =
&AbilityManagerStub::RecordAppExitReasonInner;
requestFuncMap_[static_cast<uint32_t>(AbilityManagerInterfaceCode::RECORD_PROCESS_EXIT_REASON)] =
&AbilityManagerStub::RecordProcessExitReasonInner;
requestFuncMap_[static_cast<uint32_t>(AbilityManagerInterfaceCode::REGISTER_SESSION_HANDLER)] =
&AbilityManagerStub::RegisterSessionHandlerInner;
#ifdef ABILITY_COMMAND_FOR_TEST
@ -2512,8 +2514,12 @@ int AbilityManagerStub::VerifyPermissionInner(MessageParcel &data, MessageParcel
int32_t AbilityManagerStub::ForceExitAppInner(MessageParcel &data, MessageParcel &reply)
{
int32_t pid = data.ReadInt32();
Reason reason = static_cast<Reason>(data.ReadInt32());
int32_t result = ForceExitApp(pid, reason);
std::unique_ptr<ExitReason> exitReason(data.ReadParcelable<ExitReason>());
if (!exitReason) {
HILOG_ERROR("exitReason is nullptr.");
return ERR_INVALID_VALUE;
}
int32_t result = ForceExitApp(pid, *exitReason);
if (!reply.WriteInt32(result)) {
HILOG_ERROR("write result failed.");
return ERR_INVALID_VALUE;
@ -2523,8 +2529,28 @@ int32_t AbilityManagerStub::ForceExitAppInner(MessageParcel &data, MessageParcel
int32_t AbilityManagerStub::RecordAppExitReasonInner(MessageParcel &data, MessageParcel &reply)
{
Reason reason = static_cast<Reason>(data.ReadInt32());
int32_t result = RecordAppExitReason(reason);
std::unique_ptr<ExitReason> exitReason(data.ReadParcelable<ExitReason>());
if (!exitReason) {
HILOG_ERROR("exitReason is nullptr.");
return ERR_INVALID_VALUE;
}
int32_t result = RecordAppExitReason(*exitReason);
if (!reply.WriteInt32(result)) {
HILOG_ERROR("write result failed.");
return ERR_INVALID_VALUE;
}
return NO_ERROR;
}
int32_t AbilityManagerStub::RecordProcessExitReasonInner(MessageParcel &data, MessageParcel &reply)
{
int32_t pid = data.ReadInt32();
std::unique_ptr<ExitReason> exitReason(data.ReadParcelable<ExitReason>());
if (!exitReason) {
HILOG_ERROR("exitReason is nullptr.");
return ERR_INVALID_VALUE;
}
int32_t result = RecordProcessExitReason(pid, *exitReason);
if (!reply.WriteInt32(result)) {
HILOG_ERROR("write result failed.");
return ERR_INVALID_VALUE;

View File

@ -2496,9 +2496,33 @@ void AbilityRecord::SetLaunchReason(const LaunchReason &reason)
lifeCycleStateInfo_.launchParam.launchReason = reason;
}
void AbilityRecord::SetLastExitReason(const LastExitReason &reason)
void AbilityRecord::SetLastExitReason(const ExitReason &exitReason)
{
lifeCycleStateInfo_.launchParam.lastExitReason = reason;
lifeCycleStateInfo_.launchParam.lastExitReason = CovertAppExitReasonToLastReason(exitReason.reason);
lifeCycleStateInfo_.launchParam.lastExitMessage = exitReason.exitMsg;
}
LastExitReason AbilityRecord::CovertAppExitReasonToLastReason(const Reason exitReason)
{
switch (exitReason) {
case REASON_NORMAL:
return LASTEXITREASON_NORMAL;
case REASON_CPP_CRASH:
return LASTEXITREASON_CPP_CRASH;
case REASON_JS_ERROR:
return LASTEXITREASON_JS_ERROR;
case REASON_APP_FREEZE:
return LASTEXITREASON_APP_FREEZE;
case REASON_PERFORMANCE_CONTROL:
return LASTEXITREASON_PERFORMANCE_CONTROL;
case REASON_RESOURCE_CONTROL:
return LASTEXITREASON_RESOURCE_CONTROL;
case REASON_UPGRADE:
return LASTEXITREASON_UPGRADE;
case REASON_UNKNOWN:
default:
return LASTEXITREASON_UNKNOWN;
}
}
void AbilityRecord::NotifyContinuationResult(int32_t result)

View File

@ -30,6 +30,7 @@ constexpr int32_t CHECK_INTERVAL = 100000; // 100ms
constexpr int32_t MAX_TIMES = 5; // 5 * 100ms = 500ms
constexpr const char *APP_EXIT_REASON_STORAGE_DIR = "/data/service/el1/public/database/app_exit_reason";
const std::string JSON_KEY_REASON = "reason";
const std::string JSON_KEY_EXIT_MSG = "exit_msg";
const std::string JSON_KEY_TIME_STAMP = "time_stamp";
const std::string JSON_KEY_ABILITY_LIST = "ability_list";
const std::string KEY_RECOVER_INFO_PREFIX = "recover_info";
@ -84,8 +85,8 @@ bool AppExitReasonDataManager::CheckKvStore()
return kvStorePtr_ != nullptr;
}
int32_t AppExitReasonDataManager::SetAppExitReason(
const std::string &bundleName, const std::vector<std::string> &abilityList, const AAFwk::Reason &reason)
int32_t AppExitReasonDataManager::SetAppExitReason(const std::string &bundleName,
const std::vector<std::string> &abilityList, const AAFwk::ExitReason &exitReason)
{
if (bundleName.empty()) {
HILOG_WARN("invalid value");
@ -102,7 +103,7 @@ int32_t AppExitReasonDataManager::SetAppExitReason(
}
DistributedKv::Key key(bundleName);
DistributedKv::Value value = ConvertAppExitReasonInfoToValue(abilityList, reason);
DistributedKv::Value value = ConvertAppExitReasonInfoToValue(abilityList, exitReason);
DistributedKv::Status status;
{
std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
@ -146,8 +147,8 @@ int32_t AppExitReasonDataManager::DeleteAppExitReason(const std::string &bundleN
return ERR_OK;
}
int32_t AppExitReasonDataManager::GetAppExitReason(
const std::string &bundleName, const std::string &abilityName, bool &isSetReason, AAFwk::Reason &reason)
int32_t AppExitReasonDataManager::GetAppExitReason(const std::string &bundleName, const std::string &abilityName,
bool &isSetReason, AAFwk::ExitReason &exitReason)
{
if (bundleName.empty()) {
HILOG_WARN("invalid value!");
@ -175,16 +176,17 @@ int32_t AppExitReasonDataManager::GetAppExitReason(
isSetReason = false;
for (const auto &item : allEntries) {
if (item.key.ToString() == bundleName) {
ConvertAppExitReasonInfoFromValue(item.value, reason, time_stamp, abilityList);
ConvertAppExitReasonInfoFromValue(item.value, exitReason, time_stamp, abilityList);
auto pos = std::find(abilityList.begin(), abilityList.end(), abilityName);
if (pos != abilityList.end()) {
isSetReason = true;
abilityList.erase(std::remove(abilityList.begin(), abilityList.end(), abilityName), abilityList.end());
UpdateAppExitReason(bundleName, abilityList, reason);
UpdateAppExitReason(bundleName, abilityList, exitReason);
}
HILOG_INFO(
"current bundle name: %{public}s reason: %{public}d abilityName:%{public}s isSetReason:%{public}d",
item.key.ToString().c_str(), reason, abilityName.c_str(), isSetReason);
HILOG_INFO("current bundle name: %{public}s reason: %{public}d exitMsg: %{public}s \
abilityName:%{public}s isSetReason:%{public}d",
item.key.ToString().c_str(), exitReason.reason, exitReason.exitMsg.c_str(), abilityName.c_str(),
isSetReason);
if (abilityList.empty()) {
InnerDeleteAppExitReason(bundleName);
}
@ -195,8 +197,8 @@ int32_t AppExitReasonDataManager::GetAppExitReason(
return ERR_OK;
}
void AppExitReasonDataManager::UpdateAppExitReason(
const std::string &bundleName, const std::vector<std::string> &abilityList, const AAFwk::Reason &reason)
void AppExitReasonDataManager::UpdateAppExitReason(const std::string &bundleName,
const std::vector<std::string> &abilityList, const AAFwk::ExitReason &exitReason)
{
if (kvStorePtr_ == nullptr) {
HILOG_ERROR("kvStore is nullptr.");
@ -214,7 +216,7 @@ void AppExitReasonDataManager::UpdateAppExitReason(
return;
}
DistributedKv::Value value = ConvertAppExitReasonInfoToValue(abilityList, reason);
DistributedKv::Value value = ConvertAppExitReasonInfoToValue(abilityList, exitReason);
{
std::lock_guard<std::mutex> lock(kvStorePtrMutex_);
status = kvStorePtr_->Put(key, value);
@ -225,12 +227,13 @@ void AppExitReasonDataManager::UpdateAppExitReason(
}
DistributedKv::Value AppExitReasonDataManager::ConvertAppExitReasonInfoToValue(
const std::vector<std::string> &abilityList, const AAFwk::Reason &reason)
const std::vector<std::string> &abilityList, const AAFwk::ExitReason &exitReason)
{
std::chrono::milliseconds nowMs =
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
nlohmann::json jsonObject = nlohmann::json {
{ JSON_KEY_REASON, reason },
{ JSON_KEY_REASON, exitReason.reason },
{ JSON_KEY_EXIT_MSG, exitReason.exitMsg },
{ JSON_KEY_TIME_STAMP, nowMs.count() },
{ JSON_KEY_ABILITY_LIST, abilityList },
};
@ -240,7 +243,7 @@ DistributedKv::Value AppExitReasonDataManager::ConvertAppExitReasonInfoToValue(
}
void AppExitReasonDataManager::ConvertAppExitReasonInfoFromValue(const DistributedKv::Value &value,
AAFwk::Reason &reason, int64_t &time_stamp, std::vector<std::string> &abilityList)
AAFwk::ExitReason &exitReason, int64_t &time_stamp, std::vector<std::string> &abilityList)
{
nlohmann::json jsonObject = nlohmann::json::parse(value.ToString(), nullptr, false);
if (jsonObject.is_discarded()) {
@ -248,7 +251,10 @@ void AppExitReasonDataManager::ConvertAppExitReasonInfoFromValue(const Distribut
return;
}
if (jsonObject.contains(JSON_KEY_REASON) && jsonObject[JSON_KEY_REASON].is_number_integer()) {
reason = jsonObject.at(JSON_KEY_REASON).get<AAFwk::Reason>();
exitReason.reason = jsonObject.at(JSON_KEY_REASON).get<AAFwk::Reason>();
}
if (jsonObject.contains(JSON_KEY_EXIT_MSG) && jsonObject[JSON_KEY_EXIT_MSG].is_string()) {
exitReason.exitMsg = jsonObject.at(JSON_KEY_EXIT_MSG).get<std::string>();
}
if (jsonObject.contains(JSON_KEY_TIME_STAMP) && jsonObject[JSON_KEY_TIME_STAMP].is_number_integer()) {
time_stamp = jsonObject.at(JSON_KEY_TIME_STAMP).get<int64_t>();

View File

@ -0,0 +1,165 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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 "app_exit_reason_helper.h"
#include <string>
#include <vector>
#include "ability_util.h"
#include "ability_manager_errors.h"
#include "app_exit_reason_data_manager.h"
#include "app_scheduler.h"
#include "bundle_constants.h"
#include "bundle_mgr_interface.h"
#include "hilog_wrapper.h"
#include "ipc_skeleton.h"
#include "scene_board_judgement.h"
#include "singleton.h"
namespace OHOS {
namespace AAFwk {
namespace {
constexpr int32_t U0_USER_ID = 0;
}
AppExitReasonHelper::AppExitReasonHelper(
std::shared_ptr<UIAbilityLifecycleManager> &uiAbilityLifecycleManager,
std::unordered_map<int, std::shared_ptr<MissionListManager>> &missionListManagers,
ffrt::mutex &managersMutex) : uiAbilityLifecycleManager_(uiAbilityLifecycleManager),
missionListManagers_(missionListManagers),
managersMutex_(managersMutex) {}
void AppExitReasonHelper::SetCurrentMissionListManager(
const std::shared_ptr<MissionListManager> currentMissionListManager)
{
currentMissionListManager_ = currentMissionListManager;
}
int32_t AppExitReasonHelper::RecordAppExitReason(const ExitReason &exitReason)
{
if (!IsExitReasonValid(exitReason)) {
HILOG_ERROR("Force exit reason invalid.");
return ERR_INVALID_VALUE;
}
auto bms = AbilityUtil::GetBundleManagerHelper();
CHECK_POINTER_AND_RETURN(bms, ERR_NULL_OBJECT);
std::string bundleName;
int32_t callerUid = IPCSkeleton::GetCallingUid();
if (IN_PROCESS_CALL(bms->GetNameForUid(callerUid, bundleName)) != ERR_OK) {
HILOG_ERROR("Get Bundle Name failed.");
return GET_BUNDLE_INFO_FAILED;
}
std::vector<std::string> abilityList;
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
CHECK_POINTER_AND_RETURN(uiAbilityLifecycleManager_, ERR_NULL_OBJECT);
uiAbilityLifecycleManager_->GetActiveAbilityList(bundleName, abilityList);
} else {
CHECK_POINTER_AND_RETURN(currentMissionListManager_, ERR_NULL_OBJECT);
currentMissionListManager_->GetActiveAbilityList(bundleName, abilityList);
}
if (abilityList.empty()) {
HILOG_ERROR("Active abilityLists empty.");
return ERR_GET_ACTIVE_ABILITY_LIST_EMPTY;
}
return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(
bundleName, abilityList, exitReason);
}
int32_t AppExitReasonHelper::RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason)
{
std::string bundleName;
int32_t uid;
DelayedSingleton<AppScheduler>::GetInstance()->GetBundleNameByPid(pid, bundleName, uid);
if (bundleName.empty()) {
HILOG_ERROR("Get bundle name by pid failed.");
return GET_BUNDLE_INFO_FAILED;
}
return RecordProcessExitReason(pid, exitReason, bundleName, uid);
}
int32_t AppExitReasonHelper::RecordProcessExitReason(const int32_t pid, const ExitReason &exitReason,
const std::string bundleName, const int32_t uid)
{
if (!IsExitReasonValid(exitReason)) {
HILOG_ERROR("Force exit reason invalid.");
return ERR_INVALID_VALUE;
}
int32_t targetUserId = uid / AppExecFwk::Constants::BASE_USER_RANGE;
std::vector<std::string> abilityLists;
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
CHECK_POINTER_AND_RETURN(uiAbilityLifecycleManager_, ERR_NULL_OBJECT);
uiAbilityLifecycleManager_->GetActiveAbilityList(bundleName, abilityLists, targetUserId, pid);
} else if (targetUserId == U0_USER_ID) {
GetActiveAbilityListByU0(bundleName, abilityLists, pid);
} else {
GetActiveAbilityListByUser(bundleName, abilityLists, targetUserId, pid);
}
if (abilityLists.empty()) {
HILOG_ERROR("Active abilityLists empty.");
return ERR_GET_ACTIVE_ABILITY_LIST_EMPTY;
}
return DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->SetAppExitReason(
bundleName, abilityLists, exitReason);
}
void AppExitReasonHelper::GetActiveAbilityListByU0(const std::string bundleName,
std::vector<std::string> &abilityLists, const int32_t pid)
{
std::lock_guard lock(managersMutex_);
for (auto item: missionListManagers_) {
if (!item.second) {
continue;
}
std::vector<std::string> abilityList;
item.second->GetActiveAbilityList(bundleName, abilityList, pid);
if (!abilityList.empty()) {
abilityLists.insert(abilityLists.end(), abilityList.begin(), abilityList.end());
}
}
}
void AppExitReasonHelper::GetActiveAbilityListByUser(const std::string bundleName,
std::vector<std::string> &abilityLists, const int32_t targetUserId, const int32_t pid)
{
auto listManager = GetListManagerByUserId(targetUserId);
if (listManager) {
listManager->GetActiveAbilityList(bundleName, abilityLists, pid);
}
}
std::shared_ptr<MissionListManager> AppExitReasonHelper::GetListManagerByUserId(int32_t userId)
{
std::lock_guard<ffrt::mutex> lock(managersMutex_);
auto it = missionListManagers_.find(userId);
if (it != missionListManagers_.end()) {
return it->second;
}
HILOG_ERROR("Failed to get MissionListManager. UserId = %{public}d", userId);
return nullptr;
}
bool AppExitReasonHelper::IsExitReasonValid(const ExitReason &exitReason)
{
const Reason reason = exitReason.reason;
return reason >= REASON_MIN || reason <= REASON_MAX;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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 "exit_reason.h"
#include "hilog_wrapper.h"
#include "nlohmann/json.hpp"
#include "parcel_macro_base.h"
#include "string_ex.h"
namespace OHOS {
namespace AAFwk {
ExitReason::ExitReason(const Reason reason, const std::string &exitMsg)
{
this->reason = reason;
this->exitMsg = exitMsg;
}
bool ExitReason::ReadFromParcel(Parcel &parcel)
{
int32_t reasonData;
READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, reasonData);
reason = static_cast<Reason>(reasonData);
exitMsg = Str16ToStr8(parcel.ReadString16());
return true;
}
ExitReason *ExitReason::Unmarshalling(Parcel &parcel)
{
ExitReason *data = new (std::nothrow) ExitReason();
if (!data) {
HILOG_ERROR("data is nullptr.");
return nullptr;
}
if (!data->ReadFromParcel(parcel)) {
HILOG_ERROR("read from parcel failed");
delete data;
data = nullptr;
}
return data;
}
bool ExitReason::Marshalling(Parcel &parcel) const
{
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast<int32_t>(reason));
WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(exitMsg));
return true;
}
} // namespace AppExecFwk
} // namespace OHOS

View File

@ -15,6 +15,9 @@
#include "launch_param.h"
#include "hilog_wrapper.h"
#include "string_ex.h"
namespace OHOS {
namespace AAFwk {
bool LaunchParam::ReadFromParcel(Parcel &parcel)
@ -29,6 +32,8 @@ bool LaunchParam::ReadFromParcel(Parcel &parcel)
return false;
}
lastExitReason = static_cast<LastExitReason>(reason);
lastExitMessage = Str16ToStr8(parcel.ReadString16());
return true;
}
@ -56,6 +61,10 @@ bool LaunchParam::Marshalling(Parcel &parcel) const
if (!parcel.WriteInt32(static_cast<int32_t>(lastExitReason))) {
return false;
}
if (!parcel.WriteString16(Str8ToStr16(lastExitMessage))) {
HILOG_ERROR("Write parcel lastExitMessage failed.");
return false;
}
return true;
}
} // namespace AAFwk

View File

@ -462,7 +462,8 @@ int32_t MissionList::GetMissionCount() const
return static_cast<int32_t>(missions_.size());
}
void MissionList::GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList)
void MissionList::GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList,
int32_t pid)
{
for (auto mission : missions_) {
if (!mission) {
@ -473,6 +474,10 @@ void MissionList::GetActiveAbilityList(const std::string &bundleName, std::vecto
if (!abilityRecord) {
continue;
}
if (pid != NO_PID && abilityRecord->GetPid() != pid) {
continue;
}
const AppExecFwk::AbilityInfo &abilityInfo = abilityRecord->GetAbilityInfo();
if (abilityInfo.bundleName == bundleName && !abilityInfo.name.empty()) {

View File

@ -3420,8 +3420,9 @@ bool MissionListManager::CheckLimit()
return true;
}
if (IsAppLastAbility(earliestMission->GetAbilityRecord())) {
OHOS::DelayedSingleton<AbilityManagerService>::GetInstance()->RecordAppExitReason(
REASON_RESOURCE_CONTROL);
ExitReason exitReason = { REASON_RESOURCE_CONTROL,
"Already reach ability max limit, terminate earliest ability." };
OHOS::DelayedSingleton<AbilityManagerService>::GetInstance()->RecordAppExitReason(exitReason);
}
HILOG_INFO("already reach limit instance. limit: %{public}d, and terminate earliestAbility success.",
MAX_INSTANCE_COUNT);
@ -3847,13 +3848,14 @@ int MissionListManager::DoAbilityForeground(std::shared_ptr<AbilityRecord> &abil
return ERR_OK;
}
void MissionListManager::GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList)
void MissionListManager::GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList,
int32_t pid)
{
std::lock_guard guard(managerLock_);
for (auto missionList : currentMissionLists_) {
if (missionList != nullptr) {
std::vector<std::string> currentActiveAbilities;
missionList->GetActiveAbilityList(bundleName, currentActiveAbilities);
missionList->GetActiveAbilityList(bundleName, currentActiveAbilities, pid);
if (!currentActiveAbilities.empty()) {
abilityList.insert(abilityList.end(), currentActiveAbilities.begin(), currentActiveAbilities.end());
}
@ -3862,7 +3864,7 @@ void MissionListManager::GetActiveAbilityList(const std::string &bundleName, std
if (defaultStandardList_ != nullptr) {
std::vector<std::string> defaultActiveStandardList;
defaultStandardList_->GetActiveAbilityList(bundleName, defaultActiveStandardList);
defaultStandardList_->GetActiveAbilityList(bundleName, defaultActiveStandardList, pid);
if (!defaultActiveStandardList.empty()) {
abilityList.insert(abilityList.end(), defaultActiveStandardList.begin(), defaultActiveStandardList.end());
}
@ -3870,7 +3872,7 @@ void MissionListManager::GetActiveAbilityList(const std::string &bundleName, std
if (defaultSingleList_ != nullptr) {
std::vector<std::string> defaultActiveSingleList;
defaultSingleList_->GetActiveAbilityList(bundleName, defaultActiveSingleList);
defaultSingleList_->GetActiveAbilityList(bundleName, defaultActiveSingleList, pid);
if (!defaultActiveSingleList.empty()) {
abilityList.insert(abilityList.end(), defaultActiveSingleList.begin(), defaultActiveSingleList.end());
}
@ -3894,36 +3896,13 @@ void MissionListManager::SetLastExitReason(std::shared_ptr<AbilityRecord> &abili
return;
}
Reason exitReason;
ExitReason exitReason;
bool isSetReason;
DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->GetAppExitReason(
abilityRecord->GetAbilityInfo().bundleName, abilityRecord->GetAbilityInfo().name, isSetReason, exitReason);
if (isSetReason) {
abilityRecord->SetLastExitReason(CovertAppExitReasonToLastReason(exitReason));
}
}
LastExitReason MissionListManager::CovertAppExitReasonToLastReason(const Reason exitReason)
{
switch (exitReason) {
case REASON_NORMAL:
return LASTEXITREASON_NORMAL;
case REASON_CPP_CRASH:
return LASTEXITREASON_CPP_CRASH;
case REASON_JS_ERROR:
return LASTEXITREASON_JS_ERROR;
case REASON_APP_FREEZE:
return LASTEXITREASON_APP_FREEZE;
case REASON_PERFORMANCE_CONTROL:
return LASTEXITREASON_PERFORMANCE_CONTROL;
case REASON_RESOURCE_CONTROL:
return LASTEXITREASON_RESOURCE_CONTROL;
case REASON_UPGRADE:
return LASTEXITREASON_UPGRADE;
case REASON_UNKNOWN:
default:
return LASTEXITREASON_UNKNOWN;
abilityRecord->SetLastExitReason(exitReason);
}
}

View File

@ -21,6 +21,7 @@
#include "appfreeze_manager.h"
#include "app_exit_reason_data_manager.h"
#include "errors.h"
#include "exit_reason.h"
#include "hilog_wrapper.h"
#include "hitrace_meter.h"
#include "iability_info_callback.h"
@ -1612,14 +1613,18 @@ int32_t UIAbilityLifecycleManager::GetSessionIdByAbilityToken(const sptr<IRemote
}
void UIAbilityLifecycleManager::GetActiveAbilityList(const std::string &bundleName,
std::vector<std::string> &abilityList)
std::vector<std::string> &abilityList, int32_t pid)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
auto currentAccountId = DelayedSingleton<AbilityManagerService>::GetInstance()->GetUserId();
std::lock_guard<ffrt::mutex> guard(sessionLock_);
for (const auto& [first, second] : sessionAbilityMap_) {
if (second->GetOwnerMissionUserId() == currentAccountId) {
const auto &abilityInfo = second->GetAbilityInfo();
for (const auto& [sessionId, abilityRecord] : sessionAbilityMap_) {
CHECK_POINTER_CONTINUE(abilityRecord);
if (!CheckPid(abilityRecord, pid)) {
continue;
}
if (abilityRecord->GetOwnerMissionUserId() == currentAccountId) {
const auto &abilityInfo = abilityRecord->GetAbilityInfo();
if (abilityInfo.bundleName == bundleName && !abilityInfo.name.empty()) {
HILOG_DEBUG("find ability name is %{public}s", abilityInfo.name.c_str());
abilityList.push_back(abilityInfo.name);
@ -1655,36 +1660,13 @@ void UIAbilityLifecycleManager::SetLastExitReason(std::shared_ptr<AbilityRecord>
return;
}
Reason exitReason;
ExitReason exitReason;
bool isSetReason;
DelayedSingleton<AbilityRuntime::AppExitReasonDataManager>::GetInstance()->GetAppExitReason(
abilityRecord->GetAbilityInfo().bundleName, abilityRecord->GetAbilityInfo().name, isSetReason, exitReason);
if (isSetReason) {
abilityRecord->SetLastExitReason(CovertAppExitReasonToLastReason(exitReason));
}
}
LastExitReason UIAbilityLifecycleManager::CovertAppExitReasonToLastReason(const Reason exitReason) const
{
switch (exitReason) {
case REASON_NORMAL:
return LASTEXITREASON_NORMAL;
case REASON_CPP_CRASH:
return LASTEXITREASON_CPP_CRASH;
case REASON_JS_ERROR:
return LASTEXITREASON_JS_ERROR;
case REASON_APP_FREEZE:
return LASTEXITREASON_APP_FREEZE;
case REASON_PERFORMANCE_CONTROL:
return LASTEXITREASON_PERFORMANCE_CONTROL;
case REASON_RESOURCE_CONTROL:
return LASTEXITREASON_RESOURCE_CONTROL;
case REASON_UPGRADE:
return LASTEXITREASON_UPGRADE;
case REASON_UNKNOWN:
default:
return LASTEXITREASON_UNKNOWN;
abilityRecord->SetLastExitReason(exitReason);
}
}
@ -1762,7 +1744,7 @@ std::shared_ptr<AbilityRecord> UIAbilityLifecycleManager::GetAbilityRecordsById(
}
void UIAbilityLifecycleManager::GetActiveAbilityList(const std::string &bundleName,
std::vector<std::string> &abilityList, int32_t targetUserId) const
std::vector<std::string> &abilityList, int32_t targetUserId, int32_t pid) const
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
std::lock_guard<ffrt::mutex> guard(sessionLock_);
@ -1772,6 +1754,9 @@ void UIAbilityLifecycleManager::GetActiveAbilityList(const std::string &bundleNa
HILOG_WARN("second is nullptr.");
continue;
}
if (!CheckPid(abilityRecord, pid)) {
continue;
}
const auto &abilityInfo = abilityRecord->GetAbilityInfo();
if (abilityInfo.bundleName == bundleName && !abilityInfo.name.empty() &&
(targetUserId == DEFAULT_USER_ID || abilityRecord->GetOwnerMissionUserId() == targetUserId)) {
@ -1785,6 +1770,12 @@ void UIAbilityLifecycleManager::GetActiveAbilityList(const std::string &bundleNa
}
}
bool UIAbilityLifecycleManager::CheckPid(const std::shared_ptr<AbilityRecord> abilityRecord, const int32_t pid) const
{
CHECK_POINTER_RETURN_BOOL(abilityRecord);
return pid == NO_PID || abilityRecord->GetPid() == pid;
}
void UIAbilityLifecycleManager::OnAppStateChanged(const AppInfo &info, int32_t targetUserId)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);

View File

@ -34,6 +34,7 @@ ohos_moduletest("ability_manager_client_test") {
"ability_runtime:app_manager",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"c_utils:utils",
"eventhandler:libeventhandler",
"hilog:libhilog",
"ipc:ipc_core",

View File

@ -16,6 +16,7 @@
#include <gtest/gtest.h>
#include "ability_manager_client.h"
#include "ability_manager_errors.h"
#include "hilog_wrapper.h"
using namespace testing;
@ -83,7 +84,7 @@ HWTEST_F(AbilityManagerClientTest, AbilityManagerClient_ForceExitApp_0100, TestS
{
HILOG_INFO("AbilityManagerClient_ForceExitApp_0100 start");
int32_t pid = 0;
Reason exitReason = REASON_JS_ERROR;
ExitReason exitReason = { REASON_JS_ERROR, "Js Error." };
auto result = AbilityManagerClient::GetInstance()->ForceExitApp(pid, exitReason);
EXPECT_EQ(result, ERR_OK);
HILOG_INFO("AbilityManagerClient_ForceExitApp_0100 end");
@ -97,10 +98,24 @@ HWTEST_F(AbilityManagerClientTest, AbilityManagerClient_ForceExitApp_0100, TestS
HWTEST_F(AbilityManagerClientTest, AbilityManagerClient_RecordAppExitReason_0100, TestSize.Level1)
{
HILOG_INFO("AbilityManagerClient_RecordAppExitReason_0100 start");
Reason exitReason = REASON_JS_ERROR;
ExitReason exitReason = { REASON_JS_ERROR, "Js Error." };
auto result = AbilityManagerClient::GetInstance()->RecordAppExitReason(exitReason);
EXPECT_EQ(result, ERR_OK);
EXPECT_EQ(result, GET_BUNDLE_INFO_FAILED);
HILOG_INFO("AbilityManagerClient_RecordAppExitReason_0100 end");
}
/**
* @tc.name: AbilityManagerClient_RecordProcessExitReason_0100
* @tc.desc: RecordAppExitReason
* @tc.type: FUNC
*/
HWTEST_F(AbilityManagerClientTest, AbilityManagerClient_RecordProcessExitReason_0100, TestSize.Level1)
{
HILOG_INFO("AbilityManagerClient_RecordProcessExitReason_0100 start");
ExitReason exitReason = { REASON_JS_ERROR, "Js Error." };
auto result = AbilityManagerClient::GetInstance()->RecordAppExitReason(exitReason);
EXPECT_EQ(result, GET_BUNDLE_INFO_FAILED);
HILOG_INFO("AbilityManagerClient_RecordProcessExitReason_0100 end");
}
} // namespace AAFwk
} // namespace OHOS

View File

@ -123,6 +123,7 @@ ohos_source_set("abilityms_test_source") {
"${ability_runtime_services_path}/abilitymgr/src/ability_token_stub.cpp",
"${ability_runtime_services_path}/abilitymgr/src/ams_configuration_parameter.cpp",
"${ability_runtime_services_path}/abilitymgr/src/app_exit_reason_data_manager.cpp",
"${ability_runtime_services_path}/abilitymgr/src/app_exit_reason_helper.cpp",
"${ability_runtime_services_path}/abilitymgr/src/atomic_service_status_callback.cpp",
"${ability_runtime_services_path}/abilitymgr/src/atomic_service_status_callback_proxy.cpp",
"${ability_runtime_services_path}/abilitymgr/src/atomic_service_status_callback_stub.cpp",
@ -141,6 +142,7 @@ ohos_source_set("abilityms_test_source") {
"${ability_runtime_services_path}/abilitymgr/src/dlp_state_item.cpp",
"${ability_runtime_services_path}/abilitymgr/src/ecological_rule/ability_ecological_rule_mgr_service.cpp",
"${ability_runtime_services_path}/abilitymgr/src/ecological_rule/ability_ecological_rule_mgr_service_param.cpp",
"${ability_runtime_services_path}/abilitymgr/src/exit_reason.cpp",
"${ability_runtime_services_path}/abilitymgr/src/extension_record.cpp",
"${ability_runtime_services_path}/abilitymgr/src/extension_record_manager.cpp",
"${ability_runtime_services_path}/abilitymgr/src/free_install_manager.cpp",

View File

@ -2226,7 +2226,7 @@ HWTEST_F(AbilityManagerProxyTest, AbilityManagerProxy_ForceExitApp_001, TestSize
.Times(1)
.WillOnce(Invoke(mock_.GetRefPtr(), &AbilityManagerStubMock::InvokeSendRequest));
int32_t pid = 0;
Reason exitReason = REASON_JS_ERROR;
ExitReason exitReason = { REASON_JS_ERROR, "Js Error." };
auto res = proxy_->ForceExitApp(pid, exitReason);
EXPECT_EQ(static_cast<uint32_t>(AbilityManagerInterfaceCode::FORCE_EXIT_APP), mock_->code_);
EXPECT_EQ(res, NO_ERROR);
@ -2245,12 +2245,32 @@ HWTEST_F(AbilityManagerProxyTest, AbilityManagerProxy_RecordAppExitReason_001, T
EXPECT_CALL(*mock_, SendRequest(_, _, _, _))
.Times(1)
.WillOnce(Invoke(mock_.GetRefPtr(), &AbilityManagerStubMock::InvokeSendRequest));
Reason exitReason = REASON_JS_ERROR;
ExitReason exitReason = { REASON_JS_ERROR, "Js Error." };
auto res = proxy_->RecordAppExitReason(exitReason);
EXPECT_EQ(static_cast<uint32_t>(AbilityManagerInterfaceCode::RECORD_APP_EXIT_REASON), mock_->code_);
EXPECT_EQ(res, NO_ERROR);
}
/*
* Feature: AbilityManagerService
* Function: RecordProcessExitReason
* SubFunction: NA
* FunctionPoints: AbilityManagerService RecordProcessExitReason
* EnvConditions: NA
* CaseDescription: Verify the normal process of RecordProcessExitReason
*/
HWTEST_F(AbilityManagerProxyTest, AbilityManagerProxy_RecordProcessExitReason_001, TestSize.Level1)
{
EXPECT_CALL(*mock_, SendRequest(_, _, _, _))
.Times(1)
.WillOnce(Invoke(mock_.GetRefPtr(), &AbilityManagerStubMock::InvokeSendRequest));
int32_t pid = 1;
ExitReason exitReason = { REASON_JS_ERROR, "Js Error." };
auto res = proxy_->RecordProcessExitReason(pid, exitReason);
EXPECT_EQ(static_cast<uint32_t>(AbilityManagerInterfaceCode::RECORD_PROCESS_EXIT_REASON), mock_->code_);
EXPECT_EQ(res, NO_ERROR);
}
/*
* Feature: AbilityManagerService
* Function: PrepareTerminateAbilityBySCB

View File

@ -1099,11 +1099,28 @@ HWTEST_F(AbilityManagerServiceFirstTest, RecordAppExitReason_001, TestSize.Level
HILOG_INFO("AbilityManagerServiceFirstTest RecordAppExitReason_001 start");
auto abilityMs_ = std::make_shared<AbilityManagerService>();
if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
EXPECT_EQ(abilityMs_->RecordAppExitReason(REASON_JS_ERROR), ERR_NULL_OBJECT);
ExitReason exitReason = { REASON_JS_ERROR, "Js Error." };
EXPECT_EQ(abilityMs_->RecordAppExitReason(exitReason), ERR_NULL_OBJECT);
}
HILOG_INFO("AbilityManagerServiceFirstTest RecordAppExitReason_001 end");
}
/*
* Feature: AbilityManagerService
* Function: RecordProcessExitReason
* SubFunction: NA
* FunctionPoints: AbilityManagerService RecordProcessExitReason
*/
HWTEST_F(AbilityManagerServiceFirstTest, RecordProcessExitReason_001, TestSize.Level1)
{
HILOG_INFO("AbilityManagerServiceFirstTest RecordProcessExitReason_001 start");
auto abilityMs_ = std::make_shared<AbilityManagerService>();
int32_t pid = 1;
ExitReason exitReason = { REASON_JS_ERROR, "Js Error." };
EXPECT_EQ(abilityMs_->RecordProcessExitReason(pid, exitReason), ERR_PERMISSION_DENIED);
HILOG_INFO("AbilityManagerServiceFirstTest RecordProcessExitReason_001 end");
}
/*
* Feature: AbilityManagerService
* Function: ForceExitApp
@ -1115,7 +1132,8 @@ HWTEST_F(AbilityManagerServiceFirstTest, ForceExitApp_001, TestSize.Level1)
HILOG_INFO("AbilityManagerServiceFirstTest ForceExitApp_001 start");
auto abilityMs_ = std::make_shared<AbilityManagerService>();
int32_t pid = 0;
EXPECT_EQ(abilityMs_->ForceExitApp(pid, REASON_JS_ERROR), ERR_PERMISSION_DENIED);
ExitReason exitReason = { REASON_JS_ERROR, "Js Error." };
EXPECT_EQ(abilityMs_->ForceExitApp(pid, exitReason), ERR_PERMISSION_DENIED);
HILOG_INFO("AbilityManagerServiceFirstTest ForceExitApp_001 end");
}

View File

@ -45,6 +45,7 @@ ohos_unittest("ui_ability_lifecycle_manager_test") {
]
deps = [
"${ability_runtime_innerkits_path}/ability_manager:ability_manager",
"${ability_runtime_innerkits_path}/ability_manager:ability_start_setting",
"${ability_runtime_innerkits_path}/app_manager:app_manager",
"${ability_runtime_native_path}/ability/native:abilitykit_native",

View File

@ -2081,7 +2081,8 @@ ErrCode AbilityManagerShellCommand::RunAsForceExitAppCommand()
result = OHOS::ERR_INVALID_VALUE;
}
result = AbilityManagerClient::GetInstance()->ForceExitApp(std::stoi(pid), CovertExitReason(reason));
ExitReason exitReason = { CovertExitReason(reason), "Force exit app by aa." };
result = AbilityManagerClient::GetInstance()->ForceExitApp(std::stoi(pid), exitReason);
if (result == OHOS::ERR_OK) {
resultReceiver_ = STRING_BLOCK_AMS_SERVICE_OK + "\n";
} else {