169570cc8Sopenharmony_ci/*
269570cc8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License.
569570cc8Sopenharmony_ci * You may obtain a copy of the License at
669570cc8Sopenharmony_ci *
769570cc8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
869570cc8Sopenharmony_ci *
969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and
1369570cc8Sopenharmony_ci * limitations under the License.
1469570cc8Sopenharmony_ci */
1569570cc8Sopenharmony_ci
1669570cc8Sopenharmony_ci#include "appspawn_test_cmder.h"
1769570cc8Sopenharmony_ci
1869570cc8Sopenharmony_ci#include <cerrno>
1969570cc8Sopenharmony_ci#include <cstdint>
2069570cc8Sopenharmony_ci#include <cstdio>
2169570cc8Sopenharmony_ci#include <cstdlib>
2269570cc8Sopenharmony_ci#include <fcntl.h>
2369570cc8Sopenharmony_ci#include <string>
2469570cc8Sopenharmony_ci#include <termios.h>
2569570cc8Sopenharmony_ci#include <unistd.h>
2669570cc8Sopenharmony_ci
2769570cc8Sopenharmony_ci#include <sys/stat.h>
2869570cc8Sopenharmony_ci
2969570cc8Sopenharmony_ci#include "appspawn.h"
3069570cc8Sopenharmony_ci#include "appspawn_msg.h"
3169570cc8Sopenharmony_ci#include "appspawn_utils.h"
3269570cc8Sopenharmony_ci#include "cJSON.h"
3369570cc8Sopenharmony_ci#include "command_lexer.h"
3469570cc8Sopenharmony_ci#include "json_utils.h"
3569570cc8Sopenharmony_ci#include "securec.h"
3669570cc8Sopenharmony_ci#include "thread_manager.h"
3769570cc8Sopenharmony_ci
3869570cc8Sopenharmony_ci#define MAX_THREAD 10
3969570cc8Sopenharmony_ci#define MAX_SEND 200
4069570cc8Sopenharmony_ci#define PTY_PATH_SIZE 128
4169570cc8Sopenharmony_ci
4269570cc8Sopenharmony_cinamespace OHOS {
4369570cc8Sopenharmony_cinamespace AppSpawnModuleTest {
4469570cc8Sopenharmony_cistatic const std::string g_defaultAppInfo = "{ \
4569570cc8Sopenharmony_ci    \"msg-type\": \"MSG_APP_SPAWN\", \
4669570cc8Sopenharmony_ci    \"msg-flags\": [1, 2 ], \
4769570cc8Sopenharmony_ci    \"process-name\" : \"com.example.myapplication\", \
4869570cc8Sopenharmony_ci    \"dac-info\" : { \
4969570cc8Sopenharmony_ci            \"uid\" : 20010043, \
5069570cc8Sopenharmony_ci            \"gid\" : 20010043,\
5169570cc8Sopenharmony_ci            \"gid-table\" : [],\
5269570cc8Sopenharmony_ci            \"user-name\" : \"\" \
5369570cc8Sopenharmony_ci    },\
5469570cc8Sopenharmony_ci    \"access-token\" : {\
5569570cc8Sopenharmony_ci            \"accessTokenIdEx\" : 537854093\
5669570cc8Sopenharmony_ci    },\
5769570cc8Sopenharmony_ci    \"permission\" : [\
5869570cc8Sopenharmony_ci            \"ohos.permission.READ_IMAGEVIDEO\",\
5969570cc8Sopenharmony_ci            \"ohos.permission.FILE_CROSS_APP\",\
6069570cc8Sopenharmony_ci            \"ohos.permission.ACTIVATE_THEME_PACKAGE\"\
6169570cc8Sopenharmony_ci    ],\
6269570cc8Sopenharmony_ci    \"internet-permission\" : {\
6369570cc8Sopenharmony_ci            \"set-allow-internet\" : 0,\
6469570cc8Sopenharmony_ci            \"allow-internet\" : 0\
6569570cc8Sopenharmony_ci    },\
6669570cc8Sopenharmony_ci    \"bundle-info\" : {\
6769570cc8Sopenharmony_ci            \"bundle-index\" : 0,\
6869570cc8Sopenharmony_ci            \"bundle-name\" : \"com.example.myapplication\" \
6969570cc8Sopenharmony_ci    },\
7069570cc8Sopenharmony_ci    \"owner-id\" : \"\",\
7169570cc8Sopenharmony_ci    \"render-cmd\" : \"1234567890\",\
7269570cc8Sopenharmony_ci    \"domain-info\" : {\
7369570cc8Sopenharmony_ci            \"hap-flags\" : 0,\
7469570cc8Sopenharmony_ci            \"apl\" : \"system_core\"\
7569570cc8Sopenharmony_ci    },\
7669570cc8Sopenharmony_ci    \"ext-info\" : [\
7769570cc8Sopenharmony_ci            {\
7869570cc8Sopenharmony_ci                    \"name\" : \"test\",\
7969570cc8Sopenharmony_ci                    \"value\" : \"4444444444444444444\" \
8069570cc8Sopenharmony_ci            } \
8169570cc8Sopenharmony_ci    ]\
8269570cc8Sopenharmony_ci}";
8369570cc8Sopenharmony_ci
8469570cc8Sopenharmony_cistatic const char *APPSPAWN_TEST_USAGE = "usage: AppSpawnTest <options> \n"
8569570cc8Sopenharmony_ci    "options list:\n"
8669570cc8Sopenharmony_ci    "  --help                   list available commands\n"
8769570cc8Sopenharmony_ci    "  --file xx                file path with app info\n"
8869570cc8Sopenharmony_ci    "  --thread xx              use multi-thread to send message\n"
8969570cc8Sopenharmony_ci    "  --type xx                send msg type \n"
9069570cc8Sopenharmony_ci    "  --pid xx                 render terminate pid\n"
9169570cc8Sopenharmony_ci    "  --mode nwebspawn         send message to nwebspawn service\n"
9269570cc8Sopenharmony_ci    "  --mode nativespawn       send message to nativespawn service\n";
9369570cc8Sopenharmony_ci
9469570cc8Sopenharmony_ciint AppSpawnTestCommander::ProcessArgs(int argc, char *const argv[])
9569570cc8Sopenharmony_ci{
9669570cc8Sopenharmony_ci    int sendMsg = 0;
9769570cc8Sopenharmony_ci    msgType_ = MAX_TYPE_INVALID;
9869570cc8Sopenharmony_ci    for (int32_t i = 0; i < argc; i++) {
9969570cc8Sopenharmony_ci        if (argv[i] == nullptr) {
10069570cc8Sopenharmony_ci            continue;
10169570cc8Sopenharmony_ci        }
10269570cc8Sopenharmony_ci        if (strcmp(argv[i], "--file") == 0 && ((i + 1) < argc)) {  // test file
10369570cc8Sopenharmony_ci            i++;
10469570cc8Sopenharmony_ci            testFileName_ = argv[i];
10569570cc8Sopenharmony_ci            sendMsg = 1;
10669570cc8Sopenharmony_ci        } else if (strcmp(argv[i], "--thread") == 0 && ((i + 1) < argc)) {  // use thread
10769570cc8Sopenharmony_ci            i++;
10869570cc8Sopenharmony_ci            threadCount_ = atoi(argv[i]);
10969570cc8Sopenharmony_ci            if (threadCount_ > MAX_THREAD) {
11069570cc8Sopenharmony_ci                threadCount_ = MAX_THREAD;
11169570cc8Sopenharmony_ci            }
11269570cc8Sopenharmony_ci            sendMsg = 1;
11369570cc8Sopenharmony_ci        } else if (strcmp(argv[i], "--mode") == 0 && ((i + 1) < argc)) {
11469570cc8Sopenharmony_ci            i++;
11569570cc8Sopenharmony_ci            if (strcmp(argv[i], "nwebspawn") == 0) {
11669570cc8Sopenharmony_ci                appSpawn_ = 0;
11769570cc8Sopenharmony_ci            } else if (strcmp(argv[i], "nativespawn") == 0) {
11869570cc8Sopenharmony_ci                appSpawn_ = 2; // 2 is nwebspawn
11969570cc8Sopenharmony_ci            } else {
12069570cc8Sopenharmony_ci                appSpawn_ = 1;
12169570cc8Sopenharmony_ci            }
12269570cc8Sopenharmony_ci            sendMsg = 1;
12369570cc8Sopenharmony_ci        } else if (strcmp(argv[i], "--type") == 0 && ((i + 1) < argc)) {
12469570cc8Sopenharmony_ci            i++;
12569570cc8Sopenharmony_ci            msgType_ = atoi(argv[i]);
12669570cc8Sopenharmony_ci            sendMsg = 1;
12769570cc8Sopenharmony_ci        } else if (strcmp(argv[i], "--pid") == 0 && ((i + 1) < argc)) {
12869570cc8Sopenharmony_ci            i++;
12969570cc8Sopenharmony_ci            msgType_ = MSG_GET_RENDER_TERMINATION_STATUS;
13069570cc8Sopenharmony_ci            terminatePid_ = atoi(argv[i]);
13169570cc8Sopenharmony_ci            sendMsg = 1;
13269570cc8Sopenharmony_ci        } else if (strcmp(argv[i], "--help") == 0) {
13369570cc8Sopenharmony_ci            printf("%s\n", APPSPAWN_TEST_USAGE);
13469570cc8Sopenharmony_ci            return 1;
13569570cc8Sopenharmony_ci        } else if (strcmp(argv[i], "--send") == 0 || strcmp(argv[i], "send") == 0) {
13669570cc8Sopenharmony_ci            sendMsg = 1;
13769570cc8Sopenharmony_ci        }
13869570cc8Sopenharmony_ci    }
13969570cc8Sopenharmony_ci    if (sendMsg == 0) {
14069570cc8Sopenharmony_ci        printf("%s\n", APPSPAWN_TEST_USAGE);
14169570cc8Sopenharmony_ci        return 1;
14269570cc8Sopenharmony_ci    }
14369570cc8Sopenharmony_ci    return 0;
14469570cc8Sopenharmony_ci}
14569570cc8Sopenharmony_ci
14669570cc8Sopenharmony_ciuint32_t AppSpawnTestCommander::GetUint32ArrayFromJson(const cJSON *json,
14769570cc8Sopenharmony_ci    const char *name, uint32_t dataArray[], uint32_t maxCount)
14869570cc8Sopenharmony_ci{
14969570cc8Sopenharmony_ci    APPSPAWN_CHECK(json != NULL, return 0, "Invalid json");
15069570cc8Sopenharmony_ci    APPSPAWN_CHECK(name != NULL, return 0, "Invalid name");
15169570cc8Sopenharmony_ci    APPSPAWN_CHECK(dataArray != NULL, return 0, "Invalid dataArray");
15269570cc8Sopenharmony_ci    APPSPAWN_CHECK(cJSON_IsObject(json), return 0, "json is not object.");
15369570cc8Sopenharmony_ci    cJSON *array = cJSON_GetObjectItemCaseSensitive(json, name);
15469570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(array != NULL, return 0);
15569570cc8Sopenharmony_ci    APPSPAWN_CHECK(cJSON_IsArray(array), return 0, "json is not object.");
15669570cc8Sopenharmony_ci
15769570cc8Sopenharmony_ci    uint32_t count = 0;
15869570cc8Sopenharmony_ci    uint32_t arrayLen = cJSON_GetArraySize(array);
15969570cc8Sopenharmony_ci    for (int i = 0; i < arrayLen; i++) {
16069570cc8Sopenharmony_ci        cJSON *item = cJSON_GetArrayItem(array, i);
16169570cc8Sopenharmony_ci        uint32_t value = (uint32_t)cJSON_GetNumberValue(item);
16269570cc8Sopenharmony_ci        if (count < maxCount) {
16369570cc8Sopenharmony_ci            dataArray[count++] = value;
16469570cc8Sopenharmony_ci        }
16569570cc8Sopenharmony_ci    }
16669570cc8Sopenharmony_ci    return count;
16769570cc8Sopenharmony_ci}
16869570cc8Sopenharmony_ci
16969570cc8Sopenharmony_ciint AppSpawnTestCommander::AddBundleInfoFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle)
17069570cc8Sopenharmony_ci{
17169570cc8Sopenharmony_ci    cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "bundle-info");
17269570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(config, return 0);
17369570cc8Sopenharmony_ci
17469570cc8Sopenharmony_ci    uint32_t bundleIndex = GetIntValueFromJsonObj(config, "bundle-index", 0);
17569570cc8Sopenharmony_ci    char *bundleName = GetStringFromJsonObj(config, "bundle-name");
17669570cc8Sopenharmony_ci    int ret = AppSpawnReqMsgSetBundleInfo(reqHandle, bundleIndex, bundleName);
17769570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Failed to add bundle info req %{public}s", bundleName);
17869570cc8Sopenharmony_ci    return 0;
17969570cc8Sopenharmony_ci}
18069570cc8Sopenharmony_ci
18169570cc8Sopenharmony_ciint AppSpawnTestCommander::AddDacInfoFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle)
18269570cc8Sopenharmony_ci{
18369570cc8Sopenharmony_ci    cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "dac-info");
18469570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(config, return 0);
18569570cc8Sopenharmony_ci
18669570cc8Sopenharmony_ci    AppDacInfo info = {};
18769570cc8Sopenharmony_ci    info.uid = GetIntValueFromJsonObj(config, "uid", 0);
18869570cc8Sopenharmony_ci    info.gid = GetIntValueFromJsonObj(config, "gid", 0);
18969570cc8Sopenharmony_ci    info.gidCount = GetUint32ArrayFromJson(config, "gid-table", info.gidTable, APP_MAX_GIDS);
19069570cc8Sopenharmony_ci    char *userName = GetStringFromJsonObj(config, "user-name");
19169570cc8Sopenharmony_ci    if (userName != nullptr) {
19269570cc8Sopenharmony_ci        int ret = strcpy_s(info.userName, sizeof(info.userName), userName);
19369570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return ret, "Failed to add userName info req %{public}s", userName);
19469570cc8Sopenharmony_ci    }
19569570cc8Sopenharmony_ci    return AppSpawnReqMsgSetAppDacInfo(reqHandle, &info);
19669570cc8Sopenharmony_ci}
19769570cc8Sopenharmony_ci
19869570cc8Sopenharmony_ciint AppSpawnTestCommander::AddInternetPermissionInfoFromJson(
19969570cc8Sopenharmony_ci    const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle)
20069570cc8Sopenharmony_ci{
20169570cc8Sopenharmony_ci    cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "internet-permission");
20269570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(config, return 0);
20369570cc8Sopenharmony_ci
20469570cc8Sopenharmony_ci    uint8_t setAllowInternet = GetIntValueFromJsonObj(config, "set-allow-internet", 0);
20569570cc8Sopenharmony_ci    uint8_t allowInternet = GetIntValueFromJsonObj(config, "allow-internet", 0);
20669570cc8Sopenharmony_ci    return AppSpawnReqMsgSetAppInternetPermissionInfo(reqHandle, allowInternet, setAllowInternet);
20769570cc8Sopenharmony_ci}
20869570cc8Sopenharmony_ci
20969570cc8Sopenharmony_ciint AppSpawnTestCommander::AddAccessTokenFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle)
21069570cc8Sopenharmony_ci{
21169570cc8Sopenharmony_ci    cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "access-token");
21269570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(config, return 0);
21369570cc8Sopenharmony_ci
21469570cc8Sopenharmony_ci    uint64_t accessTokenIdEx = GetIntValueFromJsonObj(config, "accessTokenIdEx", 0);
21569570cc8Sopenharmony_ci    return AppSpawnReqMsgSetAppAccessToken(reqHandle, accessTokenIdEx);
21669570cc8Sopenharmony_ci}
21769570cc8Sopenharmony_ci
21869570cc8Sopenharmony_ciint AppSpawnTestCommander::AddDomainInfoFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle)
21969570cc8Sopenharmony_ci{
22069570cc8Sopenharmony_ci    cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "domain-info");
22169570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(config, return 0);
22269570cc8Sopenharmony_ci
22369570cc8Sopenharmony_ci    uint32_t hapFlags = GetIntValueFromJsonObj(config, "hap-flags", 0);
22469570cc8Sopenharmony_ci    char *apl = GetStringFromJsonObj(config, "apl");
22569570cc8Sopenharmony_ci    int ret = AppSpawnReqMsgSetAppDomainInfo(reqHandle, hapFlags, apl);
22669570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Failed to domain info");
22769570cc8Sopenharmony_ci    return 0;
22869570cc8Sopenharmony_ci}
22969570cc8Sopenharmony_ci
23069570cc8Sopenharmony_ciint AppSpawnTestCommander::AddExtTlv(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle)
23169570cc8Sopenharmony_ci{
23269570cc8Sopenharmony_ci    cJSON *configs = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "ext-info");
23369570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(configs != nullptr, return 0);
23469570cc8Sopenharmony_ci
23569570cc8Sopenharmony_ci    int ret = 0;
23669570cc8Sopenharmony_ci    uint32_t count = cJSON_GetArraySize(configs);
23769570cc8Sopenharmony_ci    for (unsigned int j = 0; j < count; j++) {
23869570cc8Sopenharmony_ci        cJSON *config = cJSON_GetArrayItem(configs, j);
23969570cc8Sopenharmony_ci
24069570cc8Sopenharmony_ci        char *name = GetStringFromJsonObj(config, "name");
24169570cc8Sopenharmony_ci        char *value = GetStringFromJsonObj(config, "value");
24269570cc8Sopenharmony_ci        APPSPAWN_LOGV("ext-info %{public}s %{public}s", name, value);
24369570cc8Sopenharmony_ci        ret = AppSpawnReqMsgAddStringInfo(reqHandle, name, value);
24469570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return ret, "Failed to add ext name %{public}s", name);
24569570cc8Sopenharmony_ci    }
24669570cc8Sopenharmony_ci
24769570cc8Sopenharmony_ci    // 添加一个二进制的扩展元素
24869570cc8Sopenharmony_ci    AppDacInfo dacInfo{};
24969570cc8Sopenharmony_ci    dacInfo.uid = 101;          // 101 test data
25069570cc8Sopenharmony_ci    dacInfo.gid = 101;          // 101 test data
25169570cc8Sopenharmony_ci    dacInfo.gidTable[0] = 101;  // 101 test data
25269570cc8Sopenharmony_ci    dacInfo.gidCount = 1;
25369570cc8Sopenharmony_ci    (void)strcpy_s(dacInfo.userName, sizeof(dacInfo.userName), processName_.c_str());
25469570cc8Sopenharmony_ci    ret = AppSpawnReqMsgAddExtInfo(reqHandle,
25569570cc8Sopenharmony_ci        "app-dac-info", reinterpret_cast<uint8_t *>(&dacInfo), sizeof(dacInfo));
25669570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Failed to add ext name app-info");
25769570cc8Sopenharmony_ci    return ret;
25869570cc8Sopenharmony_ci}
25969570cc8Sopenharmony_ci
26069570cc8Sopenharmony_ciint AppSpawnTestCommander::BuildMsgFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle)
26169570cc8Sopenharmony_ci{
26269570cc8Sopenharmony_ci    int ret = AddBundleInfoFromJson(appInfoConfig, reqHandle);
26369570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Failed to add dac %{public}s", processName_.c_str());
26469570cc8Sopenharmony_ci
26569570cc8Sopenharmony_ci    ret = AddDomainInfoFromJson(appInfoConfig, reqHandle);
26669570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Failed to add dac %{public}s", processName_.c_str());
26769570cc8Sopenharmony_ci
26869570cc8Sopenharmony_ci    ret = AddDacInfoFromJson(appInfoConfig, reqHandle);
26969570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Failed to add dac %{public}s", processName_.c_str());
27069570cc8Sopenharmony_ci
27169570cc8Sopenharmony_ci    ret = AddAccessTokenFromJson(appInfoConfig, reqHandle);
27269570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Failed to add access token %{public}s", processName_.c_str());
27369570cc8Sopenharmony_ci
27469570cc8Sopenharmony_ci    cJSON *obj = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "permission");
27569570cc8Sopenharmony_ci    if (obj != nullptr && cJSON_IsArray(obj)) {
27669570cc8Sopenharmony_ci        int count = cJSON_GetArraySize(obj);
27769570cc8Sopenharmony_ci        for (int i = 0; i < count; i++) {
27869570cc8Sopenharmony_ci            char *value = cJSON_GetStringValue(cJSON_GetArrayItem(obj, i));
27969570cc8Sopenharmony_ci            APPSPAWN_LOGV("permission %{public}s ", value);
28069570cc8Sopenharmony_ci            ret = AppSpawnReqMsgAddPermission(reqHandle, value);
28169570cc8Sopenharmony_ci            APPSPAWN_CHECK(ret == 0, return ret, "Failed to permission %{public}s", value);
28269570cc8Sopenharmony_ci        }
28369570cc8Sopenharmony_ci    }
28469570cc8Sopenharmony_ci
28569570cc8Sopenharmony_ci    ret = AddInternetPermissionInfoFromJson(appInfoConfig, reqHandle);
28669570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Failed to internet info %{public}s", processName_.c_str());
28769570cc8Sopenharmony_ci
28869570cc8Sopenharmony_ci    std::string ownerId = GetStringFromJsonObj(appInfoConfig, "owner-id");
28969570cc8Sopenharmony_ci    if (!ownerId.empty()) {
29069570cc8Sopenharmony_ci        ret = AppSpawnReqMsgSetAppOwnerId(reqHandle, ownerId.c_str());
29169570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return ret, "Failed to ownerid %{public}s", processName_.c_str());
29269570cc8Sopenharmony_ci    }
29369570cc8Sopenharmony_ci
29469570cc8Sopenharmony_ci    std::string renderCmd = GetStringFromJsonObj(appInfoConfig, "render-cmd");
29569570cc8Sopenharmony_ci    if (!renderCmd.empty()) {
29669570cc8Sopenharmony_ci        ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_RENDER_CMD, renderCmd.c_str());
29769570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return -1, "Failed to add renderCmd %{public}s", renderCmd.c_str());
29869570cc8Sopenharmony_ci    }
29969570cc8Sopenharmony_ci    return AddExtTlv(appInfoConfig, reqHandle);
30069570cc8Sopenharmony_ci}
30169570cc8Sopenharmony_ci
30269570cc8Sopenharmony_ciint AppSpawnTestCommander::CreateOtherMsg(AppSpawnReqMsgHandle &reqHandle, pid_t pid)
30369570cc8Sopenharmony_ci{
30469570cc8Sopenharmony_ci    if (msgType_ == MSG_GET_RENDER_TERMINATION_STATUS) {
30569570cc8Sopenharmony_ci        int ret = AppSpawnTerminateMsgCreate(pid, &reqHandle);
30669570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return ret, "Failed to termination message req %{public}s", processName_.c_str());
30769570cc8Sopenharmony_ci    }
30869570cc8Sopenharmony_ci    if (msgType_ == MSG_DUMP) {
30969570cc8Sopenharmony_ci        int ret = AppSpawnReqMsgCreate(static_cast<AppSpawnMsgType>(msgType_), processName_.c_str(), &reqHandle);
31069570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return ret, "Failed to dump req %{public}s", processName_.c_str());
31169570cc8Sopenharmony_ci        ret = AppSpawnReqMsgAddStringInfo(reqHandle, "pty-name", ptyName_.c_str());
31269570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return -1, "Failed to add ptyName_ %{public}s", ptyName_.c_str());
31369570cc8Sopenharmony_ci    }
31469570cc8Sopenharmony_ci    return 0;
31569570cc8Sopenharmony_ci}
31669570cc8Sopenharmony_ci
31769570cc8Sopenharmony_cistatic uint32_t GetMsgTypeFromJson(const cJSON *json)
31869570cc8Sopenharmony_ci{
31969570cc8Sopenharmony_ci    const char *msgType = GetStringFromJsonObj(json, "msg-type");
32069570cc8Sopenharmony_ci    if (msgType == nullptr) {
32169570cc8Sopenharmony_ci        return MSG_APP_SPAWN;
32269570cc8Sopenharmony_ci    }
32369570cc8Sopenharmony_ci    if (strcmp(msgType, "MSG_SPAWN_NATIVE_PROCESS") == 0) {
32469570cc8Sopenharmony_ci        return MSG_SPAWN_NATIVE_PROCESS;
32569570cc8Sopenharmony_ci    }
32669570cc8Sopenharmony_ci    if (strcmp(msgType, "MSG_GET_RENDER_TERMINATION_STATUS") == 0) {
32769570cc8Sopenharmony_ci        return MSG_GET_RENDER_TERMINATION_STATUS;
32869570cc8Sopenharmony_ci    }
32969570cc8Sopenharmony_ci    if (strcmp(msgType, "MSG_DUMP") == 0) {
33069570cc8Sopenharmony_ci        return MSG_DUMP;
33169570cc8Sopenharmony_ci    }
33269570cc8Sopenharmony_ci    return MSG_APP_SPAWN;
33369570cc8Sopenharmony_ci}
33469570cc8Sopenharmony_ci
33569570cc8Sopenharmony_ciint AppSpawnTestCommander::CreateMsg(AppSpawnReqMsgHandle &reqHandle,
33669570cc8Sopenharmony_ci    const char *defaultConfig, uint32_t defMsgType)
33769570cc8Sopenharmony_ci{
33869570cc8Sopenharmony_ci    int ret = APPSPAWN_SYSTEM_ERROR;
33969570cc8Sopenharmony_ci    if (clientHandle_ == NULL) {
34069570cc8Sopenharmony_ci        ret = AppSpawnClientInit(appSpawn_ ? APPSPAWN_SERVER_NAME : NWEBSPAWN_SERVER_NAME, &clientHandle_);
34169570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return -1, "Failed to create client %{public}d", appSpawn_);
34269570cc8Sopenharmony_ci    }
34369570cc8Sopenharmony_ci    reqHandle = INVALID_REQ_HANDLE;
34469570cc8Sopenharmony_ci    if (appInfoConfig_) {
34569570cc8Sopenharmony_ci        cJSON_Delete(appInfoConfig_);
34669570cc8Sopenharmony_ci        appInfoConfig_ = nullptr;
34769570cc8Sopenharmony_ci    }
34869570cc8Sopenharmony_ci    if (!testFileName_.empty()) {
34969570cc8Sopenharmony_ci        appInfoConfig_ = GetJsonObjFromFile(testFileName_.c_str());
35069570cc8Sopenharmony_ci        if (appInfoConfig_ == nullptr) {
35169570cc8Sopenharmony_ci            printf("Failed to load file %s, so use default info \n", testFileName_.c_str());
35269570cc8Sopenharmony_ci        }
35369570cc8Sopenharmony_ci    }
35469570cc8Sopenharmony_ci    if (appInfoConfig_ == nullptr) {
35569570cc8Sopenharmony_ci        appInfoConfig_ = cJSON_Parse(defaultConfig);
35669570cc8Sopenharmony_ci    }
35769570cc8Sopenharmony_ci    if (appInfoConfig_ == nullptr) {
35869570cc8Sopenharmony_ci        printf("Invalid app info \n");
35969570cc8Sopenharmony_ci        return APPSPAWN_SYSTEM_ERROR;
36069570cc8Sopenharmony_ci    }
36169570cc8Sopenharmony_ci    processName_ = GetStringFromJsonObj(appInfoConfig_, "process-name");
36269570cc8Sopenharmony_ci    if (processName_.empty()) {
36369570cc8Sopenharmony_ci        processName_ = "com.example.myapplication";
36469570cc8Sopenharmony_ci    }
36569570cc8Sopenharmony_ci    msgType_ = (msgType_ == MAX_TYPE_INVALID) ? GetMsgTypeFromJson(appInfoConfig_) : msgType_;
36669570cc8Sopenharmony_ci    msgType_ = (defMsgType != MAX_TYPE_INVALID) ? defMsgType : msgType_;
36769570cc8Sopenharmony_ci    if (msgType_ == MSG_DUMP) {
36869570cc8Sopenharmony_ci        return CreateOtherMsg(reqHandle, 0);
36969570cc8Sopenharmony_ci    } else if (msgType_ == MSG_GET_RENDER_TERMINATION_STATUS) {
37069570cc8Sopenharmony_ci        pid_t pid = GetIntValueFromJsonObj(appInfoConfig_, "pid", 0);
37169570cc8Sopenharmony_ci        return CreateOtherMsg(reqHandle, pid);
37269570cc8Sopenharmony_ci    }
37369570cc8Sopenharmony_ci    ret = AppSpawnReqMsgCreate(static_cast<AppSpawnMsgType>(msgType_), processName_.c_str(), &reqHandle);
37469570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Failed to create req %{public}s", processName_.c_str());
37569570cc8Sopenharmony_ci
37669570cc8Sopenharmony_ci    uint32_t msgFlags[64] = {};  // 64
37769570cc8Sopenharmony_ci    uint32_t count = GetUint32ArrayFromJson(appInfoConfig_, "msg-flags", msgFlags, ARRAY_LENGTH(msgFlags));
37869570cc8Sopenharmony_ci    for (uint32_t j = 0; j < count; j++) {
37969570cc8Sopenharmony_ci        (void)AppSpawnReqMsgSetAppFlag(reqHandle, static_cast<AppFlagsIndex>(msgFlags[j]));
38069570cc8Sopenharmony_ci    }
38169570cc8Sopenharmony_ci    (void)AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_IGNORE_SANDBOX);
38269570cc8Sopenharmony_ci    ret = BuildMsgFromJson(appInfoConfig_, reqHandle);
38369570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, AppSpawnReqMsgFree(reqHandle);
38469570cc8Sopenharmony_ci        return ret, "Failed to build req %{public}s", processName_.c_str());
38569570cc8Sopenharmony_ci    return ret;
38669570cc8Sopenharmony_ci}
38769570cc8Sopenharmony_ci
38869570cc8Sopenharmony_ciint AppSpawnTestCommander::SendMsg()
38969570cc8Sopenharmony_ci{
39069570cc8Sopenharmony_ci    const char *server = appSpawn_ == 1 ? APPSPAWN_SERVER_NAME : (appSpawn_ == 2 ? NATIVESPAWN_SERVER_NAME :
39169570cc8Sopenharmony_ci        NWEBSPAWN_SERVER_NAME);
39269570cc8Sopenharmony_ci    printf("Send msg to server '%s' \n", server);
39369570cc8Sopenharmony_ci    AppSpawnReqMsgHandle reqHandle = INVALID_REQ_HANDLE;
39469570cc8Sopenharmony_ci    int ret = 0;
39569570cc8Sopenharmony_ci    if (msgType_ == MSG_DUMP) {
39669570cc8Sopenharmony_ci        while (!dumpFlags) {
39769570cc8Sopenharmony_ci            usleep(20000);  // 20000
39869570cc8Sopenharmony_ci        }
39969570cc8Sopenharmony_ci        ret = CreateOtherMsg(reqHandle, 0);
40069570cc8Sopenharmony_ci    } else if (msgType_ == MSG_GET_RENDER_TERMINATION_STATUS) {
40169570cc8Sopenharmony_ci        ret = CreateOtherMsg(reqHandle, terminatePid_);
40269570cc8Sopenharmony_ci    } else {
40369570cc8Sopenharmony_ci        ret = CreateMsg(reqHandle, g_defaultAppInfo.c_str());
40469570cc8Sopenharmony_ci    }
40569570cc8Sopenharmony_ci    AppSpawnResult result = {ret, 0};
40669570cc8Sopenharmony_ci    if (ret == 0) {
40769570cc8Sopenharmony_ci        ret = AppSpawnClientSendMsg(clientHandle_, reqHandle, &result);
40869570cc8Sopenharmony_ci    }
40969570cc8Sopenharmony_ci    switch (msgType_) {
41069570cc8Sopenharmony_ci        case MSG_APP_SPAWN:
41169570cc8Sopenharmony_ci            if (result.result == 0) {
41269570cc8Sopenharmony_ci                printf("Spawn app %s success, pid %d \n", processName_.c_str(), result.pid);
41369570cc8Sopenharmony_ci            } else {
41469570cc8Sopenharmony_ci                printf("Spawn app %s fail, result 0x%x \n", processName_.c_str(), result.result);
41569570cc8Sopenharmony_ci            }
41669570cc8Sopenharmony_ci            break;
41769570cc8Sopenharmony_ci        case MSG_SPAWN_NATIVE_PROCESS:
41869570cc8Sopenharmony_ci            if (result.result == 0) {
41969570cc8Sopenharmony_ci                printf("Spawn native app %s success, pid %d \n", processName_.c_str(), result.pid);
42069570cc8Sopenharmony_ci            } else {
42169570cc8Sopenharmony_ci                printf("Spawn native app %s fail, result 0x%x \n", processName_.c_str(), result.result);
42269570cc8Sopenharmony_ci            }
42369570cc8Sopenharmony_ci            break;
42469570cc8Sopenharmony_ci        case MSG_GET_RENDER_TERMINATION_STATUS:
42569570cc8Sopenharmony_ci            printf("Terminate app %s success, pid %d status 0x%x \n",
42669570cc8Sopenharmony_ci                processName_.c_str(), result.pid, result.result);
42769570cc8Sopenharmony_ci            break;
42869570cc8Sopenharmony_ci        default:
42969570cc8Sopenharmony_ci            printf("Dump server %s result %d \n", server, ret);
43069570cc8Sopenharmony_ci            break;
43169570cc8Sopenharmony_ci    }
43269570cc8Sopenharmony_ci    msgType_ = MAX_TYPE_INVALID;
43369570cc8Sopenharmony_ci    terminatePid_ = 0;
43469570cc8Sopenharmony_ci    printf("Please input cmd: \n");
43569570cc8Sopenharmony_ci    return 0;
43669570cc8Sopenharmony_ci}
43769570cc8Sopenharmony_ci
43869570cc8Sopenharmony_ciint AppSpawnTestCommander::StartSendMsg()
43969570cc8Sopenharmony_ci{
44069570cc8Sopenharmony_ci    int ret = 0;
44169570cc8Sopenharmony_ci    printf("Start send msg thread count %d file name %s \n", threadCount_, testFileName_.c_str());
44269570cc8Sopenharmony_ci    if (threadCount_ == 1) {
44369570cc8Sopenharmony_ci        SendMsg();
44469570cc8Sopenharmony_ci    } else {
44569570cc8Sopenharmony_ci        ThreadTaskHandle taskHandle = 0;
44669570cc8Sopenharmony_ci        ret = ThreadMgrAddTask(threadMgr_, &taskHandle);
44769570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return 0, "Failed to add task ");
44869570cc8Sopenharmony_ci        for (uint32_t index = 0; index < threadCount_; index++) {
44969570cc8Sopenharmony_ci            ThreadMgrAddExecutor(threadMgr_, taskHandle, TaskExecutorProc, reinterpret_cast<ThreadContext *>(this));
45069570cc8Sopenharmony_ci        }
45169570cc8Sopenharmony_ci        TaskSyncExecute(threadMgr_, taskHandle);
45269570cc8Sopenharmony_ci    }
45369570cc8Sopenharmony_ci    return 0;
45469570cc8Sopenharmony_ci}
45569570cc8Sopenharmony_ci
45669570cc8Sopenharmony_civoid AppSpawnTestCommander::TaskExecutorProc(ThreadTaskHandle handle, const ThreadContext *context)
45769570cc8Sopenharmony_ci{
45869570cc8Sopenharmony_ci    AppSpawnTestCommander *testCmder = AppSpawnTestCommander::ConvertTo(context);
45969570cc8Sopenharmony_ci    testCmder->SendMsg();
46069570cc8Sopenharmony_ci}
46169570cc8Sopenharmony_ci
46269570cc8Sopenharmony_civoid AppSpawnTestCommander::SendTaskFinish(ThreadTaskHandle handle, const ThreadContext *context)
46369570cc8Sopenharmony_ci{
46469570cc8Sopenharmony_ci    APPSPAWN_LOGV("SendTaskFinish %{public}u \n", handle);
46569570cc8Sopenharmony_ci}
46669570cc8Sopenharmony_ci
46769570cc8Sopenharmony_cistatic std::vector<std::string> g_args;
46869570cc8Sopenharmony_cistatic int HandleSplitString(const char *str, void *context)
46969570cc8Sopenharmony_ci{
47069570cc8Sopenharmony_ci    APPSPAWN_LOGV("HandleSplitString %{public}s ", str);
47169570cc8Sopenharmony_ci    std::string value = str;
47269570cc8Sopenharmony_ci    g_args.push_back(value);
47369570cc8Sopenharmony_ci    return 0;
47469570cc8Sopenharmony_ci}
47569570cc8Sopenharmony_ci
47669570cc8Sopenharmony_ciint AppSpawnTestCommander::ProcessInputCmd(std::string &cmd)
47769570cc8Sopenharmony_ci{
47869570cc8Sopenharmony_ci    g_args.clear();
47969570cc8Sopenharmony_ci    int ret = StringSplit(cmd.c_str(), " ", nullptr, HandleSplitString);
48069570cc8Sopenharmony_ci    std::vector<char *> options;
48169570cc8Sopenharmony_ci    for (const auto &arg : g_args) {
48269570cc8Sopenharmony_ci        if (!arg.empty()) {
48369570cc8Sopenharmony_ci            options.push_back(const_cast<char *>(arg.c_str()));
48469570cc8Sopenharmony_ci        }
48569570cc8Sopenharmony_ci    }
48669570cc8Sopenharmony_ci    (void)ProcessArgs(options.size(), options.data());
48769570cc8Sopenharmony_ci    StartSendMsg();
48869570cc8Sopenharmony_ci    return ret;
48969570cc8Sopenharmony_ci}
49069570cc8Sopenharmony_ci
49169570cc8Sopenharmony_civoid AppSpawnTestCommander::InputThread(ThreadTaskHandle handle, const ThreadContext *context)
49269570cc8Sopenharmony_ci{
49369570cc8Sopenharmony_ci    AppSpawnTestCommander *testCmder = AppSpawnTestCommander::ConvertTo(context);
49469570cc8Sopenharmony_ci    char buffer[1024] = {0};  // 1024 test buffer max len
49569570cc8Sopenharmony_ci    fd_set fds;
49669570cc8Sopenharmony_ci    printf("Please input cmd: \n");
49769570cc8Sopenharmony_ci    while (1) {
49869570cc8Sopenharmony_ci        FD_ZERO(&fds);
49969570cc8Sopenharmony_ci        FD_SET(STDIN_FILENO, &fds);
50069570cc8Sopenharmony_ci        int ret = select(STDIN_FILENO + 1, &fds, nullptr, nullptr, nullptr);
50169570cc8Sopenharmony_ci        if (ret <= 0) {
50269570cc8Sopenharmony_ci            if (testCmder->exit_) {
50369570cc8Sopenharmony_ci                break;
50469570cc8Sopenharmony_ci            }
50569570cc8Sopenharmony_ci            continue;
50669570cc8Sopenharmony_ci        }
50769570cc8Sopenharmony_ci        ssize_t rlen = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);
50869570cc8Sopenharmony_ci        if (rlen <= 1) {
50969570cc8Sopenharmony_ci            continue;
51069570cc8Sopenharmony_ci        }
51169570cc8Sopenharmony_ci        buffer[rlen - 1] = 0;
51269570cc8Sopenharmony_ci        printf("Recv command: '%s' \n", buffer);
51369570cc8Sopenharmony_ci        if (strncmp("quit", buffer, strlen("quit")) == 0) {
51469570cc8Sopenharmony_ci            testCmder->exit_ = 1;
51569570cc8Sopenharmony_ci            break;
51669570cc8Sopenharmony_ci        }
51769570cc8Sopenharmony_ci        if (strncmp("send", buffer, 4) == 0) {  // 4 strlen("send")
51869570cc8Sopenharmony_ci            std::string cmd(buffer);
51969570cc8Sopenharmony_ci            testCmder->ProcessInputCmd(cmd);
52069570cc8Sopenharmony_ci            printf("Please input cmd: \n");
52169570cc8Sopenharmony_ci        }
52269570cc8Sopenharmony_ci    }
52369570cc8Sopenharmony_ci}
52469570cc8Sopenharmony_ci
52569570cc8Sopenharmony_civoid AppSpawnTestCommander::DumpThread(ThreadTaskHandle handle, const ThreadContext *context)
52669570cc8Sopenharmony_ci{
52769570cc8Sopenharmony_ci    AppSpawnTestCommander *testCmder = AppSpawnTestCommander::ConvertTo(context);
52869570cc8Sopenharmony_ci    printf("Start dump thread \n");
52969570cc8Sopenharmony_ci    char buffer[10240] = {0};  // 1024 test buffer max len
53069570cc8Sopenharmony_ci    fd_set fds;
53169570cc8Sopenharmony_ci    while (1) {
53269570cc8Sopenharmony_ci        testCmder->dumpFlags = 1;
53369570cc8Sopenharmony_ci        FD_ZERO(&fds);
53469570cc8Sopenharmony_ci        FD_SET(testCmder->ptyFd_, &fds);
53569570cc8Sopenharmony_ci        int ret = select(testCmder->ptyFd_ + 1, &fds, nullptr, nullptr, nullptr);
53669570cc8Sopenharmony_ci        if (ret <= 0) {
53769570cc8Sopenharmony_ci            if (testCmder->exit_) {
53869570cc8Sopenharmony_ci                break;
53969570cc8Sopenharmony_ci            }
54069570cc8Sopenharmony_ci            continue;
54169570cc8Sopenharmony_ci        }
54269570cc8Sopenharmony_ci        if (!FD_ISSET(testCmder->ptyFd_, &fds)) {
54369570cc8Sopenharmony_ci            continue;
54469570cc8Sopenharmony_ci        }
54569570cc8Sopenharmony_ci        ssize_t rlen = read(testCmder->ptyFd_, buffer, sizeof(buffer) - 1);
54669570cc8Sopenharmony_ci        while (rlen > 0) {
54769570cc8Sopenharmony_ci            buffer[rlen] = '\0';
54869570cc8Sopenharmony_ci            printf("%s", buffer);
54969570cc8Sopenharmony_ci            fflush(stdout);
55069570cc8Sopenharmony_ci            rlen = read(testCmder->ptyFd_, buffer, sizeof(buffer) - 1);
55169570cc8Sopenharmony_ci        }
55269570cc8Sopenharmony_ci    }
55369570cc8Sopenharmony_ci}
55469570cc8Sopenharmony_ci
55569570cc8Sopenharmony_ciint AppSpawnTestCommander::Run()
55669570cc8Sopenharmony_ci{
55769570cc8Sopenharmony_ci    int ret = 0;
55869570cc8Sopenharmony_ci    const char *name = appSpawn_ == 1 ? APPSPAWN_SERVER_NAME : (appSpawn_ == 2 ? NATIVESPAWN_SERVER_NAME :
55969570cc8Sopenharmony_ci        NWEBSPAWN_SERVER_NAME);
56069570cc8Sopenharmony_ci    if (clientHandle_ == NULL) {
56169570cc8Sopenharmony_ci        ret = AppSpawnClientInit(name, &clientHandle_);
56269570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return -1, "Failed to create client %{public}s", name);
56369570cc8Sopenharmony_ci    }
56469570cc8Sopenharmony_ci
56569570cc8Sopenharmony_ci    InitPtyInterface();
56669570cc8Sopenharmony_ci
56769570cc8Sopenharmony_ci    ret = CreateThreadMgr(5, &threadMgr_);  // 5 max thread
56869570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed to create thread manager");
56969570cc8Sopenharmony_ci
57069570cc8Sopenharmony_ci    ret = ThreadMgrAddTask(threadMgr_, &inputHandle_);
57169570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return 0, "Failed to add task for thread ");
57269570cc8Sopenharmony_ci    ThreadMgrAddExecutor(threadMgr_, inputHandle_, InputThread, this);
57369570cc8Sopenharmony_ci    TaskExecute(threadMgr_, inputHandle_, SendTaskFinish, this);
57469570cc8Sopenharmony_ci
57569570cc8Sopenharmony_ci    ret = ThreadMgrAddTask(threadMgr_, &dumpHandle_);
57669570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return 0, "Failed to add task for thread ");
57769570cc8Sopenharmony_ci    ThreadMgrAddExecutor(threadMgr_, dumpHandle_, DumpThread, this);
57869570cc8Sopenharmony_ci    TaskExecute(threadMgr_, dumpHandle_, SendTaskFinish, this);
57969570cc8Sopenharmony_ci
58069570cc8Sopenharmony_ci    StartSendMsg();
58169570cc8Sopenharmony_ci
58269570cc8Sopenharmony_ci    APPSPAWN_LOGV("Finish send msg \n");
58369570cc8Sopenharmony_ci    while (!exit_) {
58469570cc8Sopenharmony_ci        usleep(200000);  // 200000 200ms
58569570cc8Sopenharmony_ci    }
58669570cc8Sopenharmony_ci    ThreadMgrCancelTask(threadMgr_, inputHandle_);
58769570cc8Sopenharmony_ci    ThreadMgrCancelTask(threadMgr_, dumpHandle_);
58869570cc8Sopenharmony_ci    DestroyThreadMgr(threadMgr_);
58969570cc8Sopenharmony_ci    threadMgr_ = nullptr;
59069570cc8Sopenharmony_ci    inputHandle_ = 0;
59169570cc8Sopenharmony_ci    dumpHandle_ = 0;
59269570cc8Sopenharmony_ci    AppSpawnClientDestroy(clientHandle_);
59369570cc8Sopenharmony_ci    clientHandle_ = nullptr;
59469570cc8Sopenharmony_ci    return 0;
59569570cc8Sopenharmony_ci}
59669570cc8Sopenharmony_ci
59769570cc8Sopenharmony_ciint AppSpawnTestCommander::InitPtyInterface()
59869570cc8Sopenharmony_ci{
59969570cc8Sopenharmony_ci    // open master pty and get slave pty
60069570cc8Sopenharmony_ci    int pfd = open("/dev/ptmx", O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
60169570cc8Sopenharmony_ci    APPSPAWN_CHECK(pfd >= 0, return -1, "Failed open pty err=%{public}d", errno);
60269570cc8Sopenharmony_ci    APPSPAWN_CHECK(grantpt(pfd) >= 0, close(pfd); return -1, "Failed to call grantpt");
60369570cc8Sopenharmony_ci    APPSPAWN_CHECK(unlockpt(pfd) >= 0, close(pfd); return -1, "Failed to call unlockpt");
60469570cc8Sopenharmony_ci    char ptsbuffer[PTY_PATH_SIZE] = {0};
60569570cc8Sopenharmony_ci    int ret = ptsname_r(pfd, ptsbuffer, sizeof(ptsbuffer));
60669570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret >= 0, close(pfd);
60769570cc8Sopenharmony_ci        return -1, "Failed to get pts name err=%{public}d", errno);
60869570cc8Sopenharmony_ci    APPSPAWN_LOGI("ptsbuffer is %{public}s", ptsbuffer);
60969570cc8Sopenharmony_ci    APPSPAWN_CHECK(chmod(ptsbuffer, S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) == 0, close(pfd);
61069570cc8Sopenharmony_ci        return -1, "Failed to chmod %{public}s, err=%{public}d", ptsbuffer, errno);
61169570cc8Sopenharmony_ci    ptyFd_ = pfd;
61269570cc8Sopenharmony_ci    ptyName_ = std::string(ptsbuffer);
61369570cc8Sopenharmony_ci    return 0;
61469570cc8Sopenharmony_ci}
61569570cc8Sopenharmony_ci}  // namespace AppSpawnModuleTest
61669570cc8Sopenharmony_ci}  // namespace OHOS
617