已合并
提供快照dfx #20157
提供快照dfx #20157
已合并
zhangtao创建于 27 天前
30 个文件变更+1904-54
@@ -28,6 +28,7 @@ ohos_shared_library("hyper_snap_manager_ani") {
28 include_dirs = [28 include_dirs = [
29 "./include",29 "./include",
30 "${ability_runtime_path}/frameworks/ets/ani/ani_common/include",30 "${ability_runtime_path}/frameworks/ets/ani/ani_common/include",
31+ "${ability_runtime_path}/frameworks/ets/ani/enum_convert",
31 "${ability_runtime_services_path}/common/include"32 "${ability_runtime_services_path}/common/include"
32 ]33 ]
33 34 
@@ -44,14 +45,17 @@ ohos_shared_library("hyper_snap_manager_ani") {
44 45 
45 deps = [46 deps = [
46 "${ability_runtime_innerkits_path}/runtime:runtime",47 "${ability_runtime_innerkits_path}/runtime:runtime",
48+ "${ability_runtime_innerkits_path}/app_manager:app_manager",
47 "${ability_runtime_native_path}/ability/native:ability_business_error",49 "${ability_runtime_native_path}/ability/native:ability_business_error",
48 "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common",50 "${ability_runtime_path}/frameworks/ets/ani/ani_common:ani_common",
49 ]51 ]
50 52 
51 external_deps = [53 external_deps = [
54+ "c_utils:utils",
52 "hilog:libhilog",55 "hilog:libhilog",
53 "napi:ace_napi",56 "napi:ace_napi",
54 "runtime_core:ani",57 "runtime_core:ani",
58+ "samgr:samgr_proxy",
55 ]59 ]
56 60 
57 defines = []61 defines = []
@@ -18,8 +18,13 @@
18#include <unordered_map>18#include <unordered_map>
19 19 
20#include "ability_business_error.h"20#include "ability_business_error.h"
21+#include "ani_common_util.h"
22+#include "ani_enum_convert.h"
23+#include "app_mgr_client.h"
24+#include "errors.h"
21#include "ets_error_utils.h"25#include "ets_error_utils.h"
22#include "hilog_tag_wrapper.h"26#include "hilog_tag_wrapper.h"
27+#include "singleton.h"
23#ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE28#ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
24#include "res_sched_client.h"29#include "res_sched_client.h"
25#include "res_type.h"30#include "res_type.h"
@@ -29,13 +34,75 @@ namespace OHOS {
29namespace HyperSnapManagerEts {34namespace HyperSnapManagerEts {
30namespace {35namespace {
31constexpr const char *HYPER_SNAP_MANAGER_SPACE_NAME = "@ohos.app.ability.hyperSnapManager.hyperSnapManager";36constexpr const char *HYPER_SNAP_MANAGER_SPACE_NAME = "@ohos.app.ability.hyperSnapManager.hyperSnapManager";
37+constexpr const char *HYPER_SNAP_ERROR_INFO_IMPL_CLASS_NAME =
38+ "@ohos.app.ability.hyperSnapManager.hyperSnapManager.HyperSnapErrorInfoImpl";
39+constexpr const char *HYPER_SNAP_ERROR_CODE_ENUM_NAME =
40+ "@ohos.app.ability.hyperSnapManager.hyperSnapManager.HyperSnapErrorCode";
32} // namespace41} // namespace
33 42 
43+static ani_object BuildHyperSnapErrorInfo(ani_env *env, const AppExecFwk::HyperSnapErrorRecord &record)
44+{
45+ if (env == nullptr) {
46+ TAG_LOGE(AAFwkTag::APPKIT, "BuildHyperSnapErrorInfo: null env");
47+ return nullptr;
48+ }
49+ 
50+ ani_class cls = nullptr;
51+ ani_status status = env->FindClass(HYPER_SNAP_ERROR_INFO_IMPL_CLASS_NAME, &cls);
52+ if (status != ANI_OK || cls == nullptr) {
53+ TAG_LOGE(AAFwkTag::APPKIT, "BuildHyperSnapErrorInfo: FindClass failed, status:%{public}d", status);
54+ return nullptr;
55+ }
56+ 
57+ ani_method ctor = nullptr;
58+ status = env->Class_FindMethod(cls, "<ctor>", ":", &ctor);
59+ if (status != ANI_OK || ctor == nullptr) {
60+ TAG_LOGE(AAFwkTag::APPKIT, "BuildHyperSnapErrorInfo: find ctor failed, status:%{public}d", status);
61+ return nullptr;
62+ }
63+ 
64+ ani_object object = nullptr;
65+ status = env->Object_New(cls, ctor, &object);
66+ if (status != ANI_OK || object == nullptr) {
67+ TAG_LOGE(AAFwkTag::APPKIT, "BuildHyperSnapErrorInfo: Object_New failed, status:%{public}d", status);
68+ return nullptr;
69+ }
70+ 
71+ ani_enum_item codeItem = nullptr;
72+ if (!AAFwk::AniEnumConvertUtil::EnumConvert_NativeToEts(env, HYPER_SNAP_ERROR_CODE_ENUM_NAME,
73+ record.code, codeItem)) {
74+ TAG_LOGE(AAFwkTag::APPKIT, "BuildHyperSnapErrorInfo: convert code to enum item failed");
75+ return nullptr;
76+ }
77+ status = env->Object_SetPropertyByName_Ref(object, "code", codeItem);
78+ if (status != ANI_OK) {
79+ TAG_LOGE(AAFwkTag::APPKIT, "BuildHyperSnapErrorInfo: set code failed, status:%{public}d", status);
80+ return nullptr;
81+ }
82+ 
83+ status = env->Object_SetPropertyByName_Ref(object, "msg", AppExecFwk::GetAniString(env, record.msg));
84+ if (status != ANI_OK) {
85+ TAG_LOGE(AAFwkTag::APPKIT, "BuildHyperSnapErrorInfo: set msg failed, status:%{public}d", status);
86+ return nullptr;
87+ }
88+ 
89+ status = env->Object_SetPropertyByName_Long(object, "occurTimeStamp",
90+ static_cast<ani_long>(record.occurTimeStamp));
91+ if (status != ANI_OK) {
92+ TAG_LOGE(AAFwkTag::APPKIT, "BuildHyperSnapErrorInfo: set occurTimeStamp failed, status:%{public}d", status);
93+ return nullptr;
94+ }
95+ 
96+ return object;
97+}
98+ 
34class EtsHyperSnapManager final {99class EtsHyperSnapManager final {
35public:100public:
36 static void SetHyperSnapEnabled(ani_env *env, ani_boolean enabledFlag);101 static void SetHyperSnapEnabled(ani_env *env, ani_boolean enabledFlag);
37 102 
38 static void RequestRebuildHyperSnap(ani_env *env);103 static void RequestRebuildHyperSnap(ani_env *env);
104+ 
105+ static void NativeGetLastError(ani_env *env, ani_enum_item errType, ani_object call);
39};106};
40 107 
41void EtsHyperSnapManager::SetHyperSnapEnabled(ani_env *env, ani_boolean enabledFlag)108void EtsHyperSnapManager::SetHyperSnapEnabled(ani_env *env, ani_boolean enabledFlag)
@@ -86,6 +153,47 @@ void EtsHyperSnapManager::RequestRebuildHyperSnap(ani_env *env)
86#endif153#endif
87}154}
88 155 
156+void EtsHyperSnapManager::NativeGetLastError(ani_env *env, ani_enum_item errType, ani_object call)
157+{
158+ TAG_LOGD(AAFwkTag::APPKIT, "NativeGetLastError called");
159+ if (env == nullptr) {
160+ TAG_LOGE(AAFwkTag::APPKIT, "NativeGetLastError: null env");
161+ return;
162+ }
163+ 
164+ int32_t typeValue = 0;
165+ if (!AAFwk::AniEnumConvertUtil::EnumConvert_EtsToNative(env, errType, typeValue)) {
166+ TAG_LOGE(AAFwkTag::APPKIT, "NativeGetLastError: parse errType failed");
167+ AbilityRuntime::EtsErrorUtil::ThrowInvalidParamError(env, "errType must be a valid HyperSnapErrorType.");
168+ return;
169+ }
170+ 
171+ auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
172+ if (appMgrClient == nullptr) {
173+ TAG_LOGE(AAFwkTag::APPKIT, "NativeGetLastError: null appMgrClient");
174+ ani_object error = AbilityRuntime::EtsErrorUtil::CreateError(env,
175+ AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER);
176+ AppExecFwk::AsyncCallback(env, call, error, nullptr);
177+ return;
178+ }
179+ 
180+ AppExecFwk::HyperSnapErrorRecord record;
181+ int32_t result = appMgrClient->GetHyperSnapLastError(typeValue, record);
182+ if (result != ERR_OK) {
183+ TAG_LOGE(AAFwkTag::APPKIT, "NativeGetLastError: IPC failed, result %{public}d", result);
184+ ani_object error = AbilityRuntime::EtsErrorUtil::CreateError(env,
185+ AbilityRuntime::AbilityErrorCode::ERROR_CODE_INNER);
186+ AppExecFwk::AsyncCallback(env, call, error, nullptr);
187+ return;
188+ }
189+ 
190+ TAG_LOGI(AAFwkTag::APPKIT, "NativeGetLastError success, errType:%{public}d, code:%{public}d",
191+ typeValue, static_cast<int32_t>(record.code));
192+ ani_object error = AbilityRuntime::EtsErrorUtil::CreateError(env, AbilityRuntime::AbilityErrorCode::ERROR_OK);
zhangtao
zhangtaozhangtao8 天前

变量的名字改为err_ok

likedislike
zhangtao
zhangtao
6 天前 评论:
193+ ani_object info = BuildHyperSnapErrorInfo(env, record);
194+ AppExecFwk::AsyncCallback(env, call, error, info);
195+}
196+ 
89void EtsHyperSnapManagerRegisterInit(ani_env *env)197void EtsHyperSnapManagerRegisterInit(ani_env *env)
90{198{
91 TAG_LOGD(AAFwkTag::APPKIT, "EtsHyperSnapManagerRegisterInit call");199 TAG_LOGD(AAFwkTag::APPKIT, "EtsHyperSnapManagerRegisterInit call");
@@ -109,6 +217,8 @@ void EtsHyperSnapManagerRegisterInit(ani_env *env)
109 reinterpret_cast<void *>(EtsHyperSnapManager::SetHyperSnapEnabled)},217 reinterpret_cast<void *>(EtsHyperSnapManager::SetHyperSnapEnabled)},
110 ani_native_function{"nativeRequestRebuildHyperSnap", nullptr,218 ani_native_function{"nativeRequestRebuildHyperSnap", nullptr,
111 reinterpret_cast<void *>(EtsHyperSnapManager::RequestRebuildHyperSnap)},219 reinterpret_cast<void *>(EtsHyperSnapManager::RequestRebuildHyperSnap)},
220+ ani_native_function{"nativeGetLastError", nullptr,
221+ reinterpret_cast<void *>(EtsHyperSnapManager::NativeGetLastError)},
112 };222 };
113 status = env->Namespace_BindNativeFunctions(ns, kitFunctions.data(), kitFunctions.size());223 status = env->Namespace_BindNativeFunctions(ns, kitFunctions.data(), kitFunctions.size());
114 if (status != ANI_OK) {224 if (status != ANI_OK) {
@@ -143,4 +253,4 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
143}253}
144} // extern "C"254} // extern "C"
145} // namespace HyperSnapManagerEts255} // namespace HyperSnapManagerEts
146-} // namespace OHOS256+} // namespace OHOS
@@ -13,9 +13,40 @@
13 * limitations under the License.13 * limitations under the License.
14 */14 */
15 15 
16+import { BusinessError } from '@ohos.base';
17+import AsyncCallbackWrapper from './utils/AbilityUtils';
18+ 
16export default namespace hyperSnapManager {19export default namespace hyperSnapManager {
17loadLibraryWithPermissionCheck("hyper_snap_manager_ani.z", "@ohos.app.ability.hyperSnapManager")20loadLibraryWithPermissionCheck("hyper_snap_manager_ani.z", "@ohos.app.ability.hyperSnapManager")
18 21 
22+export enum HyperSnapErrorType {
23+ CREATE_SNAPSHOT = 0,
24+ FORK_FROM_SNAPSHOT = 1
25+}
26+ 
27+export enum HyperSnapErrorCode {
28+ ERR_OK = 0,
29+ ERR_SYSTEM_INNER = 1,
30+ ERR_SNAPSHOT_EXIST = 2,
31+ ERR_PROCESS_IS_RUNNING = 3,
32+ ERR_SNAPSHOT_PROCESS_IS_DIED = 4,
33+ ERR_SNAPSHOT_IS_INTERRUPTED = 5,
34+ ERR_EXISTS_ILLEGAL_BINDER = 6,
35+ ERR_LAST_PROCESS_NOT_FULLY_EXITED = 7
36+}
37+ 
38+export interface HyperSnapErrorInfo {
39+ code: HyperSnapErrorCode;
40+ msg: string;
41+ occurTimeStamp: long;
42+}
43+ 
44+class HyperSnapErrorInfoImpl implements HyperSnapErrorInfo {
45+ code: HyperSnapErrorCode = HyperSnapErrorCode.ERR_OK;
46+ msg: string = '';
47+ occurTimeStamp: long = 0;
48+}
49+ 
19export native function nativeSetHyperSnapEnabled(enableFlag: boolean): void;50export native function nativeSetHyperSnapEnabled(enableFlag: boolean): void;
20export function setHyperSnapEnabled(enableFlag: boolean): void {51export function setHyperSnapEnabled(enableFlag: boolean): void {
21 hyperSnapManager.nativeSetHyperSnapEnabled(enableFlag);52 hyperSnapManager.nativeSetHyperSnapEnabled(enableFlag);
@@ -25,4 +56,26 @@ export native function nativeRequestRebuildHyperSnap(): void;
25export function requestRebuildHyperSnap(): void {56export function requestRebuildHyperSnap(): void {
26 hyperSnapManager.nativeRequestRebuildHyperSnap();57 hyperSnapManager.nativeRequestRebuildHyperSnap();
27}58}
28-} // namespace hyperSnapManager59+ 
60+export native function nativeGetLastError(errType: HyperSnapErrorType,
61+ callback: AsyncCallbackWrapper<HyperSnapErrorInfo>): void;
62+export function getLastError(errType: HyperSnapErrorType): Promise<HyperSnapErrorInfo> {
63+ return new Promise<HyperSnapErrorInfo>((resolve, reject) => {
64+ let call = new AsyncCallbackWrapper<HyperSnapErrorInfo>((err: BusinessError | null,
65+ data: HyperSnapErrorInfo | undefined) => {
66+ if (err == null || err.code == 0) {
67+ resolve(data as HyperSnapErrorInfo);
68+ } else {
69+ reject(err);
70+ }
71+ });
72+ taskpool.execute((): void => {
73+ try {
74+ hyperSnapManager.nativeGetLastError(errType, call);
75+ } catch (err) {
76+ reject(err as BusinessError);
77+ }
78+ });
79+ });
80+}
81+} // namespace hyperSnapManager
@@ -37,11 +37,13 @@ ohos_shared_library("hypersnapmanager_napi") {
37 configs = [ "${ability_runtime_services_path}/common:common_config" ]37 configs = [ "${ability_runtime_services_path}/common:common_config" ]
38 38 
39 deps = [39 deps = [
40+ "${ability_runtime_innerkits_path}/app_manager:app_manager",
40 "${ability_runtime_innerkits_path}/runtime:runtime",41 "${ability_runtime_innerkits_path}/runtime:runtime",
41 "${ability_runtime_native_path}/ability/native:ability_business_error",42 "${ability_runtime_native_path}/ability/native:ability_business_error",
42 ]43 ]
43 44 
44 external_deps = [45 external_deps = [
46+ "c_utils:utils",
45 "hilog:libhilog",47 "hilog:libhilog",
46 "napi:ace_napi",48 "napi:ace_napi",
47 "resource_schedule_service:ressched_client",49 "resource_schedule_service:ressched_client",
@@ -17,15 +17,19 @@
17 17 
18#include <cstdint>18#include <cstdint>
19#include <dlfcn.h>19#include <dlfcn.h>
20+#include <memory>
20#include <unordered_map>21#include <unordered_map>
21 22 
22#include "ability_business_error.h"23#include "ability_business_error.h"
24+#include "app_mgr_client.h"
25+#include "errors.h"
23#include "hilog_tag_wrapper.h"26#include "hilog_tag_wrapper.h"
24#include "js_error_utils.h"27#include "js_error_utils.h"
25#include "js_runtime_utils.h"28#include "js_runtime_utils.h"
26#include "napi/native_api.h"29#include "napi/native_api.h"
27#include "res_sched_client.h"30#include "res_sched_client.h"
28#include "res_type.h"31#include "res_type.h"
32+#include "singleton.h"
29 33 
30namespace OHOS {34namespace OHOS {
31namespace AbilityRuntime {35namespace AbilityRuntime {
@@ -34,6 +38,79 @@ constexpr int32_t INDEX_ZERO = 0;
34constexpr size_t ARGC_ONE = 1;38constexpr size_t ARGC_ONE = 1;
35const std::string RES_SCHED_CLIENT_SO = "libressched_client.z.so";39const std::string RES_SCHED_CLIENT_SO = "libressched_client.z.so";
36 40 
41+napi_value CreateJsHyperSnapErrorInfo(napi_env env, const AppExecFwk::HyperSnapErrorRecord &record)
42+{
43+ napi_value object = nullptr;
44+ napi_create_object(env, &object);
45+ 
46+ napi_value codeValue = nullptr;
47+ napi_create_int32(env, static_cast<int32_t>(record.code), &codeValue);
48+ napi_set_named_property(env, object, "code", codeValue);
49+ 
50+ napi_value msgValue = nullptr;
51+ napi_create_string_utf8(env, record.msg.c_str(), NAPI_AUTO_LENGTH, &msgValue);
52+ napi_set_named_property(env, object, "msg", msgValue);
53+ 
54+ napi_value timeStampValue = nullptr;
55+ napi_create_int64(env, record.occurTimeStamp, &timeStampValue);
56+ napi_set_named_property(env, object, "occurTimeStamp", timeStampValue);
57+ return object;
58+}
59+ 
60+bool SetEnumItem(napi_env env, napi_value object, const char *name, int32_t value)
61+{
62+ napi_value itemName = nullptr;
63+ napi_value itemValue = nullptr;
64+ if (napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &itemName) != napi_ok ||
65+ napi_create_int32(env, value, &itemValue) != napi_ok ||
66+ napi_set_property(env, object, itemName, itemValue) != napi_ok ||
67+ napi_set_property(env, object, itemValue, itemName) != napi_ok) {
68+ TAG_LOGE(AAFwkTag::APPKIT, "SetEnumItem failed, name:%{public}s", name);
69+ return false;
70+ }
71+ return true;
72+}
73+ 
74+// Enums declared in the d.ts are runtime values; for ArkTS dynamic apps the module
75+// object comes from this native Init, so each enum must be attached to exports.
76+napi_value InitHyperSnapErrorTypeEnum(napi_env env)
77+{
78+ napi_value object = nullptr;
79+ napi_create_object(env, &object);
80+ if (!SetEnumItem(env, object, "CREATE_SNAPSHOT",
81+ static_cast<int32_t>(AppExecFwk::HyperSnapErrorType::CREATE_SNAPSHOT)) ||
82+ !SetEnumItem(env, object, "FORK_FROM_SNAPSHOT",
83+ static_cast<int32_t>(AppExecFwk::HyperSnapErrorType::FORK_FROM_SNAPSHOT))) {
84+ return nullptr;
85+ }
86+ return object;
87+}
88+ 
89+napi_value InitHyperSnapErrorCodeEnum(napi_env env)
90+{
91+ napi_value object = nullptr;
92+ napi_create_object(env, &object);
93+ if (!SetEnumItem(env, object, "ERR_OK",
94+ static_cast<int32_t>(AppExecFwk::HyperSnapErrorCode::ERR_OK)) ||
95+ !SetEnumItem(env, object, "ERR_SYSTEM_INNER",
96+ static_cast<int32_t>(AppExecFwk::HyperSnapErrorCode::ERR_SYSTEM_INNER)) ||
97+ !SetEnumItem(env, object, "ERR_SNAPSHOT_EXIST",
98+ static_cast<int32_t>(AppExecFwk::HyperSnapErrorCode::ERR_SNAPSHOT_EXIST)) ||
99+ !SetEnumItem(env, object, "ERR_PROCESS_IS_RUNNING",
100+ static_cast<int32_t>(AppExecFwk::HyperSnapErrorCode::ERR_PROCESS_IS_RUNNING)) ||
101+ !SetEnumItem(env, object, "ERR_SNAPSHOT_PROCESS_IS_DIED",
102+ static_cast<int32_t>(AppExecFwk::HyperSnapErrorCode::ERR_SNAPSHOT_PROCESS_IS_DIED)) ||
103+ !SetEnumItem(env, object, "ERR_SNAPSHOT_IS_INTERRUPTED",
104+ static_cast<int32_t>(AppExecFwk::HyperSnapErrorCode::ERR_SNAPSHOT_IS_INTERRUPTED)) ||
105+ !SetEnumItem(env, object, "ERR_EXISTS_ILLEGAL_BINDER",
106+ static_cast<int32_t>(AppExecFwk::HyperSnapErrorCode::ERR_EXISTS_ILLEGAL_BINDER)) ||
107+ !SetEnumItem(env, object, "ERR_LAST_PROCESS_NOT_FULLY_EXITED",
108+ static_cast<int32_t>(AppExecFwk::HyperSnapErrorCode::ERR_LAST_PROCESS_NOT_FULLY_EXITED))) {
109+ return nullptr;
110+ }
111+ return object;
112+}
113+ 
37class JsHyperSnapManager final {114class JsHyperSnapManager final {
38public:115public:
39 JsHyperSnapManager()116 JsHyperSnapManager()
@@ -56,6 +133,11 @@ public:
56 {133 {
57 GET_CB_INFO_AND_CALL(env, info, JsHyperSnapManager, OnRequestRebuildHyperSnap);134 GET_CB_INFO_AND_CALL(env, info, JsHyperSnapManager, OnRequestRebuildHyperSnap);
58 }135 }
136+ 
137+ static napi_value GetLastError(napi_env env, napi_callback_info info)
138+ {
139+ GET_CB_INFO_AND_CALL(env, info, JsHyperSnapManager, OnGetLastError);
140+ }
59private:141private:
60 142 
61 napi_value OnSetHyperSnapEnabled(napi_env env, const size_t argc, napi_value* argv)143 napi_value OnSetHyperSnapEnabled(napi_env env, const size_t argc, napi_value* argv)
@@ -101,6 +183,53 @@ private:
101 }183 }
102 return CreateJsUndefined(env);184 return CreateJsUndefined(env);
103 }185 }
186+ 
187+ napi_value OnGetLastError(napi_env env, size_t argc, napi_value* argv)
jsjzju
jsjzjujsjzju18 天前

HyperSnapErrorType这个枚举需要有对应的napi实现

likedislike
zhangtao
zhangtao
9 天前 评论:
188+ {
189+ TAG_LOGD(AAFwkTag::APPKIT, "OnGetLastError");
190+ // only support 1 params
191+ if (argc < ARGC_ONE) {
192+ TAG_LOGE(AAFwkTag::APPKIT, "invalid argc");
193+ ThrowTooFewParametersError(env);
194+ return CreateJsUndefined(env);
195+ }
196+ int32_t errType = 0;
197+ if (!ConvertFromJsValue(env, argv[INDEX_ZERO], errType) ||
198+ (errType != static_cast<int32_t>(AppExecFwk::HyperSnapErrorType::CREATE_SNAPSHOT) &&
199+ errType != static_cast<int32_t>(AppExecFwk::HyperSnapErrorType::FORK_FROM_SNAPSHOT))) {
200+ TAG_LOGE(AAFwkTag::APPKIT, "get errType failed");
201+ ThrowInvalidParamError(env, "Parse param errType failed, must be a valid HyperSnapErrorType.");
202+ return CreateJsUndefined(env);
203+ }
204+ 
205+ // The service fills `record` regardless of whether an error exists (code == ERR_OK means
206+ // no error recorded); only an IPC/system failure makes the call itself fail.
207+ auto record = std::make_shared<AppExecFwk::HyperSnapErrorRecord>();
208+ auto innerErrorCode = std::make_shared<int32_t>(ERR_OK);
209+ NapiAsyncTask::ExecuteCallback execute =
210+ [errType, innerErrorCode, record]() {
211+ auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
212+ if (appMgrClient == nullptr) {
213+ TAG_LOGW(AAFwkTag::APPKIT, "null appMgrClient");
214+ *innerErrorCode = static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INNER);
215+ return;
216+ }
217+ *innerErrorCode = appMgrClient->GetHyperSnapLastError(errType, *record);
218+ };
219+ NapiAsyncTask::CompleteCallback complete =
220+ [innerErrorCode, record](napi_env env, NapiAsyncTask &task, int32_t status) {
zhangtao
zhangtaozhangtao8 天前

innerErrorCode record这两个变量要在complete函数里判空处理

likedislike
zhangtao
zhangtao
6 天前 评论:
221+ if (*innerErrorCode == ERR_OK) {
222+ task.ResolveWithNoError(env, CreateJsHyperSnapErrorInfo(env, *record));
223+ } else {
224+ task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrorCode));
225+ }
226+ };
227+ napi_value lastParam = nullptr;
228+ napi_value result = nullptr;
229+ NapiAsyncTask::ScheduleHighQos("JsHyperSnapManager::OnGetLastError",
230+ env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
231+ return result;
232+ }
104};233};
105} // namespace234} // namespace
106 235 
@@ -117,13 +246,29 @@ napi_value JsHyperSnapManagerInit(napi_env env, napi_value exportObj)
117 napi_wrap(env, exportObj, jsHyperSnapManager.release(),246 napi_wrap(env, exportObj, jsHyperSnapManager.release(),
118 JsHyperSnapManager::Finalizer, nullptr, nullptr);247 JsHyperSnapManager::Finalizer, nullptr, nullptr);
119 248 
249+ napi_value hyperSnapErrorType = InitHyperSnapErrorTypeEnum(env);
250+ if (hyperSnapErrorType == nullptr || napi_set_named_property(env, exportObj,
251+ "HyperSnapErrorType", hyperSnapErrorType) != napi_ok) {
252+ TAG_LOGE(AAFwkTag::APPKIT, "failed to export HyperSnapErrorType");
253+ return nullptr;
254+ }
255+ 
256+ napi_value hyperSnapErrorCode = InitHyperSnapErrorCodeEnum(env);
257+ if (hyperSnapErrorCode == nullptr || napi_set_named_property(env, exportObj,
258+ "HyperSnapErrorCode", hyperSnapErrorCode) != napi_ok) {
259+ TAG_LOGE(AAFwkTag::APPKIT, "failed to export HyperSnapErrorCode");
260+ return nullptr;
261+ }
262+ 
120 const char *moduleName = "JsHyperSnapManager";263 const char *moduleName = "JsHyperSnapManager";
121 BindNativeFunction(env, exportObj, "setHyperSnapEnabled", moduleName,264 BindNativeFunction(env, exportObj, "setHyperSnapEnabled", moduleName,
122 JsHyperSnapManager::SetHyperSnapEnabled);265 JsHyperSnapManager::SetHyperSnapEnabled);
123 BindNativeFunction(env, exportObj, "requestRebuildHyperSnap", moduleName,266 BindNativeFunction(env, exportObj, "requestRebuildHyperSnap", moduleName,
124 JsHyperSnapManager::RequestRebuildHyperSnap);267 JsHyperSnapManager::RequestRebuildHyperSnap);
268+ BindNativeFunction(env, exportObj, "getLastError", moduleName,
269+ JsHyperSnapManager::GetLastError);
125 TAG_LOGD(AAFwkTag::APPKIT, "JsHyperSnapManager end");270 TAG_LOGD(AAFwkTag::APPKIT, "JsHyperSnapManager end");
126 return CreateJsUndefined(env);271 return CreateJsUndefined(env);
127}272}
128-} //namespace AbilityRuntime273+} // namespace AbilityRuntime
129-} //namespace OHOS274+} // namespace OHOS
@@ -118,6 +118,7 @@ ohos_shared_library("app_manager") {
118 "src/appmgr/configuration_observer_stub.cpp",118 "src/appmgr/configuration_observer_stub.cpp",
119 "src/appmgr/configuration_policy.cpp",119 "src/appmgr/configuration_policy.cpp",
120 "src/appmgr/fault_data.cpp",120 "src/appmgr/fault_data.cpp",
121+ "src/appmgr/hyper_snap_error_record.cpp",
121 "src/appmgr/image_process_state_data.cpp",122 "src/appmgr/image_process_state_data.cpp",
122 "src/appmgr/image_error_handler_proxy.cpp",123 "src/appmgr/image_error_handler_proxy.cpp",
123 "src/appmgr/image_error_handler_stub.cpp",124 "src/appmgr/image_error_handler_stub.cpp",
@@ -1056,6 +1056,14 @@ public:
1056 int32_t IsChildProcessSupported(bool isNative, bool &isSupported);1056 int32_t IsChildProcessSupported(bool isNative, bool &isSupported);
1057 1057 
1058 int32_t GetSelfUIAbilityChildProcesses(std::vector<ChildProcessInfo> &infos);1058 int32_t GetSelfUIAbilityChildProcesses(std::vector<ChildProcessInfo> &infos);
1059+ /**
1060+ * Get the last hyper snap error of the caller for the given error type.
1061+ *
1062+ * @param errType The error type, see HyperSnapErrorType.
1063+ * @param record Output parameter, the last error record.
1064+ * @return Returns ERR_OK on success, others on failure.
1065+ */
1066+ int32_t GetHyperSnapLastError(int32_t errType, HyperSnapErrorRecord &record);
1059 1067 
1060 int32_t SetProcessCacheEnable(int32_t pid, bool enable);1068 int32_t SetProcessCacheEnable(int32_t pid, bool enable);
1061 1069 
@@ -57,6 +57,7 @@
57#include "app_cjheap_mem_info.h"57#include "app_cjheap_mem_info.h"
58#include "running_multi_info.h"58#include "running_multi_info.h"
59#include "native_child_notify_interface.h"59#include "native_child_notify_interface.h"
60+#include "hyper_snap_error_record.h"
60 61 
61namespace OHOS {62namespace OHOS {
62namespace AppExecFwk {63namespace AppExecFwk {
@@ -108,6 +109,18 @@ public:
108 return 0;109 return 0;
109 }110 }
110 111 
112+ /**
113+ * Get last HyperSnap error information.
114+ *
115+ * @param errType Error type (0: CREATE_SNAPSHOT, 1: FORK_FROM_SNAPSHOT)
116+ * @param record Output parameter for error record
117+ * @return ERR_OK on success, ERR_INVALID_VALUE on parameter error
118+ */
119+ virtual int32_t GetHyperSnapLastError(int32_t errType, HyperSnapErrorRecord &record)
120+ {
121+ return 0;
122+ }
123+ 
111 virtual int32_t NotifyTemplateProcessDeepFrozen(int32_t pid)124 virtual int32_t NotifyTemplateProcessDeepFrozen(int32_t pid)
112 {125 {
113 return 0;126 return 0;
@@ -167,7 +167,8 @@ enum class AppMgrInterfaceCode {
167 PRE_TEMPLATE_PROCESS_DEEP_FROZEN = 142,167 PRE_TEMPLATE_PROCESS_DEEP_FROZEN = 142,
168 NOTIFY_TEMPLATE_PROCESS_READY_DONE = 143,168 NOTIFY_TEMPLATE_PROCESS_READY_DONE = 143,
169 GET_SELF_UIABILITY_CHILD_PROCESSES = 144,169 GET_SELF_UIABILITY_CHILD_PROCESSES = 144,
170- GET_SELF_CHILDREN_PROCESSES = 145170+ GET_SELF_CHILDREN_PROCESSES = 145,
171+ GET_HYPER_SNAP_LAST_ERROR = 146,
171};172};
172} // AppExecFwk173} // AppExecFwk
173} // OHOS174} // OHOS
@@ -67,6 +67,8 @@ public:
67 67 
68 virtual int32_t DestroyImage(uint64_t checkpointId, sptr<IImageErrorHandler> errorHandler = nullptr) override;68 virtual int32_t DestroyImage(uint64_t checkpointId, sptr<IImageErrorHandler> errorHandler = nullptr) override;
69 69 
70+ virtual int32_t GetHyperSnapLastError(int32_t errType, HyperSnapErrorRecord &record) override;
71+ 
70 virtual int32_t NotifyTemplateProcessDeepFrozen(int32_t pid) override;72 virtual int32_t NotifyTemplateProcessDeepFrozen(int32_t pid) override;
71 73 
72 virtual int32_t PreTemplateProcessDeepFrozen(int32_t pid) override;74 virtual int32_t PreTemplateProcessDeepFrozen(int32_t pid) override;
@@ -85,6 +85,7 @@ private:
85 int32_t HandleNotifyTemplateProcessDeepFrozen(MessageParcel &data, MessageParcel &reply);85 int32_t HandleNotifyTemplateProcessDeepFrozen(MessageParcel &data, MessageParcel &reply);
86 int32_t HandlePreTemplateProcessDeepFrozen(MessageParcel &data, MessageParcel &reply);86 int32_t HandlePreTemplateProcessDeepFrozen(MessageParcel &data, MessageParcel &reply);
87 int32_t HandleNotifyTemplateProcessReadyDone(MessageParcel &data, MessageParcel &reply);87 int32_t HandleNotifyTemplateProcessReadyDone(MessageParcel &data, MessageParcel &reply);
88+ int32_t HandleGetHyperSnapLastError(MessageParcel &data, MessageParcel &reply);
88#ifdef SUPPORT_CHILD_PROCESS89#ifdef SUPPORT_CHILD_PROCESS
89 int32_t HandleGetAllChildrenProcesses(MessageParcel &data, MessageParcel &reply);90 int32_t HandleGetAllChildrenProcesses(MessageParcel &data, MessageParcel &reply);
90 int32_t HandleGetSelfChildrenProcesses(MessageParcel &data, MessageParcel &reply);91 int32_t HandleGetSelfChildrenProcesses(MessageParcel &data, MessageParcel &reply);
@@ -0,0 +1,56 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+#ifndef OHOS_ABILITY_RUNTIME_HYPER_SNAP_ERROR_RECORD_H
17+#define OHOS_ABILITY_RUNTIME_HYPER_SNAP_ERROR_RECORD_H
18+ 
19+#include <cstdint>
20+#include <string>
21+ 
22+#include "parcel.h"
23+ 
24+namespace OHOS {
25+namespace AppExecFwk {
26+ 
27+enum class HyperSnapErrorCode {
28+ ERR_OK = 0,
29+ ERR_SYSTEM_INNER = 1,
30+ ERR_SNAPSHOT_EXIST = 2,
31+ ERR_PROCESS_IS_RUNNING = 3,
32+ ERR_SNAPSHOT_PROCESS_IS_DIED = 4,
33+ ERR_SNAPSHOT_IS_INTERRUPTED = 5,
34+ ERR_EXISTS_ILLEGAL_BINDER = 6,
35+ ERR_LAST_PROCESS_NOT_FULLY_EXITED = 7,
36+};
37+ 
38+enum class HyperSnapErrorType {
39+ CREATE_SNAPSHOT = 0,
40+ FORK_FROM_SNAPSHOT = 1,
41+};
42+ 
43+struct HyperSnapErrorRecord : public Parcelable {
jsjzju
jsjzjujsjzju9 天前

文件名建议用hyper_snap_error_record

likedislike
zhangtao
zhangtao
9 天前 评论:
44+ HyperSnapErrorCode code = HyperSnapErrorCode::ERR_OK;
45+ std::string msg;
46+ int64_t occurTimeStamp = 0; // UNIX timestamp in milliseconds
47+ 
48+ bool ReadFromParcel(Parcel &parcel);
49+ virtual bool Marshalling(Parcel &parcel) const override;
50+ static HyperSnapErrorRecord *Unmarshalling(Parcel &parcel);
51+};
52+ 
53+} // namespace AppExecFwk
54+} // namespace OHOS
55+ 
56+#endif // OHOS_ABILITY_RUNTIME_HYPER_SNAP_ERROR_RECORD_H
@@ -46,6 +46,8 @@ public:
46 ERR_INNER = 11,46 ERR_INNER = 11,
47 ERR_TEMPLATE_DIED = 12,47 ERR_TEMPLATE_DIED = 12,
48 ERR_FORKALL_BUSY = 13,48 ERR_FORKALL_BUSY = 13,
49+ ERR_EXISTS_ILLEGAL_BINDER = 14,
50+ ERR_LAST_PROCESS_NOT_FULLY_EXITED = 15,
49 };51 };
50};52};
51} // namespace AppExecFwk53} // namespace AppExecFwk
@@ -1737,6 +1737,21 @@ int32_t AppMgrClient::IsChildProcessSupported(bool isNative, bool &isSupported)
1737 return service->IsChildProcessSupported(isNative, isSupported);1737 return service->IsChildProcessSupported(isNative, isSupported);
1738}1738}
1739 1739 
1740+int32_t AppMgrClient::GetHyperSnapLastError(int32_t errType, HyperSnapErrorRecord &record)
1741+{
1742+ TAG_LOGD(AAFwkTag::APPMGR, "GetHyperSnapLastError called");
1743+ if (mgrHolder_ == nullptr) {
1744+ TAG_LOGE(AAFwkTag::APPMGR, "mgrHolder_ is nullptr.");
1745+ return AppMgrResultCode::ERROR_SERVICE_NOT_READY;
1746+ }
1747+ sptr<IAppMgr> service = iface_cast<IAppMgr>(mgrHolder_->GetRemoteObject());
1748+ if (service == nullptr) {
1749+ TAG_LOGE(AAFwkTag::APPMGR, "Service is nullptr.");
1750+ return AppMgrResultCode::ERROR_SERVICE_NOT_CONNECTED;
1751+ }
1752+ return service->GetHyperSnapLastError(errType, record);
1753+}
1754+ 
1740int32_t AppMgrClient::GetSelfUIAbilityChildProcesses(std::vector<ChildProcessInfo> &infos)1755int32_t AppMgrClient::GetSelfUIAbilityChildProcesses(std::vector<ChildProcessInfo> &infos)
1741{1756{
1742 TAG_LOGD(AAFwkTag::APPMGR, "called");1757 TAG_LOGD(AAFwkTag::APPMGR, "called");
@@ -142,6 +142,38 @@ int32_t AppMgrProxy::DestroyImage(uint64_t checkpointId, sptr<IImageErrorHandler
142 return reply.ReadInt32();142 return reply.ReadInt32();
143}143}
144 144 
145+int32_t AppMgrProxy::GetHyperSnapLastError(int32_t errType, HyperSnapErrorRecord &record)
146+{
147+ TAG_LOGD(AAFwkTag::APPMGR, "called");
148+ MessageParcel data;
149+ MessageParcel reply;
150+ MessageOption option(MessageOption::TF_SYNC);
151+ if (!WriteInterfaceToken(data)) {
152+ TAG_LOGE(AAFwkTag::APPMGR, "GetHyperSnapLastError Write interface token failed.");
153+ return IPC_PROXY_ERR;
zhangtao
zhangtaozhangtao8 天前

如果返回这个IPC_PROXY_ERR对应的JS错误码是什么待确认

likedislike
zhangtao
zhangtao
6 天前 评论:
154+ }
155+ PARCEL_UTIL_WRITE_RET_INT(data, Int32, errType);
156+ 
157+ PARCEL_UTIL_SENDREQ_RET_INT(AppMgrInterfaceCode::GET_HYPER_SNAP_LAST_ERROR, data, reply, option);
158+ 
159+ int32_t result = reply.ReadInt32();
160+ if (result != ERR_OK) {
161+ TAG_LOGE(AAFwkTag::APPMGR, "GetHyperSnapLastError failed with result: %{public}d", result);
162+ return result;
163+ }
164+ 
165+ std::unique_ptr<HyperSnapErrorRecord> recordReply(reply.ReadParcelable<HyperSnapErrorRecord>());
166+ if (recordReply == nullptr) {
167+ TAG_LOGE(AAFwkTag::APPMGR, "GetHyperSnapLastError ReadParcelable failed.");
168+ return IPC_PROXY_ERR;
169+ }
170+ record = *recordReply;
171+ 
172+ TAG_LOGD(AAFwkTag::APPMGR, "GetHyperSnapLastError success, code: %{public}d",
173+ static_cast<int32_t>(record.code));
174+ return ERR_OK;
175+}
176+ 
145int32_t AppMgrProxy::NotifyTemplateProcessDeepFrozen(int32_t pid)177int32_t AppMgrProxy::NotifyTemplateProcessDeepFrozen(int32_t pid)
146{178{
147 TAG_LOGD(AAFwkTag::APPMGR, "called");179 TAG_LOGD(AAFwkTag::APPMGR, "called");
@@ -16,6 +16,7 @@
16#include "app_mgr_stub.h"16#include "app_mgr_stub.h"
17 17 
18#include "ability_info.h"18#include "ability_info.h"
19+#include "hyper_snap_error_record.h"
19#include "ability_manager_errors.h"20#include "ability_manager_errors.h"
20#include "app_jsheap_mem_info.h"21#include "app_jsheap_mem_info.h"
21#include "app_cjheap_mem_info.h"22#include "app_cjheap_mem_info.h"
@@ -463,6 +464,8 @@ int32_t AppMgrStub::OnRemoteRequestInnerEighth(uint32_t code, MessageParcel &dat
463 return HandlePreTemplateProcessDeepFrozen(data, reply);464 return HandlePreTemplateProcessDeepFrozen(data, reply);
464 case static_cast<uint32_t>(AppMgrInterfaceCode::NOTIFY_TEMPLATE_PROCESS_READY_DONE):465 case static_cast<uint32_t>(AppMgrInterfaceCode::NOTIFY_TEMPLATE_PROCESS_READY_DONE):
465 return HandleNotifyTemplateProcessReadyDone(data, reply);466 return HandleNotifyTemplateProcessReadyDone(data, reply);
467+ case static_cast<uint32_t>(AppMgrInterfaceCode::GET_HYPER_SNAP_LAST_ERROR):
468+ return HandleGetHyperSnapLastError(data, reply);
466 case static_cast<uint32_t>(AppMgrInterfaceCode::REGISTER_IMAGE_PROCESS_STATE_OBSERVER):469 case static_cast<uint32_t>(AppMgrInterfaceCode::REGISTER_IMAGE_PROCESS_STATE_OBSERVER):
467 return HandleRegisterImageProcessStateObserver(data, reply);470 return HandleRegisterImageProcessStateObserver(data, reply);
468 case static_cast<uint32_t>(AppMgrInterfaceCode::IS_CHILD_PROCESS_SUPPORTED):471 case static_cast<uint32_t>(AppMgrInterfaceCode::IS_CHILD_PROCESS_SUPPORTED):
@@ -615,6 +618,33 @@ int32_t AppMgrStub::HandleNotifyTemplateProcessReadyDone(MessageParcel &data, Me
615 return NO_ERROR;618 return NO_ERROR;
616}619}
617 620 
621+int32_t AppMgrStub::HandleGetHyperSnapLastError(MessageParcel &data, MessageParcel &reply)
622+{
623+ HITRACE_METER(HITRACE_TAG_APP);
624+ TAG_LOGD(AAFwkTag::APPMGR, "called");
625+ int32_t errType = data.ReadInt32();
626+ 
627+ HyperSnapErrorRecord record;
628+ auto result = GetHyperSnapLastError(errType, record);
629+ if (!reply.WriteInt32(result)) {
630+ TAG_LOGE(AAFwkTag::APPMGR, "Write result failed.");
631+ return ERR_APPEXECFWK_PARCEL_ERROR;
632+ }
633+
634+ if (result != ERR_OK) {
635+ TAG_LOGE(AAFwkTag::APPMGR, "GetHyperSnapLastError failed with result: %{public}d", result);
636+ return NO_ERROR;
637+ }
638+ 
639+ if (!reply.WriteParcelable(&record)) {
640+ TAG_LOGE(AAFwkTag::APPMGR, "Write record failed.");
641+ return ERR_APPEXECFWK_PARCEL_ERROR;
642+ }
643+ 
644+ TAG_LOGD(AAFwkTag::APPMGR, "GetHyperSnapLastError success, code: %{public}d", static_cast<int32_t>(record.code));
645+ return NO_ERROR;
646+}
647+ 
618int32_t AppMgrStub::HandleApplicationForegrounded(MessageParcel &data, MessageParcel &reply)648int32_t AppMgrStub::HandleApplicationForegrounded(MessageParcel &data, MessageParcel &reply)
619{649{
620 HITRACE_METER(HITRACE_TAG_APP);650 HITRACE_METER(HITRACE_TAG_APP);
@@ -0,0 +1,60 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+#include "hyper_snap_error_record.h"
17+ 
18+#include <new>
19+ 
20+#include "string_ex.h"
21+ 
22+namespace OHOS {
23+namespace AppExecFwk {
24+ 
25+bool HyperSnapErrorRecord::ReadFromParcel(Parcel &parcel)
26+{
27+ int32_t codeValue = 0;
28+ if (!parcel.ReadInt32(codeValue)) {
29+ return false;
30+ }
31+ code = static_cast<HyperSnapErrorCode>(codeValue);
32+ msg = Str16ToStr8(parcel.ReadString16());
33+ if (!parcel.ReadInt64(occurTimeStamp)) {
34+ return false;
35+ }
36+ return true;
37+}
38+ 
39+bool HyperSnapErrorRecord::Marshalling(Parcel &parcel) const
40+{
41+ if (!parcel.WriteInt32(static_cast<int32_t>(code)) ||
42+ !parcel.WriteString16(Str8ToStr16(msg)) ||
43+ !parcel.WriteInt64(occurTimeStamp)) {
44+ return false;
45+ }
46+ return true;
47+}
48+ 
49+HyperSnapErrorRecord *HyperSnapErrorRecord::Unmarshalling(Parcel &parcel)
50+{
51+ auto *record = new (std::nothrow) HyperSnapErrorRecord();
52+ if (record != nullptr && !record->ReadFromParcel(parcel)) {
53+ delete record;
54+ record = nullptr;
55+ }
56+ return record;
57+}
58+ 
59+} // namespace AppExecFwk
60+} // namespace OHOS
@@ -27,6 +27,7 @@
27#include "app_mgr_constants.h"27#include "app_mgr_constants.h"
28#include "app_mgr_service_event_handler.h"28#include "app_mgr_service_event_handler.h"
29#include "app_mgr_service_inner.h"29#include "app_mgr_service_inner.h"
30+#include "hyper_snap_error_record.h"
30#include "app_mgr_stub.h"31#include "app_mgr_stub.h"
31#include "app_record_id.h"32#include "app_record_id.h"
32#include "app_running_record.h"33#include "app_running_record.h"
@@ -92,6 +93,8 @@ public:
92 93 
93 virtual int32_t DestroyImage(uint64_t checkpointId, sptr<IImageErrorHandler> errorHandler = nullptr) override;94 virtual int32_t DestroyImage(uint64_t checkpointId, sptr<IImageErrorHandler> errorHandler = nullptr) override;
94 95 
96+ virtual int32_t GetHyperSnapLastError(int32_t errType, HyperSnapErrorRecord &record) override;
97+ 
95 virtual int32_t NotifyTemplateProcessDeepFrozen(int32_t pid) override;98 virtual int32_t NotifyTemplateProcessDeepFrozen(int32_t pid) override;
96 99 
97 virtual int32_t PreTemplateProcessDeepFrozen(int32_t pid) override;100 virtual int32_t PreTemplateProcessDeepFrozen(int32_t pid) override;
@@ -36,6 +36,7 @@
36#include "app_malloc_info.h"36#include "app_malloc_info.h"
37#include "app_mgr_constants.h"37#include "app_mgr_constants.h"
38#include "app_mgr_event.h"38#include "app_mgr_event.h"
39+#include "hyper_snap_error_record.h"
39#include "app_preloader.h"40#include "app_preloader.h"
40#include "app_record_id.h"41#include "app_record_id.h"
41#include "app_refresh_recipient.h"42#include "app_refresh_recipient.h"
@@ -461,6 +462,15 @@ public:
461 462
462 virtual void NotifyUninstallOrUpgradeAppEnd(int32_t uid);463 virtual void NotifyUninstallOrUpgradeAppEnd(int32_t uid);
463 464 
465+ /**
466+ * Get error information (internally gets caller uid via IPCSkeleton::GetCallingUid()).
467+ *
468+ * @param errType Error type.
469+ * @param record Error record output.
470+ * @return true if call succeeded (whether error exists or not), false if parameter error.
471+ */
472+ bool GetHyperSnapLastError(HyperSnapErrorType errType, HyperSnapErrorRecord& record);
473+ 
464 /**474 /**
465 * KillApplicationSelf, this allows app to terminate itself.475 * KillApplicationSelf, this allows app to terminate itself.
466 *476 *
@@ -1898,6 +1908,59 @@ private:
1898 */1908 */
1899 void RestartKeepAliveProcess(std::shared_ptr<AppRunningRecord> appRecord);1909 void RestartKeepAliveProcess(std::shared_ptr<AppRunningRecord> appRecord);
1900 1910 
1911+ /**
1912+ * Save error information for the specified app uid. Error message is generated
1913+ * internally from the error code.
1914+ *
1915+ * @param uid The target app uid the error belongs to.
1916+ * @param errType Error type.
1917+ * @param code Error code.
1918+ */
1919+ void SaveHyperSnapError(int32_t uid, HyperSnapErrorType errType, HyperSnapErrorCode code);
1920+ 
1921+ /**
1922+ * Clear error information by type for the specified app uid.
1923+ *
1924+ * @param uid The target app uid whose error record should be cleared.
1925+ * @param errType Error type to clear.
1926+ */
1927+ void ClearHyperSnapError(int32_t uid, HyperSnapErrorType errType);
1928+ 
1929+ /**
1930+ * Clear all error information for the specified uid. Used for system-initiated clears
1931+ * (e.g. app uninstall/upgrade) where the affected app is not the IPC caller.
1932+ *
1933+ * @param uid The target app uid whose error records should be cleared.
1934+ */
1935+ void ClearHyperSnapError(int32_t uid);
1936+ 
1937+ /**
1938+ * Error code mapping: ImageError -> HyperSnapErrorCode
1939+ *
1940+ * @param imageError Image error code.
1941+ * @return Mapped HyperSnapErrorCode.
1942+ */
1943+ static HyperSnapErrorCode ConvertImageErrorToHyperSnapCode(ImageError imageError);
1944+ 
1945+ /**
1946+ * Query the kernel checkpoint/restore error of the given process and log the
1947+ * kernel error message. checkpointId is a reserved kernel extension and is
1948+ * not needed for now.
1949+ *
1950+ * @param pid Process ID.
1951+ * @param forkAll Whether HandleForkAllInner was called.
1952+ * @return Kernel error as ImageError, ERR_OK when no kernel error is available.
1953+ */
1954+ static ImageError GetCheckpointRestoreError(pid_t pid, const std::string &checkpointName);
1955+ 
1956+ /**
1957+ * Get error message (fixed message based on error code enum).
1958+ *
1959+ * @param code Error code.
1960+ * @return Error message string.
1961+ */
1962+ static std::string GetHyperSnapErrorMessage(HyperSnapErrorCode code);
1963+ 
1901 bool CheckLoadAbilityConditions(const sptr<IRemoteObject> &token,1964 bool CheckLoadAbilityConditions(const sptr<IRemoteObject> &token,
1902 const std::shared_ptr<AbilityInfo> &abilityInfo, const std::shared_ptr<ApplicationInfo> &appInfo);1965 const std::shared_ptr<AbilityInfo> &abilityInfo, const std::shared_ptr<ApplicationInfo> &appInfo);
1903 1966 
@@ -2471,6 +2534,7 @@ private:
2471 2534 
2472 int32_t GetValidUserId(int32_t userId);2535 int32_t GetValidUserId(int32_t userId);
2473 int32_t NotifyImageOperationFailed(sptr<IImageErrorHandler> errorHandler, ImageError errorCode);2536 int32_t NotifyImageOperationFailed(sptr<IImageErrorHandler> errorHandler, ImageError errorCode);
2537+ int32_t NotifyMakeImageFailed(int32_t uid, sptr<IImageErrorHandler> errorHandler, ImageError errorCode);
2474 int32_t KillImageProcess(uint64_t checkpointId);2538 int32_t KillImageProcess(uint64_t checkpointId);
2475 2539 
2476 int32_t PreAddImageInfo(const std::string& bundleName, int32_t userId, int32_t appIndex,2540 int32_t PreAddImageInfo(const std::string& bundleName, int32_t userId, int32_t appIndex,
@@ -2585,6 +2649,16 @@ private:
2585 std::mutex imageInfoLock_;2649 std::mutex imageInfoLock_;
2586 std::unordered_map<MakeImageRequest, std::shared_ptr<ForkImageInfo>, MakeImageRequest::Hash> imageInfoMap_;2650 std::unordered_map<MakeImageRequest, std::shared_ptr<ForkImageInfo>, MakeImageRequest::Hash> imageInfoMap_;
2587 2651 
2652+ // Minimal in-memory error state: only what cannot be derived later.
2653+ // Error message is generated from the code at query time to save memory.
2654+ struct HyperSnapStoredError {
2655+ HyperSnapErrorCode code = HyperSnapErrorCode::ERR_OK;
2656+ int64_t occurTimeStamp = 0;
2657+ };
2658+ std::map<int32_t, HyperSnapStoredError> createSnapshotErrorMap_;
2659+ std::map<int32_t, HyperSnapStoredError> forkFromSnapshotErrorMap_;
2660+ std::mutex hyperSnapErrorMutex_;
2661+ 
2588 std::mutex imageSerialLock_;2662 std::mutex imageSerialLock_;
2589 2663 
2590 std::mutex imageReportLock_;2664 std::mutex imageReportLock_;
@@ -317,6 +317,26 @@ int32_t AppMgrService::DestroyImage(uint64_t checkpointId, sptr<IImageErrorHandl
317 return ERR_OK;317 return ERR_OK;
318}318}
319 319 
320+int32_t AppMgrService::GetHyperSnapLastError(int32_t errType, HyperSnapErrorRecord &record)
321+{
322+ TAG_LOGD(AAFwkTag::APPMGR, "GetHyperSnapLastError called, errType: %{public}d", errType);
323+ if (!IsReady()) {
324+ TAG_LOGE(AAFwkTag::APPMGR, "GetHyperSnapLastError failed: service not ready");
325+ return ERR_INVALID_OPERATION;
326+ }
327+ 
328+ HyperSnapErrorType errorType = static_cast<HyperSnapErrorType>(errType);
329+ 
330+ bool success = appMgrServiceInner_->GetHyperSnapLastError(errorType, record);
zhangtao
zhangtaozhangtao8 天前

inner的返回值不要是bool,直接返回错误码

likedislike
zhangtao
zhangtao
6 天前 评论:
331+ if (!success) {
332+ TAG_LOGE(AAFwkTag::APPMGR, "GetHyperSnapLastError failed: invalid parameter");
333+ return ERR_INVALID_VALUE;
334+ }
335+ 
336+ TAG_LOGD(AAFwkTag::APPMGR, "GetHyperSnapLastError success, code: %{public}d", static_cast<int32_t>(record.code));
337+ return ERR_OK;
338+}
339+ 
320int32_t AppMgrService::NotifyTemplateProcessDeepFrozen(int32_t pid)340int32_t AppMgrService::NotifyTemplateProcessDeepFrozen(int32_t pid)
321{341{
322 TAG_LOGD(AAFwkTag::APPMGR, "called");342 TAG_LOGD(AAFwkTag::APPMGR, "called");
@@ -332,6 +332,7 @@ constexpr const char* REASON_APPRECOVERY_NOTIFYAPP_OVER_LIMIT = "AppRecoveryNoti
332#define CHECKPOINT_IOCTL_KILL_ALL _IOR(0xE0, 0x4, int)332#define CHECKPOINT_IOCTL_KILL_ALL _IOR(0xE0, 0x4, int)
333#define CHECKPOINT_MONITOR_IOCTL_MARK_TEMPLATE _IOR(0xE0, 0x7, struct HMCheckpointMarkS)333#define CHECKPOINT_MONITOR_IOCTL_MARK_TEMPLATE _IOR(0xE0, 0x7, struct HMCheckpointMarkS)
334#define CHECKPOINT_MONITOR_IOCTL_UNMARK_TEMPLATE _IOR(0xE0, 0x8, struct HMCheckpointUnMarkS)334#define CHECKPOINT_MONITOR_IOCTL_UNMARK_TEMPLATE _IOR(0xE0, 0x8, struct HMCheckpointUnMarkS)
335+#define CHECKPOINT_IOCTL_GET_LAST_ERROR _IOWR(0xE0, 0xC, struct HmCheckpointErrMsgS)
jsjzju
jsjzjujsjzju18 天前

selinux仓要同步修改

likedislike
335 336 
336constexpr int32_t ROOT_UID = 0;337constexpr int32_t ROOT_UID = 0;
337constexpr int32_t FOUNDATION_UID = 5523;338constexpr int32_t FOUNDATION_UID = 5523;
@@ -786,13 +787,40 @@ int32_t AppMgrServiceInner::NotifyImageOperationFailed(sptr<IImageErrorHandler>
786 return ERR_OK;787 return ERR_OK;
787}788}
788 789 
790+int32_t AppMgrServiceInner::NotifyMakeImageFailed(int32_t uid,
791+ sptr<IImageErrorHandler> errorHandler, ImageError errorCode)
792+{
793+ if (uid < 0) {
794+ TAG_LOGE(AAFwkTag::APPMGR, "NotifyMakeImageFailed invalid uid:%{public}d", uid);
795+ } else {
796+ if (errorCode != ImageError::ERR_FORKALL_BUSY && errorCode != ImageError::ERR_FORKALL_FAILED) {
797+ SaveHyperSnapError(uid, HyperSnapErrorType::CREATE_SNAPSHOT, ConvertImageErrorToHyperSnapCode(errorCode));
798+ }
799+ }
800+ 
801+ if (errorHandler == nullptr) {
802+ return -1;
803+ }
804+ 
805+ errorHandler->OnError(static_cast<int32_t>(errorCode));
806+ return ERR_OK;
807+}
808+ 
789void AppMgrServiceInner::MakeImage(const AAFwk::Want &want, int32_t userId,809void AppMgrServiceInner::MakeImage(const AAFwk::Want &want, int32_t userId,
790 AppExecFwk::PreloadMode preloadMode, int32_t appIndex, sptr<IImageErrorHandler> errorHandler)810 AppExecFwk::PreloadMode preloadMode, int32_t appIndex, sptr<IImageErrorHandler> errorHandler)
791{811{
792 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);812 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
793 auto ret = MakeImageInner(want, userId, preloadMode, appIndex, errorHandler);813 auto ret = MakeImageInner(want, userId, preloadMode, appIndex, errorHandler);
794 if (ret != ImageError::ERR_OK) {814 if (ret != ImageError::ERR_OK) {
795- NotifyImageOperationFailed(errorHandler, ret);815+ auto bundleMgrHelper = remoteClientManager_ ? remoteClientManager_->GetBundleManagerHelper() : nullptr;
816+ int32_t uid = -1;
817+ if (bundleMgrHelper != nullptr) {
818+ uid = IN_PROCESS_CALL(bundleMgrHelper->GetUidByBundleName(
819+ want.GetBundle(), GetValidUserId(userId), appIndex));
820+ } else {
821+ TAG_LOGE(AAFwkTag::APPMGR, "bundleMgrHelper null");
822+ }
823+ NotifyMakeImageFailed(uid, errorHandler, ret);
796 }824 }
797}825}
798 826 
@@ -935,6 +963,27 @@ struct HMCheckpointUnMarkS {
935 int32_t pid = -1;963 int32_t pid = -1;
936};964};
937 965 
966+#define CHECKPOINT_ERRMSG_MSG_LEN 256
967+ 
968+enum CheckpointErrorType : int32_t {
969+ CHECKPOINT_ERR_NOERROR = 0,
970+ CHECKPOINT_ERR_BINDER,
971+ CHECKPOINT_ERR_FS,
972+ CHECKPOINT_ERR_NETWORK,
973+ CHECKPOINT_ERR_DRIVER,
974+ CHECKPOINT_ERR_PROCESS,
975+ CHECKPOINT_ERR_UNKNOWN,
976+ CHECKPOINT_ERR_MAX
977+};
978+ 
979+struct HmCheckpointErrMsgS {
980+ pid_t pid;
981+ int32_t type;
982+ char checkpointName[CHECKPOINT_NAME_LEN];
983+ uint32_t errNo;
984+ char msg[CHECKPOINT_ERRMSG_MSG_LEN];
985+};
986+ 
938int32_t AppMgrServiceInner::KillImageProcess(uint64_t checkpointId)987int32_t AppMgrServiceInner::KillImageProcess(uint64_t checkpointId)
939{988{
940 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);989 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
@@ -1038,14 +1087,22 @@ ImageError AppMgrServiceInner::HandleForkAllInner(std::shared_ptr<AppRunningReco
1038 auto errCode = remoteClientManager_->GetSpawnClient()->StartImageProcess(startMsg, imagePid, checkpointId);1087 auto errCode = remoteClientManager_->GetSpawnClient()->StartImageProcess(startMsg, imagePid, checkpointId);
1039 TAG_LOGI(AAFwkTag::APPMGR, "forkall after preload, name:%{public}s, errCode:%{public}d,"1088 TAG_LOGI(AAFwkTag::APPMGR, "forkall after preload, name:%{public}s, errCode:%{public}d,"
1040 " pid:%{public}d, imagePid:%{public}d", appRecord->GetProcessName().c_str(), errCode, pid, imagePid);1089 " pid:%{public}d, imagePid:%{public}d", appRecord->GetProcessName().c_str(), errCode, pid, imagePid);
1041- if (errCode == EBUSY) {
1042- return ImageError::ERR_FORKALL_BUSY;
1043- }
1044 if (errCode != ERR_OK || imagePid <= 0) {1090 if (errCode != ERR_OK || imagePid <= 0) {
1045- return ImageError::ERR_FORKALL_FAILED;1091+ auto imageError = GetCheckpointRestoreError(pid, imageInfo->imageName);
1092+ SaveHyperSnapError(appRecord->GetUid(), HyperSnapErrorType::CREATE_SNAPSHOT,
1093+ ConvertImageErrorToHyperSnapCode(imageError));
1094+ 
1095+ if (errCode == EBUSY) {
1096+ return ImageError::ERR_FORKALL_BUSY;
1097+ } else {
1098+ return ImageError::ERR_FORKALL_FAILED;
1099+ }
1046 }1100 }
1047 appRecord->SetMakeImageState(MakeImageState::MAKE_IMAGE_FINISH);1101 appRecord->SetMakeImageState(MakeImageState::MAKE_IMAGE_FINISH);
1048 UpdateImageInfo(imagePid, checkpointId, appRecord);1102 UpdateImageInfo(imagePid, checkpointId, appRecord);
1103+ 
1104+ ClearHyperSnapError(appRecord->GetUid(), HyperSnapErrorType::CREATE_SNAPSHOT);
1105+ 
1049 std::string taskName = std::string(MAKE_IMAGE_TIMEOUT_EVENT) + std::to_string(imageInfo->imageInfoId);1106 std::string taskName = std::string(MAKE_IMAGE_TIMEOUT_EVENT) + std::to_string(imageInfo->imageInfoId);
1050 TAG_LOGI(AAFwkTag::APPMGR, "cancel task:%{public}s", taskName.c_str());1107 TAG_LOGI(AAFwkTag::APPMGR, "cancel task:%{public}s", taskName.c_str());
1051 AAFwk::TaskHandlerWrap::GetFfrtHandler()->CancelTask(taskName);1108 AAFwk::TaskHandlerWrap::GetFfrtHandler()->CancelTask(taskName);
@@ -1131,7 +1188,7 @@ void AppMgrServiceInner::HandleMakeImageFailed(const std::string& bundleName, co
1131 }1188 }
1132 UnMarkTemplateProcess(imageInfo->templatePid);1189 UnMarkTemplateProcess(imageInfo->templatePid);
1133 RemoveImageInfo(bundleName, abilityName, userId, appIndex);1190 RemoveImageInfo(bundleName, abilityName, userId, appIndex);
1134- NotifyImageOperationFailed(imageInfo->errorHandler, err);1191+ NotifyMakeImageFailed(imageInfo->bundleInfo.uid, imageInfo->errorHandler, err);
1135}1192}
1136 1193 
1137int32_t AppMgrServiceInner::PreAddImageInfo(const std::string& bundleName, int32_t userId, int32_t appIndex,1194int32_t AppMgrServiceInner::PreAddImageInfo(const std::string& bundleName, int32_t userId, int32_t appIndex,
@@ -1526,6 +1583,10 @@ int32_t AppMgrServiceInner::TryToUseImageInfo(std::shared_ptr<AbilityInfo> abili
1526 appRecord = CreateAppRunningRecordFromImageInfo(imageInfo);1583 appRecord = CreateAppRunningRecordFromImageInfo(imageInfo);
1527 if (appRecord == nullptr) {1584 if (appRecord == nullptr) {
1528 SnapshotErrorReport(appInfo->uid, appInfo->bundleName, appInfo->versionName, -1, "appRecord not exist");1585 SnapshotErrorReport(appInfo->uid, appInfo->bundleName, appInfo->versionName, -1, "appRecord not exist");
1586+ 
1587+ SaveHyperSnapError(appInfo->uid, HyperSnapErrorType::FORK_FROM_SNAPSHOT, HyperSnapErrorCode::ERR_SYSTEM_INNER);
zhangtao
zhangtaozhangtao8 天前

这个错误还得确认下是否是inner

likedislike
zhangtao
zhangtao
6 天前 评论:
1588+ TAG_LOGE(AAFwkTag::APPMGR, "Saved FORK_FROM_SNAPSHOT error: CreateAppRunningRecordFromImageInfo failed");
1589+ 
1529 return ERR_OK;1590 return ERR_OK;
1530 }1591 }
1531 int32_t workPid = -1;1592 int32_t workPid = -1;
@@ -1552,10 +1613,17 @@ int32_t AppMgrServiceInner::TryToUseImageInfo(std::shared_ptr<AbilityInfo> abili
1552 appRunningManager_->RemoveAppRunningRecordById(appRecord->GetRecordId());1613 appRunningManager_->RemoveAppRunningRecordById(appRecord->GetRecordId());
1553 appRecord = nullptr;1614 appRecord = nullptr;
1554 SnapshotErrorReport(-1, appInfo->bundleName, appInfo->versionName, errCode, "forkall failed");1615 SnapshotErrorReport(-1, appInfo->bundleName, appInfo->versionName, errCode, "forkall failed");
1616+ 
1617+ auto imageError = GetCheckpointRestoreError(imageInfo->imagePid, imageInfo->imageName);
1618+ SaveHyperSnapError(appInfo->uid, HyperSnapErrorType::FORK_FROM_SNAPSHOT, ConvertImageErrorToHyperSnapCode(imageError));
1619+ 
1555 return ERR_OK;1620 return ERR_OK;
1556 }1621 }
1557 TAG_LOGI(AAFwkTag::APPMGR, "fork from image success, imagePid:%{public}d, workpid:%{public}d", imageInfo->imagePid,1622 TAG_LOGI(AAFwkTag::APPMGR, "fork from image success, imagePid:%{public}d, workpid:%{public}d", imageInfo->imagePid,
1558 workPid);1623 workPid);
1624+ 
1625+ ClearHyperSnapError(appInfo->uid, HyperSnapErrorType::FORK_FROM_SNAPSHOT);
1626+ 
1559 std::string key = std::to_string(workPid) + ":" + std::to_string(appRecord->GetUid());1627 std::string key = std::to_string(workPid) + ":" + std::to_string(appRecord->GetUid());
1560 KillingProcessManager::GetInstance().RemoveKillingCallerKey(key);1628 KillingProcessManager::GetInstance().RemoveKillingCallerKey(key);
1561 OnAppStateChanged(appRecord, ApplicationState::APP_STATE_CREATE, false, false, false);1629 OnAppStateChanged(appRecord, ApplicationState::APP_STATE_CREATE, false, false, false);
@@ -3630,6 +3698,7 @@ int32_t AppMgrServiceInner::NotifyUninstallOrUpgradeApp(const std::string &bundl
3630 InsertUninstallOrUpgradeUidSet(uid);3698 InsertUninstallOrUpgradeUidSet(uid);
3631 auto ret = KillApplicationByUid(bundleName, uid, killReason);3699 auto ret = KillApplicationByUid(bundleName, uid, killReason);
3632 DestroyImageForUninstallOrUpgrade(uid);3700 DestroyImageForUninstallOrUpgrade(uid);
3701+ ClearHyperSnapError(uid);
3633 return ret;3702 return ret;
3634}3703}
3635 3704 
@@ -13354,5 +13423,214 @@ void AppMgrServiceInner::CancelDelayedExitTask(int32_t pid)
13354 }13423 }
13355 }13424 }
13356}13425}
13426+ 
13427+HyperSnapErrorCode AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError imageError)
13428+{
13429+ switch (imageError) {
13430+ case ImageError::ERR_OK:
13431+ return HyperSnapErrorCode::ERR_OK;
13432+ case ImageError::ERR_TEMPLATE_HAS_BEEN_USED:
13433+ return HyperSnapErrorCode::ERR_SNAPSHOT_IS_INTERRUPTED;
13434+ case ImageError::ERR_IMAGE_INFO_EXIST:
13435+ return HyperSnapErrorCode::ERR_SNAPSHOT_EXIST;
13436+ case ImageError::ERR_TEMPLATE_DIED:
13437+ return HyperSnapErrorCode::ERR_SNAPSHOT_PROCESS_IS_DIED;
13438+ case ImageError::ERR_APP_RECORD_EXIST:
13439+ return HyperSnapErrorCode::ERR_PROCESS_IS_RUNNING;
13440+ case ImageError::ERR_EXISTS_ILLEGAL_BINDER:
13441+ return HyperSnapErrorCode::ERR_EXISTS_ILLEGAL_BINDER;
13442+ case ImageError::ERR_LAST_PROCESS_NOT_FULLY_EXITED:
13443+ return HyperSnapErrorCode::ERR_LAST_PROCESS_NOT_FULLY_EXITED;
13444+ default:
13445+ return HyperSnapErrorCode::ERR_SYSTEM_INNER;
13446+ }
13447+}
13448+ 
13449+std::string AppMgrServiceInner::GetHyperSnapErrorMessage(HyperSnapErrorCode code)
13450+{
13451+ switch (code) {
13452+ case HyperSnapErrorCode::ERR_OK:
13453+ return "No error";
13454+ case HyperSnapErrorCode::ERR_SYSTEM_INNER:
13455+ return "System internal error";
13456+ case HyperSnapErrorCode::ERR_SNAPSHOT_EXIST:
13457+ return "Snapshot already exists";
13458+ case HyperSnapErrorCode::ERR_PROCESS_IS_RUNNING:
13459+ return "Process is running";
13460+ case HyperSnapErrorCode::ERR_SNAPSHOT_PROCESS_IS_DIED:
13461+ return "Snapshot process died";
13462+ case HyperSnapErrorCode::ERR_SNAPSHOT_IS_INTERRUPTED:
13463+ return "Snapshot interrupted";
13464+ case HyperSnapErrorCode::ERR_EXISTS_ILLEGAL_BINDER:
13465+ return "Illegal binder exists";
13466+ case HyperSnapErrorCode::ERR_LAST_PROCESS_NOT_FULLY_EXITED:
13467+ return "Last process not fully exited";
13468+ default:
13469+ return "Unknown error";
13470+ }
13471+}
13472+ 
13473+ImageError AppMgrServiceInner::GetCheckpointRestoreError(pid_t pid, const std::string &checkpointName)
13474+{
13475+ if (pid < 0) {
13476+ TAG_LOGE(AAFwkTag::APPMGR, "GetCheckpointRestoreError invalid pid: %{public}d", pid);
13477+ return ImageError::ERR_INNER;
13478+ }
13479+ 
13480+ int fd = open(TEMPLATE_MONITOR_PATH, O_RDWR, 0);
13481+ if (fd < 0) {
13482+ TAG_LOGE(AAFwkTag::APPMGR, "GetCheckpointRestoreError open file fail: %{public}s", strerror(errno));
13483+ return ImageError::ERR_INNER;
13484+ }
13485+ 
13486+ struct HmCheckpointErrMsgS errMsg {
13487+ .pid = pid,
13488+ .type = CHECKPOINT_MONITOR_APP_TYPE
13489+ };
13490+ int32_t beginIndex = static_cast<int32_t>(checkpointName.size() - (CHECKPOINT_NAME_LEN - 1));
13491+ beginIndex = beginIndex > 0 ? beginIndex : 0;
13492+ std::size_t length = checkpointName.copy(errMsg.checkpointName, CHECKPOINT_NAME_LEN - 1, beginIndex);
13493+ errMsg.checkpointName[length] = '\0';
13494+ 
13495+ int ret = ioctl(fd, CHECKPOINT_IOCTL_GET_LAST_ERROR, &errMsg);
13496+ if (ret < 0) {
13497+ close(fd);
13498+ TAG_LOGE(AAFwkTag::APPMGR, "GetCheckpointRestoreError ioctl error: %{public}s", strerror(errno));
13499+ return ImageError::ERR_INNER;
13500+ }
13501+ close(fd);
13502+ 
13503+ ImageError imageError = ImageError::ERR_INNER;
13504+ switch (errMsg.errNo) {
13505+ case CheckpointErrorType::CHECKPOINT_ERR_BINDER:
13506+ imageError = ImageError::ERR_EXISTS_ILLEGAL_BINDER;
13507+ break;
13508+ case CheckpointErrorType::CHECKPOINT_ERR_PROCESS:
13509+ imageError = ImageError::ERR_LAST_PROCESS_NOT_FULLY_EXITED;
13510+ break;
13511+ default:
13512+ imageError = ImageError::ERR_INNER;
13513+ break;
13514+ }
13515+ TAG_LOGE(AAFwkTag::APPMGR, "Kernel checkpoint error, pid:%{public}d, error:%{public}d, msg:%{public}s",
13516+ pid, static_cast<int32_t>(imageError), errMsg.msg);
13517+ 
13518+ return imageError;
13519+}
13520+ 
13521+void AppMgrServiceInner::SaveHyperSnapError(int32_t uid, HyperSnapErrorType errType, HyperSnapErrorCode code)
13522+{
13523+ if (errType != HyperSnapErrorType::CREATE_SNAPSHOT && errType != HyperSnapErrorType::FORK_FROM_SNAPSHOT) {
13524+ TAG_LOGE(AAFwkTag::APPMGR, "SaveHyperSnapError invalid error type: %{public}d",
13525+ static_cast<int32_t>(errType));
13526+ return;
13527+ }
13528+ 
13529+ if (uid < 0) {
13530+ TAG_LOGE(AAFwkTag::APPMGR, "SaveHyperSnapError invalid uid: %{public}d", uid);
13531+ return;
13532+ }
13533+ 
13534+ int64_t timeStamp = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::
13535+ system_clock::now().time_since_epoch()).count();
13536+ 
13537+ std::lock_guard<std::mutex> lock(hyperSnapErrorMutex_);
13538+ switch (errType) {
13539+ case HyperSnapErrorType::CREATE_SNAPSHOT:
13540+ createSnapshotErrorMap_[uid] = { code, timeStamp };
13541+ TAG_LOGD(AAFwkTag::APPMGR, "Saved CREATE_SNAPSHOT error, uid: %{public}d, code: %{public}d",
13542+ uid, static_cast<int32_t>(code));
13543+ break;
13544+ case HyperSnapErrorType::FORK_FROM_SNAPSHOT:
13545+ forkFromSnapshotErrorMap_[uid] = { code, timeStamp };
13546+ TAG_LOGD(AAFwkTag::APPMGR, "Saved FORK_FROM_SNAPSHOT error, uid: %{public}d, code: %{public}d",
13547+ uid, static_cast<int32_t>(code));
13548+ break;
13549+ default:
13550+ break;
13551+ }
13552+}
13553+ 
13554+bool AppMgrServiceInner::GetHyperSnapLastError(HyperSnapErrorType errType, HyperSnapErrorRecord& record)
13555+{
13556+ HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);
13557+ if (errType != HyperSnapErrorType::CREATE_SNAPSHOT && errType != HyperSnapErrorType::FORK_FROM_SNAPSHOT) {
jsjzju
jsjzjujsjzju9 天前

函数入口加hitrace

likedislike
zhangtao
zhangtao
9 天前 评论:
13558+ TAG_LOGE(AAFwkTag::APPMGR, "GetHyperSnapLastError invalid error type: %{public}d",
13559+ static_cast<int32_t>(errType));
13560+ return false;
13561+ }
13562+ 
13563+ auto uid = IPCSkeleton::GetCallingUid();
13564+ if (uid < 0) {
13565+ TAG_LOGE(AAFwkTag::APPMGR, "GetHyperSnapLastError invalid uid: %{public}d", uid);
13566+ return false;
13567+ }
13568+ 
13569+ TAG_LOGD(AAFwkTag::APPMGR, "GetHyperSnapLastError uid: %{public}d, type: %{public}d",
13570+ uid, static_cast<int32_t>(errType));
13571+ 
13572+ std::lock_guard<std::mutex> lock(hyperSnapErrorMutex_);
13573+ auto& map = (errType == HyperSnapErrorType::CREATE_SNAPSHOT)
13574+ ? createSnapshotErrorMap_
13575+ : forkFromSnapshotErrorMap_;
13576+ auto it = map.find(uid);
13577+ 
13578+ if (it != map.end()) {
13579+ record.code = it->second.code;
13580+ record.msg = GetHyperSnapErrorMessage(it->second.code);
13581+ record.occurTimeStamp = it->second.occurTimeStamp;
13582+ TAG_LOGD(AAFwkTag::APPMGR, "Found error record, uid: %{public}d, code: %{public}d",
13583+ uid, static_cast<int32_t>(record.code));
13584+ } else {
13585+ record.code = HyperSnapErrorCode::ERR_OK;
13586+ record.msg = GetHyperSnapErrorMessage(HyperSnapErrorCode::ERR_OK);
13587+ record.occurTimeStamp = 0;
13588+ TAG_LOGD(AAFwkTag::APPMGR, "No error record found, uid: %{public}d", uid);
13589+ }
13590+ 
13591+ return true;
13592+}
13593+ 
13594+void AppMgrServiceInner::ClearHyperSnapError(int32_t uid, HyperSnapErrorType errType)
13595+{
13596+ if (errType != HyperSnapErrorType::CREATE_SNAPSHOT && errType != HyperSnapErrorType::FORK_FROM_SNAPSHOT) {
13597+ TAG_LOGE(AAFwkTag::APPMGR, "ClearHyperSnapError invalid error type: %{public}d",
13598+ static_cast<int32_t>(errType));
13599+ return;
13600+ }
13601+ 
13602+ if (uid < 0) {
13603+ TAG_LOGE(AAFwkTag::APPMGR, "ClearHyperSnapError invalid uid: %{public}d", uid);
13604+ return;
13605+ }
13606+ 
13607+ std::lock_guard<std::mutex> lock(hyperSnapErrorMutex_);
13608+ switch (errType) {
13609+ case HyperSnapErrorType::CREATE_SNAPSHOT:
13610+ createSnapshotErrorMap_.erase(uid);
13611+ TAG_LOGD(AAFwkTag::APPMGR, "Cleared CREATE_SNAPSHOT error, uid: %{public}d", uid);
13612+ break;
13613+ case HyperSnapErrorType::FORK_FROM_SNAPSHOT:
13614+ forkFromSnapshotErrorMap_.erase(uid);
13615+ TAG_LOGD(AAFwkTag::APPMGR, "Cleared FORK_FROM_SNAPSHOT error, uid: %{public}d", uid);
13616+ break;
13617+ default:
13618+ break;
13619+ }
13620+}
13621+ 
13622+void AppMgrServiceInner::ClearHyperSnapError(int32_t uid)
13623+{
13624+ if (uid < 0) {
13625+ TAG_LOGE(AAFwkTag::APPMGR, "ClearHyperSnapError invalid uid: %{public}d", uid);
13626+ return;
13627+ }
13628+ 
13629+ TAG_LOGD(AAFwkTag::APPMGR, "ClearHyperSnapError uid: %{public}d", uid);
13630+ 
13631+ std::lock_guard<std::mutex> lock(hyperSnapErrorMutex_);
13632+ createSnapshotErrorMap_.erase(uid);
13633+ forkFromSnapshotErrorMap_.erase(uid);
13634+}
13357} // namespace AppExecFwk13635} // namespace AppExecFwk
13358} // namespace OHOS13636} // namespace OHOS
@@ -157,6 +157,7 @@ public:
157 MOCK_METHOD2(DumpMem, int32_t(MemDumpInfo &info, sptr<IMemDumpCallback> callback));157 MOCK_METHOD2(DumpMem, int32_t(MemDumpInfo &info, sptr<IMemDumpCallback> callback));
158 MOCK_METHOD2(ReportDumpMemResult, int32_t(sptr<IMemDumpCallback>, const std::string&));158 MOCK_METHOD2(ReportDumpMemResult, int32_t(sptr<IMemDumpCallback>, const std::string&));
159 MOCK_METHOD1(DumpJsHandleMap, int32_t(OHOS::AppExecFwk::JsHandleMapInfo &));159 MOCK_METHOD1(DumpJsHandleMap, int32_t(OHOS::AppExecFwk::JsHandleMapInfo &));
160+ MOCK_METHOD2(GetHyperSnapLastError, int32_t(int32_t errType, HyperSnapErrorRecord &record));
160 virtual int StartUserTestProcess(161 virtual int StartUserTestProcess(
161 const AAFwk::Want &want, const sptr<IRemoteObject> &observer, const BundleInfo &bundleInfo, int32_t userId)162 const AAFwk::Want &want, const sptr<IRemoteObject> &observer, const BundleInfo &bundleInfo, int32_t userId)
162 {163 {
@@ -2028,5 +2028,44 @@ HWTEST_F(AppMgrClientTest, CancelDelayedExitTask_002, TestSize.Level2)
2028 int32_t pid = 1234;2028 int32_t pid = 1234;
2029 appMgrClient->CancelDelayedExitTask(pid);2029 appMgrClient->CancelDelayedExitTask(pid);
2030}2030}
2031+ 
2032+/**
2033+ * @tc.name: GetHyperSnapLastError_0100
2034+ * @tc.desc: get last hyper snap error without connecting service returns not connected.
2035+ * @tc.type: FUNC
2036+ */
2037+HWTEST_F(AppMgrClientTest, GetHyperSnapLastError_0100, TestSize.Level2)
2038+{
2039+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0100 start");
2040+ AAFwk::IsMockSaCall::IsMockSpecificSystemAbilityAccessPermission();
2041+ auto appMgrClient = std::make_unique<AppMgrClient>();
2042+ ASSERT_NE(appMgrClient, nullptr);
2043+ 
2044+ HyperSnapErrorRecord record;
2045+ record.code = HyperSnapErrorCode::ERR_OK;
2046+ int32_t result = appMgrClient->GetHyperSnapLastError(
2047+ static_cast<int32_t>(HyperSnapErrorType::CREATE_SNAPSHOT), record);
2048+ EXPECT_EQ(result, AppMgrResultCode::ERROR_SERVICE_NOT_CONNECTED);
2049+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_OK);
2050+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0100 end");
2051+}
2052+ 
2053+/**
2054+ * @tc.name: GetHyperSnapLastError_0200
2055+ * @tc.desc: client passes errType through without local validation when service is unreachable.
2056+ * @tc.type: FUNC
2057+ */
2058+HWTEST_F(AppMgrClientTest, GetHyperSnapLastError_0200, TestSize.Level2)
2059+{
2060+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0200 start");
2061+ AAFwk::IsMockSaCall::IsMockSpecificSystemAbilityAccessPermission();
2062+ auto appMgrClient = std::make_unique<AppMgrClient>();
2063+ ASSERT_NE(appMgrClient, nullptr);
2064+ 
2065+ HyperSnapErrorRecord record;
2066+ int32_t result = appMgrClient->GetHyperSnapLastError(99, record);
2067+ EXPECT_EQ(result, AppMgrResultCode::ERROR_SERVICE_NOT_CONNECTED);
2068+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0200 end");
2069+}
2031} // namespace AppExecFwk2070} // namespace AppExecFwk
2032} // namespace OHOS2071} // namespace OHOS
@@ -1776,5 +1776,99 @@ HWTEST_F(AppMgrProxyTest, AppMgrProxy_ReportDumpMemResult_002, TestSize.Level1)
1776 EXPECT_EQ(mockAppMgrService_->code_, static_cast<uint32_t>(AppMgrInterfaceCode::REPORT_DUMP_MEM_RESULT));1776 EXPECT_EQ(mockAppMgrService_->code_, static_cast<uint32_t>(AppMgrInterfaceCode::REPORT_DUMP_MEM_RESULT));
1777}1777}
1778 1778 
1779+/**
1780+ * @tc.name: AppMgrProxy_GetHyperSnapLastError_0100
1781+ * @tc.desc: GetHyperSnapLastError sends the correct interface code with errType.
1782+ * @tc.type: FUNC
1783+ */
1784+HWTEST_F(AppMgrProxyTest, AppMgrProxy_GetHyperSnapLastError_0100, TestSize.Level1)
1785+{
1786+ GTEST_LOG_(INFO) << "AppMgrProxy_GetHyperSnapLastError_0100 start";
1787+ 
1788+ EXPECT_CALL(*mockAppMgrService_, SendRequest(_, _, _, _))
1789+ .Times(1)
1790+ .WillOnce(Invoke(mockAppMgrService_.GetRefPtr(), &MockAppMgrService::InvokeSendRequest));
1791+ 
1792+ HyperSnapErrorRecord record;
1793+ appMgrProxy_->GetHyperSnapLastError(static_cast<int32_t>(HyperSnapErrorType::CREATE_SNAPSHOT), record);
1794+ 
1795+ EXPECT_EQ(mockAppMgrService_->code_, static_cast<uint32_t>(AppMgrInterfaceCode::GET_HYPER_SNAP_LAST_ERROR));
1796+ 
1797+ GTEST_LOG_(INFO) << "AppMgrProxy_GetHyperSnapLastError_0100 end";
1798+}
1799+ 
1800+/**
1801+ * @tc.name: AppMgrProxy_GetHyperSnapLastError_0200
1802+ * @tc.desc: GetHyperSnapLastError tolerates an empty reply from the service side.
1803+ * @tc.type: FUNC
1804+ */
1805+HWTEST_F(AppMgrProxyTest, AppMgrProxy_GetHyperSnapLastError_0200, TestSize.Level2)
1806+{
1807+ GTEST_LOG_(INFO) << "AppMgrProxy_GetHyperSnapLastError_0200 start";
1808+ 
1809+ EXPECT_CALL(*mockAppMgrService_, SendRequest(_, _, _, _))
1810+ .Times(1)
1811+ .WillOnce(Invoke(mockAppMgrService_.GetRefPtr(), &MockAppMgrService::InvokeSendRequest));
1812+ 
1813+ HyperSnapErrorRecord record;
1814+ int32_t result = appMgrProxy_->GetHyperSnapLastError(static_cast<int32_t>(HyperSnapErrorType::FORK_FROM_SNAPSHOT),
1815+ record);
1816+ EXPECT_NE(result, ERR_OK);
1817+ 
1818+ GTEST_LOG_(INFO) << "AppMgrProxy_GetHyperSnapLastError_0200 end";
1819+}
1820+ 
1821+/**
1822+ * @tc.name: AppMgrProxy_GetHyperSnapLastError_0300
1823+ * @tc.desc: GetHyperSnapLastError goes through the real stub handler and returns a default record.
1824+ * @tc.type: FUNC
1825+ */
1826+HWTEST_F(AppMgrProxyTest, AppMgrProxy_GetHyperSnapLastError_0300, TestSize.Level1)
1827+{
1828+ GTEST_LOG_(INFO) << "AppMgrProxy_GetHyperSnapLastError_0300 start";
1829+ 
1830+ // Dispatch the proxy request to the real stub: data already carries the interface token,
1831+ // HandleGetHyperSnapLastError falls back to the stub default (ERR_OK, default record).
1832+ EXPECT_CALL(*mockAppMgrService_, SendRequest(_, _, _, _))
1833+ .Times(1)
1834+ .WillOnce(Invoke(mockAppMgrService_.GetRefPtr(), &AppMgrStub::OnRemoteRequest));
1835+ 
1836+ HyperSnapErrorRecord record;
1837+ int32_t result = appMgrProxy_->GetHyperSnapLastError(static_cast<int32_t>(HyperSnapErrorType::CREATE_SNAPSHOT),
1838+ record);
1839+ EXPECT_EQ(result, ERR_OK);
1840+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_OK);
1841+ EXPECT_EQ(mockAppMgrService_->code_, static_cast<uint32_t>(AppMgrInterfaceCode::GET_HYPER_SNAP_LAST_ERROR));
1842+ 
1843+ GTEST_LOG_(INFO) << "AppMgrProxy_GetHyperSnapLastError_0300 end";
1844+}
1845+ 
1846+/**
1847+ * @tc.name: AppMgrProxy_GetHyperSnapLastError_0400
1848+ * @tc.desc: GetHyperSnapLastError returns early when the service replies a failure result.
1849+ * @tc.type: FUNC
1850+ */
1851+HWTEST_F(AppMgrProxyTest, AppMgrProxy_GetHyperSnapLastError_0400, TestSize.Level2)
1852+{
1853+ GTEST_LOG_(INFO) << "AppMgrProxy_GetHyperSnapLastError_0400 start";
1854+ 
1855+ EXPECT_CALL(*mockAppMgrService_, SendRequest(_, _, _, _))
1856+ .Times(1)
1857+ .WillOnce(Invoke([](uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) {
1858+ (void)code;
1859+ (void)data;
1860+ (void)option;
1861+ (void)reply.WriteInt32(ERR_INVALID_VALUE);
1862+ return 0;
1863+ }));
1864+ 
1865+ HyperSnapErrorRecord record;
1866+ int32_t result = appMgrProxy_->GetHyperSnapLastError(static_cast<int32_t>(HyperSnapErrorType::FORK_FROM_SNAPSHOT),
1867+ record);
1868+ EXPECT_EQ(result, ERR_INVALID_VALUE);
1869+ 
1870+ GTEST_LOG_(INFO) << "AppMgrProxy_GetHyperSnapLastError_0400 end";
1871+}
1872+ 
1779} // namespace AppExecFwk1873} // namespace AppExecFwk
1780} // namespace OHOS1874} // namespace OHOS
@@ -359,5 +359,51 @@ HWTEST_F(AppMgrServiceFourthTest, GetAllAbilityInfos_002, TestSize.Level1)
359 EXPECT_EQ(result, ERR_PERMISSION_DENIED);359 EXPECT_EQ(result, ERR_PERMISSION_DENIED);
360 TAG_LOGI(AAFwkTag::TEST, "GetAllAbilityInfos_002 end");360 TAG_LOGI(AAFwkTag::TEST, "GetAllAbilityInfos_002 end");
361}361}
362+ 
363+/**
364+ * @tc.name: GetHyperSnapLastError_0100
365+ * @tc.desc: test GetHyperSnapLastError returns ERR_INVALID_OPERATION when service is not ready
366+ * @tc.type: FUNC
367+ */
368+HWTEST_F(AppMgrServiceFourthTest, GetHyperSnapLastError_0100, TestSize.Level2)
369+{
370+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0100 start");
371+ appMgrService_->eventHandler_ = nullptr;
372+ HyperSnapErrorRecord record;
373+ EXPECT_EQ(appMgrService_->GetHyperSnapLastError(
374+ static_cast<int32_t>(HyperSnapErrorType::CREATE_SNAPSHOT), record), ERR_INVALID_OPERATION);
375+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0100 end");
376+}
377+ 
378+/**
379+ * @tc.name: GetHyperSnapLastError_0200
380+ * @tc.desc: test GetHyperSnapLastError returns ERR_INVALID_VALUE on invalid error type
381+ * @tc.type: FUNC
382+ */
383+HWTEST_F(AppMgrServiceFourthTest, GetHyperSnapLastError_0200, TestSize.Level2)
384+{
385+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0200 start");
386+ HyperSnapErrorRecord record;
387+ EXPECT_EQ(appMgrService_->GetHyperSnapLastError(99, record), ERR_INVALID_VALUE);
388+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0200 end");
389+}
390+ 
391+/**
392+ * @tc.name: GetHyperSnapLastError_0300
393+ * @tc.desc: test GetHyperSnapLastError returns ERR_OK and fills defaults when no error saved
394+ * @tc.type: FUNC
395+ */
396+HWTEST_F(AppMgrServiceFourthTest, GetHyperSnapLastError_0300, TestSize.Level1)
397+{
398+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0300 start");
399+ IPCSkeleton::SetCallingUid(UID);
400+ HyperSnapErrorRecord record;
401+ EXPECT_EQ(appMgrService_->GetHyperSnapLastError(
402+ static_cast<int32_t>(HyperSnapErrorType::FORK_FROM_SNAPSHOT), record), ERR_OK);
403+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_OK);
404+ EXPECT_EQ(record.msg, "No error");
405+ IPCSkeleton::SetCallingUid(0);
406+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0300 end");
407+}
362} // namespace AppExecFwk408} // namespace AppExecFwk
363} // namespace OHOS409} // namespace OHOS
@@ -14,11 +14,14 @@
14 */14 */
15 15 
16#include <gtest/gtest.h>16#include <gtest/gtest.h>
17+#include <gmock/gmock.h>
17#define private public18#define private public
18#include "app_mgr_service_inner.h"19#include "app_mgr_service_inner.h"
19#include "app_running_record.h"20#include "app_running_record.h"
20#include "app_spawn_client.h"21#include "app_spawn_client.h"
21#include "app_utils.h"22#include "app_utils.h"
23+#include "hyper_snap_error_record.h"
24+#include "image_error_handler_stub.h"
22#include "render_record.h"25#include "render_record.h"
23#include "child_process_record.h"26#include "child_process_record.h"
24#include "cache_process_manager.h"27#include "cache_process_manager.h"
@@ -39,6 +42,7 @@ constexpr int32_t QUICKFIX_UID = 5524;
39constexpr int32_t SHADER_CACHE_GROUPID = 3099;42constexpr int32_t SHADER_CACHE_GROUPID = 3099;
40constexpr int32_t RESOURCE_MANAGER_UID = 1096;43constexpr int32_t RESOURCE_MANAGER_UID = 1096;
41constexpr int32_t DEFAULT_USER_ID = 0;44constexpr int32_t DEFAULT_USER_ID = 0;
45+constexpr int32_t TEST_UID = 10001;
42static int g_scheduleLoadChildCall = 0;46static int g_scheduleLoadChildCall = 0;
43 47 
44namespace OHOS {48namespace OHOS {
@@ -4030,5 +4034,693 @@ HWTEST_F(AppMgrServiceInnerEighthTest, TryToUseImageInfo_NotifyAppRunningStatusE
4030 4034
4031 TAG_LOGI(AAFwkTag::TEST, "TryToUseImageInfo_NotifyAppRunningStatusEvent_001 end");4035 TAG_LOGI(AAFwkTag::TEST, "TryToUseImageInfo_NotifyAppRunningStatusEvent_001 end");
4032}4036}
4037+ 
4038+class MockImageErrorHandlerStub : public ImageErrorHandlerStub {
4039+public:
4040+ MockImageErrorHandlerStub() = default;
4041+ virtual ~MockImageErrorHandlerStub() = default;
4042+ 
4043+ MOCK_METHOD1(OnError, void(int32_t errCode));
4044+};
4045+ 
4046+/**
4047+ * @tc.name: NotifyImageOperationFailed_ShouldReturn_1WhenErrorHandleIsNullptr
4048+ * @tc.desc: Test NotifyImageOperationFailed
4049+ * @tc.type: FUNC
4050+ */
4051+HWTEST_F(AppMgrServiceInnerEighthTest, NotifyImageOperationFailed_ShouldReturn_1WhenErrorHandleIsNullptr,
4052+ TestSize.Level1)
4053+{
4054+ TAG_LOGI(AAFwkTag::TEST, "NotifyImageOperationFailed_ShouldReturn_1WhenErrorHandleIsNullptr start");
4055+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4056+ EXPECT_NE(appMgrServiceInner, nullptr);
4057+ ImageError errCode = ImageError::ERR_KILL_IMAGE_PROCESS_FAILED;
4058+ EXPECT_EQ(appMgrServiceInner->NotifyImageOperationFailed(nullptr, errCode), -1);
4059+ TAG_LOGI(AAFwkTag::TEST, "NotifyImageOperationFailed_ShouldReturn_1WhenErrorHandleIsNullptr end");
4060+}
4061+ 
4062+/**
4063+ * @tc.name: NotifyImageOperationFailed_ShouldReturnErrOkWhenErrorHandleIsNullptr
4064+ * @tc.desc: Test NotifyImageOperationFailed
4065+ * @tc.type: FUNC
4066+ */
4067+HWTEST_F(AppMgrServiceInnerEighthTest, NotifyImageOperationFailed_ShouldReturnErrOkWhenErrorHandleIsNullptr,
4068+ TestSize.Level1)
4069+{
4070+ TAG_LOGI(AAFwkTag::TEST, "NotifyImageOperationFailed_ShouldReturnErrOkWhenErrorHandleIsNullptr start");
4071+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4072+ EXPECT_NE(appMgrServiceInner, nullptr);
4073+ sptr<MockImageErrorHandlerStub> errHandler = new (std::nothrow) MockImageErrorHandlerStub();
4074+ ImageError errCode = ImageError::ERR_KILL_IMAGE_PROCESS_FAILED;
4075+ EXPECT_CALL(*errHandler, OnError(_)).Times(1);
4076+ EXPECT_EQ(appMgrServiceInner->NotifyImageOperationFailed(errHandler, errCode), ERR_OK);
4077+ TAG_LOGI(AAFwkTag::TEST, "NotifyImageOperationFailed_ShouldReturnErrOkWhenErrorHandleIsNullptr end");
4078+}
4079+ 
4080+/**
4081+ * @tc.name: ConvertImageErrorToHyperSnapCode_0100
4082+ * @tc.desc: test explicit ImageError to HyperSnapErrorCode mappings
4083+ * @tc.type: FUNC
4084+ */
4085+HWTEST_F(AppMgrServiceInnerEighthTest, ConvertImageErrorToHyperSnapCode_0100, TestSize.Level1)
4086+{
4087+ TAG_LOGI(AAFwkTag::TEST, "ConvertImageErrorToHyperSnapCode_0100 start");
4088+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_OK), HyperSnapErrorCode::ERR_OK);
4089+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_TEMPLATE_HAS_BEEN_USED),
4090+ HyperSnapErrorCode::ERR_SNAPSHOT_IS_INTERRUPTED);
4091+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_IMAGE_INFO_EXIST),
4092+ HyperSnapErrorCode::ERR_SNAPSHOT_EXIST);
4093+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_TEMPLATE_DIED),
4094+ HyperSnapErrorCode::ERR_SNAPSHOT_PROCESS_IS_DIED);
4095+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_APP_RECORD_EXIST),
4096+ HyperSnapErrorCode::ERR_PROCESS_IS_RUNNING);
4097+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_EXISTS_ILLEGAL_BINDER),
4098+ HyperSnapErrorCode::ERR_EXISTS_ILLEGAL_BINDER);
4099+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_LAST_PROCESS_NOT_FULLY_EXITED),
4100+ HyperSnapErrorCode::ERR_LAST_PROCESS_NOT_FULLY_EXITED);
4101+ TAG_LOGI(AAFwkTag::TEST, "ConvertImageErrorToHyperSnapCode_0100 end");
4102+}
4103+ 
4104+/**
4105+ * @tc.name: ConvertImageErrorToHyperSnapCode_0200
4106+ * @tc.desc: test default ImageError values fall into ERR_SYSTEM_INNER bucket
4107+ * @tc.type: FUNC
4108+ */
4109+HWTEST_F(AppMgrServiceInnerEighthTest, ConvertImageErrorToHyperSnapCode_0200, TestSize.Level1)
4110+{
4111+ TAG_LOGI(AAFwkTag::TEST, "ConvertImageErrorToHyperSnapCode_0200 start");
4112+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_TIMEOUT),
4113+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4114+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_FORKALL_FAILED),
4115+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4116+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_INVALID_PRELOAD_TYPE),
4117+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4118+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_PRELOAD_FAILED),
4119+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4120+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_IMAGE_INFO_NOT_EXIST),
4121+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4122+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_IMAGE_INFO_NOT_READY),
4123+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4124+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_KILL_IMAGE_PROCESS_FAILED),
4125+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4126+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_INNER),
4127+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4128+ EXPECT_EQ(AppMgrServiceInner::ConvertImageErrorToHyperSnapCode(ImageError::ERR_FORKALL_BUSY),
4129+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4130+ TAG_LOGI(AAFwkTag::TEST, "ConvertImageErrorToHyperSnapCode_0200 end");
4131+}
4132+ 
4133+/**
4134+ * @tc.name: GetHyperSnapErrorMessage_0100
4135+ * @tc.desc: test fixed messages for all HyperSnapErrorCode values
4136+ * @tc.type: FUNC
4137+ */
4138+HWTEST_F(AppMgrServiceInnerEighthTest, GetHyperSnapErrorMessage_0100, TestSize.Level1)
4139+{
4140+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapErrorMessage_0100 start");
4141+ EXPECT_EQ(AppMgrServiceInner::GetHyperSnapErrorMessage(HyperSnapErrorCode::ERR_OK), "No error");
4142+ EXPECT_EQ(AppMgrServiceInner::GetHyperSnapErrorMessage(HyperSnapErrorCode::ERR_SYSTEM_INNER),
4143+ "System internal error");
4144+ EXPECT_EQ(AppMgrServiceInner::GetHyperSnapErrorMessage(HyperSnapErrorCode::ERR_SNAPSHOT_EXIST),
4145+ "Snapshot already exists");
4146+ EXPECT_EQ(AppMgrServiceInner::GetHyperSnapErrorMessage(HyperSnapErrorCode::ERR_PROCESS_IS_RUNNING),
4147+ "Process is running");
4148+ EXPECT_EQ(AppMgrServiceInner::GetHyperSnapErrorMessage(HyperSnapErrorCode::ERR_SNAPSHOT_PROCESS_IS_DIED),
4149+ "Snapshot process died");
4150+ EXPECT_EQ(AppMgrServiceInner::GetHyperSnapErrorMessage(HyperSnapErrorCode::ERR_SNAPSHOT_IS_INTERRUPTED),
4151+ "Snapshot interrupted");
4152+ EXPECT_EQ(AppMgrServiceInner::GetHyperSnapErrorMessage(HyperSnapErrorCode::ERR_EXISTS_ILLEGAL_BINDER),
4153+ "Illegal binder exists");
4154+ EXPECT_EQ(AppMgrServiceInner::GetHyperSnapErrorMessage(HyperSnapErrorCode::ERR_LAST_PROCESS_NOT_FULLY_EXITED),
4155+ "Last process not fully exited");
4156+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapErrorMessage_0100 end");
4157+}
4158+ 
4159+/**
4160+ * @tc.name: GetHyperSnapErrorMessage_0200
4161+ * @tc.desc: test unknown code returns "Unknown error"
4162+ * @tc.type: FUNC
4163+ */
4164+HWTEST_F(AppMgrServiceInnerEighthTest, GetHyperSnapErrorMessage_0200, TestSize.Level2)
4165+{
4166+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapErrorMessage_0200 start");
4167+ auto invalidCode = static_cast<HyperSnapErrorCode>(99);
4168+ EXPECT_EQ(AppMgrServiceInner::GetHyperSnapErrorMessage(invalidCode), "Unknown error");
4169+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapErrorMessage_0200 end");
4170+}
4171+ 
4172+/**
4173+ * @tc.name: SaveHyperSnapError_0100
4174+ * @tc.desc: test save CREATE_SNAPSHOT error and query it back via GetHyperSnapLastError
4175+ * @tc.type: FUNC
4176+ */
4177+HWTEST_F(AppMgrServiceInnerEighthTest, SaveHyperSnapError_0100, TestSize.Level1)
4178+{
4179+ TAG_LOGI(AAFwkTag::TEST, "SaveHyperSnapError_0100 start");
4180+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4181+ ASSERT_NE(appMgrServiceInner, nullptr);
4182+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4183+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::CREATE_SNAPSHOT,
4184+ HyperSnapErrorCode::ERR_SNAPSHOT_PROCESS_IS_DIED);
4185+ HyperSnapErrorRecord record;
4186+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, record));
4187+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_SNAPSHOT_PROCESS_IS_DIED);
4188+ EXPECT_EQ(record.msg, "Snapshot process died");
4189+ EXPECT_GT(record.occurTimeStamp, 0);
4190+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4191+ TAG_LOGI(AAFwkTag::TEST, "SaveHyperSnapError_0100 end");
4192+}
4193+ 
4194+/**
4195+ * @tc.name: SaveHyperSnapError_0200
4196+ * @tc.desc: test negative uid is rejected and nothing is saved
4197+ * @tc.type: FUNC
4198+ */
4199+HWTEST_F(AppMgrServiceInnerEighthTest, SaveHyperSnapError_0200, TestSize.Level2)
4200+{
4201+ TAG_LOGI(AAFwkTag::TEST, "SaveHyperSnapError_0200 start");
4202+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4203+ ASSERT_NE(appMgrServiceInner, nullptr);
4204+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4205+ appMgrServiceInner->SaveHyperSnapError(-1, HyperSnapErrorType::CREATE_SNAPSHOT,
4206+ HyperSnapErrorCode::ERR_SNAPSHOT_EXIST);
4207+ HyperSnapErrorRecord record;
4208+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, record));
4209+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_OK);
4210+ EXPECT_EQ(record.occurTimeStamp, 0);
4211+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4212+ TAG_LOGI(AAFwkTag::TEST, "SaveHyperSnapError_0200 end");
4213+}
4214+ 
4215+/**
4216+ * @tc.name: SaveHyperSnapError_0300
4217+ * @tc.desc: test invalid error type is rejected and nothing is saved
4218+ * @tc.type: FUNC
4219+ */
4220+HWTEST_F(AppMgrServiceInnerEighthTest, SaveHyperSnapError_0300, TestSize.Level2)
4221+{
4222+ TAG_LOGI(AAFwkTag::TEST, "SaveHyperSnapError_0300 start");
4223+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4224+ ASSERT_NE(appMgrServiceInner, nullptr);
4225+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4226+ auto invalidType = static_cast<HyperSnapErrorType>(100);
4227+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, invalidType, HyperSnapErrorCode::ERR_SYSTEM_INNER);
4228+ HyperSnapErrorRecord createRecord;
4229+ HyperSnapErrorRecord forkRecord;
4230+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, createRecord));
4231+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::FORK_FROM_SNAPSHOT, forkRecord));
4232+ EXPECT_EQ(createRecord.code, HyperSnapErrorCode::ERR_OK);
4233+ EXPECT_EQ(forkRecord.code, HyperSnapErrorCode::ERR_OK);
4234+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4235+ TAG_LOGI(AAFwkTag::TEST, "SaveHyperSnapError_0300 end");
4236+}
4237+ 
4238+/**
4239+ * @tc.name: SaveHyperSnapError_0400
4240+ * @tc.desc: test save FORK_FROM_SNAPSHOT error and query it back
4241+ * @tc.type: FUNC
4242+ */
4243+HWTEST_F(AppMgrServiceInnerEighthTest, SaveHyperSnapError_0400, TestSize.Level1)
4244+{
4245+ TAG_LOGI(AAFwkTag::TEST, "SaveHyperSnapError_0400 start");
4246+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4247+ ASSERT_NE(appMgrServiceInner, nullptr);
4248+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4249+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::FORK_FROM_SNAPSHOT,
4250+ HyperSnapErrorCode::ERR_PROCESS_IS_RUNNING);
4251+ HyperSnapErrorRecord record;
4252+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::FORK_FROM_SNAPSHOT, record));
4253+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_PROCESS_IS_RUNNING);
4254+ EXPECT_EQ(record.msg, "Process is running");
4255+ EXPECT_GT(record.occurTimeStamp, 0);
4256+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4257+ TAG_LOGI(AAFwkTag::TEST, "SaveHyperSnapError_0400 end");
4258+}
4259+ 
4260+/**
4261+ * @tc.name: GetHyperSnapLastError_0100
4262+ * @tc.desc: test query with no saved error returns defaults
4263+ * @tc.type: FUNC
4264+ */
4265+HWTEST_F(AppMgrServiceInnerEighthTest, GetHyperSnapLastError_0100, TestSize.Level1)
4266+{
4267+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0100 start");
4268+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4269+ ASSERT_NE(appMgrServiceInner, nullptr);
4270+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4271+ HyperSnapErrorRecord record;
4272+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::FORK_FROM_SNAPSHOT, record));
4273+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_OK);
4274+ EXPECT_EQ(record.msg, "No error");
4275+ EXPECT_EQ(record.occurTimeStamp, 0);
4276+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4277+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0100 end");
4278+}
4279+ 
4280+/**
4281+ * @tc.name: GetHyperSnapLastError_0200
4282+ * @tc.desc: test saved FORK_FROM_SNAPSHOT error is queried back with derived msg
4283+ * @tc.type: FUNC
4284+ */
4285+HWTEST_F(AppMgrServiceInnerEighthTest, GetHyperSnapLastError_0200, TestSize.Level1)
4286+{
4287+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0200 start");
4288+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4289+ ASSERT_NE(appMgrServiceInner, nullptr);
4290+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4291+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::FORK_FROM_SNAPSHOT,
4292+ HyperSnapErrorCode::ERR_LAST_PROCESS_NOT_FULLY_EXITED);
4293+ HyperSnapErrorRecord record;
4294+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::FORK_FROM_SNAPSHOT, record));
4295+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_LAST_PROCESS_NOT_FULLY_EXITED);
4296+ EXPECT_EQ(record.msg, "Last process not fully exited");
4297+ EXPECT_GT(record.occurTimeStamp, 0);
4298+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4299+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0200 end");
4300+}
4301+ 
4302+/**
4303+ * @tc.name: GetHyperSnapLastError_0300
4304+ * @tc.desc: test invalid error type returns false
4305+ * @tc.type: FUNC
4306+ */
4307+HWTEST_F(AppMgrServiceInnerEighthTest, GetHyperSnapLastError_0300, TestSize.Level2)
4308+{
4309+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0300 start");
4310+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4311+ ASSERT_NE(appMgrServiceInner, nullptr);
4312+ HyperSnapErrorRecord record;
4313+ auto invalidType = static_cast<HyperSnapErrorType>(-1);
4314+ EXPECT_FALSE(appMgrServiceInner->GetHyperSnapLastError(invalidType, record));
4315+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0300 end");
4316+}
4317+ 
4318+/**
4319+ * @tc.name: GetHyperSnapLastError_0400
4320+ * @tc.desc: test negative calling uid returns false
4321+ * @tc.type: FUNC
4322+ */
4323+HWTEST_F(AppMgrServiceInnerEighthTest, GetHyperSnapLastError_0400, TestSize.Level2)
4324+{
4325+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0400 start");
4326+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4327+ ASSERT_NE(appMgrServiceInner, nullptr);
4328+ AAFwk::MyStatus::GetInstance().getCallingUid_ = -1;
4329+ HyperSnapErrorRecord record;
4330+ EXPECT_FALSE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, record));
4331+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4332+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0400 end");
4333+}
4334+ 
4335+/**
4336+ * @tc.name: GetHyperSnapLastError_0500
4337+ * @tc.desc: test CREATE_SNAPSHOT error does not affect FORK_FROM_SNAPSHOT query
4338+ * @tc.type: FUNC
4339+ */
4340+HWTEST_F(AppMgrServiceInnerEighthTest, GetHyperSnapLastError_0500, TestSize.Level2)
4341+{
4342+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0500 start");
4343+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4344+ ASSERT_NE(appMgrServiceInner, nullptr);
4345+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4346+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::CREATE_SNAPSHOT,
4347+ HyperSnapErrorCode::ERR_SNAPSHOT_EXIST);
4348+ HyperSnapErrorRecord record;
4349+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::FORK_FROM_SNAPSHOT, record));
4350+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_OK);
4351+ EXPECT_EQ(record.msg, "No error");
4352+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4353+ TAG_LOGI(AAFwkTag::TEST, "GetHyperSnapLastError_0500 end");
4354+}
4355+ 
4356+/**
4357+ * @tc.name: ClearHyperSnapError_0100
4358+ * @tc.desc: test clearing one error type keeps the other type intact
4359+ * @tc.type: FUNC
4360+ */
4361+HWTEST_F(AppMgrServiceInnerEighthTest, ClearHyperSnapError_0100, TestSize.Level1)
4362+{
4363+ TAG_LOGI(AAFwkTag::TEST, "ClearHyperSnapError_0100 start");
4364+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4365+ ASSERT_NE(appMgrServiceInner, nullptr);
4366+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4367+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::CREATE_SNAPSHOT,
4368+ HyperSnapErrorCode::ERR_SNAPSHOT_EXIST);
4369+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::FORK_FROM_SNAPSHOT,
4370+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4371+ appMgrServiceInner->ClearHyperSnapError(TEST_UID, HyperSnapErrorType::CREATE_SNAPSHOT);
4372+ HyperSnapErrorRecord createRecord;
4373+ HyperSnapErrorRecord forkRecord;
4374+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, createRecord));
4375+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::FORK_FROM_SNAPSHOT, forkRecord));
4376+ EXPECT_EQ(createRecord.code, HyperSnapErrorCode::ERR_OK);
4377+ EXPECT_EQ(forkRecord.code, HyperSnapErrorCode::ERR_SYSTEM_INNER);
4378+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4379+ TAG_LOGI(AAFwkTag::TEST, "ClearHyperSnapError_0100 end");
4380+}
4381+ 
4382+/**
4383+ * @tc.name: ClearHyperSnapError_0200
4384+ * @tc.desc: test clearing all error types for the uid
4385+ * @tc.type: FUNC
4386+ */
4387+HWTEST_F(AppMgrServiceInnerEighthTest, ClearHyperSnapError_0200, TestSize.Level1)
4388+{
4389+ TAG_LOGI(AAFwkTag::TEST, "ClearHyperSnapError_0200 start");
4390+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4391+ ASSERT_NE(appMgrServiceInner, nullptr);
4392+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4393+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::CREATE_SNAPSHOT,
4394+ HyperSnapErrorCode::ERR_SNAPSHOT_EXIST);
4395+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::FORK_FROM_SNAPSHOT,
4396+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4397+ appMgrServiceInner->ClearHyperSnapError(TEST_UID);
4398+ HyperSnapErrorRecord createRecord;
4399+ HyperSnapErrorRecord forkRecord;
4400+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, createRecord));
4401+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::FORK_FROM_SNAPSHOT, forkRecord));
4402+ EXPECT_EQ(createRecord.code, HyperSnapErrorCode::ERR_OK);
4403+ EXPECT_EQ(forkRecord.code, HyperSnapErrorCode::ERR_OK);
4404+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4405+ TAG_LOGI(AAFwkTag::TEST, "ClearHyperSnapError_0200 end");
4406+}
4407+ 
4408+/**
4409+ * @tc.name: ClearHyperSnapError_0300
4410+ * @tc.desc: test clearing with invalid uid/type does not crash and keeps saved records
4411+ * @tc.type: FUNC
4412+ */
4413+HWTEST_F(AppMgrServiceInnerEighthTest, ClearHyperSnapError_0300, TestSize.Level2)
4414+{
4415+ TAG_LOGI(AAFwkTag::TEST, "ClearHyperSnapError_0300 start");
4416+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4417+ ASSERT_NE(appMgrServiceInner, nullptr);
4418+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4419+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::CREATE_SNAPSHOT,
4420+ HyperSnapErrorCode::ERR_SNAPSHOT_EXIST);
4421+ appMgrServiceInner->ClearHyperSnapError(-1);
4422+ auto invalidType = static_cast<HyperSnapErrorType>(100);
4423+ appMgrServiceInner->ClearHyperSnapError(TEST_UID, invalidType);
4424+ HyperSnapErrorRecord record;
4425+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, record));
4426+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_SNAPSHOT_EXIST);
4427+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4428+ TAG_LOGI(AAFwkTag::TEST, "ClearHyperSnapError_0300 end");
4429+}
4430+ 
4431+/**
4432+ * @tc.name: ClearHyperSnapError_0400
4433+ * @tc.desc: test double-param clear with negative uid keeps saved records
4434+ * @tc.type: FUNC
4435+ */
4436+HWTEST_F(AppMgrServiceInnerEighthTest, ClearHyperSnapError_0400, TestSize.Level2)
4437+{
4438+ TAG_LOGI(AAFwkTag::TEST, "ClearHyperSnapError_0400 start");
4439+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4440+ ASSERT_NE(appMgrServiceInner, nullptr);
4441+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4442+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::CREATE_SNAPSHOT,
4443+ HyperSnapErrorCode::ERR_SNAPSHOT_EXIST);
4444+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::FORK_FROM_SNAPSHOT,
4445+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4446+ appMgrServiceInner->ClearHyperSnapError(-1, HyperSnapErrorType::CREATE_SNAPSHOT);
4447+ appMgrServiceInner->ClearHyperSnapError(-1, HyperSnapErrorType::FORK_FROM_SNAPSHOT);
4448+ HyperSnapErrorRecord createRecord;
4449+ HyperSnapErrorRecord forkRecord;
4450+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, createRecord));
4451+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::FORK_FROM_SNAPSHOT, forkRecord));
4452+ EXPECT_EQ(createRecord.code, HyperSnapErrorCode::ERR_SNAPSHOT_EXIST);
4453+ EXPECT_EQ(forkRecord.code, HyperSnapErrorCode::ERR_SYSTEM_INNER);
4454+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4455+ TAG_LOGI(AAFwkTag::TEST, "ClearHyperSnapError_0400 end");
4456+}
4457+ 
4458+/**
4459+ * @tc.name: ClearHyperSnapError_0500
4460+ * @tc.desc: test double-param clear of FORK_FROM_SNAPSHOT keeps CREATE_SNAPSHOT intact
4461+ * @tc.type: FUNC
4462+ */
4463+HWTEST_F(AppMgrServiceInnerEighthTest, ClearHyperSnapError_0500, TestSize.Level1)
4464+{
4465+ TAG_LOGI(AAFwkTag::TEST, "ClearHyperSnapError_0500 start");
4466+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4467+ ASSERT_NE(appMgrServiceInner, nullptr);
4468+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4469+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::CREATE_SNAPSHOT,
4470+ HyperSnapErrorCode::ERR_SNAPSHOT_EXIST);
4471+ appMgrServiceInner->SaveHyperSnapError(TEST_UID, HyperSnapErrorType::FORK_FROM_SNAPSHOT,
4472+ HyperSnapErrorCode::ERR_SYSTEM_INNER);
4473+ appMgrServiceInner->ClearHyperSnapError(TEST_UID, HyperSnapErrorType::FORK_FROM_SNAPSHOT);
4474+ HyperSnapErrorRecord createRecord;
4475+ HyperSnapErrorRecord forkRecord;
4476+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, createRecord));
4477+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::FORK_FROM_SNAPSHOT, forkRecord));
4478+ EXPECT_EQ(createRecord.code, HyperSnapErrorCode::ERR_SNAPSHOT_EXIST);
4479+ EXPECT_EQ(forkRecord.code, HyperSnapErrorCode::ERR_OK);
4480+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4481+ TAG_LOGI(AAFwkTag::TEST, "ClearHyperSnapError_0500 end");
4482+}
4483+ 
4484+/**
4485+ * @tc.name: GetCheckpointRestoreError_0100
4486+ * @tc.desc: test negative pid returns ERR_INNER without touching the kernel node
4487+ * @tc.type: FUNC
4488+ */
4489+HWTEST_F(AppMgrServiceInnerEighthTest, GetCheckpointRestoreError_0100, TestSize.Level2)
4490+{
4491+ TAG_LOGI(AAFwkTag::TEST, "GetCheckpointRestoreError_0100 start");
4492+ EXPECT_EQ(AppMgrServiceInner::GetCheckpointRestoreError(-1, "test"), ImageError::ERR_INNER);
4493+ TAG_LOGI(AAFwkTag::TEST, "GetCheckpointRestoreError_0100 end");
4494+}
4495+ 
4496+/**
4497+ * @tc.name: NotifyMakeImageFailed_0100
4498+ * @tc.desc: test negative uid skips saving but still notifies the error handler
4499+ * @tc.type: FUNC
4500+ */
4501+HWTEST_F(AppMgrServiceInnerEighthTest, NotifyMakeImageFailed_0100, TestSize.Level2)
4502+{
4503+ TAG_LOGI(AAFwkTag::TEST, "NotifyMakeImageFailed_0100 start");
4504+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4505+ ASSERT_NE(appMgrServiceInner, nullptr);
4506+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4507+ sptr<MockImageErrorHandlerStub> errHandler = new (std::nothrow) MockImageErrorHandlerStub();
4508+ EXPECT_CALL(*errHandler, OnError(_)).Times(1);
4509+ ImageError errCode = ImageError::ERR_KILL_IMAGE_PROCESS_FAILED;
4510+ EXPECT_EQ(appMgrServiceInner->NotifyMakeImageFailed(-1, errHandler, errCode), ERR_OK);
4511+ HyperSnapErrorRecord record;
4512+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, record));
4513+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_OK);
4514+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4515+ TAG_LOGI(AAFwkTag::TEST, "NotifyMakeImageFailed_0100 end");
4516+}
4517+ 
4518+/**
4519+ * @tc.name: NotifyMakeImageFailed_0200
4520+ * @tc.desc: test FORKALL errors are excluded from saving but handler is notified
4521+ * @tc.type: FUNC
4522+ */
4523+HWTEST_F(AppMgrServiceInnerEighthTest, NotifyMakeImageFailed_0200, TestSize.Level2)
4524+{
4525+ TAG_LOGI(AAFwkTag::TEST, "NotifyMakeImageFailed_0200 start");
4526+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4527+ ASSERT_NE(appMgrServiceInner, nullptr);
4528+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4529+ sptr<MockImageErrorHandlerStub> errHandler = new (std::nothrow) MockImageErrorHandlerStub();
4530+ EXPECT_CALL(*errHandler, OnError(_)).Times(2);
4531+ EXPECT_EQ(appMgrServiceInner->NotifyMakeImageFailed(TEST_UID, errHandler, ImageError::ERR_FORKALL_BUSY),
4532+ ERR_OK);
4533+ EXPECT_EQ(appMgrServiceInner->NotifyMakeImageFailed(TEST_UID, errHandler, ImageError::ERR_FORKALL_FAILED),
4534+ ERR_OK);
4535+ HyperSnapErrorRecord record;
4536+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, record));
4537+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_OK);
4538+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4539+ TAG_LOGI(AAFwkTag::TEST, "NotifyMakeImageFailed_0200 end");
4540+}
4541+ 
4542+/**
4543+ * @tc.name: NotifyMakeImageFailed_0300
4544+ * @tc.desc: test normal error is saved as CREATE_SNAPSHOT and handler is notified
4545+ * @tc.type: FUNC
4546+ */
4547+HWTEST_F(AppMgrServiceInnerEighthTest, NotifyMakeImageFailed_0300, TestSize.Level1)
4548+{
4549+ TAG_LOGI(AAFwkTag::TEST, "NotifyMakeImageFailed_0300 start");
4550+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4551+ ASSERT_NE(appMgrServiceInner, nullptr);
4552+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4553+ sptr<MockImageErrorHandlerStub> errHandler = new (std::nothrow) MockImageErrorHandlerStub();
4554+ EXPECT_CALL(*errHandler, OnError(_)).Times(1);
4555+ ImageError errCode = ImageError::ERR_TEMPLATE_DIED;
4556+ EXPECT_EQ(appMgrServiceInner->NotifyMakeImageFailed(TEST_UID, errHandler, errCode), ERR_OK);
4557+ HyperSnapErrorRecord record;
4558+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, record));
4559+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_SNAPSHOT_PROCESS_IS_DIED);
4560+ EXPECT_EQ(record.msg, "Snapshot process died");
4561+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4562+ TAG_LOGI(AAFwkTag::TEST, "NotifyMakeImageFailed_0300 end");
4563+}
4564+ 
4565+/**
4566+ * @tc.name: NotifyMakeImageFailed_0400
4567+ * @tc.desc: test valid uid with null handler returns -1 but still saves the error
4568+ * @tc.type: FUNC
4569+ */
4570+HWTEST_F(AppMgrServiceInnerEighthTest, NotifyMakeImageFailed_0400, TestSize.Level2)
4571+{
4572+ TAG_LOGI(AAFwkTag::TEST, "NotifyMakeImageFailed_0400 start");
4573+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4574+ ASSERT_NE(appMgrServiceInner, nullptr);
4575+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4576+ ImageError errCode = ImageError::ERR_KILL_IMAGE_PROCESS_FAILED;
4577+ EXPECT_EQ(appMgrServiceInner->NotifyMakeImageFailed(TEST_UID, nullptr, errCode), -1);
4578+ HyperSnapErrorRecord record;
4579+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, record));
4580+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_SYSTEM_INNER);
4581+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4582+ TAG_LOGI(AAFwkTag::TEST, "NotifyMakeImageFailed_0400 end");
4583+}
4584+ 
4585+/**
4586+ * @tc.name: MakeImage_0100
4587+ * @tc.desc: test MakeImage failure path with null remoteClientManager saves nothing (uid stays -1)
4588+ * @tc.type: FUNC
4589+ */
4590+HWTEST_F(AppMgrServiceInnerEighthTest, MakeImage_0100, TestSize.Level2)
4591+{
4592+ TAG_LOGI(AAFwkTag::TEST, "MakeImage_0100 start");
4593+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4594+ ASSERT_NE(appMgrServiceInner, nullptr);
4595+ appMgrServiceInner->remoteClientManager_ = nullptr;
4596+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4597+ // empty bundle makes MakeImageInner fail (preload pre-check), outer path resolves uid via
4598+ // bundleMgrHelper which is unreachable with a null remoteClientManager
4599+ Want want;
4600+ appMgrServiceInner->MakeImage(want, 0, AppExecFwk::PreloadMode::PRELOAD_MODULE, 0, nullptr);
4601+ HyperSnapErrorRecord record;
4602+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, record));
4603+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_OK);
4604+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4605+ TAG_LOGI(AAFwkTag::TEST, "MakeImage_0100 end");
4606+}
4607+ 
4608+/**
4609+ * @tc.name: MakeImage_0300
4610+ * @tc.desc: test MakeImage failure path resolves uid by bundle name and saves the error
4611+ * @tc.type: FUNC
4612+ */
4613+HWTEST_F(AppMgrServiceInnerEighthTest, MakeImage_0300, TestSize.Level1)
4614+{
4615+ TAG_LOGI(AAFwkTag::TEST, "MakeImage_0300 start");
4616+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4617+ ASSERT_NE(appMgrServiceInner, nullptr);
4618+ auto bundleMgrHelper = std::make_shared<BundleMgrHelper>();
4619+ AAFwk::MyStatus::GetInstance().getBundleManagerHelper_ = bundleMgrHelper;
4620+ // mock GetUidByBundleName returns ERR_OK(0), so calling uid must be 0 too to read back
4621+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4622+ // empty bundle fails with ERR_PRELOAD_FAILED, mapped to ERR_SYSTEM_INNER
4623+ Want want;
4624+ appMgrServiceInner->MakeImage(want, 0, AppExecFwk::PreloadMode::PRELOAD_MODULE, 0, nullptr);
4625+ HyperSnapErrorRecord record;
4626+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, record));
4627+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_SYSTEM_INNER);
4628+ AAFwk::MyStatus::GetInstance().getBundleManagerHelper_ = nullptr;
4629+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4630+ TAG_LOGI(AAFwkTag::TEST, "MakeImage_0300 end");
4631+}
4632+ 
4633+/**
4634+ * @tc.name: MakeImage_0400
4635+ * @tc.desc: test MakeImage failure path with null bundleMgrHelper notifies handler without saving
4636+ * @tc.type: FUNC
4637+ */
4638+HWTEST_F(AppMgrServiceInnerEighthTest, MakeImage_0400, TestSize.Level2)
4639+{
4640+ TAG_LOGI(AAFwkTag::TEST, "MakeImage_0400 start");
4641+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4642+ ASSERT_NE(appMgrServiceInner, nullptr);
4643+ // Null remoteClientManager makes GetBundleManagerHelper unreachable, so bundleMgrHelper
4644+ // stays nullptr and uid keeps -1.
4645+ appMgrServiceInner->remoteClientManager_ = nullptr;
4646+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4647+ sptr<MockImageErrorHandlerStub> errHandler = new (std::nothrow) MockImageErrorHandlerStub();
4648+ EXPECT_CALL(*errHandler, OnError(_)).Times(1);
4649+ Want want;
4650+ appMgrServiceInner->MakeImage(want, 0, AppExecFwk::PreloadMode::PRELOAD_MODULE, 0, errHandler);
4651+ HyperSnapErrorRecord record;
4652+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, record));
4653+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_OK);
4654+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4655+ TAG_LOGI(AAFwkTag::TEST, "MakeImage_0400 end");
4656+}
4657+ 
4658+/**
4659+ * @tc.name: TryToUseImageInfo_0100
4660+ * @tc.desc: test TryToUseImageInfo saves FORK_FROM_SNAPSHOT error when record creation from image fails
4661+ * @tc.type: FUNC
4662+ */
4663+HWTEST_F(AppMgrServiceInnerEighthTest, TryToUseImageInfo_0100, TestSize.Level2)
4664+{
4665+ TAG_LOGI(AAFwkTag::TEST, "TryToUseImageInfo_0100 start");
4666+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4667+ ASSERT_NE(appMgrServiceInner, nullptr);
4668+ auto abilityInfo = std::make_shared<AbilityInfo>();
4669+ abilityInfo->name = "ServiceAbility";
4670+ auto appInfo = std::make_shared<ApplicationInfo>();
4671+ appInfo->bundleName = "com.ix.hiservcie";
4672+ appInfo->uid = TEST_UID; // uid / BASE_USER_RANGE = 0, matches PreAddImageInfo below
4673+ PreloadRequest preloadRequest;
4674+ preloadRequest.abilityName = abilityInfo->name;
4675+ appMgrServiceInner->PreAddImageInfo(appInfo->bundleName, 0, 0, nullptr, preloadRequest);
4676+ auto imageInfo = appMgrServiceInner->GetImageInfo(appInfo->bundleName, abilityInfo->name, 0, 0);
4677+ ASSERT_NE(imageInfo, nullptr);
4678+ imageInfo->imagePid = 4321;
4679+ imageInfo->baseAppRecord = std::make_shared<AppRunningRecord>(appInfo, TEST_UID, "PROCESS_NAME");
4680+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4681+ AAFwk::MyStatus::GetInstance().checkAppRunningByUid_ = false;
4682+ // guard: if record creation succeeds, fork path calls GetSpawnClient()->StartProcess
4683+ AAFwk::MyStatus::GetInstance().getSpawnClient_ = std::make_shared<AppSpawnClient>();
4684+ std::shared_ptr<AppRunningRecord> appRecord;
4685+ int32_t result = appMgrServiceInner->TryToUseImageInfo(abilityInfo, appInfo, nullptr, "", 0,
4686+ "PROCESS_NAME", "", "", "", appRecord);
4687+ EXPECT_EQ(result, ERR_OK);
4688+ HyperSnapErrorRecord record;
4689+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::FORK_FROM_SNAPSHOT, record));
4690+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_SYSTEM_INNER);
4691+ AAFwk::MyStatus::GetInstance().getSpawnClient_ = nullptr;
4692+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4693+ TAG_LOGI(AAFwkTag::TEST, "TryToUseImageInfo_0100 end");
4694+}
4695+ 
4696+/**
4697+ * @tc.name: HandleMakeImageFailed_0100
4698+ * @tc.desc: test HandleMakeImageFailed notifies with imageInfo uid and saves the mapped error
4699+ * @tc.type: FUNC
4700+ */
4701+HWTEST_F(AppMgrServiceInnerEighthTest, HandleMakeImageFailed_0100, TestSize.Level2)
4702+{
4703+ TAG_LOGI(AAFwkTag::TEST, "HandleMakeImageFailed_0100 start");
4704+ auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
4705+ ASSERT_NE(appMgrServiceInner, nullptr);
4706+ auto abilityInfo = std::make_shared<AbilityInfo>();
4707+ abilityInfo->name = "ServiceAbility";
4708+ auto appInfo = std::make_shared<ApplicationInfo>();
4709+ appInfo->bundleName = "com.ix.hiservcie";
4710+ AAFwk::MyStatus::GetInstance().getCallingUid_ = TEST_UID;
4711+ PreloadRequest preloadRequest;
4712+ preloadRequest.abilityName = abilityInfo->name;
4713+ preloadRequest.bundleInfo.uid = TEST_UID;
4714+ sptr<MockImageErrorHandlerStub> errHandler = new MockImageErrorHandlerStub();
4715+ appMgrServiceInner->PreAddImageInfo(appInfo->bundleName, 0, 0, errHandler, preloadRequest);
4716+ EXPECT_CALL(*errHandler, OnError(static_cast<int32_t>(ImageError::ERR_TEMPLATE_DIED))).Times(1);
4717+ appMgrServiceInner->HandleMakeImageFailed(appInfo->bundleName, abilityInfo->name, 0, 0,
4718+ ImageError::ERR_TEMPLATE_DIED);
4719+ HyperSnapErrorRecord record;
4720+ EXPECT_TRUE(appMgrServiceInner->GetHyperSnapLastError(HyperSnapErrorType::CREATE_SNAPSHOT, record));
4721+ EXPECT_EQ(record.code, HyperSnapErrorCode::ERR_SNAPSHOT_PROCESS_IS_DIED);
4722+ AAFwk::MyStatus::GetInstance().getCallingUid_ = 0;
4723+ TAG_LOGI(AAFwkTag::TEST, "HandleMakeImageFailed_0100 end");
4724+}
4033} // namespace AppExecFwk4725} // namespace AppExecFwk
4034} // namespace OHOS4726} // namespace OHOS
@@ -26,13 +26,13 @@
26#include "bundle_mgr_helper.h"26#include "bundle_mgr_helper.h"
27#include "event_handler.h"27#include "event_handler.h"
28#include "hilog_tag_wrapper.h"28#include "hilog_tag_wrapper.h"
29-#include "image_error_handler_stub.h"
30#include "mock_ability_token.h"29#include "mock_ability_token.h"
31#include "mock_ipc_skeleton.h"30#include "mock_ipc_skeleton.h"
32#include "mock_my_flag.h"31#include "mock_my_flag.h"
33#include "mock_permission_verification.h"32#include "mock_permission_verification.h"
34#include "param.h"33#include "param.h"
35#include "parameters.h"34#include "parameters.h"
35+#include "hyper_snap_error_record.h"
36#include "remote_client_manager.h"36#include "remote_client_manager.h"
37#include "render_state_observer_stub.h"37#include "render_state_observer_stub.h"
38 38 
@@ -73,14 +73,6 @@ public:
73 {}73 {}
74};74};
75 75 
76-class MockImageErrorHandlerStub : public ImageErrorHandlerStub {
77-public:
78- MockImageErrorHandlerStub() = default;
79- virtual ~MockImageErrorHandlerStub() = default;
80- 
81- MOCK_METHOD1(OnError, void(int32_t errCode));
82-};
83- 
84void AppMgrServiceInnerFourthTest::InitAppInfo(const std::string& deviceName,76void AppMgrServiceInnerFourthTest::InitAppInfo(const std::string& deviceName,
85 const std::string& abilityName, const std::string& appName, const std::string& bundleName,77 const std::string& abilityName, const std::string& appName, const std::string& bundleName,
86 const std::string& moduleName)78 const std::string& moduleName)
@@ -1030,40 +1022,6 @@ HWTEST_F(AppMgrServiceInnerFourthTest, MakeImage_ShouldReturnNotOkWhenImageInfoN
1030 TAG_LOGI(AAFwkTag::TEST, "MakeImage_ShouldReturnNotOkWhenImageInfoNotExist end");1022 TAG_LOGI(AAFwkTag::TEST, "MakeImage_ShouldReturnNotOkWhenImageInfoNotExist end");
1031}1023}
1032 1024 
1033-/**
1034- * @tc.name: NotifyImageOperationFailed_ShouldReturn_1WhenErrorHandleIsNullptr
1035- * @tc.desc: Test NotifyImageOperationFailed
1036- * @tc.type: FUNC
1037- */
1038-HWTEST_F(AppMgrServiceInnerFourthTest, NotifyImageOperationFailed_ShouldReturn_1WhenErrorHandleIsNullptr,
1039- TestSize.Level1)
1040-{
1041- TAG_LOGI(AAFwkTag::TEST, "NotifyImageOperationFailed_ShouldReturn_1WhenErrorHandleIsNullptr start");
1042- auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
1043- EXPECT_NE(appMgrServiceInner, nullptr);
1044- ImageError errCode = ImageError::ERR_KILL_IMAGE_PROCESS_FAILED;
1045- EXPECT_EQ(appMgrServiceInner->NotifyImageOperationFailed(nullptr, errCode), -1);
1046- TAG_LOGI(AAFwkTag::TEST, "NotifyImageOperationFailed_ShouldReturn_1WhenErrorHandleIsNullptr end");
1047-}
1048- 
1049-/**
1050- * @tc.name: NotifyImageOperationFailed_ShouldReturnErrOkWhenErrorHandleIsNullptr
1051- * @tc.desc: Test NotifyImageOperationFailed
1052- * @tc.type: FUNC
1053- */
1054-HWTEST_F(AppMgrServiceInnerFourthTest, NotifyImageOperationFailed_ShouldReturnErrOkWhenErrorHandleIsNullptr,
1055- TestSize.Level1)
1056-{
1057- TAG_LOGI(AAFwkTag::TEST, "NotifyImageOperationFailed_ShouldReturnErrOkWhenErrorHandleIsNullptr start");
1058- auto appMgrServiceInner = std::make_shared<AppMgrServiceInner>();
1059- EXPECT_NE(appMgrServiceInner, nullptr);
1060- sptr<MockImageErrorHandlerStub> errHandler = new (std::nothrow) MockImageErrorHandlerStub();
1061- ImageError errCode = ImageError::ERR_KILL_IMAGE_PROCESS_FAILED;
1062- EXPECT_CALL(*errHandler, OnError(_)).Times(1);
1063- EXPECT_EQ(appMgrServiceInner->NotifyImageOperationFailed(errHandler, errCode), ERR_OK);
1064- TAG_LOGI(AAFwkTag::TEST, "NotifyImageOperationFailed_ShouldReturnErrOkWhenErrorHandleIsNullptr end");
1065-}
1066- 
1067/**1025/**
1068 * @tc.name: FindImageInfo_ShouldReturnNullptrWhenImageInfoNotExist1026 * @tc.name: FindImageInfo_ShouldReturnNullptrWhenImageInfoNotExist
1069 * @tc.desc: Test FindImageInfo1027 * @tc.desc: Test FindImageInfo
@@ -1468,5 +1426,42 @@ HWTEST_F(AppMgrServiceInnerFourthTest, GetImageInfoByBundleAndAbility_ShouldRetu
1468 EXPECT_NE(imageInfo, nullptr);1426 EXPECT_NE(imageInfo, nullptr);
1469 TAG_LOGI(AAFwkTag::TEST, "GetImageInfoByBundleAndAbility_ShouldReturnImageInfoWhenExist end");1427 TAG_LOGI(AAFwkTag::TEST, "GetImageInfoByBundleAndAbility_ShouldReturnImageInfoWhenExist end");
1470}1428}
1429+ 
1430+/**
1431+ * @tc.name: HyperSnapErrorRecord_0100
1432+ * @tc.desc: test HyperSnapErrorRecord parcel marshalling/unmarshalling roundtrip
1433+ * @tc.type: FUNC
1434+ */
1435+HWTEST_F(AppMgrServiceInnerFourthTest, HyperSnapErrorRecord_0100, TestSize.Level1)
1436+{
1437+ TAG_LOGI(AAFwkTag::TEST, "HyperSnapErrorRecord_0100 start");
1438+ HyperSnapErrorRecord record;
1439+ record.code = HyperSnapErrorCode::ERR_SNAPSHOT_PROCESS_IS_DIED;
1440+ record.msg = "Snapshot process died";
1441+ record.occurTimeStamp = 1755612345000; // unix ms, checks int64 precision
1442+ Parcel parcel;
1443+ ASSERT_TRUE(record.Marshalling(parcel));
1444+ auto *decoded = HyperSnapErrorRecord::Unmarshalling(parcel);
1445+ ASSERT_NE(decoded, nullptr);
1446+ EXPECT_EQ(decoded->code, HyperSnapErrorCode::ERR_SNAPSHOT_PROCESS_IS_DIED);
1447+ EXPECT_EQ(decoded->msg, "Snapshot process died");
1448+ EXPECT_EQ(decoded->occurTimeStamp, 1755612345000);
1449+ delete decoded;
1450+ TAG_LOGI(AAFwkTag::TEST, "HyperSnapErrorRecord_0100 end");
1451+}
1452+ 
1453+/**
1454+ * @tc.name: HyperSnapErrorRecord_0200
1455+ * @tc.desc: test Unmarshalling on an empty parcel returns nullptr
1456+ * @tc.type: FUNC
1457+ */
1458+HWTEST_F(AppMgrServiceInnerFourthTest, HyperSnapErrorRecord_0200, TestSize.Level2)
1459+{
1460+ TAG_LOGI(AAFwkTag::TEST, "HyperSnapErrorRecord_0200 start");
1461+ Parcel parcel;
1462+ EXPECT_EQ(HyperSnapErrorRecord::Unmarshalling(parcel), nullptr);
1463+ TAG_LOGI(AAFwkTag::TEST, "HyperSnapErrorRecord_0200 end");
1464+}
1465+ 
1471} // namespace AppExecFwk1466} // namespace AppExecFwk
1472} // namespace OHOS1467} // namespace OHOS
@@ -37,6 +37,7 @@ public:
37 GetDependentBundleInfoFlag flag = GetDependentBundleInfoFlag::GET_APP_CROSS_HSP_BUNDLE_INFO);37 GetDependentBundleInfoFlag flag = GetDependentBundleInfoFlag::GET_APP_CROSS_HSP_BUNDLE_INFO);
38 ErrCode GetBundleInfoV9(38 ErrCode GetBundleInfoV9(
39 const std::string &bundleName, int32_t flags, BundleInfo &bundleInfo, int32_t userId);39 const std::string &bundleName, int32_t flags, BundleInfo &bundleInfo, int32_t userId);
40+ ErrCode GetUidByBundleName(const std::string &bundleName, int32_t userId, int32_t appCloneIndex);
40 bool QueryDataGroupInfos(const std::string &bundleName, int32_t userId, std::vector<DataGroupInfo> &infos);41 bool QueryDataGroupInfos(const std::string &bundleName, int32_t userId, std::vector<DataGroupInfo> &infos);
41 bool RegisterBundleEventCallback(const sptr<IBundleEventCallback> &bundleEventCallback);42 bool RegisterBundleEventCallback(const sptr<IBundleEventCallback> &bundleEventCallback);
42 bool GetBundleInfos(43 bool GetBundleInfos(
@@ -46,6 +47,7 @@ public:
46 static bool hapModuleInfo_;47 static bool hapModuleInfo_;
47 static bool dataGroupInfos_;48 static bool dataGroupInfos_;
48 static ErrCode getBundleInfoV9Result_;49 static ErrCode getBundleInfoV9Result_;
50+ static int32_t mockUid_;
49 static std::string bundleVersionName_;51 static std::string bundleVersionName_;
50};52};
51} // namespace AppExecFwk53} // namespace AppExecFwk
@@ -26,6 +26,13 @@ ErrCode BundleMgrHelper::GetBundleInfoV9(
26 return getBundleInfoV9Result_;26 return getBundleInfoV9Result_;
27}27}
28 28 
29+ErrCode BundleMgrHelper::GetUidByBundleName(
30+ const std::string &bundleName, int32_t userId, int32_t appCloneIndex)
31+{
32+ // Mirrors the real helper: the ErrCode return actually carries the uid resolved by bms.
33+ return mockUid_;
34+}
35+ 
29bool BundleMgrHelper::GetHapModuleInfo(const AbilityInfo &abilityInfo, int32_t userId, HapModuleInfo &hapModuleInfo)36bool BundleMgrHelper::GetHapModuleInfo(const AbilityInfo &abilityInfo, int32_t userId, HapModuleInfo &hapModuleInfo)
30{37{
31 return hapModuleInfo_;38 return hapModuleInfo_;
@@ -57,6 +64,7 @@ bool BundleMgrHelper::QueryDataGroupInfos(const std::string &bundleName,
57bool BundleMgrHelper::hapModuleInfo_ = false;64bool BundleMgrHelper::hapModuleInfo_ = false;
58bool BundleMgrHelper::dataGroupInfos_ = false;65bool BundleMgrHelper::dataGroupInfos_ = false;
59ErrCode BundleMgrHelper::getBundleInfoV9Result_ = ERR_OK;66ErrCode BundleMgrHelper::getBundleInfoV9Result_ = ERR_OK;
67+int32_t BundleMgrHelper::mockUid_ = 0;
60std::string BundleMgrHelper::bundleVersionName_ = "";68std::string BundleMgrHelper::bundleVersionName_ = "";
61} // namespace AppExecFwk69} // namespace AppExecFwk
62} // namespace OHOS70} // namespace OHOS
@@ -15,6 +15,8 @@
15 15 
16#include <gtest/gtest.h>16#include <gtest/gtest.h>
17 17 
18+#include <memory>
19+ 
18#define private public20#define private public
19#define protected public21#define protected public
20#include "app_foreground_state_observer_stub.h"22#include "app_foreground_state_observer_stub.h"
@@ -26,6 +28,8 @@
26 28 
27#include "hilog_tag_wrapper.h"29#include "hilog_tag_wrapper.h"
28#include "ipc_types.h"30#include "ipc_types.h"
31+#include "errors.h"
32+#include "hyper_snap_error_record.h"
29#include "mem_dump_callback_interface.h"33#include "mem_dump_callback_interface.h"
30#include "mem_dump_callback_stub.h"34#include "mem_dump_callback_stub.h"
31#include "mem_dump_callback_proxy.h"35#include "mem_dump_callback_proxy.h"
@@ -254,6 +258,65 @@ HWTEST_F(AppMgrStubTest, HandleNotifyHotReloadPage_0100, TestSize.Level1)
254 TAG_LOGI(AAFwkTag::TEST, "%{public}s end.", __func__);258 TAG_LOGI(AAFwkTag::TEST, "%{public}s end.", __func__);
255}259}
256 260 
261+/**
262+ * @tc.name: HandleGetHyperSnapLastError_0100
263+ * @tc.desc: HandleGetHyperSnapLastError writes only the result when service returns failure.
264+ * @tc.type: FUNC
265+ */
266+HWTEST_F(AppMgrStubTest, HandleGetHyperSnapLastError_0100, TestSize.Level1)
267+{
268+ TAG_LOGI(AAFwkTag::TEST, "%{public}s start.", __func__);
269+ 
270+ MessageParcel data;
271+ MessageParcel reply;
272+ MessageOption option;
273+ 
274+ WriteInterfaceToken(data);
275+ data.WriteInt32(static_cast<int32_t>(HyperSnapErrorType::CREATE_SNAPSHOT));
276+ EXPECT_CALL(*mockAppMgrService_, GetHyperSnapLastError(_, _))
277+ .Times(1)
278+ .WillOnce(Return(ERR_INVALID_VALUE));
279+ int32_t ret = mockAppMgrService_->HandleGetHyperSnapLastError(data, reply);
280+ EXPECT_EQ(ret, NO_ERROR);
281+ EXPECT_EQ(reply.ReadInt32(), ERR_INVALID_VALUE);
282+ 
283+ TAG_LOGI(AAFwkTag::TEST, "%{public}s end.", __func__);
284+}
285+ 
286+/**
287+ * @tc.name: HandleGetHyperSnapLastError_0200
288+ * @tc.desc: HandleGetHyperSnapLastError writes result and record when service succeeds.
289+ * @tc.type: FUNC
290+ */
291+HWTEST_F(AppMgrStubTest, HandleGetHyperSnapLastError_0200, TestSize.Level1)
292+{
293+ TAG_LOGI(AAFwkTag::TEST, "%{public}s start.", __func__);
294+ 
295+ MessageParcel data;
296+ MessageParcel reply;
297+ MessageOption option;
298+ 
299+ WriteInterfaceToken(data);
300+ data.WriteInt32(static_cast<int32_t>(HyperSnapErrorType::FORK_FROM_SNAPSHOT));
301+ HyperSnapErrorRecord record;
302+ record.code = HyperSnapErrorCode::ERR_SNAPSHOT_EXIST;
303+ record.msg = "test msg";
304+ record.occurTimeStamp = 12345;
305+ EXPECT_CALL(*mockAppMgrService_, GetHyperSnapLastError(_, _))
306+ .Times(1)
307+ .WillOnce(DoAll(SetArgReferee<1>(record), Return(ERR_OK)));
308+ int32_t ret = mockAppMgrService_->HandleGetHyperSnapLastError(data, reply);
309+ EXPECT_EQ(ret, NO_ERROR);
310+ EXPECT_EQ(reply.ReadInt32(), ERR_OK);
311+ std::unique_ptr<HyperSnapErrorRecord> recordReply(reply.ReadParcelable<HyperSnapErrorRecord>());
312+ ASSERT_NE(recordReply, nullptr);
313+ EXPECT_EQ(recordReply->code, HyperSnapErrorCode::ERR_SNAPSHOT_EXIST);
314+ EXPECT_EQ(recordReply->msg, "test msg");
315+ EXPECT_EQ(recordReply->occurTimeStamp, 12345);
316+ 
317+ TAG_LOGI(AAFwkTag::TEST, "%{public}s end.", __func__);
318+}
319+ 
257/**320/**
258 * @tc.name: HandleNotifyUnLoadRepairPatch_0100321 * @tc.name: HandleNotifyUnLoadRepairPatch_0100
259 * @tc.desc: Handle notify unload repair patch.322 * @tc.desc: Handle notify unload repair patch.