diff --git a/BUILD.gn b/BUILD.gn index b94f68c8a90923bd13a37158d77526b399b6c86a..fc79436fa4ea541a00b375b9e8ecbbc18bd0e834 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -58,6 +58,13 @@ if (!defined(ohos_lite)) { subsystem_name = "${subsystem_name}" part_name = "${part_name}" } + + ohos_prebuilt_etc("nwebspawn.rc") { + source = "nwebspawn.cfg" + relative_install_dir = "init" + subsystem_name = "${subsystem_name}" + part_name = "${part_name}" + } } group("appspawn_all") { @@ -94,6 +101,12 @@ group("appspawn_all") { "standard:nativespawn", ] } + if (appspawn_support_nweb) { # for support nwebspawn + deps += [ + ":nwebspawn.rc", + "standard:nwebspawn", + ] + } } else { deps += [ "lite:appspawn_lite" ] } diff --git a/appdata-sandbox-app.json b/appdata-sandbox-app.json index ded5a8c1acae6a64e04b43e97ef278dbb5ec7b9e..15d5876d18e3f851eb600a0421bb51310f395dae 100644 --- a/appdata-sandbox-app.json +++ b/appdata-sandbox-app.json @@ -20,6 +20,9 @@ }, { "src-path" : "/sys_prod", "sandbox-path" : "/sys_prod" + }, { + "src-path" : "/system/app", + "sandbox-path" : "/system/app" }, { "src-path" : "/module_update", "sandbox-path" : "/module_update" @@ -38,6 +41,12 @@ }, { "src-path" : "/system/lib64", "sandbox-path" : "/system/lib64" + }, { + "src-path" : "/system/asan/lib", + "sandbox-path" : "/system/asan/lib" + }, { + "src-path" : "/system/asan/lib64", + "sandbox-path" : "/system/asan/lib64" }, { "src-path" : "/system/data", "sandbox-path" : "/system/data" @@ -53,12 +62,18 @@ }, { "src-path" : "/system/etc", "sandbox-path" : "/system/etc" + }, { + "src-path": "/system/framework", + "sandbox-path": "/system/framework" }, { "src-path" : "/system/resource", "sandbox-path" : "/system/resource" }, { "src-path" : "/vendor/", "sandbox-path" : "/vendor/" + }, { + "src-path" : "/vendor/asan/", + "sandbox-path" : "/vendor/asan/" }, { "src-path" : "/vendor/etc/vulkan", "sandbox-path" : "/vendor/etc/vulkan" @@ -138,15 +153,15 @@ }, { "src-path" : "/data/misc", "sandbox-path" : "/data/storage/el1/bundle/misc" + }, { + "src-path" : "/data/app/el1//system_optimize/", + "sandbox-path" : "/data/storage/system_optimize" }, { "src-path" : "/data/app/el1/public/aot_compiler/ark_cache/", "sandbox-path" : "/data/storage/ark-cache" }, { "src-path" : "/data/app/el1//aot_compiler/ark_profile/", "sandbox-path" : "/data/storage/ark-profile" - }, { - "src-path" : "/data/app/el1//shader_cache/", - "sandbox-path" : "/data/storage/shader_cache/local" }, { "src-path" : "/data/app/el1/public/shader_cache/cloud/", "sandbox-path" : "/data/storage/shader_cache/cloud" @@ -180,6 +195,10 @@ "mount-paths": [{ "src-path": "/mnt/user//nosharefs/docs", "sandbox-path": "/storage/Users" + }, { + "src-path": "", + "sandbox-path": "", + "dec-paths": [ "/storage/Users//appdata/el2/shareFiles" ] }, { "src-path": "/mnt/data//userExternal", "sandbox-path": "/storage/userExternal" @@ -249,6 +268,15 @@ "src-path": "/data/service/el1/public/themes//share", "sandbox-path": "/data/themes/s" }] + }, { + "name": "ohos.permission.THEME_SKIN", + "mount-paths": [{ + "src-path": "/data/service/el1/public/themes//a/skin", + "sandbox-path": "/data/themes/a/skin" + }, { + "src-path": "/data/service/el1/public/themes//b/skin", + "sandbox-path": "/data/themes/b/skin" + }] }, { "name": "ohos.permission.GET_WALLPAPER", "mount-paths": [{ @@ -357,6 +385,10 @@ "src-path": "/dev/fuse", "sandbox-path": "/mnt/data/fuse", "category": "dlp_fuse" + }, { + "src-path": "", + "sandbox-path": "", + "dec-paths": [ "/mnt/data/fuse" ] }], "mount-groups": ["dlpmgr"] }, { @@ -378,6 +410,27 @@ "src-path": "/data/service/el1/public/update/param_service/install/system/etc/", "sandbox-path": "/data/service/el1/public/update/param_service/install/system/etc/" }] + }, { + "name": "ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY", + "mount-paths": [{ + "src-path": "none", + "sandbox-path": "none", + "dec-paths": [ "/storage/Users//Download" ] + }] + }, { + "name": "ohos.permission.READ_WRITE_DESKTOP_DIRECTORY", + "mount-paths": [{ + "src-path": "none", + "sandbox-path": "none", + "dec-paths": [ "/storage/Users//Desktop" ] + }] + }, { + "name": "ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY", + "mount-paths": [{ + "src-path": "none", + "sandbox-path": "none", + "dec-paths": [ "/storage/Users//Documents" ] + }] }, { "name": "ohos.permission.READ_WRITE_USER_FILE", "gids": ["file_manager"], @@ -409,6 +462,11 @@ "sandbox-path": "/data/storage/el2/base/files/mediadata/", "sandbox-flags": ["bind", "rec"] }] + }, { + "name": "ohos.permission.ACCESS_DFX_LOG_DIR", + "sandbox-switch": "ON", + "gids": ["log"], + "mount-paths": [] }], "spawn-flag": [{ "name": "START_FLAGS_BACKUP", @@ -490,7 +548,15 @@ "gids": ["data_reserve"], "mount-paths" : [{ "src-path" : "/data/app/el1/bundle/public/", - "sandbox-path" : "/data/bundles/" + "sandbox-path" : "/data/app/el1/bundle/public/" + }] + }, { + "name": "com.ohos.settingsdata", + "sandbox-switch": "ON", + "gids": ["data_reserve"], + "mount-paths" : [{ + "src-path" : "", + "sandbox-path" : "" }] }] }, diff --git a/appdata-sandbox-asan.json b/appdata-sandbox-asan.json index 0fb704fae3ae60155d20d773d0dcf7375035a834..cfde0075b56ffe60127789909b71b0036f31cc30 100755 --- a/appdata-sandbox-asan.json +++ b/appdata-sandbox-asan.json @@ -14,6 +14,11 @@ "sandbox-path" : "/vendor/asan/lib", "sandbox-flags" : [ "bind", "rec" ], "check-action-status": "false" + }, { + "src-path" : "/system/asan/bin", + "sandbox-path" : "/system/asan/bin", + "sandbox-flags" : [ "bind", "rec" ], + "check-action-status": "false" } ], "symbol-links" : [ @@ -44,6 +49,44 @@ "sandbox-path" : "/vendor/asan/lib", "sandbox-flags" : [ "bind", "rec" ], "check-action-status": "false" + }, { + "src-path" : "/system/asan/bin", + "sandbox-path" : "/system/asan/bin", + "sandbox-flags" : [ "bind", "rec" ], + "check-action-status": "false" + } + ], + "symbol-links" : [ + ] + }], + "__internal__.com.ohos.gpu" : [{ + "sandbox-root" : "/mnt/sandbox/com.ohos.render/", + "sandbox-ns-flags" : [ "pid", "net" ], + "mount-paths" : [{ + "src-path" : "/system/asan/lib64", + "sandbox-path" : "/system/asan/lib64", + "sandbox-flags" : [ "bind", "rec" ], + "check-action-status": "false" + }, { + "src-path" : "/vendor/asan/lib64", + "sandbox-path" : "/vendor/asan/lib64", + "sandbox-flags" : [ "bind", "rec" ], + "check-action-status": "false" + }, { + "src-path" : "/system/asan/lib", + "sandbox-path" : "/system/asan/lib", + "sandbox-flags" : [ "bind", "rec" ], + "check-action-status": "false" + }, { + "src-path" : "/vendor/asan/lib", + "sandbox-path" : "/vendor/asan/lib", + "sandbox-flags" : [ "bind", "rec" ], + "check-action-status": "false" + }, { + "src-path" : "/system/asan/bin", + "sandbox-path" : "/system/asan/bin", + "sandbox-flags" : [ "bind", "rec" ], + "check-action-status": "false" } ], "symbol-links" : [ diff --git a/appdata-sandbox-gpu.json b/appdata-sandbox-gpu.json index 8e5b8806b8780da3702ef089db409432f5d9cb04..6b8d3c820e751660da2d28d8b01eb383e79e14a2 100644 --- a/appdata-sandbox-gpu.json +++ b/appdata-sandbox-gpu.json @@ -31,9 +31,7 @@ "sandbox-path" : "/system/lib64" }, { "src-path" : "/vendor/", - "sandbox-path" : "/vendor/", - "sandbox-flags" : [ "bind", "rec" ], - "check-action-status": "false" + "sandbox-path" : "/vendor/" }, { "src-path" : "/system/app/NWeb", "sandbox-path" : "/system/app/NWeb" @@ -79,8 +77,8 @@ "src-path" : "/module_update/ArkWebCore/app/", "sandbox-path" : "/module_update/ArkWebCore/app/" }, { - "src-path" : "/data/app/el1//shader_cache/", - "sandbox-path" : "/data/storage/shader_cache/local" + "src-path" : "/data/app/el1//system_optimize//shader_cache", + "sandbox-path" : "/data/storage/system_optimize/shader_cache" }, { "src-path" : "/data/app/el1/public/shader_cache/cloud/", "sandbox-path" : "/data/storage/shader_cache/cloud" diff --git a/appdata-sandbox-render.json b/appdata-sandbox-render.json index ccf57d0d8c511bc4cd7738372f26ae5516509da3..e671f9a0de2d53adb796d99906d9701072f05491 100644 --- a/appdata-sandbox-render.json +++ b/appdata-sandbox-render.json @@ -20,6 +20,9 @@ }, { "src-path" : "/system/etc", "sandbox-path" : "/system/etc" + }, { + "src-path": "/system/framework", + "sandbox-path": "/system/framework" }, { "src-path" : "/system/bin", "sandbox-path" : "/system/bin" @@ -35,9 +38,12 @@ }, { "src-path" : "/system/app/NWeb", "sandbox-path" : "/system/app/NWeb" - }, { + }, { "src-path" : "/system/asan/lib64", "sandbox-path" : "/system/asan/lib64" + }, { + "src-path" : "/system/asan/lib", + "sandbox-path" : "/system/asan/lib" }, { "src-path" : "/vendor/asan/lib64", "sandbox-path" : "/vendor/asan/lib64" diff --git a/appdata-sandbox.json b/appdata-sandbox.json index 043b888d59de5fda9ae4924acb38923ca78422b5..38115a046400a6fac9ef7f7669fbc1904101b47c 100755 --- a/appdata-sandbox.json +++ b/appdata-sandbox.json @@ -73,6 +73,11 @@ "sandbox-path" : "/system/etc", "sandbox-flags" : [ "bind", "rec" ], "check-action-status": "false" + }, { + "src-path" : "/system/framework", + "sandbox-path" : "/system/framework", + "sandbox-flags" : [ "bind", "rec" ], + "check-action-status": "false" }, { "src-path" : "/system/etc/hosts", "sandbox-path" : "/data/service/el1/network/hosts_user/hosts", @@ -128,6 +133,11 @@ "sandbox-path" : "/data/storage/el1/base", "sandbox-flags" : [ "bind", "rec" ], "check-action-status": "true" + }, { + "src-path" : "/data/app/el1//system_optimize/", + "sandbox-path" : "/data/storage/system_optimize", + "sandbox-flags" : [ "bind", "rec" ], + "check-action-status": "false" }, { "src-path" : "/mnt/hmdfs/", "sandbox-path" : "/mnt/hmdfs/", @@ -153,11 +163,6 @@ "sandbox-path" : "/data/storage/ark-profile", "sandbox-flags" : [ "bind", "rec" ], "check-action-status": "false" - }, { - "src-path" : "/data/app/el1//shader_cache/", - "sandbox-path" : "/data/storage/shader_cache/local", - "sandbox-flags" : [ "bind", "rec" ], - "check-action-status": "false" }, { "src-path" : "/data/app/el1/public/shader_cache/cloud/", "sandbox-path" : "/data/storage/shader_cache/cloud", @@ -491,6 +496,11 @@ "sandbox-path" : "/system/etc", "sandbox-flags" : [ "bind", "rec" ], "check-action-status": "false" + }, { + "src-path" : "/system/framework", + "sandbox-path" : "/system/framework", + "sandbox-flags" : [ "bind", "rec" ], + "check-action-status": "false" }, { "src-path" : "/system/etc/hosts", "sandbox-path" : "/data/service/el1/network/hosts_user/hosts", @@ -637,8 +647,8 @@ "sandbox-flags" : [ "bind", "rec" ], "check-action-status": "false" }, { - "src-path" : "/data/app/el1//shader_cache/", - "sandbox-path" : "/data/storage/shader_cache/local", + "src-path" : "/data/app/el1//system_optimize//shader_cache", + "sandbox-path" : "/data/storage/system_optimize/shader_cache", "sandbox-flags" : [ "bind", "rec" ], "check-action-status": "false" }, { @@ -701,6 +711,12 @@ "src-path": "/mnt/data//userExternal", "sandbox-path": "/storage/userExternal", "sandbox-flags": [ "bind", "rec" ] + }, + { + "src-path": "", + "sandbox-path": "", + "sandbox-flags": [], + "dec-paths": [ "/storage/Users//appdata/el2/shareFiles" ] } ] }], @@ -746,30 +762,14 @@ }, { "src-path": "/mnt/user//sharefs/docs", - "sandbox-path": "/mnt/storage/Users", - "sandbox-flags": [ "bind", "rec" ] - }, - { - "src-path": "/mnt/sandbox///mnt/storage/Users", "sandbox-path": "/storage/Users", - "sandbox-flags-customized": [ "MS_NODEV"], - "dac-override-sensitive": "true", - "fs-type": "sharefs", - "options": "override" + "sandbox-flags": [ "bind", "rec" ] }, { "src-path": "/mnt/data//userExternal", - "sandbox-path": "/mnt/storage/userExternal", + "sandbox-path": "/storage/userExternal", "sandbox-flags": [ "bind", "rec" ], "check-action-status": "false" - }, - { - "src-path": "/mnt/sandbox///mnt/storage/userExternal", - "sandbox-path": "/storage/userExternal", - "sandbox-flags-customized": [ "MS_NODEV" ], - "dac-override-sensitive": "true", - "fs-type": "sharefs", - "options": "override_support_delete" } ] }], @@ -781,7 +781,7 @@ "sandbox-flags": [ "bind", "rec" ] }, { - "src-path": "/mnt/sandbox///mnt/storage/Users", + "src-path": "/mnt/sandbox///mnt/storage/Users", "sandbox-path": "/storage/Users", "sandbox-flags-customized": [ "MS_NODEV"], "dac-override-sensitive": "true", @@ -797,7 +797,7 @@ "src-path": "/data/service/el1/public/themes//a/system", "sandbox-path": "/data/themes/a/system", "sandbox-flags": [ "bind", "rec" ] - }, + }, { "src-path": "/data/service/el1/public/themes//b/system", "sandbox-path": "/data/themes/b/system", @@ -815,6 +815,20 @@ } ] }], + "ohos.permission.THEME_SKIN":[{ + "sandbox-switch": "ON", + "mount-paths": [{ + "src-path": "/data/service/el1/public/themes//a/skin", + "sandbox-path": "/data/themes/a/skin", + "sandbox-flags": [ "bind", "rec" ] + }, + { + "src-path": "/data/service/el1/public/themes//b/skin", + "sandbox-path": "/data/themes/b/skin", + "sandbox-flags": [ "bind", "rec" ] + } + ] + }], "ohos.permission.GET_WALLPAPER":[{ "sandbox-switch": "ON", "mount-paths": [{ @@ -911,6 +925,11 @@ "dac-override-sensitive": "true", "fs-type": "fuse", "check-action-status": "false" + }, { + "src-path" : "", + "sandbox-path" : "", + "sandbox-flags" : [], + "dec-paths": [ "/mnt/data/fuse", "/mnt/sandbox/*//storage/Users/currentUser" ] } ] }], @@ -968,7 +987,7 @@ "check-action-status": "false" } ] - }], + }], "ohos.permission.ACCESS_FILE_CONTENT_SHARE":[{ "sandbox-switch": "ON", "gids": [1006, 1008], @@ -989,6 +1008,36 @@ } ] }], + "ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY":[{ + "sandbox-switch": "ON", + "mount-paths": [{ + "src-path": "", + "sandbox-path": "", + "sandbox-flags": [], + "dec-paths": [ "/storage/Users//Download" ] + } + ] + }], + "ohos.permission.READ_WRITE_DESKTOP_DIRECTORY":[{ + "sandbox-switch": "ON", + "mount-paths": [{ + "src-path": "", + "sandbox-path": "", + "sandbox-flags": [], + "dec-paths": [ "/storage/Users//Desktop" ] + } + ] + }], + "ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY":[{ + "sandbox-switch": "ON", + "mount-paths": [{ + "src-path": "", + "sandbox-path": "", + "sandbox-flags": [], + "dec-paths": [ "/storage/Users//Documents" ] + } + ] + }], "ohos.permission.ACCESS_FACTORY_OTA_DIR":[{ "sandbox-switch": "ON", "mount-paths": [{ @@ -1017,25 +1066,7 @@ "ohos.permission.READ_WRITE_USER_FILE":[{ "sandbox-switch": "ON", "gids": [1006], - "mount-paths": [{ - "src-path": "/storage/media//local/files/Docs", - "sandbox-path": "/storage/Users/", - "sandbox-flags": [ "bind", "rec" ], - "check-action-status": "false" - }, - { - "src-path": "/mnt/data/external", - "sandbox-path": "/storage/External", - "sandbox-flags": ["bind", "rec"], - "check-action-status": "false" - }, - { - "src-path": "/mnt/data//hmdfs", - "sandbox-path": "/storage/hmdfs", - "sandbox-flags": ["bind", "rec"], - "check-action-status": "false" - } - ] + "mount-paths": [] }], "ohos.permission.ACCESS_APP_CLONE_DIR":[{ "sandbox-switch": "ON", @@ -1056,6 +1087,11 @@ "sandbox-flags": ["bind", "rec"] } ] + }], + "ohos.permission.ACCESS_DFX_LOG_DIR":[{ + "sandbox-switch": "ON", + "gids":[1007], + "mount-paths": [] }] }] } diff --git a/appspawn.cfg b/appspawn.cfg index f81a733910fef63bbea0134b8da616d073de7449..989ab65f4fcbd0dc054b5d67a1081965fa15d955 100644 --- a/appspawn.cfg +++ b/appspawn.cfg @@ -47,17 +47,6 @@ "gid" : "appspawn", "option" : [ ] - }, - { - "name" : "NWebSpawn", - "family" : "AF_LOCAL", - "type" : "SOCK_STREAM", - "protocol" : "default", - "permissions" : "0666", - "uid" : "nwebspawn", - "gid" : "nwebspawn", - "option" : [ - ] }], "sandbox" : 0, "start-mode" : "boot", diff --git a/appspawn.gni b/appspawn.gni index cc2fd8e38fe921a917a83760cc2bc2f92d6a5841..2f0fe1f03f3a2aec362682644c947e189b9cb608 100644 --- a/appspawn.gni +++ b/appspawn.gni @@ -36,6 +36,11 @@ declare_args() { appspawn_support_code_signature = true appspawn_allow_internet_permission = false appspawn_custom_sandbox = false + appspawn_support_nosharefs = false + appspawn_support_local_debugger = false + appspawn_hitrace_option = true + appspawn_napi_preload_path = "../appspawn_preload.json" + appspawn_arkweb_preload = true } if (!defined(global_parts_info) || diff --git a/bundle.json b/bundle.json index 8deb812fb4fe4db4a302cbec67b4bc67c7595c60..6582a611239c0ac2be5f8a36beef5e42305da719 100644 --- a/bundle.json +++ b/bundle.json @@ -28,7 +28,11 @@ "appspawn_support_prefork", "appspawn_support_code_signature", "appspawn_allow_internet_permission", - "appspawn_custom_sandbox" + "appspawn_custom_sandbox", + "appspawn_support_nosharefs", + "appspawn_support_local_debugger", + "appspawn_napi_preload_path", + "appspawn_arkweb_preload" ], "rom": "296KB", "ram": "13125KB", diff --git a/etc/BUILD.gn b/etc/BUILD.gn index b23fdfc13f3d8226ea4f50236ae343a692f91a7f..961814940dfed7e0643cf439b403ac7d35a071cd 100644 --- a/etc/BUILD.gn +++ b/etc/BUILD.gn @@ -73,7 +73,7 @@ if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) { } ohos_prebuilt_etc("appspawn_preload.json") { - source = "../appspawn_preload.json" + source = appspawn_napi_preload_path part_name = "${part_name}" module_install_dir = "etc/appspawn" } diff --git a/interfaces/innerkits/include/appspawn.h b/interfaces/innerkits/include/appspawn.h index 9ac77ae8bf980de8c006e8c494215e0e231bb920..4d0c6039202dcb9e3387ae4ac78f0ad2877cf3e1 100644 --- a/interfaces/innerkits/include/appspawn.h +++ b/interfaces/innerkits/include/appspawn.h @@ -298,6 +298,7 @@ int AppSpawnClientAddPermission(AppSpawnClientHandle handle, AppSpawnReqMsgHandl #define MSG_EXT_NAME_JIT_PERMISSIONS "Permissions" #define MSG_EXT_NAME_USERID "uid" #define MSG_EXT_NAME_EXTENSION_TYPE "ExtensionType" +#define MSG_EXT_NAME_API_TARGET_VERSION "APITargetVersion" #define MSG_EXT_NAME_PARENT_UID "ParentUid" int AppSpawnReqMsgAddExtInfo(AppSpawnReqMsgHandle reqHandle, const char *name, const uint8_t *value, uint32_t valueLen); diff --git a/modules/ace_adapter/BUILD.gn b/modules/ace_adapter/BUILD.gn index 4c274652ee644f13eccf8a25d308c44ca3cecc8f..6b6489020af5cb67cd7901e41d5587808c8a57b2 100644 --- a/modules/ace_adapter/BUILD.gn +++ b/modules/ace_adapter/BUILD.gn @@ -63,4 +63,7 @@ ohos_shared_library("appspawn_ace") { } else { module_install_dir = "lib/appspawn/appspawn" } + if (appspawn_support_local_debugger) { + cflags = [ "-DSUPPORT_LOCAL_DEBUGGER" ] + } } diff --git a/modules/ace_adapter/ace_adapter.cpp b/modules/ace_adapter/ace_adapter.cpp index 37da3a22e9b2e6340837e24f64e2999ff8d9286b..1b00fe42a0d013d1913e92d26b1c167b6d9ec1f3 100644 --- a/modules/ace_adapter/ace_adapter.cpp +++ b/modules/ace_adapter/ace_adapter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -49,6 +49,7 @@ static const bool DEFAULT_PRELOAD_VALUE = false; #else static const bool DEFAULT_PRELOAD_VALUE = true; #endif +static const bool DEFAULT_PRELOAD_ETS_VALUE = false; static const std::string PRELOAD_JSON_CONFIG("/appspawn_preload.json"); typedef struct TagParseJsonContext { @@ -84,11 +85,17 @@ static int GetModuleSet(const cJSON *root, ParseJsonContext *context) static void PreloadModule(void) { + bool preloadEts = OHOS::system::GetBoolParameter("persist.appspawn.preloadets", DEFAULT_PRELOAD_ETS_VALUE); + APPSPAWN_LOGI("LoadExtendLib: preloadets param value is %{public}s", preloadEts ? "true" : "false"); + OHOS::AbilityRuntime::Runtime::Options options; - options.lang = OHOS::AbilityRuntime::Runtime::Language::JS; options.loadAce = true; options.preload = true; - + if (preloadEts) { + options.lang = OHOS::AbilityRuntime::Runtime::Language::ETS; + } else { + options.lang = OHOS::AbilityRuntime::Runtime::Language::JS; + } auto runtime = OHOS::AbilityRuntime::Runtime::Create(options); if (!runtime) { APPSPAWN_LOGE("LoadExtendLib: Failed to create runtime"); @@ -108,7 +115,7 @@ static void PreloadModule(void) static void LoadExtendLib(void) { const char *acelibdir = OHOS::Ace::AceForwardCompatibility::GetAceLibName(); - APPSPAWN_LOGI("LoadExtendLib: Start calling dlopen acelibdir."); + APPSPAWN_LOGI("LoadExtendLib: Start calling dlopen acelibdir"); void *aceAbilityLib = dlopen(acelibdir, RTLD_NOW | RTLD_LOCAL); APPSPAWN_CHECK(aceAbilityLib != nullptr, return, "Fail to dlopen %{public}s, [%{public}s]", acelibdir, dlerror()); APPSPAWN_LOGI("LoadExtendLib: Success to dlopen %{public}s", acelibdir); @@ -116,22 +123,23 @@ static void LoadExtendLib(void) OHOS::AppExecFwk::MainThread::PreloadExtensionPlugin(); bool preload = OHOS::system::GetBoolParameter("persist.appspawn.preload", DEFAULT_PRELOAD_VALUE); if (!preload) { - APPSPAWN_LOGI("LoadExtendLib: Do not preload JS VM"); + APPSPAWN_LOGI("LoadExtendLib: Do not preload VM"); return; } - APPSPAWN_LOGI("LoadExtendLib: Start preload JS VM"); + APPSPAWN_LOGI("LoadExtendLib: Start preload VM"); SetTraceDisabled(true); PreloadModule(); SetTraceDisabled(false); + APPSPAWN_LOGI("LoadExtendLib: Start reclaim file cache"); OHOS::Ace::AceForwardCompatibility::ReclaimFileCache(getpid()); Resource::ResourceManager *systemResMgr = Resource::GetSystemResourceManagerNoSandBox(); APPSPAWN_CHECK(systemResMgr != nullptr, return, "Fail to get system resource manager"); - APPSPAWN_LOGI("LoadExtendLib: End preload JS VM"); + APPSPAWN_LOGI("LoadExtendLib: End preload VM"); } -APPSPAWN_STATIC void PreloadCJLibs(void) +static void PreloadCJLibs(void) { const char* cjEnvLibName = "libcj_environment.z.so"; const char* cjEnvInitName = "OHOS_InitSpawnEnv"; @@ -147,7 +155,7 @@ APPSPAWN_STATIC void PreloadCJLibs(void) initSpawnEnv(); } -APPSPAWN_STATIC void LoadExtendCJLib(void) +static void LoadExtendCJLib(void) { const char *acelibdir = OHOS::Ace::AceForwardCompatibility::GetAceLibName(); APPSPAWN_LOGI("LoadExtendLib: Start calling dlopen acelibdir."); @@ -160,7 +168,7 @@ APPSPAWN_STATIC void LoadExtendCJLib(void) PreloadCJLibs(); } -APPSPAWN_STATIC int BuildFdInfoMap(const AppSpawnMsgNode *message, std::map &fdMap, int isColdRun) +static int BuildFdInfoMap(const AppSpawnMsgNode *message, std::map &fdMap, int isColdRun) { APPSPAWN_CHECK_ONLY_EXPER(message != NULL && message->buffer != NULL, return -1); APPSPAWN_CHECK_ONLY_EXPER(message->tlvOffset != NULL, return -1); @@ -206,7 +214,7 @@ APPSPAWN_STATIC int BuildFdInfoMap(const AppSpawnMsgNode *message, std::map> BITLEN32); capData[0].permitted = (__u32)(permitted); @@ -153,6 +190,10 @@ static int SetCapabilities(const AppSpawnMgr *content, const AppSpawningCtx *pro // set capabilities isRet = capset(&capHeader, &capData[0]) != 0; APPSPAWN_CHECK(!isRet, return -errno, "Failed to capset errno: %{public}d", errno); +#ifdef APPSPAWN_SUPPORT_NOSHAREFS + isRet = SetAmbientCapabilities(property); + APPSPAWN_CHECK(!isRet, return -1, "Failed to set ambient"); +#endif return 0; } @@ -225,7 +266,9 @@ static int SetXpmConfig(const AppSpawnMgr *content, const AppSpawningCtx *proper idType = PROCESS_OWNERID_APP; ownerId = ownerInfo->ownerId; } - int ret = InitXpm(jitfortEnable, idType, ownerId); + + char *apiTargetVersionStr = GetAppPropertyExt(property, MSG_EXT_NAME_API_TARGET_VERSION, &len); + int ret = InitXpm(jitfortEnable, idType, ownerId, apiTargetVersionStr); APPSPAWN_CHECK(ret == 0, return ret, "set xpm region failed: %{public}d", ret); #endif return 0; @@ -469,9 +512,25 @@ static void SpawnLoadSilk(const AppSpawnMgr *content, const AppSpawningCtx *prop { const char *processName = GetBundleName(property); APPSPAWN_CHECK(processName != NULL, return, "Can not get bundle name"); - LoadSilkLibrary(processName); + (void)LoadSilkLibrary(processName); } +#ifdef APPSPAWN_HITRACE_OPTION +APPSPAWN_STATIC int FilterAppSpawnTrace(AppSpawnMgr *content, AppSpawningCtx *property) +{ + const char *processName = GetProcessName(property); + if (processName != NULL) { + pid_t pid = getpid(); + APPSPAWN_LOGV("processName: %{public}s pid: %{public}d", processName, pid); + FilterAppTrace(processName, pid); + } else { + APPSPAWN_LOGV("processName is NULL"); + } + + return 0; +} +#endif + static int SpawnSetProperties(AppSpawnMgr *content, AppSpawningCtx *property) { APPSPAWN_LOGV("Spawning: set child property"); @@ -639,6 +698,9 @@ MODULE_CONSTRUCTOR(void) AddAppSpawnHook(STAGE_CHILD_PRE_COLDBOOT, HOOK_PRIO_HIGHEST, SpawnInitSpawningEnv); AddAppSpawnHook(STAGE_CHILD_PRE_COLDBOOT, HOOK_PRIO_COMMON + 1, SpawnSetAppEnv); AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_HIGHEST, SpawnEnableCache); +#ifdef APPSPAWN_HITRACE_OPTION + AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_COMMON, FilterAppSpawnTrace); +#endif AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_PROPERTY, SpawnSetProperties); AddAppSpawnHook(STAGE_CHILD_POST_RELY, HOOK_PRIO_HIGHEST, SpawnComplete); AddAppSpawnHook(STAGE_PARENT_POST_FORK, HOOK_PRIO_HIGHEST, CloseFdArgs); diff --git a/modules/common/appspawn_namespace.c b/modules/common/appspawn_namespace.c index 8122410fee0cb3f3690732b197a201110b930bca..e128c4ae55627b5ed4c655c4882a9e69fb6a0323 100644 --- a/modules/common/appspawn_namespace.c +++ b/modules/common/appspawn_namespace.c @@ -39,7 +39,7 @@ typedef struct TagAppSpawnNamespace { } AppSpawnNamespace; APPSPAWN_STATIC pid_t GetPidByName(const char *name); -static int AppSpawnExtDataCompareDataId(ListNode *node, void *data) +APPSPAWN_STATIC int AppSpawnExtDataCompareDataId(ListNode *node, void *data) { AppSpawnExtData *extData = (AppSpawnExtData *)ListEntry(node, AppSpawnExtData, node); return extData->dataId - *(uint32_t *)data; @@ -223,7 +223,7 @@ APPSPAWN_STATIC int PreLoadEnablePidNs(AppSpawnMgr *content) } // after calling setns, new process will be in the same pid namespace of the input pid -static int SetPidNamespace(int nsPidFd, int nsType) +APPSPAWN_STATIC int SetPidNamespace(int nsPidFd, int nsType) { APPSPAWN_LOGI("SetPidNamespace 0x%{public}x", nsType); #ifndef APPSPAWN_TEST diff --git a/modules/common/appspawn_silk.c b/modules/common/appspawn_silk.c index 37478b99a498c2f18321a84902020276a94614cb..ee349404fe7624bdbd5b0c0fee48be4cb3d9b1ee 100644 --- a/modules/common/appspawn_silk.c +++ b/modules/common/appspawn_silk.c @@ -27,33 +27,52 @@ #define SILK_JSON_CONFIG_PATH "/vendor/etc/silk/silk.json" #define SILK_JSON_ENABLE_ITEM "enabled_app_list" -#define SILK_JSON_LIBRARY_PATH "/vendor/lib64/chipsetsdk/libsilk.so.0.1" +#define SILK_JSON_LIBRARY_PATH "libsilk.so.0.1" #define SILK_JSON_MAX 128 #define SILK_JSON_NAME_MAX 256 -struct SilkConfig { - char **configItems; - int configCursor; -}; +APPSPAWN_STATIC struct SilkConfig g_silkConfig = {0}; -static struct SilkConfig g_silkConfig = {0}; +static void FreeSilkConfigItems(void) +{ + for (int i = 0; i < g_silkConfig.configCursor; i++) { + if (g_silkConfig.configItems[i] != NULL) { + free(g_silkConfig.configItems[i]); + g_silkConfig.configItems[i] = NULL; + } + } +} + +static void FreeSilkConfig(void) +{ + free(g_silkConfig.configItems); + g_silkConfig.configItems = NULL; + g_silkConfig.configCursor = 0; +} + +static void FreeAllSilkConfig(void) +{ + FreeSilkConfigItems(); + FreeSilkConfig(); +} -static void ParseSilkConfig(const cJSON *root, struct SilkConfig *config) +APPSPAWN_STATIC bool ParseSilkConfig(const cJSON *root, struct SilkConfig *config) { + bool isSuccess = false; cJSON *silkJson = cJSON_GetObjectItemCaseSensitive(root, SILK_JSON_ENABLE_ITEM); if (silkJson == NULL) { - return; + return isSuccess; } uint32_t configCount = (uint32_t)cJSON_GetArraySize(silkJson); APPSPAWN_CHECK(configCount <= SILK_JSON_MAX, configCount = SILK_JSON_MAX, "config count %{public}u is larger than %{public}d", configCount, SILK_JSON_MAX); config->configItems = (char **)malloc(configCount * sizeof(char *)); - APPSPAWN_CHECK(config->configItems != NULL, return, "Alloc for silk config items failed"); + APPSPAWN_CHECK(config->configItems != NULL, return isSuccess, "Alloc for silk config items failed"); int ret = memset_s(config->configItems, configCount * sizeof(char *), 0, configCount * sizeof(char *)); APPSPAWN_CHECK(ret == 0, free(config->configItems); - config->configItems = NULL; return, + config->configItems = NULL; return isSuccess, "Memset silk config items failed"); for (uint32_t i = 0; i < configCount; ++i) { @@ -78,46 +97,36 @@ static void ParseSilkConfig(const cJSON *root, struct SilkConfig *config) *item = NULL; break, "Copy config item %{public}s failed", appName); config->configCursor++; + if (i == configCount -1) { + isSuccess = true; + } + } + if (!isSuccess) { + FreeAllSilkConfig(); } + return isSuccess; } void LoadSilkConfig(void) { cJSON *root = GetJsonObjFromFile(SILK_JSON_CONFIG_PATH); APPSPAWN_CHECK(root != NULL, return, "Failed to load silk config"); - ParseSilkConfig(root, &g_silkConfig); + (void)ParseSilkConfig(root, &g_silkConfig); cJSON_Delete(root); } -static void FreeSilkConfigItems(void) +bool LoadSilkLibrary(const char *packageName) { - for (int i = 0; i < g_silkConfig.configCursor; i++) { - if (g_silkConfig.configItems[i] != NULL) { - free(g_silkConfig.configItems[i]); - g_silkConfig.configItems[i] = NULL; - } + bool isSuccess = false; + if (g_silkConfig.configItems == NULL) { + APPSPAWN_LOGV("ConfigItems is NULL"); + return isSuccess; + } + if (packageName == NULL) { + APPSPAWN_LOGV("PackageName is NULL"); + FreeAllSilkConfig(); + return isSuccess; } -} - -static void FreeSilkConfig(void) -{ - free(g_silkConfig.configItems); - g_silkConfig.configItems = NULL; - g_silkConfig.configCursor = 0; -} - -static void FreeAllSilkConfig(void) -{ - FreeSilkConfigItems(); - FreeSilkConfig(); -} - -void LoadSilkLibrary(const char *packageName) -{ - APPSPAWN_CHECK(g_silkConfig.configItems != NULL, return, - "ConfigItems is NULL"); - APPSPAWN_CHECK(packageName != NULL, FreeAllSilkConfig(); return, - "PackageName is NULL"); char **appName = NULL; void *handle = NULL; for (int i = 0; i < g_silkConfig.configCursor; i++) { @@ -127,6 +136,9 @@ void LoadSilkLibrary(const char *packageName) } if (handle == NULL && strcmp(*appName, packageName) == 0) { handle = dlopen(SILK_JSON_LIBRARY_PATH, RTLD_NOW); + if (handle != NULL) { + isSuccess = true; + } APPSPAWN_LOGI("Enable Silk AppName %{public}s result:%{public}s", *appName, handle ? "success" : "failed"); } @@ -134,4 +146,5 @@ void LoadSilkLibrary(const char *packageName) *appName = NULL; } FreeSilkConfig(); + return isSuccess; } \ No newline at end of file diff --git a/modules/common/appspawn_silk.h b/modules/common/appspawn_silk.h index e95a6bf8c3df2212c80e18a18da904bfc44c3af7..073ae087cd1b9d0150238d44ad0dadb44665859e 100644 --- a/modules/common/appspawn_silk.h +++ b/modules/common/appspawn_silk.h @@ -16,7 +16,12 @@ #ifndef APPSPAWN_SILK_CPP #define APPSPAWN_SILK_CPP +struct SilkConfig { + char **configItems; + int configCursor; +}; + void LoadSilkConfig(void); -void LoadSilkLibrary(const char *packageName); +bool LoadSilkLibrary(const char *packageName); -#endif \ No newline at end of file +#endif diff --git a/modules/native_adapter/BUILD.gn b/modules/native_adapter/BUILD.gn index 4a41ac595499b3d58827ad5a88a88ca41d4eb55d..e1819d51fbe798ea590241931008e3b239d39b84 100644 --- a/modules/native_adapter/BUILD.gn +++ b/modules/native_adapter/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2024 Huawei Device Co., Ltd. +# Copyright (c) 2024-2025 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -40,6 +40,9 @@ ohos_shared_library("nativespawn") { "init:libbegetutil", "napi:ace_napi", ] + if (!defined(APPSPAWN_TEST)) { + external_deps += [ "common_event_service:cesfwk_innerkits" ] + } subsystem_name = "${subsystem_name}" part_name = "${part_name}" install_enable = true diff --git a/modules/nweb_adapter/BUILD.gn b/modules/nweb_adapter/BUILD.gn index acd15abe223a366520e29f0fe8fac4c159b09e25..35ea32b4abe1dd890907acd4f1b0ce703523acdb 100644 --- a/modules/nweb_adapter/BUILD.gn +++ b/modules/nweb_adapter/BUILD.gn @@ -31,6 +31,9 @@ ohos_shared_library("appspawn_nweb") { if (target_cpu == "x86_64") { defines += [ "webview_x86_64" ] } + if (appspawn_arkweb_preload) { + defines += [ "preload_rk3568" ] + } external_deps = [ "c_utils:utils", diff --git a/modules/nweb_adapter/nwebspawn_adapter.cpp b/modules/nweb_adapter/nwebspawn_adapter.cpp index 6d0ae2730e1c37f3b222eb38d6a901f029eb14de..9bd890e806aa56393ee64c7479800565a3fe2701 100644 --- a/modules/nweb_adapter/nwebspawn_adapter.cpp +++ b/modules/nweb_adapter/nwebspawn_adapter.cpp @@ -29,6 +29,7 @@ #include "appspawn_hook.h" #include "appspawn_manager.h" +#include "parameter.h" #ifdef WITH_SECCOMP #include "seccomp_policy.h" @@ -49,6 +50,23 @@ namespace { const std::string ARK_WEB_RENDER_LIB_NAME = "libarkweb_render.so"; const std::string WEB_ENGINE_LIB_NAME = "libweb_engine.so"; const std::string WEB_RENDER_LIB_NAME = "libnweb_render.so"; + const std::string ARK_WEB_ENGINE_LIB_PRELOAD_PATH = + "/data/app/el1/bundle/public/com.huawei.hmos.arkwebcore/libs/arm64"; + const std::string OHOS_ADPT_GLUE_SRC_LIB_PATH = + "/system/lib64/libohos_adapter_glue_source.z.so"; + +#if defined(preload_rk3568) + const std::string ARKWEB_BUNDLE_NAME = "com.ohos.arkwebcore"; +#else + const std::string ARKWEB_BUNDLE_NAME = "com.huawei.hmos.arkwebcore"; +#endif + +typedef enum { + PRELOAD_NO = 0, // 不预加载 + PRELOAD_PARTIAL = 1, // 只预加载libohos_adapter_glue_source.z.so + PRELOAD_FULL = 2 // 预加载libohos_adapter_glue_source.z.so和libarkweb_engine.so +} RenderPreLoadMode; + } // namespace static bool SetSeccompPolicyForRenderer(void *nwebRenderHandle) @@ -148,6 +166,68 @@ APPSPAWN_STATIC int RunChildProcessor(AppSpawnContent *content, AppSpawnClient * return 0; } +static std::string GetOHOSAdptGlueSrcLibPath() +{ +#if defined(webview_arm64) + const std::string ARK_WEB_CORE_HAP_LIB_PATH = + "/system/lib64/libohos_adapter_glue_source.z.so"; +#else + const std::string ARK_WEB_CORE_HAP_LIB_PATH = + "/system/lib/libohos_adapter_glue_source.z.so"; +#endif + return ARK_WEB_CORE_HAP_LIB_PATH; +} + +static std::string GetArkWebEngineLibPath() +{ +#if defined(webview_arm64) + const std::string ARK_WEB_CORE_HAP_LIB_PATH = + "/data/app/el1/bundle/public/" + ARKWEB_BUNDLE_NAME + "/libs/arm64"; +#elif defined(webview_x86_64) + const std::string ARK_WEB_CORE_HAP_LIB_PATH = + "/data/app/el1/bundle/public/" + ARKWEB_BUNDLE_NAME + "/libs/x86_64"; +#else + const std::string ARK_WEB_CORE_HAP_LIB_PATH = + "/data/app/el1/bundle/public/" + ARKWEB_BUNDLE_NAME + "/libs/arm"; +#endif + return ARK_WEB_CORE_HAP_LIB_PATH; +} + +static void PreLoadArkWebEngineLib() +{ + Dl_namespace dlns; + Dl_namespace ndkns; + dlns_init(&dlns, "nweb_ns"); + const std::string arkWebEngineLibPath = GetArkWebEngineLibPath(); + dlns_create(&dlns, arkWebEngineLibPath.c_str()); + dlns_get("ndk", &ndkns); + dlns_inherit(&dlns, &ndkns, "allow_all_shared_libs"); + void *webEngineHandle = dlopen_ns(&dlns, ARK_WEB_ENGINE_LIB_NAME.c_str(), RTLD_NOW | RTLD_GLOBAL); + if (!webEngineHandle) { + APPSPAWN_LOGE("Fail to dlopen libarkweb_engine.so, errno: %{public}d", errno); + } +} + +static void PreLoadOHOSAdptGlueSrcLib() +{ + const std::string ohosAdptGlueSrcLibPath = GetOHOSAdptGlueSrcLibPath(); + void *ohosAdptGlueSrcHandle = dlopen(ohosAdptGlueSrcLibPath.c_str(), RTLD_NOW | RTLD_GLOBAL); + if (!ohosAdptGlueSrcHandle) { + APPSPAWN_LOGE("Fail to dlopen libohos_adapter_glue_source.z.so, errno: %{public}d", errno); + } +} + +#if !defined(preload_rk3568) +static int GetSysParamPreLoadMode() +{ + const int BUFFER_LEN = 8; + char preLoadMode[BUFFER_LEN] = {0}; + GetParameter("const.startup.nwebspawn.preloadMode", "0", preLoadMode, BUFFER_LEN); + int ret = std::atoi(preLoadMode); + return ret; +} +#endif + static int PreLoadNwebSpawn(AppSpawnMgr *content) { APPSPAWN_LOGI("PreLoadNwebSpawn %{public}d", IsNWebSpawnMode(content)); @@ -156,6 +236,22 @@ static int PreLoadNwebSpawn(AppSpawnMgr *content) } // register RegChildLooper(&content->content, RunChildProcessor); + + // preload render lib +#if defined(preload_rk3568) + int preloadMode = RenderPreLoadMode::PRELOAD_FULL; +#else + int preloadMode = GetSysParamPreLoadMode(); +#endif + APPSPAWN_LOGI("NwebSpawn preload render lib mode: %{public}d", preloadMode); + if (preloadMode == PRELOAD_PARTIAL) { + PreLoadOHOSAdptGlueSrcLib(); + } + if (preloadMode == PRELOAD_FULL) { + PreLoadArkWebEngineLib(); + PreLoadOHOSAdptGlueSrcLib(); + } + return 0; } diff --git a/modules/sandbox/BUILD.gn b/modules/sandbox/BUILD.gn index 194a49573d6fc1b1acd644ad5ce5095d7d1d5be7..4e314e0d7f92abf8609cf0d2840490823eb899cc 100644 --- a/modules/sandbox/BUILD.gn +++ b/modules/sandbox/BUILD.gn @@ -17,16 +17,17 @@ import("//build/ohos.gni") if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) { ohos_shared_library("appspawn_sandbox") { sources = [ - "appspawn_mount_template.c", + "modern/appspawn_mount_template.c", + "modern/appspawn_sandbox.c", + "modern/sandbox_adapter.cpp", + "modern/sandbox_cfgvar.c", + "modern/sandbox_debug_mode.c", + "modern/sandbox_expand.c", + "modern/sandbox_load.c", + "modern/sandbox_manager.c", + "modern/sandbox_shared.c", "appspawn_permission.c", - "appspawn_sandbox.c", - "sandbox_adapter.cpp", - "sandbox_cfgvar.c", - "sandbox_debug_mode.c", - "sandbox_expand.c", - "sandbox_load.c", - "sandbox_manager.c", - "sandbox_shared.c", + "sandbox_dec.c", ] include_dirs = [ @@ -80,12 +81,16 @@ if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) { sources = [ "${appspawn_innerkits_path}/permission/appspawn_mount_permission.c", "appspawn_permission.c", - "sandbox_shared_mount.cpp", - "sandbox_utils.cpp", + "sandbox_dec.c", + "normal/sandbox_shared_mount.cpp", + "normal/appspawn_sandbox_manager.cpp", + "normal/sandbox_common.cpp", + "normal/sandbox_core.cpp" ] include_dirs = [ ".", + "./normal", "${appspawn_path}/common", "${appspawn_path}/standard", "${appspawn_innerkits_path}/client", @@ -123,6 +128,9 @@ if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) { include_dirs += [ "${appspawn_path}/modules/sysevent" ] sources += [ "${appspawn_path}/modules/sysevent/hisysevent_adapter.cpp" ] } + if (appspawn_support_nosharefs) { + defines += [ "APPSPAWN_SUPPORT_NOSHAREFS" ] + } subsystem_name = "${subsystem_name}" part_name = "${part_name}" diff --git a/modules/sandbox/appspawn_mount_template.c b/modules/sandbox/modern/appspawn_mount_template.c similarity index 100% rename from modules/sandbox/appspawn_mount_template.c rename to modules/sandbox/modern/appspawn_mount_template.c diff --git a/modules/sandbox/appspawn_sandbox.c b/modules/sandbox/modern/appspawn_sandbox.c similarity index 92% rename from modules/sandbox/appspawn_sandbox.c rename to modules/sandbox/modern/appspawn_sandbox.c index 5f4f446c94c7231b8b752f1ea5fc798ad18e39b0..6c5e795cdedb8539d75e129c29ce3e7e337a777b 100644 --- a/modules/sandbox/appspawn_sandbox.c +++ b/modules/sandbox/modern/appspawn_sandbox.c @@ -38,6 +38,7 @@ #include "init_utils.h" #include "parameter.h" #include "appspawn_permission.h" +#include "sandbox_dec.h" #ifdef WITH_SELINUX #ifdef APPSPAWN_MOUNT_TMPSHM @@ -447,6 +448,97 @@ static int DoSandboxMountByCategory(const SandboxContext *context, const PathMou return ret; } +static void FreeDecPolicyPaths(DecPolicyInfo *decPolicyInfo) +{ + if (decPolicyInfo == NULL) { + return; + } + + for (uint32_t i = 0; i < decPolicyInfo->pathNum; i++) { + if (decPolicyInfo->path[i].path != NULL) { + free(decPolicyInfo->path[i].path); + } + } + + decPolicyInfo->pathNum = 0; +} + +static int SetDecPolicyWithCond(const SandboxContext *context, const PathMountNode *sandboxNode, + VarExtraData *extraData) +{ + if (sandboxNode == NULL || sandboxNode->decPolicyPaths.decPathCount == 0) { + return 0; + } + + AppSpawnMsgAccessToken *tokenInfo = (AppSpawnMsgAccessToken *)GetSandboxCtxMsgInfo(context, TLV_ACCESS_TOKEN_INFO); + APPSPAWN_CHECK(tokenInfo != NULL, return APPSPAWN_MSG_INVALID, "Get token id failed."); + + DecPolicyInfo decPolicyInfo = {0}; + decPolicyInfo.pathNum = sandboxNode->decPolicyPaths.decPathCount; + + for (uint32_t i = 0; i < decPolicyInfo.pathNum; i++) { + const char *realDecPath = GetSandboxRealVar(context, BUFFER_FOR_TARGET, sandboxNode->decPolicyPaths.decPath[i], + NULL, extraData); + if (realDecPath == NULL) { + // Handle the error appropriately if needed + continue; + } + decPolicyInfo.path[i].path = strdup(realDecPath); + if (decPolicyInfo.path[i].path == NULL) { + // Free already allocated paths before returning + FreeDecPolicyPaths(&decPolicyInfo); + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + decPolicyInfo.path[i].pathLen = (uint32_t)strlen(decPolicyInfo.path[i].path); + decPolicyInfo.path[i].mode = SANDBOX_MODE_WRITE | SANDBOX_MODE_READ; + } + + decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx; + decPolicyInfo.flag = true; + SetDecPolicyInfos(&decPolicyInfo); + FreeDecPolicyPaths(&decPolicyInfo); + return 0; +} + +static int SetDecPolicyWithDir(const SandboxContext *context) +{ + AppSpawnMsgAccessToken *tokenInfo = (AppSpawnMsgAccessToken *)GetSandboxCtxMsgInfo(context, TLV_ACCESS_TOKEN_INFO); + AppSpawnMsgBundleInfo *bundleInfo = (AppSpawnMsgBundleInfo *)GetSandboxCtxMsgInfo(context, TLV_BUNDLE_INFO); + APPSPAWN_CHECK(tokenInfo != NULL && bundleInfo != NULL, return APPSPAWN_MSG_INVALID, + "Get token info or bundle info failed."); + + uint32_t flags = CheckAppSpawnMsgFlag(context->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE) ? 0x4 : 0; + if (flags == 0) { + flags = (CheckAppSpawnMsgFlag(context->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE) && + bundleInfo->bundleIndex > 0) ? 0x1 : 0; + } + int ret = 0; + char downloadDir[PATH_MAX] = {0}; + if (flags == 1) { + ret = snprintf_s(downloadDir, PATH_MAX, PATH_MAX - 1, "/storage/Users/currentUser/Download/+clone-%d+%s", + bundleInfo->bundleIndex, bundleInfo->bundleName); + } else { + ret = snprintf_s(downloadDir, PATH_MAX, PATH_MAX - 1, "/storage/Users/currentUser/Download/%s", + bundleInfo->bundleName); + } + APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL, + "snprintf_s download path failed, ret %{public}d, err %{public}d", ret, errno); + + DecPolicyInfo decPolicyInfo = {0}; + decPolicyInfo.pathNum = 1; + PathInfo pathInfo = {0}; + pathInfo.path = downloadDir; + pathInfo.pathLen = (uint32_t)strlen(pathInfo.path); + pathInfo.mode = SANDBOX_MODE_WRITE | SANDBOX_MODE_READ; + decPolicyInfo.path[0] = pathInfo; + decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx; + decPolicyInfo.flag = true; + + SetDecPolicyInfos(&decPolicyInfo); + return 0; +} + static int DoSandboxPathNodeMount(const SandboxContext *context, const SandboxSection *section, const PathMountNode *sandboxNode, uint32_t operation) { @@ -483,7 +575,7 @@ static int DoSandboxPathNodeMount(const SandboxContext *context, int ret = 0; if (CHECK_FLAGS_BY_INDEX(operation, MOUNT_PATH_OP_UNMOUNT)) { // unmount this deps - APPSPAWN_LOGV("umount2 %{public}s", args.destinationPath); + APPSPAWN_LOGI("umount2 %{public}s", args.destinationPath); ret = umount2(args.destinationPath, MNT_DETACH); APPSPAWN_CHECK_ONLY_LOG(ret == 0, "Failed to umount %{public}s errno %{public}d", args.destinationPath, errno); } @@ -494,7 +586,12 @@ static int DoSandboxPathNodeMount(const SandboxContext *context, section->name, ret, category); return ret; } - return 0; + + ret = SetDecPolicyWithCond(context, sandboxNode, extraData); + if (ret != 0) { + APPSPAWN_LOGE("Failed to set dec policy with conditional: %{public}d", ret); + } + return ret; } static int DoSandboxPathSymLink(const SandboxContext *context, @@ -836,7 +933,7 @@ static void UnmountPath(char *rootPath, uint32_t len, const SandboxMountNode *sa PathMountNode *pathNode = (PathMountNode *)sandboxNode; int ret = strcat_s(rootPath, len, pathNode->target); APPSPAWN_CHECK(ret == 0, return, "Failed to format"); - APPSPAWN_LOGV("Unmount sandbox config sandbox path %{public}s ", rootPath); + APPSPAWN_LOGI("Unmount sandbox config sandbox path %{public}s ", rootPath); ret = umount2(rootPath, MNT_DETACH); APPSPAWN_CHECK_ONLY_LOG(ret == 0, "Failed to umount2 %{public}s errno: %{public}d", rootPath, errno); } @@ -1249,6 +1346,8 @@ int MountSandboxConfigs(AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *prope #endif ret = ChangeCurrentDir(context); APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break); + SetDecPolicyWithDir(context); + SetDecPolicy(); #if defined(APPSPAWN_MOUNT_TMPSHM) && defined(WITH_SELINUX) Restorecon(DEV_SHM_DIR); #endif diff --git a/modules/sandbox/appspawn_sandbox.h b/modules/sandbox/modern/appspawn_sandbox.h similarity index 98% rename from modules/sandbox/appspawn_sandbox.h rename to modules/sandbox/modern/appspawn_sandbox.h index 0cfd55585c1365b556bc79947cee4a1f470f85db..b0065e02b5ba3ab8c48ee9c08615a29ce1795791 100644 --- a/modules/sandbox/appspawn_sandbox.h +++ b/modules/sandbox/modern/appspawn_sandbox.h @@ -122,6 +122,11 @@ typedef struct { uint32_t mode; } PathDemandInfo; +typedef struct { + uint32_t decPathCount; // dec放行目录数量 + char **decPath; // dec放行目录数组 +} DecPolicyPaths; + typedef struct TagPathMountNode { SandboxMountNode sandboxNode; char *source; // source 目录,一般是全局的fs 目录 @@ -134,6 +139,7 @@ typedef struct TagPathMountNode { uint32_t category; char *appAplName; PathDemandInfo demandInfo[0]; + DecPolicyPaths decPolicyPaths; } PathMountNode; typedef struct TagSymbolLinkNode { diff --git a/modules/sandbox/sandbox_adapter.cpp b/modules/sandbox/modern/sandbox_adapter.cpp similarity index 99% rename from modules/sandbox/sandbox_adapter.cpp rename to modules/sandbox/modern/sandbox_adapter.cpp index 4eccf2f54f0f24f7cce438babc06b0caf1e9f96f..6f0bcbb82b42e979e0cdcfe4c571e4a93b3f4aec 100644 --- a/modules/sandbox/sandbox_adapter.cpp +++ b/modules/sandbox/modern/sandbox_adapter.cpp @@ -13,6 +13,8 @@ * limitations under the License. */ +#include + #include "sandbox_adapter.h" #include "init_utils.h" diff --git a/modules/sandbox/sandbox_adapter.h b/modules/sandbox/modern/sandbox_adapter.h similarity index 100% rename from modules/sandbox/sandbox_adapter.h rename to modules/sandbox/modern/sandbox_adapter.h diff --git a/modules/sandbox/sandbox_cfgvar.c b/modules/sandbox/modern/sandbox_cfgvar.c similarity index 100% rename from modules/sandbox/sandbox_cfgvar.c rename to modules/sandbox/modern/sandbox_cfgvar.c diff --git a/modules/sandbox/sandbox_debug_mode.c b/modules/sandbox/modern/sandbox_debug_mode.c similarity index 100% rename from modules/sandbox/sandbox_debug_mode.c rename to modules/sandbox/modern/sandbox_debug_mode.c diff --git a/modules/sandbox/sandbox_expand.c b/modules/sandbox/modern/sandbox_expand.c similarity index 100% rename from modules/sandbox/sandbox_expand.c rename to modules/sandbox/modern/sandbox_expand.c diff --git a/modules/sandbox/sandbox_load.c b/modules/sandbox/modern/sandbox_load.c similarity index 94% rename from modules/sandbox/sandbox_load.c rename to modules/sandbox/modern/sandbox_load.c index 8a6741a752d0deadd560f6d4c8716c091551a800..f7a7d617f13efbe0eac16935e1ff5d96e8457969 100644 --- a/modules/sandbox/sandbox_load.c +++ b/modules/sandbox/modern/sandbox_load.c @@ -204,6 +204,57 @@ static void FillPathDemandInfo(const cJSON *config, PathMountNode *sandboxNode) sandboxNode->demandInfo->mode = GetIntValueFromJsonObj(config, "ugo", -1); } +static int32_t DecodeDecPolicyPaths(const cJSON *config, PathMountNode *sandboxNode) +{ + if (config == NULL || sandboxNode == NULL) { + return APPSPAWN_ARG_INVALID; + } + + sandboxNode->decPolicyPaths.decPathCount = 0; + sandboxNode->decPolicyPaths.decPath = NULL; + + cJSON *pathArray = cJSON_GetObjectItemCaseSensitive(config, "dec-paths"); + if (pathArray == NULL || !cJSON_IsArray(pathArray)) { + return 0; + } + + int pathCount = cJSON_GetArraySize(pathArray); + if (pathCount == 0) { + return 0; + } + size_t decPathSize = pathCount * sizeof(char *); + sandboxNode->decPolicyPaths.decPath = (char **)malloc(decPathSize); + if (sandboxNode->decPolicyPaths.decPath == NULL) { + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + for (int i = 0; i < pathCount; i++) { + cJSON *pathItem = cJSON_GetArrayItem(pathArray, i); + if (!cJSON_IsString(pathItem)) { + APPSPAWN_LOGE("path parse failed"); + goto ERROR; + } + sandboxNode->decPolicyPaths.decPath[i] = strdup(pathItem->valuestring); + if (sandboxNode->decPolicyPaths.decPath[i] == NULL) { + goto ERROR; + } + sandboxNode->decPolicyPaths.decPathCount++; + } + return 0; + +ERROR: + for (int i = 0; i < pathCount; i++) { + if (sandboxNode->decPolicyPaths.decPath[i] != NULL) { + free(sandboxNode->decPolicyPaths.decPath[i]); + sandboxNode->decPolicyPaths.decPath[i] = NULL; + } + } + sandboxNode->decPolicyPaths.decPathCount = 0; + free(sandboxNode->decPolicyPaths.decPath); + sandboxNode->decPolicyPaths.decPath = NULL; + return -1; +} + static PathMountNode *DecodeMountPathConfig(const SandboxSection *section, const cJSON *config, uint32_t type) { char *srcPath = GetStringFromJsonObj(config, "src-path"); @@ -236,6 +287,11 @@ static PathMountNode *DecodeMountPathConfig(const SandboxSection *section, const } FillPathDemandInfo(demandInfo, sandboxNode); + int ret = DecodeDecPolicyPaths(config, sandboxNode); + if (ret != 0) { + APPSPAWN_LOGE("DecodeDecPolicyPaths failed %{public}d", ret); + } + if (sandboxNode->source == NULL || sandboxNode->target == NULL) { APPSPAWN_LOGE("Failed to get sourc or target path"); DeleteSandboxMountNode((SandboxMountNode *)sandboxNode); diff --git a/modules/sandbox/sandbox_manager.c b/modules/sandbox/modern/sandbox_manager.c similarity index 98% rename from modules/sandbox/sandbox_manager.c rename to modules/sandbox/modern/sandbox_manager.c index 2885711c471196e0924fa8bba219121e4a9293af..c90d5c623f9e7f68c78313d5de3f52ccdfa784f1 100644 --- a/modules/sandbox/sandbox_manager.c +++ b/modules/sandbox/modern/sandbox_manager.c @@ -41,6 +41,15 @@ static void FreePathMountNode(SandboxMountNode *node) free(sandboxNode->appAplName); sandboxNode->appAplName = NULL; } + for (uint32_t i = 0; i < sandboxNode->decPolicyPaths.decPathCount; i++) { + if (sandboxNode->decPolicyPaths.decPath[i] != NULL) { + free(sandboxNode->decPolicyPaths.decPath[i]); + sandboxNode->decPolicyPaths.decPath[i] = NULL; + } + } + sandboxNode->decPolicyPaths.decPathCount = 0; + free(sandboxNode->decPolicyPaths.decPath); + sandboxNode->decPolicyPaths.decPath = NULL; free(sandboxNode); } @@ -800,17 +809,6 @@ static int SpawnMountDirToShared(AppSpawnMgr *content, AppSpawningCtx *property) return ret; } -APPSPAWN_STATIC int SandboxUnmountPath(const AppSpawnMgr *content, const AppSpawnedProcessInfo *appInfo) -{ - APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1); - APPSPAWN_CHECK_ONLY_EXPER(appInfo != NULL, return -1); - AppSpawnSandboxCfg *sandbox = NULL; - APPSPAWN_LOGV("Sandbox process %{public}s %{public}u exit", appInfo->name, appInfo->uid); - sandbox = GetAppSpawnSandbox(content, content->content.sandboxType); - - return UnmountDepPaths(sandbox, appInfo->uid); -} - #ifdef APPSPAWN_SANDBOX_NEW MODULE_CONSTRUCTOR(void) { @@ -824,7 +822,6 @@ MODULE_CONSTRUCTOR(void) (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_SANDBOX, SpawnPrepareSandboxCfg); (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_SANDBOX, SpawnMountDirToShared); (void)AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_SANDBOX, SpawnBuildSandboxEnv); - (void)AddProcessMgrHook(STAGE_SERVER_APP_DIED, 0, SandboxUnmountPath); } MODULE_DESTRUCTOR(void) diff --git a/modules/sandbox/sandbox_shared.c b/modules/sandbox/modern/sandbox_shared.c similarity index 100% rename from modules/sandbox/sandbox_shared.c rename to modules/sandbox/modern/sandbox_shared.c diff --git a/modules/sandbox/sandbox_shared.h b/modules/sandbox/modern/sandbox_shared.h similarity index 100% rename from modules/sandbox/sandbox_shared.h rename to modules/sandbox/modern/sandbox_shared.h diff --git a/modules/sandbox/normal/appspawn_sandbox_manager.cpp b/modules/sandbox/normal/appspawn_sandbox_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aa9224b2ef4d99e07f92103d057074915253d9c5 --- /dev/null +++ b/modules/sandbox/normal/appspawn_sandbox_manager.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "securec.h" +#include "appspawn_hook.h" +#include "appspawn_manager.h" +#include "appspawn_utils.h" +#include "sandbox_core.h" + +#define USER_ID_SIZE 16 +#define DIR_MODE 0711 + +int32_t SetAppSandboxProperty(AppSpawnMgr *content, AppSpawningCtx *property) +{ + APPSPAWN_CHECK(property != nullptr, return -1, "Invalid appspawn client"); + APPSPAWN_CHECK(content != nullptr, return -1, "Invalid appspawn content"); + // clear g_mountInfo in the child process + std::map* mapPtr = static_cast*>(GetEl1BundleMountCount()); + if (mapPtr == nullptr) { + APPSPAWN_LOGE("Get el1 bundle mount count failed"); + return APPSPAWN_ARG_INVALID; + } + mapPtr->clear(); + int ret = 0; + // no sandbox + if (CheckAppMsgFlagsSet(property, APP_FLAGS_NO_SANDBOX)) { + return 0; + } + if ((content->content.sandboxNsFlags & CLONE_NEWPID) == CLONE_NEWPID) { + ret = getprocpid(); + if (ret < 0) { + return ret; + } + } + uint32_t sandboxNsFlags = CLONE_NEWNS; + + if (OHOS::AppSpawn::SandboxCore::NeedNetworkIsolated(property)) { + sandboxNsFlags |= content->content.sandboxNsFlags & CLONE_NEWNET ? CLONE_NEWNET : 0; + } + + APPSPAWN_LOGV("SetAppSandboxProperty sandboxNsFlags 0x%{public}x", sandboxNsFlags); + + if (IsNWebSpawnMode(content)) { + ret = OHOS::AppSpawn::SandboxCore::SetAppSandboxPropertyNweb(property, sandboxNsFlags); + } else { + ret = OHOS::AppSpawn::SandboxCore::SetAppSandboxProperty(property, sandboxNsFlags); + } + // for module test do not create sandbox, use APP_FLAGS_IGNORE_SANDBOX to ignore sandbox result + if (CheckAppMsgFlagsSet(property, APP_FLAGS_IGNORE_SANDBOX)) { + APPSPAWN_LOGW("Do not care sandbox result %{public}d", ret); + return 0; + } + return ret; +} + +static int SpawnMountDirToShared(AppSpawnMgr *content, AppSpawningCtx *property) +{ +#ifndef APPSPAWN_SANDBOX_NEW + if (!IsNWebSpawnMode(content)) { + // mount dynamic directory + MountToShared(content, property); + } +#endif + return 0; +} + +static int UninstallDebugSandbox(AppSpawnMgr *content, AppSpawningCtx *property) +{ + APPSPAWN_CHECK(property != nullptr && content != nullptr, return -1, + "Invalid appspawn client or property"); + return OHOS::AppSpawn::SandboxCore::UninstallDebugSandbox(content, property); +} + +static int InstallDebugSandbox(AppSpawnMgr *content, AppSpawningCtx *property) +{ + APPSPAWN_CHECK(property != nullptr && content != nullptr, return -1, + "Invalid appspawn client or property"); + return OHOS::AppSpawn::SandboxCore::InstallDebugSandbox(content, property); +} + +static void UmountDir(const char *rootPath, const char *targetPath, const AppSpawnedProcessInfo *appInfo) +{ + size_t allPathSize = strlen(rootPath) + USER_ID_SIZE + strlen(appInfo->name) + strlen(targetPath) + 2; + char *path = reinterpret_cast(malloc(sizeof(char) * (allPathSize))); + APPSPAWN_CHECK(path != nullptr, return, "Failed to malloc path"); + + int ret = sprintf_s(path, allPathSize, "%s%u/%s%s", rootPath, appInfo->uid / UID_BASE, + appInfo->name, targetPath); + APPSPAWN_CHECK(ret > 0 && ((size_t)ret < allPathSize), free(path); + return, "Failed to get sandbox path errno %{public}d", errno); + + ret = umount2(path, MNT_DETACH); + if (ret == 0) { + APPSPAWN_LOGI("Umount2 sandbox path %{public}s success", path); + } else { + APPSPAWN_LOGW("Failed to umount2 sandbox path %{public}s errno %{public}d", path, errno); + } + free(path); +} + +static int UmountSandboxPath(const AppSpawnMgr *content, const AppSpawnedProcessInfo *appInfo) +{ + APPSPAWN_CHECK(content != nullptr && appInfo != nullptr && appInfo->name != NULL, + return -1, "Invalid content or appInfo"); + if (!IsAppSpawnMode(content)) { + return 0; + } + APPSPAWN_LOGV("UmountSandboxPath name %{public}s pid %{public}d", appInfo->name, appInfo->pid); + const char rootPath[] = "/mnt/sandbox/"; + const char el1Path[] = "/data/storage/el1/bundle"; + + std::string varBundleName = std::string(appInfo->name); + if (appInfo->appIndex > 0) { + varBundleName = "+clone-" + std::to_string(appInfo->appIndex) + "+" + varBundleName; + } + + uint32_t userId = appInfo->uid / UID_BASE; + std::string key = std::to_string(userId) + "-" + varBundleName; + std::map *el1BundleCountMap = static_cast*>(GetEl1BundleMountCount()); + if (el1BundleCountMap == nullptr || el1BundleCountMap->find(key) == el1BundleCountMap->end()) { + return 0; + } + (*el1BundleCountMap)[key]--; + if ((*el1BundleCountMap)[key] == 0) { + APPSPAWN_LOGV("no app %{public}s use it in userId %{public}u, need umount", appInfo->name, userId); + UmountDir(rootPath, el1Path, appInfo); + el1BundleCountMap->erase(key); + } else { + APPSPAWN_LOGV("app %{public}s use it mount times %{public}d in userId %{public}u, not need umount", + appInfo->name, (*el1BundleCountMap)[key], userId); + } + return 0; +} + +#ifndef APPSPAWN_SANDBOX_NEW +MODULE_CONSTRUCTOR(void) +{ + APPSPAWN_LOGV("Load sandbox module ..."); + (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, + OHOS::AppSpawn::SandboxCommon::LoadAppSandboxConfigCJson); + (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_COMMON, SpawnMountDirToShared); + (void)AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_SANDBOX, SetAppSandboxProperty); + (void)AddAppSpawnHook(STAGE_PARENT_UNINSTALL, HOOK_PRIO_SANDBOX, UninstallDebugSandbox); + (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_SANDBOX, InstallDebugSandbox); + (void)AddProcessMgrHook(STAGE_SERVER_APP_UMOUNT, HOOK_PRIO_SANDBOX, UmountSandboxPath); + (void)AddServerStageHook(STAGE_SERVER_EXIT, HOOK_PRIO_SANDBOX, + OHOS::AppSpawn::SandboxCommon::FreeAppSandboxConfigCJson); +} +#endif \ No newline at end of file diff --git a/modules/sandbox/normal/sandbox_common.cpp b/modules/sandbox/normal/sandbox_common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..efe6d560c452710c519fd08d386cc3f513f3e8cd --- /dev/null +++ b/modules/sandbox/normal/sandbox_common.cpp @@ -0,0 +1,998 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sandbox_common.h" + +#include +#include +#include +#include +#include +#include +#include "appspawn_manager.h" +#include "appspawn_utils.h" +#include "sandbox_def.h" +#include "parameters.h" +#include "init_param.h" +#include "init_utils.h" +#include "parameter.h" +#include "config_policy_utils.h" + +#ifdef WITH_SELINUX +#include "hap_restorecon.h" +#ifdef APPSPAWN_MOUNT_TMPSHM +#include "policycoreutils.h" +#endif // APPSPAWN_MOUNT_TMPSHM +#endif // WITH_SELINUX + +namespace OHOS { +namespace AppSpawn { + +int32_t SandboxCommon::deviceTypeEnable_ = -1; +std::map> SandboxCommon::appSandboxCJsonConfig_ = {}; + +// 加载配置文件 +uint32_t SandboxCommon::GetSandboxNsFlags(bool isNweb) +{ + uint32_t nsFlags = 0; + if (!IsTotalSandboxEnabled(nullptr)) { + return nsFlags; + } + + const std::map NamespaceFlagsMap = { {"pid", CLONE_NEWPID}, + {"net", CLONE_NEWNET} }; + const char *prefixStr = + isNweb ? SandboxCommonDef::g_privatePrefix : SandboxCommonDef::g_commonPrefix; + const char *baseStr = isNweb ? SandboxCommonDef::g_ohosRender.c_str() : SandboxCommonDef::g_appBase; + + auto processor = [&baseStr, &NamespaceFlagsMap, &nsFlags](cJSON *item) { + cJSON *internal = cJSON_GetObjectItemCaseSensitive(item, baseStr); + if (!internal || !cJSON_IsArray(internal)) { + return 0; + } + + // 获取数组中第一个元素 + cJSON *firstElem = cJSON_GetArrayItem(internal, 0); + if (!firstElem) { + return 0; + } + + // 获取 "sandbox-ns-flags" 数组 + cJSON *nsFlagsJson = cJSON_GetObjectItemCaseSensitive(firstElem, SandboxCommonDef::g_sandBoxNsFlags); + if (!nsFlagsJson || !cJSON_IsArray(nsFlagsJson)) { + return 0; + } + cJSON *nsIte = nullptr; + cJSON_ArrayForEach(nsIte, nsFlagsJson) { + const char *sandboxNs = cJSON_GetStringValue(nsIte); + if (sandboxNs == nullptr) { + continue; + } + std::string sandboxNsStr = sandboxNs; + if (!NamespaceFlagsMap.count(sandboxNsStr)) { + continue; + } + nsFlags |= NamespaceFlagsMap.at(sandboxNsStr); + } + return 0; + }; + + for (auto& config : GetCJsonConfig(SandboxCommonDef::SANDBOX_APP_JSON_CONFIG)) { + // 获取 "individual" 数组 + cJSON *individual = cJSON_GetObjectItemCaseSensitive(config, prefixStr); + if (!individual || !cJSON_IsArray(individual)) { + return nsFlags; + } + (void)HandleArrayForeach(individual, processor); + } + + if (!nsFlags) { + APPSPAWN_LOGE("config is not found %{public}s ns config", isNweb ? "Nweb" : "App"); + } + return nsFlags; +} + +bool SandboxCommon::AppSandboxPidNsIsSupport(void) +{ + char buffer[10] = {0}; + uint32_t buffSize = sizeof(buffer); + + if (SystemGetParameter("const.sandbox.pidns.support", buffer, &buffSize) != 0) { + return true; + } + if (!strcmp(buffer, "false")) { + return false; + } + return true; +} + +void SandboxCommon::StoreCJsonConfig(cJSON *root, SandboxCommonDef::SandboxConfigType type) +{ + appSandboxCJsonConfig_[type].push_back(root); +} + +int32_t SandboxCommon::HandleArrayForeach(cJSON *arrayJson, ArrayItemProcessor processor) +{ + if (!arrayJson || !cJSON_IsArray(arrayJson) || !processor) { + return APPSPAWN_ERROR_UTILS_DECODE_JSON_FAIL; + } + + int ret = 0; + cJSON *item; + cJSON_ArrayForEach(item, arrayJson) { + ret = processor(item); + if (ret != 0) { + return ret; + } + } + return ret; +} + +int SandboxCommon::LoadAppSandboxConfigCJson(AppSpawnMgr *content) +{ + // load sandbox config + cJSON *sandboxCJsonRoot; + CfgFiles *files = GetCfgFiles("etc/sandbox"); + for (int i = 0; (files != nullptr) && (i < MAX_CFG_POLICY_DIRS_CNT); ++i) { + if (files->paths[i] == nullptr) { + continue; + } + std::string path = files->paths[i]; + std::string appPath = path + SandboxCommonDef::APP_JSON_CONFIG; + APPSPAWN_LOGI("LoadAppSandboxConfig %{public}s", appPath.c_str()); + sandboxCJsonRoot = GetJsonObjFromFile(appPath.c_str()); + APPSPAWN_CHECK((sandboxCJsonRoot != nullptr && cJSON_IsObject(sandboxCJsonRoot)), continue, + "Failed to load app data sandbox config %{public}s", appPath.c_str()); + StoreCJsonConfig(sandboxCJsonRoot, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); + + std::string isolatedPath = path + SandboxCommonDef::APP_ISOLATED_JSON_CONFIG; + APPSPAWN_LOGI("LoadAppSandboxConfig %{public}s", isolatedPath.c_str()); + sandboxCJsonRoot = GetJsonObjFromFile(isolatedPath.c_str()); + APPSPAWN_CHECK((sandboxCJsonRoot != nullptr && cJSON_IsObject(sandboxCJsonRoot)), continue, + "Failed to load app data sandbox config %{public}s", isolatedPath.c_str()); + StoreCJsonConfig(sandboxCJsonRoot, SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG); + } + FreeCfgFiles(files); + + bool isNweb = IsNWebSpawnMode(content); + if (!isNweb && !AppSandboxPidNsIsSupport()) { + return 0; + } + content->content.sandboxNsFlags = GetSandboxNsFlags(isNweb); + return 0; +} + +int SandboxCommon::FreeAppSandboxConfigCJson(AppSpawnMgr *content) +{ + UNUSED(content); + std::vector normalJsonVec = GetCJsonConfig(SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); + for (auto& normal : normalJsonVec) { + cJSON_Delete(normal); + } + + std::vector isolatedJsonVec = GetCJsonConfig(SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG); + for (auto& isolated : normalJsonVec) { + cJSON_Delete(isolated); + } + return 0; +} + +std::vector &SandboxCommon::GetCJsonConfig(SandboxCommonDef::SandboxConfigType type) +{ + return appSandboxCJsonConfig_[type]; +} + +// 获取应用信息 +std::string SandboxCommon::GetExtraInfoByType(const AppSpawningCtx *appProperty, const std::string &type) +{ + uint32_t len = 0; + char *info = reinterpret_cast(GetAppPropertyExt(appProperty, type.c_str(), &len)); + if (info == nullptr) { + return ""; + } + return std::string(info, len); +} + +std::string SandboxCommon::GetSandboxRootPath(const AppSpawningCtx *appProperty, cJSON *config) +{ + AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); + if (dacInfo == nullptr) { + return ""; + } + + std::string sandboxRoot = ""; + std::string isolatedFlagText = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? "isolated/" : ""; + AppSpawnMsgBundleInfo *bundleInfo = + reinterpret_cast(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); + if (bundleInfo == nullptr) { + return ""; + } + std::string tmpBundlePath = bundleInfo->bundleName; + std::ostringstream variablePackageName; + if (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE)) { + variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName; + tmpBundlePath = variablePackageName.str(); + } + const std::string variableSandboxRoot = SandboxCommonDef::g_sandBoxRootDir + + std::to_string(dacInfo->uid / UID_BASE) + "/" + isolatedFlagText.c_str() + tmpBundlePath; + + const char *sandboxRootChr = GetStringFromJsonObj(config, SandboxCommonDef::g_sandboxRootPrefix); + if (sandboxRootChr != nullptr) { + sandboxRoot = sandboxRootChr; + if (sandboxRoot == SandboxCommonDef::g_originSandboxPath || + sandboxRoot == SandboxCommonDef::g_sandboxRootPathTemplate) { + sandboxRoot = variableSandboxRoot; + } else { + sandboxRoot = ConvertToRealPath(appProperty, sandboxRoot); + APPSPAWN_LOGV("set sandbox-root name is %{public}s", sandboxRoot.c_str()); + } + } else { + sandboxRoot = variableSandboxRoot; + APPSPAWN_LOGV("set sandbox-root to default rootapp name is %{public}s", GetBundleName(appProperty)); + } + + return sandboxRoot; +} + +int SandboxCommon::CreateDirRecursive(const std::string &path, mode_t mode) +{ + return MakeDirRec(path.c_str(), mode, 1); +} + +void SandboxCommon::CreateDirRecursiveWithClock(const std::string &path, mode_t mode) +{ + size_t size = path.size(); + if (size == 0) { + return; + } +#ifdef APPSPAWN_HISYSEVENT + struct timespec startClock = {0}; + clock_gettime(CLOCK_MONOTONIC, &startClock); +#endif + size_t index = 0; + do { + size_t pathIndex = path.find_first_of('/', index); + index = pathIndex == std::string::npos ? size : pathIndex + 1; + std::string dir = path.substr(0, index); +#ifndef APPSPAWN_TEST + APPSPAWN_CHECK(!(access(dir.c_str(), F_OK) < 0 && mkdir(dir.c_str(), mode) < 0), + return, "errno is %{public}d, mkdir %{public}s failed", errno, dir.c_str()); +#endif + } while (index < size); + +#ifdef APPSPAWN_HISYSEVENT + struct timespec endClock = {0}; + clock_gettime(CLOCK_MONOTONIC, &endClock); + uint64_t diff = DiffTime(&startClock, &endClock); + + APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION, + ReportAbnormalDuration("MakeDirRecursive", diff)); +#endif +} + +bool SandboxCommon::VerifyDirRecursive(const std::string &path) +{ + size_t size = path.size(); + if (size == 0) { + return false; + } + size_t index = 0; + do { + size_t pathIndex = path.find_first_of('/', index); + index = pathIndex == std::string::npos ? size : pathIndex + 1; + std::string dir = path.substr(0, index); +#ifndef APPSPAWN_TEST + APPSPAWN_CHECK(access(dir.c_str(), F_OK) == 0, + return false, "check dir %{public}s failed, strerror: %{public}s", dir.c_str(), strerror(errno)); +#endif + } while (index < size); + return true; +} + +void SandboxCommon::CreateFileIfNotExist(const char *file) +{ + if (access(file, F_OK) == 0) { + APPSPAWN_LOGI("file %{public}s already exist", file); + return; + } + std::string path = file; + auto pos = path.find_last_of('/'); + APPSPAWN_CHECK(pos != std::string::npos, return, "file %{public}s error", file); + std::string dir = path.substr(0, pos); + (void)CreateDirRecursive(dir, SandboxCommonDef::FILE_MODE); + int fd = open(file, O_CREAT, SandboxCommonDef::FILE_MODE); + if (fd < 0) { + APPSPAWN_LOGW("failed create %{public}s, err=%{public}d", file, errno); + } else { + close(fd); + } + return; +} + +void SandboxCommon::SetSandboxPathChmod(cJSON *jsonConfig, std::string &sandboxRoot) +{ + const std::map modeMap = {{"S_IRUSR", S_IRUSR}, {"S_IWUSR", S_IWUSR}, {"S_IXUSR", S_IXUSR}, + {"S_IRGRP", S_IRGRP}, {"S_IWGRP", S_IWGRP}, {"S_IXGRP", S_IXGRP}, + {"S_IROTH", S_IROTH}, {"S_IWOTH", S_IWOTH}, {"S_IXOTH", S_IXOTH}, + {"S_IRWXU", S_IRWXU}, {"S_IRWXG", S_IRWXG}, {"S_IRWXO", S_IRWXO}}; + const char *fileMode = GetStringFromJsonObj(jsonConfig, SandboxCommonDef::g_destMode); + if (fileMode == nullptr) { + return; + } + + mode_t mode = 0; + std::string fileModeStr = fileMode; + std::vector modeVec = SplitString(fileModeStr, "|"); + for (unsigned int i = 0; i < modeVec.size(); i++) { + if (modeMap.count(modeVec[i])) { + mode |= modeMap.at(modeVec[i]); + } + } + + chmod(sandboxRoot.c_str(), mode); +} + +// 获取挂载配置参数信息 +unsigned long SandboxCommon::GetMountFlagsFromConfig(const std::vector &vec) +{ + const std::map MountFlagsMap = { {"rec", MS_REC}, {"MS_REC", MS_REC}, + {"bind", MS_BIND}, {"MS_BIND", MS_BIND}, + {"move", MS_MOVE}, {"MS_MOVE", MS_MOVE}, + {"slave", MS_SLAVE}, {"MS_SLAVE", MS_SLAVE}, + {"rdonly", MS_RDONLY}, {"MS_RDONLY", MS_RDONLY}, + {"shared", MS_SHARED}, {"MS_SHARED", MS_SHARED}, + {"unbindable", MS_UNBINDABLE}, + {"MS_UNBINDABLE", MS_UNBINDABLE}, + {"remount", MS_REMOUNT}, {"MS_REMOUNT", MS_REMOUNT}, + {"nosuid", MS_NOSUID}, {"MS_NOSUID", MS_NOSUID}, + {"nodev", MS_NODEV}, {"MS_NODEV", MS_NODEV}, + {"noexec", MS_NOEXEC}, {"MS_NOEXEC", MS_NOEXEC}, + {"noatime", MS_NOATIME}, {"MS_NOATIME", MS_NOATIME}, + {"lazytime", MS_LAZYTIME}, {"MS_LAZYTIME", MS_LAZYTIME}}; + + unsigned long mountFlags = 0; + for (unsigned int i = 0; i < vec.size(); i++) { + if (MountFlagsMap.count(vec[i])) { + mountFlags |= MountFlagsMap.at(vec[i]); + } + } + return mountFlags; +} + +bool SandboxCommon::IsDacOverrideEnabled(cJSON *config) // GetSandboxDacOverrideEnable +{ + return GetBoolValueFromJsonObj(config, SandboxCommonDef::g_dacOverrideSensitive, false); +} + +bool SandboxCommon::GetSwitchStatus(cJSON *config) // GetSbxSwitchStatusByConfig +{ + // if not find sandbox-switch node, default switch status is true + return GetBoolValueFromJsonObj(config, SandboxCommonDef::g_sandBoxSwitchPrefix, true); +} + +uint32_t SandboxCommon::ConvertFlagStr(const std::string &flagStr) +{ + const std::map flagsMap = {{"0", 0}, {"START_FLAGS_BACKUP", 1}, + {"DLP_MANAGER", 2}, + {"DEVELOPER_MODE", 17}, + {"PREINSTALLED_HAP", 29}, + {"CUSTOM_SANDBOX_HAP", 31}}; + + if (flagsMap.count(flagStr)) { + return 1 << flagsMap.at(flagStr); + } + return 0; +} + +unsigned long SandboxCommon::GetMountFlags(cJSON *config) // GetSandboxMountFlags +{ + unsigned long mountFlags = SandboxCommonDef::BASIC_MOUNT_FLAGS; + std::vector vec; + cJSON *customizedFlags = IsDacOverrideEnabled(config) ? + cJSON_GetObjectItemCaseSensitive(config, SandboxCommonDef::g_sandBoxFlagsCustomized) : + cJSON_GetObjectItemCaseSensitive(config, SandboxCommonDef::g_sandBoxFlags); + + if (!customizedFlags) { + customizedFlags = cJSON_GetObjectItemCaseSensitive(config, SandboxCommonDef::g_sandBoxFlags); + } + if (customizedFlags == nullptr || !cJSON_IsArray(customizedFlags)) { + return mountFlags; + } + + auto processor = [&vec](cJSON *item) { + const char *strItem = cJSON_GetStringValue(item); + if (strItem == nullptr) { + return -1; + } + vec.emplace_back(strItem); + return 0; + }; + + if (HandleArrayForeach(customizedFlags, processor) != 0) { + return mountFlags; + } + return GetMountFlagsFromConfig(vec); +} + +std::string SandboxCommon::GetFsType(cJSON *config) // GetSandboxFsType +{ + std::string fsType = ""; + const char *fsTypeChr = GetStringFromJsonObj(config, SandboxCommonDef::g_fsType); + if (fsTypeChr == nullptr) { + return fsType; + } + fsType = fsTypeChr; + return fsType; +} + +std::string SandboxCommon::GetOptions(const AppSpawningCtx *appProperty, cJSON *config) // GetSandboxOptions +{ + AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); + if (dacInfo == nullptr) { + return ""; + } + + std::string options = ""; + const char *optionsChr = GetStringFromJsonObj(config, SandboxCommonDef::g_sandBoxOptions); + if (optionsChr == nullptr) { + return options; + } + options = optionsChr; + options += ",user_id=" + std::to_string(dacInfo->uid / UID_BASE); + return options; +} + +std::vector SandboxCommon::GetDecPath(const AppSpawningCtx *appProperty, cJSON *config) // GetSandboxDecPath +{ + AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); + if (dacInfo == nullptr) { + return {}; + } + + std::vector decPaths = {}; + cJSON *decPathJson = cJSON_GetObjectItemCaseSensitive(config, SandboxCommonDef::g_sandBoxDecPath); + if (decPathJson == nullptr || !cJSON_IsArray(decPathJson)) { + return {}; + } + + auto processor = [&appProperty, &decPaths](cJSON *item) { + const char *strItem = cJSON_GetStringValue(item); + if (strItem == nullptr) { + return -1; + } + std::string decPath = ConvertToRealPath(appProperty, strItem); + decPaths.emplace_back(std::move(decPath)); + return 0; + }; + if (HandleArrayForeach(decPathJson, processor) != 0) { + return {}; + } + return decPaths; +} + +bool SandboxCommon::IsCreateSandboxPathEnabled(cJSON *json, std::string srcPath) // GetCreateSandboxPath +{ + bool isRet = GetBoolValueFromJsonObj(json, SandboxCommonDef::CREATE_SANDBOX_PATH, false); + if (isRet && access(srcPath.c_str(), F_OK) != 0) { + return false; + } + return true; +} + +bool SandboxCommon::IsTotalSandboxEnabled(const AppSpawningCtx *appProperty) // CheckTotalSandboxSwitchStatus +{ + SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? + SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG; + + for (auto& wholeConfig : GetCJsonConfig(type)) { + // 获取 "common" 数组 + cJSON *common = cJSON_GetObjectItemCaseSensitive(wholeConfig, SandboxCommonDef::g_commonPrefix); + if (!common || !cJSON_IsArray(common)) { + continue; + } + // 获取第一个字段 + cJSON *firstCommon = cJSON_GetArrayItem(common, 0); + if (!firstCommon) { + continue; + } + return GetBoolValueFromJsonObj(firstCommon, SandboxCommonDef::g_topSandBoxSwitchPrefix, true); + } + // default sandbox switch is on + return true; +} + +bool SandboxCommon::IsAppSandboxEnabled(const AppSpawningCtx *appProperty) // CheckAppSandboxSwitchStatus +{ + SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? + SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG; + + bool ret = true; + for (auto& wholeConfig : GetCJsonConfig(type)) { + // 获取 "individual" 数组 + cJSON *individual = cJSON_GetObjectItemCaseSensitive(wholeConfig, SandboxCommonDef::g_privatePrefix); + if (!individual || !cJSON_IsArray(individual)) { + continue; + } + cJSON *bundleNameInfo = cJSON_GetObjectItemCaseSensitive(individual, GetBundleName(appProperty)); + if (!bundleNameInfo || !cJSON_IsArray(bundleNameInfo)) { + continue; + } + // 获取第一个字段 + cJSON *firstCommon = cJSON_GetArrayItem(bundleNameInfo, 0); + if (!firstCommon) { + continue; + } + ret = GetSwitchStatus(firstCommon); + if (ret) { + break; + } + } + // default sandbox switch is on + return ret; +} + +void SandboxCommon::GetSandboxMountConfig(const AppSpawningCtx *appProperty, const std::string §ion, + cJSON *mntPoint, SandboxMountConfig &mountConfig) +{ + if (section.compare(SandboxCommonDef::g_permissionPrefix) == 0 || + section.compare(SandboxCommonDef::g_flagePoint) == 0 || + section.compare(SandboxCommonDef::g_debughap) == 0) { + mountConfig.optionsPoint = GetOptions(appProperty, mntPoint); + mountConfig.fsType = GetFsType(mntPoint); + mountConfig.decPaths = GetDecPath(appProperty, mntPoint); + } else { + mountConfig.fsType = GetFsType(mntPoint); + mountConfig.optionsPoint = ""; + mountConfig.decPaths = {}; + } + return; +} + +// 校验操作 +bool SandboxCommon::IsNeededCheckPathStatus(const AppSpawningCtx *appProperty, const char *path) +{ + if (strstr(path, "data/app/el1/") || strstr(path, "data/app/el2/")) { + return true; + } + if ((strstr(path, "data/app/el3/") || strstr(path, "data/app/el4/") || strstr(path, "data/app/el5/")) && + CheckAppMsgFlagsSet(appProperty, APP_FLAGS_UNLOCKED_STATUS)) { + return true; + } + return false; +} + +void SandboxCommon::CheckMountStatus(const std::string &path) +{ + std::ifstream file("/proc/self/mountinfo"); + if (!file.is_open()) { + APPSPAWN_LOGE("Failed to open /proc/self/mountinfo errno %{public}d", errno); + return; + } + + bool flag = false; + std::string line; + while (std::getline(file, line)) { + if (line.find(path) != std::string::npos) { + flag = true; + APPSPAWN_LOGI("Current mountinfo %{public}s", line.c_str()); + } + } + file.close(); + APPSPAWN_CHECK_ONLY_LOG(flag, "Mountinfo not contains %{public}s", path.c_str()); +} + +bool SandboxCommon::HasPrivateInBundleName(const std::string &bundleName) // CheckBundleNameForPrivate +{ + if (bundleName.find(SandboxCommonDef::g_internal) != std::string::npos) { + return false; + } + return true; +} + +bool SandboxCommon::IsMountSuccessful(cJSON *mntPoint) // GetCheckStatus +{ + // default false + return GetBoolValueFromJsonObj(mntPoint, SandboxCommonDef::g_actionStatuc, false); +} + +int SandboxCommon::CheckBundleName(const std::string &bundleName) +{ + if (bundleName.empty() || bundleName.size() > APP_LEN_BUNDLE_NAME) { + return -1; + } + if (bundleName.find('\\') != std::string::npos || bundleName.find('/') != std::string::npos) { + return -1; + } + return 0; +} + +int32_t SandboxCommon::CheckAppFullMountEnable() +{ + if (deviceTypeEnable_ != -1) { + return deviceTypeEnable_; + } + + char value[] = "false"; + int32_t ret = GetParameter("const.filemanager.full_mount.enable", "false", value, sizeof(value)); + if (ret > 0 && (strcmp(value, "true")) == 0) { + deviceTypeEnable_ = SandboxCommonDef::FILE_CROSS_APP_STATUS; + } else if (ret > 0 && (strcmp(value, "false")) == 0) { + deviceTypeEnable_ = SandboxCommonDef::FILE_ACCESS_COMMON_DIR_STATUS; + } else { + deviceTypeEnable_ = -1; + } + + return deviceTypeEnable_; +} + +bool SandboxCommon::IsPrivateSharedStatus(const std::string &bundleName, AppSpawningCtx *appProperty) +{ + bool result = false; + SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? + SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG; + + for (auto& config : GetCJsonConfig(type)) { + // 获取 "individual" 数组 + cJSON *individual = cJSON_GetObjectItemCaseSensitive(config, SandboxCommonDef::g_privatePrefix); + if (!individual || !cJSON_IsArray(individual)) { + return result; + } + cJSON *bundleNameInfo = cJSON_GetObjectItemCaseSensitive(individual, bundleName.c_str()); + if (!bundleNameInfo || !cJSON_IsArray(bundleNameInfo)) { + return result; + } + result = GetBoolValueFromJsonObj(bundleNameInfo, SandboxCommonDef::g_sandBoxShared, false); + } + return result; +} + +bool SandboxCommon::IsValidMountConfig(cJSON *mntPoint, const AppSpawningCtx *appProperty, bool checkFlag) +{ + const char *srcPath = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_srcPath); + const char *sandboxPath = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_sandBoxPath); + cJSON *customizedFlags = cJSON_GetObjectItemCaseSensitive(mntPoint, SandboxCommonDef::g_sandBoxFlagsCustomized); + cJSON *flags = cJSON_GetObjectItemCaseSensitive(mntPoint, SandboxCommonDef::g_sandBoxFlags); + if (srcPath == nullptr || sandboxPath == nullptr || (customizedFlags == nullptr && flags == nullptr)) { + APPSPAWN_LOGE("read mount config failed, app name is %{public}s", GetBundleName(appProperty)); + return false; + } + + AppSpawnMsgDomainInfo *info = + reinterpret_cast(GetAppProperty(appProperty, TLV_DOMAIN_INFO)); + APPSPAWN_CHECK(info != nullptr, return false, "Filed to get domain info %{public}s", GetBundleName(appProperty)); + const char *appAplName = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_appAplName); + if (appAplName != nullptr) { + if (!strcmp(appAplName, info->apl)) { + return false; + } + } + + const std::string configSrcPath = srcPath; + // special handle wps and don't use /data/app/xxx/ config + if (checkFlag && (configSrcPath.find("/data/app") != std::string::npos && + (configSrcPath.find("/base") != std::string::npos || + configSrcPath.find("/database") != std::string::npos + ) && configSrcPath.find(SandboxCommonDef::g_packageName) != std::string::npos)) { + return false; + } + + return true; +} + +// 路径处理 +std::string SandboxCommon::ReplaceAllVariables(std::string str, const std::string& from, const std::string& to) +{ + while (true) { + std::string::size_type pos(0); + if ((pos = str.find(from)) != std::string::npos) { + str.replace(pos, from.length(), to); + } else { + break; + } + } + return str; +} + +std::vector SandboxCommon::SplitString(std::string &str, const std::string &delimiter) +{ + std::string::size_type pos; + std::vector result; + str += delimiter; + size_t size = str.size(); + for (unsigned int i = 0; i < size; i++) { + pos = str.find(delimiter, i); + if (pos < size) { + std::string s = str.substr(i, pos - i); + result.push_back(s); + i = pos + delimiter.size() - 1; + } + } + + return result; +} + +void SandboxCommon::MakeAtomicServiceDir(const AppSpawningCtx *appProperty, std::string path, + std::string variablePackageName) +{ + AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); + APPSPAWN_CHECK(dacInfo != nullptr, return, "No dac info in msg app property"); + if (path.find("/mnt/share") != std::string::npos) { + path = "/data/service/el2/" + std::to_string(dacInfo->uid / UID_BASE) + "/share/" + variablePackageName; + } + struct stat st = {}; + if (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) { + return; + } + + int ret = mkdir(path.c_str(), S_IRWXU); + APPSPAWN_CHECK(ret == 0, return, "mkdir %{public}s failed, errno %{public}d", path.c_str(), errno); + + if (path.find("/database") != std::string::npos || path.find("/data/service/el2") != std::string::npos) { + ret = chmod(path.c_str(), S_IRWXU | S_IRWXG | S_ISGID); + } else if (path.find("/log") != std::string::npos) { + ret = chmod(path.c_str(), S_IRWXU | S_IRWXG); + } + APPSPAWN_CHECK(ret == 0, return, "chmod %{public}s failed, errno %{public}d", path.c_str(), errno); + +#ifdef WITH_SELINUX + AppSpawnMsgDomainInfo *msgDomainInfo = + reinterpret_cast(GetAppProperty(appProperty, TLV_DOMAIN_INFO)); + APPSPAWN_CHECK(msgDomainInfo != nullptr, return, "No domain info for %{public}s", GetProcessName(appProperty)); + HapContext hapContext; + HapFileInfo hapFileInfo; + hapFileInfo.pathNameOrig.push_back(path); + hapFileInfo.apl = msgDomainInfo->apl; + hapFileInfo.packageName = GetBundleName(appProperty); + hapFileInfo.hapFlags = msgDomainInfo->hapFlags; + if (CheckAppMsgFlagsSet(appProperty, APP_FLAGS_DEBUGGABLE)) { + hapFileInfo.hapFlags |= SELINUX_HAP_DEBUGGABLE; + } + if ((path.find("/base") != std::string::npos) || (path.find("/database") != std::string::npos)) { + ret = hapContext.HapFileRestorecon(hapFileInfo); + APPSPAWN_CHECK(ret == 0, return, "set dir %{public}s selinuxLabel failed, apl %{public}s, ret %{public}d", + path.c_str(), hapFileInfo.apl.c_str(), ret); + } +#endif + if (path.find("/base") != std::string::npos || path.find("/data/service/el2") != std::string::npos) { + ret = chown(path.c_str(), dacInfo->uid, dacInfo->gid); + } else if (path.find("/database") != std::string::npos) { + ret = chown(path.c_str(), dacInfo->uid, DecodeGid("ddms")); + } else if (path.find("/log") != std::string::npos) { + ret = chown(path.c_str(), dacInfo->uid, DecodeGid("log")); + } + APPSPAWN_CHECK(ret == 0, return, "chown %{public}s failed, errno %{public}d", path.c_str(), errno); + return; +} + +std::string SandboxCommon::ReplaceVariablePackageName(const AppSpawningCtx *appProperty, const std::string &path) +{ + std::string tmpSandboxPath = path; + AppSpawnMsgBundleInfo *bundleInfo = + reinterpret_cast(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); + APPSPAWN_CHECK(bundleInfo != nullptr, return "", "No bundle info in msg %{public}s", GetBundleName(appProperty)); + + char *extension; + uint32_t flags = CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE) ? 0x4 : 0; + if (flags == 0) { + flags = (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE) && + bundleInfo->bundleIndex > 0) ? 0x1 : 0; + flags |= CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_EXTENSION_SANDBOX) ? 0x2 : 0; + extension = reinterpret_cast( + GetAppSpawnMsgExtInfo(appProperty->message, MSG_EXT_NAME_APP_EXTENSION, nullptr)); + } + std::ostringstream variablePackageName; + switch (flags) { + case SANDBOX_PACKAGENAME_DEFAULT: // 0 default + variablePackageName << bundleInfo->bundleName; + break; + case SANDBOX_PACKAGENAME_CLONE: // 1 +clone-bundleIndex+packageName + variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName; + break; + case SANDBOX_PACKAGENAME_EXTENSION: { // 2 +extension-+packageName + APPSPAWN_CHECK(extension != nullptr, return "", "Invalid extension data "); + variablePackageName << "+extension-" << extension << "+" << bundleInfo->bundleName; + break; + } + case SANDBOX_PACKAGENAME_CLONE_AND_EXTENSION: { // 3 +clone-bundleIndex+extension-+packageName + APPSPAWN_CHECK(extension != nullptr, return "", "Invalid extension data "); + variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+extension" << "-" << + extension << "+" << bundleInfo->bundleName; + break; + } + case SANDBOX_PACKAGENAME_ATOMIC_SERVICE: { // 4 +auid-+packageName + std::string accountId = GetExtraInfoByType(appProperty, MSG_EXT_NAME_ACCOUNT_ID); + variablePackageName << "+auid-" << accountId << "+" << bundleInfo->bundleName; + std::string atomicServicePath = path; + atomicServicePath = ReplaceAllVariables(atomicServicePath, SandboxCommonDef::g_variablePackageName, + variablePackageName.str()); + MakeAtomicServiceDir(appProperty, atomicServicePath, variablePackageName.str()); + break; + } + default: + variablePackageName << bundleInfo->bundleName; + break; + } + tmpSandboxPath = ReplaceAllVariables(tmpSandboxPath, SandboxCommonDef::g_variablePackageName, variablePackageName.str()); + APPSPAWN_LOGV("tmpSandboxPath %{public}s", tmpSandboxPath.c_str()); + return tmpSandboxPath; +} + +std::string SandboxCommon::ReplaceHostUserId(const AppSpawningCtx *appProperty, const std::string &path) +{ + std::string tmpSandboxPath = path; + int32_t uid = 0; + const char *userId = + (const char *)(GetAppSpawnMsgExtInfo(appProperty->message, MSG_EXT_NAME_PARENT_UID, nullptr)); + if (userId != nullptr) { + uid = atoi(userId); + } + tmpSandboxPath = ReplaceAllVariables(tmpSandboxPath, SandboxCommonDef::g_hostUserId, + std::to_string(uid / UID_BASE)); + APPSPAWN_LOGV("tmpSandboxPath %{public}s", tmpSandboxPath.c_str()); + return tmpSandboxPath; +} + +std::string SandboxCommon::ReplaceClonePackageName(const AppSpawningCtx *appProperty, const std::string &path) +{ + std::string tmpSandboxPath = path; + AppSpawnMsgBundleInfo *bundleInfo = + reinterpret_cast(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); + APPSPAWN_CHECK(bundleInfo != nullptr, return "", "No bundle info in msg %{public}s", GetBundleName(appProperty)); + + std::string tmpBundlePath = bundleInfo->bundleName; + std::ostringstream variablePackageName; + if (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE)) { + variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName; + tmpBundlePath = variablePackageName.str(); + } + + tmpSandboxPath = ReplaceAllVariables(tmpSandboxPath, SandboxCommonDef::g_clonePackageName, tmpBundlePath); + APPSPAWN_LOGV("tmpSandboxPath %{public}s", tmpSandboxPath.c_str()); + return tmpSandboxPath; +} + +const std::string& SandboxCommon::GetArkWebPackageName(void) +{ + static std::string arkWebPackageName; + if (arkWebPackageName.empty()) { + arkWebPackageName = system::GetParameter(SandboxCommonDef::ARK_WEB_PERSIST_PACKAGE_NAME, ""); + } + return arkWebPackageName; +} + +std::string SandboxCommon::ConvertToRealPathWithPermission(const AppSpawningCtx *appProperty, std::string path) +{ + AppSpawnMsgBundleInfo *info = + reinterpret_cast(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); + if (info == nullptr) { + return ""; + } + if (path.find(SandboxCommonDef::g_packageNameIndex) != std::string::npos) { + std::string bundleNameWithIndex = info->bundleName; + if (info->bundleIndex != 0) { + bundleNameWithIndex = std::to_string(info->bundleIndex) + "_" + bundleNameWithIndex; + } + path = ReplaceAllVariables(path, SandboxCommonDef::g_packageNameIndex, bundleNameWithIndex); + } + + if (path.find(SandboxCommonDef::g_packageName) != std::string::npos) { + path = ReplaceAllVariables(path, SandboxCommonDef::g_packageName, info->bundleName); + } + + if (path.find(SandboxCommonDef::g_userId) != std::string::npos) { + if (deviceTypeEnable_ == SandboxCommonDef::FILE_CROSS_APP_STATUS) { + path = ReplaceAllVariables(path, SandboxCommonDef::g_userId, "currentUser"); + } else if (deviceTypeEnable_ == SandboxCommonDef::FILE_ACCESS_COMMON_DIR_STATUS) { + path = ReplaceAllVariables(path, SandboxCommonDef::g_userId, "currentUser"); + } else { + return ""; + } + } + return path; +} + +std::string SandboxCommon::ConvertToRealPath(const AppSpawningCtx *appProperty, std::string path) +{ + AppSpawnMsgBundleInfo *info = + reinterpret_cast(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); + AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); + if (info == nullptr || dacInfo == nullptr) { + return ""; + } + if (path.find(SandboxCommonDef::g_packageNameIndex) != std::string::npos) { + std::string bundleNameWithIndex = info->bundleName; + if (info->bundleIndex != 0) { + bundleNameWithIndex = std::to_string(info->bundleIndex) + "_" + bundleNameWithIndex; + } + path = ReplaceAllVariables(path, SandboxCommonDef::g_packageNameIndex, bundleNameWithIndex); + } + + if (path.find(SandboxCommonDef::g_packageName) != std::string::npos) { + path = ReplaceAllVariables(path, SandboxCommonDef::g_packageName, info->bundleName); + } + + if (path.find(SandboxCommonDef::g_userId) != std::string::npos) { + path = ReplaceAllVariables(path, SandboxCommonDef::g_userId, std::to_string(dacInfo->uid / UID_BASE)); + } + + if (path.find(SandboxCommonDef::g_hostUserId) != std::string::npos) { + path = ReplaceHostUserId(appProperty, path); + } + + if (path.find(SandboxCommonDef::g_variablePackageName) != std::string::npos) { + path = ReplaceVariablePackageName(appProperty, path); + } + + if (path.find(SandboxCommonDef::g_clonePackageName) != std::string::npos) { + path = ReplaceClonePackageName(appProperty, path); + } + + if (path.find(SandboxCommonDef::g_arkWebPackageName) != std::string::npos) { + path = ReplaceAllVariables(path, SandboxCommonDef::g_arkWebPackageName, GetArkWebPackageName()); + APPSPAWN_LOGV("arkWeb sandbox, path %{public}s, package:%{public}s", + path.c_str(), GetArkWebPackageName().c_str()); + } + + return path; +} + +// 挂载操作 +int32_t SandboxCommon::DoAppSandboxMountOnce(const AppSpawningCtx *appProperty, const SharedMountArgs *arg) +{ + if (!(arg && arg->srcPath && arg->destPath && arg->srcPath[0] != '\0' && arg->destPath[0] != '\0')) { + return 0; + } + if (strstr(arg->srcPath, "system/etc/hosts") != nullptr || strstr(arg->srcPath, "system/etc/profile") != nullptr) { + CreateFileIfNotExist(arg->destPath); + } else { + (void)CreateDirRecursive(arg->destPath, SandboxCommonDef::FILE_MODE); + } + + int ret = 0; + // to mount fs and bind mount files or directory + struct timespec mountStart = {0}; + clock_gettime(CLOCK_MONOTONIC_COARSE, &mountStart); + APPSPAWN_LOGV("Bind mount %{public}s to %{public}s '%{public}s' '%{public}lu' '%{public}s' '%{public}u'", + arg->srcPath, arg->destPath, arg->fsType, arg->mountFlags, arg->options, arg->mountSharedFlag); + ret = mount(arg->srcPath, arg->destPath, arg->fsType, arg->mountFlags, arg->options); + struct timespec mountEnd = {0}; + clock_gettime(CLOCK_MONOTONIC_COARSE, &mountEnd); + uint64_t diff = DiffTime(&mountStart, &mountEnd); + APPSPAWN_CHECK_ONLY_LOG(diff < SandboxCommonDef::MAX_MOUNT_TIME, "mount %{public}s time %{public}" PRId64 " us", arg->srcPath, diff); +#ifdef APPSPAWN_HISYSEVENT + APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION, ReportAbnormalDuration("MOUNT", diff)); +#endif + if (ret != 0) { + APPSPAWN_LOGI("errno is: %{public}d, bind mount %{public}s to %{public}s", errno, arg->srcPath, arg->destPath); + if (errno == ENOENT && IsNeededCheckPathStatus(appProperty, arg->srcPath)) { + VerifyDirRecursive(arg->srcPath); + } + return ret; + } + + ret = mount(nullptr, arg->destPath, nullptr, arg->mountSharedFlag, nullptr); + if (ret != 0) { + APPSPAWN_LOGI("errno is: %{public}d, private mount to %{public}s '%{public}u' failed", + errno, arg->destPath, arg->mountSharedFlag); + if (errno == EINVAL) { + CheckMountStatus(arg->destPath); + } + return ret; + } + return 0; +} + +} // namespace AppSpawn +} // namespace OHOS \ No newline at end of file diff --git a/modules/sandbox/normal/sandbox_common.h b/modules/sandbox/normal/sandbox_common.h new file mode 100644 index 0000000000000000000000000000000000000000..2bdee646c61f5ca81d95077fc6234c55d2904707 --- /dev/null +++ b/modules/sandbox/normal/sandbox_common.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SANDBOX_COMMON_H +#define SANDBOX_COMMON_H + +#include +#include +#include +#include +#include "sandbox_def.h" +#include "appspawn_msg.h" +#include "appspawn_server.h" +#include "appspawn_manager.h" +#include "sandbox_shared_mount.h" +#include "json_utils.h" + +namespace OHOS { +namespace AppSpawn { + +// 挂载选项 +typedef struct SandboxMountConfig { + unsigned long mountFlags; + std::string optionsPoint; + std::string fsType; + std::string sandboxPath; + std::vector decPaths; +} SandboxMountConfig; + +typedef struct MountPointProcessParams { + const AppSpawningCtx *appProperty; // 引用属性 + bool checkFlag; // 检查标志 + std::string section; // 分区名称 + std::string sandboxRoot; // 沙箱根路径 + std::string bundleName; // 包名 +} MountPointProcessParams; + +using ArrayItemProcessor = std::function; + +class SandboxCommon { + +public: + // 加载配置文件 + static int LoadAppSandboxConfigCJson(AppSpawnMgr *content); + static int FreeAppSandboxConfigCJson(AppSpawnMgr *content); + static void StoreJsonConfig(cJSON *appSandboxConfig, SandboxCommonDef::SandboxConfigType type); + static std::vector &GetCJsonConfig(SandboxCommonDef::SandboxConfigType type); // GetJsonConfig + + static int32_t HandleArrayForeach(cJSON *arrayJson, ArrayItemProcessor processor); + + // 获取应用信息 + static std::string GetExtraInfoByType(const AppSpawningCtx *appProperty, const std::string &type); + static std::string GetSandboxRootPath(const AppSpawningCtx *appProperty, cJSON *config); // GetSbxPathByConfig + + // 文件操作 + static int CreateDirRecursive(const std::string &path, mode_t mode); // MakeDirRecursive + static void CreateDirRecursiveWithClock(const std::string &path, mode_t mode); // MakeDirRecursiveWithClock + static void SetSandboxPathChmod(cJSON *jsonConfig, std::string &sandboxRoot); // DoSandboxChmod + + // 获取挂载配置参数信息 + static uint32_t ConvertFlagStr(const std::string &flagStr); + static unsigned long GetMountFlags(cJSON *config); // GetSandboxMountFlags + static bool IsCreateSandboxPathEnabled(cJSON *json, std::string srcPath); // GetCreateSandboxPath + static bool IsTotalSandboxEnabled(const AppSpawningCtx *appProperty); // CheckTotalSandboxSwitchStatus + static bool IsAppSandboxEnabled(const AppSpawningCtx *appProperty); // CheckAppSandboxSwitchStatus + static void GetSandboxMountConfig(const AppSpawningCtx *appProperty, const std::string §ion, + cJSON *mntPoint, SandboxMountConfig &mountConfig); + + // 校验操作 + static bool HasPrivateInBundleName(const std::string &bundleName); // CheckBundleNameForPrivate + static bool IsMountSuccessful(cJSON *mntPoint); // GetCheckStatus + static int CheckBundleName(const std::string &bundleName); + static bool IsValidMountConfig(cJSON *mntPoint, const AppSpawningCtx *appProperty, + bool checkFlag); // CheckMountConfig + static bool IsPrivateSharedStatus(const std::string &bundleName, + AppSpawningCtx *appProperty); // GetSandboxPrivateSharedStatus + static int32_t CheckAppFullMountEnable(); + + // 路径处理 + static std::vector SplitString(std::string &str, const std::string &delimiter); // split + static std::string ReplaceAllVariables(std::string str, const std::string& from, + const std::string& to); // replace_all + static std::string ConvertToRealPath(const AppSpawningCtx *appProperty, std::string path); + static std::string ConvertToRealPathWithPermission(const AppSpawningCtx *appProperty, std::string path); + + // 挂载操作 + static int32_t DoAppSandboxMountOnce(const AppSpawningCtx *appProperty, const SharedMountArgs *arg); + +private: + // 加载配置文件 + static uint32_t GetSandboxNsFlags(bool isNweb); + static bool AppSandboxPidNsIsSupport(void); + static void StoreCJsonConfig(cJSON *root, SandboxCommonDef::SandboxConfigType type); + + // 文件操作 + static bool VerifyDirRecursive(const std::string &path); // CheckDirRecursive + static void CreateFileIfNotExist(const char *file); // CheckAndCreatFile + + // 获取挂载配置参数信息 + static bool GetSwitchStatus(cJSON *config); // GetSbxSwitchStatusByConfig + static unsigned long GetMountFlagsFromConfig(const std::vector &vec); + static bool IsDacOverrideEnabled(cJSON *config); // GetSandboxDacOverrideEnable + static std::string GetFsType(cJSON *config); // GetSandboxFsType + static std::string GetOptions(const AppSpawningCtx *appProperty, cJSON *config); // GetSandboxOptions + static std::vector GetDecPath(const AppSpawningCtx *appProperty, cJSON *config); // GetSandboxDecPath + + // 校验操作 + static bool IsNeededCheckPathStatus(const AppSpawningCtx *appProperty, const char *path); + static void CheckMountStatus(const std::string &path); + + // 路径处理 + static std::string ReplaceVariablePackageName(const AppSpawningCtx *appProperty, const std::string &path); + static void MakeAtomicServiceDir(const AppSpawningCtx *appProperty, std::string path, + std::string variablePackageName); + static std::string ReplaceHostUserId(const AppSpawningCtx *appProperty, const std::string &path); + static std::string ReplaceClonePackageName(const AppSpawningCtx *appProperty, const std::string &path); + static const std::string &GetArkWebPackageName(void); + +private: + static int32_t deviceTypeEnable_; + static std::map> appSandboxCJsonConfig_; + typedef enum { + SANDBOX_PACKAGENAME_DEFAULT = 0, + SANDBOX_PACKAGENAME_CLONE, + SANDBOX_PACKAGENAME_EXTENSION, + SANDBOX_PACKAGENAME_CLONE_AND_EXTENSION, + SANDBOX_PACKAGENAME_ATOMIC_SERVICE, + } SandboxVarPackageNameType; +}; + +} // namespace AppSpawn +} // namespace OHOS + +#endif // SANDBOX_COMMON_H \ No newline at end of file diff --git a/modules/sandbox/normal/sandbox_core.cpp b/modules/sandbox/normal/sandbox_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..033213f9fb6430879534efc26b45a07dbef45d4f --- /dev/null +++ b/modules/sandbox/normal/sandbox_core.cpp @@ -0,0 +1,1447 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sandbox_core.h" + +#include +#include +#include +#include +#include +#include +#include "securec.h" +#include "appspawn_manager.h" +#include "appspawn_trace.h" +#include "appspawn_utils.h" +#include "sandbox_dec.h" +#include "sandbox_def.h" +#ifdef APPSPAWN_HISYSEVENT +#include "hisysevent_adapter.h" +#endif + +#ifdef WITH_DLP +#include "dlp_fuse_fd.h" +#endif + +namespace OHOS { +namespace AppSpawn { + +bool SandboxCore::NeedNetworkIsolated(AppSpawningCtx *property) +{ + int developerMode = IsDeveloperModeOpen(); + if (CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX) && !developerMode) { + return true; + } + + if (CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_NETWORK)) { + std::string extensionType = SandboxCommon::GetExtraInfoByType(property, MSG_EXT_NAME_EXTENSION_TYPE); + if (extensionType.length() == 0 || !developerMode) { + return true; + } + } + + return false; +} + +int SandboxCore::EnableSandboxNamespace(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags) +{ +#ifdef APPSPAWN_HISYSEVENT + struct timespec startClock = {0}; + clock_gettime(CLOCK_MONOTONIC, &startClock); +#endif + int rc = unshare(sandboxNsFlags); +#ifdef APPSPAWN_HISYSEVENT + struct timespec endClock = {0}; + clock_gettime(CLOCK_MONOTONIC, &endClock); + uint64_t diff = DiffTime(&startClock, &endClock); + APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION, ReportAbnormalDuration("unshare", diff)); +#endif + APPSPAWN_CHECK(rc == 0, return rc, "unshare %{public}s failed, err %{public}d", GetBundleName(appProperty), errno); + + if ((sandboxNsFlags & CLONE_NEWNET) == CLONE_NEWNET) { + rc = EnableNewNetNamespace(); + APPSPAWN_CHECK(rc == 0, return rc, "Set %{public}s new netnamespace failed", GetBundleName(appProperty)); + } + return 0; +} + +uint32_t SandboxCore::GetAppMsgFlags(const AppSpawningCtx *property) +{ + APPSPAWN_CHECK(property != nullptr && property->message != nullptr, + return 0, "Invalid property for name %{public}u", TLV_MSG_FLAGS); + AppSpawnMsgFlags *msgFlags = (AppSpawnMsgFlags *)GetAppSpawnMsgInfo(property->message, TLV_MSG_FLAGS); + APPSPAWN_CHECK(msgFlags != nullptr, + return 0, "No TLV_MSG_FLAGS in msg %{public}s", property->message->msgHeader.processName); + return msgFlags->flags[0]; +} + +bool SandboxCore::CheckMountFlag(const AppSpawningCtx *appProperty, const std::string bundleName, + cJSON *appConfig) +{ + const char *flagChr = GetStringFromJsonObj(appConfig, SandboxCommonDef::g_flags); + if (flagChr == nullptr) { + return false; + } + std::string flagStr(flagChr); + if (((SandboxCommon::ConvertFlagStr(flagStr) & GetAppMsgFlags(appProperty)) != 0) && + bundleName.find("wps") != std::string::npos) { + return true; + } + return false; +} + +void SandboxCore::UpdateMsgFlagsWithPermission(AppSpawningCtx *appProperty) +{ + int32_t processIndex = GetPermissionIndex(nullptr, SandboxCommonDef::GET_ALL_PROCESSES_MODE.c_str()); + if ((CheckAppPermissionFlagSet(appProperty, static_cast(processIndex)) == 0)) { + APPSPAWN_LOGV("Don't need set GET_ALL_PROCESSES_MODE flag"); + return; + } + + int ret = SetAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_GET_ALL_PROCESSES); + if (ret != 0) { + APPSPAWN_LOGV("Set GET_ALL_PROCESSES_MODE flag failed"); + } +} + +int32_t SandboxCore::UpdatePermissionFlags(AppSpawningCtx *appProperty) +{ + int32_t index = 0; + int32_t appFullMountStatus = SandboxCommon::CheckAppFullMountEnable(); + if (appFullMountStatus == SandboxCommonDef::FILE_CROSS_APP_STATUS) { + index = GetPermissionIndex(nullptr, SandboxCommonDef::FILE_CROSS_APP_MODE.c_str()); + } else if (appFullMountStatus == SandboxCommonDef::FILE_ACCESS_COMMON_DIR_STATUS) { + index = GetPermissionIndex(nullptr, SandboxCommonDef::FILE_ACCESS_COMMON_DIR_MODE.c_str()); + } + int32_t fileMgrIndex = GetPermissionIndex(nullptr, SandboxCommonDef::FILE_ACCESS_MANAGER_MODE.c_str()); + if (index > 0 && (CheckAppPermissionFlagSet(appProperty, static_cast(fileMgrIndex)) == 0)) { + return SetAppPermissionFlags(appProperty, index); + } + return 0; +} + +std::string SandboxCore::GetSandboxPath(const AppSpawningCtx *appProperty, cJSON *mntPoint, + const std::string §ion, std::string sandboxRoot) +{ + std::string sandboxPath = ""; + const char *tmpSandboxPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_sandBoxPath); + if (tmpSandboxPathChr == nullptr) { + return ""; + } + std::string tmpSandboxPath(tmpSandboxPathChr); + if (section.compare(SandboxCommonDef::g_permissionPrefix) == 0) { + sandboxPath = sandboxRoot + SandboxCommon::ConvertToRealPathWithPermission(appProperty, tmpSandboxPath); + } else { + sandboxPath = sandboxRoot + SandboxCommon::ConvertToRealPath(appProperty, tmpSandboxPath); + } + return sandboxPath; +} + +int32_t SandboxCore::DoDlpAppMountStrategy(const AppSpawningCtx *appProperty, const std::string &srcPath, + const std::string &sandboxPath, const std::string &fsType, unsigned long mountFlags) +{ + AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); + if (dacInfo == nullptr) { + return -1; + } + + // umount fuse path, make sure that sandbox path is not a mount point + umount2(sandboxPath.c_str(), MNT_DETACH); + + int fd = open("/dev/fuse", O_RDWR); + APPSPAWN_CHECK(fd != -1, return -EINVAL, "open /dev/fuse failed, errno is %{public}d", errno); + + char options[SandboxCommonDef::OPTIONS_MAX_LEN]; + (void)sprintf_s(options, sizeof(options), "fd=%d," + "rootmode=40000,user_id=%u,group_id=%u,allow_other," + "context=\"u:object_r:dlp_fuse_file:s0\"," + "fscontext=u:object_r:dlp_fuse_file:s0", + fd, dacInfo->uid, dacInfo->gid); + + // To make sure destinationPath exist + (void)SandboxCommon::CreateDirRecursive(sandboxPath, SandboxCommonDef::FILE_MODE); + + int ret = 0; +#ifndef APPSPAWN_TEST + APPSPAWN_LOGV("Bind mount %{public}s to %{public}s '%{public}s' '%{public}lu' '%{public}s'", + srcPath.c_str(), sandboxPath.c_str(), fsType.c_str(), mountFlags, options); + ret = mount(srcPath.c_str(), sandboxPath.c_str(), fsType.c_str(), mountFlags, options); + APPSPAWN_CHECK(ret == 0, close(fd); + return ret, "DoDlpAppMountStrategy failed, bind mount %{public}s to %{public}s failed %{public}d", + srcPath.c_str(), sandboxPath.c_str(), errno); + + ret = mount(nullptr, sandboxPath.c_str(), nullptr, MS_SHARED, nullptr); + APPSPAWN_CHECK(ret == 0, close(fd); + return ret, "errno is: %{public}d, private mount to %{public}s failed", errno, sandboxPath.c_str()); +#endif + /* set DLP_FUSE_FD */ +#ifdef WITH_DLP + SetDlpFuseFd(fd); +#endif + return fd; +} + +int32_t SandboxCore::HandleSpecialAppMount(const AppSpawningCtx *appProperty, const std::string &srcPath, + const std::string &sandboxPath, const std::string &fsType, unsigned long mountFlags) +{ + std::string bundleName = GetBundleName(appProperty); + std::string processName = GetProcessName(appProperty); + /* dlp application mount strategy */ + /* dlp is an example, we should change to real bundle name later */ + if (bundleName.find(SandboxCommonDef::g_dlpBundleName) != std::string::npos && + processName.compare(SandboxCommonDef::g_dlpBundleName) == 0) { + if (!fsType.empty()) { + return DoDlpAppMountStrategy(appProperty, srcPath, sandboxPath, fsType, mountFlags); + } + } + return -1; +} + +cJSON *SandboxCore::GetPrivateJsonInfo(const AppSpawningCtx *appProperty, cJSON *wholeConfig) +{ + cJSON *firstPrivate = GetFirstCommonConfig(wholeConfig, SandboxCommonDef::g_privatePrefix); + if (!firstPrivate) { + return nullptr; + } + + const char *bundleName = GetBundleName(appProperty); + return GetFirstSubConfig(firstPrivate, bundleName); +} + +int32_t SandboxCore::DoSandboxFilePrivateBind(const AppSpawningCtx *appProperty, cJSON *wholeConfig) +{ + cJSON *bundleNameInfo = GetPrivateJsonInfo(appProperty, wholeConfig); + if (bundleNameInfo == nullptr) { + return 0; + } + (void)DoAddGid((AppSpawningCtx *)appProperty, bundleNameInfo, "", SandboxCommonDef::g_privatePrefix); + return DoAllMntPointsMount(appProperty, bundleNameInfo, nullptr, SandboxCommonDef::g_privatePrefix); +} + +int32_t SandboxCore::DoSandboxFilePrivateSymlink(const AppSpawningCtx *appProperty, cJSON *wholeConfig) +{ + cJSON *bundleNameInfo = GetPrivateJsonInfo(appProperty, wholeConfig); + if (bundleNameInfo == nullptr) { + return 0; + } + return DoAllSymlinkPointslink(appProperty, bundleNameInfo); +} + +int32_t SandboxCore::DoSandboxFilePrivateFlagsPointHandle(const AppSpawningCtx *appProperty, cJSON *wholeConfig) +{ + cJSON *bundleNameInfo = GetPrivateJsonInfo(appProperty, wholeConfig); + if (bundleNameInfo == nullptr) { + return 0; + } + return HandleFlagsPoint(appProperty, bundleNameInfo); +} + +int32_t SandboxCore::SetPrivateAppSandboxProperty_(const AppSpawningCtx *appProperty, cJSON *config) +{ + int ret = DoSandboxFilePrivateBind(appProperty, config); + APPSPAWN_CHECK(ret == 0, return ret, "DoSandboxFilePrivateBind failed"); + + ret = DoSandboxFilePrivateSymlink(appProperty, config); + APPSPAWN_CHECK_ONLY_LOG(ret == 0, "DoSandboxFilePrivateSymlink failed"); + + ret = DoSandboxFilePrivateFlagsPointHandle(appProperty, config); + APPSPAWN_CHECK_ONLY_LOG(ret == 0, "DoSandboxFilePrivateFlagsPointHandle failed"); + + return ret; +} + +int32_t SandboxCore::DoSandboxFilePermissionBind(AppSpawningCtx *appProperty, cJSON *wholeConfig) +{ + cJSON *permission = cJSON_GetObjectItemCaseSensitive(wholeConfig, SandboxCommonDef::g_permissionPrefix); + if (!permission || !cJSON_IsArray(permission)) { + return 0; + } + + auto processor = [&appProperty](cJSON *item) { + cJSON *permissionChild = item->child; + while (permissionChild != nullptr) { + int index = GetPermissionIndex(nullptr, permissionChild->string); + APPSPAWN_LOGV("DoSandboxFilePermissionBind %{public}s index %{public}d", permissionChild->string, index); + if (CheckAppPermissionFlagSet(appProperty, static_cast(index)) == 0) { + permissionChild = permissionChild->next; + continue; + } + DoAddGid(appProperty, permissionChild, permissionChild->string, SandboxCommonDef::g_permissionPrefix); + cJSON *permissionMountPaths = cJSON_GetArrayItem(permissionChild, 0); + if (!permissionMountPaths) { + permissionChild = permissionChild->next; + continue; + } + DoAddGid(appProperty, permissionMountPaths, permissionChild->string, SandboxCommonDef::g_permissionPrefix); + DoAllMntPointsMount(appProperty, permissionMountPaths, permissionChild->string, + SandboxCommonDef::g_permissionPrefix); + + permissionChild = permissionChild->next; + } + return 0; + }; + + return SandboxCommon::HandleArrayForeach(permission, processor); +} + +int32_t SandboxCore::SetPermissionAppSandboxProperty_(AppSpawningCtx *appProperty, cJSON *config) +{ + int ret = DoSandboxFilePermissionBind(appProperty, config); + APPSPAWN_CHECK(ret == 0, return ret, "DoSandboxFilePermissionBind failed"); + return ret; +} + +cJSON *SandboxCore::GetFirstCommonConfig(cJSON *wholeConfig, const char *prefix) +{ + cJSON *commonConfig = cJSON_GetObjectItemCaseSensitive(wholeConfig, prefix); + if (!commonConfig || !cJSON_IsArray(commonConfig)) { + return nullptr; + } + + return cJSON_GetArrayItem(commonConfig, 0); +} + +cJSON *SandboxCore::GetFirstSubConfig(cJSON *parent, const char *key) +{ + cJSON *config = cJSON_GetObjectItemCaseSensitive(parent, key); + if (!config || !cJSON_IsArray(config)) { + return nullptr; + } + + return cJSON_GetArrayItem(config, 0); +} + +int32_t SandboxCore::DoSandboxFileCommonBind(const AppSpawningCtx *appProperty, cJSON *wholeConfig) +{ + cJSON *firstCommon = GetFirstCommonConfig(wholeConfig, SandboxCommonDef::g_commonPrefix); + if (!firstCommon) { + return 0; + } + + cJSON *appBaseConfig = GetFirstSubConfig(firstCommon, SandboxCommonDef::g_appBase); + if (!appBaseConfig) { + return 0; + } + + int ret = DoAllMntPointsMount(appProperty, appBaseConfig, nullptr, SandboxCommonDef::g_appBase); + if (ret) { + return ret; + } + + cJSON *appResourcesConfig = GetFirstSubConfig(firstCommon, SandboxCommonDef::g_appResources); + if (!appResourcesConfig) { + return 0; + } + ret = DoAllMntPointsMount(appProperty, appResourcesConfig, nullptr, SandboxCommonDef::g_appResources); + return ret; +} + +int32_t SandboxCore::DoSandboxFileCommonSymlink(const AppSpawningCtx *appProperty, cJSON *wholeConfig) +{ + cJSON *firstCommon = GetFirstCommonConfig(wholeConfig, SandboxCommonDef::g_commonPrefix); + if (!firstCommon) { + return 0; + } + + cJSON *appBaseConfig = GetFirstSubConfig(firstCommon, SandboxCommonDef::g_appBase); + if (!appBaseConfig) { + return 0; + } + + int ret = DoAllSymlinkPointslink(appProperty, appBaseConfig); + if (ret) { + return ret; + } + + cJSON *appResourcesConfig = GetFirstSubConfig(firstCommon, SandboxCommonDef::g_appResources); + if (!appResourcesConfig) { + return 0; + } + ret = DoAllSymlinkPointslink(appProperty, appResourcesConfig); + return ret; +} + +int32_t SandboxCore::DoSandboxFileCommonFlagsPointHandle(const AppSpawningCtx *appProperty, cJSON *wholeConfig) +{ + cJSON *firstCommon = GetFirstCommonConfig(wholeConfig, SandboxCommonDef::g_commonPrefix); + if (!firstCommon) { + return 0; + } + + cJSON *appResoucesConfig = GetFirstSubConfig(firstCommon, SandboxCommonDef::g_appResources); + if (!appResoucesConfig) { + return 0; + } + + return HandleFlagsPoint(appProperty, appResoucesConfig); +} + +int32_t SandboxCore::SetCommonAppSandboxProperty_(const AppSpawningCtx *appProperty, cJSON *config) +{ + int rc = 0; + rc = DoSandboxFileCommonBind(appProperty, config); + APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxFileCommonBind failed, %{public}s", GetBundleName(appProperty)); + + // if sandbox switch is off, don't do symlink work again + if (SandboxCommon::IsAppSandboxEnabled(appProperty) == true && + (SandboxCommon::IsTotalSandboxEnabled(appProperty) == true)) { + rc = DoSandboxFileCommonSymlink(appProperty, config); + APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxFileCommonSymlink failed, %{public}s", GetBundleName(appProperty)); + } + + rc = DoSandboxFileCommonFlagsPointHandle(appProperty, config); + APPSPAWN_CHECK_ONLY_LOG(rc == 0, "DoSandboxFilePrivateFlagsPointHandle failed"); + + return rc; +} + +static inline bool CheckPath(const std::string& name) +{ + return !name.empty() && name != "." && name != ".." && name.find("/") == std::string::npos; +} + +static inline cJSON *GetJsonObjFromProperty(const AppSpawningCtx *appProperty, const char *name) +{ + uint32_t size = 0; + const char *extInfo = (char *)(GetAppSpawnMsgExtInfo(appProperty->message, name, &size)); + if (size == 0 || extInfo == nullptr) { + return nullptr; + } + APPSPAWN_LOGV("Get json name %{public}s value %{public}s", name, extInfo); + cJSON *root = cJSON_Parse(extInfo); + APPSPAWN_CHECK(root != nullptr, return nullptr, "Invalid ext info %{public}s for %{public}s", extInfo, name); + return root; +} + +int32_t SandboxCore::MountAllHsp(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath) +{ + if (appProperty == nullptr || sandboxPackagePath == "") { + return 0; + } + int ret = 0; + cJSON *hspRoot = GetJsonObjFromProperty(appProperty, SandboxCommonDef::HSPLIST_SOCKET_TYPE.c_str()); + APPSPAWN_CHECK_ONLY_EXPER(hspRoot != nullptr && cJSON_IsObject(hspRoot), return 0); + + cJSON *bundles = cJSON_GetObjectItemCaseSensitive(hspRoot, "bundles"); + cJSON *modules = cJSON_GetObjectItemCaseSensitive(hspRoot, "modules"); + cJSON *versions = cJSON_GetObjectItemCaseSensitive(hspRoot, "versions"); + APPSPAWN_CHECK(bundles != nullptr && cJSON_IsArray(bundles), return -1, "MountAllHsp: invalid bundles"); + APPSPAWN_CHECK(modules != nullptr && cJSON_IsArray(modules), return -1, "MountAllHsp: invalid modules"); + APPSPAWN_CHECK(versions != nullptr && cJSON_IsArray(versions), return -1, "MountAllHsp: invalid versions"); + int count = cJSON_GetArraySize(bundles); + APPSPAWN_CHECK(count == cJSON_GetArraySize(modules), return -1, "MountAllHsp: sizes are not same"); + APPSPAWN_CHECK(count == cJSON_GetArraySize(versions), return -1, "MountAllHsp: sizes are not same"); + + APPSPAWN_LOGI("MountAllHsp app: %{public}s, count: %{public}d", GetBundleName(appProperty), count); + for (int i = 0; i < count; i++) { + if (!(cJSON_IsString(cJSON_GetArrayItem(bundles, i)) && cJSON_IsString(cJSON_GetArrayItem(modules, i)) && + cJSON_IsString(cJSON_GetArrayItem(versions, i)))) { + return -1; + } + const char *libBundleName = cJSON_GetStringValue(cJSON_GetArrayItem(bundles, i)); + const char *libModuleName = cJSON_GetStringValue(cJSON_GetArrayItem(modules, i)); + const char *libVersion = cJSON_GetStringValue(cJSON_GetArrayItem(versions, i)); + APPSPAWN_CHECK(libBundleName != nullptr && libModuleName != nullptr && libVersion != nullptr, + return -1, "MountAllHsp: config error"); + APPSPAWN_CHECK(CheckPath(libBundleName) && CheckPath(libModuleName) && CheckPath(libVersion), + return -1, "MountAllHsp: path error"); + + std::string libPhysicalPath = SandboxCommonDef::g_physicalAppInstallPath + libBundleName + "/" + + libVersion + "/" + libModuleName; + std::string mntPath = + sandboxPackagePath + SandboxCommonDef::g_sandboxHspInstallPath + libBundleName + "/" + libModuleName; + SharedMountArgs arg = { + .srcPath = libPhysicalPath.c_str(), + .destPath = mntPath.c_str() + }; + ret = SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg); + APPSPAWN_CHECK(ret == 0, return 0, "mount library failed %{public}d", ret); + } + cJSON_Delete(hspRoot); + return 0; +} + +int32_t SandboxCore::MountAllGroup(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath) +{ + if (appProperty == nullptr || sandboxPackagePath == "") { + return 0; + } + cJSON *dataGroupRoot = GetJsonObjFromProperty(appProperty, SandboxCommonDef::DATA_GROUP_SOCKET_TYPE.c_str()); + APPSPAWN_CHECK_ONLY_EXPER(dataGroupRoot != nullptr, return 0); + + mode_t mountSharedFlag = MS_SLAVE; + if (CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX)) { + APPSPAWN_LOGV("Data group flags is isolated"); + mountSharedFlag |= MS_REMOUNT | MS_NODEV | MS_RDONLY | MS_BIND; + } + + auto processor = [&appProperty, &sandboxPackagePath, &mountSharedFlag](cJSON *item) { + APPSPAWN_CHECK(IsValidDataGroupItem(item), return -1, "MountAllGroup: data group item error"); + const char *srcPathChr = GetStringFromJsonObj(item, SandboxCommonDef::g_groupList_key_dir.c_str()); + if (srcPathChr == nullptr) { + return 0; + } + std::string srcPath(srcPathChr); + APPSPAWN_CHECK(!CheckPath(srcPath), return -1, "MountAllGroup: path error"); + const char *uuidChr = GetStringFromJsonObj(item, SandboxCommonDef::g_groupList_key_uuid.c_str()); + if (uuidChr == nullptr) { + return 0; + } + std::string uuidStr(uuidChr); + + int elxValue = GetElxInfoFromDir(srcPath.c_str()); + APPSPAWN_CHECK((elxValue >= EL2 && elxValue < ELX_MAX), return -1, "Get elx value failed"); + + const DataGroupSandboxPathTemplate *templateItem = GetDataGroupArgTemplate(elxValue); + APPSPAWN_CHECK(templateItem != nullptr, return -1, "Get data group arg template failed"); + + // If permission isn't null, need check permission flag + if (templateItem->permission != nullptr) { + int index = GetPermissionIndex(nullptr, templateItem->permission); + APPSPAWN_LOGV("mount dir no lock mount permission flag %{public}d", index); + if (CheckAppPermissionFlagSet(appProperty, static_cast(index)) == 0) { + return 0; + } + } + + std::string mntPath = sandboxPackagePath + templateItem->sandboxPath + uuidStr; + SharedMountArgs arg = { + .srcPath = srcPath.c_str(), + .destPath = mntPath.c_str(), + .mountSharedFlag = mountSharedFlag + }; + int result = SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg); + if (result != 0) { + APPSPAWN_LOGE("mount el%{public}d datagroup failed", elxValue); + } + return 0; + }; + int ret = SandboxCommon::HandleArrayForeach(dataGroupRoot, processor); + cJSON_Delete(dataGroupRoot); + return ret; +} + +int32_t SandboxCore::ProcessMountPoint(cJSON *mntPoint, MountPointProcessParams ¶ms) +{ + APPSPAWN_CHECK_ONLY_EXPER(SandboxCommon::IsValidMountConfig(mntPoint, params.appProperty, params.checkFlag), + return 0); + const char *srcPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_srcPath); + const char *sandboxPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_sandBoxPath); + if (srcPathChr == nullptr || sandboxPathChr == nullptr) { + return 0; + } + std::string srcPath(srcPathChr); + std::string sandboxPath(sandboxPathChr); + srcPath = SandboxCommon::ConvertToRealPath(params.appProperty, srcPath); + APPSPAWN_CHECK_ONLY_EXPER(SandboxCommon::IsCreateSandboxPathEnabled(mntPoint, srcPath), return 0); + sandboxPath = GetSandboxPath(params.appProperty, mntPoint, params.section, params.sandboxRoot); + SandboxMountConfig mountConfig = {0}; + SandboxCommon::GetSandboxMountConfig(params.appProperty, params.section, mntPoint, mountConfig); + SharedMountArgs arg = { + .srcPath = srcPath.c_str(), + .destPath = sandboxPath.c_str(), + .fsType = mountConfig.fsType.c_str(), + .mountFlags = SandboxCommon::GetMountFlags(mntPoint), + .options = mountConfig.optionsPoint.c_str(), + .mountSharedFlag = + GetBoolValueFromJsonObj(mntPoint, SandboxCommonDef::g_mountSharedFlag, false) ? MS_SHARED : MS_SLAVE + }; + + /* if app mount failed for special strategy, we need deal with common mount config */ + int ret = HandleSpecialAppMount(params.appProperty, arg.srcPath, arg.destPath, arg.fsType, arg.mountFlags); + if (ret < 0) { + ret = SandboxCommon::DoAppSandboxMountOnce(params.appProperty, &arg); + } + APPSPAWN_CHECK(ret == 0 || !SandboxCommon::IsMountSuccessful(mntPoint), +#ifdef APPSPAWN_HISYSEVENT + ReportMountFail(params.bundleName.c_str(), arg.srcPath, arg.destPath, errno); + ret = APPSPAWN_SANDBOX_MOUNT_FAIL; +#endif + return ret, + "DoAppSandboxMountOnce section %{public}s failed, %{public}s", params.section.c_str(), arg.destPath); + SetDecPolicyWithPermission(params.appProperty, mountConfig); + SandboxCommon::SetSandboxPathChmod(mntPoint, params.sandboxRoot); + return 0; +} + +int32_t SandboxCore::DoAllMntPointsMount(const AppSpawningCtx *appProperty, cJSON *appConfig, + const char *typeName, const std::string §ion) +{ + std::string bundleName = GetBundleName(appProperty); + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(appConfig, SandboxCommonDef::g_mountPrefix); + if (mountPoints == nullptr || !cJSON_IsArray(mountPoints)) { + APPSPAWN_LOGI("mount config is not found in %{public}s, app name is %{public}s", + section.c_str(), bundleName.c_str()); + return 0; + } + + std::string sandboxRoot = SandboxCommon::GetSandboxRootPath(appProperty, appConfig); + bool checkFlag = CheckMountFlag(appProperty, bundleName, appConfig); + MountPointProcessParams mountPointParams = { + .appProperty = appProperty, + .checkFlag = checkFlag, + .section = section, + .sandboxRoot = sandboxRoot, + .bundleName = bundleName + }; + + auto processor = [&mountPointParams](cJSON *mntPoint) { + return ProcessMountPoint(mntPoint, mountPointParams); + }; + + return SandboxCommon::HandleArrayForeach(mountPoints, processor); +} + +int32_t SandboxCore::DoAddGid(AppSpawningCtx *appProperty, cJSON *appConfig, + const char *permissionName, const std::string §ion) +{ + AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); + if (dacInfo == nullptr) { + return 0; + } + + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(appConfig, SandboxCommonDef::g_gidPrefix); + if (mountPoints == nullptr || !cJSON_IsArray(mountPoints)) { + return 0; + } + + std::string bundleName = GetBundleName(appProperty); + auto processor = [&dacInfo](cJSON *item) { + gid_t gid = 0; + if (cJSON_IsNumber(item)) { + gid = (gid_t)cJSON_GetNumberValue(item); + } + if (gid <= 0) { + return 0; + } + if (dacInfo->gidCount < APP_MAX_GIDS) { + dacInfo->gidTable[dacInfo->gidCount++] = gid; + } + return 0; + }; + + return SandboxCommon::HandleArrayForeach(mountPoints, processor); +} + +int32_t SandboxCore::DoAllSymlinkPointslink(const AppSpawningCtx *appProperty, cJSON *appConfig) +{ + cJSON *symlinkPoints = cJSON_GetObjectItemCaseSensitive(appConfig, SandboxCommonDef::g_symlinkPrefix); + if (symlinkPoints == nullptr || !cJSON_IsArray(symlinkPoints)) { + APPSPAWN_LOGV("symlink config is not found"); + return 0; + } + + std::string sandboxRoot = SandboxCommon::GetSandboxRootPath(appProperty, appConfig); + auto processor = [&appProperty, &sandboxRoot](cJSON *item) { + const char *targetNameChr = GetStringFromJsonObj(item, SandboxCommonDef::g_targetName); + const char *linkNameChr = GetStringFromJsonObj(item, SandboxCommonDef::g_linkName); + if (targetNameChr == nullptr || linkNameChr == nullptr) { + return 0; + } + std::string targetName(targetNameChr); + std::string linkName(linkNameChr); + targetName = SandboxCommon::ConvertToRealPath(appProperty, targetName); + linkName = sandboxRoot + SandboxCommon::ConvertToRealPath(appProperty, linkName); + int ret = symlink(targetName.c_str(), linkName.c_str()); + if (ret && errno != EEXIST && SandboxCommon::IsMountSuccessful(item)) { + APPSPAWN_LOGE("errno is %{public}d, symlink failed, %{public}s", errno, linkName.c_str()); + return -1; + } + SandboxCommon::SetSandboxPathChmod(item, sandboxRoot); + return 0; + }; + + return SandboxCommon::HandleArrayForeach(symlinkPoints, processor); +} + +int32_t SandboxCore::DoSandboxRootFolderCreateAdapt(std::string &sandboxPackagePath) +{ +#ifndef APPSPAWN_TEST + int rc = mount(nullptr, "/", nullptr, MS_REC | MS_SLAVE, nullptr); + APPSPAWN_CHECK(rc == 0, return rc, "set propagation slave failed"); +#endif + (void)SandboxCommon::CreateDirRecursive(sandboxPackagePath, SandboxCommonDef::FILE_MODE); + + // bind mount "/" to /mnt/sandbox// path + // rootfs: to do more resources bind mount here to get more strict resources constraints +#ifndef APPSPAWN_TEST + rc = mount("/", sandboxPackagePath.c_str(), nullptr, SandboxCommonDef::BASIC_MOUNT_FLAGS, nullptr); + APPSPAWN_CHECK(rc == 0, return rc, "mount bind / failed, %{public}d", errno); +#endif + return 0; +} + +int32_t SandboxCore::DoSandboxRootFolderCreate(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath) +{ +#ifndef APPSPAWN_TEST + int rc = mount(nullptr, "/", nullptr, MS_REC | MS_SLAVE, nullptr); + if (rc) { + return rc; + } +#endif + SharedMountArgs arg = { + .srcPath = sandboxPackagePath.c_str(), + .destPath = sandboxPackagePath.c_str() + }; + SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg); + + return 0; +} + +int32_t SandboxCore::HandleFlagsPoint(const AppSpawningCtx *appProperty, cJSON *appConfig) +{ + cJSON *flagsPoints = cJSON_GetObjectItemCaseSensitive(appConfig, SandboxCommonDef::g_flagePoint); + if (flagsPoints == nullptr || !cJSON_IsArray(flagsPoints)) { + APPSPAWN_LOGV("flag points config is not found"); + return 0; + } + + auto processor = [&appProperty](cJSON *item) { + const char *flagsChr = GetStringFromJsonObj(item, SandboxCommonDef::g_flags); + if (flagsChr == nullptr) { + return 0; + } + std::string flagsStr(flagsChr); + uint32_t flag = SandboxCommon::ConvertFlagStr(flagsStr); + if ((GetAppMsgFlags(appProperty) & flag) == 0) { + return 0; + } + return DoAllMntPointsMount(appProperty, item, nullptr, SandboxCommonDef::g_flagePoint); + }; + return SandboxCommon::HandleArrayForeach(flagsPoints, processor); +} + +int32_t SandboxCore::SetOverlayAppSandboxProperty(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath) +{ + int ret = 0; + if (!CheckAppMsgFlagsSet(appProperty, APP_FLAGS_OVERLAY)) { + return ret; + } + + std::string overlayInfo = SandboxCommon::GetExtraInfoByType(appProperty, SandboxCommonDef::OVERLAY_SOCKET_TYPE); + std::set mountedSrcSet; + std::vector splits = SandboxCommon::SplitString(overlayInfo, SandboxCommonDef::g_overlayDecollator); + std::string sandboxOverlayPath = sandboxPackagePath + SandboxCommonDef::g_overlayPath; + for (auto hapPath : splits) { + size_t pathIndex = hapPath.find_last_of(SandboxCommonDef::g_fileSeparator); + if (pathIndex == std::string::npos) { + continue; + } + std::string srcPath = hapPath.substr(0, pathIndex); + if (mountedSrcSet.find(srcPath) != mountedSrcSet.end()) { + APPSPAWN_LOGV("%{public}s have mounted before, no need to mount twice.", srcPath.c_str()); + continue; + } + + auto bundleNameIndex = srcPath.find_last_of(SandboxCommonDef::g_fileSeparator); + std::string destPath = sandboxOverlayPath + srcPath.substr(bundleNameIndex + 1, srcPath.length()); + SharedMountArgs arg = { + .srcPath = srcPath.c_str(), + .destPath = destPath.c_str() + }; + int32_t retMount = SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg); + if (retMount != 0) { + APPSPAWN_LOGE("fail to mount overlay path, src is %{public}s.", hapPath.c_str()); + ret = retMount; + } + + mountedSrcSet.emplace(srcPath); + } + return ret; +} + +int32_t SandboxCore::SetBundleResourceAppSandboxProperty(const AppSpawningCtx *appProperty, + std::string &sandboxPackagePath) +{ + if (!CheckAppMsgFlagsSet(appProperty, APP_FLAGS_BUNDLE_RESOURCES)) { + return 0; + } + + std::string destPath = sandboxPackagePath + SandboxCommonDef::g_bundleResourceDestPath; + SharedMountArgs arg = { + .srcPath = SandboxCommonDef::g_bundleResourceSrcPath.c_str(), + .destPath = destPath.c_str() + }; + return SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg); +} + +int32_t SandboxCore::SetCommonAppSandboxProperty(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath) +{ + int ret = 0; + SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? + SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG; + + for (auto& jsonConfig : SandboxCommon::GetCJsonConfig(type)) { + ret = SetCommonAppSandboxProperty_(appProperty, jsonConfig); + APPSPAWN_CHECK(ret == 0, return ret, + "parse appdata config for common failed, %{public}s", sandboxPackagePath.c_str()); + } + + ret = MountAllHsp(appProperty, sandboxPackagePath); + APPSPAWN_CHECK(ret == 0, return ret, "mount extraInfo failed, %{public}s", sandboxPackagePath.c_str()); + + ret = MountAllGroup(appProperty, sandboxPackagePath); + APPSPAWN_CHECK(ret == 0, return ret, "mount groupList failed, %{public}s", sandboxPackagePath.c_str()); + + AppSpawnMsgDomainInfo *info = + reinterpret_cast(GetAppProperty(appProperty, TLV_DOMAIN_INFO)); + APPSPAWN_CHECK(info != nullptr, return -1, "No domain info %{public}s", sandboxPackagePath.c_str()); + if (strcmp(info->apl, SandboxCommonDef::APL_SYSTEM_BASIC.data()) == 0 || + strcmp(info->apl, SandboxCommonDef::APL_SYSTEM_CORE.data()) == 0 || + CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ACCESS_BUNDLE_DIR)) { + // need permission check for system app here + std::string destbundlesPath = sandboxPackagePath + SandboxCommonDef::g_dataBundles; + SharedMountArgs arg = { + .srcPath = SandboxCommonDef::g_physicalAppInstallPath.c_str(), + .destPath = destbundlesPath.c_str() + }; + SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg); + } + + return 0; +} + +int32_t SandboxCore::SetPrivateAppSandboxProperty(const AppSpawningCtx *appProperty) +{ + int ret = 0; + SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? + SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG; + + for (auto& config : SandboxCommon::GetCJsonConfig(type)) { + ret = SetPrivateAppSandboxProperty_(appProperty, config); + APPSPAWN_CHECK(ret == 0, return ret, "parse adddata-sandbox config failed"); + } + return ret; +} + +int32_t SandboxCore::SetPermissionAppSandboxProperty(AppSpawningCtx *appProperty) +{ + int ret = 0; + SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? + SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG; + + for (auto& config : SandboxCommon::GetCJsonConfig(type)) { + ret = SetPermissionAppSandboxProperty_(appProperty, config); + APPSPAWN_CHECK(ret == 0, return ret, "parse permission config failed"); + } + return ret; +} + +int32_t SandboxCore::SetSandboxProperty(AppSpawningCtx *appProperty, std::string &sandboxPackagePath) +{ + int32_t ret = 0; + const std::string bundleName = GetBundleName(appProperty); + ret = SetCommonAppSandboxProperty(appProperty, sandboxPackagePath); + APPSPAWN_CHECK(ret == 0, return ret, "SetCommonAppSandboxProperty failed, packagename is %{public}s", + bundleName.c_str()); + if (SandboxCommon::HasPrivateInBundleName(bundleName)) { + ret = SetPrivateAppSandboxProperty(appProperty); + APPSPAWN_CHECK(ret == 0, return ret, "SetPrivateAppSandboxProperty failed, packagename is %{public}s", + bundleName.c_str()); + } + ret = SetPermissionAppSandboxProperty(appProperty); + APPSPAWN_CHECK(ret == 0, return ret, "SetPermissionAppSandboxProperty failed, packagename is %{public}s", + bundleName.c_str()); + + ret = SetOverlayAppSandboxProperty(appProperty, sandboxPackagePath); + APPSPAWN_CHECK(ret == 0, return ret, "SetOverlayAppSandboxProperty failed, packagename is %{public}s", + bundleName.c_str()); + + ret = SetBundleResourceAppSandboxProperty(appProperty, sandboxPackagePath); + APPSPAWN_CHECK(ret == 0, return ret, "SetBundleResourceAppSandboxProperty failed, packagename is %{public}s", + bundleName.c_str()); + APPSPAWN_LOGV("Set appsandbox property success"); + return ret; +} + +int32_t SandboxCore::SetAppSandboxProperty(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags) +{ + APPSPAWN_CHECK(appProperty != nullptr, return -1, "Invalid appspawn client"); + if (SandboxCommon::CheckBundleName(GetBundleName(appProperty)) != 0) { + return -1; + } + AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); + if (dacInfo == nullptr) { + return -1; + } + + const std::string bundleName = GetBundleName(appProperty); + cJSON *tmpJson = nullptr; + std::string sandboxPackagePath = SandboxCommon::GetSandboxRootPath(appProperty, tmpJson); + SandboxCommon::CreateDirRecursiveWithClock(sandboxPackagePath.c_str(), SandboxCommonDef::FILE_MODE); + bool sandboxSharedStatus = SandboxCommon::IsPrivateSharedStatus(bundleName, appProperty) || + (CheckAppPermissionFlagSet(appProperty, static_cast(GetPermissionIndex(nullptr, + SandboxCommonDef::ACCESS_DLP_FILE_MODE.c_str()))) != 0); + + // add pid to a new mnt namespace + int rc = EnableSandboxNamespace(appProperty, sandboxNsFlags); + APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", bundleName.c_str()); + if (UpdatePermissionFlags(appProperty) != 0) { + APPSPAWN_LOGW("Set app permission flag fail."); + return -1; + } + UpdateMsgFlagsWithPermission(appProperty); + // check app sandbox switch + if ((SandboxCommon::IsTotalSandboxEnabled(appProperty) == false) || + (SandboxCommon::IsAppSandboxEnabled(appProperty) == false)) { + rc = DoSandboxRootFolderCreateAdapt(sandboxPackagePath); + } else if (!sandboxSharedStatus) { + rc = DoSandboxRootFolderCreate(appProperty, sandboxPackagePath); + } + APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxRootFolderCreate failed, %{public}s", bundleName.c_str()); + rc = SetSandboxProperty(appProperty, sandboxPackagePath); + APPSPAWN_CHECK(rc == 0, return rc, "SetSandboxProperty failed, %{public}s", bundleName.c_str()); + +#ifdef APPSPAWN_MOUNT_TMPSHM + MountDevShmPath(sandboxPackagePath); +#endif + +#ifndef APPSPAWN_TEST + rc = ChangeCurrentDir(sandboxPackagePath, bundleName, sandboxSharedStatus); + APPSPAWN_CHECK(rc == 0, return rc, "change current dir failed"); + APPSPAWN_LOGV("Change root dir success"); +#endif + SetDecWithDir(appProperty, dacInfo->uid / UID_BASE); + SetDecDenyWithDir(appProperty); + SetDecPolicy(); +#if defined(APPSPAWN_MOUNT_TMPSHM) && defined(WITH_SELINUX) + Restorecon(DEV_SHM_DIR); +#endif + return 0; +} + +int32_t SandboxCore::SetRenderSandboxPropertyNweb(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath) +{ + char *processType = (char *)(GetAppSpawnMsgExtInfo(appProperty->message, MSG_EXT_NAME_PROCESS_TYPE, nullptr)); + APPSPAWN_CHECK(processType != nullptr, return -1, "Invalid processType data"); + SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? + SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG; + + int ret = 0; + const char *bundleName = GetBundleName(appProperty); + for (auto& config : SandboxCommon::GetCJsonConfig(type)) { + cJSON *firstIndividual = GetFirstCommonConfig(config, SandboxCommonDef::g_privatePrefix); + if (!firstIndividual) { + continue; + } + if (strcmp(processType, "render") == 0) { + cJSON *renderInfo = GetFirstSubConfig(firstIndividual, SandboxCommonDef::g_ohosRender.c_str()); + if (!renderInfo) { + continue; + } + ret = DoAllMntPointsMount(appProperty, renderInfo, nullptr, SandboxCommonDef::g_ohosRender); + APPSPAWN_CHECK(ret == 0, return ret, "DoAllMntPointsMount failed, %{public}s", bundleName); + + ret = DoAllSymlinkPointslink(appProperty, renderInfo); + APPSPAWN_CHECK(ret == 0, return ret, "DoAllSymlinkPointslink failed, %{public}s", bundleName); + + ret = HandleFlagsPoint(appProperty, renderInfo); + APPSPAWN_CHECK_ONLY_LOG(ret == 0, "HandleFlagsPoint for render-sandbox failed, %{public}s", bundleName); + } else if (strcmp(processType, "gpu") == 0) { + cJSON *gpuInfo = GetFirstSubConfig(firstIndividual, SandboxCommonDef::g_ohosGpu.c_str()); + if (!gpuInfo) { + continue; + } + ret = DoAllMntPointsMount(appProperty, gpuInfo, nullptr, SandboxCommonDef::g_ohosGpu); + APPSPAWN_CHECK(ret == 0, return ret, "DoAllMntPointsMount failed, %{public}s", bundleName); + + ret = DoAllSymlinkPointslink(appProperty, gpuInfo); + APPSPAWN_CHECK(ret == 0, return ret, "DoAllSymlinkPointslink failed, %{public}s", bundleName); + + ret = HandleFlagsPoint(appProperty, gpuInfo); + APPSPAWN_CHECK_ONLY_LOG(ret == 0, "HandleFlagsPoint for gpu-sandbox failed, %{public}s", bundleName); + } + } + + return 0; +} + +int32_t SandboxCore::SetAppSandboxPropertyNweb(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags) +{ + APPSPAWN_CHECK(appProperty != nullptr, return -1, "Invalid appspawn client"); + if (SandboxCommon::CheckBundleName(GetBundleName(appProperty)) != 0) { + return -1; + } + std::string sandboxPackagePath = SandboxCommonDef::g_sandBoxRootDirNweb; + const std::string bundleName = GetBundleName(appProperty); + bool sandboxSharedStatus = SandboxCommon::IsPrivateSharedStatus(bundleName, appProperty); + sandboxPackagePath += bundleName; + SandboxCommon::CreateDirRecursiveWithClock(sandboxPackagePath.c_str(), SandboxCommonDef::FILE_MODE); + + // add pid to a new mnt namespace + int rc = EnableSandboxNamespace(appProperty, sandboxNsFlags); + APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", bundleName.c_str()); + + // check app sandbox switch + if ((SandboxCommon::IsTotalSandboxEnabled(appProperty) == false) || + (SandboxCommon::IsAppSandboxEnabled(appProperty) == false)) { + rc = DoSandboxRootFolderCreateAdapt(sandboxPackagePath); + } else if (!sandboxSharedStatus) { + rc = DoSandboxRootFolderCreate(appProperty, sandboxPackagePath); + } + APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxRootFolderCreate failed, %{public}s", bundleName.c_str()); + // rendering process can be created by different apps, + // and the bundle names of these apps are different, + // so we can't use the method SetPrivateAppSandboxProperty + // which mount dirs by using bundle name. + rc = SetRenderSandboxPropertyNweb(appProperty, sandboxPackagePath); + APPSPAWN_CHECK(rc == 0, return rc, "SetRenderSandboxPropertyNweb for %{public}s failed", bundleName.c_str()); + + rc = SetOverlayAppSandboxProperty(appProperty, sandboxPackagePath); + APPSPAWN_CHECK(rc == 0, return rc, "SetOverlayAppSandboxProperty for %{public}s failed", bundleName.c_str()); + + rc = SetBundleResourceAppSandboxProperty(appProperty, sandboxPackagePath); + APPSPAWN_CHECK(rc == 0, return rc, "SetBundleResourceAppSandboxProperty for %{public}s failed", bundleName.c_str()); + +#ifndef APPSPAWN_TEST + rc = chdir(sandboxPackagePath.c_str()); + APPSPAWN_CHECK(rc == 0, return rc, "chdir %{public}s failed, err %{public}d", sandboxPackagePath.c_str(), errno); + + if (sandboxSharedStatus) { + rc = chroot(sandboxPackagePath.c_str()); + APPSPAWN_CHECK(rc == 0, return rc, "chroot %{public}s failed, err %{public}d", + sandboxPackagePath.c_str(), errno); + return 0; + } + + rc = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str()); + APPSPAWN_CHECK(rc == 0, return rc, "pivot %{public}s failed, err %{public}d", sandboxPackagePath.c_str(), errno); + + rc = umount2(".", MNT_DETACH); + APPSPAWN_CHECK(rc == 0, return rc, "MNT_DETACH failed, packagename is %{public}s", bundleName.c_str()); +#endif + return 0; +} + +int32_t SandboxCore::ChangeCurrentDir(std::string &sandboxPackagePath, const std::string &bundleName, + bool sandboxSharedStatus) +{ + int32_t ret = 0; + ret = chdir(sandboxPackagePath.c_str()); + APPSPAWN_CHECK(ret == 0, return ret, "chdir %{public}s failed, err %{public}d", sandboxPackagePath.c_str(), errno); + + if (sandboxSharedStatus) { + ret = chroot(sandboxPackagePath.c_str()); + APPSPAWN_CHECK(ret == 0, return ret, "chroot %{public}s failed, err %{public}d", + sandboxPackagePath.c_str(), errno); + return ret; + } + + ret = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str()); + APPSPAWN_CHECK(ret == 0, return ret, "pivot %{public}s failed, err %{public}d", sandboxPackagePath.c_str(), errno); + + ret = umount2(".", MNT_DETACH); + APPSPAWN_CHECK(ret == 0, return ret, "MNT_DETACH failed, packagename is %{public}s", bundleName.c_str()); + return ret; +} + + + +static const DecDenyPathTemplate DEC_DENY_PATH_MAP[] = { + {"ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY", "/storage/Users/currentUser/Download"}, + {"ohos.permission.READ_WRITE_DESKTOP_DIRECTORY", "/storage/Users/currentUser/Desktop"}, + {"ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY", "/storage/Users/currentUser/Documents"}, +}; + +int32_t SandboxCore::SetDecWithDir(const AppSpawningCtx *appProperty, uint32_t userId) +{ + AppSpawnMsgAccessToken *tokenInfo = + reinterpret_cast(GetAppProperty(appProperty, TLV_ACCESS_TOKEN_INFO)); + APPSPAWN_CHECK(tokenInfo != nullptr, return APPSPAWN_MSG_INVALID, "Get token id failed."); + + AppSpawnMsgBundleInfo *bundleInfo = + reinterpret_cast(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); + APPSPAWN_CHECK(bundleInfo != nullptr, return APPSPAWN_MSG_INVALID, "No bundle info in msg %{public}s", + GetBundleName(appProperty)); + + uint32_t flags = CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE) ? 0x4 : 0; + if (flags == 0) { + flags = (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE) && + bundleInfo->bundleIndex > 0) ? 0x1 : 0; + } + std::ostringstream clonePackageName; + if (flags == 1) { + clonePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName; + } else { + clonePackageName << bundleInfo->bundleName; + } + std::string dir = "/storage/Users/currentUser/Download/" + clonePackageName.str(); + DecPolicyInfo decPolicyInfo = {0}; + decPolicyInfo.pathNum = 1; + PathInfo pathInfo = {0}; + pathInfo.path = strdup(dir.c_str()); + if (pathInfo.path == nullptr) { + APPSPAWN_LOGE("strdup %{public}s failed, err %{public}d", dir.c_str(), errno); + return APPSPAWN_MSG_INVALID; + } + pathInfo.pathLen = static_cast(strlen(pathInfo.path)); + pathInfo.mode = SANDBOX_MODE_WRITE | SANDBOX_MODE_READ; + decPolicyInfo.path[0] = pathInfo; + decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx; + decPolicyInfo.flag = true; + SetDecPolicyInfos(&decPolicyInfo); + + if (decPolicyInfo.path[0].path) { + free(decPolicyInfo.path[0].path); + decPolicyInfo.path[0].path = nullptr; + } + return 0; +} + +int32_t SandboxCore::SetDecPolicyWithPermission(const AppSpawningCtx *appProperty, SandboxMountConfig &mountConfig) +{ + if (mountConfig.decPaths.size() == 0) { + return 0; + } + AppSpawnMsgAccessToken *tokenInfo = + reinterpret_cast(GetAppProperty(appProperty, TLV_ACCESS_TOKEN_INFO)); + APPSPAWN_CHECK(tokenInfo != nullptr, return APPSPAWN_MSG_INVALID, "Get token id failed."); + + DecPolicyInfo decPolicyInfo = {0}; + decPolicyInfo.pathNum = mountConfig.decPaths.size(); + int ret = 0; + for (uint32_t i = 0; i < decPolicyInfo.pathNum; i++) { + PathInfo pathInfo = {0}; + pathInfo.path = strdup(mountConfig.decPaths[i].c_str()); + if (pathInfo.path == nullptr) { + APPSPAWN_LOGE("strdup %{public}s failed, err %{public}d", mountConfig.decPaths[i].c_str(), errno); + ret = APPSPAWN_ERROR_UTILS_MEM_FAIL; + goto EXIT; + } + pathInfo.pathLen = static_cast(strlen(pathInfo.path)); + pathInfo.mode = SANDBOX_MODE_WRITE | SANDBOX_MODE_READ; + decPolicyInfo.path[i] = pathInfo; + } + decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx; + decPolicyInfo.flag = true; + SetDecPolicyInfos(&decPolicyInfo); +EXIT: + for (uint32_t i = 0; i < decPolicyInfo.pathNum; i++) { + if (decPolicyInfo.path[i].path) { + free(decPolicyInfo.path[i].path); + decPolicyInfo.path[i].path = nullptr; + } + } + return ret; +} + +void SandboxCore::SetDecDenyWithDir(const AppSpawningCtx *appProperty) +{ + int32_t userFileIndex = GetPermissionIndex(nullptr, SandboxCommonDef::READ_WRITE_USER_FILE_MODE.c_str()); + if (CheckAppPermissionFlagSet(appProperty, static_cast(userFileIndex)) == 0) { + APPSPAWN_LOGV("The app doesn't have %{public}s, no need to set deny rules", + SandboxCommonDef::READ_WRITE_USER_FILE_MODE.c_str()); + return; + } + + AppSpawnMsgAccessToken *tokenInfo = + reinterpret_cast(GetAppProperty(appProperty, TLV_ACCESS_TOKEN_INFO)); + APPSPAWN_CHECK(tokenInfo != nullptr, return, "Get token id failed"); + + DecPolicyInfo decPolicyInfo = {0}; + decPolicyInfo.pathNum = 0; + uint32_t count = ARRAY_LENGTH(DEC_DENY_PATH_MAP); + for (uint32_t i = 0, j = 0; i < count; i++) { + int32_t index = GetPermissionIndex(nullptr, DEC_DENY_PATH_MAP[i].permission); + if (CheckAppPermissionFlagSet(appProperty, static_cast(index))) { + continue; + } + PathInfo pathInfo = {0}; + pathInfo.path = const_cast(DEC_DENY_PATH_MAP[i].decPath); + pathInfo.pathLen = static_cast(strlen(pathInfo.path)); + pathInfo.mode = DEC_MODE_DENY_READ | DEC_MODE_DENY_WRITE; + decPolicyInfo.path[j++] = pathInfo; + decPolicyInfo.pathNum += 1; + } + decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx; + decPolicyInfo.flag = true; + SetDecPolicyInfos(&decPolicyInfo); +} + +std::string SandboxCore::ConvertDebugRealPath(const AppSpawningCtx *appProperty, std::string path) +{ + AppSpawnMsgBundleInfo *info = + reinterpret_cast(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); + AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); + if (info == nullptr || dacInfo == nullptr) { + return ""; + } + if (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE)) { + path = SandboxCommon::ReplaceAllVariables(path, SandboxCommonDef::g_variablePackageName, info->bundleName); + } + return SandboxCommon::ConvertToRealPath(appProperty, path); +} + +void SandboxCore::DoUninstallDebugSandbox(std::vector &bundleList, cJSON *config) +{ + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(config, SandboxCommonDef::g_mountPrefix); + if (mountPoints == nullptr || !cJSON_IsArray(mountPoints)) { + APPSPAWN_LOGI("Invalid mountPoints"); + return; + } + + auto processor = [&bundleList](cJSON *mntPoint) { + const char *srcPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_srcPath); + const char *sandboxPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_sandBoxPath); + if (srcPathChr == nullptr || sandboxPathChr == nullptr) { + return 0; + } + std::string sandboxPath(sandboxPathChr); + for (const auto& currentBundle : bundleList) { + sandboxPath = currentBundle + sandboxPath; + APPSPAWN_LOGV("DoUninstallDebugSandbox with path %{public}s", sandboxPath.c_str()); + APPSPAWN_CHECK(access(sandboxPath.c_str(), F_OK) == 0, return 0, + "Invalid path %{public}s", sandboxPath.c_str()); + int ret = umount2(sandboxPath.c_str(), MNT_DETACH); + APPSPAWN_CHECK_ONLY_LOG(ret == 0, "umount failed %{public}d %{public}d", ret, errno); + ret = rmdir(sandboxPath.c_str()); + APPSPAWN_CHECK_ONLY_LOG(ret == 0, "rmdir failed %{public}d %{public}d", ret, errno); + } + return 0; + }; + + (void)SandboxCommon::HandleArrayForeach(mountPoints, processor); +} + +int32_t SandboxCore::GetPackageList(AppSpawningCtx *property, std::vector &bundleList, bool tmp) +{ + APPSPAWN_CHECK(property != nullptr, return APPSPAWN_ARG_INVALID, "Invalid property"); + AppDacInfo *info = reinterpret_cast(GetAppProperty(property, TLV_DAC_INFO)); + if (GetBundleName(property) == nullptr ||SandboxCommon::CheckBundleName(GetBundleName(property)) != 0 || + info == nullptr) { + std::string uid; + char *userId = (char *)GetAppSpawnMsgExtInfo(property->message, MSG_EXT_NAME_USERID, nullptr); + if (userId != nullptr) { + uid = std::string(userId); + } else { + APPSPAWN_CHECK(info != nullptr, return APPSPAWN_ARG_INVALID, "Invalid dacInfo"); + uid = std::to_string(info->uid / UID_BASE); + } + std::string defaultSandboxRoot = (tmp ? SandboxCommonDef::g_mntTmpRoot : SandboxCommonDef::g_mntShareRoot) + + uid + "/debug_hap"; + APPSPAWN_CHECK(access(defaultSandboxRoot.c_str(), F_OK) == 0, return APPSPAWN_ARG_INVALID, + "Failed to access %{public}s, err %{public}d", defaultSandboxRoot.c_str(), errno); + + DIR *dir = opendir(defaultSandboxRoot.c_str()); + if (dir == nullptr) { + APPSPAWN_LOGE("Failed to open %{public}s, err %{public}d", defaultSandboxRoot.c_str(), errno); + return APPSPAWN_SYSTEM_ERROR; + } + struct dirent *entry; + while ((entry = readdir(dir)) != nullptr) { + if (entry->d_name[0] == '.') { + continue; + } + std::string packagePath = defaultSandboxRoot + "/" + std::string(entry->d_name); + APPSPAWN_LOGV("GetPackageList %{public}s", packagePath.c_str()); + bundleList.push_back(packagePath); + } + closedir(dir); + } else { + bundleList.push_back(ConvertDebugRealPath(property, tmp ? SandboxCommonDef::g_mntTmpSandboxRoot : + SandboxCommonDef::g_mntShareSandboxRoot)); + } + return 0; +} + +int32_t SandboxCore::UninstallDebugSandbox(AppSpawnMgr *content, AppSpawningCtx *property) +{ + APPSPAWN_CHECK(property != nullptr && content != nullptr, return APPSPAWN_ARG_INVALID, "Invalid property"); + + std::vector bundleList; + int ret = GetPackageList(property, bundleList, true); + APPSPAWN_CHECK(ret == 0, return -1, "GetPackageList failed"); + SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? + SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG; + for (auto& wholeConfig : SandboxCommon::GetCJsonConfig(type)) { + cJSON *debugJson = GetFirstCommonConfig(wholeConfig, SandboxCommonDef::g_debughap); + if (!debugJson) { + continue; + } + cJSON *debugCommonConfig = GetFirstSubConfig(debugJson, SandboxCommonDef::g_commonPrefix); + if (!debugCommonConfig) { + continue; + } + DoUninstallDebugSandbox(bundleList, debugCommonConfig); + + cJSON *debugPermissionConfig = GetFirstSubConfig(debugJson, SandboxCommonDef::g_permissionPrefix); + if (!debugPermissionConfig) { + continue; + } + + cJSON *permissionChild = debugPermissionConfig->child; + while (permissionChild != nullptr) { + DoUninstallDebugSandbox(bundleList, permissionChild); + permissionChild = permissionChild->next; + } + } + bundleList.clear(); + ret = GetPackageList(property, bundleList, false); + APPSPAWN_CHECK(ret == 0, return -1, "GetPackageList failed"); + for (const auto& currentBundle : bundleList) { + std::string sandboxPath = currentBundle; + APPSPAWN_LOGV("UninstallDebugSandbox with path %{public}s", sandboxPath.c_str()); + APPSPAWN_CHECK(access(sandboxPath.c_str(), F_OK) == 0, continue, + "Invalid path %{public}s", sandboxPath.c_str()); + ret = umount2(sandboxPath.c_str(), MNT_DETACH); + APPSPAWN_CHECK_ONLY_LOG(ret == 0, "umount failed %{public}d %{public}d", ret, errno); + ret = rmdir(sandboxPath.c_str()); + APPSPAWN_CHECK_ONLY_LOG(ret == 0, "rmdir failed %{public}d %{public}d", ret, errno); + } + + return 0; +} + +int32_t SandboxCore::DoMountDebugPoints(const AppSpawningCtx *appProperty, cJSON *appConfig) +{ + std::string bundleName = GetBundleName(appProperty); + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(appConfig, SandboxCommonDef::g_mountPrefix); + if (mountPoints == nullptr || !cJSON_IsArray(mountPoints)) { + APPSPAWN_LOGI("mount config is not found, app name is %{public}s", bundleName.c_str()); + return 0; + } + + std::string sandboxRoot = ConvertDebugRealPath(appProperty, SandboxCommonDef::g_mntTmpSandboxRoot); + int atomicService = CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE); + + auto processor = [&sandboxRoot, &atomicService, &appProperty](cJSON *mntPoint) { + const char *srcPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_srcPath); + const char *sandboxPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_sandBoxPath); + if (srcPathChr == nullptr || sandboxPathChr == nullptr) { + return 0; + } + std::string srcPath(srcPathChr); + std::string sandboxPath(sandboxPathChr); + srcPath = SandboxCommon::ConvertToRealPath(appProperty, srcPath); + sandboxPath = GetSandboxPath(appProperty, mntPoint, SandboxCommonDef::g_debughap, sandboxRoot); + if (access(sandboxPath.c_str(), F_OK) == 0) { + APPSPAWN_CHECK(atomicService, return 0, "sandbox path already exist"); + APPSPAWN_CHECK(umount2(sandboxPath.c_str(), MNT_DETACH) == 0, return 0, + "umount sandbox path failed, errno is %{public}d %{public}s", errno, sandboxPath.c_str()); + } + SandboxMountConfig mountConfig = {0}; + SandboxCommon::GetSandboxMountConfig(appProperty, SandboxCommonDef::g_debughap, mntPoint, mountConfig); + SharedMountArgs arg = { + .srcPath = srcPath.c_str(), + .destPath = sandboxPath.c_str(), + .fsType = mountConfig.fsType.c_str(), + .mountFlags = SandboxCommon::GetMountFlags(mntPoint), + .options = mountConfig.optionsPoint.c_str(), + .mountSharedFlag = + GetBoolValueFromJsonObj(mntPoint, SandboxCommonDef::g_mountSharedFlag, false) ? MS_SHARED : MS_SLAVE + }; + int ret = SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg); + APPSPAWN_CHECK(ret == 0 || !SandboxCommon::IsMountSuccessful(mntPoint), return ret, + "DoMountDebugPoints %{public}s failed", arg.destPath); + return ret; + }; + + (void)SandboxCommon::HandleArrayForeach(mountPoints, processor); + return 0; +} + +int32_t SandboxCore::MountDebugSharefs(const AppSpawningCtx *property, const char *src, const char *target) +{ + char dataPath[SandboxCommonDef::OPTIONS_MAX_LEN] = {0}; + int ret = snprintf_s(dataPath, SandboxCommonDef::OPTIONS_MAX_LEN, SandboxCommonDef::OPTIONS_MAX_LEN - 1, + "%s/data", target); + if (ret >= 0 && access(dataPath, F_OK) == 0) { + return 0; + } + + ret = MakeDirRec(target, SandboxCommonDef::FILE_MODE, 1); + if (ret != 0) { + return APPSPAWN_SANDBOX_ERROR_MKDIR_FAIL; + } + + AppDacInfo *info = reinterpret_cast(GetAppProperty(property, TLV_DAC_INFO)); + if (info == nullptr) { + return APPSPAWN_ARG_INVALID; + } + char options[SandboxCommonDef::OPTIONS_MAX_LEN] = {0}; + ret = snprintf_s(options, SandboxCommonDef::OPTIONS_MAX_LEN, SandboxCommonDef::OPTIONS_MAX_LEN - 1, + "override_support_delete,user_id=%u", info->uid / UID_BASE); + if (ret <= 0) { + return APPSPAWN_ERROR_UTILS_MEM_FAIL; + } + + if (mount(src, target, "sharefs", MS_NODEV, options) != 0) { + APPSPAWN_LOGE("sharefs mount %{public}s to %{public}s failed, errno %{public}d", src, target, errno); + return APPSPAWN_SANDBOX_ERROR_MOUNT_FAIL; + } + if (mount(nullptr, target, nullptr, MS_SHARED, nullptr) != 0) { + APPSPAWN_LOGE("mount path %{public}s to shared failed, errno %{public}d", target, errno); + return APPSPAWN_SANDBOX_ERROR_MOUNT_FAIL; + } + + return 0; +} + +int32_t SandboxCore::InstallDebugSandbox(AppSpawnMgr *content, AppSpawningCtx *property) +{ + if (!IsDeveloperModeOn(property)) { + return 0; + } + + uint32_t len = 0; + char *provisionType = reinterpret_cast(GetAppPropertyExt(property, + MSG_EXT_NAME_PROVISION_TYPE, &len)); + if (provisionType == nullptr || len == 0 || strcmp(provisionType, "debug") != 0) { + return 0; + } + + SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? + SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG; + + for (auto& wholeConfig : SandboxCommon::GetCJsonConfig(type)) { + cJSON *debugJson = GetFirstCommonConfig(wholeConfig, SandboxCommonDef::g_debughap); + if (!debugJson) { + continue; + } + cJSON *debugCommonConfig = GetFirstSubConfig(debugJson, SandboxCommonDef::g_commonPrefix); + if (!debugCommonConfig) { + continue; + } + DoMountDebugPoints(property, debugCommonConfig); + + cJSON *debugPermissionConfig = GetFirstSubConfig(debugJson, SandboxCommonDef::g_permissionPrefix); + if (!debugPermissionConfig) { + continue; + } + + cJSON *permissionChild = debugPermissionConfig->child; + while (permissionChild != nullptr) { + int index = GetPermissionIndex(nullptr, permissionChild->string); + if (CheckAppPermissionFlagSet(property, static_cast(index)) == 0) { + permissionChild = permissionChild->next; + continue; + } + cJSON *permissionMountPaths = cJSON_GetArrayItem(permissionChild, 0); + if (!permissionMountPaths) { + permissionChild = permissionChild->next; + continue; + } + DoMountDebugPoints(property, permissionMountPaths); + + permissionChild = permissionChild->next; + } + } + + MountDebugSharefs(property, ConvertDebugRealPath(property, SandboxCommonDef::g_mntTmpSandboxRoot).c_str(), + ConvertDebugRealPath(property, SandboxCommonDef::g_mntShareSandboxRoot).c_str()); + return 0; +} +} // namespace AppSpawn +} // namespace OHOS diff --git a/modules/sandbox/sandbox_utils.h b/modules/sandbox/normal/sandbox_core.h old mode 100755 new mode 100644 similarity index 37% rename from modules/sandbox/sandbox_utils.h rename to modules/sandbox/normal/sandbox_core.h index e4cc70b4b9e8eae420e24e5915eca69f67bbc706..9f379b7206054b83d7d222d5c1aeee471b8d10b9 --- a/modules/sandbox/sandbox_utils.h +++ b/modules/sandbox/normal/sandbox_core.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Huawei Device Co., Ltd. + * Copyright (C) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,126 +13,116 @@ * limitations under the License. */ -#ifndef SANDBOX_UTILS_H -#define SANDBOX_UTILS_H +#ifndef SANDBOX_CORE_H +#define SANDBOX_CORE_H -#include #include -#include -#include #include - -#include "sandbox_shared_mount.h" +#include +#include "sandbox_def.h" +#include "appspawn_msg.h" #include "appspawn_server.h" #include "appspawn_manager.h" - -typedef enum { - SANBOX_APP_JSON_CONFIG, - SANBOX_ISOLATED_JSON_CONFIG -} SandboxConfigType; +#include "sandbox_shared_mount.h" +#include "sandbox_common.h" namespace OHOS { namespace AppSpawn { -class SandboxUtils { + +class SandboxCore { public: - static void StoreJsonConfig(nlohmann::json &appSandboxConfig, SandboxConfigType type); - static std::vector &GetJsonConfig(SandboxConfigType type); - static int32_t SetAppSandboxProperty(AppSpawningCtx *client, uint32_t sandboxNsFlags = CLONE_NEWNS); - static int32_t SetAppSandboxPropertyNweb(AppSpawningCtx *client, uint32_t sandboxNsFlags = CLONE_NEWNS); - static uint32_t GetSandboxNsFlags(bool isNweb); - static std::set GetMountPermissionNames(); - static std::string GetExtraInfoByType(const AppSpawningCtx *appProperty, const std::string &type); - typedef struct { - unsigned long mountFlags; - std::string optionsPoint; - std::string fsType; - std::string sandboxPath; - } SandboxMountConfig; - -#ifndef APPSPAWN_TEST -private: -#endif - static int32_t DoAppSandboxMountOnce(const AppSpawningCtx *appProperty, const SharedMountArgs *arg); - static int32_t DoSandboxFileCommonBind(const AppSpawningCtx *appProperty, nlohmann::json &wholeConfig); - static int32_t DoSandboxFileCommonSymlink(const AppSpawningCtx *appProperty, - nlohmann::json &wholeConfig); - static int32_t DoSandboxFilePrivateBind(const AppSpawningCtx *appProperty, nlohmann::json &wholeConfig); - static int32_t DoSandboxFilePrivateSymlink(const AppSpawningCtx *appProperty, - nlohmann::json &wholeConfig); - static int32_t DoSandboxFilePrivateFlagsPointHandle(const AppSpawningCtx *appProperty, - nlohmann::json &wholeConfig); - static int32_t DoSandboxFileCommonFlagsPointHandle(const AppSpawningCtx *appProperty, - nlohmann::json &wholeConfig); - static int32_t HandleFlagsPoint(const AppSpawningCtx *appProperty, - nlohmann::json &wholeConfig); - static int32_t SetPrivateAppSandboxProperty(const AppSpawningCtx *appProperty); - static int32_t SetCommonAppSandboxProperty(const AppSpawningCtx *appProperty, - std::string &sandboxPackagePath); - static int32_t MountAllHsp(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); - static int32_t MountAllGroup(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); + // 沙箱挂载公共处理 + static int32_t DoAllMntPointsMount(const AppSpawningCtx *appProperty, cJSON *appConfig, + const char *typeName, const std::string §ion = "app-base"); + static int32_t DoAddGid(AppSpawningCtx *appProperty, cJSON *appConfig, + const char* permissionName, const std::string §ion); + static int32_t DoAllSymlinkPointslink(const AppSpawningCtx *appProperty, cJSON *appConfig); + static int32_t DoSandboxRootFolderCreate(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); static int32_t DoSandboxRootFolderCreateAdapt(std::string &sandboxPackagePath); - static int32_t DoSandboxRootFolderCreate(const AppSpawningCtx *appProperty, - std::string &sandboxPackagePath); - static void DoSandboxChmod(nlohmann::json jsonConfig, std::string &sandboxRoot); - static int DoAllMntPointsMount(const AppSpawningCtx *appProperty, - nlohmann::json &appConfig, const char *typeName, const std::string §ion = "app-base"); - static int DoAllSymlinkPointslink(const AppSpawningCtx *appProperty, nlohmann::json &appConfig); - static std::string ConvertToRealPath(const AppSpawningCtx *appProperty, std::string path); - static std::string ConvertToRealPathWithPermission(const AppSpawningCtx *appProperty, std::string path); - static std::string GetSbxPathByConfig(const AppSpawningCtx *appProperty, nlohmann::json &config); - static bool CheckTotalSandboxSwitchStatus(const AppSpawningCtx *appProperty); - static bool CheckAppSandboxSwitchStatus(const AppSpawningCtx *appProperty); - static bool CheckBundleNameForPrivate(const std::string &bundleName); - static bool GetSbxSwitchStatusByConfig(nlohmann::json &config); - static unsigned long GetMountFlagsFromConfig(const std::vector &vec); - static int32_t SetCommonAppSandboxProperty_(const AppSpawningCtx *appProperty, - nlohmann::json &config); - static int32_t SetPrivateAppSandboxProperty_(const AppSpawningCtx *appProperty, - nlohmann::json &config); - static int32_t SetRenderSandboxProperty(const AppSpawningCtx *appProperty, - std::string &sandboxPackagePath); - static int32_t SetRenderSandboxPropertyNweb(const AppSpawningCtx *appProperty, - std::string &sandboxPackagePath); - static int32_t SetOverlayAppSandboxProperty(const AppSpawningCtx *appProperty, - std::string &sandboxPackagePath); + static int32_t HandleFlagsPoint(const AppSpawningCtx *appProperty, cJSON *appConfig); + static int32_t SetOverlayAppSandboxProperty(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); static int32_t SetBundleResourceAppSandboxProperty(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); - static int32_t DoSandboxFilePermissionBind(AppSpawningCtx *appProperty, - nlohmann::json &wholeConfig); - static int32_t SetPermissionAppSandboxProperty_(AppSpawningCtx *appProperty, - nlohmann::json &config); + static bool NeedNetworkIsolated(AppSpawningCtx *property); + + // 处理应用沙箱挂载 + static int32_t SetCommonAppSandboxProperty(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); + static int32_t SetPrivateAppSandboxProperty(const AppSpawningCtx *appProperty); static int32_t SetPermissionAppSandboxProperty(AppSpawningCtx *appProperty); - static int32_t DoAddGid(AppSpawningCtx *appProperty, nlohmann::json &appConfig, - const char* permissionName, const std::string §ion); - static int32_t CheckAppFullMountEnable(); - static void UpdateMsgFlagsWithPermission(AppSpawningCtx *appProperty); - static int32_t UpdatePermissionFlags(AppSpawningCtx *appProperty); static int32_t SetSandboxProperty(AppSpawningCtx *appProperty, std::string &sandboxPackagePath); + static int32_t SetAppSandboxProperty(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags = CLONE_NEWNS); + + static int32_t SetRenderSandboxPropertyNweb(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); + static int32_t SetAppSandboxPropertyNweb(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags = CLONE_NEWNS); + + // 沙箱目录切根 static int32_t ChangeCurrentDir(std::string &sandboxPackagePath, const std::string &bundleName, bool sandboxSharedStatus); - static int32_t GetMountPermissionFlags(const std::string permissionName); - static bool GetSandboxDacOverrideEnable(nlohmann::json &config); - static unsigned long GetSandboxMountFlags(nlohmann::json &config); - static std::string GetSandboxFsType(nlohmann::json &config); - static std::string GetSandboxOptions(const AppSpawningCtx *appProperty, nlohmann::json &config); - static std::string GetSandboxPath(const AppSpawningCtx *appProperty, nlohmann::json &mntPoint, + + // 设置DEC规则 + static int32_t SetDecWithDir(const AppSpawningCtx *appProperty, uint32_t userId); + static int32_t SetDecPolicyWithPermission(const AppSpawningCtx *appProperty, SandboxMountConfig &mountConfig); + static void SetDecDenyWithDir(const AppSpawningCtx *appProperty); + + // debug hap + static int32_t UninstallDebugSandbox(AppSpawnMgr *content, AppSpawningCtx *property); + static int32_t InstallDebugSandbox(AppSpawnMgr *content, AppSpawningCtx *property); + +private: + // 获取应用信息 + static int EnableSandboxNamespace(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags); + static uint32_t GetAppMsgFlags(const AppSpawningCtx *property); + static bool CheckMountFlag(const AppSpawningCtx *appProperty, const std::string bundleName, + cJSON *appConfig); + static void UpdateMsgFlagsWithPermission(AppSpawningCtx *appProperty); + static int32_t UpdatePermissionFlags(AppSpawningCtx *appProperty); + static std::string GetSandboxPath(const AppSpawningCtx *appProperty, cJSON *mntPoint, const std::string §ion, std::string sandboxRoot); - static void GetSandboxMountConfig(const AppSpawningCtx *appProperty, const std::string §ion, - nlohmann::json &mntPoint, SandboxMountConfig &mountConfig); -#ifdef APPSPAWN_MOUNT_TMPSHM - static void MountDevShmPath(std::string &sandboxPath); -#endif - static std::map> appSandboxConfig_; - static int32_t deviceTypeEnable_; -}; -class JsonUtils { -public: - static bool GetJsonObjFromJson(nlohmann::json &jsonObj, const std::string &jsonPath); - static bool GetStringFromJson(const nlohmann::json &json, const std::string &key, std::string &value); + + // 解析挂载信息公共函数 + static cJSON *GetFirstCommonConfig(cJSON *wholeConfig, const char *prefix); + static cJSON *GetFirstSubConfig(cJSON *parent, const char *key); + + // 处理dlpmanager挂载 + static int32_t DoDlpAppMountStrategy(const AppSpawningCtx *appProperty, const std::string &srcPath, + const std::string &sandboxPath, const std::string &fsType, unsigned long mountFlags); + static int32_t HandleSpecialAppMount(const AppSpawningCtx *appProperty, const std::string &srcPath, + const std::string &sandboxPath, const std::string &fsType, unsigned long mountFlags); + + // 处理应用私有挂载 + static cJSON *GetPrivateJsonInfo(const AppSpawningCtx *appProperty, cJSON *wholeConfig); + static int32_t DoSandboxFilePrivateBind(const AppSpawningCtx *appProperty, cJSON *wholeConfig); + static int32_t DoSandboxFilePrivateSymlink(const AppSpawningCtx *appProperty, cJSON *wholeConfig); + static int32_t DoSandboxFilePrivateFlagsPointHandle(const AppSpawningCtx *appProperty, cJSON *wholeConfig); + static int32_t SetPrivateAppSandboxProperty_(const AppSpawningCtx *appProperty, cJSON *config); + + // 处理应用基于权限挂载 + static int32_t DoSandboxFilePermissionBind(AppSpawningCtx *appProperty, cJSON *wholeConfig); + static int32_t SetPermissionAppSandboxProperty_(AppSpawningCtx *appProperty, cJSON *config); + + // 处理应用公共挂载 + static int32_t DoSandboxFileCommonBind(const AppSpawningCtx *appProperty, cJSON *wholeConfig); + static int32_t DoSandboxFileCommonSymlink(const AppSpawningCtx *appProperty, cJSON *wholeConfig); + static int32_t DoSandboxFileCommonFlagsPointHandle(const AppSpawningCtx *appProperty, cJSON *wholeConfig); + static int32_t SetCommonAppSandboxProperty_(const AppSpawningCtx *appProperty, cJSON *config); + + // 处理可变参数的挂载 + static int32_t MountAllHsp(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); + static int32_t MountAllGroup(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath); + + // 沙箱回调函数 + static int32_t ProcessMountPoint(cJSON *mntPoint, MountPointProcessParams ¶ms); + + // debug hap + static std::string ConvertDebugRealPath(const AppSpawningCtx *appProperty, std::string path); + static void DoUninstallDebugSandbox(std::vector &bundleList, cJSON *mountPoints); + static int32_t GetPackageList(AppSpawningCtx *property, std::vector &bundleList, bool tmp); + + static int32_t DoMountDebugPoints(const AppSpawningCtx *appProperty, cJSON *appConfig); + static int32_t MountDebugSharefs(const AppSpawningCtx *property, const char *src, const char *target); }; + } // namespace AppSpawn } // namespace OHOS -int LoadAppSandboxConfig(AppSpawnMgr *content); - -#endif // SANDBOX_UTILS_H +#endif // SANDBOX_CORE_H diff --git a/modules/sandbox/normal/sandbox_def.h b/modules/sandbox/normal/sandbox_def.h new file mode 100644 index 0000000000000000000000000000000000000000..2762d14bb3f72f1b0264f512243470af576a9f0a --- /dev/null +++ b/modules/sandbox/normal/sandbox_def.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SANDBOX_DEF_H +#define SANDBOX_DEF_H + +#include +#include +#include +#include + +namespace OHOS { +namespace AppSpawn { +namespace SandboxCommonDef { +// 全局常量定义 +constexpr int32_t OPTIONS_MAX_LEN = 256; +constexpr int32_t FILE_ACCESS_COMMON_DIR_STATUS = 0; +constexpr int32_t FILE_CROSS_APP_STATUS = 1; +constexpr static mode_t FILE_MODE = 0711; +constexpr static mode_t BASIC_MOUNT_FLAGS = MS_REC | MS_BIND; +constexpr int32_t MAX_MOUNT_TIME = 500; // 500us +constexpr int32_t LOCK_STATUS_SIZE = 16; + +// 沙盒配置文件 +const std::string APP_JSON_CONFIG = "/appdata-sandbox.json"; +const std::string APP_ISOLATED_JSON_CONFIG = "/appdata-sandbox-isolated.json"; + +/* 沙盒配置文件中关键字 */ +// 公共属性 +constexpr const char *g_sandboxRootPrefix = "sandbox-root"; +constexpr const char *g_sandBoxNsFlags = "sandbox-ns-flags"; +constexpr const char *g_topSandBoxSwitchPrefix = "top-sandbox-switch"; +constexpr const char *g_sandBoxSwitchPrefix = "sandbox-switch"; +const std::string g_ohosGpu = "__internal__.com.ohos.gpu"; +const std::string g_ohosRender = "__internal__.com.ohos.render"; +constexpr const char *g_commonPrefix = "common"; +constexpr const char *g_privatePrefix = "individual"; +constexpr const char *g_permissionPrefix = "permission"; +constexpr const char *g_appBase = "app-base"; +constexpr const char *g_appResources = "app-resources"; +constexpr const char *g_flagePoint = "flags-point"; +const std::string g_internal = "__internal__"; +const std::string g_mntTmpRoot = "/mnt/debugtmp/"; +const std::string g_mntShareRoot = "/mnt/debug/"; +const std::string g_sandboxRootPathTemplate = "/mnt/sandbox//"; +const std::string g_originSandboxPath = "/mnt/sandbox/"; + +// 挂载目录字段 +constexpr const char *g_mountPrefix = "mount-paths"; +constexpr const char *g_srcPath = "src-path"; +constexpr const char *g_sandBoxPath = "sandbox-path"; +constexpr const char *g_sandBoxFlags = "sandbox-flags"; +constexpr const char *g_fsType = "fs-type"; +constexpr const char *g_sandBoxOptions = "options"; +constexpr const char *g_actionStatuc = "check-action-status"; +constexpr const char *g_destMode = "dest-mode"; +constexpr const char *g_flags = "flags"; + +// 挂载可选属性 +constexpr const char *g_sandBoxShared = "sandbox-shared"; +constexpr const char *g_mountSharedFlag = "mount-shared-flag"; +constexpr const char *g_dacOverrideSensitive = "dac-override-sensitive"; +constexpr const char *g_sandBoxFlagsCustomized = "sandbox-flags-customized"; +constexpr const char *g_appAplName = "app-apl-name"; +constexpr const char *g_sandBoxDecPath = "dec-paths"; +constexpr const char *CREATE_SANDBOX_PATH = "create-sandbox-path"; + +// link目录字段 +constexpr const char *g_symlinkPrefix = "symbol-links"; +constexpr const char *g_targetName = "target-name"; +constexpr const char *g_linkName = "link-name"; + +constexpr const char *g_gidPrefix = "gids"; + +// 可变参数 +const std::string g_userId = ""; +const std::string g_permissionUser = ""; +const std::string g_packageName = ""; +const std::string g_packageNameIndex = ""; +const std::string g_variablePackageName = ""; +const std::string g_clonePackageName = ""; +const std::string g_arkWebPackageName = ""; +const std::string g_hostUserId = ""; + +/* HSP */ +const std::string HSPLIST_SOCKET_TYPE = "HspList"; +const std::string g_hspList_key_bundles = "bundles"; +const std::string g_hspList_key_modules = "modules"; +const std::string g_hspList_key_versions = "versions"; +const std::string g_sandboxHspInstallPath = "/data/storage/el1/bundle/"; + +/* DataGroup */ +const std::string DATA_GROUP_SOCKET_TYPE = "DataGroup"; +const std::string g_groupList_key_dataGroupId = "dataGroupId"; +const std::string g_groupList_key_gid = "gid"; +const std::string g_groupList_key_dir = "dir"; +const std::string g_groupList_key_uuid = "uuid"; + +/* Overlay */ +const std::string OVERLAY_SOCKET_TYPE = "Overlay"; +const std::string g_overlayPath = "/data/storage/overlay/"; + +/* system hap */ +const std::string APL_SYSTEM_CORE = "system_core"; +const std::string APL_SYSTEM_BASIC = "system_basic"; +const std::string g_physicalAppInstallPath = "/data/app/el1/bundle/public/"; +const std::string g_dataBundles = "/data/bundles/"; + +/* bundle resource with APP_FLAGS_BUNDLE_RESOURCES */ +const std::string g_bundleResourceSrcPath = "/data/service/el1/public/bms/bundle_resources/"; +const std::string g_bundleResourceDestPath = "/data/storage/bundle_resources/"; + +/* 配置文件中value校验值 */ +const std::string g_sandBoxRootDir = "/mnt/sandbox/"; +const std::string g_sandBoxRootDirNweb = "/mnt/sandbox/com.ohos.render/"; +const std::string DEV_SHM_DIR = "/dev/shm/"; +const std::string g_statusCheck = "true"; +const std::string g_sbxSwitchCheck = "ON"; +const std::string g_dlpBundleName = "com.ohos.dlpmanager"; + +/* debug hap */ +constexpr const char *g_mntTmpSandboxRoot = "/mnt/debugtmp//debug_hap/"; +constexpr const char *g_mntShareSandboxRoot = "/mnt/debug//debug_hap/"; +constexpr const char *g_debughap = "debug"; + +/* 分割符 */ +constexpr const char *g_fileSeparator = "/"; +constexpr const char *g_overlayDecollator = "|"; + +/* 权限名 */ +const std::string FILE_CROSS_APP_MODE = "ohos.permission.FILE_CROSS_APP"; +const std::string FILE_ACCESS_COMMON_DIR_MODE = "ohos.permission.FILE_ACCESS_COMMON_DIR"; +const std::string ACCESS_DLP_FILE_MODE = "ohos.permission.ACCESS_DLP_FILE"; +const std::string FILE_ACCESS_MANAGER_MODE = "ohos.permission.FILE_ACCESS_MANAGER"; +const std::string READ_WRITE_USER_FILE_MODE = "ohos.permission.READ_WRITE_USER_FILE"; +const std::string GET_ALL_PROCESSES_MODE = "ohos.permission.GET_ALL_PROCESSES"; +const std::string ARK_WEB_PERSIST_PACKAGE_NAME = "persist.arkwebcore.package_name"; + +// 枚举类型 +enum SandboxConfigType { + SANDBOX_APP_JSON_CONFIG, + SANDBOX_ISOLATED_JSON_CONFIG +}; + +} // namespace SandboxCommonDef +} // namespace AppSpawn +} // namespace OHOS + +#endif // SANDBOX_DEF_H \ No newline at end of file diff --git a/modules/sandbox/sandbox_shared_mount.cpp b/modules/sandbox/normal/sandbox_shared_mount.cpp similarity index 89% rename from modules/sandbox/sandbox_shared_mount.cpp rename to modules/sandbox/normal/sandbox_shared_mount.cpp index c752a28b2f7595b962c39adaec34de79a8878b60..fe9f145350f5deb8a46f4ff859a19e5fbc693beb 100644 --- a/modules/sandbox/sandbox_shared_mount.cpp +++ b/modules/sandbox/normal/sandbox_shared_mount.cpp @@ -86,13 +86,18 @@ const DataGroupSandboxPathTemplate *GetDataGroupArgTemplate(uint32_t category) return nullptr; } -bool IsValidDataGroupItem(nlohmann::json &item) +bool IsValidDataGroupItem(cJSON *item) { // Check if the item contains the specified key and if the value corresponding to the key is a string - if (item.contains(GROUPLIST_KEY_DATAGROUPID) && item[GROUPLIST_KEY_DATAGROUPID].is_string() && - item.contains(GROUPLIST_KEY_GID) && item[GROUPLIST_KEY_GID].is_string() && - item.contains(GROUPLIST_KEY_DIR) && item[GROUPLIST_KEY_DIR].is_string() && - item.contains(GROUPLIST_KEY_UUID) && item[GROUPLIST_KEY_UUID].is_string()) { + cJSON *datagroupId = cJSON_GetObjectItem(item, GROUPLIST_KEY_DATAGROUPID); + cJSON *gid = cJSON_GetObjectItem(item, GROUPLIST_KEY_GID); + cJSON *dir = cJSON_GetObjectItem(item, GROUPLIST_KEY_DIR); + cJSON *uuid = cJSON_GetObjectItem(item, GROUPLIST_KEY_UUID); + + if (datagroupId && cJSON_IsString(datagroupId) && + gid && cJSON_IsString(gid) && + dir && cJSON_IsString(dir) && + uuid && cJSON_IsString(uuid)) { return true; } return false; @@ -114,7 +119,7 @@ static bool IsUnlockStatus(uint32_t uid) std::string lockStatusParam = "startup.appspawn.lockstatus_" + std::to_string(uid); char userLockStatus[LOCK_STATUS_SIZE] = {0}; int ret = GetParameter(lockStatusParam.c_str(), "1", userLockStatus, sizeof(userLockStatus)); - APPSPAWN_LOGI("get param %{public}s %{public}s", lockStatusParam.c_str(), userLockStatus); + APPSPAWN_LOGI("lockStatus %{public}u %{public}s", uid, userLockStatus); if (ret > 0 && (strcmp(userLockStatus, "0") == 0)) { // 0:unlock status 1:lock status return true; } @@ -297,7 +302,16 @@ static int MountWithOther(const AppSpawningCtx *property, const AppDacInfo *info APPSPAWN_LOGE("snprintf options failed, errno %{public}d", errno); return APPSPAWN_ERROR_UTILS_MEM_FAIL; } - +#ifdef APPSPAWN_SUPPORT_NOSHAREFS + SharedMountArgs arg = { + .srcPath = sharefsDocsDir, + .destPath = storageUserPath, + .fsType = nullptr, + .mountFlags = MS_BIND | MS_REC, + .options = nullptr, + .mountSharedFlag = MS_SHARED + }; +#else SharedMountArgs arg = { .srcPath = sharefsDocsDir, .destPath = storageUserPath, @@ -306,6 +320,7 @@ static int MountWithOther(const AppSpawningCtx *property, const AppDacInfo *info .options = options, .mountSharedFlag = MS_SHARED }; +#endif ret = DoSharedMount(&arg); if (ret != 0) { APPSPAWN_LOGE("mount %{public}s shared failed, ret %{public}d", storageUserPath, ret); @@ -437,16 +452,6 @@ static int AddDataGroupItemToQueue(AppSpawnMgr *content, const std::string &srcP return 0; } -static std::string GetExtraInfoByType(const AppSpawningCtx *appPropery, const std::string &type) -{ - uint32_t len = 0; - char *info = reinterpret_cast(GetAppPropertyExt(appPropery, type.c_str(), &len)); - if (info == nullptr) { - return ""; - } - return std::string(info, len); -} - static void DumpDataGroupCtxQueue(const ListNode *front) { if (front == nullptr) { @@ -466,33 +471,51 @@ static void DumpDataGroupCtxQueue(const ListNode *front) } } +static inline cJSON *GetJsonObjFromExtInfo(const AppSpawningCtx *property, const char *name) +{ + uint32_t size = 0; + char *extInfo = (char *)(GetAppSpawnMsgExtInfo(property->message, name, &size)); + if (size == 0 || extInfo == nullptr) { + return nullptr; + } + APPSPAWN_LOGV("Get json name %{public}s value %{public}s", name, extInfo); + cJSON *extInfoJson = cJSON_Parse(extInfo); // need to free + APPSPAWN_CHECK(extInfoJson != nullptr, return nullptr, "Invalid ext info %{public}s for %{public}s", extInfo, name); + return extInfoJson; +} + static int ParseDataGroupList(AppSpawnMgr *content, const AppSpawningCtx *property, AppDacInfo *info, const char *varBundleName) { int ret = 0; - std::string dataGroupList = GetExtraInfoByType(property, DATA_GROUP_SOCKET_TYPE); - if (dataGroupList.length() == 0) { + cJSON *dataGroupList = GetJsonObjFromExtInfo(property, DATA_GROUP_SOCKET_TYPE); + if (dataGroupList == nullptr || !cJSON_IsArray(dataGroupList)) { APPSPAWN_LOGE("dataGroupList is empty"); return APPSPAWN_ARG_INVALID; } - nlohmann::json dataGroupJson = nlohmann::json::parse(dataGroupList.c_str(), nullptr, false); - if (dataGroupJson.is_discarded() && dataGroupJson.contains(GROUPLIST_KEY_DATAGROUPID) && - dataGroupJson.contains(GROUPLIST_KEY_GID) && dataGroupJson.contains(GROUPLIST_KEY_DIR) && - dataGroupJson.contains(GROUPLIST_KEY_UUID)) { - APPSPAWN_LOGE("dataGroupJson is discarded"); - return APPSPAWN_ARG_INVALID; - } - for (auto &item : dataGroupJson) { - APPSPAWN_CHECK(IsValidDataGroupItem(item), return -1, "Element is not a valid data group item"); - std::string srcPath = item[GROUPLIST_KEY_DIR]; - APPSPAWN_CHECK(!CheckPath(srcPath), return -1, "src path %{public}s is invalid", srcPath.c_str()); + // Iterate through the array (assuming groups is an array) + cJSON *item = nullptr; + cJSON_ArrayForEach(item, dataGroupList) { + // Check if the item is valid + APPSPAWN_CHECK((item != nullptr && IsValidDataGroupItem(item)), break, + "Element is not a valid data group item"); + + cJSON *dirItem = cJSON_GetObjectItemCaseSensitive(item, "dir"); + cJSON *uuidItem = cJSON_GetObjectItemCaseSensitive(item, "uuid"); + if (dirItem == nullptr || !cJSON_IsString(dirItem) || uuidItem == nullptr || !cJSON_IsString(uuidItem)) { + APPSPAWN_LOGE("Data group element is invalid"); + break; + } + + const char *srcPath = dirItem->valuestring; + APPSPAWN_CHECK(!CheckPath(srcPath), break, "src path %{public}s is invalid", srcPath); + + int elxValue = GetElxInfoFromDir(srcPath); + APPSPAWN_CHECK((elxValue >= EL2 && elxValue < ELX_MAX), break, "Get elx value failed"); - int elxValue = GetElxInfoFromDir(srcPath.c_str()); - APPSPAWN_CHECK((elxValue >= EL2 && elxValue < ELX_MAX), return -1, "Get elx value failed"); - const DataGroupSandboxPathTemplate *templateItem = GetDataGroupArgTemplate(elxValue); - APPSPAWN_CHECK(templateItem != nullptr, return -1, "Get data group arg template failed"); + APPSPAWN_CHECK(templateItem != nullptr, break, "Get data group arg template failed"); // If permission isn't null, need check permission flag if (templateItem->permission != nullptr) { @@ -502,18 +525,18 @@ static int ParseDataGroupList(AppSpawnMgr *content, const AppSpawningCtx *proper continue; } } - // sandboxPath: /mnt/sandbox///data/storage/el/group std::string sandboxPath = "/mnt/sandbox/" + std::to_string(info->uid / UID_BASE) + "/" + varBundleName + templateItem->sandboxPath; - ret = AddDataGroupItemToQueue(content, srcPath, sandboxPath, item[GROUPLIST_KEY_UUID]); + ret = AddDataGroupItemToQueue(content, srcPath, sandboxPath, uuidItem->valuestring); if (ret != 0) { APPSPAWN_LOGE("Add datagroup item to dataGroupCtxQueue failed, el%{public}d", elxValue); OH_ListRemoveAll(&content->dataGroupCtxQueue, nullptr); - return -1; + break; } } + cJSON_Delete(dataGroupList); DumpDataGroupCtxQueue(&content->dataGroupCtxQueue); return ret; @@ -552,7 +575,7 @@ int UpdateDataGroupDirs(AppSpawnMgr *content) } node = node->next; } - OH_ListRemoveAll(&content->dataGroupCtxQueue, NULL); + OH_ListRemoveAll(&content->dataGroupCtxQueue, nullptr); return 0; } @@ -581,7 +604,7 @@ static void MountDirToShared(AppSpawnMgr *content, const AppSpawningCtx *propert AppDacInfo *info = reinterpret_cast(GetAppProperty(property, TLV_DAC_INFO)); std::string varBundleName = ReplaceVarBundleName(property); - if (info == NULL || varBundleName == "") { + if (info == nullptr || varBundleName == "") { APPSPAWN_LOGE("Invalid app dac info or varBundleName"); return; } diff --git a/modules/sandbox/sandbox_shared_mount.h b/modules/sandbox/normal/sandbox_shared_mount.h similarity index 95% rename from modules/sandbox/sandbox_shared_mount.h rename to modules/sandbox/normal/sandbox_shared_mount.h index 1a24f2cce94ebc4c10277dc73ccc17985aee6874..c90efcdb5d00f215771bac7841c4a4c479403152 100644 --- a/modules/sandbox/sandbox_shared_mount.h +++ b/modules/sandbox/normal/sandbox_shared_mount.h @@ -16,13 +16,12 @@ #ifndef SANDBOX_SHARED_MOUNT_H #define SANDBOX_SHARED_MOUNT_H -#include "nlohmann/json.hpp" - #include "appspawn.h" #include "appspawn_hook.h" #include "appspawn_manager.h" #include "appspawn_utils.h" #include "list.h" +#include "json_utils.h" #ifdef __cplusplus extern "C" { @@ -57,7 +56,7 @@ struct SharedMountArgs { mode_t mountSharedFlag = MS_SLAVE; }; -bool IsValidDataGroupItem(nlohmann::json &item); +bool IsValidDataGroupItem(cJSON *item); int GetElxInfoFromDir(const char *path); const DataGroupSandboxPathTemplate *GetDataGroupArgTemplate(uint32_t category); void *GetEl1BundleMountCount(void); diff --git a/modules/sandbox/sandbox_dec.c b/modules/sandbox/sandbox_dec.c new file mode 100644 index 0000000000000000000000000000000000000000..cc1e74eba50e22a971e164d311c0fb2000c0603d --- /dev/null +++ b/modules/sandbox/sandbox_dec.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sandbox_dec.h" + +#include +#include +#include +#include +#include "appspawn_utils.h" +#include "appspawn_hook.h" + +static const char *g_decConstraintDir[] = { + "/storage/Users", + "/storage/External", + "/storage/Share", + "/storage/hmdfs", + "/mnt/data/fuse", + "/mnt/debug", + "/storage/userExternal" +}; + +static const char *g_decForcedPrefix[] = { + "/storage/Users/currentUser/appdata", +}; + +static DecPolicyInfo *g_decPolicyInfos = NULL; + +void DestroyDecPolicyInfos(DecPolicyInfo *decPolicyInfos) +{ + if (decPolicyInfos == NULL) { + return; + } + for (uint32_t i = 0; i < decPolicyInfos->pathNum; i++) { + if (decPolicyInfos->path[i].path) { + free(decPolicyInfos->path[i].path); + decPolicyInfos->path[i].pathLen = 0; + decPolicyInfos->path[i].flag = 0; + decPolicyInfos->path[i].mode = 0; + } + } + decPolicyInfos->pathNum = 0; + decPolicyInfos->tokenId = 0; + decPolicyInfos->flag = 0; + free(decPolicyInfos); +} + +void SetDecPolicyInfos(DecPolicyInfo *decPolicyInfos) +{ + if (decPolicyInfos == NULL || decPolicyInfos->pathNum == 0) { + return; + } + + if (g_decPolicyInfos == NULL) { + g_decPolicyInfos = (DecPolicyInfo *)calloc(1, sizeof(DecPolicyInfo)); + if (g_decPolicyInfos == NULL) { + APPSPAWN_LOGE("calloc failed"); + return; + } + } + + APPSPAWN_CHECK(g_decPolicyInfos->pathNum + decPolicyInfos->pathNum <= MAX_POLICY_NUM, + DestroyDecPolicyInfos(g_decPolicyInfos); + g_decPolicyInfos = NULL; + return, "Out of MAX_POLICY_NUM %{public}d, %{public}d", g_decPolicyInfos->pathNum, decPolicyInfos->pathNum); + for (uint32_t i = 0; i < decPolicyInfos->pathNum; i++) { + PathInfo pathInfo = {0}; + if (decPolicyInfos->path[i].path == NULL) { + DestroyDecPolicyInfos(g_decPolicyInfos); + g_decPolicyInfos = NULL; + return; + } + pathInfo.path = strdup(decPolicyInfos->path[i].path); + if (pathInfo.path == NULL) { + DestroyDecPolicyInfos(g_decPolicyInfos); + g_decPolicyInfos = NULL; + return; + } + pathInfo.pathLen = (uint32_t)strlen(pathInfo.path); + pathInfo.mode = decPolicyInfos->path[i].mode; + uint32_t index = g_decPolicyInfos->pathNum + i; + g_decPolicyInfos->path[index] = pathInfo; + } + g_decPolicyInfos->tokenId = decPolicyInfos->tokenId; + g_decPolicyInfos->pathNum += decPolicyInfos->pathNum; + g_decPolicyInfos->flag = true; + g_decPolicyInfos->userId = 0; +} + +static int SetDenyConstraintDirs(AppSpawnMgr *content) +{ + APPSPAWN_LOGI("enter SetDenyConstraintDirs sandbox policy success."); + UNUSED(content); + const char *decFilename = "/dev/dec"; + int fd = open(decFilename, O_RDWR); + if (fd < 0) { + APPSPAWN_LOGE("open dec file fail."); + return 0; + } + + uint32_t decDirsSize = ARRAY_LENGTH(g_decConstraintDir); + DecPolicyInfo decPolicyInfos = {0}; + decPolicyInfos.tokenId = 0; + decPolicyInfos.pathNum = decDirsSize; + decPolicyInfos.flag = 0; + + for (uint32_t i = 0; i < decDirsSize; i++) { + PathInfo pathInfo = {(char *)g_decConstraintDir[i], (uint32_t)strlen(g_decConstraintDir[i]), SANDBOX_MODE_READ}; + decPolicyInfos.path[i] = pathInfo; + } + + if (ioctl(fd, CONSTRAINT_DEC_POLICY_CMD, &decPolicyInfos) < 0) { + APPSPAWN_LOGE("set sandbox policy failed."); + } else { + APPSPAWN_LOGI("set CONSTRAINT_DEC_POLICY_CMD sandbox policy success."); + for (uint32_t i = 0; i < decDirsSize; i++) { + APPSPAWN_LOGI("policy info: %{public}s", decPolicyInfos.path[i].path); + } + } + close(fd); + return 0; +} + +static int SetForcedPrefixDirs(AppSpawnMgr *content) +{ + APPSPAWN_LOGI("enter SetForcedPrefixDirs sandbox policy success."); + UNUSED(content); + const char *decFilename = "/dev/dec"; + int fd = open(decFilename, O_RDWR); + if (fd < 0) { + APPSPAWN_LOGE("open dec file fail."); + return 0; + } + + uint32_t decDirsSize = ARRAY_LENGTH(g_decForcedPrefix); + DecPolicyInfo decPolicyInfos = {0}; + decPolicyInfos.tokenId = 0; + decPolicyInfos.pathNum = decDirsSize; + decPolicyInfos.flag = 0; + + for (uint32_t i = 0; i < decDirsSize; i++) { + PathInfo pathInfo = {(char *)g_decForcedPrefix[i], (uint32_t)strlen(g_decForcedPrefix[i]), SANDBOX_MODE_READ}; + decPolicyInfos.path[i] = pathInfo; + } + + if (ioctl(fd, SET_DEC_PREFIX_CMD, &decPolicyInfos) < 0) { + APPSPAWN_LOGE("set sandbox forced prefix failed."); + } else { + APPSPAWN_LOGI("set SET_DEC_PREFIX_CMD sandbox policy success."); + for (uint32_t i = 0; i < decDirsSize; i++) { + APPSPAWN_LOGI("policy info: %{public}s", decPolicyInfos.path[i].path); + } + } + close(fd); + return 0; +} + +void SetDecPolicy(void) +{ + if (g_decPolicyInfos == NULL) { + return; + } + const char *decFilename = "/dev/dec"; + int fd = open(decFilename, O_RDWR); + if (fd < 0) { + APPSPAWN_LOGE("open dec file fail."); + DestroyDecPolicyInfos(g_decPolicyInfos); + g_decPolicyInfos = NULL; + return; + } + + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + uint64_t timestamp = ts.tv_sec * APPSPAWN_SEC_TO_NSEC + ts.tv_nsec; + g_decPolicyInfos->timestamp = timestamp; + + if (ioctl(fd, SET_DEC_POLICY_CMD, g_decPolicyInfos) < 0) { + APPSPAWN_LOGE("set sandbox policy failed."); + } else { + APPSPAWN_LOGI("set SET_DEC_POLICY_CMD sandbox policy success. timestamp:%{public}" PRId64 "", timestamp); + for (uint32_t i = 0; i < g_decPolicyInfos->pathNum; i++) { + APPSPAWN_LOGI("policy info: path %{public}s, mode 0x%{public}x", + g_decPolicyInfos->path[i].path, g_decPolicyInfos->path[i].mode); + } + } + close(fd); + DestroyDecPolicyInfos(g_decPolicyInfos); + g_decPolicyInfos = NULL; + return; +} + +MODULE_CONSTRUCTOR(void) +{ + APPSPAWN_LOGI("Load sandbox dec module ..."); + AddPreloadHook(HOOK_PRIO_COMMON, SetDenyConstraintDirs); + AddPreloadHook(HOOK_PRIO_COMMON, SetForcedPrefixDirs); +} diff --git a/modules/sandbox/sandbox_dec.h b/modules/sandbox/sandbox_dec.h new file mode 100644 index 0000000000000000000000000000000000000000..6445289385e3dc5ca4c6fda89b07c5679d930bed --- /dev/null +++ b/modules/sandbox/sandbox_dec.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SANDBOX_DEC_H +#define SANDBOX_DEC_H + +#include +#include +#include +#include +#include +#include "appspawn_hook.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#define DEV_DEC_MINOR 0x25 +#define HM_DEC_IOCTL_BASE 's' +#define HM_SET_POLICY_ID 1 +#define HM_DEL_POLICY_ID 2 +#define HM_QUERY_POLICY_ID 3 +#define HM_CHECK_POLICY_ID 4 +#define HM_DESTORY_POLICY_ID 5 +#define HM_CONSTRAINT_POLICY_ID 6 +#define HM_DENY_POLICY_ID 7 +#define HM_SET_PREFIX_ID 8 + +#define SET_DEC_POLICY_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_SET_POLICY_ID, DecPolicyInfo) +#define DEL_DEC_POLICY_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_DEL_POLICY_ID, DecPolicyInfo) // 忽略flag和mode +#define CHECK_DEC_POLICY_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_CHECK_POLICY_ID, DecPolicyInfo) // 忽略flag +#define DESTORY_DEC_POLICY_CMD _IOW(HM_DEC_IOCTL_BASE, HM_DESTORY_POLICY_ID, uint64_t) +#define CONSTRAINT_DEC_POLICY_CMD _IOW(HM_DEC_IOCTL_BASE, HM_CONSTRAINT_POLICY_ID, DecPolicyInfo) +#define DENY_DEC_POLICY_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_DENY_POLICY_ID, DecPolicyInfo) // 忽略tokenid/flag/mode +#define SET_DEC_PREFIX_CMD _IOWR(HM_DEC_IOCTL_BASE, HM_SET_PREFIX_ID, DecPolicyInfo) + +#define MAX_POLICY_NUM 8 +#define SANDBOX_MODE_READ 0x00000001 +#define SANDBOX_MODE_WRITE (SANDBOX_MODE_READ << 1) +#define DEC_MODE_DENY_READ (1 << 5) +#define DEC_MODE_DENY_WRITE (1 << 6) + +#define DEC_POLICY_HEADER_RESERVED 64 + +typedef struct PathInfo { + char *path; + uint32_t pathLen; + uint32_t mode; + bool flag; +} PathInfo; + +typedef struct DecPolicyInfo { + uint64_t tokenId; + uint64_t timestamp; + PathInfo path[MAX_POLICY_NUM]; + uint32_t pathNum; + int32_t userId; + uint64_t reserved[DEC_POLICY_HEADER_RESERVED]; + bool flag; +} DecPolicyInfo; + +typedef struct DecDenyPathTemplate { + const char *permission; + const char *decPath; +} DecDenyPathTemplate; + +void SetDecPolicyInfos(DecPolicyInfo *decPolicyInfos); +void DestroyDecPolicyInfos(DecPolicyInfo *decPolicyInfos); +void SetDecPolicy(void); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif diff --git a/modules/sandbox/sandbox_utils.cpp b/modules/sandbox/sandbox_utils.cpp deleted file mode 100644 index 777da7a5c3c4827652fa5ee5cf20fd3edd3c5cd7..0000000000000000000000000000000000000000 --- a/modules/sandbox/sandbox_utils.cpp +++ /dev/null @@ -1,2116 +0,0 @@ -/* - * Copyright (C) 2024-2025 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "sandbox_utils.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "appspawn_hook.h" -#include "appspawn_mount_permission.h" -#include "appspawn_msg.h" -#include "appspawn_server.h" -#include "appspawn_service.h" -#include "appspawn_utils.h" -#include "config_policy_utils.h" -#ifdef WITH_DLP -#include "dlp_fuse_fd.h" -#endif -#include "init_param.h" -#include "init_utils.h" -#include "parameter.h" -#include "parameters.h" -#include "securec.h" -#ifdef APPSPAWN_HISYSEVENT -#include "hisysevent_adapter.h" -#endif - -#ifdef WITH_SELINUX -#include "hap_restorecon.h" -#ifdef APPSPAWN_MOUNT_TMPSHM -#include "policycoreutils.h" -#endif // APPSPAWN_MOUNT_TMPSHM -#endif // WITH_SELINUX - -#define MAX_MOUNT_TIME 500 // 500us -#define LOCK_STATUS_SIZE 16 -#define DEV_SHM_DIR "/dev/shm/" - -using namespace std; -using namespace OHOS; - -namespace OHOS { -namespace AppSpawn { -namespace { - constexpr int32_t OPTIONS_MAX_LEN = 256; - constexpr int32_t FILE_ACCESS_COMMON_DIR_STATUS = 0; - constexpr int32_t FILE_CROSS_APP_STATUS = 1; - constexpr static mode_t FILE_MODE = 0711; - constexpr static mode_t BASIC_MOUNT_FLAGS = MS_REC | MS_BIND; - constexpr std::string_view APL_SYSTEM_CORE("system_core"); - constexpr std::string_view APL_SYSTEM_BASIC("system_basic"); - const std::string APP_JSON_CONFIG("/appdata-sandbox.json"); - const std::string APP_ISOLATED_JSON_CONFIG("/appdata-sandbox-isolated.json"); - const std::string g_physicalAppInstallPath = "/data/app/el1/bundle/public/"; - const std::string g_sandboxGroupPath = "/data/storage/el2/group/"; - const std::string g_sandboxHspInstallPath = "/data/storage/el1/bundle/"; - const std::string g_sandBoxAppInstallPath = "/data/accounts/account_0/applications/"; - const std::string g_bundleResourceSrcPath = "/data/service/el1/public/bms/bundle_resources/"; - const std::string g_bundleResourceDestPath = "/data/storage/bundle_resources/"; - const std::string g_dataBundles = "/data/bundles/"; - const std::string g_userId = ""; - const std::string g_packageName = ""; - const std::string g_packageNameIndex = ""; - const std::string g_variablePackageName = ""; - const std::string g_arkWebPackageName = ""; - const std::string g_hostUserId = ""; - const std::string g_sandBoxDir = "/mnt/sandbox/"; - const std::string g_statusCheck = "true"; - const std::string g_sbxSwitchCheck = "ON"; - const std::string g_dlpBundleName = "com.ohos.dlpmanager"; - const std::string g_internal = "__internal__"; - const std::string g_hspList_key_bundles = "bundles"; - const std::string g_hspList_key_modules = "modules"; - const std::string g_hspList_key_versions = "versions"; - const std::string g_overlayPath = "/data/storage/overlay/"; - const std::string g_groupList_key_dataGroupId = "dataGroupId"; - const std::string g_groupList_key_gid = "gid"; - const std::string g_groupList_key_dir = "dir"; - const std::string g_groupList_key_uuid = "uuid"; - const std::string HSPLIST_SOCKET_TYPE = "HspList"; - const std::string OVERLAY_SOCKET_TYPE = "Overlay"; - const std::string DATA_GROUP_SOCKET_TYPE = "DataGroup"; - const char *g_actionStatuc = "check-action-status"; - const char *g_appBase = "app-base"; - const char *g_appResources = "app-resources"; - const char *g_appAplName = "app-apl-name"; - const char *g_commonPrefix = "common"; - const char *g_destMode = "dest-mode"; - const char *g_fsType = "fs-type"; - const char *g_linkName = "link-name"; - const char *g_mountPrefix = "mount-paths"; - const char *g_gidPrefix = "gids"; - const char *g_privatePrefix = "individual"; - const char *g_permissionPrefix = "permission"; - const char *g_srcPath = "src-path"; - const char *g_sandBoxPath = "sandbox-path"; - const char *g_sandBoxFlags = "sandbox-flags"; - const char *g_sandBoxFlagsCustomized = "sandbox-flags-customized"; - const char *g_sandBoxOptions = "options"; - const char *g_dacOverrideSensitive = "dac-override-sensitive"; - const char *g_sandBoxShared = "sandbox-shared"; - const char *g_sandBoxSwitchPrefix = "sandbox-switch"; - const char *g_symlinkPrefix = "symbol-links"; - const char *g_sandboxRootPrefix = "sandbox-root"; - const char *g_topSandBoxSwitchPrefix = "top-sandbox-switch"; - const char *g_targetName = "target-name"; - const char *g_flagePoint = "flags-point"; - const char *g_mountSharedFlag = "mount-shared-flag"; - const char *g_flags = "flags"; - const char *g_sandBoxNsFlags = "sandbox-ns-flags"; - const char* g_fileSeparator = "/"; - const char* g_overlayDecollator = "|"; - const char *CREATE_SANDBOX_PATH = "create-sandbox-path"; - const std::string g_sandBoxRootDir = "/mnt/sandbox/"; - const std::string g_ohosGpu = "__internal__.com.ohos.gpu"; - const std::string g_ohosRender = "__internal__.com.ohos.render"; - const std::string g_sandBoxRootDirNweb = "/mnt/sandbox/com.ohos.render/"; - const std::string FILE_CROSS_APP_MODE = "ohos.permission.FILE_CROSS_APP"; - const std::string FILE_ACCESS_COMMON_DIR_MODE = "ohos.permission.FILE_ACCESS_COMMON_DIR"; - const std::string ACCESS_DLP_FILE_MODE = "ohos.permission.ACCESS_DLP_FILE"; - const std::string FILE_ACCESS_MANAGER_MODE = "ohos.permission.FILE_ACCESS_MANAGER"; - const std::string READ_WRITE_USER_FILE_MODE = "ohos.permission.READ_WRITE_USER_FILE"; - const std::string GET_ALL_PROCESSES_MODE = "ohos.permission.GET_ALL_PROCESSES"; - const std::string ARK_WEB_PERSIST_PACKAGE_NAME = "persist.arkwebcore.package_name"; - - const std::string& getArkWebPackageName() - { - static std::string arkWebPackageName; - if (arkWebPackageName.empty()) { - arkWebPackageName = system::GetParameter(ARK_WEB_PERSIST_PACKAGE_NAME, ""); - } - return arkWebPackageName; - } -} - -static uint32_t GetAppMsgFlags(const AppSpawningCtx *property) -{ - APPSPAWN_CHECK(property != nullptr && property->message != nullptr, - return 0, "Invalid property for name %{public}u", TLV_MSG_FLAGS); - AppSpawnMsgFlags *msgFlags = (AppSpawnMsgFlags *)GetAppSpawnMsgInfo(property->message, TLV_MSG_FLAGS); - APPSPAWN_CHECK(msgFlags != nullptr, - return 0, "No TLV_MSG_FLAGS in msg %{public}s", property->message->msgHeader.processName); - return msgFlags->flags[0]; -} - -bool JsonUtils::GetJsonObjFromJson(nlohmann::json &jsonObj, const std::string &jsonPath) -{ - APPSPAWN_CHECK(jsonPath.length() <= PATH_MAX, return false, "jsonPath is too long"); - std::ifstream jsonFileStream; - jsonFileStream.open(jsonPath.c_str(), std::ios::in); - APPSPAWN_CHECK_ONLY_EXPER(jsonFileStream.is_open(), return false); - std::ostringstream buf; - char ch; - while (buf && jsonFileStream.get(ch)) { - buf.put(ch); - } - jsonFileStream.close(); - jsonObj = nlohmann::json::parse(buf.str(), nullptr, false); - APPSPAWN_CHECK(!jsonObj.is_discarded() && jsonObj.is_structured(), return false, "Parse json file failed"); - return true; -} - -bool JsonUtils::GetStringFromJson(const nlohmann::json &json, const std::string &key, std::string &value) -{ - APPSPAWN_CHECK(json != nullptr && json.is_object(), return false, "json is not object."); - bool isRet = json.find(key) != json.end() && json.at(key).is_string(); - if (isRet) { - value = json.at(key).get(); - APPSPAWN_LOGV("Find key[%{public}s] : %{public}s successful.", key.c_str(), value.c_str()); - } - return isRet; -} - -std::map> SandboxUtils::appSandboxConfig_ = {}; -int32_t SandboxUtils::deviceTypeEnable_ = -1; - -void SandboxUtils::StoreJsonConfig(nlohmann::json &appSandboxConfig, SandboxConfigType type) -{ - SandboxUtils::appSandboxConfig_[type].push_back(appSandboxConfig); -} - -std::vector &SandboxUtils::GetJsonConfig(SandboxConfigType type) -{ - return SandboxUtils::appSandboxConfig_[type]; -} - -static void MakeDirRecursive(const std::string &path, mode_t mode) -{ - size_t size = path.size(); - if (size == 0) { - return; - } - - size_t index = 0; - do { - size_t pathIndex = path.find_first_of('/', index); - index = pathIndex == std::string::npos ? size : pathIndex + 1; - std::string dir = path.substr(0, index); -#ifndef APPSPAWN_TEST - APPSPAWN_CHECK(!(access(dir.c_str(), F_OK) < 0 && mkdir(dir.c_str(), mode) < 0), - return, "errno is %{public}d, mkdir %{public}s failed", errno, dir.c_str()); -#endif - } while (index < size); -} - -static void MakeDirRecursiveWithClock(const std::string &path, mode_t mode) -{ - size_t size = path.size(); - if (size == 0) { - return; - } -#ifdef APPSPAWN_HISYSEVENT - struct timespec startClock = {0}; - clock_gettime(CLOCK_MONOTONIC, &startClock); -#endif - size_t index = 0; - do { - size_t pathIndex = path.find_first_of('/', index); - index = pathIndex == std::string::npos ? size : pathIndex + 1; - std::string dir = path.substr(0, index); -#ifndef APPSPAWN_TEST - APPSPAWN_CHECK(!(access(dir.c_str(), F_OK) < 0 && mkdir(dir.c_str(), mode) < 0), - return, "errno is %{public}d, mkdir %{public}s failed", errno, dir.c_str()); -#endif - } while (index < size); - -#ifdef APPSPAWN_HISYSEVENT - struct timespec endClock = {0}; - clock_gettime(CLOCK_MONOTONIC, &endClock); - uint64_t diff = DiffTime(&startClock, &endClock); - - APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION, - ReportAbnormalDuration("MakeDirRecursive", diff)); -#endif -} - -static bool CheckDirRecursive(const std::string &path) -{ - size_t size = path.size(); - if (size == 0) { - return false; - } - size_t index = 0; - do { - size_t pathIndex = path.find_first_of('/', index); - index = pathIndex == std::string::npos ? size : pathIndex + 1; - std::string dir = path.substr(0, index); -#ifndef APPSPAWN_TEST - APPSPAWN_CHECK(access(dir.c_str(), F_OK) == 0, - return false, "check dir %{public}s failed, strerror: %{public}s", dir.c_str(), strerror(errno)); -#endif - } while (index < size); - return true; -} - -static void CheckAndCreatFile(const char *file) -{ - if (access(file, F_OK) == 0) { - APPSPAWN_LOGI("file %{public}s already exist", file); - return; - } - std::string path = file; - auto pos = path.find_last_of('/'); - APPSPAWN_CHECK(pos != std::string::npos, return, "file %{public}s error", file); - std::string dir = path.substr(0, pos); - MakeDirRecursive(dir, FILE_MODE); - int fd = open(file, O_CREAT, FILE_MODE); - if (fd < 0) { - APPSPAWN_LOGW("failed create %{public}s, err=%{public}d", file, errno); - } else { - close(fd); - } - return; -} - -static void CheckMountStatus(const std::string &path) -{ - std::ifstream file("/proc/self/mountinfo"); - if (!file.is_open()) { - APPSPAWN_LOGE("Failed to open /proc/self/mountinfo errno %{public}d", errno); - return; - } - - bool flag = false; - std::string line; - while (std::getline(file, line)) { - if (line.find(path) != std::string::npos) { - flag = true; - APPSPAWN_LOGI("Current mountinfo %{public}s", line.c_str()); - } - } - file.close(); - APPSPAWN_CHECK_ONLY_LOG(flag, "Mountinfo not contains %{public}s", path.c_str()); -} - -static bool IsNeededCheckPathStatus(const AppSpawningCtx *appProperty, const char *path) -{ - if (strstr(path, "data/app/el1/") || strstr(path, "data/app/el2/")) { - return true; - } - if ((strstr(path, "data/app/el3/") || strstr(path, "data/app/el4/") || strstr(path, "data/app/el5/")) && - CheckAppMsgFlagsSet(appProperty, APP_FLAGS_UNLOCKED_STATUS)) { - return true; - } - return false; -} - -int32_t SandboxUtils::DoAppSandboxMountOnce(const AppSpawningCtx *appProperty, const SharedMountArgs *arg) -{ - if (!(arg && arg->srcPath && arg->destPath && arg->srcPath[0] != '\0' && arg->destPath[0] != '\0')) { - return 0; - } - if (strstr(arg->srcPath, "system/etc/hosts") != nullptr || strstr(arg->srcPath, "system/etc/profile") != nullptr) { - CheckAndCreatFile(arg->destPath); - } else { - MakeDirRecursive(arg->destPath, FILE_MODE); - } - - int ret = 0; - // to mount fs and bind mount files or directory - struct timespec mountStart = {0}; - clock_gettime(CLOCK_MONOTONIC_COARSE, &mountStart); - APPSPAWN_LOGV("Bind mount %{public}s to %{public}s '%{public}s' '%{public}lu' '%{public}s' '%{public}u'", - arg->srcPath, arg->destPath, arg->fsType, arg->mountFlags, arg->options, arg->mountSharedFlag); - ret = mount(arg->srcPath, arg->destPath, arg->fsType, arg->mountFlags, arg->options); - struct timespec mountEnd = {0}; - clock_gettime(CLOCK_MONOTONIC_COARSE, &mountEnd); - uint64_t diff = DiffTime(&mountStart, &mountEnd); - APPSPAWN_CHECK_ONLY_LOG(diff < MAX_MOUNT_TIME, "mount %{public}s time %{public}" PRId64 " us", arg->srcPath, diff); -#ifdef APPSPAWN_HISYSEVENT - APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION, ReportAbnormalDuration("MOUNT", diff)); -#endif - if (ret != 0) { - APPSPAWN_LOGI("errno is: %{public}d, bind mount %{public}s to %{public}s", errno, arg->srcPath, arg->destPath); - if (errno == ENOENT && IsNeededCheckPathStatus(appProperty, arg->srcPath)) { - CheckDirRecursive(arg->srcPath); - } - return ret; - } - - ret = mount(nullptr, arg->destPath, nullptr, arg->mountSharedFlag, nullptr); - if (ret != 0) { - APPSPAWN_LOGI("errno is: %{public}d, private mount to %{public}s '%{public}u' failed", - errno, arg->destPath, arg->mountSharedFlag); - if (errno == EINVAL) { - CheckMountStatus(arg->destPath); - } - return ret; - } - return 0; -} - -static std::string& replace_all(std::string& str, const std::string& old_value, const std::string& new_value) -{ - while (true) { - std::string::size_type pos(0); - if ((pos = str.find(old_value)) != std::string::npos) { - str.replace(pos, old_value.length(), new_value); - } else { - break; - } - } - return str; -} - -static std::vector split(std::string &str, const std::string &pattern) -{ - std::string::size_type pos; - std::vector result; - str += pattern; - size_t size = str.size(); - - for (unsigned int i = 0; i < size; i++) { - pos = str.find(pattern, i); - if (pos < size) { - std::string s = str.substr(i, pos - i); - result.push_back(s); - i = pos + pattern.size() - 1; - } - } - - return result; -} - -void SandboxUtils::DoSandboxChmod(nlohmann::json jsonConfig, std::string &sandboxRoot) -{ - const std::map modeMap = {{"S_IRUSR", S_IRUSR}, {"S_IWUSR", S_IWUSR}, {"S_IXUSR", S_IXUSR}, - {"S_IRGRP", S_IRGRP}, {"S_IWGRP", S_IWGRP}, {"S_IXGRP", S_IXGRP}, - {"S_IROTH", S_IROTH}, {"S_IWOTH", S_IWOTH}, {"S_IXOTH", S_IXOTH}, - {"S_IRWXU", S_IRWXU}, {"S_IRWXG", S_IRWXG}, {"S_IRWXO", S_IRWXO}}; - std::string fileModeStr; - mode_t mode = 0; - - bool rc = JsonUtils::GetStringFromJson(jsonConfig, g_destMode, fileModeStr); - if (rc == false) { - return; - } - - std::vector modeVec = split(fileModeStr, "|"); - for (unsigned int i = 0; i < modeVec.size(); i++) { - if (modeMap.count(modeVec[i])) { - mode |= modeMap.at(modeVec[i]); - } - } - - chmod(sandboxRoot.c_str(), mode); -} - -unsigned long SandboxUtils::GetMountFlagsFromConfig(const std::vector &vec) -{ - const std::map MountFlagsMap = { {"rec", MS_REC}, {"MS_REC", MS_REC}, - {"bind", MS_BIND}, {"MS_BIND", MS_BIND}, - {"move", MS_MOVE}, {"MS_MOVE", MS_MOVE}, - {"slave", MS_SLAVE}, {"MS_SLAVE", MS_SLAVE}, - {"rdonly", MS_RDONLY}, {"MS_RDONLY", MS_RDONLY}, - {"shared", MS_SHARED}, {"MS_SHARED", MS_SHARED}, - {"unbindable", MS_UNBINDABLE}, - {"MS_UNBINDABLE", MS_UNBINDABLE}, - {"remount", MS_REMOUNT}, {"MS_REMOUNT", MS_REMOUNT}, - {"nosuid", MS_NOSUID}, {"MS_NOSUID", MS_NOSUID}, - {"nodev", MS_NODEV}, {"MS_NODEV", MS_NODEV}, - {"noexec", MS_NOEXEC}, {"MS_NOEXEC", MS_NOEXEC}, - {"noatime", MS_NOATIME}, {"MS_NOATIME", MS_NOATIME}, - {"lazytime", MS_LAZYTIME}, {"MS_LAZYTIME", MS_LAZYTIME}}; - unsigned long mountFlags = 0; - - for (unsigned int i = 0; i < vec.size(); i++) { - if (MountFlagsMap.count(vec[i])) { - mountFlags |= MountFlagsMap.at(vec[i]); - } - } - - return mountFlags; -} - -static void MakeAtomicServiceDir(const AppSpawningCtx *appProperty, std::string path, std::string variablePackageName) -{ - AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); - APPSPAWN_CHECK(dacInfo != NULL, return, "No dac info in msg app property"); - if (path.find("/mnt/share") != std::string::npos) { - path = "/data/service/el2/" + std::to_string(dacInfo->uid / UID_BASE) + "/share/" + variablePackageName; - } - struct stat st = {}; - if (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) { - return; - } - - int ret = mkdir(path.c_str(), S_IRWXU); - APPSPAWN_CHECK(ret == 0, return, "mkdir %{public}s failed, errno %{public}d", path.c_str(), errno); - - if (path.find("/database") != std::string::npos || path.find("/data/service/el2") != std::string::npos) { - ret = chmod(path.c_str(), S_IRWXU | S_IRWXG | S_ISGID); - } else if (path.find("/log") != std::string::npos) { - ret = chmod(path.c_str(), S_IRWXU | S_IRWXG); - } - APPSPAWN_CHECK(ret == 0, return, "chmod %{public}s failed, errno %{public}d", path.c_str(), errno); - -#ifdef WITH_SELINUX - AppSpawnMsgDomainInfo *msgDomainInfo = - reinterpret_cast(GetAppProperty(appProperty, TLV_DOMAIN_INFO)); - APPSPAWN_CHECK(msgDomainInfo != NULL, return, "No domain info for %{public}s", GetProcessName(appProperty)); - HapContext hapContext; - HapFileInfo hapFileInfo; - hapFileInfo.pathNameOrig.push_back(path); - hapFileInfo.apl = msgDomainInfo->apl; - hapFileInfo.packageName = GetBundleName(appProperty); - hapFileInfo.hapFlags = msgDomainInfo->hapFlags; - if (CheckAppMsgFlagsSet(appProperty, APP_FLAGS_DEBUGGABLE)) { - hapFileInfo.hapFlags |= SELINUX_HAP_DEBUGGABLE; - } - if ((path.find("/base") != std::string::npos) || (path.find("/database") != std::string::npos)) { - ret = hapContext.HapFileRestorecon(hapFileInfo); - APPSPAWN_CHECK(ret == 0, return, "set dir %{public}s selinuxLabel failed, apl %{public}s, ret %{public}d", - path.c_str(), hapFileInfo.apl.c_str(), ret); - } -#endif - if (path.find("/base") != std::string::npos || path.find("/data/service/el2") != std::string::npos) { - ret = chown(path.c_str(), dacInfo->uid, dacInfo->gid); - } else if (path.find("/database") != std::string::npos) { - ret = chown(path.c_str(), dacInfo->uid, DecodeGid("ddms")); - } else if (path.find("/log") != std::string::npos) { - ret = chown(path.c_str(), dacInfo->uid, DecodeGid("log")); - } - APPSPAWN_CHECK(ret == 0, return, "chown %{public}s failed, errno %{public}d", path.c_str(), errno); - return; -} - -static std::string ReplaceVariablePackageName(const AppSpawningCtx *appProperty, const std::string &path) -{ - std::string tmpSandboxPath = path; - AppSpawnMsgBundleInfo *bundleInfo = - reinterpret_cast(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); - APPSPAWN_CHECK(bundleInfo != NULL, return "", "No bundle info in msg %{public}s", GetBundleName(appProperty)); - - char *extension; - uint32_t flags = CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE) ? 0x4 : 0; - if (flags == 0) { - flags = (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE) && - bundleInfo->bundleIndex > 0) ? 0x1 : 0; - flags |= CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_EXTENSION_SANDBOX) ? 0x2 : 0; - extension = reinterpret_cast( - GetAppSpawnMsgExtInfo(appProperty->message, MSG_EXT_NAME_APP_EXTENSION, NULL)); - } - std::ostringstream variablePackageName; - switch (flags) { - case 0: // 0 default - variablePackageName << bundleInfo->bundleName; - break; - case 1: // 1 +clone-bundleIndex+packageName - variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName; - break; - case 2: { // 2 +extension-+packageName - APPSPAWN_CHECK(extension != NULL, return "", "Invalid extension data "); - variablePackageName << "+extension-" << extension << "+" << bundleInfo->bundleName; - break; - } - case 3: { // 3 +clone-bundleIndex+extension-+packageName - APPSPAWN_CHECK(extension != NULL, return "", "Invalid extension data "); - variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+extension" << "-" << - extension << "+" << bundleInfo->bundleName; - break; - } - case 4: { // 4 +auid-+packageName - std::string accountId = SandboxUtils::GetExtraInfoByType(appProperty, MSG_EXT_NAME_ACCOUNT_ID); - variablePackageName << "+auid-" << accountId << "+" << bundleInfo->bundleName; - std::string atomicServicePath = path; - atomicServicePath = replace_all(atomicServicePath, g_variablePackageName, variablePackageName.str()); - MakeAtomicServiceDir(appProperty, atomicServicePath, variablePackageName.str()); - break; - } - default: - variablePackageName << bundleInfo->bundleName; - break; - } - tmpSandboxPath = replace_all(tmpSandboxPath, g_variablePackageName, variablePackageName.str()); - APPSPAWN_LOGV("tmpSandboxPath %{public}s", tmpSandboxPath.c_str()); - return tmpSandboxPath; -} - -static std::string ReplaceHostUserId(const AppSpawningCtx *appProperty, const std::string &path) -{ - std::string tmpSandboxPath = path; - int32_t uid = 0; - const char *userId = - (const char *)(GetAppSpawnMsgExtInfo(appProperty->message, MSG_EXT_NAME_PARENT_UID, NULL)); - if (userId != nullptr) { - uid = atoi(userId); - } - tmpSandboxPath = replace_all(tmpSandboxPath, g_hostUserId, std::to_string(uid / UID_BASE)); - APPSPAWN_LOGV("tmpSandboxPath %{public}s", tmpSandboxPath.c_str()); - return tmpSandboxPath; -} - -string SandboxUtils::ConvertToRealPath(const AppSpawningCtx *appProperty, std::string path) -{ - AppSpawnMsgBundleInfo *info = - reinterpret_cast(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); - AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); - if (info == nullptr || dacInfo == nullptr) { - return ""; - } - if (path.find(g_packageNameIndex) != std::string::npos) { - std::string bundleNameWithIndex = info->bundleName; - if (info->bundleIndex != 0) { - bundleNameWithIndex = std::to_string(info->bundleIndex) + "_" + bundleNameWithIndex; - } - path = replace_all(path, g_packageNameIndex, bundleNameWithIndex); - } - - if (path.find(g_packageName) != std::string::npos) { - path = replace_all(path, g_packageName, info->bundleName); - } - - if (path.find(g_userId) != std::string::npos) { - path = replace_all(path, g_userId, std::to_string(dacInfo->uid / UID_BASE)); - } - - if (path.find(g_hostUserId) != std::string::npos) { - path = ReplaceHostUserId(appProperty, path); - } - - if (path.find(g_variablePackageName) != std::string::npos) { - path = ReplaceVariablePackageName(appProperty, path); - } - - if (path.find(g_arkWebPackageName) != std::string::npos) { - path = replace_all(path, g_arkWebPackageName, getArkWebPackageName()); - APPSPAWN_LOGV( - "arkWeb sandbox, path %{public}s, package:%{public}s", - path.c_str(), getArkWebPackageName().c_str()); - } - - return path; -} - -std::string SandboxUtils::ConvertToRealPathWithPermission(const AppSpawningCtx *appProperty, - std::string path) -{ - AppSpawnMsgBundleInfo *info = - reinterpret_cast(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); - if (info == nullptr) { - return ""; - } - if (path.find(g_packageNameIndex) != std::string::npos) { - std::string bundleNameWithIndex = info->bundleName; - if (info->bundleIndex != 0) { - bundleNameWithIndex = std::to_string(info->bundleIndex) + "_" + bundleNameWithIndex; - } - path = replace_all(path, g_packageNameIndex, bundleNameWithIndex); - } - - if (path.find(g_packageName) != std::string::npos) { - path = replace_all(path, g_packageName, info->bundleName); - } - - if (path.find(g_userId) != std::string::npos) { - if (deviceTypeEnable_ == FILE_CROSS_APP_STATUS) { - path = replace_all(path, g_userId, "currentUser"); - } else if (deviceTypeEnable_ == FILE_ACCESS_COMMON_DIR_STATUS) { - path = replace_all(path, g_userId, "currentUser"); - } else { - return ""; - } - } - return path; -} - -bool SandboxUtils::GetSandboxDacOverrideEnable(nlohmann::json &config) -{ - std::string dacOverrideSensitive = ""; - if (config.find(g_dacOverrideSensitive) == config.end()) { - return false; - } - dacOverrideSensitive = config[g_dacOverrideSensitive].get(); - if (dacOverrideSensitive.compare("true") == 0) { - return true; - } - return false; -} - -std::string SandboxUtils::GetSbxPathByConfig(const AppSpawningCtx *appProperty, nlohmann::json &config) -{ - AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); - if (dacInfo == nullptr) { - return ""; - } - - std::string sandboxRoot = ""; - const std::string sandboxRootPathTemplate = "/mnt/sandbox//"; - const std::string originSandboxPath = "/mnt/sandbox/"; - std::string isolatedFlagText = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? "isolated/" : ""; - AppSpawnMsgBundleInfo *bundleInfo = - reinterpret_cast(GetAppProperty(appProperty, TLV_BUNDLE_INFO)); - if (bundleInfo == nullptr) { - return ""; - } - std::string tmpBundlePath = bundleInfo->bundleName; - std::ostringstream variablePackageName; - if (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE)) { - variablePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName; - tmpBundlePath = variablePackageName.str(); - } - const std::string variableSandboxRoot = g_sandBoxDir + to_string(dacInfo->uid / UID_BASE) + - "/" + isolatedFlagText.c_str() + tmpBundlePath; - if (config.find(g_sandboxRootPrefix) != config.end()) { - sandboxRoot = config[g_sandboxRootPrefix].get(); - if (sandboxRoot == originSandboxPath || sandboxRoot == sandboxRootPathTemplate) { - sandboxRoot = variableSandboxRoot; - } else { - sandboxRoot = ConvertToRealPath(appProperty, sandboxRoot); - APPSPAWN_LOGV("set sandbox-root name is %{public}s", sandboxRoot.c_str()); - } - } else { - sandboxRoot = variableSandboxRoot; - APPSPAWN_LOGV("set sandbox-root to default rootapp name is %{public}s", GetBundleName(appProperty)); - } - - return sandboxRoot; -} - -bool SandboxUtils::GetSbxSwitchStatusByConfig(nlohmann::json &config) -{ - if (config.find(g_sandBoxSwitchPrefix) != config.end()) { - std::string switchStatus = config[g_sandBoxSwitchPrefix].get(); - if (switchStatus == g_sbxSwitchCheck) { - return true; - } else { - return false; - } - } - - // if not find sandbox-switch node, default switch status is true - return true; -} - -static bool CheckMountConfig(nlohmann::json &mntPoint, const AppSpawningCtx *appProperty, - bool checkFlag) -{ - bool istrue = mntPoint.find(g_srcPath) == mntPoint.end() || (!mntPoint[g_srcPath].is_string()) || - mntPoint.find(g_sandBoxPath) == mntPoint.end() || (!mntPoint[g_sandBoxPath].is_string()) || - ((mntPoint.find(g_sandBoxFlags) == mntPoint.end()) && - (mntPoint.find(g_sandBoxFlagsCustomized) == mntPoint.end())); - APPSPAWN_CHECK(!istrue, return false, - "read mount config failed, app name is %{public}s", GetBundleName(appProperty)); - - AppSpawnMsgDomainInfo *info = - reinterpret_cast(GetAppProperty(appProperty, TLV_DOMAIN_INFO)); - APPSPAWN_CHECK(info != nullptr, return false, "Filed to get domain info %{public}s", GetBundleName(appProperty)); - - if (mntPoint[g_appAplName] != nullptr) { - std::string app_apl_name = mntPoint[g_appAplName].get(); - const char *p_app_apl = nullptr; - p_app_apl = app_apl_name.c_str(); - if (!strcmp(p_app_apl, info->apl)) { - return false; - } - } - - const std::string configSrcPath = mntPoint[g_srcPath].get(); - // special handle wps and don't use /data/app/xxx/ config - if (checkFlag && (configSrcPath.find("/data/app") != std::string::npos && - (configSrcPath.find("/base") != std::string::npos || - configSrcPath.find("/database") != std::string::npos - ) && configSrcPath.find(g_packageName) != std::string::npos)) { - return false; - } - - return true; -} - -static int32_t DoDlpAppMountStrategy(const AppSpawningCtx *appProperty, - const std::string &srcPath, const std::string &sandboxPath, - const std::string &fsType, unsigned long mountFlags) -{ - AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); - if (dacInfo == nullptr) { - return -1; - } - - // umount fuse path, make sure that sandbox path is not a mount point - umount2(sandboxPath.c_str(), MNT_DETACH); - - int fd = open("/dev/fuse", O_RDWR); - APPSPAWN_CHECK(fd != -1, return -EINVAL, "open /dev/fuse failed, errno is %{public}d", errno); - - char options[OPTIONS_MAX_LEN]; - (void)sprintf_s(options, sizeof(options), "fd=%d," - "rootmode=40000,user_id=%u,group_id=%u,allow_other," - "context=\"u:object_r:dlp_fuse_file:s0\"," - "fscontext=u:object_r:dlp_fuse_file:s0", - fd, dacInfo->uid, dacInfo->gid); - - // To make sure destinationPath exist - MakeDirRecursive(sandboxPath, FILE_MODE); - - int ret = 0; -#ifndef APPSPAWN_TEST - APPSPAWN_LOGV("Bind mount %{public}s to %{public}s '%{public}s' '%{public}lu' '%{public}s'", - srcPath.c_str(), sandboxPath.c_str(), fsType.c_str(), mountFlags, options); - ret = mount(srcPath.c_str(), sandboxPath.c_str(), fsType.c_str(), mountFlags, options); - APPSPAWN_CHECK(ret == 0, close(fd); - return ret, "DoDlpAppMountStrategy failed, bind mount %{public}s to %{public}s failed %{public}d", - srcPath.c_str(), sandboxPath.c_str(), errno); - - ret = mount(nullptr, sandboxPath.c_str(), nullptr, MS_SHARED, nullptr); - APPSPAWN_CHECK(ret == 0, close(fd); - return ret, "errno is: %{public}d, private mount to %{public}s failed", errno, sandboxPath.c_str()); -#endif - /* set DLP_FUSE_FD */ -#ifdef WITH_DLP - SetDlpFuseFd(fd); -#endif - ret = fd; - return ret; -} - -static int32_t HandleSpecialAppMount(const AppSpawningCtx *appProperty, - const std::string &srcPath, const std::string &sandboxPath, const std::string &fsType, unsigned long mountFlags) -{ - std::string bundleName = GetBundleName(appProperty); - std::string processName = GetProcessName(appProperty); - /* dlp application mount strategy */ - /* dlp is an example, we should change to real bundle name later */ - if (bundleName.find(g_dlpBundleName) != std::string::npos && - processName.compare(g_dlpBundleName) == 0) { - if (!fsType.empty()) { - return DoDlpAppMountStrategy(appProperty, srcPath, sandboxPath, fsType, mountFlags); - } - } - return -1; -} - -static uint32_t ConvertFlagStr(const std::string &flagStr) -{ - const std::map flagsMap = {{"0", 0}, {"START_FLAGS_BACKUP", 1}, - {"DLP_MANAGER", 2}, - {"DEVELOPER_MODE", 17}, - {"PREINSTALLED_HAP", 29}, - {"CUSTOM_SANDBOX_HAP", 31}}; - - if (flagsMap.count(flagStr)) { - return 1 << flagsMap.at(flagStr); - } - - return 0; -} - -unsigned long SandboxUtils::GetSandboxMountFlags(nlohmann::json &config) -{ - unsigned long mountFlags = BASIC_MOUNT_FLAGS; - if (GetSandboxDacOverrideEnable(config) && (config.find(g_sandBoxFlagsCustomized) != config.end())) { - mountFlags = GetMountFlagsFromConfig(config[g_sandBoxFlagsCustomized].get>()); - } else if (config.find(g_sandBoxFlags) != config.end()) { - mountFlags = GetMountFlagsFromConfig(config[g_sandBoxFlags].get>()); - } - return mountFlags; -} - -std::string SandboxUtils::GetSandboxFsType(nlohmann::json &config) -{ - std::string fsType = ""; - if (GetSandboxDacOverrideEnable(config) && (config.find(g_fsType) != config.end())) { - fsType = config[g_fsType].get(); - } - return fsType; -} - -std::string SandboxUtils::GetSandboxOptions(const AppSpawningCtx *appProperty, nlohmann::json &config) -{ - AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); - if (dacInfo == nullptr) { - return ""; - } - - std::string options = ""; - const int userIdBase = UID_BASE; - if (GetSandboxDacOverrideEnable(config) && (config.find(g_sandBoxOptions) != config.end())) { - options = config[g_sandBoxOptions].get() + ",user_id="; - options += std::to_string(dacInfo->uid / userIdBase); - } - return options; -} - -void SandboxUtils::GetSandboxMountConfig(const AppSpawningCtx *appProperty, const std::string §ion, - nlohmann::json &mntPoint, SandboxMountConfig &mountConfig) -{ - if (section.compare(g_permissionPrefix) == 0) { - mountConfig.optionsPoint = GetSandboxOptions(appProperty, mntPoint); - mountConfig.fsType = GetSandboxFsType(mntPoint); - } else { - mountConfig.fsType = (mntPoint.find(g_fsType) != mntPoint.end()) ? mntPoint[g_fsType].get() : ""; - mountConfig.optionsPoint = ""; - } - return; -} - -std::string SandboxUtils::GetSandboxPath(const AppSpawningCtx *appProperty, nlohmann::json &mntPoint, - const std::string §ion, std::string sandboxRoot) -{ - std::string sandboxPath = ""; - std::string tmpSandboxPath = mntPoint[g_sandBoxPath].get(); - if (section.compare(g_permissionPrefix) == 0) { - sandboxPath = sandboxRoot + ConvertToRealPathWithPermission(appProperty, tmpSandboxPath); - } else { - sandboxPath = sandboxRoot + ConvertToRealPath(appProperty, tmpSandboxPath); - } - return sandboxPath; -} - -static bool CheckMountFlag(const AppSpawningCtx *appProperty, const std::string bundleName, nlohmann::json &appConfig) -{ - if (appConfig.find(g_flags) != appConfig.end()) { - if (((ConvertFlagStr(appConfig[g_flags].get()) & GetAppMsgFlags(appProperty)) != 0) && - bundleName.find("wps") != std::string::npos) { - return true; - } - } - return false; -} - -static bool GetCreateSandboxPath(nlohmann::json &json, std::string srcPath) -{ - APPSPAWN_CHECK(json != nullptr && json.is_object(), return true, "json is not object."); - bool isRet = json.find(CREATE_SANDBOX_PATH) != json.end() && json.at(CREATE_SANDBOX_PATH).is_string(); - if (isRet) { - std::string value = json.at(CREATE_SANDBOX_PATH).get(); - APPSPAWN_LOGV("Find create-sandbox-path: %{public}s successful.", value.c_str()); - if (value == "false" && access(srcPath.c_str(), F_OK) != 0) { - return false; - } - } - return true; -} - -static bool GetCheckStatus(nlohmann::json &mntPoint) -{ - std::string value = g_statusCheck; - (void)JsonUtils::GetStringFromJson(mntPoint, g_actionStatuc, value); - if (value == g_statusCheck) { - return true; - } - return false; -} - -int SandboxUtils::DoAllMntPointsMount(const AppSpawningCtx *appProperty, - nlohmann::json &appConfig, const char *typeName, const std::string §ion) -{ - std::string bundleName = GetBundleName(appProperty); - if (appConfig.find(g_mountPrefix) == appConfig.end()) { - APPSPAWN_LOGV("mount config is not found in %{public}s, app name is %{public}s", - section.c_str(), bundleName.c_str()); - return 0; - } - std::string sandboxRoot = GetSbxPathByConfig(appProperty, appConfig); - bool checkFlag = CheckMountFlag(appProperty, bundleName, appConfig); - nlohmann::json& mountPoints = appConfig[g_mountPrefix]; - unsigned int mountPointSize = mountPoints.size(); - for (unsigned int i = 0; i < mountPointSize; i++) { - nlohmann::json& mntPoint = mountPoints[i]; - APPSPAWN_CHECK_ONLY_EXPER(CheckMountConfig(mntPoint, appProperty, checkFlag), continue); - - std::string srcPath = ConvertToRealPath(appProperty, mntPoint[g_srcPath].get()); - APPSPAWN_CHECK_ONLY_EXPER(GetCreateSandboxPath(mntPoint, srcPath), continue); - std::string sandboxPath = GetSandboxPath(appProperty, mntPoint, section, sandboxRoot); - SandboxMountConfig mountConfig = {0}; - GetSandboxMountConfig(appProperty, section, mntPoint, mountConfig); - SharedMountArgs arg = { - .srcPath = srcPath.c_str(), - .destPath = sandboxPath.c_str(), - .fsType = mountConfig.fsType.c_str(), - .mountFlags = GetSandboxMountFlags(mntPoint), - .options = mountConfig.optionsPoint.c_str(), - .mountSharedFlag = (mntPoint.find(g_mountSharedFlag) != mntPoint.end()) ? MS_SHARED : MS_SLAVE - }; - - /* if app mount failed for special strategy, we need deal with common mount config */ - int ret = HandleSpecialAppMount(appProperty, arg.srcPath, arg.destPath, arg.fsType, arg.mountFlags); - if (ret < 0) { - ret = DoAppSandboxMountOnce(appProperty, &arg); - } - APPSPAWN_CHECK(ret == 0 || !GetCheckStatus(mntPoint), -#ifdef APPSPAWN_HISYSEVENT - ReportMountFail(bundleName.c_str(), arg.srcPath, arg.destPath, errno); - ret = APPSPAWN_SANDBOX_MOUNT_FAIL; -#endif - return ret, - "DoAppSandboxMountOnce section %{public}s failed, %{public}s", section.c_str(), arg.destPath); - DoSandboxChmod(mntPoint, sandboxRoot); - } - return 0; -} - -int32_t SandboxUtils::DoAddGid(AppSpawningCtx *appProperty, nlohmann::json &appConfig, - const char* permissionName, const std::string §ion) -{ - std::string bundleName = GetBundleName(appProperty); - if (appConfig.find(g_gidPrefix) == appConfig.end()) { - return 0; - } - AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); - if (dacInfo == nullptr) { - return 0; - } - - nlohmann::json& gids = appConfig[g_gidPrefix]; - unsigned int gidSize = gids.size(); - for (unsigned int i = 0; i < gidSize; i++) { - if (dacInfo->gidCount < APP_MAX_GIDS) { - APPSPAWN_LOGI("add gid to gitTable in %{public}s, permission is %{public}s, gid:%{public}u", - bundleName.c_str(), permissionName, gids[i].get()); - dacInfo->gidTable[dacInfo->gidCount++] = gids[i].get(); - } - } - return 0; -} - -int SandboxUtils::DoAllSymlinkPointslink(const AppSpawningCtx *appProperty, nlohmann::json &appConfig) -{ - APPSPAWN_CHECK(appConfig.find(g_symlinkPrefix) != appConfig.end(), return 0, "symlink config is not found," - "maybe result sandbox launch failed app name is %{public}s", GetBundleName(appProperty)); - - nlohmann::json& symlinkPoints = appConfig[g_symlinkPrefix]; - std::string sandboxRoot = GetSbxPathByConfig(appProperty, appConfig); - unsigned int symlinkPointSize = symlinkPoints.size(); - - for (unsigned int i = 0; i < symlinkPointSize; i++) { - nlohmann::json& symPoint = symlinkPoints[i]; - - // Check the validity of the symlink configuration - if (symPoint.find(g_targetName) == symPoint.end() || (!symPoint[g_targetName].is_string()) || - symPoint.find(g_linkName) == symPoint.end() || (!symPoint[g_linkName].is_string())) { - APPSPAWN_LOGE("read symlink config failed, app name is %{public}s", GetBundleName(appProperty)); - continue; - } - - std::string targetName = ConvertToRealPath(appProperty, symPoint[g_targetName].get()); - std::string linkName = sandboxRoot + ConvertToRealPath(appProperty, symPoint[g_linkName].get()); - APPSPAWN_LOGV("symlink, from %{public}s to %{public}s", targetName.c_str(), linkName.c_str()); - - int ret = symlink(targetName.c_str(), linkName.c_str()); - if (ret && errno != EEXIST) { - APPSPAWN_LOGE("errno is %{public}d, symlink failed, %{public}s", errno, linkName.c_str()); - - std::string actionStatus = g_statusCheck; - (void)JsonUtils::GetStringFromJson(symPoint, g_actionStatuc, actionStatus); - if (actionStatus == g_statusCheck) { - return ret; - } - } - - DoSandboxChmod(symPoint, sandboxRoot); - } - - return 0; -} - -int32_t SandboxUtils::DoSandboxFilePrivateBind(const AppSpawningCtx *appProperty, - nlohmann::json &wholeConfig) -{ - const char *bundleName = GetBundleName(appProperty); - nlohmann::json& privateAppConfig = wholeConfig[g_privatePrefix][0]; - if (privateAppConfig.find(bundleName) != privateAppConfig.end()) { - APPSPAWN_LOGV("DoSandboxFilePrivateBind %{public}s", bundleName); - DoAddGid((AppSpawningCtx *)appProperty, privateAppConfig[bundleName][0], "", g_privatePrefix); - return DoAllMntPointsMount(appProperty, privateAppConfig[bundleName][0], nullptr, g_privatePrefix); - } - - return 0; -} - -int32_t SandboxUtils::DoSandboxFilePermissionBind(AppSpawningCtx *appProperty, - nlohmann::json &wholeConfig) -{ - if (wholeConfig.find(g_permissionPrefix) == wholeConfig.end()) { - APPSPAWN_LOGV("DoSandboxFilePermissionBind not found permission information in config file"); - return 0; - } - nlohmann::json& permissionAppConfig = wholeConfig[g_permissionPrefix][0]; - for (nlohmann::json::iterator it = permissionAppConfig.begin(); it != permissionAppConfig.end(); ++it) { - const std::string permission = it.key(); - int index = GetPermissionIndex(nullptr, permission.c_str()); - APPSPAWN_LOGV("DoSandboxFilePermissionBind mountPermissionFlags %{public}d", index); - if (CheckAppPermissionFlagSet(appProperty, static_cast(index))) { - DoAddGid(appProperty, permissionAppConfig[permission][0], permission.c_str(), g_permissionPrefix); - DoAllMntPointsMount(appProperty, permissionAppConfig[permission][0], permission.c_str(), - g_permissionPrefix); - } else { - APPSPAWN_LOGV("DoSandboxFilePermissionBind false %{public}s permission %{public}s", - GetBundleName(appProperty), permission.c_str()); - } - } - return 0; -} - -std::set SandboxUtils::GetMountPermissionNames() -{ - std::set permissionSet; - for (auto& config : SandboxUtils::GetJsonConfig(SANBOX_APP_JSON_CONFIG)) { - if (config.find(g_permissionPrefix) == config.end()) { - continue; - } - nlohmann::json& permissionAppConfig = config[g_permissionPrefix][0]; - for (auto it = permissionAppConfig.begin(); it != permissionAppConfig.end(); it++) { - permissionSet.insert(it.key()); - } - } - APPSPAWN_LOGI("GetMountPermissionNames size: %{public}lu", static_cast(permissionSet.size())); - return permissionSet; -} - -int32_t SandboxUtils::DoSandboxFilePrivateSymlink(const AppSpawningCtx *appProperty, - nlohmann::json &wholeConfig) -{ - const char *bundleName = GetBundleName(appProperty); - nlohmann::json& privateAppConfig = wholeConfig[g_privatePrefix][0]; - if (privateAppConfig.find(bundleName) != privateAppConfig.end()) { - return DoAllSymlinkPointslink(appProperty, privateAppConfig[bundleName][0]); - } - - return 0; -} - -int32_t SandboxUtils::HandleFlagsPoint(const AppSpawningCtx *appProperty, - nlohmann::json &appConfig) -{ - if (appConfig.find(g_flagePoint) == appConfig.end()) { - return 0; - } - - nlohmann::json& flagsPoints = appConfig[g_flagePoint]; - unsigned int flagsPointSize = flagsPoints.size(); - - for (unsigned int i = 0; i < flagsPointSize; i++) { - nlohmann::json& flagPoint = flagsPoints[i]; - - if (flagPoint.find(g_flags) != flagPoint.end() && flagPoint[g_flags].is_string()) { - std::string flagsStr = flagPoint[g_flags].get(); - uint32_t flag = ConvertFlagStr(flagsStr); - if ((GetAppMsgFlags(appProperty) & flag) == 0) { - continue; - } - int ret = DoAllMntPointsMount(appProperty, flagPoint, nullptr, g_flagePoint); - if (ret != 0) { - APPSPAWN_LOGE("DoAllMntPointsMount failed ret: %{public}d", ret); - } - } else { - APPSPAWN_LOGE("read flags config failed, app name is %{public}s", GetBundleName(appProperty)); - } - } - - return 0; -} - -int32_t SandboxUtils::DoSandboxFilePrivateFlagsPointHandle(const AppSpawningCtx *appProperty, - nlohmann::json &wholeConfig) -{ - const char *bundleName = GetBundleName(appProperty); - nlohmann::json& privateAppConfig = wholeConfig[g_privatePrefix][0]; - if (privateAppConfig.find(bundleName) != privateAppConfig.end()) { - return HandleFlagsPoint(appProperty, privateAppConfig[bundleName][0]); - } - - return 0; -} - -int32_t SandboxUtils::DoSandboxFileCommonFlagsPointHandle(const AppSpawningCtx *appProperty, - nlohmann::json &wholeConfig) -{ - nlohmann::json& commonConfig = wholeConfig[g_commonPrefix][0]; - if (commonConfig.find(g_appResources) != commonConfig.end()) { - return HandleFlagsPoint(appProperty, commonConfig[g_appResources][0]); - } - - return 0; -} - -int32_t SandboxUtils::DoSandboxFileCommonBind(const AppSpawningCtx *appProperty, nlohmann::json &wholeConfig) -{ - nlohmann::json& commonConfig = wholeConfig[g_commonPrefix][0]; - int ret = 0; - - if (commonConfig.find(g_appBase) != commonConfig.end()) { - ret = DoAllMntPointsMount(appProperty, commonConfig[g_appBase][0], nullptr, g_appBase); - if (ret) { - return ret; - } - } - - if (commonConfig.find(g_appResources) != commonConfig.end()) { - ret = DoAllMntPointsMount(appProperty, commonConfig[g_appResources][0], nullptr, g_appResources); - } - - return ret; -} - -int32_t SandboxUtils::DoSandboxFileCommonSymlink(const AppSpawningCtx *appProperty, - nlohmann::json &wholeConfig) -{ - nlohmann::json& commonConfig = wholeConfig[g_commonPrefix][0]; - int ret = 0; - - if (commonConfig.find(g_appBase) != commonConfig.end()) { - ret = DoAllSymlinkPointslink(appProperty, commonConfig[g_appBase][0]); - if (ret) { - return ret; - } - } - - if (commonConfig.find(g_appResources) != commonConfig.end()) { - ret = DoAllSymlinkPointslink(appProperty, commonConfig[g_appResources][0]); - } - - return ret; -} - -int32_t SandboxUtils::SetPrivateAppSandboxProperty_(const AppSpawningCtx *appProperty, - nlohmann::json &config) -{ - int ret = DoSandboxFilePrivateBind(appProperty, config); - APPSPAWN_CHECK(ret == 0, return ret, "DoSandboxFilePrivateBind failed"); - - ret = DoSandboxFilePrivateSymlink(appProperty, config); - APPSPAWN_CHECK_ONLY_LOG(ret == 0, "DoSandboxFilePrivateSymlink failed"); - - ret = DoSandboxFilePrivateFlagsPointHandle(appProperty, config); - APPSPAWN_CHECK_ONLY_LOG(ret == 0, "DoSandboxFilePrivateFlagsPointHandle failed"); - - return ret; -} - -int32_t SandboxUtils::SetPermissionAppSandboxProperty_(AppSpawningCtx *appProperty, - nlohmann::json &config) -{ - int ret = DoSandboxFilePermissionBind(appProperty, config); - APPSPAWN_CHECK(ret == 0, return ret, "DoSandboxFilePermissionBind failed"); - return ret; -} - - -int32_t SandboxUtils::SetRenderSandboxProperty(const AppSpawningCtx *appProperty, - std::string &sandboxPackagePath) -{ - return 0; -} - -int32_t SandboxUtils::SetRenderSandboxPropertyNweb(const AppSpawningCtx *appProperty, - std::string &sandboxPackagePath) -{ - SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? - SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; - - for (auto& config : SandboxUtils::GetJsonConfig(type)) { - nlohmann::json& privateAppConfig = config[g_privatePrefix][0]; - char *processType = (char *)(GetAppSpawnMsgExtInfo(appProperty->message, MSG_EXT_NAME_PROCESS_TYPE, NULL)); - APPSPAWN_CHECK(processType != NULL, return -1, "Invalid processType data"); - - if (strcmp(processType, "render") == 0 && privateAppConfig.find(g_ohosRender) != privateAppConfig.end()) { - int ret = DoAllMntPointsMount(appProperty, privateAppConfig[g_ohosRender][0], nullptr, g_ohosRender); - APPSPAWN_CHECK(ret == 0, return ret, "DoAllMntPointsMount failed, %{public}s", - GetBundleName(appProperty)); - ret = DoAllSymlinkPointslink(appProperty, privateAppConfig[g_ohosRender][0]); - APPSPAWN_CHECK(ret == 0, return ret, "DoAllSymlinkPointslink failed, %{public}s", - GetBundleName(appProperty)); - ret = HandleFlagsPoint(appProperty, privateAppConfig[g_ohosRender][0]); - APPSPAWN_CHECK_ONLY_LOG(ret == 0, "HandleFlagsPoint for render-sandbox failed, %{public}s", - GetBundleName(appProperty)); - } else if (strcmp(processType, "gpu") == 0 && privateAppConfig.find(g_ohosGpu) != privateAppConfig.end()) { - int ret = DoAllMntPointsMount(appProperty, privateAppConfig[g_ohosGpu][0], nullptr, g_ohosGpu); - APPSPAWN_CHECK(ret == 0, return ret, "DoAllMntPointsMount failed, %{public}s", - GetBundleName(appProperty)); - ret = DoAllSymlinkPointslink(appProperty, privateAppConfig[g_ohosGpu][0]); - APPSPAWN_CHECK(ret == 0, return ret, "DoAllSymlinkPointslink failed, %{public}s", - GetBundleName(appProperty)); - ret = HandleFlagsPoint(appProperty, privateAppConfig[g_ohosGpu][0]); - APPSPAWN_CHECK_ONLY_LOG(ret == 0, "HandleFlagsPoint for render-sandbox failed, %{public}s", - GetBundleName(appProperty)); - } - } - return 0; -} - -int32_t SandboxUtils::SetPrivateAppSandboxProperty(const AppSpawningCtx *appProperty) -{ - int ret = 0; - SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? - SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; - - for (auto& config : SandboxUtils::GetJsonConfig(type)) { - ret = SetPrivateAppSandboxProperty_(appProperty, config); - APPSPAWN_CHECK(ret == 0, return ret, "parse adddata-sandbox config failed"); - } - return ret; -} - -static bool GetSandboxPrivateSharedStatus(const string &bundleName, AppSpawningCtx *appProperty) -{ - bool result = false; - SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? - SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; - - for (auto& config : SandboxUtils::GetJsonConfig(type)) { - nlohmann::json& privateAppConfig = config[g_privatePrefix][0]; - if (privateAppConfig.find(bundleName) != privateAppConfig.end() && - privateAppConfig[bundleName][0].find(g_sandBoxShared) != - privateAppConfig[bundleName][0].end()) { - string sandboxSharedStatus = - privateAppConfig[bundleName][0][g_sandBoxShared].get(); - if (sandboxSharedStatus == g_statusCheck) { - result = true; - } - } - } - return result; -} - -int32_t SandboxUtils::SetPermissionAppSandboxProperty(AppSpawningCtx *appProperty) -{ - int ret = 0; - SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? - SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; - - for (auto& config : SandboxUtils::GetJsonConfig(type)) { - ret = SetPermissionAppSandboxProperty_(appProperty, config); - APPSPAWN_CHECK(ret == 0, return ret, "parse adddata-sandbox config failed"); - } - return ret; -} - - -int32_t SandboxUtils::SetCommonAppSandboxProperty_(const AppSpawningCtx *appProperty, - nlohmann::json &config) -{ - int rc = 0; - - rc = DoSandboxFileCommonBind(appProperty, config); - APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxFileCommonBind failed, %{public}s", GetBundleName(appProperty)); - - // if sandbox switch is off, don't do symlink work again - if (CheckAppSandboxSwitchStatus(appProperty) == true && (CheckTotalSandboxSwitchStatus(appProperty) == true)) { - rc = DoSandboxFileCommonSymlink(appProperty, config); - APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxFileCommonSymlink failed, %{public}s", GetBundleName(appProperty)); - } - - rc = DoSandboxFileCommonFlagsPointHandle(appProperty, config); - APPSPAWN_CHECK_ONLY_LOG(rc == 0, "DoSandboxFilePrivateFlagsPointHandle failed"); - - return rc; -} - -int32_t SandboxUtils::SetCommonAppSandboxProperty(const AppSpawningCtx *appProperty, - std::string &sandboxPackagePath) -{ - int ret = 0; - SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? - SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; - - for (auto& jsonConfig : SandboxUtils::GetJsonConfig(type)) { - ret = SetCommonAppSandboxProperty_(appProperty, jsonConfig); - APPSPAWN_CHECK(ret == 0, return ret, - "parse appdata config for common failed, %{public}s", sandboxPackagePath.c_str()); - } - - ret = MountAllHsp(appProperty, sandboxPackagePath); - APPSPAWN_CHECK(ret == 0, return ret, "mount extraInfo failed, %{public}s", sandboxPackagePath.c_str()); - - ret = MountAllGroup(appProperty, sandboxPackagePath); - APPSPAWN_CHECK(ret == 0, return ret, "mount groupList failed, %{public}s", sandboxPackagePath.c_str()); - - AppSpawnMsgDomainInfo *info = - reinterpret_cast(GetAppProperty(appProperty, TLV_DOMAIN_INFO)); - APPSPAWN_CHECK(info != nullptr, return -1, "No domain info %{public}s", sandboxPackagePath.c_str()); - if (strcmp(info->apl, APL_SYSTEM_BASIC.data()) == 0 || strcmp(info->apl, APL_SYSTEM_CORE.data()) == 0 || - CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ACCESS_BUNDLE_DIR)) { - // need permission check for system app here - std::string destbundlesPath = sandboxPackagePath + g_dataBundles; - SharedMountArgs arg = { - .srcPath = g_physicalAppInstallPath.c_str(), - .destPath = destbundlesPath.c_str() - }; - DoAppSandboxMountOnce(appProperty, &arg); - } - - return 0; -} - -static inline bool CheckPath(const std::string& name) -{ - return !name.empty() && name != "." && name != ".." && name.find("/") == std::string::npos; -} - -std::string SandboxUtils::GetExtraInfoByType(const AppSpawningCtx *appProperty, const std::string &type) -{ - uint32_t len = 0; - char *info = reinterpret_cast(GetAppPropertyExt(appProperty, type.c_str(), &len)); - if (info == nullptr) { - return ""; - } - return std::string(info, len); -} - -int32_t SandboxUtils::MountAllHsp(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath) -{ - int ret = 0; - string hspListInfo = GetExtraInfoByType(appProperty, HSPLIST_SOCKET_TYPE); - if (hspListInfo.length() == 0) { - return ret; - } - - nlohmann::json hsps = nlohmann::json::parse(hspListInfo.c_str(), nullptr, false); - APPSPAWN_CHECK(!hsps.is_discarded() && hsps.contains(g_hspList_key_bundles) && hsps.contains(g_hspList_key_modules) - && hsps.contains(g_hspList_key_versions), return -1, "MountAllHsp: json parse failed"); - - nlohmann::json& bundles = hsps[g_hspList_key_bundles]; - nlohmann::json& modules = hsps[g_hspList_key_modules]; - nlohmann::json& versions = hsps[g_hspList_key_versions]; - APPSPAWN_CHECK(bundles.is_array() && modules.is_array() && versions.is_array() && bundles.size() == modules.size() - && bundles.size() == versions.size(), return -1, "MountAllHsp: value is not arrary or sizes are not same"); - - APPSPAWN_LOGV("MountAllHsp: app = %{public}s, cnt = %{public}lu", - GetBundleName(appProperty), static_cast(bundles.size())); - for (uint32_t i = 0; i < bundles.size(); i++) { - // elements in json arrary can be different type - APPSPAWN_CHECK(bundles[i].is_string() && modules[i].is_string() && versions[i].is_string(), - return -1, "MountAllHsp: element type error"); - - std::string libBundleName = bundles[i]; - std::string libModuleName = modules[i]; - std::string libVersion = versions[i]; - APPSPAWN_CHECK(CheckPath(libBundleName) && CheckPath(libModuleName) && CheckPath(libVersion), - return -1, "MountAllHsp: path error"); - - std::string libPhysicalPath = g_physicalAppInstallPath + libBundleName + "/" + libVersion + "/" + libModuleName; - std::string mntPath = sandboxPackagePath + g_sandboxHspInstallPath + libBundleName + "/" + libModuleName; - SharedMountArgs arg = { - .srcPath = libPhysicalPath.c_str(), - .destPath = mntPath.c_str() - }; - ret = DoAppSandboxMountOnce(appProperty, &arg); - APPSPAWN_CHECK(ret == 0, return ret, "mount library failed %{public}d", ret); - } - return ret; -} - -int32_t SandboxUtils::DoSandboxRootFolderCreateAdapt(std::string &sandboxPackagePath) -{ -#ifndef APPSPAWN_TEST - int rc = mount(nullptr, "/", nullptr, MS_REC | MS_SLAVE, nullptr); - APPSPAWN_CHECK(rc == 0, return rc, "set propagation slave failed"); -#endif - MakeDirRecursive(sandboxPackagePath, FILE_MODE); - - // bind mount "/" to /mnt/sandbox// path - // rootfs: to do more resources bind mount here to get more strict resources constraints -#ifndef APPSPAWN_TEST - rc = mount("/", sandboxPackagePath.c_str(), nullptr, BASIC_MOUNT_FLAGS, nullptr); - APPSPAWN_CHECK(rc == 0, return rc, "mount bind / failed, %{public}d", errno); -#endif - return 0; -} - -int32_t SandboxUtils::MountAllGroup(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath) -{ - int ret = 0; - string dataGroupInfo = GetExtraInfoByType(appProperty, DATA_GROUP_SOCKET_TYPE); - if (dataGroupInfo.length() == 0) { - return ret; - } - - nlohmann::json groups = nlohmann::json::parse(dataGroupInfo.c_str(), nullptr, false); - if (groups.is_discarded() && groups.contains(g_groupList_key_dataGroupId) && groups.contains(g_groupList_key_dir) && - groups.contains(g_groupList_key_gid) && groups.contains(g_groupList_key_uuid)) { - APPSPAWN_LOGE("dataGroupJson is discarded"); - return APPSPAWN_ARG_INVALID; - } - - for (auto& item : groups) { - // elements in json arrary can be different type - APPSPAWN_CHECK(IsValidDataGroupItem(item), return -1, "MountAllGroup: data group item error"); - std::string srcPath = item[g_groupList_key_dir]; - APPSPAWN_CHECK(!CheckPath(srcPath), return -1, "MountAllGroup: path error"); - - int elxValue = GetElxInfoFromDir(srcPath.c_str()); - APPSPAWN_CHECK((elxValue >= EL2 && elxValue < ELX_MAX), return -1, "Get elx value failed"); - - const DataGroupSandboxPathTemplate *templateItem = GetDataGroupArgTemplate(elxValue); - APPSPAWN_CHECK(templateItem != nullptr, return -1, "Get data group arg template failed"); - - // If permission isn't null, need check permission flag - if (templateItem->permission != nullptr) { - int index = GetPermissionIndex(nullptr, templateItem->permission); - APPSPAWN_LOGV("mount dir no lock mount permission flag %{public}d", index); - if (CheckAppPermissionFlagSet(appProperty, static_cast(index)) == 0) { - continue; - } - } - - std::string dataGroupUuid = item[g_groupList_key_uuid]; - std::string mntPath = sandboxPackagePath + templateItem->sandboxPath + dataGroupUuid; - mode_t mountSharedFlag = MS_SLAVE; - if (CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX)) { - mountSharedFlag |= MS_REMOUNT | MS_NODEV | MS_RDONLY | MS_BIND; - } - SharedMountArgs arg = { - .srcPath = srcPath.c_str(), - .destPath = mntPath.c_str(), - .mountSharedFlag = mountSharedFlag - }; - ret = DoAppSandboxMountOnce(appProperty, &arg); - if (ret != 0) { - APPSPAWN_LOGE("mount el%{public}d datagroup failed", elxValue); - } - } - return 0; -} - -int32_t SandboxUtils::DoSandboxRootFolderCreate(const AppSpawningCtx *appProperty, - std::string &sandboxPackagePath) -{ -#ifndef APPSPAWN_TEST - int rc = mount(nullptr, "/", nullptr, MS_REC | MS_SLAVE, nullptr); - if (rc) { - return rc; - } -#endif - SharedMountArgs arg = { - .srcPath = sandboxPackagePath.c_str(), - .destPath = sandboxPackagePath.c_str() - }; - DoAppSandboxMountOnce(appProperty, &arg); - - return 0; -} - -uint32_t SandboxUtils::GetSandboxNsFlags(bool isNweb) -{ - uint32_t nsFlags = 0; - nlohmann::json appConfig; - const std::map NamespaceFlagsMap = { {"pid", CLONE_NEWPID}, - {"net", CLONE_NEWNET} }; - - if (!CheckTotalSandboxSwitchStatus(nullptr)) { - return nsFlags; - } - - for (auto& config : SandboxUtils::GetJsonConfig(SANBOX_APP_JSON_CONFIG)) { - if (isNweb) { - nlohmann::json& privateAppConfig = config[g_privatePrefix][0]; - if (privateAppConfig.find(g_ohosRender) == privateAppConfig.end()) { - continue; - } - appConfig = privateAppConfig[g_ohosRender][0]; - } else { - nlohmann::json& baseConfig = config[g_commonPrefix][0]; - if (baseConfig.find(g_appBase) == baseConfig.end()) { - continue; - } - appConfig = baseConfig[g_appBase][0]; - } - if (appConfig.find(g_sandBoxNsFlags) == appConfig.end()) { - continue; - } - const auto vec = appConfig[g_sandBoxNsFlags].get>(); - for (unsigned int j = 0; j < vec.size(); j++) { - if (NamespaceFlagsMap.count(vec[j])) { - nsFlags |= NamespaceFlagsMap.at(vec[j]); - } - } - } - - if (!nsFlags) { - APPSPAWN_LOGE("config is not found %{public}s ns config", isNweb ? "Nweb" : "App"); - } - return nsFlags; -} - -bool SandboxUtils::CheckBundleNameForPrivate(const std::string &bundleName) -{ - if (bundleName.find(g_internal) != std::string::npos) { - return false; - } - return true; -} - -bool SandboxUtils::CheckTotalSandboxSwitchStatus(const AppSpawningCtx *appProperty) -{ - SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? - SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; - - for (auto& wholeConfig : SandboxUtils::GetJsonConfig(type)) { - if (wholeConfig.find(g_commonPrefix) == wholeConfig.end()) { - continue; - } - nlohmann::json& commonAppConfig = wholeConfig[g_commonPrefix][0]; - if (commonAppConfig.find(g_topSandBoxSwitchPrefix) != commonAppConfig.end()) { - std::string switchStatus = commonAppConfig[g_topSandBoxSwitchPrefix].get(); - return switchStatus == g_sbxSwitchCheck; - } - } - // default sandbox switch is on - return true; -} - -bool SandboxUtils::CheckAppSandboxSwitchStatus(const AppSpawningCtx *appProperty) -{ - bool rc = true; - SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? - SANBOX_ISOLATED_JSON_CONFIG : SANBOX_APP_JSON_CONFIG; - - for (auto& wholeConfig : SandboxUtils::GetJsonConfig(type)) { - if (wholeConfig.find(g_privatePrefix) == wholeConfig.end()) { - continue; - } - nlohmann::json& privateAppConfig = wholeConfig[g_privatePrefix][0]; - if (privateAppConfig.find(GetBundleName(appProperty)) != privateAppConfig.end()) { - nlohmann::json& appConfig = privateAppConfig[GetBundleName(appProperty)][0]; - rc = GetSbxSwitchStatusByConfig(appConfig); - if (rc) { - break; - } - } - } - // default sandbox switch is on - return rc; -} - -static int CheckBundleName(const std::string &bundleName) -{ - if (bundleName.empty() || bundleName.size() > APP_LEN_BUNDLE_NAME) { - return -1; - } - if (bundleName.find('\\') != std::string::npos || bundleName.find('/') != std::string::npos) { - return -1; - } - return 0; -} - -int32_t SandboxUtils::SetOverlayAppSandboxProperty(const AppSpawningCtx *appProperty, - string &sandboxPackagePath) -{ - int ret = 0; - if (!CheckAppMsgFlagsSet(appProperty, APP_FLAGS_OVERLAY)) { - return ret; - } - - string overlayInfo = GetExtraInfoByType(appProperty, OVERLAY_SOCKET_TYPE); - set mountedSrcSet; - vector splits = split(overlayInfo, g_overlayDecollator); - string sandboxOverlayPath = sandboxPackagePath + g_overlayPath; - for (auto hapPath : splits) { - size_t pathIndex = hapPath.find_last_of(g_fileSeparator); - if (pathIndex == string::npos) { - continue; - } - std::string srcPath = hapPath.substr(0, pathIndex); - if (mountedSrcSet.find(srcPath) != mountedSrcSet.end()) { - APPSPAWN_LOGV("%{public}s have mounted before, no need to mount twice.", srcPath.c_str()); - continue; - } - - auto bundleNameIndex = srcPath.find_last_of(g_fileSeparator); - string destPath = sandboxOverlayPath + srcPath.substr(bundleNameIndex + 1, srcPath.length()); - SharedMountArgs arg = { - .srcPath = srcPath.c_str(), - .destPath = destPath.c_str() - }; - int32_t retMount = DoAppSandboxMountOnce(appProperty, &arg); - if (retMount != 0) { - APPSPAWN_LOGE("fail to mount overlay path, src is %{public}s.", hapPath.c_str()); - ret = retMount; - } - - mountedSrcSet.emplace(srcPath); - } - return ret; -} - -int32_t SandboxUtils::SetBundleResourceAppSandboxProperty(const AppSpawningCtx *appProperty, - string &sandboxPackagePath) -{ - if (!CheckAppMsgFlagsSet(appProperty, APP_FLAGS_BUNDLE_RESOURCES)) { - return 0; - } - - string destPath = sandboxPackagePath + g_bundleResourceDestPath; - SharedMountArgs arg = { - .srcPath = g_bundleResourceSrcPath.c_str(), - .destPath = destPath.c_str() - }; - return DoAppSandboxMountOnce(appProperty, &arg); -} - -int32_t SandboxUtils::CheckAppFullMountEnable() -{ - if (deviceTypeEnable_ != -1) { - return deviceTypeEnable_; - } - - char value[] = "false"; - int32_t ret = GetParameter("const.filemanager.full_mount.enable", "false", value, sizeof(value)); - if (ret > 0 && (strcmp(value, "true")) == 0) { - deviceTypeEnable_ = FILE_CROSS_APP_STATUS; - } else if (ret > 0 && (strcmp(value, "false")) == 0) { - deviceTypeEnable_ = FILE_ACCESS_COMMON_DIR_STATUS; - } else { - deviceTypeEnable_ = -1; - } - - return deviceTypeEnable_; -} - -int32_t SandboxUtils::SetSandboxProperty(AppSpawningCtx *appProperty, std::string &sandboxPackagePath) -{ - int32_t ret = 0; - const std::string bundleName = GetBundleName(appProperty); - ret = SetCommonAppSandboxProperty(appProperty, sandboxPackagePath); - APPSPAWN_CHECK(ret == 0, return ret, "SetCommonAppSandboxProperty failed, packagename is %{public}s", - bundleName.c_str()); - if (CheckBundleNameForPrivate(bundleName)) { - ret = SetPrivateAppSandboxProperty(appProperty); - APPSPAWN_CHECK(ret == 0, return ret, "SetPrivateAppSandboxProperty failed, packagename is %{public}s", - bundleName.c_str()); - } - ret = SetPermissionAppSandboxProperty(appProperty); - APPSPAWN_CHECK(ret == 0, return ret, "SetPermissionAppSandboxProperty failed, packagename is %{public}s", - bundleName.c_str()); - - ret = SetOverlayAppSandboxProperty(appProperty, sandboxPackagePath); - APPSPAWN_CHECK(ret == 0, return ret, "SetOverlayAppSandboxProperty failed, packagename is %{public}s", - bundleName.c_str()); - - ret = SetBundleResourceAppSandboxProperty(appProperty, sandboxPackagePath); - APPSPAWN_CHECK(ret == 0, return ret, "SetBundleResourceAppSandboxProperty failed, packagename is %{public}s", - bundleName.c_str()); - APPSPAWN_LOGV("Set appsandbox property success"); - return ret; -} - -int32_t SandboxUtils::ChangeCurrentDir(std::string &sandboxPackagePath, const std::string &bundleName, - bool sandboxSharedStatus) -{ - int32_t ret = 0; - ret = chdir(sandboxPackagePath.c_str()); - APPSPAWN_CHECK(ret == 0, return ret, "chdir failed, packagename is %{public}s, path is %{public}s", - bundleName.c_str(), sandboxPackagePath.c_str()); - - if (sandboxSharedStatus) { - ret = chroot(sandboxPackagePath.c_str()); - APPSPAWN_CHECK(ret == 0, return ret, "chroot failed, path is %{public}s errno is %{public}d", - sandboxPackagePath.c_str(), errno); - return ret; - } - - ret = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str()); - APPSPAWN_CHECK(ret == 0, return ret, "errno is %{public}d, pivot root failed, packagename is %{public}s", - errno, bundleName.c_str()); - - ret = umount2(".", MNT_DETACH); - APPSPAWN_CHECK(ret == 0, return ret, "MNT_DETACH failed, packagename is %{public}s", bundleName.c_str()); - return ret; -} - -static int EnableSandboxNamespace(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags) -{ -#ifdef APPSPAWN_HISYSEVENT - struct timespec startClock = {0}; - clock_gettime(CLOCK_MONOTONIC, &startClock); -#endif - int rc = unshare(sandboxNsFlags); -#ifdef APPSPAWN_HISYSEVENT - struct timespec endClock = {0}; - clock_gettime(CLOCK_MONOTONIC, &endClock); - uint64_t diff = DiffTime(&startClock, &endClock); - APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION, ReportAbnormalDuration("unshare", diff)); -#endif - APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", GetBundleName(appProperty)); - - if ((sandboxNsFlags & CLONE_NEWNET) == CLONE_NEWNET) { - rc = EnableNewNetNamespace(); - APPSPAWN_CHECK(rc == 0, return rc, "Set new netnamespace failed %{public}s", GetBundleName(appProperty)); - } - return 0; -} - -void SandboxUtils::UpdateMsgFlagsWithPermission(AppSpawningCtx *appProperty) -{ - int32_t processIndex = GetPermissionIndex(nullptr, GET_ALL_PROCESSES_MODE.c_str()); - if ((CheckAppPermissionFlagSet(appProperty, static_cast(processIndex)) == 0)) { - APPSPAWN_LOGV("Don't need set GET_ALL_PROCESSES_MODE flag"); - return; - } - - int ret = SetAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_GET_ALL_PROCESSES); - if (ret != 0) { - APPSPAWN_LOGV("Set GET_ALL_PROCESSES_MODE flag failed"); - } -} - -int32_t SandboxUtils::UpdatePermissionFlags(AppSpawningCtx *appProperty) -{ - int32_t index = 0; - int32_t appFullMountStatus = CheckAppFullMountEnable(); - if (appFullMountStatus == FILE_CROSS_APP_STATUS) { - index = GetPermissionIndex(nullptr, FILE_CROSS_APP_MODE.c_str()); - } else if (appFullMountStatus == FILE_ACCESS_COMMON_DIR_STATUS) { - index = GetPermissionIndex(nullptr, FILE_ACCESS_COMMON_DIR_MODE.c_str()); - } - int32_t userFileIndex = GetPermissionIndex(nullptr, READ_WRITE_USER_FILE_MODE.c_str()); - int32_t fileMgrIndex = GetPermissionIndex(nullptr, FILE_ACCESS_MANAGER_MODE.c_str()); - if ((CheckAppPermissionFlagSet(appProperty, static_cast(userFileIndex)) != 0) && - (CheckAppPermissionFlagSet(appProperty, static_cast(fileMgrIndex)) != 0)) { - APPSPAWN_LOGE("invalid msg request."); - return -1; - } - if (index > 0 && (fileMgrIndex > 0 && userFileIndex > 0) && - (CheckAppPermissionFlagSet(appProperty, static_cast(userFileIndex)) == 0) && - (CheckAppPermissionFlagSet(appProperty, static_cast(fileMgrIndex)) == 0)) { - return SetAppPermissionFlags(appProperty, index); - } - return 0; -} - -#ifdef APPSPAWN_MOUNT_TMPSHM -void SandboxUtils::MountDevShmPath(std::string &sandboxPath) -{ - std::string sandboxDevShmPath = sandboxPath + DEV_SHM_DIR; - int result = mount("tmpfs", sandboxDevShmPath.c_str(), "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV, "size=32M"); - if (result != 0) { - APPSPAWN_LOGW("Error mounting %{public}s to tmpfs, errno %{public}d", sandboxDevShmPath.c_str(), errno); - } -} -#endif - -int32_t SandboxUtils::SetAppSandboxProperty(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags) -{ - APPSPAWN_CHECK(appProperty != nullptr, return -1, "Invalid appspwn client"); - if (CheckBundleName(GetBundleName(appProperty)) != 0) { - return -1; - } - AppSpawnMsgDacInfo *dacInfo = reinterpret_cast(GetAppProperty(appProperty, TLV_DAC_INFO)); - if (dacInfo == nullptr) { - return -1; - } - - const std::string bundleName = GetBundleName(appProperty); - nlohmann::json tmpJson = {}; - std::string sandboxPackagePath = GetSbxPathByConfig(appProperty, tmpJson); - MakeDirRecursiveWithClock(sandboxPackagePath.c_str(), FILE_MODE); - bool sandboxSharedStatus = GetSandboxPrivateSharedStatus(bundleName, appProperty) || - (CheckAppPermissionFlagSet(appProperty, static_cast(GetPermissionIndex(nullptr, - ACCESS_DLP_FILE_MODE.c_str()))) != 0); - - // add pid to a new mnt namespace - int rc = EnableSandboxNamespace(appProperty, sandboxNsFlags); - APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", bundleName.c_str()); - if (UpdatePermissionFlags(appProperty) != 0) { - APPSPAWN_LOGW("Set app permission flag fail."); - return -1; - } - UpdateMsgFlagsWithPermission(appProperty); - // check app sandbox switch - if ((CheckTotalSandboxSwitchStatus(appProperty) == false) || - (CheckAppSandboxSwitchStatus(appProperty) == false)) { - rc = DoSandboxRootFolderCreateAdapt(sandboxPackagePath); - } else if (!sandboxSharedStatus) { - rc = DoSandboxRootFolderCreate(appProperty, sandboxPackagePath); - } - APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxRootFolderCreate failed, %{public}s", bundleName.c_str()); - rc = SetSandboxProperty(appProperty, sandboxPackagePath); - APPSPAWN_CHECK(rc == 0, return rc, "SetSandboxProperty failed, %{public}s", bundleName.c_str()); - -#ifdef APPSPAWN_MOUNT_TMPSHM - MountDevShmPath(sandboxPackagePath); -#endif - -#ifndef APPSPAWN_TEST - rc = ChangeCurrentDir(sandboxPackagePath, bundleName, sandboxSharedStatus); - APPSPAWN_CHECK(rc == 0, return rc, "change current dir failed"); - APPSPAWN_LOGV("Change root dir success"); -#if defined(APPSPAWN_MOUNT_TMPSHM) && defined(WITH_SELINUX) - Restorecon(DEV_SHM_DIR); -#endif // APPSPAWN_MOUNT_TMPSHM && WITH_SELINUX -#endif // APPSPAWN_TEST - return 0; -} - -int32_t SandboxUtils::SetAppSandboxPropertyNweb(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags) -{ - APPSPAWN_CHECK(appProperty != nullptr, return -1, "Invalid appspwn client"); - if (CheckBundleName(GetBundleName(appProperty)) != 0) { - return -1; - } - std::string sandboxPackagePath = g_sandBoxRootDirNweb; - const std::string bundleName = GetBundleName(appProperty); - bool sandboxSharedStatus = GetSandboxPrivateSharedStatus(bundleName, appProperty); - sandboxPackagePath += bundleName; - MakeDirRecursiveWithClock(sandboxPackagePath.c_str(), FILE_MODE); - - // add pid to a new mnt namespace - int rc = EnableSandboxNamespace(appProperty, sandboxNsFlags); - APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", bundleName.c_str()); - - // check app sandbox switch - if ((CheckTotalSandboxSwitchStatus(appProperty) == false) || - (CheckAppSandboxSwitchStatus(appProperty) == false)) { - rc = DoSandboxRootFolderCreateAdapt(sandboxPackagePath); - } else if (!sandboxSharedStatus) { - rc = DoSandboxRootFolderCreate(appProperty, sandboxPackagePath); - } - APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxRootFolderCreate failed, %{public}s", bundleName.c_str()); - // rendering process can be created by different apps, - // and the bundle names of these apps are different, - // so we can't use the method SetPrivateAppSandboxProperty - // which mount dirs by using bundle name. - rc = SetRenderSandboxPropertyNweb(appProperty, sandboxPackagePath); - APPSPAWN_CHECK(rc == 0, return rc, "SetRenderSandboxPropertyNweb failed, packagename is %{public}s", - sandboxPackagePath.c_str()); - - rc = SetOverlayAppSandboxProperty(appProperty, sandboxPackagePath); - APPSPAWN_CHECK(rc == 0, return rc, "SetOverlayAppSandboxProperty failed, packagename is %{public}s", - bundleName.c_str()); - - rc = SetBundleResourceAppSandboxProperty(appProperty, sandboxPackagePath); - APPSPAWN_CHECK(rc == 0, return rc, "SetBundleResourceAppSandboxProperty failed, packagename is %{public}s", - bundleName.c_str()); - -#ifndef APPSPAWN_TEST - rc = chdir(sandboxPackagePath.c_str()); - APPSPAWN_CHECK(rc == 0, return rc, "chdir failed, packagename is %{public}s, path is %{public}s", - bundleName.c_str(), sandboxPackagePath.c_str()); - - if (sandboxSharedStatus) { - rc = chroot(sandboxPackagePath.c_str()); - APPSPAWN_CHECK(rc == 0, return rc, "chroot failed, path is %{public}s errno is %{public}d", - sandboxPackagePath.c_str(), errno); - return 0; - } - - rc = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str()); - APPSPAWN_CHECK(rc == 0, return rc, "errno is %{public}d, pivot root failed, packagename is %{public}s", - errno, bundleName.c_str()); - - rc = umount2(".", MNT_DETACH); - APPSPAWN_CHECK(rc == 0, return rc, "MNT_DETACH failed, packagename is %{public}s", bundleName.c_str()); -#endif - return 0; -} -} // namespace AppSpawn -} // namespace OHOS - -static bool AppSandboxPidNsIsSupport(void) -{ - char buffer[10] = {0}; - uint32_t buffSize = sizeof(buffer); - - if (SystemGetParameter("const.sandbox.pidns.support", buffer, &buffSize) != 0) { - return true; - } - if (!strcmp(buffer, "false")) { - return false; - } - return true; -} - -int LoadAppSandboxConfig(AppSpawnMgr *content) -{ - bool rc = true; - // load sandbox config - nlohmann::json appSandboxConfig; - CfgFiles *files = GetCfgFiles("etc/sandbox"); - for (int i = 0; (files != nullptr) && (i < MAX_CFG_POLICY_DIRS_CNT); ++i) { - if (files->paths[i] == nullptr) { - continue; - } - std::string path = files->paths[i]; - std::string appPath = path + OHOS::AppSpawn::APP_JSON_CONFIG; - APPSPAWN_LOGI("LoadAppSandboxConfig %{public}s", appPath.c_str()); - rc = OHOS::AppSpawn::JsonUtils::GetJsonObjFromJson(appSandboxConfig, appPath); - APPSPAWN_CHECK(rc, continue, "Failed to load app data sandbox config %{public}s", appPath.c_str()); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(appSandboxConfig, SANBOX_APP_JSON_CONFIG); - - std::string isolatedPath = path + OHOS::AppSpawn::APP_ISOLATED_JSON_CONFIG; - APPSPAWN_LOGI("LoadAppSandboxConfig %{public}s", isolatedPath.c_str()); - rc = OHOS::AppSpawn::JsonUtils::GetJsonObjFromJson(appSandboxConfig, isolatedPath); - APPSPAWN_CHECK(rc, continue, "Failed to load app data sandbox config %{public}s", isolatedPath.c_str()); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(appSandboxConfig, SANBOX_ISOLATED_JSON_CONFIG); - } - FreeCfgFiles(files); - bool isNweb = IsNWebSpawnMode(content); - if (!isNweb && !AppSandboxPidNsIsSupport()) { - return 0; - } - content->content.sandboxNsFlags = OHOS::AppSpawn::SandboxUtils::GetSandboxNsFlags(isNweb); - return 0; -} - -static bool NeedNetworkIsolated(AppSpawningCtx *property) -{ - int developerMode = IsDeveloperModeOpen(); - if (CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX) && !developerMode) { - return true; - } - - if (CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_NETWORK)) { - std::string extensionType = - OHOS::AppSpawn::SandboxUtils::GetExtraInfoByType(property, MSG_EXT_NAME_EXTENSION_TYPE); - if (extensionType.length() == 0 || !developerMode) { - return true; - } - } - - return false; -} - -int32_t SetAppSandboxProperty(AppSpawnMgr *content, AppSpawningCtx *property) -{ - APPSPAWN_CHECK(property != nullptr, return -1, "Invalid appspwn client"); - APPSPAWN_CHECK(content != nullptr, return -1, "Invalid appspwn content"); - // clear g_mountInfo in the child process - std::map* mapPtr = static_cast*>(GetEl1BundleMountCount()); - if (mapPtr == nullptr) { - APPSPAWN_LOGE("Get el1 bundle mount count failed"); - return APPSPAWN_ARG_INVALID; - } - mapPtr->clear(); - int ret = 0; - // no sandbox - if (CheckAppMsgFlagsSet(property, APP_FLAGS_NO_SANDBOX)) { - return 0; - } - if ((content->content.sandboxNsFlags & CLONE_NEWPID) == CLONE_NEWPID) { - ret = getprocpid(); - if (ret < 0) { - return ret; - } - } - uint32_t sandboxNsFlags = CLONE_NEWNS; - - if (NeedNetworkIsolated(property)) { - sandboxNsFlags |= content->content.sandboxNsFlags & CLONE_NEWNET ? CLONE_NEWNET : 0; - } - - APPSPAWN_LOGV("SetAppSandboxProperty sandboxNsFlags 0x%{public}x", sandboxNsFlags); - - if (IsNWebSpawnMode(content)) { - ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxPropertyNweb(property, sandboxNsFlags); - } else { - ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(property, sandboxNsFlags); - } - // for module test do not create sandbox, use APP_FLAGS_IGNORE_SANDBOX to ignore sandbox result - if (CheckAppMsgFlagsSet(property, APP_FLAGS_IGNORE_SANDBOX)) { - APPSPAWN_LOGW("Do not care sandbox result %{public}d", ret); - return 0; - } - return ret; -} - -#define USER_ID_SIZE 16 -#define DIR_MODE 0711 - -static int SpawnMountDirToShared(AppSpawnMgr *content, AppSpawningCtx *property) -{ -#ifndef APPSPAWN_SANDBOX_NEW - if (!IsNWebSpawnMode(content)) { - // mount dynamic directory - MountToShared(content, property); - } -#endif - return 0; -} - -static void UmountDir(const char *rootPath, const char *targetPath, const AppSpawnedProcessInfo *appInfo) -{ - size_t allPathSize = strlen(rootPath) + USER_ID_SIZE + strlen(appInfo->name) + strlen(targetPath) + 2; - char *path = reinterpret_cast(malloc(sizeof(char) * (allPathSize))); - APPSPAWN_CHECK(path != NULL, return, "Failed to malloc path"); - - int ret = sprintf_s(path, allPathSize, "%s%u/%s%s", rootPath, appInfo->uid / UID_BASE, - appInfo->name, targetPath); - APPSPAWN_CHECK(ret > 0 && ((size_t)ret < allPathSize), free(path); - return, "Failed to get sandbox path errno %{public}d", errno); - - ret = umount2(path, MNT_DETACH); - if (ret == 0) { - APPSPAWN_LOGI("Umount2 sandbox path %{public}s success", path); - } else { - APPSPAWN_LOGW("Failed to umount2 sandbox path %{public}s errno %{public}d", path, errno); - } - free(path); -} - -static int UmountSandboxPath(const AppSpawnMgr *content, const AppSpawnedProcessInfo *appInfo) -{ - APPSPAWN_CHECK(content != NULL && appInfo != NULL && appInfo->name != NULL, - return -1, "Invalid content or appInfo"); - if (!IsAppSpawnMode(content)) { - return 0; - } - APPSPAWN_LOGV("UmountSandboxPath name %{public}s pid %{public}d", appInfo->name, appInfo->pid); - const char rootPath[] = "/mnt/sandbox/"; - const char el1Path[] = "/data/storage/el1/bundle"; - - std::string varBundleName = std::string(appInfo->name); - if (appInfo->appIndex > 0) { - varBundleName = "+clone-" + std::to_string(appInfo->appIndex) + "+" + varBundleName; - } - - uint32_t userId = appInfo->uid / UID_BASE; - std::string key = std::to_string(userId) + "-" + varBundleName; - map *el1BundleCountMap = static_cast*>(GetEl1BundleMountCount()); - if (el1BundleCountMap == nullptr || el1BundleCountMap->find(key) == el1BundleCountMap->end()) { - return 0; - } - (*el1BundleCountMap)[key]--; - if ((*el1BundleCountMap)[key] == 0) { - APPSPAWN_LOGV("no app %{public}s use it in userId %{public}u, need umount", appInfo->name, userId); - UmountDir(rootPath, el1Path, appInfo); - el1BundleCountMap->erase(key); - } else { - APPSPAWN_LOGV("app %{public}s use it mount times %{public}d in userId %{public}u, not need umount", - appInfo->name, (*el1BundleCountMap)[key], userId); - } - return 0; -} - -#ifndef APPSPAWN_SANDBOX_NEW -MODULE_CONSTRUCTOR(void) -{ - APPSPAWN_LOGV("Load sandbox module ..."); - (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, LoadAppSandboxConfig); - (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_COMMON, SpawnMountDirToShared); - (void)AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_SANDBOX, SetAppSandboxProperty); - (void)AddProcessMgrHook(STAGE_SERVER_APP_UMOUNT, HOOK_PRIO_SANDBOX, UmountSandboxPath); -} -#endif diff --git a/nwebspawn.cfg b/nwebspawn.cfg new file mode 100644 index 0000000000000000000000000000000000000000..6777a5f0dfea48333f8a428e12f8de4cff174631 --- /dev/null +++ b/nwebspawn.cfg @@ -0,0 +1,37 @@ +{ + "jobs" : [{ + "name" : "param:bootevent.boot.completed", + "condition" : "bootevent.boot.completed=true", + "cmds" : [ + "start nwebspawn" + ] + } + ], + "services" : [{ + "name" : "nwebspawn", + "path" : ["/system/bin/nwebspawn", + "-mode nwebspawn", + "--process-name com.ohos.nwebspawn.startup --start-flags daemon --type standard ", + "--sandbox-switch on --bundle-name com.ohos.nwebspawn.startup --app-operate-type operate ", + "--render-command command --app-launch-type singleton --app-visible true"], + "uid" : "nwebspawn", + "gid" : ["nwebspawn"], + "setuid" : true, + "caps" : ["CAP_SYS_ADMIN", "CAP_SETGID", "CAP_SETUID", "CAP_KILL"], + "socket" : [{ + "name" : "NWebSpawn", + "family" : "AF_LOCAL", + "type" : "SOCK_STREAM", + "protocol" : "default", + "permissions" : "0666", + "uid" : "nwebspawn", + "gid" : "nwebspawn", + "option" : [ + ] + }], + "start_mode" : "condition", + "sandbox" : 0, + "secon" : "u:r:nwebspawn:s0" + } + ] +} \ No newline at end of file diff --git a/service/hnp/base/hnp_base.h b/service/hnp/base/hnp_base.h index 5129a0de0d9793e3c2b49818a23d972d41947b03..f296384ba5e88dda58cd4f1b5bbd0b63213856f8 100644 --- a/service/hnp/base/hnp_base.h +++ b/service/hnp/base/hnp_base.h @@ -327,6 +327,21 @@ char *HnpCurrentVersionGet(const char *name); HILOG_ERROR(LOG_CORE, "[%{public}s:%{public}d]" args, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__); \ HnpLogPrintf(HNP_LOG_ERROR, "HNP", "[%{public}s:%{public}d]" args, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__) #endif +#define HNP_ERROR_CHECK(ret, statement, format, ...) \ + do { \ + if (!(ret)) { \ + HNP_LOGE(format, ##__VA_ARGS__); \ + statement; \ + } \ + } while (0) + +#define HNP_INFO_CHECK(ret, statement, format, ...) \ + do { \ + if (!(ret)) { \ + HNP_LOGI(format, ##__VA_ARGS__); \ + statement; \ + } \ + } while (0) #ifdef __cplusplus } diff --git a/service/hnp/installer/src/hnp_installer.c b/service/hnp/installer/src/hnp_installer.c index c8bee46446842598bde023d918cd4f82c7f2b428..c9658e8aae680d445b27531447aa7d53a919e335 100644 --- a/service/hnp/installer/src/hnp_installer.c +++ b/service/hnp/installer/src/hnp_installer.c @@ -197,6 +197,55 @@ static int HnpInstall(const char *hnpFile, HnpInstallInfo *hnpInfo, HnpCfgInfo * return HnpGenerateSoftLink(hnpInfo->hnpVersionPath, hnpInfo->hnpBasePath, hnpCfg); } +/** + * 删除 ../hnppublic/bin目录下所有失效的hnp + */ +APPSPAWN_STATIC void ClearSoftLink(int uid) +{ + char path[MAX_FILE_PATH_LEN] = {0}; + ssize_t bytes = snprintf_s(path, MAX_FILE_PATH_LEN, MAX_FILE_PATH_LEN - 1, + HNP_DEFAULT_INSTALL_ROOT_PATH"/%d/hnppublic/bin", uid); + HNP_ERROR_CHECK(bytes > 0, return, + "Build bin path failed %{public}d %{public}zd", uid, bytes); + + DIR *dir = opendir(path); + HNP_ERROR_CHECK(dir != NULL, return, + "open bin path failed %{public}s %{public}d", path, errno); + + struct dirent *entry; + int count = 0; + while ((entry = readdir(dir)) != NULL) { + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { + continue; + } + count++; + HNP_INFO_CHECK(entry->d_type == DT_LNK, continue, + "not lnk file %s skip to next", entry->d_name); + + char sourcePath[MAX_FILE_PATH_LEN] = {0}; + bytes = snprintf_s(sourcePath, MAX_FILE_PATH_LEN, MAX_FILE_PATH_LEN - 1, + "%s/%s", path, entry->d_name); + HNP_ERROR_CHECK(bytes > 0, continue, + "build soft link path failed %{public}s", entry->d_name); + + char targetPath[MAX_FILE_PATH_LEN] = {0}; + bytes = readlink(sourcePath, targetPath, MAX_FILE_PATH_LEN); + HNP_ERROR_CHECK(bytes > 0, continue, "readlink failed %{public}s", sourcePath); + + char linkPath[MAX_FILE_PATH_LEN] = {0}; + bytes = snprintf_s(linkPath, MAX_FILE_PATH_LEN, MAX_FILE_PATH_LEN - 1, + "%s/%s", path, targetPath); + HNP_ERROR_CHECK(bytes > 0, continue, "build link file source path failed %{public}s", targetPath); + + if (access(linkPath, F_OK) != 0) { + int ret = unlink(sourcePath); + HNP_LOGI("unlink file %{public}s %{public}d", sourcePath, ret); + } + } + HNP_LOGI("file count is %d", count); + closedir(dir); +} + /** * 卸载公共hnp. * @@ -249,6 +298,7 @@ static int HnpUnInstallPublicHnp(const char* packageName, const char *name, cons } if (HnpPathFileCount(hnpNamePath) == 0) { + ClearSoftLink(uid); return HnpDeleteFolder(hnpNamePath); } diff --git a/standard/BUILD.gn b/standard/BUILD.gn index e9c5b1ec1b4539e41171553b636a035b4956f822..779676dc5a73a6876ea528c2268bc181d750252c 100644 --- a/standard/BUILD.gn +++ b/standard/BUILD.gn @@ -307,3 +307,89 @@ ohos_prebuilt_etc("nativespawn.rc") { subsystem_name = "${subsystem_name}" part_name = "${part_name}" } + +# to support nwebspawn +ohos_executable("nwebspawn") { + sources = [ + "${appspawn_path}/common/appspawn_server.c", + "${appspawn_path}/common/appspawn_trace.cpp", + "${appspawn_path}/modules/common/appspawn_dfx_dump.cpp", + "${appspawn_path}/modules/modulemgr/appspawn_modulemgr.c", + "${appspawn_path}/standard/appspawn_appmgr.c", + "${appspawn_path}/standard/appspawn_kickdog.c", + "${appspawn_path}/standard/appspawn_main.c", + "${appspawn_path}/standard/appspawn_msgmgr.c", + "${appspawn_path}/standard/appspawn_service.c", + "${appspawn_path}/standard/nwebspawn_launcher.c", + ] + + defines = ["NWEB_SPAWN"] + configs = [ + ":appspawn_server_config", + "${appspawn_path}:appspawn_config", + ] + deps = [ + "${appspawn_path}/modules/module_engine:libappspawn_stub_versionscript", + "${appspawn_path}/util:libappspawn_util", + ] + if (asan_detector || is_asan) { + defines += [ "ASAN_DETECTOR" ] + } + if (is_debug || build_variant == "root") { + defines += [ "DEBUG_BEGETCTL_BOOT" ] + } + if (appspawn_support_prefork) { + defines += [ "APPSPAWN_SUPPORT_PREFORK" ] + } + + external_deps = [ + "cJSON:cjson", + "c_utils:utils", + "config_policy:configpolicy_util", + "ffrt:libffrt", + "hilog:libhilog", + "hitrace:hitrace_meter", + "init:libbegetutil", + ] + if (enable_appspawn_dump_catcher) { + external_deps += [ "faultloggerd:libdfx_dumpcatcher" ] + } + + if (appspawn_report_event) { + defines += [ "APPSPAWN_HISYSEVENT" ] + external_deps += [ "hisysevent:libhisysevent" ] + sources += [ + "${appspawn_path}/modules/sysevent/appspawn_hisysevent.cpp", + "${appspawn_path}/modules/sysevent/hisysevent_adapter.cpp", + ] + } + if (build_selinux) { + defines += [ "WITH_SELINUX" ] + external_deps += [ + "selinux:libselinux", + "selinux_adapter:libhap_restorecon", + ] + } + cflags = [] + + if (defined(appspawn_sandbox_new) && appspawn_sandbox_new) { + defines += [ "APPSPAWN_SANDBOX_NEW" ] + } + + #ldflags = [ "-Wl,--dynamic-linker,/system/bin/linker64z" ] + if (defined(global_parts_info) && + defined(global_parts_info.security_code_signature)) { + defines += [ "CODE_SIGNATURE_ENABLE" ] + external_deps += [ "code_signature:libcode_sign_attr_utils" ] + } + + version_script = get_label_info( + "${appspawn_path}/modules/module_engine:libappspawn_stub_versionscript", + "target_gen_dir") + "/" + get_label_info( + "${appspawn_path}/modules/module_engine:libappspawn_stub_versionscript", + "name") + stub_version_script_suffix + + install_enable = true + subsystem_name = "${subsystem_name}" + part_name = "${part_name}" +} diff --git a/standard/appspawn_kickdog.c b/standard/appspawn_kickdog.c index 04a7db138c948d06e14b057fb46df161a47d273e..a471c7d12a26a4273964f53f20cb4548ae1b6f4c 100644 --- a/standard/appspawn_kickdog.c +++ b/standard/appspawn_kickdog.c @@ -73,9 +73,9 @@ static void DealSpawnWatchdog(AppSpawnContent *content, bool isOpen) if (isOpen) { content->wdgOpened = (result != -1); } - APPSPAWN_LOGI("%{public}s %{public}s %{public}s watchdog end,result:%{public}d", - content->isLinux ? "Linux" : "Hm", (content->mode == MODE_FOR_NWEB_SPAWN) ? - "Nwebspawn" : "Appspawn", isOpen ? "enable" : "kick", result); + APPSPAWN_DUMP_LOGI("%{public}s %{public}s %{public}d", + (content->mode == MODE_FOR_NWEB_SPAWN) ? + "Nweb" : "Apps", isOpen ? "enable" : "kick", result); } static void ProcessTimerHandle(const TimerHandle taskHandle, void *context) diff --git a/standard/appspawn_main.c b/standard/appspawn_main.c index 2f87220cb899694524c54c98c51d2666473ff8b5..df5fe79f011b8e226c2ca7380164794f9226c2c4 100644 --- a/standard/appspawn_main.c +++ b/standard/appspawn_main.c @@ -77,7 +77,7 @@ static void CheckPreload(char *const argv[]) #ifndef NATIVE_SPAWN static AppSpawnStartArgTemplate *GetAppSpawnStartArg(const char *serverName, AppSpawnStartArgTemplate *argTemplate, - int count) + AppSpawnStartArgTemplate *argTemp, int count) { for (int i = 0; i < count; i++) { if (strcmp(serverName, argTemplate[i].serverName) == 0) { @@ -85,7 +85,7 @@ static AppSpawnStartArgTemplate *GetAppSpawnStartArg(const char *serverName, App } } - return argTemplate; + return argTemp; } #endif @@ -112,15 +112,21 @@ int main(int argc, char *const argv[]) argTemp = &g_appCJSpawnStartArgTemplate[CJPROCESS_FOR_APP_SPAWN]; if (argc > MODE_VALUE_INDEX) { argTemp = GetAppSpawnStartArg(argv[MODE_VALUE_INDEX], g_appCJSpawnStartArgTemplate, - ARRAY_LENGTH(g_appCJSpawnStartArgTemplate)); + argTemp, ARRAY_LENGTH(g_appCJSpawnStartArgTemplate)); } #elif NATIVE_SPAWN argTemp = &g_appSpawnStartArgTemplate[PROCESS_FOR_NATIVE_SPAWN]; +#elif NWEB_SPAWN + argTemp = &g_appSpawnStartArgTemplate[PROCESS_FOR_NWEB_SPAWN]; + if (argc > MODE_VALUE_INDEX) { + argTemp = GetAppSpawnStartArg(argv[MODE_VALUE_INDEX], g_appSpawnStartArgTemplate, + argTemp, ARRAY_LENGTH(g_appSpawnStartArgTemplate)); + } #else argTemp = &g_appSpawnStartArgTemplate[PROCESS_FOR_APP_SPAWN]; if (argc > MODE_VALUE_INDEX) { argTemp = GetAppSpawnStartArg(argv[MODE_VALUE_INDEX], g_appSpawnStartArgTemplate, - ARRAY_LENGTH(g_appSpawnStartArgTemplate)); + argTemp, ARRAY_LENGTH(g_appSpawnStartArgTemplate)); } #endif arg = &argTemp->arg; diff --git a/standard/appspawn_manager.h b/standard/appspawn_manager.h index 4ddb4782469a45c56564808e6b9b78d54cca5e8f..39f6a785197dc3cc85fe8b166e2a176437f3c286 100644 --- a/standard/appspawn_manager.h +++ b/standard/appspawn_manager.h @@ -232,6 +232,9 @@ APPSPAWN_INLINE int IsColdRunMode(const AppSpawnMgr *content) APPSPAWN_INLINE int IsDeveloperModeOn(const AppSpawningCtx *property) { +#ifdef SUPPORT_LOCAL_DEBUGGER + return true; +#endif return (property != NULL && ((property->client.flags & APP_DEVELOPER_MODE) == APP_DEVELOPER_MODE)); } diff --git a/standard/appspawn_msgmgr.c b/standard/appspawn_msgmgr.c index 2e844d93a49d9f09810b90df8b0fae5b9ed63a07..51d9f8df2540d36b707290d91a72e25df0868a08 100644 --- a/standard/appspawn_msgmgr.c +++ b/standard/appspawn_msgmgr.c @@ -386,7 +386,7 @@ void DumpAppSpawnMsg(const AppSpawnMsgNode *message) APPSPAWN_DUMP("App dac info uid: %{public}d gid: %{public}d count: %{public}d", dacInfo->uid, dacInfo->gid, dacInfo->gidCount); for (uint32_t i = 0; i < dacInfo->gidCount; i++) { - APPSPAWN_DUMP("gid group[%{public}d]: %{public}d", i, dacInfo->gidTable[i]); + APPSPAWN_LOGV("gid group[%{public}d]: %{public}d", i, dacInfo->gidTable[i]); } } AppSpawnMsgBundleInfo *bundleInfo = (AppSpawnMsgBundleInfo *)GetAppSpawnMsgInfo(message, TLV_BUNDLE_INFO); diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index 001ddcbf27acccac44048752d7159d004e3ed1b2..fa68507df51868d5858f6e9c5c17e6384f2f833a 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -195,14 +195,6 @@ static void HandleDiedPid(pid_t pid, uid_t uid, int status) ProcessMgrHookExecute(STAGE_SERVER_APP_DIED, GetAppSpawnContent(), appInfo); ProcessMgrHookExecute(STAGE_SERVER_APP_UMOUNT, GetAppSpawnContent(), appInfo); - // if current process of death is nwebspawn, restart appspawn - if (strcmp(appInfo->name, NWEBSPAWN_SERVER_NAME) == 0) { - OH_ListRemove(&appInfo->node); - free(appInfo); - APPSPAWN_LOGW("Current process of death is nwebspawn, pid = %{public}d, restart appspawn", pid); - StopAppSpawn(); - return; - } // move app info to died queue in NWEBSPAWN, or delete appinfo TerminateSpawnedProcess(appInfo); } @@ -303,6 +295,7 @@ static int SendResponse(const AppSpawnConnection *connection, const AppSpawnMsg uint32_t bufferSize = sizeof(AppSpawnResponseMsg); BufferHandle handle = LE_CreateBuffer(LE_GetDefaultLoop(), bufferSize); AppSpawnResponseMsg *buffer = (AppSpawnResponseMsg *)LE_GetBufferInfo(handle, NULL, &bufferSize); + APPSPAWN_CHECK(buffer != NULL, return APPSPAWN_ERROR_UTILS_MEM_FAIL, "buffer is null"); int ret = memcpy_s(buffer, bufferSize, msg, sizeof(AppSpawnMsg)); APPSPAWN_CHECK(ret == 0, LE_FreeBuffer(LE_GetDefaultLoop(), NULL, handle); return -1, "Failed to memcpy_s bufferSize"); @@ -467,8 +460,8 @@ static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, connection->receiverCtx.incompleteMsg = NULL; int ret = 0; do { - APPSPAWN_LOGI("OnReceiveRequest connectionId: %{public}u start: 0x%{public}x buffLen %{public}d", - connection->connectionId, *(uint32_t *)(buffer + currLen), buffLen - currLen); + APPSPAWN_LOGI("connectionId:%{public}u buffLen:%{public}d", + connection->connectionId, buffLen - currLen); ret = GetAppSpawnMsgFromBuffer(buffer + currLen, buffLen - currLen, &message, &connection->receiverCtx.msgRecvLen, &reminder); @@ -1203,6 +1196,8 @@ APPSPAWN_STATIC int AppSpawnColdStartApp(struct AppSpawnContent *content, AppSpa char *path = property->forkCtx.coldRunPath != NULL ? property->forkCtx.coldRunPath : "/system/bin/cjappspawn"; #elif NATIVE_SPAWN char *path = property->forkCtx.coldRunPath != NULL ? property->forkCtx.coldRunPath : "/system/bin/nativespawn"; +#elif NWEB_SPAWN + char *path = property->forkCtx.coldRunPath != NULL ? property->forkCtx.coldRunPath : "/system/bin/nwebspawn"; #else char *path = property->forkCtx.coldRunPath != NULL ? property->forkCtx.coldRunPath : "/system/bin/appspawn"; #endif @@ -1395,20 +1390,7 @@ AppSpawnContent *StartSpawnService(const AppSpawnStartArg *startArg, uint32_t ar AppSpawnStartArg *arg = (AppSpawnStartArg *)startArg; APPSPAWN_LOGV("Start appspawn argvSize %{public}d mode %{public}d service %{public}s", argvSize, arg->mode, arg->serviceName); - if (arg->mode == MODE_FOR_APP_SPAWN) { -#ifndef APPSPAWN_TEST - pid = NWebSpawnLaunch(); - if (pid == 0) { - arg->socketName = NWEBSPAWN_SOCKET_NAME; - arg->serviceName = NWEBSPAWN_SERVER_NAME; - arg->moduleType = MODULE_NWEBSPAWN; - arg->mode = MODE_FOR_NWEB_SPAWN; - arg->initArg = 1; - } -#endif - } else if (arg->mode == MODE_FOR_NWEB_SPAWN && getuid() == 0) { - NWebSpawnInit(); - } + if (arg->initArg) { int ret = memset_s(argv[0], argvSize, 0, (size_t)argvSize); APPSPAWN_CHECK(ret == EOK, return NULL, "Failed to memset argv[0]"); @@ -1434,7 +1416,6 @@ AppSpawnContent *StartSpawnService(const AppSpawnStartArg *startArg, uint32_t ar #endif AddAppSpawnHook(STAGE_CHILD_PRE_RUN, HOOK_PRIO_LOWEST, AppSpawnClearEnv); if (arg->mode == MODE_FOR_APP_SPAWN) { - AddSpawnedProcess(pid, NWEBSPAWN_SERVER_NAME, 0, false); SetParameter("bootevent.appspawn.started", "true"); } return content; @@ -1597,7 +1578,7 @@ static void ProcessSpawnRestartMsg(AppSpawnConnection *connection, AppSpawnMsgNo } } - char *path = "/system/bin/appspawn"; + char *path = "/system/bin/nwebspawn"; char *mode = NWEBSPAWN_RESTART; const char *const formatCmds[] = {path, "-mode", mode, NULL}; ret = execv(path, (char **)formatCmds); diff --git a/test/BUILD.gn b/test/BUILD.gn index faf729d9c56f1840fdcbd2fe15711d336a872169..7679d78436aa4b6f06d2fb17f1ead29d136e6ed9 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -31,6 +31,7 @@ group("unittest") { deps += [ "unittest/app_spawn_standard_test:AppSpawn_coldrun_ut" ] } deps += [ "unittest/hnp_test:HnpTest" ] + deps += [ "unittest/single_test/hnp_installer:hnp_installer_test" ] deps += [ "unittest/devicedebug_test:DevicedebugTest" ] } else { testonly = true diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0100.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0100.json new file mode 100644 index 0000000000000000000000000000000000000000..680ba7fec8c5989c498e99b75d49eab04bbd29f0 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0100.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0100.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0100.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0100.py new file mode 100644 index 0000000000000000000000000000000000000000..cc5240317e819e0bcb59635c228e9b37bb5717c4 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0100.py @@ -0,0 +1,83 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn0100(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:首次获取nativesapwn进程号") + pid1 = self.driver.System.get_pid("nativespawn") + Step("步骤5:点击start Native Process Isolated按钮") + self.driver.touch(BY.text("start Native Process Isolated")) + Step("步骤6:第二次获取nativesapwn进程号") + pid2 = self.driver.System.get_pid("nativespawn") + Step("步骤7:关闭测试应用") + self.driver.stop_app("com.acts.childprocessmanager") + Step("步骤8:第三次获取nativesapwn进程号") + pid3 = self.driver.System.get_pid("nativespawn") + Step("步骤9:预期结果校验") + self.driver.Assert.equal(pid1, None) + self.driver.Assert.not_equal(pid2, None) + self.driver.Assert.equal(pid3, None) + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0200.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0200.json new file mode 100644 index 0000000000000000000000000000000000000000..35f2dbc3c2e4698b8c2aa744417aa00e18c22831 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0200.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0200.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0200.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0200.py new file mode 100644 index 0000000000000000000000000000000000000000..1b81b8e1ad18828b857bc100b91d2e11a5a30c64 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0200.py @@ -0,0 +1,82 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn0200(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Ark Process按钮") + self.driver.touch(BY.text("Start Ark Process")) + Step("步骤5:获取测试应用pid") + pid = self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:获取测试应用appspawn孵化子进程pid") + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:ArkProcess0") + Step("步骤7:查看数据") + res = self.driver.shell("ls -l /proc/%d/ns/net" % pid) + childres = self.driver.shell("ls -l /proc/%d/ns/net" % child_pid) + Step("步骤7:预期结果检验") + arr = res.split("-> ")[1] + childarr = childres.split("-> ")[1] + self.driver.Assert.equal(arr, childarr) + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0300.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0300.json new file mode 100644 index 0000000000000000000000000000000000000000..52c04399192844138443904d9090ea5503e532e6 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0300.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0300.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0300.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0300.py new file mode 100644 index 0000000000000000000000000000000000000000..30963fe61a13ad9a62b57f0c015843b852b50508 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0300.py @@ -0,0 +1,82 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn0300(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Ark Process按钮") + self.driver.touch(BY.text("Start Ark Process Isolated")) + Step("步骤5:获取测试应用pid") + pid = self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:获取测试应用appspawn孵化子进程pid") + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:ArkProcess0") + Step("步骤7:查看数据") + res = self.driver.shell("ls -l /proc/%d/ns/net" % pid) + childres = self.driver.shell("ls -l /proc/%d/ns/net" % child_pid) + Step("步骤7:预期结果检验") + arr = res.split("-> ")[1] + childarr = childres.split("-> ")[1] + self.driver.Assert.not_equal(arr, childarr) + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0400.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0400.json new file mode 100644 index 0000000000000000000000000000000000000000..53ec308d8b07d17a43ec365c74f0d9dc62677784 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0400.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0400.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0400.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0400.py new file mode 100644 index 0000000000000000000000000000000000000000..57bf33a338758ebe4775d142b819010fa9108e70 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0400.py @@ -0,0 +1,82 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn0400(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Ark Process按钮") + self.driver.touch(BY.text("start Native Process")) + Step("步骤5:获取测试应用pid") + pid = self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:获取测试应用nativespawn孵化子进程pid") + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:Native_libentry0") + Step("步骤7:查看数据") + res = self.driver.shell("ls -l /proc/%d/ns/net" % pid) + childres = self.driver.shell("ls -l /proc/%d/ns/net" % child_pid) + Step("步骤7:预期结果检验") + arr = res.split("-> ")[1] + childarr = childres.split("-> ")[1] + self.driver.Assert.equal(arr, childarr) + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0500.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0500.json new file mode 100644 index 0000000000000000000000000000000000000000..8ac0c9f06308f5d28576051d995679d6abbab164 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0500.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0500.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0500.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0500.py new file mode 100644 index 0000000000000000000000000000000000000000..c01985d2a74eef7d59896520cb42494efd52e83d --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0500.py @@ -0,0 +1,82 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn0500(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Ark Process按钮") + self.driver.touch(BY.text("start Native Process Isolated")) + Step("步骤5:获取测试应用pid") + pid = self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:获取测试应用nativespawn孵化子进程pid") + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:Native_libentry0") + Step("步骤7:查看数据") + res = self.driver.shell("ls -l /proc/%d/ns/net" % pid) + childres = self.driver.shell("ls -l /proc/%d/ns/net" % child_pid) + Step("步骤7:预期结果检验") + arr = res.split("-> ")[1] + childarr = childres.split("-> ")[1] + self.driver.Assert.not_equal(arr, childarr) + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0700.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0700.json new file mode 100644 index 0000000000000000000000000000000000000000..e524f783a15c0c75bb3222b7b085dbc8404340cf --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0700.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0700.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0700.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0700.py new file mode 100644 index 0000000000000000000000000000000000000000..159ff680f3f70eacf7dd5ddfc18c2528b1235bdf --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0700.py @@ -0,0 +1,82 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn0700(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Ark Process按钮") + self.driver.touch(BY.text("Start Ark Process Isolated")) + Step("步骤5:获取测试应用pid") + pid = self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:获取测试应用appspawn孵化子进程pid") + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:ArkProcess0") + Step("步骤7:测试应用沙箱路径data/storage/el1生成一个123.txt") + self.driver.shell("echo 123456789 > /proc/%d/root/data/storage/el1/123.txt" % pid) + Step("步骤8:测试应用appspawn孵化子进程查看沙箱路径data/storage/el1") + childres = self.driver.shell("cat /proc/%d/root/data/storage/el1/123.txt" % child_pid) + Step("步骤8:预期结果检验") + self.driver.Assert.contains(childres, "root/data/storage/el1/123.txt: No such file or directory") + self.driver.shell("rm -rf /proc/%d/root/data/storage/el1/123.txt" % pid) + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0900.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0900.json new file mode 100644 index 0000000000000000000000000000000000000000..4dadc000629fa9eb1a8283f6a2bd8369c3a1496a --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0900.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0900.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0900.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0900.py new file mode 100644 index 0000000000000000000000000000000000000000..e425e2310d73fb145cd803d7c94c8c26a388e080 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_0900.py @@ -0,0 +1,84 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn0900(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Ark Process Isolated按钮") + self.driver.touch(BY.text("start Native Process Isolated")) + Step("步骤5:获取测试应用pid") + pid = self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:获取测试应用孵化native进程pid") + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:Native_libentry0") + Step("步骤7:测试应用沙箱路径data/storage/el1生成一个123.txt") + self.driver.shell("echo 0123456789 > /proc/%d/root/data/storage/el1/123.txt" % pid) + Step("步骤8:测试应用孵化native进程查看沙箱路径data/storage/el1") + childres = self.driver.shell("cat /proc/%d/root/data/storage/el1/123.txt" % child_pid) + Step("步骤8:预期结果检验") + self.driver.Assert.contains(childres, "root/data/storage/el1/123.txt: No such file or directory") + self.driver.shell("rm -rf /proc/%d/root/data/storage/el1/123.txt" % pid) + + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") + diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1000.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1000.json new file mode 100644 index 0000000000000000000000000000000000000000..65eb9d6c961e652a5e13c7afe70202a36aa39673 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1000.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1000.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1000.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1000.py new file mode 100644 index 0000000000000000000000000000000000000000..5041713f21bf2a9eb665155d70394fcfe7bb96df --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1000.py @@ -0,0 +1,91 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn1000(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Ark Process按钮") + self.driver.touch(BY.text("Start Ark Process")) + Step("步骤5:获取测试应用pid") + pid = self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:获取测试应用appspawn孵化子进程pid") + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:ArkProcess0") + Step("步骤7:测试应用沙箱路径data/storage/el1/bundle目录下,创建2个文件夹") + self.driver.shell("mkdir /proc/%d/root/data/storage/el1/bundle/test1 /proc/%d/root/data/storage/el1/bundle/test2" % (pid, pid)) + Step("步骤8:测试应用沙箱路径data/storage/el1/bundle/tets1,创建1个test.txt文件") + self.driver.shell("echo this is test1 > /proc/%d/root/data/storage/el1/bundle/test1/test.txt" % pid) + Step("步骤9:test1挂载test2") + self.driver.shell("mount /proc/%d/root/data/storage/el1/bundle/test1 /proc/%d/root/data/storage/el1/bundle/test2" % (pid, pid)) + Step("步骤10:查看test2目录下的文件是否和test1内容一致") + res = self.driver.shell("cat /proc/%d/root/data/storage/el1/bundle/test2/test.txt" % pid) + Step("步骤11:测试应用appspawn孵化子进程查看沙箱路径data/storage/el1/bundle/test2/test.txt") + childres = self.driver.shell("cat /proc/%d/root/data/storage/el1/bundle/test2/test.txt" % child_pid) + Step("步骤12:预期结果检验") + self.driver.Assert.contains(res, "this is test1") + self.driver.Assert.contains(childres, "root/data/storage/el1/bundle/test2/test.txt: No such file or directory") + self.driver.shell("rm -rf /proc/%d/root/data/storage/el1/bundle/test1 /proc/%d/root/data/storage/el1/bundle/test2" % (pid, pid)) + + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") + diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1100.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1100.json new file mode 100644 index 0000000000000000000000000000000000000000..52e18e1cf4fedf7b60ecb9c09d2c7c3428a40252 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1100.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1100.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1100.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1100.py new file mode 100644 index 0000000000000000000000000000000000000000..3d6179da2b7e4c128d71408f0866d1093ee85783 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1100.py @@ -0,0 +1,91 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn1100(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Ark Process Isolated按钮") + self.driver.touch(BY.text("Start Ark Process Isolated")) + Step("步骤5:获取测试应用pid") + pid = self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:获取测试应用appspawn孵化子进程pid") + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:ArkProcess0") + Step("步骤7:测试应用沙箱路径data/storage/el1/bundle目录下,创建2个文件夹") + self.driver.shell("mkdir /proc/%d/root/data/storage/el1/bundle/test1 /proc/%d/root/data/storage/el1/bundle/test2" % (pid, pid)) + Step("步骤8:测试应用沙箱路径data/storage/el1/bundle/tets1,创建1个test.txt文件") + self.driver.shell("echo this is test1 > /proc/%d/root/data/storage/el1/bundle/test1/test.txt" % pid) + Step("步骤9:test1挂载test2") + self.driver.shell("mount /proc/%d/root/data/storage/el1/bundle/test1 /proc/%d/root/data/storage/el1/bundle/test2" % (pid, pid)) + Step("步骤10:查看test2目录下的文件是否和test1内容一致") + res = self.driver.shell("cat /proc/%d/root/data/storage/el1/bundle/test2/test.txt" % pid) + Step("步骤11:测试应用appspawn孵化子进程查看沙箱路径data/storage/el1/bundle/test2/test.txt") + childres = self.driver.shell("cat /proc/%d/root/data/storage/el1/bundle/test2/test.txt" % child_pid) + Step("步骤12:预期结果检验") + self.driver.Assert.contains(res, "this is test1") + self.driver.Assert.contains(childres, "root/data/storage/el1/bundle/test2/test.txt: No such file or directory") + self.driver.shell("rm -rf /proc/%d/root/data/storage/el1/bundle/test1 /proc/%d/root/data/storage/el1/bundle/test2" % (pid, pid)) + + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") + diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1200.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1200.json new file mode 100644 index 0000000000000000000000000000000000000000..ff9fc37a5ea011ed6a18bcda6687f4ca518c0125 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1200.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1200.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1200.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1200.py new file mode 100644 index 0000000000000000000000000000000000000000..8fcadffd5a1682466704dcd282cf504f312a9a34 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1200.py @@ -0,0 +1,91 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn1200(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Native Process按钮") + self.driver.touch(BY.text("start Native Process")) + Step("步骤5:获取测试应用pid") + pid = self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:孵化native子进程pid") + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:Native_libentry0") + Step("步骤7:测试应用沙箱路径data/storage/el1/bundle目录下,创建2个文件夹") + self.driver.shell("mkdir /proc/%d/root/data/storage/el1/bundle/zsj1 /proc/%d/root/data/storage/el1/bundle/zsj2" % (pid, pid)) + Step("步骤8:测试应用沙箱路径data/storage/el1/bundle/tets1,创建1个zsj.txt文件") + self.driver.shell("echo this is zsj1 > /proc/%d/root/data/storage/el1/bundle/zsj1/zsj.txt" % pid) + Step("步骤9:test1挂载test2") + self.driver.shell("mount /proc/%d/root/data/storage/el1/bundle/zsj1 /proc/%d/root/data/storage/el1/bundle/zsj2" % (pid, pid)) + Step("步骤10:查看test2目录下的文件是否和test1内容一致") + res = self.driver.shell("cat /proc/%d/root/data/storage/el1/bundle/zsj2/zsj.txt" % pid) + Step("步骤11:孵化native子进程查看沙箱路径data/storage/el1/bundle/zsj2/zsj.txt") + childres = self.driver.shell("cat /proc/%d/root/data/storage/el1/bundle/zsj2/zsj.txt" % child_pid) + Step("步骤12:预期结果检验") + self.driver.Assert.contains(res, "this is zsj1") + self.driver.Assert.contains(childres, "root/data/storage/el1/bundle/zsj2/zsj.txt: No such file or directory") + self.driver.shell("rm -rf /proc/%d/root/data/storage/el1/bundle/zsj1 /proc/%d/root/data/storage/el1/bundle/zsj2" % (pid, pid)) + + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") + diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1300.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1300.json new file mode 100644 index 0000000000000000000000000000000000000000..060f23479bd1ec68b5d37d14402393a99bb06ece --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1300.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1300.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1300.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1300.py new file mode 100644 index 0000000000000000000000000000000000000000..29eaca606886fbc505cbbe1c0139bd7e7a86597d --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1300.py @@ -0,0 +1,91 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn1300(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Native Process Isolated按钮") + self.driver.touch(BY.text("start Native Process Isolated")) + Step("步骤5:获取测试应用pid") + pid = self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:获取孵化native子进程pid") + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:Native_libentry0") + Step("步骤7:测试应用沙箱路径data/storage/el1/bundle目录下,创建2个文件夹") + self.driver.shell("mkdir /proc/%d/root/data/storage/el1/bundle/zsj1 /proc/%d/root/data/storage/el1/bundle/zsj2" % (pid, pid)) + Step("步骤8:测试应用沙箱路径data/storage/el1/bundle/tets1,创建1个zsj.txt文件") + self.driver.shell("echo this is zsj1 > /proc/%d/root/data/storage/el1/bundle/zsj1/zsj.txt" % pid) + Step("步骤9:test1挂载test2") + self.driver.shell("mount /proc/%d/root/data/storage/el1/bundle/zsj1 /proc/%d/root/data/storage/el1/bundle/zsj2" % (pid, pid)) + Step("步骤10:查看test2目录下的文件是否和test1内容一致") + res = self.driver.shell("cat /proc/%d/root/data/storage/el1/bundle/zsj2/zsj.txt" % pid) + Step("步骤11:孵化native子进程查看沙箱路径data/storage/el1/bundle/zsj2/zsj.txt") + childres = self.driver.shell("cat /proc/%d/root/data/storage/el1/bundle/zsj2/zsj.txt" % child_pid) + Step("步骤12:预期结果检验") + self.driver.Assert.contains(res, "this is zsj1") + self.driver.Assert.contains(childres, "root/data/storage/el1/bundle/zsj2/zsj.txt: No such file or directory") + self.driver.shell("rm -rf /proc/%d/root/data/storage/el1/bundle/zsj1 /proc/%d/root/data/storage/el1/bundle/zsj2" % (pid, pid)) + + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") + diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1400.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1400.json new file mode 100644 index 0000000000000000000000000000000000000000..6b1aade8c9e12af961bca1127ab8ca3ca9f84204 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1400.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1400.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1400.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1400.py new file mode 100644 index 0000000000000000000000000000000000000000..71c95199cfe295801308a5aba0c3e9fcc3dff745 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1400.py @@ -0,0 +1,90 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn1400(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Ark Process Isolated按钮") + self.driver.touch(BY.text("start Native Process Isolated")) + Step("步骤5:获取测试应用pid") + self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:获取测试应用孵化native进程pid") + child_pid 1 = self.driver.System.get_pid("com.acts.childprocessmanager:Native_libentry0") + Step("步骤7:测试应用沙箱路径data/storage/el1生成一个native.txt") + self.driver.shell("echo this is native1 > /proc/%d/root/data/storage/el1/native.txt" % child_pid 1) + childres = self.driver.shell("cat /proc/%d/root/data/storage/el1/native.txt" % child_pid 1) + Step("步骤8:杀死孵化native进程") + self.driver.shell("kill -9 %d" % child_pid 1) + Step("步骤9:再次点击start Ark Process Isolated按钮") + self.driver.touch(BY.text("start Native Process Isolated")) + Step("步骤10:测试应用孵化native进程查看沙箱路径data/storage/el1") + child_pid 2 = self.driver.System.get_pid("com.acts.childprocessmanager:Native_libentry1") + childres2 = self.driver.shell("cat /proc/%d/root/data/storage/el1/native.txt" % child_pid 2) + Step("步骤11:预期结果检验") + self.driver.Assert.contains(childres, "this is native1") + self.driver.Assert.contains(childres2, "this is native1") + self.driver.shell("rm -rf /proc/%d/root/data/storage/el1/native.txt" % child_pid 2) + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") + diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1500.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1500.json new file mode 100644 index 0000000000000000000000000000000000000000..851b51223a6fe81b8ff8bf3e97467f52acd300a3 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1500.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1500.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1500.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1500.py new file mode 100644 index 0000000000000000000000000000000000000000..dc71daf44fb956265c5b5579d7fe275519992b1c --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1500.py @@ -0,0 +1,85 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn1500(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Ark Process Isolated按钮") + self.driver.touch(BY.text("start Native Process Isolated")) + Step("步骤5:获取测试应用pid") + pid = self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:获取测试应用孵化native进程pid") + child_pid 1 = self.driver.System.get_pid("com.acts.childprocessmanager:Native_libentry0") + Step("步骤7:杀死nativespawn进程") + self.driver.shell("kill -9 `pidof nativespawn`") + Step("步骤8:查询测试应用") + result = self.driver.shell("ps -ef | grep com.acts.childprocessmanager") + Step("步骤9:查询nativespawn进程号") + nativepid = self.driver.System.get_pid("nativespawn") + self.driver.Assert.contains(result, str(child_pid 1)) + self.driver.Assert.contains(result, str(pid)) + self.driver.Assert.equal(nativepid, None) + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") + diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1600.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1600.json new file mode 100644 index 0000000000000000000000000000000000000000..749e6f9959947b54f173657a1c4b3a4dd03c8515 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1600.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1600.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1600.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1600.py new file mode 100644 index 0000000000000000000000000000000000000000..4a3bc803cc34df4e138a00f47c17bdeabad9870b --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1600.py @@ -0,0 +1,78 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn1600(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Ark Process按钮") + self.driver.touch(BY.text("start Native Process Isolated")) + Step("步骤5:获取测试应用nativespawn孵化子进程pid") + time.sleep(1) + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:Native_libentry0") + Step("步骤6:孵化的native子进程(Isolated=true)selinux标签类型") + childres = self.driver.shell("ps -efZ | grep %d | grep -v grep" % child_pid) + Step("步骤9: 预期结果校验") + self.driver.Assert.contains(childres, "u:r:isolated_render:s0") + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1700.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1700.json new file mode 100644 index 0000000000000000000000000000000000000000..949a2197805fa2395ae8ca5f35ac29dc6b254f0d --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1700.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1700.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1700.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1700.py new file mode 100644 index 0000000000000000000000000000000000000000..58b4c977109c6cc4de6ade43547aedc10b2eb8a0 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1700.py @@ -0,0 +1,83 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn1700(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:点击start Ark Process按钮") + self.driver.touch(BY.text("start Native Process")) + Step("步骤5:获取测试应用pid") + pid = self.driver.System.get_pid("com.acts.childprocessmanager") + Step("步骤6:获取测试应用nativespawn孵化子进程pid") + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:Native_libentry0") + Step("步骤7:测试应用selinux标签类型") + res = self.driver.shell("ps -efZ | grep %d | grep -v grep" % pid) + Step("步骤8:孵化的native子进程(Isolated=false)selinux标签类型") + childres = self.driver.shell("ps -efZ | grep %d | grep -v grep" % child_pid) + string = res.split(" ")[0] + child_string = childres.split(" ")[0] + Step("步骤9: 预期结果校验") + self.driver.Assert.equal(string, child_string) + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1800.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1800.json new file mode 100644 index 0000000000000000000000000000000000000000..b5bedb14789015eec490b40cd2a9858909dd38d8 --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1800.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1800.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1800.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1800.py new file mode 100644 index 0000000000000000000000000000000000000000..a1ab55679961bcad0d40d2f3457b0724f2b0ee3a --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1800.py @@ -0,0 +1,93 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn1800(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + self.driver.install_app(hap) + Step("步骤2:打开测试应用") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:首次获取nativesapwn进程号") + pid1 = self.driver.System.get_pid("nativespawn") + Step("步骤5:点击start Native Process Isolated按钮") + self.driver.touch(BY.text("start Native Process Isolated")) + time.sleep(1) + Step("步骤6:再次点击start Native Process Isolated按钮") + self.driver.touch(BY.text("start Native Process Isolated")) + Step("步骤7:第二次获取nativesapwn进程号") + pid2 = self.driver.System.get_pid("nativespawn") + Step("步骤8:杀掉孵化的一个nativ进程") + child_pid = self.driver.System.get_pid("com.acts.childprocessmanager:Native_libentry0") + self.driver.shell("kill -9 %d" % child_pid) + Step("步骤9:第三次获取nativesapwn进程号") + pid3 = self.driver.System.get_pid("nativespawn") + Step("步骤10:杀掉孵化的最后一个native子进程") + child_pid 1 = self.driver.System.get_pid("com.acts.childprocessmanager:Native_libentry1") + self.driver.shell("kill -9 %d" % child_pid 1) + Step("步骤11:第四次获取nativesapwn进程号") + pid4 = self.driver.System.get_pid("nativespawn") + Step("步骤12:预期结果校验") + self.driver.Assert.equal(pid1, None) + self.driver.Assert.not_equal(pid2, None) + self.driver.Assert.not_equal(pid3, None) + self.driver.Assert.equal(pid4, None) + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1900.json b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1900.json new file mode 100644 index 0000000000000000000000000000000000000000..77347638d95a1c37628f959e4c5948a95b5346ea --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1900.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1900.py"] + } +} \ No newline at end of file diff --git a/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1900.py b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1900.py new file mode 100644 index 0000000000000000000000000000000000000000..a4f318c88b170d95141541bdb8ea4531d954be0e --- /dev/null +++ b/test/autotest/SubStartupAppspawnNativespawn/sub_startup_appspawn_nativespawn_1900.py @@ -0,0 +1,102 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium import UiParam +from hypium.model import UiParam +from aw import Common +import time + + +class SubStartupAppspawnNativespawn1900(TestCase): + + def __init__(self, controllers): + self.tag = self.__class__.__name__ + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.tag, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('获取权限状态') + is_status = self.driver.shell("param get persist.sys.abilityms.multi_process_model") + if ("true" in is_status): + pass + else: + Step('设置权限为true') + self.driver.shell("param set persist.sys.abilityms.multi_process_model true") + Step('重启生效') + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + self.driver.ScreenLock.unlock() + + def test_step1(self): + Step("步骤1:安装测试应用") + hap1 = Common.sourcepath('entry-default-nativespawn.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + hap2 = Common.sourcepath('entry-default-nativespawn1.hap', "SUB_STARTUP_STABILITY_APPSPAWN") + is_hap = self.driver.has_app("com.acts.childprocessmanager") + if(is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager") + else: + pass + is_hap = self.driver.has_app("com.acts.childprocessmanager1") + if (is_hap): + self.driver.uninstall_app("com.acts.childprocessmanager1") + else: + pass + self.driver.install_app(hap1) + self.driver.install_app(hap2) + Step("步骤2:打开测试应用1") + self.driver.start_app("com.acts.childprocessmanager") + Step("步骤3:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤4:首次获取nativesapwn进程号") + pid1 = self.driver.System.get_pid("nativespawn") + Step("步骤5:点击start Native Process Isolated按钮") + self.driver.touch(BY.text("start Native Process Isolated")) + Step("步骤6:第二次获取nativesapwn进程号") + pid2 = self.driver.System.get_pid("nativespawn") + Step("步骤7:打开测试应用2") + self.driver.start_app("com.acts.childprocessmanager1") + Step("步骤8:点击StartArk用例按钮") + self.driver.touch(BY.text("StartArk用例")) + Step("步骤9:点击start Native Process Isolated按钮") + self.driver.touch(BY.text("start Native Process Isolated")) + Step("步骤10:关闭测试应用1") + self.driver.stop_app("com.acts.childprocessmanager") + Step("步骤11:第三次获取nativesapwn进程号") + pid3 = self.driver.System.get_pid("nativespawn") + Step("步骤12:关闭测试应用1") + self.driver.stop_app("com.acts.childprocessmanager1") + Step("步骤13:第四次获取nativesapwn进程号") + pid4 = self.driver.System.get_pid("nativespawn") + Step("步骤12:预期结果校验") + self.driver.Assert.equal(pid1, None) + self.driver.Assert.not_equal(pid2, None) + self.driver.Assert.not_equal(pid3, None) + self.driver.Assert.equal(pid4, None) + + def teardown(self): + Step("收尾工作:卸载测试应用") + self.driver.uninstall_app("com.acts.childprocessmanager") + self.driver.uninstall_app("com.acts.childprocessmanager1") \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0100.json b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0100.json new file mode 100644 index 0000000000000000000000000000000000000000..1fd513bc99342b81b1fef726a5f2b7ef749d2243 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0100.json @@ -0,0 +1,14 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "sub_startup_appspawn_debughap/SubStartupAppspawnDebughap0100.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0100.py b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0100.py new file mode 100644 index 0000000000000000000000000000000000000000..a429b69f6c80ba5ead369569789bae0489dcb1b9 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0100.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import time +from devicetest.core.test_case import TestCase, Step +from hypium.action.os_hypium.device_logger import DeviceLogger +from aw import Common + + +class SubStartupAppspawnDebughap0100(TestCase): + + def __init__(self, controllers): + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step(self.devices[0].device_id) + device = self.driver.shell("param get const.product.model") + device = device.replace("\n", "").replace(" ", "") + device = str(device) + Step(device) + # 解锁屏幕 + wake = self.driver.Screen.is_on() + time.sleep(0.5) + if wake: + self.driver.ScreenLock.unlock() + else: + self.driver.Screen.wake_up() + self.driver.ScreenLock.unlock() + self.driver.Screen.enable_stay_awake() + + def process(self): + Step("安装测试hap并打开") + bundle_name = "com.example.release" + hap_path = Common.sourcepath('release.hap', "sub_startup_appspawn_debughap") + hap = self.driver.AppManager.has_app(bundle_name) + if hap: + self.driver.AppManager.clear_app_data(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) + self.driver.AppManager.install_app(hap_path) + else: + self.driver.AppManager.install_app(hap_path) + self.driver.AppManager.start_app(bundle_name) + + release_has = self.driver.Storage.has_dir("/mnt/debug/100/debug_hap/%s" % bundle_name) + self.driver.Assert.equal(release_has, False) + + def teardown(self): + Step("收尾工作.................") + self.driver.AppManager.stop_app(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0200.json b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0200.json new file mode 100644 index 0000000000000000000000000000000000000000..66713d048e5f32dda102475701ce3eab1fb92c8c --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0200.json @@ -0,0 +1,14 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "sub_startup_appspawn_debughap/SubStartupAppspawnDebughap0200.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0200.py b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0200.py new file mode 100644 index 0000000000000000000000000000000000000000..dec704a03f93ba6bec8b87bfe058838d599ac8c7 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0200.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import time +from devicetest.core.test_case import TestCase, Step +from hypium.action.os_hypium.device_logger import DeviceLogger +from aw import Common + + +class SubStartupAppspawnDebughap0200(TestCase): + + def __init__(self, controllers): + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step(self.devices[0].device_id) + device = self.driver.shell("param get const.product.model") + device = device.replace("\n", "").replace(" ", "") + device = str(device) + Step(device) + # 解锁屏幕 + wake = self.driver.Screen.is_on() + time.sleep(0.5) + if wake: + self.driver.ScreenLock.unlock() + else: + self.driver.Screen.wake_up() + self.driver.ScreenLock.unlock() + self.driver.Screen.enable_stay_awake() + + def process(self): + Step("安装测试hap并打开") + bundle_name = "com.example.myapplication" + hap_path = Common.sourcepath('debug.hap', "sub_startup_appspawn_debughap") + hap = self.driver.AppManager.has_app(bundle_name) + if hap: + self.driver.AppManager.uninstall_app(bundle_name) + self.driver.AppManager.install_app(hap_path) + else: + self.driver.AppManager.install_app(hap_path) + self.driver.shell("param set startup.appspawn.sandbox.debughap true") + self.driver.AppManager.start_app(bundle_name) + + result = self.driver.shell("ls /mnt/debug/100/debug_hap").split() + self.driver.Assert.contains(result, bundle_name) + + def teardown(self): + Step("收尾工作.................") + self.driver.AppManager.stop_app(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0300.json b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0300.json new file mode 100644 index 0000000000000000000000000000000000000000..4918b0b9a12739b6edf82828ad3bfce4cf06b820 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0300.json @@ -0,0 +1,14 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "sub_startup_appspawn_debughap/SubStartupAppspawnDebughap0300.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0300.py b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0300.py new file mode 100644 index 0000000000000000000000000000000000000000..fb7609b23dae061f1a2b6fa17830ad2d94a02e16 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0300.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import time +from devicetest.core.test_case import TestCase, Step +from hypium.action.os_hypium.device_logger import DeviceLogger +from aw import Common + + +class SubStartupAppspawnDebughap0300(TestCase): + + def __init__(self, controllers): + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step(self.devices[0].device_id) + device = self.driver.shell("param get const.product.model") + device = device.replace("\n", "").replace(" ", "") + device = str(device) + Step(device) + # 解锁屏幕 + wake = self.driver.Screen.is_on() + time.sleep(0.5) + if wake: + self.driver.ScreenLock.unlock() + else: + self.driver.Screen.wake_up() + self.driver.ScreenLock.unlock() + self.driver.Screen.enable_stay_awake() + + def process(self): + Step("安装测试hap并打开") + bundle_name = "com.example.myapplication" + hap_path = Common.sourcepath('debug.hap', "sub_startup_appspawn_debughap") + hap = self.driver.AppManager.has_app(bundle_name) + if hap: + self.driver.AppManager.uninstall_app(bundle_name) + self.driver.AppManager.install_app(hap_path) + else: + self.driver.AppManager.install_app(hap_path) + self.driver.shell("param set startup.appspawn.sandbox.debughap true") + self.driver.AppManager.start_app(bundle_name) + + sandbox_list = [] + mount_dict = list(filter(None, self.driver.shell("mount|grep %s" % bundle_name).split("\n"))) + for mount in mount_dict: + if mount.split()[2].startswith("/mnt/debug"): + sandbox_list.append(mount.split()[2]) + else: + pass + + for i in range(1, 5): + for path in ["base", "database"]: + self.driver.Assert.contains(sandbox_list, "/mnt/debug/100/debug_hap/%s/data/storage/el%d/%s" + % (bundle_name, i, path)) + + list01 = ["el2/share", "el2/log", "el1/bundle", "el2/auth_groups", "el2/distributedfiles"] + for path in list01: + self.driver.Assert.contains(sandbox_list, "/mnt/debug/100/debug_hap/%s/data/storage/%s" + % (bundle_name, path)) + + def teardown(self): + Step("收尾工作.................") + self.driver.AppManager.stop_app(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0500.json b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0500.json new file mode 100644 index 0000000000000000000000000000000000000000..a8e1e788d82d2c7dc101455bd9e73331af48bb9c --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0500.json @@ -0,0 +1,14 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "sub_startup_appspawn_debughap/SubStartupAppspawnDebughap0500.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0500.py b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0500.py new file mode 100644 index 0000000000000000000000000000000000000000..e410e953548cfcadd30fc9c38002e2449242febc --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0500.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import time +from devicetest.core.test_case import TestCase, Step +from hypium.action.os_hypium.device_logger import DeviceLogger +from aw import Common + + +class SubStartupAppspawnDebughap0500(TestCase): + + def __init__(self, controllers): + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step(self.devices[0].device_id) + device = self.driver.shell("param get const.product.model") + device = device.replace("\n", "").replace(" ", "") + device = str(device) + Step(device) + # 解锁屏幕 + wake = self.driver.Screen.is_on() + time.sleep(0.5) + if wake: + self.driver.ScreenLock.unlock() + else: + self.driver.Screen.wake_up() + self.driver.ScreenLock.unlock() + self.driver.Screen.enable_stay_awake() + + def process(self): + Step("安装测试hap并打开") + bundle_name = "com.example.myapplication" + hap_path = Common.sourcepath('debug.hap', "sub_startup_appspawn_debughap") + hap = self.driver.AppManager.has_app(bundle_name) + if hap: + self.driver.AppManager.clear_app_data(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) + self.driver.AppManager.install_app(hap_path) + else: + self.driver.AppManager.install_app(hap_path) + self.driver.AppManager.start_app(bundle_name) + + result = self.driver.shell("ls -Z /mnt/debug/100/debug_hap").split("\n") + self.driver.Assert.contains(result, "u:object_r:sharefs:s0 %s" % bundle_name) + + def teardown(self): + Step("收尾工作.................") + self.driver.AppManager.stop_app(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0600.json b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0600.json new file mode 100644 index 0000000000000000000000000000000000000000..7a19d9b426519d9fad44c31389168998c6fe6a23 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0600.json @@ -0,0 +1,15 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device", + "label": "" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "sub_startup_appspawn_debughap/SubStartupAppspawnDebughap0600.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0600.py b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0600.py new file mode 100644 index 0000000000000000000000000000000000000000..446185f8061bfb0d5a8c976ffc8f9f79153c0282 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0600.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import time +from devicetest.core.test_case import TestCase, Step +from hypium.action.os_hypium.device_logger import DeviceLogger +from aw import Common + + +class SubStartupAppspawnDebughap0600(TestCase): + + def __init__(self, controllers): + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step(self.devices[0].device_id) + device = self.driver.shell("param get const.product.model") + device = device.replace("\n", "").replace(" ", "") + device = str(device) + Step(device) + # 解锁屏幕 + wake = self.driver.Screen.is_on() + time.sleep(0.5) + if wake: + self.driver.ScreenLock.unlock() + else: + self.driver.Screen.wake_up() + self.driver.ScreenLock.unlock() + self.driver.Screen.enable_stay_awake() + + def process(self): + Step("安装测试hap并打开") + bundle_name = "com.example.myapplication" + hap_path = Common.sourcepath('debug.hap', "sub_startup_appspawn_debughap") + hap = self.driver.AppManager.has_app(bundle_name) + if hap: + self.driver.AppManager.clear_app_data(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) + self.driver.AppManager.install_app(hap_path) + else: + self.driver.AppManager.install_app(hap_path) + self.driver.AppManager.start_app(bundle_name) + + result = self.driver.shell("ls /mnt/debug/100/debug_hap").split() + self.driver.Assert.contains(result, bundle_name) + + def teardown(self): + Step("收尾工作.................") + self.driver.AppManager.stop_app(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0700.json b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0700.json new file mode 100644 index 0000000000000000000000000000000000000000..5538e209a217f335453b2f050bc35dab6a22cc2c --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0700.json @@ -0,0 +1,15 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device", + "label": "phone" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "sub_startup_appspawn_debughap/SubStartupAppspawnDebughap0700.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0700.py b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0700.py new file mode 100644 index 0000000000000000000000000000000000000000..e19ac7fd2320ba21a14668c4d854538e43448a81 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0700.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import time +from devicetest.core.test_case import TestCase, Step +from hypium.action.os_hypium.device_logger import DeviceLogger +from aw import Common + + +class SubStartupAppspawnDebughap0700(TestCase): + + def __init__(self, controllers): + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step(self.devices[0].device_id) + device = self.driver.shell("param get const.product.model") + device = device.replace("\n", "").replace(" ", "") + device = str(device) + Step(device) + + self.driver.hdc("target mount") + self.driver.shell("mv /system/etc/init/init_dec.cfg /system/etc/init/init_dec.cfg_bak") + cfg_path = Common.sourcepath('init_dec.cfg', "sub_startup_appspawn_debughap") + self.driver.push_file(cfg_path, "/system/etc/init") + self.driver.System.reboot() + # 解锁屏幕 + wake = self.driver.Screen.is_on() + time.sleep(0.5) + if wake: + self.driver.ScreenLock.unlock() + else: + self.driver.Screen.wake_up() + self.driver.ScreenLock.unlock() + self.driver.Screen.enable_stay_awake() + + def process(self): + Step("安装测试hap并打开") + bundle_name = "com.example.myapplication" + hap_path = Common.sourcepath('debug.hap', "sub_startup_appspawn_debughap") + hap = self.driver.AppManager.has_app(bundle_name) + if hap: + self.driver.AppManager.clear_app_data(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) + self.driver.AppManager.install_app(hap_path) + else: + self.driver.AppManager.install_app(hap_path) + self.driver.shell("param set startup.appspawn.sandbox.debughap true") + self.driver.AppManager.start_app(bundle_name) + + has_dir = self.driver.Storage.has_dir("/mnt/debug/100/debug_hap/%s" % bundle_name) + self.driver.Assert.equal(has_dir, True) + result = self.driver.shell("ls /mnt/debug/100/debug_hap/%s" % bundle_name) + self.driver.Assert.contains(result, "Operation not permitted") + + def teardown(self): + Step("收尾工作.................") + self.driver.hdc("target mount") + self.driver.shell("mv /system/etc/init/init_dec.cfg_bak /system/etc/init/init_dec.cfg") + self.driver.AppManager.stop_app(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) + self.driver.System.reboot() + self.driver.System.wait_for_boot_complete() + self.driver.shell("param set startup.appspawn.sandbox.debughap true") \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0800.json b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0800.json new file mode 100644 index 0000000000000000000000000000000000000000..d17ff07fde09a75eb1d3364aea7bb8efba3c3155 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0800.json @@ -0,0 +1,14 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "sub_startup_appspawn_debughap/SubStartupAppspawnDebughap0800.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0800.py b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0800.py new file mode 100644 index 0000000000000000000000000000000000000000..7974ad11f57c1e351ae9c3a1a7fabe027c4b4224 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0800.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import time +from devicetest.core.test_case import TestCase, Step +from hypium.action.os_hypium.device_logger import DeviceLogger +from aw import Common + + +class SubStartupAppspawnDebughap0800(TestCase): + + def __init__(self, controllers): + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step(self.devices[0].device_id) + device = self.driver.shell("param get const.product.model") + device = device.replace("\n", "").replace(" ", "") + device = str(device) + Step(device) + # 解锁屏幕 + wake = self.driver.Screen.is_on() + time.sleep(0.5) + if wake: + self.driver.ScreenLock.unlock() + else: + self.driver.Screen.wake_up() + self.driver.ScreenLock.unlock() + self.driver.Screen.enable_stay_awake() + + def process(self): + Step("安装测试hap并打开") + bundle_name = "com.example.myapplication" + hap_path = Common.sourcepath('debug.hap', "sub_startup_appspawn_debughap") + hap = self.driver.AppManager.has_app(bundle_name) + if hap: + self.driver.AppManager.clear_app_data(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) + self.driver.AppManager.install_app(hap_path) + else: + self.driver.AppManager.install_app(hap_path) + self.driver.AppManager.start_app(bundle_name) + + for i in range(1, 5): + for path in {"database", "base"}: + mac_path = self.driver.Storage.has_dir("/data/app/el%d/100/%s/%s" % (i, path, bundle_name)) + sandbox_path = self.driver.Storage.has_dir("/mnt/debug/100/debug_hap/%s/data/storage/el%d/%s" + % (bundle_name, i, path)) + self.driver.Assert.equal(mac_path, sandbox_path) + + if mac_path is True: + mac_path_content = self.driver.shell("ls /data/app/el%d/100/%s/%s" % (i, path, bundle_name)) + sandbox_path_content = self.driver.shell("ls /mnt/debug/100/debug_hap/%s/data/storage/el%d/%s" + % (bundle_name, i, path)) + self.driver.Assert.equal(mac_path_content, sandbox_path_content) + + path_dict = { + "/mnt/hmdfs/100/non_account/merge_view/data": "el2/auth_groups", + "/mnt/hmdfs/100/account/merge_view/data": "el2/distributedfiles", + "/data/app/el2/100/log": "el2/log", + "/data/app/el1/bundle/public": "el1/bundle", + "/mnt/share/100": "el2/share" + } + + for mac, sandbox in path_dict.items(): + if mac != "/mnt/hmdfs/100/non_account/merge_view/data": + mac_path = self.driver.Storage.has_dir("%s/%s" % (mac, bundle_name)) + sandbox_path = self.driver.Storage.has_dir("/mnt/debug/100/debug_hap/%s/data/storage/%s" + % (bundle_name, sandbox)) + self.driver.Assert.equal(mac_path, sandbox_path) + if mac_path is True: + mac_path_content = self.driver.shell("ls %s/%s" % (mac, bundle_name)) + sandbox_path_content = self.driver.shell( + "ls /mnt/debug/100/debug_hap/%s/data/storage/%s" % (bundle_name, sandbox)) + self.driver.Assert.equal(mac_path_content, sandbox_path_content) + else: + mac_path = self.driver.Storage.has_dir("%s" % mac) + sandbox_path = self.driver.Storage.has_dir("/mnt/debug/100/debug_hap/%s/data/storage/%s" + % (bundle_name, sandbox)) + self.driver.Assert.equal(mac_path, sandbox_path) + if mac_path is True: + mac_path_content = self.driver.shell("ls %s" % mac) + sandbox_path_content = self.driver.shell("ls /mnt/debug/100/debug_hap/%s/data/storage/%s" + % (bundle_name, sandbox)) + self.driver.Assert.equal(mac_path_content, sandbox_path_content) + + def teardown(self): + Step("收尾工作.................") + self.driver.AppManager.stop_app(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0900.json b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0900.json new file mode 100644 index 0000000000000000000000000000000000000000..ab601307be4559b5a2a8cdd30490e869e8a8c997 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0900.json @@ -0,0 +1,14 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "sub_startup_appspawn_debughap/SubStartupAppspawnDebughap0900.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0900.py b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0900.py new file mode 100644 index 0000000000000000000000000000000000000000..67a388ef2fd4d98a646a1bf0c3f7a0392e2e086b --- /dev/null +++ b/test/autotest/sub_startup_appspawn_debughap/sub_startup_appspawn_debughap_0900.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import time +from devicetest.core.test_case import TestCase, Step +from hypium.action.os_hypium.device_logger import DeviceLogger +from aw import Common + + +class SubStartupAppspawnDebughap0900(TestCase): + + def __init__(self, controllers): + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step(self.devices[0].device_id) + device = self.driver.shell("param get const.product.model") + device = device.replace("\n", "").replace(" ", "") + device = str(device) + Step(device) + # 解锁屏幕 + wake = self.driver.Screen.is_on() + time.sleep(0.5) + if wake: + self.driver.ScreenLock.unlock() + else: + self.driver.Screen.wake_up() + self.driver.ScreenLock.unlock() + self.driver.Screen.enable_stay_awake() + + def process(self): + Step("安装测试hap并打开") + bundle_name = "com.example.myapplication" + hap_path = Common.sourcepath('debug.hap', "sub_startup_appspawn_debughap") + hap = self.driver.AppManager.has_app(bundle_name) + if hap: + self.driver.AppManager.clear_app_data(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) + self.driver.AppManager.install_app(hap_path) + else: + self.driver.AppManager.install_app(hap_path) + self.driver.AppManager.start_app(bundle_name) + + result = self.driver.shell("ls -Z /mnt/debug/100") + self.driver.Assert.contains(result, "u:object_r:sharefs:s0 debug_hap") + + def teardown(self): + Step("收尾工作.................") + self.driver.AppManager.stop_app(bundle_name) + self.driver.AppManager.uninstall_app(bundle_name) \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_fd/sub_startup_appspawn_fd_0100.json b/test/autotest/sub_startup_appspawn_fd/sub_startup_appspawn_fd_0100.json new file mode 100644 index 0000000000000000000000000000000000000000..d2ef15d1b102c91ec8be8f87744eeb9f19b7e2c7 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_fd/sub_startup_appspawn_fd_0100.json @@ -0,0 +1,14 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "sub_startup_appspawn_fd/SubStartupAppspawnFd0100.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_fd/sub_startup_appspawn_fd_0100.py b/test/autotest/sub_startup_appspawn_fd/sub_startup_appspawn_fd_0100.py new file mode 100644 index 0000000000000000000000000000000000000000..d65e7ce41247a3f821073ea26369733521c5e494 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_fd/sub_startup_appspawn_fd_0100.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from time import sleep +from devicetest.core.test_case import Step, TestCase +from hypium.action.os_hypium.device_logger import DeviceLogger +from aw import Common + + +class SubStartupAppspawnFd0100(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + Step(self.devices[0].device_id) + Step("安装测试hap.................") + sourpath = Common.sourcepath("fd.hap", "sub_startup_appspawn_fd") + Step(sourpath) + self.driver.AppManager.install_app(sourpath) + Step("设置系统参数.................") + self.driver.shell('param set persist.sys.abilityms.multi_process_model true') + Step("执行重启..........................") + self.driver.System.reboot() + sleep(3) + self.driver.System.wait_for_boot_complete() + Step("预置工作:检测屏幕是否亮.................") + self.driver.Screen.wake_up() + self.driver.ScreenLock.unlock() + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + self.d = UiExplorer(self.device1) + device_logger = DeviceLogger(self.d) + Step("设置关键字..........................") + device_logger.set_filter_string("ldprocessmanager:OtherProcess") + Step("开启日志..........................") + device_logger.start_log("testFile/Log/log.txt") + Step("打开测试hap.................") + self.driver.start_app("com.acts.childprocessmanager", "EntryAbility") + sleep(3) + Step("点击Start Child Process.................") + self.driver.touch(BY.text("Start Child Process")) + Step("点击Start Ark Process.................") + self.driver.touch(BY.text("Start Ark Process")) + sleep(10) + Step("停止日志..........................") + device_logger.stop_log() + Step("校验日志内容..........................") + Step("查看childprocessmanager服务pid..........................") + pid = self.driver.System.get_pid('com.acts.childprocessmanager:OtherProcess1') + result = self.driver.shell("ls -al /proc/%d/fd" % pid) + Step("步骤6:预期结果校验") + self.driver.Assert.contains(result, "/data/storage/el2/base/haps/entry/files/test.txt") + self.driver.Assert.contains(result, "/data/storage/el2/base/haps/entry/files/test2.txt") + + def teardown(self): + Step("收尾工作.................") + Step("收尾工作:卸载hap......................") + self.driver.AppManager.clear_app_data('com.acts.childprocessmanager') + self.driver.AppManager.uninstall_app('com.acts.childprocessmanager') + Step("恢复系统参数.................") + self.driver.hdc('param set persist.sys.abilityms.multi_process_model false') + Step("执行重启..........................") + self.driver.System.reboot() + sleep(3) + self.driver.System.wait_for_boot_complete() diff --git a/test/autotest/sub_startup_appspawn_ftpd/sub_startup_appspawn_ftpd_0100.json b/test/autotest/sub_startup_appspawn_ftpd/sub_startup_appspawn_ftpd_0100.json new file mode 100644 index 0000000000000000000000000000000000000000..850e6d6a2a1ded8079bb6217fc0d5780b3af98ca --- /dev/null +++ b/test/autotest/sub_startup_appspawn_ftpd/sub_startup_appspawn_ftpd_0100.json @@ -0,0 +1,15 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device", + "label": "phone" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": [ + "sub_startup_appspawn_ftpd/SubStartupAppspawnFtpd0100.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_ftpd/sub_startup_appspawn_ftpd_0100.py b/test/autotest/sub_startup_appspawn_ftpd/sub_startup_appspawn_ftpd_0100.py new file mode 100644 index 0000000000000000000000000000000000000000..a2385b2dc46b2412ac0dd3cf6dd3c6ada2787336 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_ftpd/sub_startup_appspawn_ftpd_0100.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from devicetest.core.test_case import Step, TestCase + +from aw import Common + + +class SubStartupAppspawnFtpd0100(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + Step(self.devices[0].device_id) + Step("设置系统参数sysctl -w kernel.xpm.xpm_mode=0..........................") + self.driver.hdc("target mount") + self.driver.shell("sed -i 's%/proc/sys/kernel/xpm/xpm_mode 4%/proc/sys/kernel/xpm/xpm_mode 0%g' /system/etc/init/key_enable.cfg") + self.driver.shell("reboot") + self.driver.System.wait_for_boot_complete() + set_result = self.driver.shell("sysctl -w kernel.xpm.xpm_mode=0") + self.driver.Assert.contains(set_result, "kernel.xpm.xpm_mode = 0") + Step("安装测试hap.................") + sourpath = Common.sourcepath("ftpd.hap", "sub_startup_appspawn_ftpd") + Step(sourpath) + self.driver.AppManager.install_app(sourpath) + Step("预置工作:检测屏幕是否亮.................") + self.driver.Screen.wake_up() + self.driver.ScreenLock.unlock() + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("打开测试hap.................") + self.driver.start_app("com.ohos.myapplication", "EntryAbility") + Step("打开bftpd.................") + aa_resutl = self.driver.shell("aa process -b com.ohos.myapplication -a EntryAbility -D '/system/bin/bftpd -D -p 9021' -S") + self.driver.Assert.contains(aa_resutl, "start native process successfully") + Step("校验bftpd进程") + pid = self.driver.System.get_pid('bftpd') + + def teardown(self): + Step("收尾工作.................") + Step("收尾工作:卸载hap......................") + self.driver.AppManager.clear_app_data('com.ohos.myapplication') + self.driver.AppManager.uninstall_app('com.ohos.myapplication') + Step("恢复系统参数......................") + recovery_result = self.driver.shell("sysctl -w kernel.xpm.xpm_mode=4") + self.driver.Assert.contains(recovery_result, "kernel.xpm.xpm_mode = 4") diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0100.json b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0100.json new file mode 100644 index 0000000000000000000000000000000000000000..12504c728f7fed951fe0157084550df8d993c409 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0100.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_hnpinstall/SubStartupAppspawnHnpinstall0100.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0100.py b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0100.py new file mode 100644 index 0000000000000000000000000000000000000000..8aa9ec0062cf3519c80a5cb77c236fd590c7a391 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0100.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os +from aw import Common + + +class SubStartupAppspawnHnpinstall0100(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("步骤1:安装测试应用") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-hnpinsall.hap')) + isHap = self.driver.has_app("com.example.hnp_test") + if(isHap): + self.driver.uninstall_app("com.example.hnp_test") + else: + pass + self.driver.install_app(hnp) + Step("是否刷root包") + isroot = self.driver.shell("ls") + Step("步骤2:展示公有目录列表") + result1 = self.driver.shell("ls /data/app/el1/bundle/100/hnppublic") + self.driver.Assert.contains(result1, "hnpsample.org") + if ("Permission denied" in isroot): + Step("步骤4:执行公有目录软链二进制") + th = Common.hnpexecute_async(self.driver, "/data/app/el1/bundle/100/hnppublic/bin/hnpsample 5") + th.start() + result3 = self.driver.shell("ps -ef | grep hnpsample | grep -v grep") + self.driver.Assert.contains(result3, "hnpsample") + else: + Step("步骤3:展示私有目录列表") + result2 = self.driver.shell("ls /data/app/el1/bundle/100/hnp/com.example.hnp_test") + self.driver.Assert.contains(result2, "node.org") + Step("步骤4:执行公有目录软链二进制") + result3 = self.driver.hdc("hdc shell /data/app/el1/bundle/100/hnppublic/bin/hnpsample") + self.driver.Assert.contains(result3, "start hnp sample") + self.driver.Assert.contains(result3, "hnp sample end") + + def teardown(self): + Step("收尾工作:卸载hap") + self.driver.uninstall_app("com.example.hnp_test") diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0200.json b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0200.json new file mode 100644 index 0000000000000000000000000000000000000000..8a17d83b952a3a5c0561cd5d01808a91a7945110 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0200.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_hnpinstall/SubStartupAppspawnHnpinstall0200.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0200.py b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0200.py new file mode 100644 index 0000000000000000000000000000000000000000..4831a3f78694aecd4f55e8db81d74d3d920bde8c --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0200.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnHnpinstall0200(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("步骤1:安装测试应用") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-hnpinsall.hap')) + isHap = self.driver.has_app("com.example.hnp_test") + if(isHap): + self.driver.uninstall_app("com.example.hnp_test") + else: + pass + self.driver.install_app(hnp) + Step("步骤2:读取公有目录列表") + result1 = self.driver.shell("cat /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json") + self.driver.Assert.contains(result1, "hnpsample") + Step("是否刷root包") + isroot = self.driver.shell("ls") + if("Permission denied" in isroot): + Step("步骤3:读取私有目录列表") + result2 = self.driver.shell( + "cat /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json") + self.driver.Assert.contains(result2, "Permission denied") + else: + Step("步骤3:读取私有目录列表") + result2 = self.driver.shell("cat /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json") + self.driver.Assert.contains(result2, "node") + + def teardown(self): + Step("收尾工作:卸载hap") + self.driver.uninstall_app("com.example.hnp_test") diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0300.json b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0300.json new file mode 100644 index 0000000000000000000000000000000000000000..90f6a911b0baddcafebff838038daea2f00af233 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0300.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_hnpinstall/SubStartupAppspawnHnpinstall0300.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0300.py b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0300.py new file mode 100644 index 0000000000000000000000000000000000000000..268ea56fe50797c9f5d4cbe50074db5f67012223 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0300.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnHnpinstall0300(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("步骤1:安装测试应用") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-hnpinsall.hap')) + isHap = self.driver.has_app("com.example.hnp_test") + if (isHap): + self.driver.uninstall_app("com.example.hnp_test") + else: + pass + self.driver.install_app(hnp) + isroot = self.driver.shell("ls") + if ("Permission denied" in isroot): + Step("步骤2:修改公有目录文件内容") + data = {"name": "zsj", "sex": "girl", "age": 31}; + result1 = self.driver.shell(f"echo {data} > /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json") + self.driver.Assert.contains(result1, "Permission denied") + Step("步骤3:修改私有目录文件内容") + data = {"name": "private", "sex": "girl", "age": 31}; + result2 = self.driver.shell(f"echo {data} > /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json") + self.driver.Assert.contains(result2, "Permission denied") + else: + Step("步骤2:修改公有目录文件内容") + data = {"name": "zsj", "sex": "girl", "age": 31}; + self.driver.shell(f"echo {data} > /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json") + result1 = self.driver.shell("cat /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json") + self.driver.Assert.contains(result1, "zsj") + Step("步骤3:修改私有目录文件内容") + data = {"name": "private", "sex": "girl", "age": 31}; + self.driver.shell( + f"echo {data} > /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json") + result2 = self.driver.shell( + "cat /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json") + self.driver.Assert.contains(result2, "private") + + def teardown(self): + Step("收尾工作:卸载hap") + self.driver.uninstall_app("com.example.hnp_test") diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0400.json b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0400.json new file mode 100644 index 0000000000000000000000000000000000000000..eab617a873d76e995a7d994aa88670463df3cfb0 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0400.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_hnpinstall/SubStartupAppspawnHnpinstall0400.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0400.py b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0400.py new file mode 100644 index 0000000000000000000000000000000000000000..67daef310ed3581ca1760d53ebdba27f6fb4991f --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0400.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnHnpinstall0400(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("步骤1:安装测试应用") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-hnpinsall.hap')) + isHap = self.driver.has_app("com.example.hnp_test") + if (isHap): + self.driver.uninstall_app("com.example.hnp_test") + else: + pass + self.driver.install_app(hnp) + isroot = self.driver.shell("ls") + if ("Permission denied" in isroot): + Step("步骤2:修改公有目录文件内容") + result1 = self.driver.shell(f"touch /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/123.txt") + self.driver.Assert.contains(result1, "Permission denied") + Step("步骤3:修改私有目录文件内容") + result2 = self.driver.shell(f"touch /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/abc.txt") + self.driver.Assert.contains(result2, "Permission denied") + else: + Step("步骤2:修改公有目录文件内容") + self.driver.shell(f"touch /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/123.txt") + result1 = self.driver.shell("ls /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/") + self.driver.Assert.contains(result1, "123.txt") + Step("步骤3:修改私有目录文件内容") + self.driver.shell(f"touch /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/abc.txt") + result2 = self.driver.shell( + "ls /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/") + self.driver.Assert.contains(result2, "abc.txt") + + def teardown(self): + Step("收尾工作:卸载hap") + self.driver.uninstall_app("com.example.hnp_test") diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0500.json b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0500.json new file mode 100644 index 0000000000000000000000000000000000000000..2cd611866ae9e4265cb0cbb70925f7ca7204da7b --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0500.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_hnpinstall/SubStartupAppspawnHnpinstall0500.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0500.py b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0500.py new file mode 100644 index 0000000000000000000000000000000000000000..ad73decfc6cc6e25889509361b6514b634d76c4c --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0500.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnHnpinstall0500(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("步骤1:安装测试应用") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-hnpinsall.hap')) + isHap = self.driver.has_app("com.example.hnp_test") + if (isHap): + self.driver.uninstall_app("com.example.hnp_test") + else: + pass + self.driver.install_app(hnp) + isroot = self.driver.shell("ls") + if ("Permission denied" in isroot): + Step("步骤2:修改公有目录文件内容") + result1 = self.driver.shell( + f"rm -rf /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json") + self.driver.Assert.contains(result1, "Permission denied") + Step("步骤3:修改私有目录文件内容") + result2 = self.driver.shell( + f"rm -rf /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json") + self.driver.Assert.contains(result2, "Permission denied") + else: + Step("步骤2:修改公有目录文件内容") + self.driver.shell(f"rm -rf /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json") + result1 = self.driver.shell("ls /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/") + self.driver.Assert.is_true("hnp.json" not in result1) + Step("步骤3:修改私有目录文件内容") + self.driver.shell(f"rm -rf /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json") + result2 = self.driver.shell( + "ls /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/") + self.driver.Assert.is_true("hnp.json" not in result2) + + def teardown(self): + Step("收尾工作:卸载hap") + self.driver.uninstall_app("com.example.hnp_test") diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0600.json b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0600.json new file mode 100644 index 0000000000000000000000000000000000000000..009ebc7cefe970e87ad4d67d747777c6a8fd5d2e --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0600.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_hnpinstall/SubStartupAppspawnHnpinstall0600.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0600.py b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0600.py new file mode 100644 index 0000000000000000000000000000000000000000..206576825b7bf65be447ea862bea98e5060eeedb --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0600.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnHnpinstall0600(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("步骤1:安装测试应用") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-hnpinsall.hap')) + isHap = self.driver.has_app("com.example.hnp_test") + if (isHap): + self.driver.uninstall_app("com.example.hnp_test") + else: + pass + self.driver.install_app(hnp) + isroot = self.driver.shell("ls") + if ("Permission denied" in isroot): + Step("步骤2:修改公有目录文件内容") + result1 = self.driver.shell( + f"chmod 777 /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json") + self.driver.Assert.contains(result1, "Operation not permitted") + Step("步骤3:修改私有目录文件内容") + result2 = self.driver.shell( + f"chmod 777 /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json") + self.driver.Assert.contains(result2, "Permission denied") + else: + Step("步骤2:修改公有目录文件内容") + self.driver.shell(f"chmod 777 /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json") + result1 = self.driver.shell("ls -l /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json") + self.driver.Assert.contains(result1, "rwxrwxrwx") + Step("步骤3:修改私有目录文件内容") + self.driver.shell(f"chmod 777 /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json") + result2 = self.driver.shell( + "ls -l /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json") + self.driver.Assert.contains(result2, "rwxrwxrwx") + + def teardown(self): + Step("收尾工作:卸载hap") + self.driver.uninstall_app("com.example.hnp_test") diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0700.json b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0700.json new file mode 100644 index 0000000000000000000000000000000000000000..94f5f1274eff614bfba134bdb00db40dd3c0b6fd --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0700.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_hnpinstall/SubStartupAppspawnHnpinstall0700.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0700.py b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0700.py new file mode 100644 index 0000000000000000000000000000000000000000..e1bfc549628cfc87b36248f72795a86687b9b614 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0700.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnHnpinstall0700(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("步骤1:安装测试应用") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-hnpinsall.hap')) + isHap = self.driver.has_app("com.example.hnp_test") + if (isHap): + self.driver.uninstall_app("com.example.hnp_test") + else: + pass + self.driver.install_app(hnp) + isroot = self.driver.shell("ls") + if ("Permission denied" in isroot): + Step("步骤2:修改公有目录文件内容") + result1 = self.driver.shell( + f"mv /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/zsj.json") + self.driver.Assert.contains(result1, "Permission denied") + Step("步骤3:修改私有目录文件内容") + result2 = self.driver.shell( + f"mv /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/zsj.json") + self.driver.Assert.contains(result2, "Permission denied") + else: + Step("步骤2:修改公有目录文件内容") + self.driver.shell(f"mv /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/zsj.json") + result1 = self.driver.shell("ls /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/") + self.driver.Assert.contains(result1, "zsj.json") + Step("步骤3:修改私有目录文件内容") + self.driver.shell(f"mv /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/zsj.json") + result2 = self.driver.shell( + "ls /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/") + self.driver.Assert.contains(result2, "zsj.json") + + +def teardown(self): + Step("收尾工作:卸载hap") + self.driver.uninstall_app("com.example.hnp_test") diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0800.json b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0800.json new file mode 100644 index 0000000000000000000000000000000000000000..646ceb0ddeb26088343266f349b3a873dee6f310 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0800.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_hnpinstall/SubStartupAppspawnHnpinstall0800.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0800.py b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0800.py new file mode 100644 index 0000000000000000000000000000000000000000..b43d38a0ff11a74409a084f66799e8a8265ddc50 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0800.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnHnpinstall0800(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("步骤1:安装测试应用") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-hnpinsall.hap')) + isHap = self.driver.has_app("com.example.hnp_test") + if (isHap): + self.driver.uninstall_app("com.example.hnp_test") + else: + pass + self.driver.install_app(hnp) + isroot = self.driver.shell("ls") + if ("Permission denied" in isroot): + Step("步骤2:修改公有目录文件内容") + result1 = self.driver.shell( + f"cp /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/zsj.json") + self.driver.Assert.contains(result1, "Permission denied") + Step("步骤3:修改私有目录文件内容") + result2 = self.driver.shell( + f"cp /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/zsj.json") + self.driver.Assert.contains(result2, "Permission denied") + else: + Step("步骤2:修改公有目录文件内容") + self.driver.shell( + f"cp /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/hnp.json /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/zsj.json") + result1 = self.driver.shell("ls /data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/") + self.driver.Assert.contains(result1, "zsj.json") + self.driver.Assert.contains(result1, "hnp.json") + Step("步骤3:修改私有目录文件内容") + self.driver.shell( + f"cp /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/hnp.json /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/zsj.json") + result2 = self.driver.shell( + "ls /data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/") + self.driver.Assert.contains(result2, "zsj.json") + self.driver.Assert.contains(result2, "hnp.json") + + def teardown(self): + Step("收尾工作:卸载hap") + self.driver.uninstall_app("com.example.hnp_test") diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0900.json b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0900.json new file mode 100644 index 0000000000000000000000000000000000000000..6598b82342f1feadf1a6b58cc0412126b8b6d4d4 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0900.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_hnpinstall/SubStartupAppspawnHnpinstall0900.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0900.py b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0900.py new file mode 100644 index 0000000000000000000000000000000000000000..24bae3ed717610b65db77b058d878414d2e0609d --- /dev/null +++ b/test/autotest/sub_startup_appspawn_hnpinstall/sub_startup_appspawn_hnpinstall_0900.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os +from aw import Common + + +class SubStartupAppspawnHnpinstall0900(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("步骤1:安装测试应用") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-hnpinsall.hap')) + isHap = self.driver.has_app("com.example.hnp_test") + if (isHap): + self.driver.uninstall_app("com.example.hnp_test") + else: + pass + self.driver.install_app(hnp) + Step("是否刷root包") + isroot = self.driver.shell("ls") + if ("Permission denied" in isroot): + Step("步骤2:执行公有目录二进制文件") + th = Common.hnpexecute_async(self.driver, "/data/app/el1/bundle/100/hnppublic/bin/hnpsample 5") + th.start() + result3 = self.driver.shell("ps -ef | grep hnpsample | grep -v grep") + self.driver.Assert.contains(result3, "hnpsample") + Step("步骤3:读取私有目录列表") + result2 = self.driver.shell("./data/app/el1/bundle/100/hnp/com.example.hnp_test/node.org/node_1.0/bin/node") + self.driver.Assert.contains(result2, "inaccessible or not found") + else: + Step("步骤2:执行公有目录二进制文件") + result1 = self.driver.shell("./data/app/el1/bundle/100/hnppublic/hnpsample.org/hnpsample_1.1/bin/hnpsample") + self.driver.Assert.contains(result1, "start hnp sample") + self.driver.Assert.contains(result1, "hnp sample end") + + def teardown(self): + Step("收尾工作:卸载hap") + self.driver.uninstall_app("com.example.hnp_test") diff --git a/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0100.json b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0100.json new file mode 100644 index 0000000000000000000000000000000000000000..c467494bfb5420f44f1207b35bb83f3dde77213b --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0100.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_nativedmscheck/SubStartupAppspawnNativedmscheck0100.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0100.py b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0100.py new file mode 100644 index 0000000000000000000000000000000000000000..a3f4c19127cf6cd2613b6cbbd8b6530c19ed05a5 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0100.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import time +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnNativedmscheck0100(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:唤醒屏幕.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("步骤1:创建公有hnp存放目录") + self.driver.shell("mkdir -p data/no_sign/public") + Step("步骤2:导入安装包文件hnp") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/no_sign/hnpsample.hnp')) + hap = os.path.abspath( + os.path.join(os.path.join(path, "testFile"), + 'SUB_STARTUP_APPSPAWN_NATIVE/no_sign/entry-default-signedArm64.hap')) + self.driver.push_file(hnp, "data/no_sign/public/") + self.driver.push_file(hap, "data/no_sign") + Step("步骤3:执行安装命令") + result = self.driver.shell( + "hnp install -u 100 -p wechat_sign -i /data/no_sign -s /data/no_sign/entry-default-signedArm64-test11.hap -a arm64 -f") + Step("步骤4:预期结果校验") + self.driver.Assert.contains(result, "hnp uninstall start now! name=hnpsample") + self.driver.Assert.contains(result, "native manager process exit. ret=8393475") + + def teardown(self): + self.driver.shell("rm -rf data/no_sign") diff --git a/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0200.json b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0200.json new file mode 100644 index 0000000000000000000000000000000000000000..676d65fa75ef0aa726981bca252773278d0efbc8 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0200.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_nativedmscheck/SubStartupAppspawnNativedmscheck0200.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0200.py b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0200.py new file mode 100644 index 0000000000000000000000000000000000000000..6e495429239e87d5154ddb1903ba1c13a450e70c --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0200.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import time +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnNativedmscheck0200(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:唤醒屏幕.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("步骤1:创建公有hnp存放目录") + self.driver.shell("mkdir -p data/wechat_sign/public") + Step("步骤2:导入安装包文件hnp") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/sign/hnpsample.hnp')) + hap = os.path.abspath( + os.path.join(os.path.join(path, "testFile"), + 'SUB_STARTUP_APPSPAWN_NATIVE/sign/entry-default-signedArm64-test11.hap')) + self.driver.push_file(hnp, "data/wechat_sign/public/") + self.driver.push_file(hap, "data/wechat_sign") + Step("步骤3:执行安装命令") + result1 = self.driver.shell( + "hnp install -u 100 -p wechat_sign -i /data/wechat_sign -s /data/wechat_sign/entry-default-signedArm64-test11.hap -a arm64 -f") + Step("步骤4:预期结果校验") + public = self.driver.shell("ls /data/app/el1/bundle/100/hnppublic/") + self.driver.Assert.contains(public, "hnpsample.org") + result = self.driver.shell("cat /data/service/el1/startup/hnp_info.json") + self.driver.Assert.contains(result, "wechat_sign") + self.driver.Assert.contains(result1, "native manager process exit. ret=0") + self.driver.Assert.contains(result1, "hnp install start now! src file=/data/wechat_sign/public/hnpsample.hnp, dst path=/data/app/el1/bundle/100/hnppublic") + + def teardown(self): + self.driver.shell("rm -rf data/sign") + self.driver.shell("hnp uninstall -u 100 -p wechat_sign") diff --git a/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0300.json b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0300.json new file mode 100644 index 0000000000000000000000000000000000000000..7edfe4b8a76654751870a5a26b54dac071af1f48 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0300.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_nativedmscheck/SubStartupAppspawnNativedmscheck0300.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0300.py b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0300.py new file mode 100644 index 0000000000000000000000000000000000000000..54d9d5e7b2cdb68b6f3a37849cc999d232474568 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0300.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import time +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.action.os_hypium.device_logger import DeviceLogger +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnNativedmscheck0300(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:唤醒屏幕.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('开启DEBUG日志') + self.driver.shell("hilog -b I -D 0xC02C11") + self.driver.shell("hilog -b DEBUG -T APPSPAWN") + self.driver.shell("hilog -b D -D 0xDC02C11") + self.driver.shell("hilog -G 16M") + host.shell('hdc shell "hilog -r"') + + def test_step1(self): + Step("步骤1:安装私有路径hap包") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hap1 = os.path.abspath( + os.path.join(os.path.join(path, "testFile"), + 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-signedArm64Pri-test.hap')) + hap2 = os.path.abspath( + os.path.join(os.path.join(path, "testFile"), + 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-signed-hnpselinux.hap')) + self.driver.install_app(hap1) + self.driver.install_app(hap2) + Step("步骤2:过滤日志") + device_logger = DeviceLogger(self.driver) + device_logger.set_filter_string("MY_TAG") + Step("步骤3:开始抓取日志") + device_logger.start_log(path + '\\testFile\\log\\%s.log' % (self.TAG)) + Step("步骤4:打开测试应用") + self.driver.start_app("com.example.hnpselinuxtestapplication", "EntryAbility") + time.sleep(60) + Step("步骤4:关闭日志") + device_logger.stop_log() + time.sleep(4) + device_logger.check_log('Open public cfg file to read failed, errno=[2]') + device_logger.check_log('Open public cfg file to write failed, errno=[2]') + device_logger.check_log('Open private cfg file to read failed, errno=[2]') + device_logger.check_log('Open private cfg file to write failed, errno=[2]') + + def teardown(self): + Step("收尾工作:删除hap") + self.driver.uninstall_app("com.example.hnp_test") + self.driver.uninstall_app("com.example.hnpselinuxtestapplication") + self.driver.shell("hilog -b I") diff --git a/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0400.json b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0400.json new file mode 100644 index 0000000000000000000000000000000000000000..1aafb7c2674242d73358a98e981940a1ce96b7ca --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0400.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_nativedmscheck/SubStartupAppspawnNativedmscheck0400.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0400.py b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0400.py new file mode 100644 index 0000000000000000000000000000000000000000..2cdbd51ede9dc9df8ee2f2c56e684333c800dc7f --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativedmscheck/sub_startup_appspawn_nativedmscheck_0400.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import time +from devicetest.core.test_case import TestCase, Step, CheckPoint +from devicetest.core.test_case import Step, TestCase +from hypium.action.os_hypium.device_logger import DeviceLogger +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnNativedmscheck0400(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:唤醒屏幕.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('开启DEBUG日志') + self.driver.shell("hilog -b I -D 0xC02C11") + self.driver.shell("hilog -b DEBUG -T APPSPAWN") + self.driver.shell("hilog -b D -D 0xDC02C11") + self.driver.shell("hilog -G 16M") + host.shell('hdc shell "hilog -r"') + + def test_step1(self): + Step("步骤1:安装私有路径hap包") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hap1 = os.path.abspath( + os.path.join(os.path.join(path, "testFile"), + 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-signedArm64-test.hap')) + hap2 = os.path.abspath( + os.path.join(os.path.join(path, "testFile"), + 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-signed-hnpselinux.hap')) + self.driver.install_app(hap1) + self.driver.install_app(hap2) + Step("步骤2:过滤日志") + device_logger = DeviceLogger(self.driver) + device_logger.set_filter_string("MY_TAG") + Step("步骤3:开始抓取日志") + device_logger.start_log(path + '\\testFile\\log\\%s.log' % (self.TAG)) + Step("步骤4:打开测试应用") + self.driver.start_app("com.example.hnpselinuxtestapplication", "EntryAbility") + time.sleep(60) + Step("步骤4:关闭日志") + device_logger.stop_log() + time.sleep(4) + Step("识别设备型号...............................") + device = self.driver.shell("param get const.product.model") + device = device.replace("\n", "").replace(" ", "") + device = str(device) + if ("HYM" in device or "HAD" in device): + device_logger.check_log("cfg file content:") + device_logger.check_log("[This is hnp sample config file.].") + device_logger.check_log("cfg file end") + device_logger.check_log('Open public cfg file to write failed, errno=[13]') + else: + device_logger.check_log('Open public cfg file to read failed, errno=[2]') + device_logger.check_log('Open public cfg file to write failed, errno=[2]') + device_logger.check_log('Open private cfg file to read failed, errno=[2]') + device_logger.check_log('Open private cfg file to write failed, errno=[2]') + + def teardown(self): + Step("收尾工作:删除hap") + self.driver.uninstall_app("com.example.hnp_test") + self.driver.uninstall_app("com.example.hnpselinuxtestapplication") + self.driver.shell("hilog -b I") diff --git a/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0100.json b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0100.json new file mode 100644 index 0000000000000000000000000000000000000000..a8e61cc24d97fb02be064d81093bb19152b4c524 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0100.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_nativepack/SubStartupAppspawnNativepack0100.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0100.py b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0100.py new file mode 100644 index 0000000000000000000000000000000000000000..60b3688b429c62569f356c3885ed973fd16a001b --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0100.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os +import time + + +class SubStartupAppspawnNativepack0100(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('预置工作:新增一个123.txt文件') + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + file = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/sample')) + with open(file + "\\lib\\123.txt", "a+") as f1: + f1.write("12345678hdaskheiwoi4eliqwkldsajoejqooiudsisa") + + def test_step1(self): + Step("获取bat文件路径") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + bat = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/run.bat')) + Step("执行bat文件") + host.shell(bat) + Step("复制压缩文件") + out = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/out/')) + sample = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/sample/')) + file1 = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/out/hnpsample.hnp')) + file2 = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/out/hnpsample.zip')) + host.shell("copy "+file1 + " " + file2) + Step("步骤7:解压hnpsample.zip文件") + host.unzip_file(file2, out) + Step("步骤8:比较2个文件内容是否一致") + time.sleep(1) + dif1 = f.read() + with open(out+"\\sample\\cfg\\hnpsample.cfg") as f: + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + dif1 = f.read() + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + with open(sample + "\\lib\\123.txt") as f: + dif1 = f.read() + with open(out + "\\sample\\lib\\123.txt") as f: + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + + def teardown(self): + Step("收尾工作:删除out目录文件") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + out = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/out/')) \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0200.json b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0200.json new file mode 100644 index 0000000000000000000000000000000000000000..f42ce0d51c895e78db482eea8b4a98aa6be4ecb3 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0200.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_nativepack/SubStartupAppspawnNativepack0200.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0200.py b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0200.py new file mode 100644 index 0000000000000000000000000000000000000000..1a38d824604abd6e2e1d7895afddcdbf4969c03c --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0200.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os +import time + + +class SubStartupAppspawnNativepack0200(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("获取bat文件路径") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + bat = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/run.bat')) + Step("执行bat文件") + host.shell(bat) + Step("复制压缩文件") + out = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/out/')) + sample = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/sample/')) + file1 = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/out/hnpsample.hnp')) + file2 = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/out/hnpsample.zip')) + host.shell("copy "+file1 + " " + file2) + Step("步骤7:解压hnpsample.zip文件") + host.unzip_file(file2, out) + Step("步骤8:比较2个文件内容是否一致") + time.sleep(1) + dif1 = f.read() + with open(out+"\\sample\\cfg\\hnpsample.cfg") as f: + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + dif1 = f.read() + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + + def teardown(self): + Step("收尾工作:删除out目录文件") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + out = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/out/')) \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0300.json b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0300.json new file mode 100644 index 0000000000000000000000000000000000000000..376a9a5ff9b5538b9277a40b82adf2c1757c960c --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0300.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_nativepack/SubStartupAppspawnNativepack0300.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0300.py b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0300.py new file mode 100644 index 0000000000000000000000000000000000000000..9a1631ccc595ad1873debd4bde935c9f41f8b8ec --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0300.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os +import time + + +class SubStartupAppspawnNativepack0300(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('预置工作:修改打包的文件') + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + file = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/sample')) + with open(file+"\\cfg\\hnpsample.cfg", "a") as f1: + f1.write("weuhriqj82hs9九jisapojhwkeioqw8321093nskjdlajejnphoneklv") + time.sleep(2) + + def test_step1(self): + Step("获取bat文件路径") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + bat = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/run.bat')) + Step("执行bat文件") + host.shell(bat) + Step("复制压缩文件") + out = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/out/')) + sample = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/sample/')) + file1 = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/out/hnpsample.hnp')) + file2 = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/out/hnpsample.zip')) + host.shell("copy "+file1 + " " + file2) + Step("步骤7:解压hnpsample.zip文件") + host.unzip_file(file2, out) + Step("步骤8:比较2个文件内容是否一致") + time.sleep(1) + dif1 = f.read() + with open(out+"\\sample\\cfg\\hnpsample.cfg") as f: + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + dif1 = f.read() + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + + def teardown(self): + Step("收尾工作:删除out目录文件") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + out = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/window/out/')) + file = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/sample')) + with open(file + "\\cfg\\hnpsample.cfg", "w") as f1: + f1.write("This is hnp sample config file.") \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0400.json b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0400.json new file mode 100644 index 0000000000000000000000000000000000000000..b615cf0608da074a78ae01c772fad6377a46e5b2 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0400.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_nativepack/SubStartupAppspawnNativepack0400.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0400.py b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0400.py new file mode 100644 index 0000000000000000000000000000000000000000..ed43fa775cd72dbbb90f582ad8cc4b9b3cfd4a92 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0400.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os +import time + + +class SubStartupAppspawnNativepack0400(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + + def test_step1(self): + Step("步骤1:添加读写权限") + self.driver.hdc("target mount") + Step("步骤2:导入打包所需的文件到设备data/usr目录") + self.driver.shell("mkdir data/usr") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + file1 = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/hnpcli')) + file2 = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/sample')) + self.driver.hdc("hdc file send " + file1 + " /data") + self.driver.hdc("hdc file send " + file2 + " /data/usr") + Step("步骤3:添加权限") + self.driver.shell("chmod +x /data/hnpcli") + Step("步骤4:执行打包命令") + self.driver.shell("data/hnpcli pack -i /data/usr/sample -o /data ") + Step("步骤5:复制hnp文件为zip文件") + self.driver.shell("cp /data/hnpsample.hnp /data/hnpsample.zip") + Step("步骤6:导出生成的zip包到本地") + out = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/out/')) + self.driver.hdc("hdc file recv /data/hnpsample.zip "+out) + Step("步骤7:解压hnpsample.zip文件") + Step("步骤8:比较2个文件内容是否一致") + time.sleep(1) + with open(file2+"\\cfg\\hnpsample.cfg") as f: + dif1 = f.read() + with open(out+"\\sample\\cfg\\hnpsample.cfg") as f: + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + dif1 = f.read() + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + + def teardown(self): + Step("收尾工作:删除out目录文件") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + out = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/out/')) + self.driver.shell("rm -rf /data/hnpsample.zip") + self.driver.shell("rm -rf /data/hnpsample.hnp") \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0500.json b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0500.json new file mode 100644 index 0000000000000000000000000000000000000000..ecdac029c621bd4e8a51b5e8534519f0bb211b2c --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0500.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_nativepack/SubStartupAppspawnNativepack0500.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0500.py b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0500.py new file mode 100644 index 0000000000000000000000000000000000000000..a50cf5e1ae633a6040aa9ec0088d9144193c154e --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0500.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import time + +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnNativepack0500(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('预置工作:设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('预置工作:修改打包的文件') + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + file = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/sample')) + with open(file+"\\cfg\\hnpsample.cfg", "a") as f1: + f1.write("weuhriqj82hs9九jisapojhwkeioqw8321093nskjdlajejnphoneklv") + time.sleep(2) + + def test_step1(self): + Step("步骤1:添加读写权限") + self.driver.hdc("target mount") + Step("步骤2:导入打包所需的文件到设备data/usr目录") + self.driver.shell("mkdir data/usr") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + file1 = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/hnpcli')) + file2 = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/sample')) + self.driver.hdc("hdc file send " + file1 + " /data") + self.driver.hdc("hdc file send " + file2 + " /data/usr") + Step("步骤3:添加权限") + self.driver.shell("chmod +x /data/hnpcli") + Step("步骤4:执行打包命令") + self.driver.shell("data/hnpcli pack -i /data/usr/sample -o /data ") + Step("步骤5:复制hnp文件为zip文件") + self.driver.shell("cp /data/hnpsample.hnp /data/hnpsample.zip") + Step("步骤6:导出生成的zip包到本地") + out = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/out/')) + self.driver.hdc("hdc file recv /data/hnpsample.zip " + out) + Step("步骤7:解压hnpsample.zip文件") + host.unzip_file(out + "\\hnpsample.zip", out) + Step("步骤8:比较2个文件内容是否一致") + time.sleep(1) + dif1 = f.read() + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + dif1 = f.read() + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + + def teardown(self): + Step("收尾工作:删除&修改相关文件") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + out = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/out/')) + self.driver.shell("rm -rf /data/hnpsample.zip") + self.driver.shell("rm -rf /data/hnpsample.hnp") + file = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/sample')) + with open(file + "\\cfg\\hnpsample.cfg", "w") as f1: + f1.write("This is hnp sample config file.") + + diff --git a/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0600.json b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0600.json new file mode 100644 index 0000000000000000000000000000000000000000..434e339a270a03da1a2afe35c763e9c27129b54a --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0600.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_nativepack/SubStartupAppspawnNativepack0600.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0600.py b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0600.py new file mode 100644 index 0000000000000000000000000000000000000000..49a7f75cbb19878da24a9352bead5aba1197441f --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativepack/sub_startup_appspawn_nativepack_0600.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import time + +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnNativepack0600(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('预置工作:设置屏幕常亮') + self.driver.Screen.enable_stay_awake() + Step('预置工作:新增一个123.txt文件') + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + file = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/sample')) + f1.write("12345678hdaskheiwoi4eliqwkldsajoejqooiudsisa") + + def test_step1(self): + Step("步骤1:添加读写权限") + self.driver.hdc("target mount") + Step("步骤2:导入打包所需的文件到设备data/usr目录") + self.driver.shell("mkdir data/usr") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + file1 = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/hnpcli')) + file2 = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/sample')) + self.driver.hdc("hdc file send " + file1 + " /data") + self.driver.hdc("hdc file send " + file2 + " /data/usr") + Step("步骤3:添加权限") + self.driver.shell("chmod +x /data/hnpcli") + Step("步骤4:执行打包命令") + self.driver.shell("data/hnpcli pack -i /data/usr/sample -o /data ") + Step("步骤5:复制hnp文件为zip文件") + self.driver.shell("cp /data/hnpsample.hnp /data/hnpsample.zip") + Step("步骤6:导出生成的zip包到本地") + out = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/out/')) + self.driver.hdc("hdc file recv /data/hnpsample.zip " + out) + Step("步骤7:解压hnpsample.zip文件") + host.unzip_file(out + "\\hnpsample.zip", out) + Step("步骤8:比较2个文件内容是否一致") + time.sleep(1) + dif1 = f.read() + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + dif1 = f.read() + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + dif1 = f.read() + with open(out + "\\sample\\lib\\123.txt") as f: + dif2 = f.read() + self.driver.Assert.equal(dif1, dif2) + + def teardown(self): + Step("收尾工作:删除相关文件") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + out = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/out/')) + file = os.path.abspath(os.path.join(os.path.join(path, "testFile"), 'sub_startup_appspawn_nativepack/sample')) + self.driver.shell("rm -rf /data/hnpsample.zip") + self.driver.shell("rm -rf /data/hnpsample.hnp") diff --git a/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess.json b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess.json new file mode 100644 index 0000000000000000000000000000000000000000..8c1a9c370f82a6d7f4b73161a96f4711baaaf2b6 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess.json @@ -0,0 +1,20 @@ +{ + "description": "Config for OpenHarmony app test suites", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTestSuite", + "testsuite": "sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess.py", + "suitecases": [ + "sub_startup_appspawn_nativeprocess/SubStartupAppspawnNativeprocess0100.py", + "sub_startup_appspawn_nativeprocess/SubStartupAppspawnNativeprocess0200.py", + "sub_startup_appspawn_nativeprocess/SubStartupAppspawnNativeprocess0300.py", + "sub_startup_appspawn_nativeprocess/SubStartupAppspawnNativeprocess0400.py", + "sub_startup_appspawn_nativeprocess/SubStartupAppspawnNativeprocess0500.py", + "sub_startup_appspawn_nativeprocess/SubStartupAppspawnNativeprocess0600.py" + ] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess.py b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess.py new file mode 100644 index 0000000000000000000000000000000000000000..3ef49829c029dae5c9a11d1e85fcc6f7ac805dee --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from time import sleep +from devicetest.core.test_case import Step +from devicetest.core.suite.test_suite import TestSuite +from aw import Common + + +class SubStartupAppspawnNativeprocess(TestSuite): + + def setup(self): + Step("TestCase: setup") + self.driver = UiDriver(self.device1) + Step("预置工作:初始化手机开始.................") + Step(self.devices[0].device_id) + Step("导入配置文件.................") + self.driver.hdc("target mount") + sourpath = Common.sourcepath("AppSpawnTest", "sub_startup_appspawn_nativeprocess") + destpath = "/data/AppSpawnTest" + self.driver.push_file(sourpath, destpath) + sleep(3) + Step("给测试文件AppSpawnTest可执行权限.................") + self.driver.shell('chmod +x /data/AppSpawnTest') + self.driver.shell('./data/AppSpawnTest') + + def teardown(self): + Step("收尾工作,删除文件.................") + self.driver.shell("rm /data/AppSpawnTest") diff --git a/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0100.py b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0100.py new file mode 100644 index 0000000000000000000000000000000000000000..26b96df1904c017e9da3ead3684f6f6fab0e04e3 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0100.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import Step, TestCase + + +class SubStartupAppspawnNativeprocess0100(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("TestCase: setup") + Step("预置工作:初始化手机开始.................") + Step(self.devices[0].device_id) + + def test_step1(self): + Step("执行AppSpawnTest'.................") + result = self.driver.shell('./data/AppSpawnTest') + self.driver.Assert.contains(result, "Failed spawn new app result", "默认启动孵化APPSPAWN失败") + + def teardown(self): + Step("TestCase: teardown") diff --git a/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0200.py b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0200.py new file mode 100644 index 0000000000000000000000000000000000000000..27866f8dbb47dacd20bb295eb37ea833a080aef8 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0200.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import Step, TestCase + + +class SubStartupAppspawnNativeprocess0200(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("TestCase: setup") + Step("预置工作:初始化手机开始.................") + Step(self.devices[0].device_id) + + def test_step1(self): + Step("执行AppSpawnTest'.................") + result = self.driver.shell('./data/AppSpawnTest -s -b moduleTestProcessName') + self.driver.Assert.contains(result, "Failed spawn new app result", "带沙盒启动孵化APPSPAWN失败") + Step("执行AppSpawnTest'.................") + failresult = self.driver.shell('./data/AppSpawnTest -s') + self.driver.Assert.contains(failresult, "Failed spawn new app result -1", "模拟'带沙盒启动孵化APPSPAWN失败'失败") + + def teardown(self): + Step("TestCase: teardown") diff --git a/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0400.py b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0400.py new file mode 100644 index 0000000000000000000000000000000000000000..c16add36afe4655238c04353b6c11432565b90ee --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0400.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import Step, TestCase + + +class SubStartupAppspawnNativeprocess0400(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("TestCase: setup") + Step("预置工作:初始化手机开始.................") + Step(self.devices[0].device_id) + + def test_step1(self): + Step("执行AppSpawnTest'.................") + result = self.driver.shell('./data/AppSpawnTest -b ohos.xxxxxx.xxxxxxxx') + self.driver.Assert.contains(result, "Failed spawn new app result", "模拟新app启动孵化APPSPAWN失败") + + def teardown(self): + Step("TestCase: teardown") diff --git a/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0500.py b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0500.py new file mode 100644 index 0000000000000000000000000000000000000000..f10dd2c76e461d75ba339d2645f0e00fe90ea51c --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0500.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import Step, TestCase + + +class SubStartupAppspawnNativeprocess0500(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("TestCase: setup") + Step("预置工作:初始化手机开始.................") + Step(self.devices[0].device_id) + + def test_step1(self): + Step("执行AppSpawnTest'.................") + result = self.driver.shell('./data/AppSpawnTest -b ohos.xxxxxx.xxxxxxxx -s') + self.driver.Assert.contains(result, "Failed spawn new app result -1", "指定不存在app启动孵化APPSPAWN失败") + + def teardown(self): + Step("TestCase: teardown") diff --git a/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0600.py b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0600.py new file mode 100644 index 0000000000000000000000000000000000000000..dc1c22483b4bc252fdac770b4c928a86f32e26a3 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativeprocess/sub_startup_appspawn_nativeprocess_0600.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from devicetest.core.test_case import Step, TestCase + + +class SubStartupAppspawnNativeprocess0600(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("TestCase: setup") + Step("预置工作:初始化手机开始.................") + Step(self.devices[0].device_id) + + def test_step1(self): + Step("执行AppSpawnTest'.................") + result = self.driver.shell('./data/AppSpawnTest -b ohos.xxxxxx.xxxxxxxx -s') + self.driver.Assert.contains(result, "Failed spawn new app result -1", "指定不存在app启动孵化APPSPAWN失败") + Step("执行AppSpawnTest'.................") + successresult = self.driver.shell('./data/AppSpawnTest -C') + self.driver.Assert.contains(result, "Failed spawn new app result", "模拟指定不存在的app启动孵化APPSPAWN失败后,重新启动测试失败") + + def teardown(self): + Step("TestCase: teardown") diff --git a/test/autotest/sub_startup_appspawn_nativesandbox/sub_startup_appspawn_nativesandbox_0100.json b/test/autotest/sub_startup_appspawn_nativesandbox/sub_startup_appspawn_nativesandbox_0100.json new file mode 100644 index 0000000000000000000000000000000000000000..9f5581fd527da1af73a11d798d07844424041a6a --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativesandbox/sub_startup_appspawn_nativesandbox_0100.json @@ -0,0 +1,12 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_nativesandbox/SubStartupAppspawnNativesandbox0100.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativesandbox/sub_startup_appspawn_nativesandbox_0100.py b/test/autotest/sub_startup_appspawn_nativesandbox/sub_startup_appspawn_nativesandbox_0100.py new file mode 100644 index 0000000000000000000000000000000000000000..982ae50835f097aac0b4d293fdfa1fce224a3f27 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativesandbox/sub_startup_appspawn_nativesandbox_0100.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import time +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnNativesandbox0100(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.shell("power-shell timeout -o 2147483647") + + def test_step1(self): + Step("步骤1:创建公有hnp存放目录") + self.driver.shell("mkdir -p data/UCbrowser/public") + Step("步骤2:导入安装包文件hnp") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/sign/hnpsample.hnp')) + hap = os.path.abspath( + os.path.join(os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/sign/entry-default-signedArm64-test11.hap')) + self.driver.push_file(hnp, "data/UCbrowser/public/") + self.driver.push_file(hap, "data/UCbrowser") + Step("步骤3:执行安装命令") + self.driver.shell( + "hnp install -u 100 -p uc_browser -i data/UCbrowser -s data/UCbrowser/entry-default-signedArm64-test11.hap -a arm64 -f") + Step("步骤4:查看是是否安装成功") + public = self.driver.shell("ls /data/app/el1/bundle/100/hnppublic/") + self.driver.Assert.contains(public, "hnpsample.org") + result = self.driver.shell("cat /data/service/el1/startup/hnp_info.json") + self.driver.Assert.contains(result, "uc_browser") + Step("步骤5:安装测试hap包") + ishap = self.driver.has_app("com.example.hnptestapplication") + if (ishap): + hap1 = os.path.abspath( + os.path.join(os.path.join(path, "testFile"), + 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-sandbox.hap')) + self.driver.install_app(hap1) + Step("步骤6:打开测试hap包") + self.driver.shell("aa start -a EntryAbility -b com.example.hnptestapplication") + Step("步骤7:获取测试应用pid") + time.sleep(3) + pid = self.driver.System.get_pid("com.example.hnptestapplication") + Step("步骤8:查看测试应用公有沙箱路径") + result = self.driver.shell("ls /proc/%d/root/data/service/hnp" % pid) + Step("步骤9:预期结果校验") + Step("识别设备型号...............................") + device = self.driver.shell("param get const.product.model") + device = device.replace("\n", "").replace(" ", "") + device = str(device) + if ("HYM" in device or "HAD" in device): + self.driver.Assert.contains(result, "bin") + self.driver.Assert.contains(result, "hnpsample.org") + else: + self.driver.Assert.contains(result, "No such file or directory") + diff --git a/test/autotest/sub_startup_appspawn_nativesandbox/sub_startup_appspawn_nativesandbox_0200.json b/test/autotest/sub_startup_appspawn_nativesandbox/sub_startup_appspawn_nativesandbox_0200.json new file mode 100644 index 0000000000000000000000000000000000000000..700785e5376a083d4bcce2b9f6c967191f4dbe61 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativesandbox/sub_startup_appspawn_nativesandbox_0200.json @@ -0,0 +1,13 @@ +{ + "description": "Config for OpenHarmony devicetest test cases", + "environment": [ + { + "type": "device" + + } + ], + "driver": { + "type": "DeviceTest", + "py_file": ["sub_startup_appspawn_nativesandbox/SubStartupAppspawnNativesandbox0200.py"] + } +} \ No newline at end of file diff --git a/test/autotest/sub_startup_appspawn_nativesandbox/sub_startup_appspawn_nativesandbox_0200.py b/test/autotest/sub_startup_appspawn_nativesandbox/sub_startup_appspawn_nativesandbox_0200.py new file mode 100644 index 0000000000000000000000000000000000000000..d26ab39db79cf70dc7aa7db8bfb2ca2f0e17b2f4 --- /dev/null +++ b/test/autotest/sub_startup_appspawn_nativesandbox/sub_startup_appspawn_nativesandbox_0200.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import time +from devicetest.core.test_case import Step, TestCase +from hypium.model import UiParam, WindowFilter +import os + + +class SubStartupAppspawnNativesandbox0200(TestCase): + + def __init__(self, controllers): + self.tests = [ + "test_step1" + ] + TestCase.__init__(self, self.TAG, controllers) + self.driver = UiDriver(self.device1) + + def setup(self): + Step("预置工作:初始化手机开始.................") + self.driver = UiDriver(self.device1) + Step("预置工作:检测屏幕是否亮.................") + self.driver.enable_auto_wakeup(self.device1) + Step("预置工作:滑动解锁.................") + self.driver.swipe(UiParam.UP, side=UiParam.BOTTOM) + Step('设置屏幕常亮') + self.driver.shell("power-shell timeout -o 2147483647") + + def test_step1(self): + Step("步骤1:创建公有hnp存放目录") + self.driver.shell("mkdir -p data/com.example.hnptestapplication/private") + Step("步骤2:导入安装包文件hnp") + path = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) + hnp = os.path.abspath(os.path.join( + os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/sign/hnpsample.hnp')) + hap = os.path.abspath( + os.path.join(os.path.join(path, "testFile"), 'SUB_STARTUP_APPSPAWN_NATIVE/sign/entry-default-signedArm64-test11.hap')) + self.driver.push_file(hnp, "data/com.example.hnptestapplication/private/") + self.driver.push_file(hap, "data/com.example.hnptestapplication") + Step("步骤3:执行安装命令") + self.driver.shell( + "hnp install -u 100 -p com.example.hnptestapplication -i data/com.example.hnptestapplication -s data/com.example.hnptestapplication/entry-default-signedArm64-test11.hap -a arm64 -f") + Step("步骤4:查看是是否安装成功") + public = self.driver.shell("ls /data/app/el1/bundle/100/hnp/com.example.hnptestapplication") + self.driver.Assert.contains(public, "hnpsample.org") + Step("步骤5:安装测试hap包") + ishap = self.driver.has_app("com.example.hnptestapplication") + if (ishap): + hap1 = os.path.abspath( + os.path.join(os.path.join(path, "testFile"), + 'SUB_STARTUP_APPSPAWN_NATIVE/entry-default-sandbox.hap')) + self.driver.install_app(hap1) + Step("步骤6:打开测试hap包") + self.driver.shell("aa start -a EntryAbility -b com.example.hnptestapplication") + Step("步骤7:获取测试应用pid") + time.sleep(1) + pid = self.driver.System.get_pid("com.example.hnptestapplication") + Step("步骤8:查看测试应用公有沙箱路径") + result = self.driver.shell("ls /proc/%d/root/data/app" % pid) + Step("步骤9:预期结果校验") + Step("识别设备型号...............................") + device = self.driver.shell("param get const.product.model") + device = device.replace("\n", "").replace(" ", "") + device = str(device) + if ("HYM" in device or "HAD" in device): + self.driver.Assert.contains(result, "bin") + self.driver.Assert.contains(result, "hnpsample.org") + else: + self.driver.Assert.contains(result, "No such file or directory") + + def teardown(self): + self.driver.shell("hnp uninstall -u 100 -p com.example.hnptestapplication") diff --git a/test/mock/app_spawn_stub.cpp b/test/mock/app_spawn_stub.cpp index 5de78bf44ed9a0c48bbe465625b96bb6b2fe8494..0ef6d8c2c708d88bdd8f31db9abd63109dadfb30 100644 --- a/test/mock/app_spawn_stub.cpp +++ b/test/mock/app_spawn_stub.cpp @@ -49,6 +49,18 @@ #include #endif +static uint32_t g_preloadParamResult = 0; +static uint32_t g_preloadEtsParamResult = 0; +void SetBoolParamResult(const char *key, bool flag) +{ + if (strcmp(key, "persist.appspawn.preload") == 0) { + flag ? (g_preloadParamResult = true) : (g_preloadParamResult = false); + } + if (strcmp(key, "persist.appspawn.preloadets") == 0) { + flag ? (g_preloadEtsParamResult = true) : (g_preloadEtsParamResult = false); + } +} + namespace OHOS { namespace system { bool GetIntParameter(const std::string &key, bool def, bool arg1 = false, bool arg2 = false) @@ -58,6 +70,12 @@ namespace system { bool GetBoolParameter(const std::string &key, bool def) { + if (strcmp(key.c_str(), "persist.appspawn.preload") == 0) { + return g_preloadParamResult ? true : false; + } + if (strcmp(key.c_str(), "persist.appspawn.preloadets") == 0) { + return g_preloadEtsParamResult ? true : false; + } return def; } } // namespace system diff --git a/test/mock/app_spawn_stub.h b/test/mock/app_spawn_stub.h index 4aaced7181ed22f39c6c46f5b9818bdc27257b43..56de858ed543ed9f3a5727a50cd86fa3038258a5 100644 --- a/test/mock/app_spawn_stub.h +++ b/test/mock/app_spawn_stub.h @@ -27,6 +27,9 @@ #include "appspawn_client.h" #include "appspawn_hook.h" +void SetBoolParamResult(const char *key, bool flag); +int SetSelinuxConNweb(const AppSpawnMgr *content, const AppSpawningCtx *property); + #ifdef __cplusplus extern "C" { #endif @@ -49,10 +52,17 @@ typedef struct TagPathMountNode PathMountNode; typedef struct TagMountArg MountArg; typedef struct TagVarExtraData VarExtraData; typedef struct TagSandboxSection SandboxSection; -typedef struct TagAppSpawnNamespace AppSpawnNamespace; +typedef struct TagAppSpawnNamespace { + AppSpawnExtData extData; + int nsSelfPidFd; + int nsInitPidFd; +} AppSpawnNamespace; typedef struct TagAppSpawnedProcess AppSpawnedProcessInfo; +int AppSpawnExtDataCompareDataId(ListNode *node, void *data); AppSpawnNamespace *GetAppSpawnNamespace(const AppSpawnMgr *content); +int SetPidNamespace(int nsPidFd, int nsType); +AppSpawnNamespace *CreateAppSpawnNamespace(void); void DeleteAppSpawnNamespace(AppSpawnNamespace *ns); void FreeAppSpawnNamespace(struct TagAppSpawnExtData *data); int PreForkSetPidNamespace(AppSpawnMgr *content, AppSpawningCtx *property); @@ -104,6 +114,7 @@ int LoadPermission(AppSpawnClientType type); void DeletePermission(AppSpawnClientType type); int SetProcessName(const AppSpawnMgr *content, const AppSpawningCtx *property); int SetIsolateDir(const AppSpawningCtx *property); +int SetCapabilities(const AppSpawnMgr *content, const AppSpawningCtx *property); int SetFdEnv(AppSpawnMgr *content, AppSpawningCtx *property); int PreLoadEnablePidNs(AppSpawnMgr *content); int NsInitFunc(); @@ -116,6 +127,11 @@ void RunAppSandbox(const char *ptyName); HOOK_MGR *GetAppSpawnHookMgr(void); int SpawnKickDogStart(AppSpawnMgr *mgrContent); int AddPermissionToEncaps(cJSON *extInfoJson, cJSON *encaps, uint32_t *permissionCount); + +#ifdef APPSPAWN_HITRACE_OPTION +int FilterAppSpawnTrace(AppSpawnMgr *content, AppSpawningCtx *property); +#endif + #define STUB_NEED_CHECK 0x01 typedef int (*ExecvFunc)(const char *pathname, char *const argv[]); enum { @@ -134,6 +150,5 @@ StubNode *GetStubNode(int type); #ifdef __cplusplus } #endif -int SetSelinuxConNweb(const AppSpawnMgr *content, const AppSpawningCtx *property); -void InitAppCommonEnv(const AppSpawningCtx *property); + #endif // APPSPAWN_TEST_STUB_H diff --git a/test/mock/js_runtime.h b/test/mock/js_runtime.h index 3870ea6ffed124ec70f4a9efbfcbc2129da70a10..4e05753fdc702c4c35825411f845965c820aa41d 100644 --- a/test/mock/js_runtime.h +++ b/test/mock/js_runtime.h @@ -27,6 +27,7 @@ namespace AbilityRuntime { public: enum class Language { JS = 0, + ETS = 1, }; struct Options { diff --git a/test/moduletest/BUILD.gn b/test/moduletest/BUILD.gn index 79f39b125306497896879413f722f22c8de4f575..2eb10a4a3bcc84b03a9b0e19487c1c30fbb1e90e 100644 --- a/test/moduletest/BUILD.gn +++ b/test/moduletest/BUILD.gn @@ -61,7 +61,7 @@ ohos_moduletest("AppSpawnModuleTest") { sources = [ "${appspawn_path}/test/moduletest/appspawn_client_test.cpp", - "${appspawn_path}/test/moduletest/appspawn_module_test.cpp", + #"${appspawn_path}/test/moduletest/appspawn_module_test.cpp", "${appspawn_path}/test/moduletest/appspawn_test_cmder.cpp", ] diff --git a/test/moduletest/appspawn_client_test.cpp b/test/moduletest/appspawn_client_test.cpp index 3272b03d0322ce0c3d18e8b0bbb21c5cdf3687fa..411d3bfe1aa9656878ef26d7f38026b222d7e8bc 100644 --- a/test/moduletest/appspawn_client_test.cpp +++ b/test/moduletest/appspawn_client_test.cpp @@ -66,7 +66,7 @@ static AppSpawnReqMsgHandle CreateMsg(AppSpawnClientHandle handle, const char *b APPSPAWN_CHECK(ret == 0, break, "Failed to add access token %{public}s", APPSPAWN_SERVER_NAME); static const char *permissions[] = { - "ohos.permission.READ_IMAGEVIDEO", + "ohos.permission.MANAGE_PRIVATE_PHOTOS", "ohos.permission.FILE_CROSS_APP", "ohos.permission.ACTIVATE_THEME_PACKAGE", "ohos.permission.GET_WALLPAPER", diff --git a/test/moduletest/appspawn_test_cmder.cpp b/test/moduletest/appspawn_test_cmder.cpp index 4b35c5aede4b52f6dd812513a1864086a3c095d6..4aa7461dae0e8eec4a1ff869f2a6e78a518442a6 100644 --- a/test/moduletest/appspawn_test_cmder.cpp +++ b/test/moduletest/appspawn_test_cmder.cpp @@ -55,7 +55,7 @@ static const std::string g_defaultAppInfo = "{ \ \"accessTokenIdEx\" : 537854093\ },\ \"permission\" : [\ - \"ohos.permission.READ_IMAGEVIDEO\",\ + \"ohos.permission.MANAGE_PRIVATE_PHOTOS\",\ \"ohos.permission.FILE_CROSS_APP\",\ \"ohos.permission.ACTIVATE_THEME_PACKAGE\"\ ],\ diff --git a/test/moduletest/test_app_info.json b/test/moduletest/test_app_info.json index a25fb501912afaa2a15bc50e96d4acf767d455d3..fea0f4b3c90cb662798e64df2c2c14c1dd0c2db2 100644 --- a/test/moduletest/test_app_info.json +++ b/test/moduletest/test_app_info.json @@ -13,7 +13,7 @@ "accessTokenIdEx": 537854093 }, "permission": [ - "ohos.permission.READ_IMAGEVIDEO", + "ohos.permission.MANAGE_PRIVATE_PHOTOS", "ohos.permission.FILE_CROSS_APP", "ohos.permission.ACTIVATE_THEME_PACKAGE" ], diff --git a/test/test_app_info/permissions/test_app_info1.json b/test/test_app_info/permissions/test_app_info1.json index cccf056a2d23d4e1aa2e312329b86d3b890cc2d5..0c9850b1a0adfd7b9973a2e9a7349c3637ce59b5 100644 --- a/test/test_app_info/permissions/test_app_info1.json +++ b/test/test_app_info/permissions/test_app_info1.json @@ -13,7 +13,7 @@ "accessTokenIdEx": 537854093 }, "permission": [ - "ohos.permission.READ_IMAGEVIDEO" + "ohos.permission.MANAGE_PRIVATE_PHOTOS" ], "internet-permission": { "set-allow-internet": 0, diff --git a/test/test_app_info/permissions/test_app_info2.json b/test/test_app_info/permissions/test_app_info2.json index 7d1703af3f0fcf2cce16168115d0687f6507582a..41963bbc41f90df6110b5f72c57d4cf0a8aec9a4 100644 --- a/test/test_app_info/permissions/test_app_info2.json +++ b/test/test_app_info/permissions/test_app_info2.json @@ -13,7 +13,7 @@ "accessTokenIdEx": 537854093 }, "permission": [ - "ohos.permission.READ_IMAGEVIDEO" + "ohos.permission.MANAGE_PRIVATE_PHOTOS" ], "internet-permission": { "set-allow-internet": 0, diff --git a/test/test_app_info/permissions/test_app_info3.json b/test/test_app_info/permissions/test_app_info3.json index 3b30adc6c58a5245de573a83bfe633188857b823..3de5055cc1f942c312d4ab087f9ba518e36965e2 100644 --- a/test/test_app_info/permissions/test_app_info3.json +++ b/test/test_app_info/permissions/test_app_info3.json @@ -13,7 +13,7 @@ "accessTokenIdEx": 537854093 }, "permission": [ - "ohos.permission.READ_IMAGEVIDEO" + "ohos.permission.MANAGE_PRIVATE_PHOTOS" ], "internet-permission": { "set-allow-internet": 0, diff --git a/test/test_app_info/permissions/test_app_info4.json b/test/test_app_info/permissions/test_app_info4.json index 096dd38dbdf194babf4a92667e2b10bfea5bf920..a7a28f9e39c75aa50c7b8a7f9e807ab7cf5e9c0f 100644 --- a/test/test_app_info/permissions/test_app_info4.json +++ b/test/test_app_info/permissions/test_app_info4.json @@ -13,7 +13,7 @@ "accessTokenIdEx": 537854093 }, "permission": [ - "ohos.permission.READ_IMAGEVIDEO" + "ohos.permission.MANAGE_PRIVATE_PHOTOS" ], "internet-permission": { "set-allow-internet": 0, diff --git a/test/unittest/app_spawn_client_test/BUILD.gn b/test/unittest/app_spawn_client_test/BUILD.gn index 7d874cfa1db83cc5fe5d234ebec90ccad6b0bcde..d8c8f61c3178c73c63d1550aa5713eac2be0bc77 100644 --- a/test/unittest/app_spawn_client_test/BUILD.gn +++ b/test/unittest/app_spawn_client_test/BUILD.gn @@ -39,6 +39,8 @@ ohos_unittest("AppSpawn_client_ut") { "${appspawn_path}/modules/ace_adapter", "${appspawn_path}/modules/common", "${appspawn_path}/modules/sandbox", + "${appspawn_path}/modules/sandbox/normal", + "${appspawn_path}/modules/sandbox/modern", "${appspawn_path}/modules/module_engine/include", "${appspawn_path}/modules/sysevent", "${appspawn_innerkits_path}/client", @@ -92,6 +94,12 @@ ohos_unittest("AppSpawn_client_ut") { "hitrace:hitrace_meter", "init:libbegetutil", ] + + if (appspawn_hitrace_option == true) { + defines += [ "APPSPAWN_HITRACE_OPTION" ] + external_deps += [ "hitrace:libhitrace_option" ] + } + if (enable_appspawn_dump_catcher) { external_deps += [ "faultloggerd:libdfx_dumpcatcher" ] } diff --git a/test/unittest/app_spawn_client_test/app_spawn_interface_test.cpp b/test/unittest/app_spawn_client_test/app_spawn_interface_test.cpp index 755c1c3f50cd3502184e6e2369969850ceab8283..60386f6b8cb7f8c2f7657dfb2ee375431d333c25 100644 --- a/test/unittest/app_spawn_client_test/app_spawn_interface_test.cpp +++ b/test/unittest/app_spawn_client_test/app_spawn_interface_test.cpp @@ -369,7 +369,7 @@ HWTEST_F(AppSpawnInterfaceTest, App_Spawn_Interface_Add_Permission_001, TestSize EXPECT_EQ(0, ret); const AppSpawnReqMsgHandle inputHandle[] = {reqHandle, nullptr}; - const char *permission[] = {"ohos.permission.READ_IMAGEVIDEO", "", nullptr}; + const char *permission[] = {"ohos.permission.MANAGE_PRIVATE_PHOTOS", "", nullptr}; for (size_t i = 0; i < ARRAY_LENGTH(inputHandle); i++) { for (size_t j = 0; j < ARRAY_LENGTH(permission); j++) { printf("App_Spawn_Interface_Add_Permission_001 %zu %zu %d \n", i, j, ret); diff --git a/test/unittest/app_spawn_standard_test/BUILD.gn b/test/unittest/app_spawn_standard_test/BUILD.gn index 92ece3b5cff4a02fbd1fa9e02dca15096dda55ba..820b49d3b7c975b4c2ddf3c2b7a2cb72de638c46 100644 --- a/test/unittest/app_spawn_standard_test/BUILD.gn +++ b/test/unittest/app_spawn_standard_test/BUILD.gn @@ -16,8 +16,9 @@ import("//build/test.gni") ohos_unittest("AppSpawn_ut") { module_out_path = "appspawn/appspawn" + cflags = [ "-Dprivate=public" ] if (appspawn_unittest_coverage) { - cflags = [ "--coverage" ] + cflags += [ "--coverage" ] ldflags = [ "--coverage" ] cflags_cc = [ "--coverage" ] } @@ -64,6 +65,8 @@ ohos_unittest("AppSpawn_ut") { "${appspawn_path}/modules/ace_adapter", "${appspawn_path}/modules/common", "${appspawn_path}/modules/sandbox", + "${appspawn_path}/modules/sandbox/normal", + "${appspawn_path}/modules/sandbox/modern", "${appspawn_path}/modules/sysevent", "${appspawn_innerkits_path}/client", "${appspawn_innerkits_path}/include", @@ -104,14 +107,15 @@ ohos_unittest("AppSpawn_ut") { "${appspawn_path}/modules/common/appspawn_namespace.c", "${appspawn_path}/modules/common/appspawn_silk.c", "${appspawn_path}/modules/nweb_adapter/nwebspawn_adapter.cpp", - "${appspawn_path}/modules/sandbox/appspawn_mount_template.c", + "${appspawn_path}/modules/sandbox/modern/appspawn_mount_template.c", "${appspawn_path}/modules/sandbox/appspawn_permission.c", - "${appspawn_path}/modules/sandbox/appspawn_sandbox.c", - "${appspawn_path}/modules/sandbox/sandbox_adapter.cpp", - "${appspawn_path}/modules/sandbox/sandbox_cfgvar.c", - "${appspawn_path}/modules/sandbox/sandbox_expand.c", - "${appspawn_path}/modules/sandbox/sandbox_load.c", - "${appspawn_path}/modules/sandbox/sandbox_manager.c", + "${appspawn_path}/modules/sandbox/modern/appspawn_sandbox.c", + "${appspawn_path}/modules/sandbox/modern/sandbox_adapter.cpp", + "${appspawn_path}/modules/sandbox/modern/sandbox_cfgvar.c", + "${appspawn_path}/modules/sandbox/sandbox_dec.c", + "${appspawn_path}/modules/sandbox/modern/sandbox_expand.c", + "${appspawn_path}/modules/sandbox/modern/sandbox_load.c", + "${appspawn_path}/modules/sandbox/modern/sandbox_manager.c", ] # add stub @@ -133,6 +137,7 @@ ohos_unittest("AppSpawn_ut") { "${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_module_interface_test.cpp", "${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_sandboxmgr_test.cpp", "${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_service_test.cpp", + "${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_silk_test.cpp", "${appspawn_path}/test/unittest/app_spawn_standard_test/nweb_spawn_service_test.cpp", "${appspawn_path}/test/unittest/app_spawn_test_helper.cpp", ] @@ -146,8 +151,10 @@ ohos_unittest("AppSpawn_ut") { defines += [ "APPSPAWN_SANDBOX_NEW" ] } else { sources += [ - "${appspawn_path}/modules/sandbox/sandbox_shared_mount.cpp", - "${appspawn_path}/modules/sandbox/sandbox_utils.cpp", + "${appspawn_path}/modules/sandbox/normal/sandbox_shared_mount.cpp", + "${appspawn_path}/modules/sandbox/normal/sandbox_core.cpp", + "${appspawn_path}/modules/sandbox/normal/sandbox_common.cpp", + "${appspawn_path}/modules/sandbox/normal/appspawn_sandbox_manager.cpp", "${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp", ] } @@ -177,6 +184,12 @@ ohos_unittest("AppSpawn_ut") { "os_account:os_account_innerkits", "resource_management:global_resmgr", ] + + if (appspawn_hitrace_option == true) { + defines += [ "APPSPAWN_HITRACE_OPTION" ] + external_deps += [ "hitrace:libhitrace_option" ] + } + if (enable_appspawn_dump_catcher) { external_deps += [ "faultloggerd:libdfx_dumpcatcher" ] } @@ -216,8 +229,9 @@ ohos_unittest("AppSpawn_ut") { ohos_unittest("AppSpawn_coldrun_ut") { module_out_path = "appspawn/appspawn" + cflags = [ "-Dprivate=public" ] if (appspawn_unittest_coverage) { - cflags = [ "--coverage" ] + cflags += [ "--coverage" ] ldflags = [ "--coverage" ] cflags_cc = [ "--coverage" ] } @@ -264,6 +278,8 @@ ohos_unittest("AppSpawn_coldrun_ut") { "${appspawn_path}/modules/ace_adapter", "${appspawn_path}/modules/common", "${appspawn_path}/modules/sandbox", + "${appspawn_path}/modules/sandbox/normal", + "${appspawn_path}/modules/sandbox/modern", "${appspawn_path}/modules/sysevent", "${appspawn_innerkits_path}/client", "${appspawn_innerkits_path}/include", @@ -304,14 +320,15 @@ ohos_unittest("AppSpawn_coldrun_ut") { "${appspawn_path}/modules/common/appspawn_namespace.c", "${appspawn_path}/modules/common/appspawn_silk.c", "${appspawn_path}/modules/nweb_adapter/nwebspawn_adapter.cpp", - "${appspawn_path}/modules/sandbox/appspawn_mount_template.c", + "${appspawn_path}/modules/sandbox/modern/appspawn_mount_template.c", "${appspawn_path}/modules/sandbox/appspawn_permission.c", - "${appspawn_path}/modules/sandbox/appspawn_sandbox.c", - "${appspawn_path}/modules/sandbox/sandbox_adapter.cpp", - "${appspawn_path}/modules/sandbox/sandbox_cfgvar.c", - "${appspawn_path}/modules/sandbox/sandbox_expand.c", - "${appspawn_path}/modules/sandbox/sandbox_load.c", - "${appspawn_path}/modules/sandbox/sandbox_manager.c", + "${appspawn_path}/modules/sandbox/modern/appspawn_sandbox.c", + "${appspawn_path}/modules/sandbox/modern/sandbox_adapter.cpp", + "${appspawn_path}/modules/sandbox/modern/sandbox_cfgvar.c", + "${appspawn_path}/modules/sandbox/sandbox_dec.c", + "${appspawn_path}/modules/sandbox/modern/sandbox_expand.c", + "${appspawn_path}/modules/sandbox/modern/sandbox_load.c", + "${appspawn_path}/modules/sandbox/modern/sandbox_manager.c", ] if (appspawn_use_encaps == true) { @@ -337,8 +354,10 @@ ohos_unittest("AppSpawn_coldrun_ut") { sources += [ "${appspawn_path}/modules/sandbox/sandbox_shared.c" ] } else { sources += [ - "${appspawn_path}/modules/sandbox/sandbox_shared_mount.cpp", - "${appspawn_path}/modules/sandbox/sandbox_utils.cpp", + "${appspawn_path}/modules/sandbox/normal/sandbox_shared_mount.cpp", + "${appspawn_path}/modules/sandbox/normal/sandbox_core.cpp", + "${appspawn_path}/modules/sandbox/normal/sandbox_common.cpp", + "${appspawn_path}/modules/sandbox/normal/appspawn_sandbox_manager.cpp", ] } @@ -406,8 +425,9 @@ ohos_unittest("AppSpawn_coldrun_ut") { ohos_unittest("AppSpawn_common_ut") { module_out_path = "appspawn/appspawn" + cflags = [ "-Dprivate=public" ] if (appspawn_unittest_coverage) { - cflags = [ "--coverage" ] + cflags += [ "--coverage" ] ldflags = [ "--coverage" ] cflags_cc = [ "--coverage" ] } @@ -454,6 +474,8 @@ ohos_unittest("AppSpawn_common_ut") { "${appspawn_path}/modules/ace_adapter", "${appspawn_path}/modules/common", "${appspawn_path}/modules/sandbox", + "${appspawn_path}/modules/sandbox/normal", + "${appspawn_path}/modules/sandbox/modern", "${appspawn_path}/modules/sysevent", "${appspawn_innerkits_path}/client", "${appspawn_innerkits_path}/include", @@ -495,14 +517,15 @@ ohos_unittest("AppSpawn_common_ut") { "${appspawn_path}/modules/common/appspawn_namespace.c", "${appspawn_path}/modules/common/appspawn_silk.c", "${appspawn_path}/modules/nweb_adapter/nwebspawn_adapter.cpp", - "${appspawn_path}/modules/sandbox/appspawn_mount_template.c", + "${appspawn_path}/modules/sandbox/modern/appspawn_mount_template.c", "${appspawn_path}/modules/sandbox/appspawn_permission.c", - "${appspawn_path}/modules/sandbox/appspawn_sandbox.c", - "${appspawn_path}/modules/sandbox/sandbox_adapter.cpp", - "${appspawn_path}/modules/sandbox/sandbox_cfgvar.c", - "${appspawn_path}/modules/sandbox/sandbox_expand.c", - "${appspawn_path}/modules/sandbox/sandbox_load.c", - "${appspawn_path}/modules/sandbox/sandbox_manager.c", + "${appspawn_path}/modules/sandbox/modern/appspawn_sandbox.c", + "${appspawn_path}/modules/sandbox/modern/sandbox_adapter.cpp", + "${appspawn_path}/modules/sandbox/modern/sandbox_cfgvar.c", + "${appspawn_path}/modules/sandbox/sandbox_dec.c", + "${appspawn_path}/modules/sandbox/modern/sandbox_expand.c", + "${appspawn_path}/modules/sandbox/modern/sandbox_load.c", + "${appspawn_path}/modules/sandbox/modern/sandbox_manager.c", ] # add stub @@ -515,6 +538,7 @@ ohos_unittest("AppSpawn_common_ut") { # add test include_dirs += [ "${appspawn_path}/test/unittest" ] sources += [ + "${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_ace_test.cpp", "${appspawn_path}/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp", "${appspawn_path}/test/unittest/app_spawn_test_helper.cpp", ] @@ -524,8 +548,10 @@ ohos_unittest("AppSpawn_common_ut") { sources += [ "${appspawn_path}/modules/sandbox/sandbox_shared.c" ] } else { sources += [ - "${appspawn_path}/modules/sandbox/sandbox_shared_mount.cpp", - "${appspawn_path}/modules/sandbox/sandbox_utils.cpp", + "${appspawn_path}/modules/sandbox/normal/sandbox_shared_mount.cpp", + "${appspawn_path}/modules/sandbox/normal/sandbox_core.cpp", + "${appspawn_path}/modules/sandbox/normal/sandbox_common.cpp", + "${appspawn_path}/modules/sandbox/normal/appspawn_sandbox_manager.cpp", ] } diff --git a/test/unittest/app_spawn_standard_test/app_spawn_ace_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_ace_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9dfb2c6759a3710fba41b394e555e1e941227eb6 --- /dev/null +++ b/test/unittest/app_spawn_standard_test/app_spawn_ace_test.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "appspawn.h" +#include "appspawn_hook.h" +#include "appspawn_manager.h" +#include "app_spawn_stub.h" +#include "app_spawn_test_helper.h" + +using namespace testing; +using namespace testing::ext; +using namespace OHOS; + +APPSPAWN_STATIC int RunChildThread(const AppSpawnMgr *content, const AppSpawningCtx *property); +APPSPAWN_STATIC int RunChildByRenderCmd(const AppSpawnMgr *content, const AppSpawningCtx *property); +APPSPAWN_STATIC int PreLoadAppSpawn(AppSpawnMgr *content); +APPSPAWN_STATIC int DlopenAppSpawn(AppSpawnMgr *content); + +namespace OHOS { +static AppSpawnTestHelper g_testHelper; +class AppSpawnAceTest : public testing::Test { +public: + static void SetUpTestCase() {} + static void TearDownTestCase() {} + void SetUp() {} + void TearDown() {} +}; + +/** + * @brief nwebspawn进行预加载 + * @note 预期结果: nwebspawn不支持预加载,直接返回 + * + */ +HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_Preload_001, TestSize.Level0) +{ + AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_NWEB_SPAWN); + ASSERT_NE(mgr, nullptr); + mgr->content.longProcName = const_cast(NWEBSPAWN_SERVER_NAME); + mgr->content.longProcNameLen = APP_LEN_PROC_NAME; + + int ret = PreLoadAppSpawn(mgr); + DeleteAppSpawnMgr(mgr); + EXPECT_EQ(ret, 0); +} + +/** + * @brief cjappspawn进行预加载 + * @note 预期结果: cjappspawn通过processName校验,执行LoadExtendCJLib预加载 + * + */ +HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_Preload_002, TestSize.Level0) +{ + AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_CJAPP_SPAWN); + ASSERT_NE(mgr, nullptr); + mgr->content.longProcName = const_cast(CJAPPSPAWN_SERVER_NAME); + mgr->content.longProcNameLen = APP_LEN_PROC_NAME; + + int ret = PreLoadAppSpawn(mgr); + DeleteAppSpawnMgr(mgr); + EXPECT_EQ(ret, 0); +} + +/** + * @brief 未设置preload参数时(使用参数默认值),appspawn进行预加载 + * @note 预期结果: appspawn根据参数默认值判断是否执行preload预加载 + * + */ +HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_Preload_003, TestSize.Level0) +{ + AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN); + ASSERT_NE(mgr, nullptr); + mgr->content.longProcName = const_cast(APPSPAWN_SERVER_NAME); + mgr->content.longProcNameLen = APP_LEN_PROC_NAME; + + int ret = PreLoadAppSpawn(mgr); + DeleteAppSpawnMgr(mgr); + EXPECT_EQ(ret, 0); +} + +/** + * @brief preload参数设置为true时,测试appspawn进行预加载 + * @note 预期结果: appspawn执行preload预加载 + * + */ +HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_Preload_004, TestSize.Level0) +{ + AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN); + ASSERT_NE(mgr, nullptr); + mgr->content.longProcName = const_cast(APPSPAWN_SERVER_NAME); + mgr->content.longProcNameLen = APP_LEN_PROC_NAME; + + SetBoolParamResult("presist.appspwn.preload", true); + int ret = PreLoadAppSpawn(mgr); + SetBoolParamResult("presist.appspwn.preload", false); + DeleteAppSpawnMgr(mgr); + EXPECT_EQ(ret, 0); +} + +/** + * @brief preload参数和preloadets参数均设置为true时,测试appspawn进行预加载 + * @note 预期结果: appspawn执行preload和preloadets预加载 + * + */ +HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_Preload_005, TestSize.Level0) +{ + AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN); + ASSERT_NE(mgr, nullptr); + mgr->content.longProcName = const_cast(APPSPAWN_SERVER_NAME); + mgr->content.longProcNameLen = APP_LEN_PROC_NAME; + + SetBoolParamResult("presist.appspwn.preload", true); + SetBoolParamResult("presist.appspwn.preloadets", true); + int ret = PreLoadAppSpawn(mgr); + SetBoolParamResult("presist.appspwn.preload", false); + SetBoolParamResult("presist.appspwn.preloadets", false); + DeleteAppSpawnMgr(mgr); + EXPECT_EQ(ret, 0); +} + +/** + * @brief nwebspawn进行加载system libs + * @note 预期结果: nwebspawn不支持加载system libs,直接返回 + * + */ +HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_Dlopen_001, TestSize.Level0) +{ + AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_NWEB_SPAWN); + ASSERT_NE(mgr, nullptr); + + int ret = DlopenAppSpawn(mgr); + DeleteAppSpawnMgr(mgr); + EXPECT_EQ(ret, 0); +} + +/** + * @brief appspawn进行加载system libs + * @note 预期结果: appspawn加载system libs正常 + * + */ +HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_Dlopen_002, TestSize.Level0) +{ + AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN); + ASSERT_NE(mgr, nullptr); + + int ret = DlopenAppSpawn(mgr); + DeleteAppSpawnMgr(mgr); + EXPECT_EQ(ret, 0); +} + +/** + * @brief appspawn执行RunChildThread + * @note 预期结果: 执行正常,分支覆盖 + * + */ +HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_RunChild_001, TestSize.Level0) +{ + AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN); + ASSERT_NE(mgr, nullptr); + AppSpawningCtx *property = CreateAppSpawningCtx(); + ASSERT_NE(property, nullptr); + property->message = CreateAppSpawnMsg(); + ASSERT_NE(property->message, nullptr); + + int ret = RunChildThread(mgr, property); + DeleteAppSpawningCtx(property); + DeleteAppSpawnMgr(mgr); + EXPECT_EQ(ret, 0); +} + +/** + * @brief appspawn执行RunChildByRenderCmd + * @note 预期结果: 执行正常,分支覆盖 + * + */ +HWTEST_F(AppSpawnAceTest, App_Spawn_Ace_RunChild_002, TestSize.Level0) +{ + AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN); + ASSERT_NE(mgr, nullptr); + AppSpawningCtx *property = CreateAppSpawningCtx(); + ASSERT_NE(property, nullptr); + property->message = CreateAppSpawnMsg(); + ASSERT_NE(property->message, nullptr); + + int ret = RunChildByRenderCmd(mgr, property); + DeleteAppSpawningCtx(property); + DeleteAppSpawnMgr(mgr); + EXPECT_EQ(ret, -1); +} +} // namespace OHOS diff --git a/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp index e10b6d13d547a442a32be7b4a86108b7be4fc8e5..c0f2bed163524b12efcb04d3dd3870c10ad1102a 100644 --- a/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp +++ b/test/unittest/app_spawn_standard_test/app_spawn_common_test.cpp @@ -40,11 +40,6 @@ using namespace testing; using namespace testing::ext; using namespace OHOS; -APPSPAWN_STATIC int BuildFdInfoMap(const AppSpawnMsgNode *message, std::map &fdMap, int isColdRun); -APPSPAWN_STATIC void LoadExtendCJLib(void); -APPSPAWN_STATIC int PreLoadAppSpawn(AppSpawnMgr *content); -APPSPAWN_STATIC int RunChildByRenderCmd(const AppSpawnMgr *content, const AppSpawningCtx *property); - namespace OHOS { static AppSpawnTestHelper g_testHelper; class AppSpawnCommonTest : public testing::Test { @@ -390,60 +385,6 @@ HWTEST_F(AppSpawnCommonTest, App_Spawn_Common_016, TestSize.Level0) AppSpawnHiSysEventWrite(); } -HWTEST_F(AppSpawnCommonTest, App_Spawn_Common_017, TestSize.Level0) -{ - AppSpawnMgr *content = CreateAppSpawnMgr(MODE_FOR_NWEB_SPAWN); - EXPECT_EQ(content != nullptr, 1); - int ret = -1; - do { - LoadExtendCJLib(); - } while (0); - DeleteAppSpawnMgr(content); - ASSERT_EQ(ret, -1); -} - -HWTEST_F(AppSpawnCommonTest, App_Spawn_Common_018, TestSize.Level0) -{ - AppSpawnMgr *content = CreateAppSpawnMgr(MODE_FOR_NWEB_SPAWN); - EXPECT_EQ(content != nullptr, 1); - int ret = -1; - do { - // spawn - ret = PreLoadAppSpawn(content); - } while (0); - DeleteAppSpawnMgr(content); - ASSERT_EQ(ret, 0); -} - -HWTEST_F(AppSpawnCommonTest, App_Spawn_Common_019, TestSize.Level0) -{ - AppSpawnMgr *content = CreateAppSpawnMgr(MODE_FOR_NWEB_SPAWN); - EXPECT_EQ(content != nullptr, 1); - int ret = -1; - do { - RunChildByRenderCmd(nullptr, nullptr); - } while (0); - DeleteAppSpawnMgr(content); - ASSERT_EQ(ret, -1); -} - -HWTEST_F(AppSpawnCommonTest, App_Spawn_Common_020, TestSize.Level0) -{ - AppSpawnMgr *content = CreateAppSpawnMgr(MODE_FOR_NWEB_SPAWN); - EXPECT_EQ(content != nullptr, 1); - int ret = -1; - do { - // spawn - AppSpawnMsgNode *msgNode = CreateAppSpawnMsg(); - EXPECT_EQ(msgNode != nullptr, 1); - std::map fdMap; - ret = BuildFdInfoMap(msgNode, fdMap, 0); - } while (0); - DeleteAppSpawnMgr(content); - ASSERT_EQ(ret, -1); -} - - HWTEST_F(AppSpawnCommonTest, App_Spawn_Common_021, TestSize.Level0) { int ret = SetInternetPermission(nullptr); @@ -658,6 +599,81 @@ HWTEST_F(AppSpawnCommonTest, App_Spawn_Common_031, TestSize.Level0) AppSpawnClientInit(nullptr, nullptr); } +HWTEST_F(AppSpawnCommonTest, App_Spawn_Common_GetAppSpawnNamespace, TestSize.Level0) +{ + int ret = -1; + AppSpawnMgr *mgr = nullptr; + AppSpawnNamespace *appSpawnNamespace = nullptr; + mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN); + EXPECT_EQ(mgr != nullptr, 1); + appSpawnNamespace = CreateAppSpawnNamespace(); + appSpawnNamespace->nsSelfPidFd = GetNsPidFd(getpid()); + OH_ListInit(&appSpawnNamespace->extData.node); + OH_ListAddTail(&mgr->extData, &appSpawnNamespace->extData.node); + AppSpawnNamespace *appSpawnNamespace1 = nullptr; + appSpawnNamespace1 = GetAppSpawnNamespace(mgr); + EXPECT_EQ(appSpawnNamespace1 != nullptr, 1); + uint32_t dataId = EXT_DATA_NAMESPACE; + AppSpawnExtDataCompareDataId(&mgr->extData, (void *)&dataId); + DeleteAppSpawnNamespace(appSpawnNamespace); + DeleteAppSpawnMgr(mgr); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Common_GetPidByName, TestSize.Level0) +{ + int ret = -1; + AppSpawnMgr *mgr = nullptr; + AppSpawnNamespace *appSpawnNamespace = nullptr; + mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN); + EXPECT_EQ(mgr != nullptr, 1); + appSpawnNamespace = CreateAppSpawnNamespace(); + OH_ListInit(&appSpawnNamespace->extData.node); + OH_ListAddTail(&mgr->extData, &appSpawnNamespace->extData.node); + appSpawnNamespace->nsInitPidFd = GetNsPidFd(getpid()); + pid_t pid = GetPidByName("appspawn"); + EXPECT_EQ(pid > 0, 1); + DeleteAppSpawnNamespace(appSpawnNamespace); + DeleteAppSpawnMgr(mgr); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Common_PreLoadEnablePidNs, TestSize.Level0) +{ + int ret = -1; + AppSpawnMgr *mgr = nullptr; + AppSpawnNamespace *appSpawnNamespace = nullptr; + mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN); + EXPECT_EQ(mgr != nullptr, 1); + mgr->content.sandboxNsFlags = CLONE_NEWPID; + ret = PreLoadEnablePidNs(mgr); + EXPECT_EQ(ret, 0); + AppSpawnNamespace *appSpawnNamespace1 = nullptr; + appSpawnNamespace1 = GetAppSpawnNamespace(mgr); + EXPECT_EQ(appSpawnNamespace1 != nullptr, 1); + DeleteAppSpawnNamespace(appSpawnNamespace); + DeleteAppSpawnMgr(mgr); + SetPidNamespace(0, 0); +} + +HWTEST_F(AppSpawnCommonTest, App_Spawn_Common_PreForkSetPidNamespace, TestSize.Level0) +{ + int ret = -1; + AppSpawnMgr *mgr = nullptr; + AppSpawnNamespace *appSpawnNamespace = nullptr; + mgr = CreateAppSpawnMgr(MODE_FOR_APP_SPAWN); + EXPECT_EQ(mgr != nullptr, 1); + mgr->content.sandboxNsFlags = CLONE_NEWPID; + ret = PreLoadEnablePidNs(mgr); + EXPECT_EQ(ret, 0); + PreForkSetPidNamespace(mgr, nullptr); + PostForkSetPidNamespace(mgr, nullptr); + mgr->content.sandboxNsFlags = 0; + PreForkSetPidNamespace(mgr, nullptr); + PostForkSetPidNamespace(mgr, nullptr); + DeleteAppSpawnNamespace(appSpawnNamespace); + DeleteAppSpawnMgr(mgr); + SetPidNamespace(0, 0); +} + HWTEST_F(AppSpawnCommonTest, App_Spawn_Encaps_001, TestSize.Level0) { const char encapsJsonStr[] = "{\"name\":\"Permissions\",\"ohos.encaps.count\":0,\"permissions\":" @@ -812,4 +828,56 @@ HWTEST_F(AppSpawnCommonTest, App_Spawn_SetIsolateDir, TestSize.Level0) ASSERT_EQ(ret, 0); } +#ifdef APPSPAWN_HITRACE_OPTION +HWTEST_F(AppSpawnCommonTest, App_Spawn_FilterAppSpawnTrace, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + int ret = -1; + FilterAppSpawnTrace(nullptr, property); + EXPECT_EQ(property, nullptr); + + do { + ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", APPSPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, + "Failed to create req %{public}s", APPSPAWN_SERVER_NAME); + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + FilterAppSpawnTrace(nullptr, property); + } while (0); + + DeleteAppSpawningCtx(property); + AppSpawnClientDestroy(clientHandle); +} +#endif + +HWTEST_F(AppSpawnCommonTest, App_Spawn_SetCapabilities, TestSize.Level0) +{ + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnReqMsgHandle reqHandle = 0; + AppSpawningCtx *property = nullptr; + AppSpawnMgr *mgr = nullptr; + int ret = -1; + do { + mgr = CreateAppSpawnMgr(MODE_FOR_NWEB_SPAWN); + EXPECT_EQ(mgr != nullptr, 1); + // create msg + ret = AppSpawnClientInit(NWEBSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create reqMgr %{public}s", NWEBSPAWN_SERVER_NAME); + reqHandle = g_testHelper.CreateMsg(clientHandle, MSG_APP_SPAWN, 0); + APPSPAWN_CHECK(reqHandle != INVALID_REQ_HANDLE, break, + "Failed to create req %{public}s", NWEBSPAWN_SERVER_NAME); + property = g_testHelper.GetAppProperty(clientHandle, reqHandle); + APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, break); + ret = SetCapabilities(mgr, property); + } while (0); + DeleteAppSpawningCtx(property); + AppSpawnClientDestroy(clientHandle); + DeleteAppSpawnMgr(mgr); + ASSERT_EQ(ret, 0); +} + } // namespace OHOS diff --git a/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp index 85a6f01e2ff0490c6c4be91354dba7d848b0b803..d0e46d925edb1482273e2b9ccf83a7a2bca2316b 100644 --- a/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp +++ b/test/unittest/app_spawn_standard_test/app_spawn_sandbox_test.cpp @@ -23,17 +23,19 @@ #include "appspawn_service.h" #include "json_utils.h" #include "parameter.h" -#include "sandbox_utils.h" +#include "sandbox_def.h" +#include "sandbox_core.h" +#include "sandbox_common.h" #include "securec.h" #include "app_spawn_stub.h" #include "app_spawn_test_helper.h" +#include "sandbox_dec.h" #include "sandbox_shared_mount.h" using namespace testing; using namespace testing::ext; using namespace OHOS::AppSpawn; -using nlohmann::json; namespace OHOS { AppSpawnTestHelper g_testHelper; @@ -50,9 +52,33 @@ void AppSpawnSandboxTest::SetUpTestCase() {} void AppSpawnSandboxTest::TearDownTestCase() {} -void AppSpawnSandboxTest::SetUp() {} +void AppSpawnSandboxTest::SetUp() { + const TestInfo *info = UnitTest::GetInstance()->current_test_info(); + GTEST_LOG_(INFO) << info->test_suite_name() << "." << info->name() << " start"; + APPSPAWN_LOGI("%{public}s.%{public}s start", info->test_suite_name(), info->name()); -void AppSpawnSandboxTest::TearDown() {} + std::vector &appVec = + AppSpawn::SandboxCommon::GetCJsonConfig(SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); + appVec.erase(appVec.begin(), appVec.end()); + + std::vector &isolatedVec = + AppSpawn::SandboxCommon::GetCJsonConfig(SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG); + isolatedVec.erase(isolatedVec.begin(), isolatedVec.end()); +} + +void AppSpawnSandboxTest::TearDown() { + std::vector &appVec = + AppSpawn::SandboxCommon::GetCJsonConfig(SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); + appVec.erase(appVec.begin(), appVec.end()); + + std::vector &isolatedVec = + AppSpawn::SandboxCommon::GetCJsonConfig(SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG); + isolatedVec.erase(isolatedVec.begin(), isolatedVec.end()); + + const TestInfo *info = UnitTest::GetInstance()->current_test_info(); + GTEST_LOG_(INFO) << info->test_suite_name() << "." << info->name() << " end"; + APPSPAWN_LOGI("%{public}s.%{public}s end", info->test_suite_name(), info->name()); +} static AppSpawningCtx *GetTestAppProperty() { @@ -84,14 +110,14 @@ static AppSpawningCtx *GetTestAppPropertyWithExtInfo(const char *name, const cha */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_08, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_08 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("ohos.samples.ecg"); AppSpawningCtx *appProperty = GetTestAppProperty(); - OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(appProperty); + int32_t ret = AppSpawn::SandboxCore::SetAppSandboxProperty(appProperty, CLONE_NEWPID); + EXPECT_EQ(ret, 0); + DeleteAppSpawningCtx(appProperty); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_08 end"; } /** @@ -103,70 +129,62 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_08, TestSize.Level0) */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_09, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09 start"; g_testHelper.SetProcessName("com.ohos.dlpmanager"); g_testHelper.SetTestApl("normal"); AppSpawningCtx *appProperty = GetTestAppProperty(); - OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(appProperty); + int32_t ret = AppSpawn::SandboxCore::SetAppSandboxProperty(appProperty, CLONE_NEWPID); + EXPECT_EQ(ret, 0); + DeleteAppSpawningCtx(appProperty); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09 end"; } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_09_1, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09_1 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("com.ohos.dlpmanager"); g_testHelper.SetTestApl("normal"); - AppSpawningCtx *appProperty = GetTestAppProperty(); - int ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(nullptr); + int32_t ret = AppSpawn::SandboxCore::SetAppSandboxProperty(nullptr, CLONE_NEWPID); EXPECT_NE(ret, 0); - DeleteAppSpawningCtx(appProperty); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09_1 end"; } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_09_2, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09_1 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName(""); g_testHelper.SetTestApl("normal"); AppSpawningCtx *appProperty = GetTestAppProperty(); - - int ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(appProperty); + int32_t ret = AppSpawn::SandboxCore::SetAppSandboxProperty(appProperty, CLONE_NEWPID); EXPECT_NE(ret, 0); + DeleteAppSpawningCtx(appProperty); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09_1 end"; } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_09_3, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09_1 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("com.\\ohos.dlpmanager"); g_testHelper.SetTestApl("normal"); AppSpawningCtx *appProperty = GetTestAppProperty(); - int ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(appProperty); + int32_t ret = AppSpawn::SandboxCore::SetAppSandboxProperty(appProperty, CLONE_NEWPID); EXPECT_NE(ret, 0); + DeleteAppSpawningCtx(appProperty); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09_1 end"; } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_09_4, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09_1 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("com./ohos.dlpmanager"); g_testHelper.SetTestApl("normal"); AppSpawningCtx *appProperty = GetTestAppProperty(); - int ret = OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(appProperty); + int32_t ret = AppSpawn::SandboxCore::SetAppSandboxProperty(appProperty, CLONE_NEWPID); EXPECT_NE(ret, 0); + DeleteAppSpawningCtx(appProperty); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09_1 end"; } /** @@ -178,7 +196,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_09_4, TestSize.Level0) */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_10, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_10 start"; std::string mJsconfig = "{ \ \"common\":[{ \ \"top-sandbox-switch\": \"ON\", \ @@ -196,19 +213,20 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_10, TestSize.Level0) }], \ \"individual\": [] \ }"; - nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); - GTEST_LOG_(INFO) << "SetAppSandboxProperty start" << std::endl; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("test.appspawn"); g_testHelper.SetTestApl("normal"); AppSpawningCtx *appProperty = GetTestAppProperty(); - GTEST_LOG_(INFO) << "SetAppSandboxProperty section 2" << std::endl; - OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(appProperty); + int32_t ret = AppSpawn::SandboxCore::SetAppSandboxProperty(appProperty, CLONE_NEWPID); + EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config); DeleteAppSpawningCtx(appProperty); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_10 end"; } /** @@ -220,7 +238,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_10, TestSize.Level0) */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_13, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_13 start"; std::string mJsconfig = "{ \ \"common\":[{ \ \"app-base\":[{ \ @@ -237,19 +254,20 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_13, TestSize.Level0) }], \ \"individual\": [] \ }"; - nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); - - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); - GTEST_LOG_(INFO) << "SetAppSandboxProperty start" << std::endl; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("test.appspawn"); g_testHelper.SetTestApl("normal"); AppSpawningCtx *appProperty = GetTestAppProperty(); - OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(appProperty); + int32_t ret = AppSpawn::SandboxCore::SetAppSandboxProperty(appProperty, CLONE_NEWPID); + EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config); DeleteAppSpawningCtx(appProperty); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_13 end"; } /** @@ -261,7 +279,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_13, TestSize.Level0) */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_14, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_14 start"; std::string mJsconfig = "{ \ \"common\":[{ \ \"app-base\":[{ \ @@ -277,22 +294,20 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_14, TestSize.Level0) }], \ \"individual\": [] \ }"; - nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); - - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); - - GTEST_LOG_(INFO) << "SetAppSandboxProperty start" << std::endl; + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("test.appspawn"); g_testHelper.SetTestApl("normal"); AppSpawningCtx *appProperty = GetTestAppProperty(); + int32_t ret = AppSpawn::SandboxCore::SetAppSandboxProperty(appProperty, CLONE_NEWPID); + EXPECT_EQ(ret, 0); - GTEST_LOG_(INFO) << "SetAppSandboxProperty section 2" << std::endl; - OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(appProperty); + cJSON_Delete(j_config); DeleteAppSpawningCtx(appProperty); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_14 end"; } /** @@ -304,7 +319,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_14, TestSize.Level0) */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_15, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_15 start"; std::string mJsconfig = "{ \ \"common\":[{ \ \"app-base\":[{ \ @@ -321,20 +335,20 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_15, TestSize.Level0) }], \ \"individual\": [] \ }"; - nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); - - GTEST_LOG_(INFO) << "SetAppSandboxProperty start" << std::endl; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("test.appspawn"); g_testHelper.SetTestApl("normal"); AppSpawningCtx *appProperty = GetTestAppProperty(); - GTEST_LOG_(INFO) << "SetAppSandboxProperty section 2" << std::endl; - OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(appProperty); + int32_t ret = AppSpawn::SandboxCore::SetAppSandboxProperty(appProperty, CLONE_NEWPID); + EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config); DeleteAppSpawningCtx(appProperty); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_15 end"; } /** @@ -346,7 +360,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_15, TestSize.Level0) */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_16, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_16 start"; std::string mJsconfig = "{ \ \"common\":[{ \ \"app-base\":[{ \ @@ -356,30 +369,30 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_16, TestSize.Level0) }], \ \"individual\": [] \ }"; - nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); - - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); - GTEST_LOG_(INFO) << "SetAppSandboxProperty start" << std::endl; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("test.appspawn"); g_testHelper.SetTestApl("normal"); AppSpawningCtx *appProperty = GetTestAppProperty(); - OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(appProperty); + int32_t ret = AppSpawn::SandboxCore::SetAppSandboxProperty(appProperty, CLONE_NEWPID); + EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config); DeleteAppSpawningCtx(appProperty); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_16 end"; } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_17, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09 start"; - nlohmann::json appSandboxConfig; - bool rc = JsonUtils::GetJsonObjFromJson(appSandboxConfig, ""); - EXPECT_FALSE(rc); + cJSON *appSandboxConfig = GetJsonObjFromFile(""); + EXPECT_EQ(appSandboxConfig, nullptr); + std::string path(256, 'w'); // 256 test - rc = JsonUtils::GetJsonObjFromJson(appSandboxConfig, path); - EXPECT_FALSE(rc); + appSandboxConfig = GetJsonObjFromFile(path.c_str()); + EXPECT_EQ(appSandboxConfig, nullptr); std::string mJsconfig = "{ \ \"common\":[{ \ @@ -390,45 +403,51 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_17, TestSize.Level0) }], \ \"individual\": [] \ }"; - nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); - std::string value; - rc = JsonUtils::GetStringFromJson(j_config, "common", value); - EXPECT_FALSE(rc); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_09 end"; + const char *value = GetStringFromJsonObj(j_config, "common"); + EXPECT_EQ(value, nullptr); + + cJSON_Delete(j_config); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_18, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_18 start"; std::string mJsconfig1 = "{ \ \"sandbox-switch\": \"ON\", \ \"sandbox-root\" : \"/mnt/sandbox//\" \ }"; - nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str()); - bool ret = OHOS::AppSpawn::SandboxUtils::GetSbxSwitchStatusByConfig(j_config1); + cJSON *j_config1 = cJSON_Parse(mJsconfig1.c_str()); + ASSERT_NE(j_config1, nullptr); + bool ret = AppSpawn::SandboxCommon::GetSwitchStatus(j_config1); EXPECT_TRUE(ret); std::string mJsconfig2 = "{ \ \"sandbox-switch\": \"OFF\", \ \"sandbox-root\" : \"/mnt/sandbox//\" \ }"; - nlohmann::json j_config2 = nlohmann::json::parse(mJsconfig2.c_str()); - ret = OHOS::AppSpawn::SandboxUtils::GetSbxSwitchStatusByConfig(j_config2); + cJSON *j_config2 = cJSON_Parse(mJsconfig2.c_str()); + ASSERT_NE(j_config2, nullptr); + ret = AppSpawn::SandboxCommon::GetSwitchStatus(j_config2); EXPECT_FALSE(ret); std::string mJsconfig3 = "{ \ \"sandbox-root\" : \"/mnt/sandbox//\" \ }"; - nlohmann::json j_config3 = nlohmann::json::parse(mJsconfig3.c_str()); - ret = OHOS::AppSpawn::SandboxUtils::GetSbxSwitchStatusByConfig(j_config3); + cJSON *j_config3 = cJSON_Parse(mJsconfig3.c_str()); + ASSERT_NE(j_config3, nullptr); + ret = AppSpawn::SandboxCommon::GetSwitchStatus(j_config3); EXPECT_TRUE(ret); + + cJSON_Delete(j_config1); + cJSON_Delete(j_config2); + cJSON_Delete(j_config3); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_20, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_20 start"; std::string mJsconfig = "{ \ \"common\":[{ \ \"top-sandbox-switch\": \"OFF\", \ @@ -439,16 +458,17 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_20, TestSize.Level0) }], \ \"individual\": [] \ }"; - nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("test.appspawn"); g_testHelper.SetTestApl("normal"); AppSpawningCtx *appProperty = GetTestAppProperty(); - - OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(appProperty); + int32_t ret = AppSpawn::SandboxCore::SetAppSandboxProperty(appProperty, CLONE_NEWPID); + EXPECT_EQ(ret, 0); std::string mJsconfig1 = "{ \ \"common\":[{ \ @@ -464,29 +484,33 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_20, TestSize.Level0) }] \ }] \ }"; - nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str()); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config1, SANBOX_APP_JSON_CONFIG); - OHOS::AppSpawn::SandboxUtils::SetAppSandboxProperty(appProperty); + cJSON *j_config1 = cJSON_Parse(mJsconfig1.c_str()); + ASSERT_NE(j_config1, nullptr); + + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config1, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); + ret = AppSpawn::SandboxCore::SetAppSandboxProperty(appProperty, CLONE_NEWPID); + EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config); + cJSON_Delete(j_config1); DeleteAppSpawningCtx(appProperty); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_21, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_21 start"; - - bool ret = OHOS::AppSpawn::SandboxUtils::CheckBundleNameForPrivate(std::string("__internal__")); + bool ret = AppSpawn::SandboxCommon::HasPrivateInBundleName(std::string("__internal__")); EXPECT_FALSE(ret); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_22, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_22 start"; std::string mJsconfig1 = "{ \ \"common\":[], \ \"individual\": [] \ }"; - nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str()); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config1, SANBOX_APP_JSON_CONFIG); + cJSON *j_config = cJSON_Parse(mJsconfig1.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test @@ -496,24 +520,15 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_22, TestSize.Level0) const char *strl1 = "/mnt/sandbox/100/test.bundle1"; std::string testBundle = strl1; - int ret = OHOS::AppSpawn::SandboxUtils::SetCommonAppSandboxProperty(appProperty, testBundle); - DeleteAppSpawningCtx(appProperty); + int32_t ret = AppSpawn::SandboxCore::SetCommonAppSandboxProperty(appProperty, testBundle); EXPECT_EQ(ret, 0); -} -HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_23, TestSize.Level0) -{ - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_23 start"; - const char *strl1 = "/mnt/sandbox/100/test.bundle1"; - std::string testBundle = strl1; - int ret = OHOS::AppSpawn::SandboxUtils::SetRenderSandboxProperty(nullptr, testBundle); - EXPECT_EQ(ret, 0); + cJSON_Delete(j_config); + DeleteAppSpawningCtx(appProperty); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_24, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_24 start"; - g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("test.bundle.name1"); @@ -541,8 +556,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_24, TestSize.Level0) }] \ }] \ }"; - nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str()); - int ret = OHOS::AppSpawn::SandboxUtils::DoSandboxFileCommonSymlink(appProperty, j_config1); + cJSON *j_config1 = cJSON_Parse(mJsconfig1.c_str()); + ASSERT_NE(j_config1, nullptr); + int32_t ret = AppSpawn::SandboxCore::DoSandboxFileCommonSymlink(appProperty, j_config1); EXPECT_EQ(ret, 0); std::string mJsconfig2 = "{ \ @@ -557,15 +573,18 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_24, TestSize.Level0) }] \ }] \ }"; - nlohmann::json j_config2 = nlohmann::json::parse(mJsconfig2.c_str()); - ret = OHOS::AppSpawn::SandboxUtils::DoSandboxFileCommonSymlink(appProperty, j_config2); - DeleteAppSpawningCtx(appProperty); + cJSON *j_config2 = cJSON_Parse(mJsconfig2.c_str()); + ASSERT_NE(j_config2, nullptr); + ret = AppSpawn::SandboxCore::DoSandboxFileCommonSymlink(appProperty, j_config2); EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config1); + cJSON_Delete(j_config2); + DeleteAppSpawningCtx(appProperty); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_25, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_25 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("test.bundle.wps"); @@ -595,23 +614,26 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_25, TestSize.Level0) }] \ }] \ }"; - nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str()); - int ret = OHOS::AppSpawn::SandboxUtils::DoSandboxFileCommonBind(appProperty, j_config1); + cJSON *j_config1 = cJSON_Parse(mJsconfig1.c_str()); + ASSERT_NE(j_config1, nullptr); + int32_t ret = AppSpawn::SandboxCore::DoSandboxFileCommonBind(appProperty, j_config1); EXPECT_EQ(ret, 0); - ret = OHOS::AppSpawn::SandboxUtils::DoSandboxFileCommonFlagsPointHandle(appProperty, j_config1); - DeleteAppSpawningCtx(appProperty); + ret = AppSpawn::SandboxCore::DoSandboxFileCommonFlagsPointHandle(appProperty, j_config1); EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config1); + DeleteAppSpawningCtx(appProperty); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_26, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_26 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("com.ohos.dlpmanager"); g_testHelper.SetTestApl("system_basic"); AppSpawningCtx *appProperty = GetTestAppProperty(); + std::string mJsconfig2 = "{ \ \"common\":[{ \ \"app-base\" : [{ \ @@ -626,15 +648,17 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_26, TestSize.Level0) }] \ }] \ }"; - nlohmann::json j_config2 = nlohmann::json::parse(mJsconfig2.c_str()); - int ret = OHOS::AppSpawn::SandboxUtils::DoSandboxFileCommonBind(appProperty, j_config2); - DeleteAppSpawningCtx(appProperty); + cJSON *j_config2 = cJSON_Parse(mJsconfig2.c_str()); + ASSERT_NE(j_config2, nullptr); + int32_t ret = AppSpawn::SandboxCore::DoSandboxFileCommonBind(appProperty, j_config2); EXPECT_NE(ret, 0); + + cJSON_Delete(j_config2); + DeleteAppSpawningCtx(appProperty); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_27, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_27 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("test.bundle.name"); @@ -649,8 +673,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_27, TestSize.Level0) }] \ }] \ }"; - nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str()); - int ret = OHOS::AppSpawn::SandboxUtils::DoSandboxFilePrivateFlagsPointHandle(appProperty, j_config1); + cJSON *j_config1 = cJSON_Parse(mJsconfig1.c_str()); + ASSERT_NE(j_config1, nullptr); + int32_t ret = AppSpawn::SandboxCore::DoSandboxFilePrivateFlagsPointHandle(appProperty, j_config1); EXPECT_EQ(ret, 0); std::string mJsconfig2 = "{ \ @@ -670,15 +695,18 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_27, TestSize.Level0) }] \ }] \ }"; - nlohmann::json j_config2 = nlohmann::json::parse(mJsconfig2.c_str()); - ret = OHOS::AppSpawn::SandboxUtils::DoSandboxFilePrivateFlagsPointHandle(appProperty, j_config2); - DeleteAppSpawningCtx(appProperty); + cJSON *j_config2 = cJSON_Parse(mJsconfig2.c_str()); + ASSERT_NE(j_config2, nullptr); + ret = AppSpawn::SandboxCore::DoSandboxFilePrivateFlagsPointHandle(appProperty, j_config2); EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config1); + cJSON_Delete(j_config2); + DeleteAppSpawningCtx(appProperty); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_28, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_28 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("test.bundle.name"); @@ -704,15 +732,17 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_28, TestSize.Level0) }] \ }] \ }"; - nlohmann::json j_config3 = nlohmann::json::parse(mJsconfig3.c_str()); - int ret = OHOS::AppSpawn::SandboxUtils::DoSandboxFilePrivateFlagsPointHandle(appProperty, j_config3); - DeleteAppSpawningCtx(appProperty); + cJSON *j_config3 = cJSON_Parse(mJsconfig3.c_str()); + ASSERT_NE(j_config3, nullptr); + int ret = AppSpawn::SandboxCore::DoSandboxFilePrivateFlagsPointHandle(appProperty, j_config3); EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config3); + DeleteAppSpawningCtx(appProperty); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_29, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_29 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("test.bundle.name"); @@ -738,15 +768,17 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_29, TestSize.Level0) }] \ }] \ }"; - nlohmann::json j_config3 = nlohmann::json::parse(mJsconfig3.c_str()); - int ret = OHOS::AppSpawn::SandboxUtils::DoSandboxFilePrivateFlagsPointHandle(appProperty, j_config3); - DeleteAppSpawningCtx(appProperty); + cJSON *j_config3 = cJSON_Parse(mJsconfig3.c_str()); + ASSERT_NE(j_config3, nullptr); + int ret = AppSpawn::SandboxCore::DoSandboxFilePrivateFlagsPointHandle(appProperty, j_config3); EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config3); + DeleteAppSpawningCtx(appProperty); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_30, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_30 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("com.ohos.wps"); @@ -764,8 +796,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_30, TestSize.Level0) \"check-action-status\": \"false\" \ }] \ }"; - nlohmann::json j_config3 = nlohmann::json::parse(mJsconfig3.c_str()); - int ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config3, nullptr); + cJSON *j_config3 = cJSON_Parse(mJsconfig3.c_str()); + ASSERT_NE(j_config3, nullptr); + int32_t ret = AppSpawn::SandboxCore::DoAllMntPointsMount(appProperty, j_config3, nullptr); EXPECT_EQ(ret, 0); std::string mJsconfig4 = "{ \ @@ -778,15 +811,18 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_30, TestSize.Level0) \"check-action-status\": \"false\" \ }] \ }"; - nlohmann::json j_config4 = nlohmann::json::parse(mJsconfig4.c_str()); - ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config4, nullptr); - DeleteAppSpawningCtx(appProperty); + cJSON *j_config4 = cJSON_Parse(mJsconfig4.c_str()); + ASSERT_NE(j_config4, nullptr); + ret = AppSpawn::SandboxCore::DoAllMntPointsMount(appProperty, j_config4, nullptr); EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config3); + cJSON_Delete(j_config4); + DeleteAppSpawningCtx(appProperty); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_31, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_31 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("com.ohos.dlpmanager"); @@ -803,8 +839,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_31, TestSize.Level0) \"check-action-status\": \"false\" \ }] \ }"; - nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str()); - int ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config1, nullptr); + cJSON *j_config1 = cJSON_Parse(mJsconfig1.c_str()); + ASSERT_NE(j_config1, nullptr); + int32_t ret = AppSpawn::SandboxCore::DoAllMntPointsMount(appProperty, j_config1, nullptr); EXPECT_EQ(ret, 0); std::string mJsconfig2 = "{ \ @@ -825,32 +862,36 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_31, TestSize.Level0) \"check-action-status\": \"true\" \ }] \ }"; + cJSON *j_config2 = cJSON_Parse(mJsconfig2.c_str()); + ASSERT_NE(j_config2, nullptr); + ret = AppSpawn::SandboxCore::DoAllMntPointsMount(appProperty, j_config2, nullptr); + EXPECT_NE(ret, 0); - nlohmann::json j_config2 = nlohmann::json::parse(mJsconfig2.c_str()); - ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config2, nullptr); + cJSON_Delete(j_config1); + cJSON_Delete(j_config2); DeleteAppSpawningCtx(appProperty); - EXPECT_TRUE(ret != 0); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_32, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_32 start"; - int ret = OHOS::AppSpawn::SandboxUtils::DoAppSandboxMountOnce(nullptr, nullptr); + int32_t ret = AppSpawn::SandboxCommon::DoAppSandboxMountOnce(nullptr, nullptr); EXPECT_EQ(ret, 0); std::string mJsconfig1 = "{ \ \"dest-mode\" : \"S_IRUSR|S_IWUSR|S_IXUSR\" \ }"; - nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str()); + cJSON *j_config1 = cJSON_Parse(mJsconfig1.c_str()); + ASSERT_NE(j_config1, nullptr); std::string sandboxRoot; const char *str = "/data/test11122"; sandboxRoot = str; - OHOS::AppSpawn::SandboxUtils::DoSandboxChmod(j_config1, sandboxRoot); + AppSpawn::SandboxCommon::SetSandboxPathChmod(j_config1, sandboxRoot); + + cJSON_Delete(j_config1); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_34, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_34 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("com.ohos.dlpmanager"); @@ -864,19 +905,19 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_34, TestSize.Level0) \"versions\":[\"v10001\", \"v10002\"] \ }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); + EXPECT_EQ(ret, 0); + DeleteAppSpawningCtx(appProperty); - EXPECT_EQ(0, ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_34 end"; } static void InvalidJsonTest(std::string &testBundle) { char hspListStr[] = "{"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_EQ(ret, 0); } static void NoBundleTest(std::string &testBundle) @@ -886,9 +927,9 @@ static void NoBundleTest(std::string &testBundle) \"versions\":[\"v10001\", \"v10002\"] \ }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_NE(ret, 0); } static void NoModulesTest(std::string &testBundle) @@ -899,9 +940,9 @@ static void NoModulesTest(std::string &testBundle) }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_NE(ret, 0); } static void NoVersionsTest(std::string &testBundle) @@ -911,9 +952,9 @@ static void NoVersionsTest(std::string &testBundle) \"modules\":[\"module1\", \"module2\"] \ }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_NE(ret, 0); } static void ListSizeNotSameTest(std::string &testBundle) @@ -924,9 +965,9 @@ static void ListSizeNotSameTest(std::string &testBundle) \"versions\":[\"v10001\", \"v10002\"] \ }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_NE(ret, 0); } static void ValueTypeIsNotArraryTest(std::string &testBundle) @@ -937,9 +978,9 @@ static void ValueTypeIsNotArraryTest(std::string &testBundle) \"versions\": 1001 \ }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_NE(ret, 0); } static void ElementTypeIsNotStringTest(std::string &testBundle) @@ -950,9 +991,9 @@ static void ElementTypeIsNotStringTest(std::string &testBundle) \"versions\": [1001, 1002] \ }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_NE(ret, 0); } static void ElementTypeIsNotSameTestSN(std::string &testBundle) @@ -964,9 +1005,9 @@ static void ElementTypeIsNotSameTestSN(std::string &testBundle) \"versions\": [\"v10001\", 1002] \ }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_NE(ret, 0); } static void ElementTypeIsNotSameTestNS(std::string &testBundle) @@ -978,14 +1019,13 @@ static void ElementTypeIsNotSameTestNS(std::string &testBundle) \"versions\": [1001, \"v10002\"] \ }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_NE(ret, 0); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_35, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_35 start"; const char *strl1 = "/mnt/sandbox/100/test.bundle1"; std::string testBundle = strl1; InvalidJsonTest(testBundle); @@ -997,12 +1037,10 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_35, TestSize.Level0) ElementTypeIsNotStringTest(testBundle); ElementTypeIsNotSameTestSN(testBundle); ElementTypeIsNotSameTestNS(testBundle); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_35 end"; } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_36, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_36 start"; const char *strl1 = "/mnt/sandbox/100/test.bundle1"; std::string testBundle = strl1; @@ -1013,9 +1051,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_36, TestSize.Level0) \"versions\":[\"v10001\", \"v10002\"] \ }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_NE(ret, 0); } { // name is . char hspListStr[] = "{ \ @@ -1024,9 +1062,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_36, TestSize.Level0) \"versions\":[\"v10001\", \"v10002\"] \ }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_NE(ret, 0); } { // name is .. char hspListStr[] = "{ \ @@ -1035,9 +1073,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_36, TestSize.Level0) \"versions\":[\"v10001\", \"v10002\"] \ }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_NE(ret, 0); } { // name contains / char hspListStr[] = "{ \ @@ -1046,16 +1084,14 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_36, TestSize.Level0) \"versions\":[\"v10001\", \"v10002\"] \ }"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("HspList", hspListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllHsp(appProperty, testBundle); + int32_t ret = AppSpawn::SandboxCore::MountAllHsp(appProperty, testBundle); DeleteAppSpawningCtx(appProperty); - EXPECT_NE(0, ret); + EXPECT_NE(ret, 0); } - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_36 end"; } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_37, TestSize.Level0) { - APPSPAWN_LOGI("App_Spawn_Sandbox_37 start"); g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("ohos.samples.xxx"); @@ -1063,22 +1099,21 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_37, TestSize.Level0) AppSpawningCtx *appProperty = GetTestAppProperty(); AppSpawnMgr content; - LoadAppSandboxConfig(&content); + AppSpawn::SandboxCommon::LoadAppSandboxConfigCJson(&content); std::string sandboxPackagePath = "/mnt/sandbox/100/"; const std::string bundleName = GetBundleName(appProperty); sandboxPackagePath += bundleName; - int ret = SandboxUtils::SetPrivateAppSandboxProperty(appProperty); - EXPECT_EQ(0, ret); - ret = SandboxUtils::SetCommonAppSandboxProperty(appProperty, sandboxPackagePath); + int32_t ret = AppSpawn::SandboxCore::SetPrivateAppSandboxProperty(appProperty); + EXPECT_EQ(ret, 0); + ret = AppSpawn::SandboxCore::SetCommonAppSandboxProperty(appProperty, sandboxPackagePath); + EXPECT_EQ(ret, 0); + DeleteAppSpawningCtx(appProperty); - EXPECT_EQ(0, ret); - APPSPAWN_LOGI("App_Spawn_Sandbox_37 end"); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_38, TestSize.Level0) { - APPSPAWN_LOGI("App_Spawn_Sandbox_38 start"); g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("com.example.deviceinfo"); @@ -1107,19 +1142,20 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_38, TestSize.Level0) }] \ }] \ }"; - - nlohmann::json p_config1 = nlohmann::json::parse(pJsconfig1.c_str()); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(p_config1, SANBOX_APP_JSON_CONFIG); + cJSON *j_config = cJSON_Parse(pJsconfig1.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); std::string sandboxPackagePath = "/mnt/sandbox/100/"; const std::string bundleName = GetBundleName(appProperty); sandboxPackagePath += bundleName; - int ret = SandboxUtils::SetPrivateAppSandboxProperty(appProperty); - EXPECT_EQ(0, ret); - ret = SandboxUtils::SetCommonAppSandboxProperty(appProperty, sandboxPackagePath); + int32_t ret = AppSpawn::SandboxCore::SetPrivateAppSandboxProperty(appProperty); + EXPECT_EQ(ret, 0); + ret = AppSpawn::SandboxCore::SetCommonAppSandboxProperty(appProperty, sandboxPackagePath); + EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config); DeleteAppSpawningCtx(appProperty); - EXPECT_EQ(0, ret); - APPSPAWN_LOGI("App_Spawn_Sandbox_38 end"); } /** @@ -1131,7 +1167,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_38, TestSize.Level0) */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_39, TestSize.Level0) { - APPSPAWN_LOGI("App_Spawn_Sandbox_39 start"); g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("com.ohos.demo"); @@ -1142,11 +1177,12 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_39, TestSize.Level0) overlayInfo += "/data/app/el1/bundle/public/com.ohos.demo/feature.hsp|"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("Overlay", overlayInfo.c_str()); std::string sandBoxRootDir = "/mnt/sandbox/100/com.ohos.demo"; - int32_t ret = OHOS::AppSpawn::SandboxUtils::SetOverlayAppSandboxProperty(appProperty, sandBoxRootDir); + int32_t ret = AppSpawn::SandboxCore::SetOverlayAppSandboxProperty(appProperty, sandBoxRootDir); + EXPECT_EQ(ret, 0); + DeleteAppSpawningCtx(appProperty); - EXPECT_EQ(0, ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_39 end"; } + /** * @tc.name: App_Spawn_Sandbox_40 * @tc.desc: load group info config SetAppSandboxProperty @@ -1156,7 +1192,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_39, TestSize.Level0) */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_40, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_40 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("com.ohos.demo"); @@ -1178,22 +1213,21 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_40, TestSize.Level0) } ])"; AppSpawningCtx *appProperty = GetTestAppPropertyWithExtInfo("DataGroup", dataGroupInfoListStr); - int ret = OHOS::AppSpawn::SandboxUtils::MountAllGroup(appProperty, sandboxPrefix); + int32_t ret = AppSpawn::SandboxCore::MountAllGroup(appProperty, sandboxPrefix); + EXPECT_EQ(ret, 0); + DeleteAppSpawningCtx(appProperty); - EXPECT_EQ(0, ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_40 end"; } /** * @tc.name: App_Spawn_Sandbox_41 - * @tc.desc: parse namespace config. + * @tc.desc: parse namespace config * @tc.type: FUNC * @tc.require:issueI8B63M * @tc.author: */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_41, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_41 start"; std::string mJsconfig = "{ \ \"common\":[{ \ \"top-sandbox-switch\": \"ON\", \ @@ -1213,29 +1247,28 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_41, TestSize.Level0) }] \ }] \ }"; - nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); - - uint32_t cloneFlags = OHOS::AppSpawn::SandboxUtils::GetSandboxNsFlags(false); + uint32_t cloneFlags = AppSpawn::SandboxCommon::GetSandboxNsFlags(false); EXPECT_EQ(!!(cloneFlags & CLONE_NEWPID), true); - cloneFlags = OHOS::AppSpawn::SandboxUtils::GetSandboxNsFlags(true); + cloneFlags = AppSpawn::SandboxCommon::GetSandboxNsFlags(true); EXPECT_EQ(!!(cloneFlags & (CLONE_NEWPID | CLONE_NEWNET)), true); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_41 end"; + cJSON_Delete(j_config); } /** * @tc.name: App_Spawn_Sandbox_42 - * @tc.desc: parse config file for fstype . + * @tc.desc: parse config file for fstype * @tc.type: FUNC * @tc.require: https://gitee.com/openharmony/startup_appspawn/issues/I8OF9K * @tc.author: */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_42, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_42 start"; std::string mJsconfig = "{ \ \"mount-paths\": [{ \ \"src-path\": \"/data/app/el1//base\", \ @@ -1246,16 +1279,26 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_42, TestSize.Level0) \"options\": \"support_overwrite=1\" \ }] \ }"; - nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); - const char *mountPath = "mount-paths"; - nlohmann::json j_secondConfig = j_config[mountPath][0]; - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); - - std::string fsType = OHOS::AppSpawn::SandboxUtils::GetSandboxFsType(j_secondConfig); - int ret = strcmp(fsType.c_str(), "sharefs"); - EXPECT_EQ(ret, 0); + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); + + int ret = 0; + do { + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(j_config, "mount-paths"); + APPSPAWN_CHECK(mountPoints != nullptr || cJSON_IsArray(mountPoints), ret = -1; + break, "Invalid mountPaths config"); + + for (int i = 0; i < cJSON_GetArraySize(mountPoints); ++i) { + cJSON *mntPoint = cJSON_GetArrayItem(mountPoints, i); + APPSPAWN_CHECK(mntPoint != nullptr, ret = -2; break, "Invalid mountPoint config"); + std::string fsType = AppSpawn::SandboxCommon::GetFsType(mntPoint); + ret = strcmp(fsType.c_str(), "sharefs"); + } + EXPECT_EQ(ret, 0); + } while (0); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_42 end"; + cJSON_Delete(j_config); } /** @@ -1267,7 +1310,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_42, TestSize.Level0) */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_43, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_43 start"; std::string mJsconfig = "{ \ \"mount-paths\": [{ \ \"src-path\": \"/data/app/el1//base\", \ @@ -1278,18 +1320,29 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_43, TestSize.Level0) \"options\": \"support_overwrite=1\" \ }] \ }"; - nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); - const char *mountPath = "mount-paths"; - nlohmann::json j_secondConfig = j_config[mountPath][0]; + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); - OHOS::AppSpawn::SandboxUtils::SandboxMountConfig mountConfig; - std::string section = "common"; + int ret = 0; AppSpawningCtx *appProperty = GetTestAppProperty(); - OHOS::AppSpawn::SandboxUtils::GetSandboxMountConfig(appProperty, section, j_secondConfig, mountConfig); - int ret = strcmp(mountConfig.fsType.c_str(), "sharefs"); - EXPECT_EQ(ret, 0); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_43 end"; + do { + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(j_config, "mount-paths"); + APPSPAWN_CHECK(mountPoints != nullptr || cJSON_IsArray(mountPoints), ret = -1; + break, "Invalid mountPaths config"); + + for (int i = 0; i < cJSON_GetArraySize(mountPoints); ++i) { + cJSON *mntPoint = cJSON_GetArrayItem(mountPoints, i); + APPSPAWN_CHECK(mntPoint != nullptr, ret = -2; break, "Invalid mntPoint config"); + SandboxMountConfig mountConfig = {0}; + AppSpawn::SandboxCommon::GetSandboxMountConfig(appProperty, "common", mntPoint, mountConfig); + ret = strcmp(mountConfig.fsType.c_str(), "sharefs"); + } + EXPECT_EQ(ret, 0); + } while (0); + + cJSON_Delete(j_config); + DeleteAppSpawningCtx(appProperty); } /** @@ -1301,7 +1354,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_43, TestSize.Level0) */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_44, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_44 start"; std::string mJsconfig = "{ \ \"mount-paths\": [{ \ \"src-path\": \"/data/app/el1//base\", \ @@ -1312,18 +1364,29 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_44, TestSize.Level0) \"options\": \"support_overwrite=1\" \ }] \ }"; - nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); - const char *mountPath = "mount-paths"; - nlohmann::json j_secondConfig = j_config[mountPath][0]; + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); - OHOS::AppSpawn::SandboxUtils::SandboxMountConfig mountConfig; - std::string section = "permission"; + int ret = 0; AppSpawningCtx *appProperty = GetTestAppProperty(); - OHOS::AppSpawn::SandboxUtils::GetSandboxMountConfig(appProperty, section, j_secondConfig, mountConfig); - int ret = strcmp(mountConfig.fsType.c_str(), "sharefs"); - EXPECT_EQ(ret, 0); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_44 end"; + do { + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(j_config, "mount-paths"); + APPSPAWN_CHECK(mountPoints != nullptr || cJSON_IsArray(mountPoints), ret = -1; + break, "Invalid mountPaths config"); + + for (int i = 0; i < cJSON_GetArraySize(mountPoints); ++i) { + cJSON *mntPoint = cJSON_GetArrayItem(mountPoints, i); + APPSPAWN_CHECK(mntPoint != nullptr, ret = -2; break, "Invalid mntPoint config"); + SandboxMountConfig mountConfig = {0}; + AppSpawn::SandboxCommon::GetSandboxMountConfig(appProperty, "permission", mntPoint, mountConfig); + ret = strcmp(mountConfig.fsType.c_str(), "sharefs"); + } + EXPECT_EQ(ret, 0); + } while (0); + + cJSON_Delete(j_config); + DeleteAppSpawningCtx(appProperty); } /** @@ -1335,7 +1398,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_44, TestSize.Level0) */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_45, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_45 start"; std::string mJsconfig = "{ \ \"mount-paths\": [{ \ \"src-path\": \"/data/app/el1//base\", \ @@ -1346,21 +1408,32 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_45, TestSize.Level0) \"options\": \"support_overwrite=1\" \ }] \ }"; - nlohmann::json j_config = nlohmann::json::parse(mJsconfig.c_str()); - const char *mountPath = "mount-paths"; - nlohmann::json j_secondConfig = j_config[mountPath][0]; + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); - OHOS::AppSpawn::SandboxUtils::StoreJsonConfig(j_config, SANBOX_APP_JSON_CONFIG); + int ret = 0; AppSpawningCtx *appProperty = GetTestAppProperty(); - std::string options = OHOS::AppSpawn::SandboxUtils::GetSandboxOptions(appProperty, j_secondConfig); - int ret = strcmp(options.c_str(), "support_overwrite=1,user_id=100"); - EXPECT_EQ(ret, 0); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_45 end"; + do { + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(j_config, "mount-paths"); + APPSPAWN_CHECK(mountPoints != nullptr || cJSON_IsArray(mountPoints), ret = -1; + break, "Invalid mountPaths config"); + + for (int i = 0; i < cJSON_GetArraySize(mountPoints); ++i) { + cJSON *mntPoint = cJSON_GetArrayItem(mountPoints, i); + APPSPAWN_CHECK(mntPoint != nullptr, ret = -2; break, "Invalid mountPoint config"); + std::string options = AppSpawn::SandboxCommon::GetOptions(appProperty, mntPoint); + ret = strcmp(options.c_str(), "support_overwrite=1,user_id=100"); + } + EXPECT_EQ(ret, 0); + } while (0); + + cJSON_Delete(j_config); + DeleteAppSpawningCtx(appProperty); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_46, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_46 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("com.example.myapplication"); @@ -1377,8 +1450,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_46, TestSize.Level0) \"check-action-status\": \"false\" \ }] \ }"; - nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str()); - int ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config1, nullptr); + cJSON *j_config1 = cJSON_Parse(mJsconfig1.c_str()); + ASSERT_NE(j_config1, nullptr); + int32_t ret = AppSpawn::SandboxCore::DoAllMntPointsMount(appProperty, j_config1, nullptr); EXPECT_EQ(ret, 0); std::string mJsconfig2 = "{ \ @@ -1391,15 +1465,18 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_46, TestSize.Level0) \"create-sandbox-path\": \"true\" \ }] \ }"; - nlohmann::json j_config2 = nlohmann::json::parse(mJsconfig2.c_str()); - ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config2, nullptr); - DeleteAppSpawningCtx(appProperty); + cJSON *j_config2 = cJSON_Parse(mJsconfig2.c_str()); + ASSERT_NE(j_config2, nullptr); + ret = AppSpawn::SandboxCore::DoAllMntPointsMount(appProperty, j_config2, nullptr); EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config1); + cJSON_Delete(j_config2); + DeleteAppSpawningCtx(appProperty); } HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_47, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_47 start"; g_testHelper.SetTestUid(1000); // 1000 test g_testHelper.SetTestGid(1000); // 1000 test g_testHelper.SetProcessName("com.example.myapplication"); @@ -1416,8 +1493,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_47, TestSize.Level0) \"check-action-status\": \"false\" \ }] \ }"; - nlohmann::json j_config1 = nlohmann::json::parse(mJsconfig1.c_str()); - int ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config1, nullptr); + cJSON *j_config1 = cJSON_Parse(mJsconfig1.c_str()); + ASSERT_NE(j_config1, nullptr); + int32_t ret = AppSpawn::SandboxCore::DoAllMntPointsMount(appProperty, j_config1, nullptr); EXPECT_EQ(ret, 0); std::string mJsconfig2 = "{ \ @@ -1430,10 +1508,14 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_47, TestSize.Level0) \"create-sandbox-path\": \"false\" \ }] \ }"; - nlohmann::json j_config2 = nlohmann::json::parse(mJsconfig2.c_str()); - ret = OHOS::AppSpawn::SandboxUtils::DoAllMntPointsMount(appProperty, j_config2, nullptr); - DeleteAppSpawningCtx(appProperty); + cJSON *j_config2 = cJSON_Parse(mJsconfig2.c_str()); + ASSERT_NE(j_config2, nullptr); + ret = AppSpawn::SandboxCore::DoAllMntPointsMount(appProperty, j_config2, nullptr); EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config1); + cJSON_Delete(j_config2); + DeleteAppSpawningCtx(appProperty); } /** * @brief 测试app extension @@ -1442,10 +1524,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_47, TestSize.Level0) HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_AppExtension_004, TestSize.Level0) { AppSpawningCtx *spawningCtx = GetTestAppProperty(); - std::string path = SandboxUtils::ConvertToRealPath(spawningCtx, "/system//module"); - APPSPAWN_LOGV("path %{public}s", path.c_str()); - ASSERT_EQ(path.c_str() != nullptr, 1); - ASSERT_EQ(strcmp(path.c_str(), "/system/com.example.myapplication/module") == 0, 1); + std::string path = AppSpawn::SandboxCommon::ConvertToRealPath(spawningCtx, "/system//module"); + ASSERT_NE(path.c_str(), nullptr); + ASSERT_EQ(strcmp(path.c_str(), "/system/com.example.myapplication/module"), 0); DeleteAppSpawningCtx(spawningCtx); } @@ -1456,10 +1537,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_AppExtension_005, TestSize.Level int ret = SetAppSpawnMsgFlag(spawningCtx->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE); ASSERT_EQ(ret, 0); - std::string path = SandboxUtils::ConvertToRealPath(spawningCtx, "/system//module"); - APPSPAWN_LOGV("path %{public}s", path.c_str()); - ASSERT_EQ(path.c_str() != nullptr, 1); // +clone-bundleIndex+packageName - ASSERT_EQ(strcmp(path.c_str(), "/system/+clone-100+com.example.myapplication/module") == 0, 1); + std::string path = AppSpawn::SandboxCommon::ConvertToRealPath(spawningCtx, "/system//module"); + ASSERT_NE(path.c_str(), nullptr); // +clone-bundleIndex+packageName + ASSERT_EQ(strcmp(path.c_str(), "/system/+clone-100+com.example.myapplication/module"), 0); DeleteAppSpawningCtx(spawningCtx); } @@ -1477,10 +1557,10 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_AppExtension_006, TestSize.Level AppSpawningCtx *spawningCtx = g_testHelper.GetAppProperty(clientHandle, reqHandle); ASSERT_EQ(spawningCtx != nullptr, 1); - std::string path = SandboxUtils::ConvertToRealPath(spawningCtx, "/system//module"); - APPSPAWN_LOGV("path %{public}s", path.c_str()); - ASSERT_EQ(path.c_str() != nullptr, 1); // +extension-+packageName - ASSERT_EQ(strcmp(path.c_str(), "/system/+extension-test001+com.example.myapplication/module") == 0, 1); + std::string path = AppSpawn::SandboxCommon::ConvertToRealPath(spawningCtx, "/system//module"); + ASSERT_NE(path.c_str(), nullptr); // +extension-+packageName + ASSERT_EQ(strcmp(path.c_str(), "/system/+extension-test001+com.example.myapplication/module"), 0); + DeleteAppSpawningCtx(spawningCtx); AppSpawnClientDestroy(clientHandle); } @@ -1501,11 +1581,10 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_AppExtension_007, TestSize.Level AppSpawningCtx *spawningCtx = g_testHelper.GetAppProperty(clientHandle, reqHandle); ASSERT_EQ(spawningCtx != nullptr, 1); - std::string path = SandboxUtils::ConvertToRealPath(spawningCtx, "/system//module"); - APPSPAWN_LOGV("path %{public}s", path.c_str()); - ASSERT_EQ(path.c_str() != nullptr, 1); // +clone-bundleIndex+extension-+packageName + std::string path = AppSpawn::SandboxCommon::ConvertToRealPath(spawningCtx, "/system//module"); + ASSERT_NE(path.c_str(), nullptr); // +clone-bundleIndex+extension-+packageName + ASSERT_EQ(strcmp(path.c_str(), "/system/+clone-100+extension-test001+com.example.myapplication/module"), 0); - ASSERT_EQ(strcmp(path.c_str(), "/system/+clone-100+extension-test001+com.example.myapplication/module") == 0, 1); DeleteAppSpawningCtx(spawningCtx); AppSpawnClientDestroy(clientHandle); } @@ -1524,8 +1603,7 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_AppExtension_008, TestSize.Level AppSpawningCtx *spawningCtx = g_testHelper.GetAppProperty(clientHandle, reqHandle); ASSERT_EQ(spawningCtx != nullptr, 1); - std::string path = SandboxUtils::ConvertToRealPath(spawningCtx, "/system//module"); - APPSPAWN_LOGV("path %{public}s", path.c_str()); + std::string path = AppSpawn::SandboxCommon::ConvertToRealPath(spawningCtx, "/system//module"); ASSERT_STREQ(path.c_str(), ""); DeleteAppSpawningCtx(spawningCtx); @@ -1544,14 +1622,263 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_AppExtension_009, TestSize.Level AppSpawningCtx *spawningCtx = g_testHelper.GetAppProperty(clientHandle, reqHandle); ASSERT_EQ(spawningCtx != nullptr, 1); - std::string path = SandboxUtils::ConvertToRealPath(spawningCtx, "/system//module"); - APPSPAWN_LOGV("path %{public}s", path.c_str()); + std::string path = AppSpawn::SandboxCommon::ConvertToRealPath(spawningCtx, "/system//module"); ASSERT_STREQ(path.c_str(), ""); DeleteAppSpawningCtx(spawningCtx); AppSpawnClientDestroy(clientHandle); } +/** + * @tc.name: App_Spawn_Sandbox_dec_01 + * @tc.desc: parse config file for dec paths. + * @tc.type: FUNC + * @tc.author: + */ +#define DEC_PATH_SIZE 3 +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_01, TestSize.Level0) +{ + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags-customized\": [ \"MS_NODEV\", \"MS_RDONLY\" ], \ + \"dec-paths\": [ \"/storage/Users\", \"/storage/External\", \"/storage/test\" ] \ + }] \ + }"; + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); + + int ret = 0; + AppSpawningCtx *appProperty = GetTestAppProperty(); + do { + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(j_config, "mount-paths"); + APPSPAWN_CHECK(mountPoints != nullptr || cJSON_IsArray(mountPoints), ret = -1; + break, "Invalid mountPaths config"); + + for (int i = 0; i < cJSON_GetArraySize(mountPoints); ++i) { + cJSON *mntPoint = cJSON_GetArrayItem(mountPoints, i); + APPSPAWN_CHECK(mntPoint != nullptr, ret = -2; break, "Invalid mntPoint config"); + SandboxMountConfig mountConfig = {0}; + AppSpawn::SandboxCommon::GetSandboxMountConfig(appProperty, "permission", mntPoint, mountConfig); + + int decPathSize = mountConfig.decPaths.size(); + ASSERT_EQ(decPathSize, DEC_PATH_SIZE); + ret = strcmp(mountConfig.decPaths[0].c_str(), "/storage/Users") || + strcmp(mountConfig.decPaths[1].c_str(), "/storage/External") || + strcmp(mountConfig.decPaths[2].c_str(), "/storage/test"); + } + EXPECT_EQ(ret, 0); + } while (0); + + cJSON_Delete(j_config); + DeleteAppSpawningCtx(appProperty); +} + +/** + * @tc.name: App_Spawn_Sandbox_dec_02 + * @tc.desc: parse config file for dec paths. + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_02, TestSize.Level0) +{ + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags-customized\": [ \"MS_NODEV\", \"MS_RDONLY\" ], \ + \"dec-paths\": [ ] \ + }] \ + }"; + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); + + int ret = 0; + AppSpawningCtx *appProperty = GetTestAppProperty(); + do { + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(j_config, "mount-paths"); + APPSPAWN_CHECK(mountPoints != nullptr || cJSON_IsArray(mountPoints), ret = -1; + break, "Invalid mountPaths config"); + + for (int i = 0; i < cJSON_GetArraySize(mountPoints); ++i) { + cJSON *mntPoint = cJSON_GetArrayItem(mountPoints, i); + APPSPAWN_CHECK(mntPoint != nullptr, ret = -2; break, "Invalid mntPoint config"); + SandboxMountConfig mountConfig = {0}; + AppSpawn::SandboxCommon::GetSandboxMountConfig(appProperty, "permission", mntPoint, mountConfig); + + int decPathSize = mountConfig.decPaths.size(); + EXPECT_EQ(decPathSize, 0); + } + EXPECT_EQ(ret, 0); + } while (0); + + cJSON_Delete(j_config); + DeleteAppSpawningCtx(appProperty); +} + +/** + * @tc.name: App_Spawn_Sandbox_dec_03 + * @tc.desc: parse config file for set policy. + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_03, TestSize.Level0) +{ + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags-customized\": [ \"MS_NODEV\", \"MS_RDONLY\" ], \ + \"dec-paths\": [ \"/storage/Users\", \"/storage/External\", \"/storage/test\" ] \ + }] \ + }"; + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); + + int ret = 0; + AppSpawningCtx *appProperty = GetTestAppProperty(); + do { + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(j_config, "mount-paths"); + APPSPAWN_CHECK(mountPoints != nullptr || cJSON_IsArray(mountPoints), ret = -1; + break, "Invalid mountPaths config"); + + for (int i = 0; i < cJSON_GetArraySize(mountPoints); ++i) { + cJSON *mntPoint = cJSON_GetArrayItem(mountPoints, i); + APPSPAWN_CHECK(mntPoint != nullptr, ret = -2; break, "Invalid mntPoint config"); + SandboxMountConfig mountConfig = {0}; + AppSpawn::SandboxCommon::GetSandboxMountConfig(appProperty, "permission", mntPoint, mountConfig); + + int decPathSize = mountConfig.decPaths.size(); + EXPECT_EQ(decPathSize, DEC_PATH_SIZE); + ret = AppSpawn::SandboxCore::SetDecPolicyWithPermission(appProperty, mountConfig); + } + EXPECT_EQ(ret, 0); + } while (0); + + cJSON_Delete(j_config); + DeleteAppSpawningCtx(appProperty); +} + +/** + * @tc.name: App_Spawn_Sandbox_dec_04 + * @tc.desc: parse config file for mount. + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_04, TestSize.Level0) +{ + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags-customized\": [ \"MS_NODEV\", \"MS_RDONLY\" ], \ + \"dec-paths\": [ \"/storage/Users\", \"/storage/External\", \"/storage/test\" ] \ + }] \ + }"; + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); + + int ret = 0; + AppSpawningCtx *appProperty = GetTestAppProperty(); + do { + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(j_config, "mount-paths"); + APPSPAWN_CHECK(mountPoints != nullptr || cJSON_IsArray(mountPoints), ret = -1; + break, "Invalid mountPaths config"); + + for (int i = 0; i < cJSON_GetArraySize(mountPoints); ++i) { + cJSON *mntPoint = cJSON_GetArrayItem(mountPoints, i); + APPSPAWN_CHECK(mntPoint != nullptr, ret = -2; break, "Invalid mntPoint config"); + SandboxMountConfig mountConfig = {0}; + AppSpawn::SandboxCommon::GetSandboxMountConfig(appProperty, "permission", mntPoint, mountConfig); + + int decPathSize = mountConfig.decPaths.size(); + EXPECT_EQ(decPathSize, DEC_PATH_SIZE); + } + EXPECT_EQ(ret, 0); + } while (0); + ret = AppSpawn::SandboxCore::DoAllMntPointsMount(appProperty, j_config, nullptr, "permission"); + EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config); + DeleteAppSpawningCtx(appProperty); +} + +/** + * @tc.name: App_Spawn_Sandbox_dec_05 + * @tc.desc: parse config file for READ_WRITE_DOWNLOAD_DIRECTORY. + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_05, TestSize.Level0) +{ + std::string mJsconfig = "{ \ + \"mount-paths\": [{ \ + \"src-path\": \"\", \ + \"sandbox-path\": \"\", \ + \"sandbox-flags-customized\": [ \"MS_NODEV\", \"MS_RDONLY\" ], \ + \"dec-paths\": [ \"/storage/Users//Download\" ] \ + }] \ + }"; + cJSON *j_config = cJSON_Parse(mJsconfig.c_str()); + ASSERT_NE(j_config, nullptr); + AppSpawn::SandboxCommon::StoreCJsonConfig(j_config, SandboxCommonDef::SANDBOX_APP_JSON_CONFIG); + + int ret = 0; + AppSpawningCtx *appProperty = GetTestAppProperty(); + do { + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(j_config, "mount-paths"); + APPSPAWN_CHECK(mountPoints != nullptr || cJSON_IsArray(mountPoints), ret = -1; + break, "Invalid mountPaths config"); + + for (int i = 0; i < cJSON_GetArraySize(mountPoints); ++i) { + cJSON *mntPoint = cJSON_GetArrayItem(mountPoints, i); + APPSPAWN_CHECK(mntPoint != nullptr, ret = -2; break, "Invalid mntPoint config"); + SandboxMountConfig mountConfig = {0}; + AppSpawn::SandboxCommon::GetSandboxMountConfig(appProperty, "permission", mntPoint, mountConfig); + + int decPathSize = mountConfig.decPaths.size(); + EXPECT_EQ(decPathSize, 1); + } + EXPECT_EQ(ret, 0); + } while (0); + ret = AppSpawn::SandboxCore::DoAllMntPointsMount(appProperty, j_config, nullptr, "permission"); + EXPECT_EQ(ret, 0); + + cJSON_Delete(j_config); + DeleteAppSpawningCtx(appProperty); +} + +/** + * @tc.name: App_Spawn_Sandbox_dec_06 + * @tc.desc: set deny dec rules + * @tc.type: FUNC + * @tc.author: + */ +HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_dec_06, TestSize.Level0) +{ + AppSpawningCtx *appProperty = GetTestAppProperty(); + AppSpawn::SandboxCore::SetDecDenyWithDir(appProperty); + + int32_t userFileIndex = GetPermissionIndex(nullptr, "ohos.permission.READ_WRITE_USER_FILE"); + ASSERT_NE(userFileIndex, 0); + int ret = SetAppPermissionFlags(appProperty, userFileIndex); + ASSERT_EQ(ret, 0); + AppSpawn::SandboxCore::SetDecDenyWithDir(appProperty); + + int32_t downloadIndex = GetPermissionIndex(nullptr, "ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY"); + ASSERT_NE(downloadIndex, 0); + ret = SetAppPermissionFlags(appProperty, downloadIndex); + ASSERT_EQ(ret, 0); + AppSpawn::SandboxCore::SetDecDenyWithDir(appProperty); + + DeleteAppSpawningCtx(appProperty); +} + /** * @tc.name: App_Spawn_Sandbox_Shared_Mount_01 * @tc.desc: [IsValidDataGroupItem] input valid param @@ -1560,7 +1887,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_AppExtension_009, TestSize.Level */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_01, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_01 start"; char dataGroupInfoListStr[] = R"( { "gid": "1002", @@ -1569,10 +1895,12 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_01, TestSize.Level0 "uuid": "49c016e6-065a-abd1-5867-b1f91114f840" } )"; - nlohmann::json j_config = nlohmann::json::parse(dataGroupInfoListStr); + cJSON *j_config = cJSON_Parse(dataGroupInfoListStr); + ASSERT_NE(j_config, nullptr); bool ret = IsValidDataGroupItem(j_config); EXPECT_TRUE(ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_01 end"; + + cJSON_Delete(j_config); } /** @@ -1583,7 +1911,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_01, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_02, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_02 start"; char dataGroupInfoListStr[] = R"([ { "gid": "1002", @@ -1598,16 +1925,19 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_02, TestSize.Level0 "uuid": "49c016e6-065a-abd1-5867-b1f91114f840" } ])"; - nlohmann::json j_config = nlohmann::json::parse(dataGroupInfoListStr); + cJSON *j_config = cJSON_Parse(dataGroupInfoListStr); + ASSERT_NE(j_config, nullptr); bool ret = false; - for (auto& item : j_config) { - ret = IsValidDataGroupItem(item); - if (ret != true) { + cJSON *child = nullptr; + cJSON_ArrayForEach(child, j_config) { + ret = IsValidDataGroupItem(child); + if (!ret) { break; } } EXPECT_TRUE(ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_02 end"; + + cJSON_Delete(j_config); } /** @@ -1618,7 +1948,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_02, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_03, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_03 start"; char dataGroupInfoListStr[] = R"( { "gid": "1002", @@ -1627,10 +1956,12 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_03, TestSize.Level0 "uuid": "49c016e6-065a-abd1-5867-b1f91114f840" } )"; - nlohmann::json j_config = nlohmann::json::parse(dataGroupInfoListStr); + cJSON *j_config = cJSON_Parse(dataGroupInfoListStr); + ASSERT_NE(j_config, nullptr); bool ret = IsValidDataGroupItem(j_config); EXPECT_FALSE(ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_03 end"; + + cJSON_Delete(j_config); } /** @@ -1641,7 +1972,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_03, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_04, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_04 start"; char dataGroupInfoListStr[] = R"( { "gid": 1002, @@ -1650,10 +1980,12 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_04, TestSize.Level0 "uuid": "49c016e6-065a-abd1-5867-b1f91114f840" } )"; - nlohmann::json j_config = nlohmann::json::parse(dataGroupInfoListStr); + cJSON *j_config = cJSON_Parse(dataGroupInfoListStr); + ASSERT_NE(j_config, nullptr); bool ret = IsValidDataGroupItem(j_config); EXPECT_FALSE(ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_04 end"; + + cJSON_Delete(j_config); } /** @@ -1664,7 +1996,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_04, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_05, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_05 start"; char dataGroupInfoListStr[] = R"( { "gid": "1002", @@ -1673,10 +2004,12 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_05, TestSize.Level0 "uuid": "49c016e6-065a-abd1-5867-b1f91114f840" } )"; - nlohmann::json j_config = nlohmann::json::parse(dataGroupInfoListStr); + cJSON *j_config = cJSON_Parse(dataGroupInfoListStr); + ASSERT_NE(j_config, nullptr); bool ret = IsValidDataGroupItem(j_config); EXPECT_FALSE(ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_05 end"; + + cJSON_Delete(j_config); } /** @@ -1687,7 +2020,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_05, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_06, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_06 start"; char dataGroupInfoListStr[] = R"( { "gid": "1002", @@ -1696,10 +2028,12 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_06, TestSize.Level0 "uuid": 124 } )"; - nlohmann::json j_config = nlohmann::json::parse(dataGroupInfoListStr); + cJSON *j_config = cJSON_Parse(dataGroupInfoListStr); + ASSERT_NE(j_config, nullptr); bool ret = IsValidDataGroupItem(j_config); EXPECT_FALSE(ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_06 end"; + + cJSON_Delete(j_config); } /** @@ -1710,7 +2044,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_06, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_07, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_07 start"; char dataGroupInfoListStr[] = R"( { "gid": 1002, @@ -1719,10 +2052,12 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_07, TestSize.Level0 "uuid": "49c016e6-065a-abd1-5867-b1f91114f840" } )"; - nlohmann::json j_config = nlohmann::json::parse(dataGroupInfoListStr); + cJSON *j_config = cJSON_Parse(dataGroupInfoListStr); + ASSERT_NE(j_config, nullptr); bool ret = IsValidDataGroupItem(j_config); EXPECT_FALSE(ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_07 end"; + + cJSON_Delete(j_config); } /** @@ -1733,7 +2068,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_07, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_08, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_08 start"; char dataGroupInfoListStr[] = R"( { "gid": "1002", @@ -1742,10 +2076,12 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_08, TestSize.Level0 "uuid": "49c016e6-065a-abd1-5867-b1f91114f840" } )"; - nlohmann::json j_config = nlohmann::json::parse(dataGroupInfoListStr); + cJSON *j_config = cJSON_Parse(dataGroupInfoListStr); + ASSERT_NE(j_config, nullptr); bool ret = IsValidDataGroupItem(j_config); EXPECT_FALSE(ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_08 end"; + + cJSON_Delete(j_config); } /** @@ -1756,7 +2092,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_08, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_09, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_09 start"; char dataGroupInfoListStr[] = R"( { "gid": "1002", @@ -1765,10 +2100,12 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_09, TestSize.Level0 "uuid": 124 } )"; - nlohmann::json j_config = nlohmann::json::parse(dataGroupInfoListStr); + cJSON *j_config = cJSON_Parse(dataGroupInfoListStr); + ASSERT_NE(j_config, nullptr); bool ret = IsValidDataGroupItem(j_config); EXPECT_FALSE(ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_09 end"; + + cJSON_Delete(j_config); } /** @@ -1779,7 +2116,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_09, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_10, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_10 start"; char dataGroupInfoListStr[] = R"( { "gid": 1002, @@ -1788,10 +2124,12 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_10, TestSize.Level0 "uuid": "49c016e6-065a-abd1-5867-b1f91114f840" } )"; - nlohmann::json j_config = nlohmann::json::parse(dataGroupInfoListStr); + cJSON *j_config = cJSON_Parse(dataGroupInfoListStr); + ASSERT_NE(j_config, nullptr); bool ret = IsValidDataGroupItem(j_config); EXPECT_FALSE(ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_10 end"; + + cJSON_Delete(j_config); } /** @@ -1802,7 +2140,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_10, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_11, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_11 start"; char dataGroupInfoListStr[] = R"( { "gid": 1002, @@ -1811,10 +2148,12 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_11, TestSize.Level0 "uuid": 124 } )"; - nlohmann::json j_config = nlohmann::json::parse(dataGroupInfoListStr); + cJSON *j_config = cJSON_Parse(dataGroupInfoListStr); + ASSERT_NE(j_config, nullptr); bool ret = IsValidDataGroupItem(j_config); EXPECT_FALSE(ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_11 end"; + + cJSON_Delete(j_config); } /** @@ -1825,7 +2164,6 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_11, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_12, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_12 start"; char dataGroupInfoListStr[] = R"( { "gid": "1002", @@ -1834,10 +2172,12 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_12, TestSize.Level0 "uuid": 124 } )"; - nlohmann::json j_config = nlohmann::json::parse(dataGroupInfoListStr); + cJSON *j_config = cJSON_Parse(dataGroupInfoListStr); + ASSERT_NE(j_config, nullptr); bool ret = IsValidDataGroupItem(j_config); EXPECT_FALSE(ret); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_12 end"; + + cJSON_Delete(j_config); } /** @@ -1848,11 +2188,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_12, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_13, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_13 start"; std::string str = "/data/storage/el2/group/"; int res = GetElxInfoFromDir(str.c_str()); EXPECT_EQ(res, EL2); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_13 end"; } /** @@ -1863,11 +2201,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_13, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_14, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_14 start"; std::string str = "/data/storage/el3/group/"; int res = GetElxInfoFromDir(str.c_str()); EXPECT_EQ(res, EL3); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_14 end"; } /** @@ -1878,11 +2214,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_14, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_15, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_15 start"; std::string str = "/data/storage/el4/group/"; int res = GetElxInfoFromDir(str.c_str()); EXPECT_EQ(res, EL4); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_15 end"; } /** @@ -1893,11 +2227,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_15, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_16, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_16 start"; std::string str = "/data/storage/el5/group/"; int res = GetElxInfoFromDir(str.c_str()); EXPECT_EQ(res, EL5); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_16 end"; } /** @@ -1908,11 +2240,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_16, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_17, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_17 start"; std::string str = "/data/storage/el0/group/"; int res = GetElxInfoFromDir(str.c_str()); EXPECT_EQ(res, ELX_MAX); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_17 end"; } /** @@ -1923,11 +2253,9 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_17, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_18, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_18 start"; std::string str = "/data/storage/el6/group/"; int res = GetElxInfoFromDir(str.c_str()); EXPECT_EQ(res, ELX_MAX); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_18 end"; } /** @@ -1938,10 +2266,8 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_18, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_19, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_19 start"; int res = GetElxInfoFromDir(nullptr); EXPECT_EQ(res, ELX_MAX); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_19 end"; } /** @@ -1952,12 +2278,10 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_19, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_20, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_20 start"; const DataGroupSandboxPathTemplate *templateItem = GetDataGroupArgTemplate(EL2); ASSERT_EQ(templateItem != nullptr, 1); int res = strcmp(templateItem->elxName, "el2"); EXPECT_EQ(res, 0); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_20 end"; } /** @@ -1968,12 +2292,10 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_20, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_21, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_21 start"; const DataGroupSandboxPathTemplate *templateItem = GetDataGroupArgTemplate(EL3); ASSERT_EQ(templateItem != nullptr, 1); int res = strcmp(templateItem->elxName, "el3"); EXPECT_EQ(res, 0); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_21 end"; } /** @@ -1984,12 +2306,10 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_21, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_22, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_22 start"; const DataGroupSandboxPathTemplate *templateItem = GetDataGroupArgTemplate(EL4); ASSERT_EQ(templateItem != nullptr, 1); int res = strcmp(templateItem->elxName, "el4"); EXPECT_EQ(res, 0); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_22 end"; } /** @@ -2000,12 +2320,10 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_22, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_23, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_23 start"; const DataGroupSandboxPathTemplate *templateItem = GetDataGroupArgTemplate(EL5); ASSERT_EQ(templateItem != nullptr, 1); int res = strcmp(templateItem->elxName, "el5"); EXPECT_EQ(res, 0); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_23 end"; } /** @@ -2016,13 +2334,11 @@ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_23, TestSize.Level0 */ HWTEST_F(AppSpawnSandboxTest, App_Spawn_Sandbox_Shared_Mount_24, TestSize.Level0) { - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_24 start"; const DataGroupSandboxPathTemplate *templateItem = GetDataGroupArgTemplate(6); int res = -1; if (templateItem == nullptr) { res = 0; } EXPECT_EQ(res, 0); - GTEST_LOG_(INFO) << "App_Spawn_Sandbox_Shared_Mount_24 end"; } } // namespace OHOS diff --git a/test/unittest/app_spawn_standard_test/app_spawn_silk_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_silk_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..475eb46342e004c0e7115db9f1f5fe04af4c5476 --- /dev/null +++ b/test/unittest/app_spawn_standard_test/app_spawn_silk_test.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "appspawn_utils.h" + +#ifdef __cplusplus +extern "C" { +#endif +#include "cJSON.h" +#include "appspawn_silk.h" + +extern struct SilkConfig g_silkConfig; +APPSPAWN_STATIC bool ParseSilkConfig(const cJSON *root, struct SilkConfig *config); +#ifdef __cplusplus +} +#endif + +using namespace testing; +using namespace testing::ext; + +class ParseSilkConfigTest : public ::testing::Test { +protected: + void SetUp() override {} + void TearDown() override {} +}; + +/** + * @brief 模拟测试,正常解析json文件并且正常使能silk + * + */ +HWTEST_F(ParseSilkConfigTest, Parse_Silk_Config_001, TestSize.Level0) +{ + const char *silkJsonStr = "{\"enabled_app_list\":[\"com.taobao.taobao\",\"com.tencent.mm\"]}"; + cJSON *root = cJSON_Parse(silkJsonStr); + const char* testEnableSilkProcessName = "com.taobao.taobao"; + bool ret = ParseSilkConfig(root, &g_silkConfig); + cJSON_Delete(root); + ASSERT_EQ(ret, true); + ASSERT_EQ(g_silkConfig.configCursor, 2); + ret = LoadSilkLibrary(testEnableSilkProcessName); + ASSERT_EQ(ret, true); + ASSERT_EQ(g_silkConfig.configItems, NULL); + ASSERT_EQ(g_silkConfig.configCursor, 0); +} + +/** + * @brief 模拟测试,processName为NULL的情况 + * + */ +HWTEST_F(ParseSilkConfigTest, Parse_Silk_Config_002, TestSize.Level0) +{ + const char *silkJsonStr = "{\"enabled_app_list\":[\"com.taobao.taobao\",\"com.tencent.mm\"]}"; + cJSON *root = cJSON_Parse(silkJsonStr); + const char* testEnableSilkProcessName = NULL; + bool ret = ParseSilkConfig(root, &g_silkConfig); + cJSON_Delete(root); + ASSERT_EQ(ret, true); + ASSERT_EQ(g_silkConfig.configCursor, 2); + ret = LoadSilkLibrary(testEnableSilkProcessName); + ASSERT_EQ(ret, false); + ASSERT_EQ(g_silkConfig.configItems, NULL); + ASSERT_EQ(g_silkConfig.configCursor, 0); +} + +HWTEST_F(ParseSilkConfigTest, Parse_Silk_Config_003, TestSize.Level0) +{ + const char *silkJsonStr = "{\"enabled_app_list0\":[\"com.taobao.taobao\",\"com.tencent.mm\"]}"; + cJSON *root = cJSON_Parse(silkJsonStr); + const char* testEnableSilkProcessName = NULL; + bool ret = ParseSilkConfig(root, &g_silkConfig); + cJSON_Delete(root); + ASSERT_EQ(ret, false); +} diff --git a/test/unittest/app_spawn_test_helper.h b/test/unittest/app_spawn_test_helper.h index c161d3e8018514fcf1a1d6e32b249135dbea1a9d..4c9bfc33e483151c5b637c5657e6ee6e621320e8 100644 --- a/test/unittest/app_spawn_test_helper.h +++ b/test/unittest/app_spawn_test_helper.h @@ -148,7 +148,7 @@ private: uint32_t defaultMsgFlags_ = 0; int fdArg = -1; std::vector permissions_ = { - const_cast("ohos.permission.READ_IMAGEVIDEO"), + const_cast("ohos.permission.MANAGE_PRIVATE_PHOTOS"), const_cast("ohos.permission.FILE_CROSS_APP"), const_cast("ohos.permission.ACTIVATE_THEME_PACKAGE"), const_cast("ohos.permission.GET_WALLPAPER"), diff --git a/test/unittest/single_test/hnp_installer/BUILD.gn b/test/unittest/single_test/hnp_installer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..066a44127f2fc71caa65dc4f630ea41a28f8cd32 --- /dev/null +++ b/test/unittest/single_test/hnp_installer/BUILD.gn @@ -0,0 +1,63 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//base/startup/appspawn/appspawn.gni") +import("//build/test.gni") + +if (!defined(ohos_lite)) { + ohos_unittest("hnp_installer_test") { + module_out_path = "appspawn/appspawn" + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-unused-function", + "-Dprivate=public", + "-Dprotected=public", + ] + + cflags_cc = [ + "-Wno-implicit-fallthrough", + "-fexceptions", + ] + + include_dirs = [ + "${appspawn_path}/service/hnp/base", + "${appspawn_path}/service/hnp/pack/include", + "${appspawn_path}/service/hnp/installer/include", + "${appspawn_path}/interfaces/innerkits/hnp/include", + "${appspawn_path}/util/include", + "include", + ] + + sources = [ + "${appspawn_path}/service/hnp/base/hnp_log.c", + "${appspawn_path}/service/hnp/installer/src/hnp_installer.c", + "src/hnp_installer_test.cpp", + ] + + defines = [ "APPSPAWN_TEST" ] + + deps = [ "${appspawn_path}/util:libappspawn_util" ] + + external_deps = [ + "bounds_checking_function:libsec_shared", + "cJSON:cjson", + "hilog:libhilog", + "init:libbegetutil", + "selinux_adapter:librestorecon", + "zlib:shared_libz", + ] + + if (appspawn_support_code_signature) { + external_deps += [ "code_signature:libcode_sign_utils" ] + } + } +} diff --git a/test/unittest/single_test/hnp_installer/include/hnp_installer_test.h b/test/unittest/single_test/hnp_installer/include/hnp_installer_test.h new file mode 100644 index 0000000000000000000000000000000000000000..7100ccefbc80c1be94390bbbb69c0439071c7493 --- /dev/null +++ b/test/unittest/single_test/hnp_installer/include/hnp_installer_test.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HNP_INSTALL_TEST_H +#define HNP_INSTALL_TEST_H + +#ifdef __cplusplus +extern "C" { +#endif + +void ClearSoftLink(int uid); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/test/unittest/single_test/hnp_installer/src/hnp_installer_test.cpp b/test/unittest/single_test/hnp_installer/src/hnp_installer_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e7c1d7f5c36dfbb0fd93b234816f16b50e7594cd --- /dev/null +++ b/test/unittest/single_test/hnp_installer/src/hnp_installer_test.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "hnp_installer_test.h" +#include + +#include +#include +#include +#include +#include +#include "hnp_installer.h" + + +using namespace testing; +using namespace testing::ext; + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +namespace OHOS { +class InitFirststageTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void InitFirststageTest::SetUpTestCase() +{ + GTEST_LOG_(INFO) << "Hnp_Installer_TEST SetUpTestCase"; +} + +void InitFirststageTest::TearDownTestCase() +{ + GTEST_LOG_(INFO) << "Hnp_Installer_TEST TearDownTestCase"; +} + +void InitFirststageTest::SetUp() +{ + GTEST_LOG_(INFO) << "Hnp_Installer_TEST SetUp"; +} + +void InitFirststageTest::TearDown() +{ + GTEST_LOG_(INFO) << "Hnp_Installer_TEST TearDown"; +} + +static void MakeDirRecursive(const std::string &path, mode_t mode) +{ + size_t size = path.size(); + if (size == 0) { + return; + } + + size_t index = 0; + do { + size_t pathIndex = path.find_first_of('/', index); + index = pathIndex == std::string::npos ? size : pathIndex + 1; + std::string dir = path.substr(0, index); + if (access(dir.c_str(), F_OK) < 0) { + int ret = mkdir(dir.c_str(), mode); + if (ret != 0) { + return; + } + } + } while (index < size); +} + +static void CreateTestFile(const char *fileName, const char *data) +{ + FILE *tmpFile = fopen(fileName, "wr"); + if (tmpFile != nullptr) { + fprintf(tmpFile, "%s", data); + (void)fflush(tmpFile); + fclose(tmpFile); + } +} + +HWTEST_F(InitFirststageTest, hnp_clearSoftLink_001, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "hnp_clearSoftLink_001 start"; + + const std::string binDir = HNP_DEFAULT_INSTALL_ROOT_PATH"/100/hnppublic/bin"; + const std::string fileDir = HNP_DEFAULT_INSTALL_ROOT_PATH"/100/hnppublic/test.org/bin"; + + MakeDirRecursive(binDir, 0711); + MakeDirRecursive(fileDir, 0711); + + const std::string lnkFile = HNP_DEFAULT_INSTALL_ROOT_PATH"/100/hnppublic/bin/test"; + const std::string sourceFile = "../test.org/bin/test"; + + CreateTestFile(HNP_DEFAULT_INSTALL_ROOT_PATH"/100/hnppublic/test.org/bin/test", "test"); + symlink(sourceFile.c_str(), lnkFile.c_str()); + + ClearSoftLink(100); + int ret = access(lnkFile.c_str(), F_OK); + EXPECT_EQ(ret, 0); + + remove(HNP_DEFAULT_INSTALL_ROOT_PATH"/100/hnppublic/test.org/bin/test"); + ClearSoftLink(100); + + ret = access(lnkFile.c_str(), F_OK); + EXPECT_NE(ret, 0); +} + +} \ No newline at end of file diff --git a/util/include/appspawn_utils.h b/util/include/appspawn_utils.h index 2ab428c73b7dc0a697ed517bb2de610df4563c88..1fe1c99c70200187d741f3972420034d0e02690d 100644 --- a/util/include/appspawn_utils.h +++ b/util/include/appspawn_utils.h @@ -181,7 +181,8 @@ int EnableNewNetNamespace(void); HILOG_WARN(LOG_CORE, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__) #define APPSPAWN_LOGF(fmt, ...) \ HILOG_FATAL(LOG_CORE, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__) - +#define APPSPAWN_DUMP_LOGI(fmt, ...) \ + HILOG_INFO(LOG_CORE, fmt, ##__VA_ARGS__) #define APPSPAWN_DUMP(fmt, ...) \ do { \ HILOG_INFO(LOG_CORE, fmt, ##__VA_ARGS__); \ @@ -198,6 +199,8 @@ int EnableNewNetNamespace(void); HILOG_DEBUG(HILOG_MODULE_HIVIEW, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__) #define APPSPAWN_LOGW(fmt, ...) \ HILOG_FATAL(HILOG_MODULE_HIVIEW, "[%{public}s:%{public}d]" fmt, (APP_FILE_NAME), (__LINE__), ##__VA_ARGS__) +#define APPSPAWN_DUMP_LOGI(fmt, ...) \ + HILOG_INFO(HILOG_MODULE_HIVIEW, fmt, ##__VA_ARGS__) #endif #define APPSPAWN_CHECK(retCode, exper, fmt, ...) \ diff --git a/util/src/appspawn_utils.c b/util/src/appspawn_utils.c index 774b11f82e4883a31a0a317033900b0c092cc9b3..20d8ca2e0c125943322d2d02f967666afb70ee61 100644 --- a/util/src/appspawn_utils.c +++ b/util/src/appspawn_utils.c @@ -38,9 +38,9 @@ #include "securec.h" static const AppSpawnCommonEnv COMMON_ENV[] = { - {"HNP_PRIVATE_HOME", "/data/app", true}, - {"HNP_PUBLIC_HOME", "/data/service/hnp", true}, - {"PATH", "${HNP_PRIVATE_HOME}/bin:${HNP_PUBLIC_HOME}/bin:${PATH}", true}, + {"HNP_PRIVATE_HOME", "/data/app", false}, + {"HNP_PUBLIC_HOME", "/data/service/hnp", false}, + {"PATH", "${HNP_PRIVATE_HOME}/bin:${HNP_PUBLIC_HOME}/bin:${PATH}", false}, {"HOME", "/storage/Users/currentUser", false}, {"TMPDIR", "/data/storage/el2/base/cache", false}, {"SHELL", "/bin/sh", false},