已合并
提供快照dfx #20157
zhangtao创建于 27 天前
提供快照dfx #20157
已合并
共 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 | 18 | ||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 21 | 25 | ||
| 22 | 26 | ||
| 27 | + | ||
| 23 | 28 | ||
| 24 | 29 | ||
| 25 | 30 | ||
| @@ -29,13 +34,75 @@ namespace OHOS { | |||
| 29 | namespace HyperSnapManagerEts { | 34 | namespace HyperSnapManagerEts { |
| 30 | namespace { | 35 | namespace { |
| 31 | constexpr const char *HYPER_SNAP_MANAGER_SPACE_NAME = "@ohos.app.ability.hyperSnapManager.hyperSnapManager"; | 36 | constexpr 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 | } // namespace | 41 | } // 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 | + | ||
| 34 | class EtsHyperSnapManager final { | 99 | class EtsHyperSnapManager final { |
| 35 | public: | 100 | public: |
| 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 | ||
| 41 | void EtsHyperSnapManager::SetHyperSnapEnabled(ani_env *env, ani_boolean enabledFlag) | 108 | void EtsHyperSnapManager::SetHyperSnapEnabled(ani_env *env, ani_boolean enabledFlag) |
| @@ -86,6 +153,47 @@ void EtsHyperSnapManager::RequestRebuildHyperSnap(ani_env *env) | |||
| 86 | 153 | ||
| 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); | ||
| 193 | + ani_object info = BuildHyperSnapErrorInfo(env, record); | ||
| 194 | + AppExecFwk::AsyncCallback(env, call, error, info); | ||
| 195 | +} | ||
| 196 | + | ||
| 89 | void EtsHyperSnapManagerRegisterInit(ani_env *env) | 197 | void 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 HyperSnapManagerEts | 255 | } // namespace HyperSnapManagerEts |
| 146 | -} // namespace OHOS | 256 | +} // 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 | + | ||
| 16 | export default namespace hyperSnapManager { | 19 | export default namespace hyperSnapManager { |
| 17 | loadLibraryWithPermissionCheck("hyper_snap_manager_ani.z", "@ohos.app.ability.hyperSnapManager") | 20 | loadLibraryWithPermissionCheck("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 | + | ||
| 19 | export native function nativeSetHyperSnapEnabled(enableFlag: boolean): void; | 50 | export native function nativeSetHyperSnapEnabled(enableFlag: boolean): void; |
| 20 | export function setHyperSnapEnabled(enableFlag: boolean): void { | 51 | export function setHyperSnapEnabled(enableFlag: boolean): void { |
| 21 | hyperSnapManager.nativeSetHyperSnapEnabled(enableFlag); | 52 | hyperSnapManager.nativeSetHyperSnapEnabled(enableFlag); |
| @@ -25,4 +56,26 @@ export native function nativeRequestRebuildHyperSnap(): void; | |||
| 25 | export function requestRebuildHyperSnap(): void { | 56 | export function requestRebuildHyperSnap(): void { |
| 26 | hyperSnapManager.nativeRequestRebuildHyperSnap(); | 57 | hyperSnapManager.nativeRequestRebuildHyperSnap(); |
| 27 | } | 58 | } |
| 28 | -} // namespace hyperSnapManager | 59 | + |
| 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 | 18 | ||
| 19 | 19 | ||
| 20 | + | ||
| 20 | 21 | ||
| 21 | 22 | ||
| 22 | 23 | ||
| 24 | + | ||
| 25 | + | ||
| 23 | 26 | ||
| 24 | 27 | ||
| 25 | 28 | ||
| 26 | 29 | ||
| 27 | 30 | ||
| 28 | 31 | ||
| 32 | + | ||
| 29 | 33 | ||
| 30 | namespace OHOS { | 34 | namespace OHOS { |
| 31 | namespace AbilityRuntime { | 35 | namespace AbilityRuntime { |
| @@ -34,6 +38,79 @@ constexpr int32_t INDEX_ZERO = 0; | |||
| 34 | constexpr size_t ARGC_ONE = 1; | 38 | constexpr size_t ARGC_ONE = 1; |
| 35 | const std::string RES_SCHED_CLIENT_SO = "libressched_client.z.so"; | 39 | const 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 | + | ||
| 37 | class JsHyperSnapManager final { | 114 | class JsHyperSnapManager final { |
| 38 | public: | 115 | public: |
| 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 | + } | ||
| 59 | private: | 141 | private: |
| 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) | ||
HyperSnapErrorType这个枚举需要有对应的napi实现 ![]() ![]() | |||
| 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) { | ||
innerErrorCode record这两个变量要在complete函数里判空处理 ![]() ![]() | |||
| 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 | } // namespace | 234 | } // 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 AbilityRuntime | 273 | +} // namespace AbilityRuntime |
| 129 | -} //namespace OHOS | 274 | +} // 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 | 57 | ||
| 58 | 58 | ||
| 59 | 59 | ||
| 60 | + | ||
| 60 | 61 | ||
| 61 | namespace OHOS { | 62 | namespace OHOS { |
| 62 | namespace AppExecFwk { | 63 | namespace 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 = 145 | 170 | + GET_SELF_CHILDREN_PROCESSES = 145, |
| 171 | + GET_HYPER_SNAP_LAST_ERROR = 146, | ||
| 171 | }; | 172 | }; |
| 172 | } // AppExecFwk | 173 | } // AppExecFwk |
| 173 | } // OHOS | 174 | } // 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 | 89 | ||
| 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 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 { | ||
文件名建议用hyper_snap_error_record ![]() ![]() | |||
| 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 | + | ||
| @@ -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 AppExecFwk | 53 | } // 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 | + | ||
| 1740 | int32_t AppMgrClient::GetSelfUIAbilityChildProcesses(std::vector<ChildProcessInfo> &infos) | 1755 | int32_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; | ||
如果返回这个IPC_PROXY_ERR对应的JS错误码是什么待确认 ![]() ![]() | |||
| 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 | + | ||
| 145 | int32_t AppMgrProxy::NotifyTemplateProcessDeepFrozen(int32_t pid) | 177 | int32_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 | 16 | ||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | + | ||
| 19 | 20 | ||
| 20 | 21 | ||
| 21 | 22 | ||
| @@ -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 | + | ||
| 618 | int32_t AppMgrStub::HandleApplicationForegrounded(MessageParcel &data, MessageParcel &reply) | 648 | int32_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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 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 | 27 | ||
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | + | ||
| 30 | 31 | ||
| 31 | 32 | ||
| 32 | 33 | ||
| @@ -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 | 36 | ||
| 37 | 37 | ||
| 38 | 38 | ||
| 39 | + | ||
| 39 | 40 | ||
| 40 | 41 | ||
| 41 | 42 | ||
| @@ -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); | ||
inner的返回值不要是bool,直接返回错误码 ![]() ![]() | |||
| 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 | + | ||
| 320 | int32_t AppMgrService::NotifyTemplateProcessDeepFrozen(int32_t pid) | 340 | int32_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 | 332 | ||
| 333 | 333 | ||
| 334 | 334 | ||
| 335 | + | ||
selinux仓要同步修改 ![]() ![]() | |||
| 335 | 336 | ||
| 336 | constexpr int32_t ROOT_UID = 0; | 337 | constexpr int32_t ROOT_UID = 0; |
| 337 | constexpr int32_t FOUNDATION_UID = 5523; | 338 | constexpr 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 | + | ||
| 789 | void AppMgrServiceInner::MakeImage(const AAFwk::Want &want, int32_t userId, | 809 | void 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 | + | ||
| 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 | + | ||
| 938 | int32_t AppMgrServiceInner::KillImageProcess(uint64_t checkpointId) | 987 | int32_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 | ||
| 1137 | int32_t AppMgrServiceInner::PreAddImageInfo(const std::string& bundleName, int32_t userId, int32_t appIndex, | 1194 | int32_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); | ||
这个错误还得确认下是否是inner ![]() ![]() | |||
| 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) { | ||
函数入口加hitrace ![]() ![]() | |||
| 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 AppExecFwk | 13635 | } // namespace AppExecFwk |
| 13358 | } // namespace OHOS | 13636 | } // 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 AppExecFwk | 2070 | } // namespace AppExecFwk |
| 2032 | } // namespace OHOS | 2071 | } // 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 AppExecFwk | 1873 | } // namespace AppExecFwk |
| 1780 | } // namespace OHOS | 1874 | } // 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 AppExecFwk | 408 | } // namespace AppExecFwk |
| 363 | } // namespace OHOS | 409 | } // namespace OHOS |
| @@ -14,11 +14,14 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | + | ||
| 17 | 18 | ||
| 18 | 19 | ||
| 19 | 20 | ||
| 20 | 21 | ||
| 21 | 22 | ||
| 23 | + | ||
| 24 | + | ||
| 22 | 25 | ||
| 23 | 26 | ||
| 24 | 27 | ||
| @@ -39,6 +42,7 @@ constexpr int32_t QUICKFIX_UID = 5524; | |||
| 39 | constexpr int32_t SHADER_CACHE_GROUPID = 3099; | 42 | constexpr int32_t SHADER_CACHE_GROUPID = 3099; |
| 40 | constexpr int32_t RESOURCE_MANAGER_UID = 1096; | 43 | constexpr int32_t RESOURCE_MANAGER_UID = 1096; |
| 41 | constexpr int32_t DEFAULT_USER_ID = 0; | 44 | constexpr int32_t DEFAULT_USER_ID = 0; |
| 45 | +constexpr int32_t TEST_UID = 10001; | ||
| 42 | static int g_scheduleLoadChildCall = 0; | 46 | static int g_scheduleLoadChildCall = 0; |
| 43 | 47 | ||
| 44 | namespace OHOS { | 48 | namespace 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 AppExecFwk | 4725 | } // namespace AppExecFwk |
| 4034 | } // namespace OHOS | 4726 | } // namespace OHOS |
| @@ -26,13 +26,13 @@ | |||
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | - | ||
| 30 | 29 | ||
| 31 | 30 | ||
| 32 | 31 | ||
| 33 | 32 | ||
| 34 | 33 | ||
| 35 | 34 | ||
| 35 | + | ||
| 36 | 36 | ||
| 37 | 37 | ||
| 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 | - | ||
| 84 | void AppMgrServiceInnerFourthTest::InitAppInfo(const std::string& deviceName, | 76 | void 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_ShouldReturnNullptrWhenImageInfoNotExist | 1026 | * @tc.name: FindImageInfo_ShouldReturnNullptrWhenImageInfoNotExist |
| 1069 | * @tc.desc: Test FindImageInfo | 1027 | * @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 AppExecFwk | 1466 | } // namespace AppExecFwk |
| 1472 | } // namespace OHOS | 1467 | } // 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 AppExecFwk | 53 | } // 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 | + | ||
| 29 | bool BundleMgrHelper::GetHapModuleInfo(const AbilityInfo &abilityInfo, int32_t userId, HapModuleInfo &hapModuleInfo) | 36 | bool 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, | |||
| 57 | bool BundleMgrHelper::hapModuleInfo_ = false; | 64 | bool BundleMgrHelper::hapModuleInfo_ = false; |
| 58 | bool BundleMgrHelper::dataGroupInfos_ = false; | 65 | bool BundleMgrHelper::dataGroupInfos_ = false; |
| 59 | ErrCode BundleMgrHelper::getBundleInfoV9Result_ = ERR_OK; | 66 | ErrCode BundleMgrHelper::getBundleInfoV9Result_ = ERR_OK; |
| 67 | +int32_t BundleMgrHelper::mockUid_ = 0; | ||
| 60 | std::string BundleMgrHelper::bundleVersionName_ = ""; | 68 | std::string BundleMgrHelper::bundleVersionName_ = ""; |
| 61 | } // namespace AppExecFwk | 69 | } // namespace AppExecFwk |
| 62 | } // namespace OHOS | 70 | } // namespace OHOS |
| @@ -15,6 +15,8 @@ | |||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | + | ||
| 19 | + | ||
| 18 | 20 | ||
| 19 | 21 | ||
| 20 | 22 | ||
| @@ -26,6 +28,8 @@ | |||
| 26 | 28 | ||
| 27 | 29 | ||
| 28 | 30 | ||
| 31 | + | ||
| 32 | + | ||
| 29 | 33 | ||
| 30 | 34 | ||
| 31 | 35 | ||
| @@ -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_0100 | 321 | * @tc.name: HandleNotifyUnLoadRepairPatch_0100 |
| 259 | * @tc.desc: Handle notify unload repair patch. | 322 | * @tc.desc: Handle notify unload repair patch. |


变量的名字改为err_ok