diff --git a/BUILD.gn b/BUILD.gn index df3662ae..90f10d88 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -79,6 +79,7 @@ group("appspawn_all") { "${appspawn_path}/modules/module_engine:libappspawn_stub_empty", ] deps += [ "service/hnp:hnp" ] + deps += [ "service/devicedebug:devicedebug" ] if (appspawn_support_cj) { # for support cj appspawn deps += [ ":cjappspawn.rc", diff --git a/interfaces/innerkits/include/appspawn.h b/interfaces/innerkits/include/appspawn.h index 8f67c151..f3edf5f9 100644 --- a/interfaces/innerkits/include/appspawn.h +++ b/interfaces/innerkits/include/appspawn.h @@ -106,6 +106,7 @@ typedef enum { MSG_BEGET_SPAWNTIME, MSG_UPDATE_MOUNT_POINTS, MSG_RESTART_SPAWNER, + MSG_DEVICE_DEBUG, MAX_TYPE_INVALID } AppSpawnMsgType; diff --git a/service/devicedebug/BUILD.gn b/service/devicedebug/BUILD.gn new file mode 100644 index 00000000..3dcde0cc --- /dev/null +++ b/service/devicedebug/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//base/startup/appspawn/appspawn.gni") +import("//build/ohos.gni") + +if (!defined(ohos_lite)) { + ohos_executable("devicedebug") { + include_dirs = [ + "base", + "kill/include", + ] + sources = [ + "${appspawn_path}/service/devicedebug/devicedebug_main.c", + "${appspawn_path}/service/devicedebug/kill/src/devicedebug_kill.c", + ] + configs = [] + cflags = [] + deps = [ + "${appspawn_path}/interfaces/innerkits/client:appspawn_client", + "${appspawn_path}/util:libappspawn_util", + ] + external_deps = [ + "cJSON:cjson", + "hilog:libhilog", + ] + install_enable = true + subsystem_name = "${subsystem_name}" + part_name = "${part_name}" + } +} diff --git a/service/devicedebug/base/devicedebug_base.h b/service/devicedebug/base/devicedebug_base.h new file mode 100644 index 00000000..7ef2fba5 --- /dev/null +++ b/service/devicedebug/base/devicedebug_base.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DEVICEDEBUG_BASE_H +#define DEVICEDEBUG_BASE_H + +#include "hilog/log.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#undef LOG_TAG +#define LOG_TAG "APPSPAWN_DEVICEDEBUG" +#undef LOG_DOMAIN +#define LOG_DOMAIN (0xD002C00 + 0x11) + +#ifndef APPSPAWN_TEST +#define APPSPAWN_STATIC static +#else +#define APPSPAWN_STATIC +#endif + +/* 数字索引 */ +enum { + DEVICEDEBUG_NUM_0 = 0, + DEVICEDEBUG_NUM_1, + DEVICEDEBUG_NUM_2, + DEVICEDEBUG_NUM_3, + DEVICEDEBUG_NUM_4, + DEVICEDEBUG_NUM_5, + DEVICEDEBUG_NUM_6, + DEVICEDEBUG_NUM_7 +}; + +// 0x11 操作类型非法 +#define DEVICEDEBUG_ERRNO_OPERATOR_TYPE_INVALID 0x11 +// 0x12 参数缺失 +#define DEVICEDEBUG_ERRNO_OPERATOR_ARGV_MISS 0x12 +// 0x13 非开发者模式 +#define DEVICEDEBUG_ERRNO_NOT_IN_DEVELOPER_MODE 0x13 +// 0x14 创建json对象失败 +#define DEVICEDEBUG_ERRNO_JSON_CREATED_FAILED 0x14 +// 0x16 参数错误 +#define DEVICEDEBUG_ERRNO_PARAM_INVALID 0x16 + +#define DEVICEDEBUG_LOGI(args, ...) \ + HILOG_INFO(LOG_CORE, "[%{public}s:%{public}d]" args, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__) + +#define DEVICEDEBUG_LOGE(args, ...) \ + HILOG_ERROR(LOG_CORE, "[%{public}s:%{public}d]" args, (__FILE_NAME__), (__LINE__), ##__VA_ARGS__) + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/service/devicedebug/devicedebug_main.c b/service/devicedebug/devicedebug_main.c new file mode 100644 index 00000000..5aa22a9c --- /dev/null +++ b/service/devicedebug/devicedebug_main.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include "devicedebug_base.h" +#include "devicedebug_kill.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int (*DEVICEDEBUG_CMD_PROCESS_FUNC)(int argc, char *argv[]); + +typedef struct DeviceDebugManagerCmdInfoStru { + char *cmd; + DEVICEDEBUG_CMD_PROCESS_FUNC process; +} DeviceDebugManagerCmdInfo; + +APPSPAWN_STATIC int DeviceDebugShowHelp(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + + printf("\r\nusage: devicedebug \r\n" + "\r\nThese are common devicedebug commands list:\r\n" + "\r\n help list available commands" + "\r\n kill send a signal to a process\r\n"); + + return 0; +} + +DeviceDebugManagerCmdInfo g_deviceDebugManagerCmd[] = { + {"help", DeviceDebugShowHelp}, + {"-h", DeviceDebugShowHelp}, + {"kill", DeviceDebugCmdKill}, +}; + +APPSPAWN_STATIC DeviceDebugManagerCmdInfo* DeviceDebugCmdCheck(const char *cmd) +{ + int cmdNum = sizeof(g_deviceDebugManagerCmd) / sizeof(DeviceDebugManagerCmdInfo); + + for (int i = 0; i < cmdNum; i++) { + if (!strcmp(cmd, g_deviceDebugManagerCmd[i].cmd)) { + return &g_deviceDebugManagerCmd[i]; + } + } + return NULL; +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + DeviceDebugManagerCmdInfo *cmdInfo = NULL; + + if (argc < DEVICEDEBUG_NUM_2) { + DeviceDebugShowHelp(argc, argv); + return DEVICEDEBUG_ERRNO_PARAM_INVALID; + } + + DEVICEDEBUG_LOGI("devicedebug manager process start."); + + /* 检验用户命令,获取对应的处理函数 */ + cmdInfo = DeviceDebugCmdCheck(argv[DEVICEDEBUG_NUM_1]); + if (cmdInfo == NULL) { + DEVICEDEBUG_LOGE("invalid cmd!. cmd:%{public}s\r\n", argv[DEVICEDEBUG_NUM_1]); + return DEVICEDEBUG_ERRNO_OPERATOR_TYPE_INVALID; + } + + /* 执行命令 */ + ret = cmdInfo->process(argc, argv); + + /* 返回值依赖此条log打印,切勿随意修改 */ + DEVICEDEBUG_LOGI("devicedebug manager process exit. ret=%{public}d \r\n", ret); + return ret; +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/service/devicedebug/kill/include/devicedebug_kill.h b/service/devicedebug/kill/include/devicedebug_kill.h new file mode 100644 index 00000000..fd27bc27 --- /dev/null +++ b/service/devicedebug/kill/include/devicedebug_kill.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DEVICEDEBUG_KILL_H +#define DEVICEDEBUG_KILL_H + +#ifdef __cplusplus +extern "C" { +#endif + +int DeviceDebugCmdKill(int argc, char *argv[]); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/service/devicedebug/kill/src/devicedebug_kill.c b/service/devicedebug/kill/src/devicedebug_kill.c new file mode 100644 index 00000000..5bb0a1b7 --- /dev/null +++ b/service/devicedebug/kill/src/devicedebug_kill.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include "appspawn.h" +#include "appspawn_utils.h" + +#include "devicedebug_base.h" +#include "devicedebug_kill.h" +#include "cJSON.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEVICEDEBUG_KILL_CMD_NUM 4 +#define DEVICEDEBUG_KILL_CMD_SIGNAL_INDEX 2 +#define DEVICEDEBUG_KILL_CMD_PID_INDEX 3 + +APPSPAWN_STATIC void DeviceDebugShowKillHelp(void) +{ + printf("\r\nusage: devicedebug kill [options] " + "\r\noptions list:" + "\r\n -h, --help list available commands" + "\r\n kill - send a signal to a process\r\n"); +} + +APPSPAWN_STATIC char* DeviceDebugJsonStringGeneral(int pid, const char *op, cJSON *args) +{ + cJSON *root = cJSON_CreateObject(); + if (root == NULL) { + DEVICEDEBUG_LOGE("devicedebug json write create root object unsuccess"); + return NULL; + } + + cJSON_AddNumberToObject(root, "app", pid); + cJSON_AddStringToObject(root, "op", op); + cJSON_AddItemToObject(root, "args", args); + + char *jsonString = cJSON_Print(root); + cJSON_Delete(root); + return jsonString; +} + +APPSPAWN_STATIC int DeviceDebugKill(int pid, int signal) +{ + AppSpawnClientHandle clientHandle; + int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); + if (ret != 0) { + DEVICEDEBUG_LOGE("devicedebug appspawn client init unsuccess, ret=%{public}d", ret); + return ret; + } + + AppSpawnReqMsgHandle reqHandle; + ret = AppSpawnReqMsgCreate(MSG_DEVICE_DEBUG, "devicedebug", &reqHandle); + if (ret != 0) { + DEVICEDEBUG_LOGE("devicedebug appspawn message create unsuccess, ret=%{public}d", ret); + return ret; + } + + cJSON *args = cJSON_CreateObject(); + if (args == NULL) { + DEVICEDEBUG_LOGE("devicedebug json write create args object unsuccess"); + return DEVICEDEBUG_ERRNO_JSON_CREATED_FAILED; + } + cJSON_AddNumberToObject(args, "signal", signal); + char *jsonString = DeviceDebugJsonStringGeneral(pid, "kill", args); + if (jsonString == NULL) { + cJSON_Delete(args); + return DEVICEDEBUG_ERRNO_JSON_CREATED_FAILED; + } + + ret = AppSpawnReqMsgAddExtInfo(reqHandle, "devicedebug", (uint8_t *)jsonString, strlen(jsonString) + 1); + if (ret != 0) { + DEVICEDEBUG_LOGE("devicedebug appspawn message add devicedebug[%{public}s] unsuccess, ret=%{public}d", + jsonString, ret); + return ret; + } + + AppSpawnResult result = {0}; + ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result); + AppSpawnClientDestroy(clientHandle); + if (ret != 0) { + DEVICEDEBUG_LOGE("devicedebug appspawn send msg unsuccess, ret=%{public}d", ret); + return ret; + } + + if (result.result != 0) { + DEVICEDEBUG_LOGE("devicedebug appspawn kill process unsuccess, result=%{public}d", result.result); + return result.result; + } + + return 0; +} + +int DeviceDebugCmdKill(int argc, char *argv[]) +{ + if (!IsDeveloperModeOpen()) { + return DEVICEDEBUG_ERRNO_NOT_IN_DEVELOPER_MODE; + } + + if (argc <= DEVICEDEBUG_NUM_2 || strcmp(argv[DEVICEDEBUG_NUM_2], "-h") == 0 || + strcmp(argv[DEVICEDEBUG_NUM_2], "help") == 0) { + DeviceDebugShowKillHelp(); + return 0; + } + + if (argc < DEVICEDEBUG_KILL_CMD_NUM) { + DEVICEDEBUG_LOGE("devicedebug cmd operator num is %{public}d < %{public}d", argc, DEVICEDEBUG_KILL_CMD_NUM); + DeviceDebugShowKillHelp(); + return DEVICEDEBUG_ERRNO_OPERATOR_ARGV_MISS; + } + + int signal = atoi(argv[DEVICEDEBUG_KILL_CMD_SIGNAL_INDEX] + 1); + if (signal > SIGRTMAX || signal <= 0) { + DEVICEDEBUG_LOGE("signal is %{public}d > %{public}d", signal, SIGRTMAX); + DeviceDebugShowKillHelp(); + return DEVICEDEBUG_ERRNO_PARAM_INVALID; + } + + int pid = atoi(argv[DEVICEDEBUG_KILL_CMD_PID_INDEX]); + DEVICEDEBUG_LOGI("devicedebug cmd kill start signal[%{public}d], pid[%{public}d]", signal, pid); + + return DeviceDebugKill(pid, signal); +} + +#ifdef __cplusplus +} +#endif diff --git a/standard/BUILD.gn b/standard/BUILD.gn index dfe0dd28..ec2ee283 100644 --- a/standard/BUILD.gn +++ b/standard/BUILD.gn @@ -72,6 +72,7 @@ ohos_executable("appspawn") { } external_deps = [ + "cJSON:cjson", "c_utils:utils", "config_policy:configpolicy_util", "hilog:libhilog", @@ -183,6 +184,7 @@ ohos_executable("cjappspawn") { } external_deps = [ + "cJSON:cjson", "c_utils:utils", "config_policy:configpolicy_util", "hilog:libhilog", @@ -253,6 +255,7 @@ ohos_executable("nativespawn") { } external_deps = [ + "cJSON:cjson", "c_utils:utils", "config_policy:configpolicy_util", "hilog:libhilog", diff --git a/standard/appspawn_appmgr.c b/standard/appspawn_appmgr.c index 3f0d08df..93da4f54 100644 --- a/standard/appspawn_appmgr.c +++ b/standard/appspawn_appmgr.c @@ -137,7 +137,7 @@ static int AppInfoCompareProc(ListNode *node, ListNode *newNode) return node1->pid - node2->pid; } -AppSpawnedProcess *AddSpawnedProcess(pid_t pid, const char *processName) +AppSpawnedProcess *AddSpawnedProcess(pid_t pid, const char *processName, bool isDebuggable) { APPSPAWN_CHECK(g_appSpawnMgr != NULL && processName != NULL, return NULL, "Invalid mgr or process name"); APPSPAWN_CHECK(pid > 0, return NULL, "Invalid pid for %{public}s", processName); @@ -150,6 +150,7 @@ AppSpawnedProcess *AddSpawnedProcess(pid_t pid, const char *processName) node->max = 0; node->uid = 0; node->exitStatus = 0; + node->isDebuggable = isDebuggable; int ret = strcpy_s(node->name, len, processName); APPSPAWN_CHECK(ret == 0, free(node); return NULL, "Failed to strcpy process name"); diff --git a/standard/appspawn_manager.h b/standard/appspawn_manager.h index 6a4c7945..eb261354 100644 --- a/standard/appspawn_manager.h +++ b/standard/appspawn_manager.h @@ -97,6 +97,7 @@ typedef struct TagAppSpawnedProcess { #ifdef DEBUG_BEGETCTL_BOOT AppSpawnMsgNode *message; #endif + bool isDebuggable; char name[0]; } AppSpawnedProcess; @@ -136,7 +137,7 @@ AppSpawnContent *GetAppSpawnContent(void); */ typedef void (*AppTraversal)(const AppSpawnMgr *mgr, AppSpawnedProcess *appInfo, void *data); void TraversalSpawnedProcess(AppTraversal traversal, void *data); -AppSpawnedProcess *AddSpawnedProcess(pid_t pid, const char *processName); +AppSpawnedProcess *AddSpawnedProcess(pid_t pid, const char *processName, bool isDebuggable); AppSpawnedProcess *GetSpawnedProcess(pid_t pid); AppSpawnedProcess *GetSpawnedProcessByName(const char *name); void TerminateSpawnedProcess(AppSpawnedProcess *node); diff --git a/standard/appspawn_service.c b/standard/appspawn_service.c index ab502132..70101949 100644 --- a/standard/appspawn_service.c +++ b/standard/appspawn_service.c @@ -42,6 +42,7 @@ #include "parameter.h" #include "appspawn_adapter.h" #include "securec.h" +#include "cJSON.h" #ifdef APPSPAWN_HISYSEVENT #include "appspawn_hisysevent.h" #endif @@ -52,6 +53,7 @@ #define PATH_SIZE 256 #define FD_PATH_SIZE 128 #define MAX_MEM_SIZE (4 * 1024) +#define APPSPAWN_MSG_USER_CHECK_COUNT 3 #define PREFORK_PROCESS "apppool" #ifndef PIDFD_NONBLOCK #define PIDFD_NONBLOCK O_NONBLOCK @@ -340,6 +342,28 @@ static int HandleRecvMessage(const TaskHandle taskHandle, uint8_t * buffer, int return recvLen; } +APPSPAWN_STATIC bool OnConnectionUserCheck(uid_t uid) +{ + const uid_t uids[APPSPAWN_MSG_USER_CHECK_COUNT] = { + 0, // root 0 + 3350, // app_fwk_update 3350 + 5523, // foundation 5523 + }; + + for (int i = 0; i < APPSPAWN_MSG_USER_CHECK_COUNT; i++) { + if (uid == uids[i]) { + return true; + } + } + + // shell 2000 + if (uid == 2000 && IsDeveloperModeOpen()) { + return true; + } + + return false; +} + static int OnConnection(const LoopHandle loopHandle, const TaskHandle server) { APPSPAWN_CHECK(server != NULL && loopHandle != NULL, return -1, "Error server"); @@ -361,8 +385,7 @@ static int OnConnection(const LoopHandle loopHandle, const TaskHandle server) struct ucred cred = {-1, -1, -1}; socklen_t credSize = sizeof(struct ucred); if ((getsockopt(LE_GetSocketFd(stream), SOL_SOCKET, SO_PEERCRED, &cred, &credSize) < 0) || - (cred.uid != DecodeUid("foundation") && cred.uid != DecodeUid("root") - && cred.uid != DecodeUid("app_fwk_update"))) { + !OnConnectionUserCheck(cred.uid)) { APPSPAWN_LOGE("Invalid uid %{public}d from client", cred.uid); LE_CloseStreamTask(LE_GetDefaultLoop(), stream); return -1; @@ -381,6 +404,27 @@ static int OnConnection(const LoopHandle loopHandle, const TaskHandle server) return 0; } +APPSPAWN_STATIC bool MsgDevicedebugCheck(TaskHandle stream, AppSpawnMsgNode *message) +{ + struct ucred cred = {0, 0, 0}; + socklen_t credSize = sizeof(cred); + if (getsockopt(LE_GetSocketFd(stream), SOL_SOCKET, SO_PEERCRED, &cred, &credSize) < 0) { + return false; + } + + if (cred.uid != DecodeUid("shell")) { + return true; + } + + AppSpawnMsg *msg = &message->msgHeader; + if (msg->msgType != MSG_DEVICE_DEBUG) { + APPSPAWN_LOGE("appspawn devicedebug msg type is not devicedebug [%{public}d]", msg->msgType); + return false; + } + + return true; +} + static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, uint32_t buffLen) { AppSpawnConnection *connection = (AppSpawnConnection *)LE_GetUserData(taskHandle); @@ -412,6 +456,10 @@ static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, LE_StopTimer(LE_GetDefaultLoop(), connection->receiverCtx.timer); connection->receiverCtx.timer = NULL; } + + APPSPAWN_CHECK_ONLY_EXPER(MsgDevicedebugCheck(connection->stream, message), + LE_CloseTask(LE_GetDefaultLoop(), taskHandle); return); + // decode msg ret = DecodeAppSpawnMsg(message); APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break); @@ -922,6 +970,24 @@ static void WaitChildTimeout(const TimerHandle taskHandle, void *context) DeleteAppSpawningCtx(property); } +static int ProcessChildFdCheck(int fd, AppSpawningCtx *property, int *pResult) +{ + int result = 0; + (void)read(fd, &result, sizeof(result)); + APPSPAWN_LOGI("Child process %{public}s success pid %{public}d appId: %{public}d result: %{public}d", + GetProcessName(property), property->pid, property->client.id, result); + APPSPAWN_CHECK(property->message != NULL, return -1, "Invalid message in ctx %{public}d", property->client.id); + + if (result != 0) { + SendResponse(property->message->connection, &property->message->msgHeader, result, property->pid); + DeleteAppSpawningCtx(property); + return -1; + } + *pResult = result; + + return 0; +} + #define MSG_EXT_NAME_MAX_DECIMAL 10 #define MSG_EXT_NAME 1 static void ProcessChildResponse(const WatcherHandle taskHandle, int fd, uint32_t *events, const void *context) @@ -931,18 +997,13 @@ static void ProcessChildResponse(const WatcherHandle taskHandle, int fd, uint32_ LE_RemoveWatcher(LE_GetDefaultLoop(), (WatcherHandle)taskHandle); int result = 0; - (void)read(fd, &result, sizeof(result)); - APPSPAWN_LOGI("Child process %{public}s success pid %{public}d appId: %{public}d result: %{public}d", - GetProcessName(property), property->pid, property->client.id, result); - APPSPAWN_CHECK(property->message != NULL, return, "Invalid message in ctx %{public}d", property->client.id); - - if (result != 0) { - SendResponse(property->message->connection, &property->message->msgHeader, result, property->pid); - DeleteAppSpawningCtx(property); + if (ProcessChildFdCheck(fd, property, &result) != 0) { return; } + // success - AppSpawnedProcess *appInfo = AddSpawnedProcess(property->pid, GetBundleName(property)); + bool isDebuggable = CheckAppMsgFlagsSet(property, APP_FLAGS_DEBUGGABLE) == 1 ? true : false; + AppSpawnedProcess *appInfo = AddSpawnedProcess(property->pid, GetBundleName(property), isDebuggable); uint32_t len = 0; char *pidMaxStr = NULL; pidMaxStr = GetAppPropertyExt(property, MSG_EXT_NAME_MAX_CHILD_PROCCESS_MAX, &len); @@ -1278,7 +1339,7 @@ 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); + AddSpawnedProcess(pid, NWEBSPAWN_SERVER_NAME, false); SetParameter("bootevent.appspawn.started", "true"); } return content; @@ -1477,6 +1538,85 @@ static void ProcessSpawnRestartMsg(AppSpawnConnection *connection, AppSpawnMsgNo APPSPAWN_LOGE("Failed to execv, ret %{public}d, errno %{public}d", ret, errno); } +APPSPAWN_STATIC int AppspawpnDevicedebugKill(int pid, cJSON *args) +{ + cJSON *signal = cJSON_GetObjectItem(args, "signal"); + if (!cJSON_IsNumber(signal)) { + APPSPAWN_LOGE("appspawn devicedebug json get signal fail"); + return -1; + } + + AppSpawnedProcess *appInfo = GetSpawnedProcess(pid); + if (appInfo == NULL) { + APPSPAWN_LOGE("appspawn devicedebug get app info unsuccess, pid=%{public}d", pid); + return -1; + } + + if (!appInfo->isDebuggable) { + APPSPAWN_LOGE("appspawn devicedebug process is not debuggable, pid=%{public}d", pid); + return -1; + } + + APPSPAWN_LOGI("appspawn devicedebug debugable=%{public}d, pid=%{public}d, signal=%{public}d", + appInfo->isDebuggable, pid, signal->valueint); + + if (kill(pid, signal->valueint) != 0) { + APPSPAWN_LOGE("appspawn devicedebug unable to kill process, pid: %{public}d ret %{public}d", pid, errno); + return -1; + } + + return 0; +} + +APPSPAWN_STATIC int AppspawnDevicedebugDeal(const char* op, int pid, cJSON *args) +{ + if (strcmp(op, "kill") == 0) { + return AppspawpnDevicedebugKill(pid, args); + } + + APPSPAWN_LOGE("appspawn devicedebug op:%{public}s invaild", op); + + return -1; +} + +APPSPAWN_STATIC int ProcessAppSpawnDeviceDebugMsg(AppSpawnMsgNode *message) +{ + APPSPAWN_CHECK_ONLY_EXPER(message != NULL, return -1); + uint32_t len = 0; + + const char* jsonString = (char *)GetAppSpawnMsgExtInfo(message, "devicedebug", &len); + if (jsonString == NULL || len == 0) { + APPSPAWN_LOGE("appspawn devicedebug get devicedebug fail"); + return -1; + } + + cJSON *json = cJSON_Parse(jsonString); + if (json == NULL) { + APPSPAWN_LOGE("appspawn devicedebug json parse fail"); + return -1; + } + + cJSON *app = cJSON_GetObjectItem(json, "app"); + if (!cJSON_IsNumber(app)) { + APPSPAWN_LOGE("appspawn devicedebug json get app fail"); + return -1; + } + + cJSON *op = cJSON_GetObjectItem(json, "op"); + if (!cJSON_IsString(op) || op->valuestring == NULL) { + APPSPAWN_LOGE("appspawn devicedebug json get op fail"); + return -1; + } + + cJSON *args = cJSON_GetObjectItem(json, "args"); + if (!cJSON_IsObject(args)) { + APPSPAWN_LOGE("appspawn devicedebug json get args fail"); + return -1; + } + + return AppspawnDevicedebugDeal(op->valuestring, app->valueint, args); +} + static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *message) { AppSpawnMsg *msg = &message->msgHeader; @@ -1521,6 +1661,11 @@ static void ProcessRecvMsg(AppSpawnConnection *connection, AppSpawnMsgNode *mess case MSG_RESTART_SPAWNER: ProcessSpawnRestartMsg(connection, message); break; + case MSG_DEVICE_DEBUG: + ret = ProcessAppSpawnDeviceDebugMsg(message); + SendResponse(connection, msg, ret, 0); + DeleteAppSpawnMsg(message); + break; default: SendResponse(connection, msg, APPSPAWN_MSG_INVALID, 0); DeleteAppSpawnMsg(message); diff --git a/test/BUILD.gn b/test/BUILD.gn index 7ae5d78e..25fcacb6 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -29,6 +29,7 @@ group("unittest") { deps += [ "unittest/app_spawn_standard_test:AppSpawn_ut" ] } deps += [ "unittest/hnp_test:HnpTest" ] + deps += [ "unittest/devicedebug_test:DevicedebugTest" ] } else { testonly = true deps = [ "unittest/app_spawn_lite_test:unittest" ] diff --git a/test/unittest/app_spawn_standard_test/app_spawn_appmgr_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_appmgr_test.cpp index 773f2e92..64787af2 100644 --- a/test/unittest/app_spawn_standard_test/app_spawn_appmgr_test.cpp +++ b/test/unittest/app_spawn_standard_test/app_spawn_appmgr_test.cpp @@ -124,7 +124,7 @@ HWTEST_F(AppSpawnAppMgrTest, App_Spawn_AppSpawnedProcess_001, TestSize.Level0) int result[resultCount] = {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0}; for (size_t i = 0; i < processNameCount; i++) { for (size_t j = 0; j < pidCount; j++) { - AppSpawnedProcess *app = AddSpawnedProcess(pidInput[j], processNameInput[i]); + AppSpawnedProcess *app = AddSpawnedProcess(pidInput[j], processNameInput[i], false); EXPECT_EQ(app != nullptr, result[i * pidCount + j]); } } @@ -167,7 +167,7 @@ HWTEST_F(AppSpawnAppMgrTest, App_Spawn_AppSpawnedProcess_002, TestSize.Level0) int result[resultCount] = {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0}; for (size_t i = 0; i < processNameCount; i++) { for (size_t j = 0; j < pidCount; j++) { - AppSpawnedProcess *app = AddSpawnedProcess(pidInput[j], processNameInput[i]); + AppSpawnedProcess *app = AddSpawnedProcess(pidInput[j], processNameInput[i], false); EXPECT_EQ(app != nullptr, result[i * pidCount + j]); } } @@ -205,7 +205,7 @@ HWTEST_F(AppSpawnAppMgrTest, App_Spawn_AppSpawnedProcess_003, TestSize.Level0) // GetSpawnedProcessByName size_t processNameCount = ARRAY_LENGTH(processNameInput); for (size_t i = 0; i < processNameCount; i++) { - AppSpawnedProcess *app = AddSpawnedProcess(1000, processNameInput[i]); // 10000 + AppSpawnedProcess *app = AddSpawnedProcess(1000, processNameInput[i], false); // 10000 EXPECT_EQ(app != nullptr, 1); } for (size_t i = 0; i < processNameCount; i++) { @@ -492,7 +492,7 @@ HWTEST_F(AppSpawnAppMgrTest, App_Spawn_AppSpawnMsgNode_005, TestSize.Level0) EXPECT_EQ(memcmp(buffer.data() + sizeof(AppSpawnMsg), outMsg->buffer, msgLen - sizeof(AppSpawnMsg)), 0); EXPECT_EQ(0, reminder); - AppSpawnedProcess *app = AddSpawnedProcess(9999999, "aaaa"); // 9999999 test + AppSpawnedProcess *app = AddSpawnedProcess(9999999, "aaaa", false); // 9999999 test EXPECT_EQ(app != nullptr, 1); TerminateSpawnedProcess(app); AppSpawnExtData extData; @@ -540,7 +540,7 @@ HWTEST_F(AppSpawnAppMgrTest, App_Spawn_AppSpawnMsgNode_006, TestSize.Level0) EXPECT_EQ(memcmp(buffer.data() + sizeof(AppSpawnMsg), outMsg->buffer, msgLen - sizeof(AppSpawnMsg)), 0); EXPECT_EQ(0, reminder); - AppSpawnedProcess *app = AddSpawnedProcess(9999999, "aaaa"); // 9999999 test + AppSpawnedProcess *app = AddSpawnedProcess(9999999, "aaaa", false); // 9999999 test EXPECT_EQ(app != nullptr, 1); ret = DecodeAppSpawnMsg(outMsg); diff --git a/test/unittest/app_spawn_standard_test/app_spawn_module_interface_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_module_interface_test.cpp index 689b7ed0..eed9eac9 100644 --- a/test/unittest/app_spawn_standard_test/app_spawn_module_interface_test.cpp +++ b/test/unittest/app_spawn_standard_test/app_spawn_module_interface_test.cpp @@ -183,7 +183,7 @@ HWTEST_F(AppSpawnModuleInterfaceTest, App_Spawn_Process_Hook_001, TestSize.Level { AppSpawnMgr *mgr = CreateAppSpawnMgr(MODE_FOR_NWEB_SPAWN); EXPECT_EQ(mgr != nullptr, 1); - AppSpawnedProcess *app = AddSpawnedProcess(1000, "test-001"); + AppSpawnedProcess *app = AddSpawnedProcess(1000, "test-001", false); EXPECT_EQ(app != nullptr, 1); int ret = 0; diff --git a/test/unittest/app_spawn_standard_test/app_spawn_service_test.cpp b/test/unittest/app_spawn_standard_test/app_spawn_service_test.cpp index fff0b3df..910ed625 100644 --- a/test/unittest/app_spawn_standard_test/app_spawn_service_test.cpp +++ b/test/unittest/app_spawn_standard_test/app_spawn_service_test.cpp @@ -31,6 +31,7 @@ #include "json_utils.h" #include "parameter.h" #include "securec.h" +#include "cJSON.h" #include "app_spawn_stub.h" #include "app_spawn_test_helper.h" @@ -547,6 +548,88 @@ HWTEST_F(AppSpawnServiceTest, App_Spawn_Msg_008, TestSize.Level0) ASSERT_EQ(ret, 0); } +HWTEST_F(AppSpawnServiceTest, App_Spawn_Msg_009, TestSize.Level0) +{ + int ret = 0; + char pid[16]; + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnResult result = {}; + do { + ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME); + AppSpawnReqMsgHandle reqHandle = testServer->CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 0); + + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR); + + ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result); + APPSPAWN_CHECK(ret == 0, break, "Failed to send msg %{public}d", ret); + + AppSpawnedProcess *app = GetSpawnedProcessByName(testServer->GetDefaultTestAppBundleName()); + EXPECT_NE(app, nullptr); + + AppSpawnReqMsgHandle reqHandle2; + ret = AppSpawnReqMsgCreate(MSG_DEVICE_DEBUG, "devicedebug", &reqHandle2); + EXPECT_GT(sprintf_s(pid, 16, "%d", app->pid), 0); + AppSpawnReqMsgAddStringInfo(reqHandle2, "signal", "-9"); + AppSpawnReqMsgAddStringInfo(reqHandle2, "pid", pid); + ret = AppSpawnClientSendMsg(clientHandle, reqHandle2, &result); + APPSPAWN_CHECK(ret == 0 && result.result == 0, break, "Failed to send msg ret:%{public}d, result:%{public}d", + ret, result.result); + ASSERT_EQ(kill(app->pid, SIGKILL), 0); + } while (0); + + AppSpawnClientDestroy(clientHandle); + ASSERT_EQ(ret, 0); + ASSERT_EQ(result.result, -1); +} + +HWTEST_F(AppSpawnServiceTest, App_Spawn_Msg_010, TestSize.Level0) +{ + int ret = 0; + AppSpawnClientHandle clientHandle = nullptr; + AppSpawnResult result = {}; + do { + ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); + APPSPAWN_CHECK(ret == 0, break, "Failed to create client %{public}s", APPSPAWN_SERVER_NAME); + AppSpawnReqMsgHandle reqHandle = testServer->CreateMsg(clientHandle, MSG_SPAWN_NATIVE_PROCESS, 0); + + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_DEBUGGABLE); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_NATIVEDEBUG); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_BUNDLE_RESOURCES); + AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_ACCESS_BUNDLE_DIR); + + ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result); + APPSPAWN_CHECK(ret == 0, break, "Failed to send msg %{public}d", ret); + + AppSpawnedProcess *app = GetSpawnedProcessByName(testServer->GetDefaultTestAppBundleName()); + EXPECT_NE(app, nullptr); + + AppSpawnReqMsgHandle reqHandle2; + ret = AppSpawnReqMsgCreate(MSG_DEVICE_DEBUG, "devicedebug", &reqHandle2); + cJSON *args = cJSON_CreateObject(); + EXPECT_NE(args, nullptr); + cJSON_AddNumberToObject(args, "signal", 9); + cJSON *root = cJSON_CreateObject(); + EXPECT_NE(root, nullptr); + cJSON_AddNumberToObject(root, "app", app->pid); + cJSON_AddStringToObject(root, "op", "kill"); + cJSON_AddItemToObject(root, "args", args); + char *jsonString = cJSON_Print(root); + cJSON_Delete(root); + ret = AppSpawnReqMsgAddExtInfo(reqHandle2, "devicedebug", (uint8_t *)jsonString, strlen(jsonString) + 1); + ASSERT_EQ(ret, 0); + ret = AppSpawnClientSendMsg(clientHandle, reqHandle2, &result); + APPSPAWN_CHECK(ret == 0 && result.result == 0, break, "Failed to send msg ret:%{public}d, result:%{public}d", + ret, result.result); + } while (0); + + AppSpawnClientDestroy(clientHandle); + ASSERT_EQ(ret, 0); + ASSERT_EQ(result.result, 0); +} + /** * @brief 必须最后一个,kill nwebspawn,appspawn的线程结束 * diff --git a/test/unittest/devicedebug_test/BUILD.gn b/test/unittest/devicedebug_test/BUILD.gn new file mode 100644 index 00000000..b075d6c8 --- /dev/null +++ b/test/unittest/devicedebug_test/BUILD.gn @@ -0,0 +1,63 @@ +# Copyright (c) 2021-2022 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("DevicedebugTest") { + module_out_path = "${module_output_path}" + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-unused-function", + "-Dprivate=public", + "-Dprotected=public", + ] + + cflags_cc = [ + "-Wno-implicit-fallthrough", + "-fexceptions", + ] + + include_dirs = [ + "${appspawn_path}/service/devicedebug/base", + "${appspawn_path}/service/devicedebug/kill/include", + "${appspawn_path}/test/unittest/devicedebug_test", + ] + + sources = [ + "${appspawn_path}/service/devicedebug/kill/src/devicedebug_kill.c", + "${appspawn_path}/test/unittest/devicedebug_test/devicedebug_stub.c", + "devicedebug_kill_test.cpp", + ] + + defines = [ + "IsDeveloperModeOpen=IsDeveloperModeOpenStub", + "AppSpawnClientInit=AppSpawnClientInitStub", + "AppSpawnReqMsgCreate=AppSpawnReqMsgCreateStub", + "AppSpawnReqMsgAddExtInfo=AppSpawnReqMsgAddExtInfoStub", + "AppSpawnClientSendMsg=AppSpawnClientSendMsgStub", + "APPSPAWN_TEST", + ] + + external_deps = [ + "cJSON:cjson", + "hilog:libhilog", + ] + + deps = [ + "${appspawn_path}/interfaces/innerkits/client:appspawn_client", + "${appspawn_path}/service/devicedebug:devicedebug", + "${appspawn_path}/util:libappspawn_util", + ] + } +} diff --git a/test/unittest/devicedebug_test/devicedebug_kill_test.cpp b/test/unittest/devicedebug_test/devicedebug_kill_test.cpp new file mode 100644 index 00000000..3330489c --- /dev/null +++ b/test/unittest/devicedebug_test/devicedebug_kill_test.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "devicedebug_base.h" +#include "devicedebug_kill.h" +#include "devicedebug_stub.h" + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +class DevicedebugKillTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void DevicedebugKillTest::SetUpTestCase() +{ + GTEST_LOG_(INFO) << "Devicedebug_Kill_TEST SetUpTestCase"; +} + +void DevicedebugKillTest::TearDownTestCase() +{ + GTEST_LOG_(INFO) << "Devicedebug_Kill_TEST TearDownTestCase"; +} + +void DevicedebugKillTest::SetUp() +{ + GTEST_LOG_(INFO) << "Devicedebug_Kill_TEST SetUp"; +} + +void DevicedebugKillTest::TearDown() +{ + GTEST_LOG_(INFO) << "Devicedebug_Kill_TEST TearDown"; +} + +/** +* @tc.name: DevicedebugCmdKill_001 +* @tc.desc: Verify develop mode and argc validate. +* @tc.type: FUNC +* @tc.require:issueIASN4F +* @tc.author: +*/ +HWTEST_F(DevicedebugKillTest, DevicedebugCmdKill_001, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "DevicedebugCmdKill_001 test...."; + { + int argc = 3; + char argv0[] = "devicedebug"; + char argv1[] = "kill"; + char argv2[] = "-9"; + char* argv[] = {argv0, argv1, argv2}; + EXPECT_EQ(DeviceDebugCmdKill(argc, argv), DEVICEDEBUG_ERRNO_NOT_IN_DEVELOPER_MODE); + DeveloperModeOpenSet(1); + EXPECT_EQ(DeviceDebugCmdKill(argc, argv), DEVICEDEBUG_ERRNO_OPERATOR_ARGV_MISS); + } + { + int argc = 2; + char argv0[] = "devicedebug"; + char argv1[] = "-h"; + char* argv[] = {argv0, argv1}; + EXPECT_EQ(DeviceDebugCmdKill(argc, argv), 0); + } + { + DeveloperModeOpenSet(1); + int argc = 3; + char argv0[] = "devicedebug"; + char argv1[] = "kill"; + char argv2[] = "-9"; + char* argv[] = {argv0, argv1, argv2}; + EXPECT_EQ(DeviceDebugCmdKill(argc, argv), DEVICEDEBUG_ERRNO_OPERATOR_ARGV_MISS); + } +} + +/** +* @tc.name: DevicedebugCmdKill_002 +* @tc.desc: Verify signal validate. +* @tc.type: FUNC +* @tc.require:issueIASN4F +* @tc.author: +*/ +HWTEST_F(DevicedebugKillTest, DevicedebugCmdKill_002, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "DevicedebugCmdKill_002 test...."; + + DeveloperModeOpenSet(1); + { + int argc = 4; + char argv0[] = "devicedebug"; + char argv1[] = "kill"; + char argv2[] = "-0"; + char argv3[] = "12111"; + char* argv[] = {argv0, argv1, argv2, argv3}; + EXPECT_EQ(DeviceDebugCmdKill(argc, argv), DEVICEDEBUG_ERRNO_PARAM_INVALID); + } + { + int argc = 4; + char argv0[] = "devicedebug"; + char argv1[] = "kill"; + char argv2[] = "-65"; + char argv3[] = "12111"; + char* argv[] = {argv0, argv1, argv2, argv3}; + EXPECT_EQ(DeviceDebugCmdKill(argc, argv), DEVICEDEBUG_ERRNO_PARAM_INVALID); + } +} + +/** +* @tc.name: DevicedebugCmdKill_003 +* @tc.desc: Verify devicedebug kill success. +* @tc.type: FUNC +* @tc.require:issueIASN4F +* @tc.author: +*/ +HWTEST_F(DevicedebugKillTest, DevicedebugCmdKill_003, TestSize.Level0) +{ + GTEST_LOG_(INFO) << "DevicedebugCmdKill_003 test...."; + + DeveloperModeOpenSet(1); + int argc = 4; + char argv0[] = "devicedebug"; + char argv1[] = "kill"; + char argv2[] = "-9"; + char argv3[] = "12111"; + char* argv[] = {argv0, argv1, argv2, argv3}; + { + AppSpawnClientInitRetSet(-1); + EXPECT_EQ(DeviceDebugCmdKill(argc, argv), -1); + } + AppSpawnClientInitRetSet(0); + { + AppSpawnReqMsgCreateRetSet(-2); + EXPECT_EQ(DeviceDebugCmdKill(argc, argv), -2); + } + AppSpawnReqMsgCreateRetSet(0); + { + AppSpawnReqMsgAddExtInfoRetSet(-3); + EXPECT_EQ(DeviceDebugCmdKill(argc, argv), -3); + } + AppSpawnReqMsgAddExtInfoRetSet(0); + { + AppSpawnClientSendMsgRetSet(-4); + EXPECT_EQ(DeviceDebugCmdKill(argc, argv), -4); + } + AppSpawnClientSendMsgRetSet(0); + { + AppSpawnClientSendMsgResultSet(-5); + EXPECT_EQ(DeviceDebugCmdKill(argc, argv), -5); + } + AppSpawnClientSendMsgResultSet(0); + { + EXPECT_EQ(DeviceDebugCmdKill(argc, argv), 0); + } +} + +} \ No newline at end of file diff --git a/test/unittest/devicedebug_test/devicedebug_stub.c b/test/unittest/devicedebug_test/devicedebug_stub.c new file mode 100644 index 00000000..4fd342ae --- /dev/null +++ b/test/unittest/devicedebug_test/devicedebug_stub.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "devicedebug_stub.h" + +#include "appspawn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int g_isDeveloperModeOpen = 0; + +void DeveloperModeOpenSet(int developerMode) +{ + g_isDeveloperModeOpen = developerMode; +} + +int IsDeveloperModeOpenStub() +{ + return g_isDeveloperModeOpen; +} + +int g_appSpawnClientInitRet = 0; + +void AppSpawnClientInitRetSet(int appSpawnClientInitRet) +{ + g_appSpawnClientInitRet = appSpawnClientInitRet; +} + +int AppSpawnClientInitStub(const char *serviceName, AppSpawnClientHandle *handle) +{ + (void)serviceName; + (void)handle; + + return g_appSpawnClientInitRet; +} + +int g_appSpawnReqMsgCreateRet = 0; + +void AppSpawnReqMsgCreateRetSet(int appSpawnReqMsgCreateRet) +{ + g_appSpawnReqMsgCreateRet = appSpawnReqMsgCreateRet; +} + +int AppSpawnReqMsgCreateStub(AppSpawnMsgType msgType, const char *processName, AppSpawnReqMsgHandle *reqHandle) +{ + (void)msgType; + (void)processName; + (void)reqHandle; + + return g_appSpawnReqMsgCreateRet; +} + +int g_appSpawnReqMsgAddExtInfoRet = 0; + +void AppSpawnReqMsgAddExtInfoRetSet(int appSpawnReqMsgAddExtInfoRet) +{ + g_appSpawnReqMsgAddExtInfoRet = appSpawnReqMsgAddExtInfoRet; +} + +int AppSpawnReqMsgAddExtInfoStub(AppSpawnReqMsgHandle reqHandle, const char *name, const uint8_t *value, + uint32_t valueLen) +{ + (void)reqHandle; + (void)name; + (void)value; + (void)valueLen; + + return g_appSpawnReqMsgAddExtInfoRet; +} + +int g_appSpawnClientSendMsgResulte = 0; +int g_appSpawnClientSendMsgRet = 0; + +void AppSpawnClientSendMsgResultSet(int appSpawnClientSendMsgResult) +{ + g_appSpawnClientSendMsgResulte = appSpawnClientSendMsgResult; +} + +void AppSpawnClientSendMsgRetSet(int appSpawnClientSendMsgRet) +{ + g_appSpawnClientSendMsgRet = appSpawnClientSendMsgRet; +} + +int AppSpawnClientSendMsgStub(AppSpawnClientHandle handle, AppSpawnReqMsgHandle reqHandle, AppSpawnResult *result) +{ + (void)handle; + (void)reqHandle; + result->result = g_appSpawnClientSendMsgResulte; + + return g_appSpawnClientSendMsgRet; +} + +#ifdef __cplusplus +} +#endif diff --git a/test/unittest/devicedebug_test/devicedebug_stub.h b/test/unittest/devicedebug_test/devicedebug_stub.h new file mode 100644 index 00000000..5bda5bd3 --- /dev/null +++ b/test/unittest/devicedebug_test/devicedebug_stub.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DEVICEDEBUG_STUB_H +#define DEVICEDEBUG_STUB_H + +#ifdef __cplusplus +extern "C" { +#endif + +void DeveloperModeOpenSet(int developerMode); + +void AppSpawnClientInitRetSet(int appSpawnClientInitRet); + +void AppSpawnReqMsgCreateRetSet(int appSpawnClientSendMsgRet); + +void AppSpawnReqMsgAddExtInfoRetSet(int appSpawnReqMsgAddExtInfoRet); + +void AppSpawnClientSendMsgResultSet(int appSpawnClientSendMsgResult); + +void AppSpawnClientSendMsgRetSet(int appSpawnClientSendMsgRet); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file