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 "app_spawn_test_helper.h"
1769570cc8Sopenharmony_ci
1869570cc8Sopenharmony_ci#include <cstdint>
1969570cc8Sopenharmony_ci#include <cstdio>
2069570cc8Sopenharmony_ci#include <cstdlib>
2169570cc8Sopenharmony_ci#include <fcntl.h>
2269570cc8Sopenharmony_ci#include <pthread.h>
2369570cc8Sopenharmony_ci#include <csignal>
2469570cc8Sopenharmony_ci#include <string>
2569570cc8Sopenharmony_ci#include <sys/eventfd.h>
2669570cc8Sopenharmony_ci#include <sys/wait.h>
2769570cc8Sopenharmony_ci#include <unistd.h>
2869570cc8Sopenharmony_ci#include <inttypes.h>
2969570cc8Sopenharmony_ci
3069570cc8Sopenharmony_ci#include "appspawn.h"
3169570cc8Sopenharmony_ci#include "appspawn_client.h"
3269570cc8Sopenharmony_ci#include "appspawn_modulemgr.h"
3369570cc8Sopenharmony_ci#include "appspawn_msg.h"
3469570cc8Sopenharmony_ci#include "appspawn_server.h"
3569570cc8Sopenharmony_ci#include "appspawn_service.h"
3669570cc8Sopenharmony_ci#include "appspawn_manager.h"
3769570cc8Sopenharmony_ci#include "appspawn_utils.h"
3869570cc8Sopenharmony_ci#include "loop_event.h"
3969570cc8Sopenharmony_ci#include "parameters.h"
4069570cc8Sopenharmony_ci#include "securec.h"
4169570cc8Sopenharmony_ci
4269570cc8Sopenharmony_ci#include "app_spawn_stub.h"
4369570cc8Sopenharmony_ci
4469570cc8Sopenharmony_cinamespace OHOS {
4569570cc8Sopenharmony_citypedef struct {
4669570cc8Sopenharmony_ci    int32_t bundleIndex;
4769570cc8Sopenharmony_ci    char bundleName[APP_LEN_BUNDLE_NAME];  // process name
4869570cc8Sopenharmony_ci} AppBundleInfo;
4969570cc8Sopenharmony_ci
5069570cc8Sopenharmony_citypedef struct {
5169570cc8Sopenharmony_ci    uint32_t hapFlags;
5269570cc8Sopenharmony_ci    char apl[APP_APL_MAX_LEN];
5369570cc8Sopenharmony_ci} AppDomainInfo;
5469570cc8Sopenharmony_ci
5569570cc8Sopenharmony_ciconst uint32_t AppSpawnTestServer::defaultProtectTime = 60000; // 60000 60s
5669570cc8Sopenharmony_ci
5769570cc8Sopenharmony_ciuint32_t AppSpawnTestServer::serverId = 0;
5869570cc8Sopenharmony_cistatic int TestChildLoopRun(AppSpawnContent *content, AppSpawnClient *client)
5969570cc8Sopenharmony_ci{
6069570cc8Sopenharmony_ci    APPSPAWN_LOGV("ChildLoopRun ...");
6169570cc8Sopenharmony_ci    sleep(1);
6269570cc8Sopenharmony_ci    return 0;
6369570cc8Sopenharmony_ci}
6469570cc8Sopenharmony_ci
6569570cc8Sopenharmony_ciAppSpawnTestServer::~AppSpawnTestServer()
6669570cc8Sopenharmony_ci{
6769570cc8Sopenharmony_ci    if (localServer_) {
6869570cc8Sopenharmony_ci        delete localServer_;
6969570cc8Sopenharmony_ci        localServer_ = nullptr;
7069570cc8Sopenharmony_ci    }
7169570cc8Sopenharmony_ci}
7269570cc8Sopenharmony_ci
7369570cc8Sopenharmony_civoid AppSpawnTestServer::CloseCheckHandler(void)
7469570cc8Sopenharmony_ci{
7569570cc8Sopenharmony_ci    APPSPAWN_LOGV("CloseCheckHandler");
7669570cc8Sopenharmony_ci#ifdef USER_TIMER_TO_CHECK
7769570cc8Sopenharmony_ci    if (timer_ != nullptr) {
7869570cc8Sopenharmony_ci        LE_StopTimer(LE_GetDefaultLoop(), timer_);
7969570cc8Sopenharmony_ci        timer_ = nullptr;
8069570cc8Sopenharmony_ci    }
8169570cc8Sopenharmony_ci#else
8269570cc8Sopenharmony_ci    if (idle_) {
8369570cc8Sopenharmony_ci        LE_DelIdle(idle_);
8469570cc8Sopenharmony_ci        idle_ = nullptr;
8569570cc8Sopenharmony_ci    }
8669570cc8Sopenharmony_ci#endif
8769570cc8Sopenharmony_ci}
8869570cc8Sopenharmony_ci
8969570cc8Sopenharmony_civoid AppSpawnTestServer::StartCheckHandler(void)
9069570cc8Sopenharmony_ci{
9169570cc8Sopenharmony_ci#ifdef USER_TIMER_TO_CHECK
9269570cc8Sopenharmony_ci    int ret = LE_CreateTimer(LE_GetDefaultLoop(), &timer_, ProcessIdle, this);
9369570cc8Sopenharmony_ci    if (ret == 0) {
9469570cc8Sopenharmony_ci        ret = LE_StartTimer(LE_GetDefaultLoop(), timer_, 100, 10000000);  // 100 10000000 repeat
9569570cc8Sopenharmony_ci    }
9669570cc8Sopenharmony_ci#else
9769570cc8Sopenharmony_ci    LE_AddIdle(LE_GetDefaultLoop(), &idle_, ProcessIdle, this, 10000000);  // 10000000 repeat
9869570cc8Sopenharmony_ci#endif
9969570cc8Sopenharmony_ci}
10069570cc8Sopenharmony_ci
10169570cc8Sopenharmony_civoid AppSpawnTestServer::ServiceThread()
10269570cc8Sopenharmony_ci{
10369570cc8Sopenharmony_ci    CmdArgs *args = nullptr;
10469570cc8Sopenharmony_ci    pid_t pid = getpid();
10569570cc8Sopenharmony_ci    APPSPAWN_LOGV("AppSpawnTestServer::ServiceThread %{public}s", serviceCmd_.c_str());
10669570cc8Sopenharmony_ci
10769570cc8Sopenharmony_ci    running_ = true;
10869570cc8Sopenharmony_ci    // 测试server时,使用appspawn的server
10969570cc8Sopenharmony_ci    if (testServer_) {
11069570cc8Sopenharmony_ci        content_ = AppSpawnTestHelper::StartSpawnServer(serviceCmd_, args);
11169570cc8Sopenharmony_ci        if (content_ == nullptr) {
11269570cc8Sopenharmony_ci            return;
11369570cc8Sopenharmony_ci        }
11469570cc8Sopenharmony_ci        if (pid == getpid()) {  // 主进程进行处理
11569570cc8Sopenharmony_ci            APPSPAWN_LOGV("Service start timer %{public}s ", serviceCmd_.c_str());
11669570cc8Sopenharmony_ci            StartCheckHandler();
11769570cc8Sopenharmony_ci            AppSpawnMgr *content = reinterpret_cast<AppSpawnMgr *>(content_);
11869570cc8Sopenharmony_ci            APPSPAWN_CHECK_ONLY_EXPER(content != nullptr, return);
11969570cc8Sopenharmony_ci            AppSpawnedProcess *info = GetSpawnedProcessByName(NWEBSPAWN_SERVER_NAME);
12069570cc8Sopenharmony_ci            if (info != nullptr) {
12169570cc8Sopenharmony_ci                APPSPAWN_LOGV("Save nwebspawn pid: %{public}d %{public}d", info->pid, serverId_);
12269570cc8Sopenharmony_ci                appPid_.store(info->pid);
12369570cc8Sopenharmony_ci            }
12469570cc8Sopenharmony_ci            // register
12569570cc8Sopenharmony_ci            RegChildLooper(&content->content, TestChildLoopRun);
12669570cc8Sopenharmony_ci        }
12769570cc8Sopenharmony_ci        content_->runAppSpawn(content_, args->argc, args->argv);
12869570cc8Sopenharmony_ci        if (pid != getpid()) {  // 子进程退出
12969570cc8Sopenharmony_ci            exit(0);
13069570cc8Sopenharmony_ci        } else {
13169570cc8Sopenharmony_ci            content_ = nullptr;
13269570cc8Sopenharmony_ci        }
13369570cc8Sopenharmony_ci    } else {
13469570cc8Sopenharmony_ci        StartCheckHandler();
13569570cc8Sopenharmony_ci        localServer_ = new LocalTestServer();
13669570cc8Sopenharmony_ci        localServer_->Run(APPSPAWN_SOCKET_NAME, recvMsgProcess_);
13769570cc8Sopenharmony_ci    }
13869570cc8Sopenharmony_ci    APPSPAWN_LOGV("AppSpawnTestServer::ServiceThread finish %{public}s ", serviceCmd_.c_str());
13969570cc8Sopenharmony_ci    if (args) {
14069570cc8Sopenharmony_ci        free(args);
14169570cc8Sopenharmony_ci    }
14269570cc8Sopenharmony_ci    return;
14369570cc8Sopenharmony_ci}
14469570cc8Sopenharmony_ci
14569570cc8Sopenharmony_civoid AppSpawnTestServer::Start(void)
14669570cc8Sopenharmony_ci{
14769570cc8Sopenharmony_ci    Start(nullptr);
14869570cc8Sopenharmony_ci}
14969570cc8Sopenharmony_ci
15069570cc8Sopenharmony_cistatic void *ServiceHelperThread(void *arg)
15169570cc8Sopenharmony_ci{
15269570cc8Sopenharmony_ci    AppSpawnTestServer *server = reinterpret_cast<AppSpawnTestServer *>(arg);
15369570cc8Sopenharmony_ci    APPSPAWN_LOGV("AppSpawnTestServer::thread ");
15469570cc8Sopenharmony_ci    server->ServiceThread();
15569570cc8Sopenharmony_ci    return nullptr;
15669570cc8Sopenharmony_ci}
15769570cc8Sopenharmony_ci
15869570cc8Sopenharmony_civoid AppSpawnTestServer::Start(RecvMsgProcess process, uint32_t time)
15969570cc8Sopenharmony_ci{
16069570cc8Sopenharmony_ci    APPSPAWN_LOGV("AppSpawnTestServer::Start serverId %{public}u", AppSpawnTestServer::serverId);
16169570cc8Sopenharmony_ci    protectTime_ = time;
16269570cc8Sopenharmony_ci    uint32_t retry = 0;
16369570cc8Sopenharmony_ci    if (threadId_ != 0) {
16469570cc8Sopenharmony_ci        return;
16569570cc8Sopenharmony_ci    }
16669570cc8Sopenharmony_ci    clock_gettime(CLOCK_MONOTONIC, &startTime_);
16769570cc8Sopenharmony_ci    recvMsgProcess_ = process;
16869570cc8Sopenharmony_ci    errno = 0;
16969570cc8Sopenharmony_ci    int ret = 0;
17069570cc8Sopenharmony_ci    do {
17169570cc8Sopenharmony_ci        threadId_ = 0;
17269570cc8Sopenharmony_ci        ret = pthread_create(&threadId_, nullptr, ServiceHelperThread, static_cast<void *>(this));
17369570cc8Sopenharmony_ci        if (ret == 0) {
17469570cc8Sopenharmony_ci            break;
17569570cc8Sopenharmony_ci        }
17669570cc8Sopenharmony_ci        APPSPAWN_LOGE("AppSpawnTestServer::Start create thread fail %{public}d %{public}d", ret, errno);
17769570cc8Sopenharmony_ci        usleep(20000); // 20000 20ms
17869570cc8Sopenharmony_ci        retry++;
17969570cc8Sopenharmony_ci    } while (ret == EAGAIN && retry < 10); // 10 max retry
18069570cc8Sopenharmony_ci
18169570cc8Sopenharmony_ci    // wait server thread run
18269570cc8Sopenharmony_ci    retry = 0;
18369570cc8Sopenharmony_ci    while (!running_ && (retry < 10)) { // 10 max retry
18469570cc8Sopenharmony_ci        usleep(20000); // 20000 20ms
18569570cc8Sopenharmony_ci        retry++;
18669570cc8Sopenharmony_ci    }
18769570cc8Sopenharmony_ci    APPSPAWN_LOGV("AppSpawnTestServer::Start retry %{public}u", retry);
18869570cc8Sopenharmony_ci}
18969570cc8Sopenharmony_ci
19069570cc8Sopenharmony_civoid AppSpawnTestServer::Stop()
19169570cc8Sopenharmony_ci{
19269570cc8Sopenharmony_ci    APPSPAWN_LOGV("AppSpawnTestServer::Stop serverId %{public}u", AppSpawnTestServer::serverId);
19369570cc8Sopenharmony_ci    if (threadId_ != 0) {
19469570cc8Sopenharmony_ci        stop_ = true;
19569570cc8Sopenharmony_ci        pthread_join(threadId_, nullptr);
19669570cc8Sopenharmony_ci        threadId_ = 0;
19769570cc8Sopenharmony_ci        APPSPAWN_LOGV("Stop");
19869570cc8Sopenharmony_ci    }
19969570cc8Sopenharmony_ci}
20069570cc8Sopenharmony_ci
20169570cc8Sopenharmony_civoid AppSpawnTestServer::KillNWebSpawnServer()
20269570cc8Sopenharmony_ci{
20369570cc8Sopenharmony_ci    APPSPAWN_LOGV("Kill nwebspawn %{public}d", serverId_);
20469570cc8Sopenharmony_ci    if (appPid_ > 0) {
20569570cc8Sopenharmony_ci        kill(appPid_, SIGKILL);
20669570cc8Sopenharmony_ci    }
20769570cc8Sopenharmony_ci}
20869570cc8Sopenharmony_ci
20969570cc8Sopenharmony_civoid AppSpawnTestServer::StopSpawnService(void)
21069570cc8Sopenharmony_ci{
21169570cc8Sopenharmony_ci    APPSPAWN_LOGV("StopSpawnService ");
21269570cc8Sopenharmony_ci    if (serverStoped) {
21369570cc8Sopenharmony_ci        CloseCheckHandler();
21469570cc8Sopenharmony_ci    }
21569570cc8Sopenharmony_ci    serverStoped = true;
21669570cc8Sopenharmony_ci    if (testServer_) {
21769570cc8Sopenharmony_ci        struct signalfd_siginfo siginfo = {};
21869570cc8Sopenharmony_ci        siginfo.ssi_signo = SIGTERM;
21969570cc8Sopenharmony_ci        siginfo.ssi_uid = 0;
22069570cc8Sopenharmony_ci        ProcessSignal(&siginfo);
22169570cc8Sopenharmony_ci    } else {
22269570cc8Sopenharmony_ci        localServer_->Stop();
22369570cc8Sopenharmony_ci    }
22469570cc8Sopenharmony_ci}
22569570cc8Sopenharmony_ci
22669570cc8Sopenharmony_ci#ifdef USER_TIMER_TO_CHECK
22769570cc8Sopenharmony_civoid AppSpawnTestServer::ProcessIdle(const TimerHandle taskHandle, void *context)
22869570cc8Sopenharmony_ci#else
22969570cc8Sopenharmony_civoid AppSpawnTestServer::ProcessIdle(const IdleHandle taskHandle, void *context)
23069570cc8Sopenharmony_ci#endif
23169570cc8Sopenharmony_ci{
23269570cc8Sopenharmony_ci    APPSPAWN_LOGV("AppSpawnTestServer::ProcessIdle");
23369570cc8Sopenharmony_ci    AppSpawnTestServer *server = reinterpret_cast<AppSpawnTestServer *>(const_cast<void *>(context));
23469570cc8Sopenharmony_ci    if (server->stop_) {
23569570cc8Sopenharmony_ci        server->StopSpawnService();
23669570cc8Sopenharmony_ci        return;
23769570cc8Sopenharmony_ci    }
23869570cc8Sopenharmony_ci
23969570cc8Sopenharmony_ci    struct timespec end;
24069570cc8Sopenharmony_ci    clock_gettime(CLOCK_MONOTONIC, &end);
24169570cc8Sopenharmony_ci    uint64_t diff = DiffTime(&server->startTime_, &end);
24269570cc8Sopenharmony_ci    if (diff >= (server->protectTime_ * 1000)) {  // 1000 ms -> us
24369570cc8Sopenharmony_ci        APPSPAWN_LOGV("AppSpawnTestServer:: timeout %{public}u %{public}" PRIu64 "", server->protectTime_, diff);
24469570cc8Sopenharmony_ci        server->StopSpawnService();
24569570cc8Sopenharmony_ci        return;
24669570cc8Sopenharmony_ci    }
24769570cc8Sopenharmony_ci}
24869570cc8Sopenharmony_ci
24969570cc8Sopenharmony_cistatic int HandleRecvMessage(const TaskHandle taskHandle, uint8_t * buffer, int bufferSize, int flags)
25069570cc8Sopenharmony_ci{
25169570cc8Sopenharmony_ci    int socketFd = LE_GetSocketFd(taskHandle);
25269570cc8Sopenharmony_ci    struct iovec iov = {
25369570cc8Sopenharmony_ci        .iov_base = buffer,
25469570cc8Sopenharmony_ci        .iov_len = bufferSize,
25569570cc8Sopenharmony_ci    };
25669570cc8Sopenharmony_ci    char ctrlBuffer[CMSG_SPACE(APP_MAX_FD_COUNT * sizeof(int))];
25769570cc8Sopenharmony_ci    struct msghdr msg = {
25869570cc8Sopenharmony_ci        .msg_iov = &iov,
25969570cc8Sopenharmony_ci        .msg_iovlen = 1,
26069570cc8Sopenharmony_ci        .msg_control = ctrlBuffer,
26169570cc8Sopenharmony_ci        .msg_controllen = sizeof(ctrlBuffer),
26269570cc8Sopenharmony_ci    };
26369570cc8Sopenharmony_ci
26469570cc8Sopenharmony_ci    AppSpawnConnection *connection = (AppSpawnConnection *) LE_GetUserData(taskHandle);
26569570cc8Sopenharmony_ci    errno = 0;
26669570cc8Sopenharmony_ci    int recvLen = recvmsg(socketFd, &msg, flags);
26769570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_LOG(errno == 0, "recvmsg with errno %d", errno);
26869570cc8Sopenharmony_ci    struct cmsghdr *cmsg = nullptr;
26969570cc8Sopenharmony_ci    for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != nullptr; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
27069570cc8Sopenharmony_ci        if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
27169570cc8Sopenharmony_ci            int fdCount = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
27269570cc8Sopenharmony_ci            int* fd = reinterpret_cast<int*>(CMSG_DATA(cmsg));
27369570cc8Sopenharmony_ci            APPSPAWN_CHECK(fdCount <= APP_MAX_FD_COUNT,
27469570cc8Sopenharmony_ci                return -1, "failed to recv fd %d %d", connection->receiverCtx.fdCount, fdCount);
27569570cc8Sopenharmony_ci            APPSPAWN_CHECK(memcpy_s(connection->receiverCtx.fds, fdCount * sizeof(int), fd,
27669570cc8Sopenharmony_ci                fdCount * sizeof(int)) == 0, return -1, "memcpy_s fd failed");
27769570cc8Sopenharmony_ci            connection->receiverCtx.fdCount = fdCount;
27869570cc8Sopenharmony_ci        }
27969570cc8Sopenharmony_ci    }
28069570cc8Sopenharmony_ci
28169570cc8Sopenharmony_ci    return recvLen;
28269570cc8Sopenharmony_ci}
28369570cc8Sopenharmony_ci
28469570cc8Sopenharmony_ciint LocalTestServer::OnConnection(const LoopHandle loopHandle, const TaskHandle server)
28569570cc8Sopenharmony_ci{
28669570cc8Sopenharmony_ci    static uint32_t connectionId = 0;
28769570cc8Sopenharmony_ci    TaskHandle stream;
28869570cc8Sopenharmony_ci    LE_StreamInfo info = {};
28969570cc8Sopenharmony_ci    info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_CONNECT;
29069570cc8Sopenharmony_ci    info.baseInfo.close = OnClose;
29169570cc8Sopenharmony_ci    info.baseInfo.userDataSize = sizeof(TestConnection);
29269570cc8Sopenharmony_ci    info.disConnectComplete = nullptr;
29369570cc8Sopenharmony_ci    info.sendMessageComplete = SendMessageComplete;
29469570cc8Sopenharmony_ci    info.recvMessage = OnReceiveRequest;
29569570cc8Sopenharmony_ci    info.handleRecvMsg = HandleRecvMessage;
29669570cc8Sopenharmony_ci
29769570cc8Sopenharmony_ci    ServerInfo *serverInfo = (ServerInfo *)LE_GetUserData(server);
29869570cc8Sopenharmony_ci    APPSPAWN_CHECK(serverInfo != nullptr, return -1, "Failed to alloc stream");
29969570cc8Sopenharmony_ci
30069570cc8Sopenharmony_ci    LE_STATUS ret = LE_AcceptStreamClient(loopHandle, server, &stream, &info);
30169570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed to alloc stream");
30269570cc8Sopenharmony_ci    TestConnection *connection = (TestConnection *)LE_GetUserData(stream);
30369570cc8Sopenharmony_ci    APPSPAWN_CHECK(connection != nullptr, return -1, "Failed to alloc stream");
30469570cc8Sopenharmony_ci    connection->connectionId = ++connectionId;
30569570cc8Sopenharmony_ci    connection->stream = stream;
30669570cc8Sopenharmony_ci    connection->msgRecvLen = 0;
30769570cc8Sopenharmony_ci    (void)memset_s(&connection->msg, sizeof(connection->msg), 0, sizeof(connection->msg));
30869570cc8Sopenharmony_ci    connection->buffer = nullptr;
30969570cc8Sopenharmony_ci    connection->recvMsgProcess = serverInfo->recvMsgProcess;
31069570cc8Sopenharmony_ci    APPSPAWN_LOGI("OnConnection connection.id %{public}d fd %{public}d ",
31169570cc8Sopenharmony_ci        connection->connectionId, LE_GetSocketFd(stream));
31269570cc8Sopenharmony_ci    return 0;
31369570cc8Sopenharmony_ci}
31469570cc8Sopenharmony_ci
31569570cc8Sopenharmony_civoid LocalTestServer::SendMessageComplete(const TaskHandle taskHandle, BufferHandle handle)
31669570cc8Sopenharmony_ci{
31769570cc8Sopenharmony_ci    return;
31869570cc8Sopenharmony_ci}
31969570cc8Sopenharmony_ci
32069570cc8Sopenharmony_civoid LocalTestServer::OnClose(const TaskHandle taskHandle)
32169570cc8Sopenharmony_ci{
32269570cc8Sopenharmony_ci    TestConnection *connection = (TestConnection *)LE_GetUserData(taskHandle);
32369570cc8Sopenharmony_ci    APPSPAWN_CHECK(connection != nullptr, return, "Invalid connection");
32469570cc8Sopenharmony_ci    APPSPAWN_LOGI("OnClose connection.id %{public}d socket %{public}d",
32569570cc8Sopenharmony_ci        connection->connectionId, LE_GetSocketFd(taskHandle));
32669570cc8Sopenharmony_ci
32769570cc8Sopenharmony_ci    AppSpawnConnection *spawnConnection = (AppSpawnConnection *) LE_GetUserData(taskHandle);
32869570cc8Sopenharmony_ci    if (spawnConnection != nullptr) {
32969570cc8Sopenharmony_ci        int fdCount = spawnConnection->receiverCtx.fdCount;
33069570cc8Sopenharmony_ci        for (int i = 0; i < fdCount; i++) {
33169570cc8Sopenharmony_ci            APPSPAWN_LOGI("OnClose close fd %d", spawnConnection->receiverCtx.fds[i]);
33269570cc8Sopenharmony_ci            if (spawnConnection->receiverCtx.fds[i] >= 0) {
33369570cc8Sopenharmony_ci                close(spawnConnection->receiverCtx.fds[i]);
33469570cc8Sopenharmony_ci            }
33569570cc8Sopenharmony_ci        }
33669570cc8Sopenharmony_ci    }
33769570cc8Sopenharmony_ci}
33869570cc8Sopenharmony_ci
33969570cc8Sopenharmony_civoid LocalTestServer::OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, uint32_t buffLen)
34069570cc8Sopenharmony_ci{
34169570cc8Sopenharmony_ci    TestConnection *connection = (TestConnection *)LE_GetUserData(taskHandle);
34269570cc8Sopenharmony_ci    APPSPAWN_CHECK(connection != nullptr, LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
34369570cc8Sopenharmony_ci        return, "Failed to get client form socket");
34469570cc8Sopenharmony_ci
34569570cc8Sopenharmony_ci    if (connection->recvMsgProcess) {
34669570cc8Sopenharmony_ci        connection->recvMsgProcess(connection, buffer, buffLen);
34769570cc8Sopenharmony_ci    }
34869570cc8Sopenharmony_ci}
34969570cc8Sopenharmony_ci
35069570cc8Sopenharmony_ciint LocalTestServer::Run(const char *socketName, RecvMsgProcess recvMsg)
35169570cc8Sopenharmony_ci{
35269570cc8Sopenharmony_ci    char path[128] = {0};  // 128 max path
35369570cc8Sopenharmony_ci    int ret = snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s%s", APPSPAWN_SOCKET_DIR, socketName);
35469570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret >= 0, return -1, "Failed to snprintf_s %{public}d", ret);
35569570cc8Sopenharmony_ci    LE_StreamServerInfo info = {};
35669570cc8Sopenharmony_ci    info.baseInfo.flags = TASK_STREAM | TASK_PIPE | TASK_SERVER;
35769570cc8Sopenharmony_ci    info.baseInfo.userDataSize = sizeof(ServerInfo);
35869570cc8Sopenharmony_ci    info.socketId = -1;
35969570cc8Sopenharmony_ci    info.server = path;
36069570cc8Sopenharmony_ci    info.baseInfo.close = nullptr;
36169570cc8Sopenharmony_ci    info.incommingConnect = OnConnection;
36269570cc8Sopenharmony_ci
36369570cc8Sopenharmony_ci    MakeDirRec(path, 0711, 0);  // 0711 default mask
36469570cc8Sopenharmony_ci    ret = LE_CreateStreamServer(LE_GetDefaultLoop(), &serverHandle_, &info);
36569570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed to create socket for %{public}s errno: %{public}d", path, errno);
36669570cc8Sopenharmony_ci    APPSPAWN_LOGI("LocalTestServer path %{public}s fd %{public}d", path, LE_GetSocketFd(serverHandle_));
36769570cc8Sopenharmony_ci
36869570cc8Sopenharmony_ci    ServerInfo *serverInfo = (ServerInfo *)LE_GetUserData(serverHandle_);
36969570cc8Sopenharmony_ci    APPSPAWN_CHECK(serverInfo != nullptr, return -1, "Failed to alloc stream");
37069570cc8Sopenharmony_ci    serverInfo->local = this;
37169570cc8Sopenharmony_ci    serverInfo->recvMsgProcess = recvMsg;
37269570cc8Sopenharmony_ci    LE_RunLoop(LE_GetDefaultLoop());
37369570cc8Sopenharmony_ci    LE_CloseStreamTask(LE_GetDefaultLoop(), serverHandle_);
37469570cc8Sopenharmony_ci    LE_StopLoop(LE_GetDefaultLoop());
37569570cc8Sopenharmony_ci    LE_CloseLoop(LE_GetDefaultLoop());
37669570cc8Sopenharmony_ci    APPSPAWN_LOGI("LocalTestServer exit");
37769570cc8Sopenharmony_ci    return 0;
37869570cc8Sopenharmony_ci}
37969570cc8Sopenharmony_ci
38069570cc8Sopenharmony_civoid LocalTestServer::Stop()
38169570cc8Sopenharmony_ci{
38269570cc8Sopenharmony_ci    APPSPAWN_LOGI("Stop LocalTestServer ");
38369570cc8Sopenharmony_ci    LE_StopLoop(LE_GetDefaultLoop());
38469570cc8Sopenharmony_ci}
38569570cc8Sopenharmony_ci
38669570cc8Sopenharmony_ciint TestConnection::SendResponse(const AppSpawnMsg *msg, int result, pid_t pid)
38769570cc8Sopenharmony_ci{
38869570cc8Sopenharmony_ci    APPSPAWN_LOGV("SendResponse result: %{public}d pid: %{public}d", result, pid);
38969570cc8Sopenharmony_ci    uint32_t bufferSize = sizeof(AppSpawnResponseMsg);
39069570cc8Sopenharmony_ci    BufferHandle handle = LE_CreateBuffer(LE_GetDefaultLoop(), bufferSize);
39169570cc8Sopenharmony_ci    AppSpawnResponseMsg *buffer = (AppSpawnResponseMsg *)LE_GetBufferInfo(handle, nullptr, &bufferSize);
39269570cc8Sopenharmony_ci    int ret = memcpy_s(buffer, bufferSize, msg, sizeof(AppSpawnMsg));
39369570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed to memcpy_s bufferSize");
39469570cc8Sopenharmony_ci    buffer->result.result = result;
39569570cc8Sopenharmony_ci    buffer->result.pid = pid;
39669570cc8Sopenharmony_ci    return LE_Send(LE_GetDefaultLoop(), stream, handle, bufferSize);
39769570cc8Sopenharmony_ci}
39869570cc8Sopenharmony_ci
39969570cc8Sopenharmony_ciuint32_t AppSpawnTestHelper::GenRandom(void)
40069570cc8Sopenharmony_ci{
40169570cc8Sopenharmony_ci    uint32_t random = 0;
40269570cc8Sopenharmony_ci    int fd = open("/dev/random", O_RDONLY);
40369570cc8Sopenharmony_ci    if (fd >= 0) {
40469570cc8Sopenharmony_ci        read(fd, &random, sizeof(random));
40569570cc8Sopenharmony_ci        close(fd);
40669570cc8Sopenharmony_ci    }
40769570cc8Sopenharmony_ci    return random;
40869570cc8Sopenharmony_ci}
40969570cc8Sopenharmony_ci
41069570cc8Sopenharmony_ciCmdArgs *AppSpawnTestHelper::ToCmdList(const char *cmd)
41169570cc8Sopenharmony_ci{
41269570cc8Sopenharmony_ci    const uint32_t maxArgc = 20;
41369570cc8Sopenharmony_ci    const uint32_t length = sizeof(CmdArgs) + maxArgc * sizeof(char *) + strlen(cmd) + APP_LEN_PROC_NAME + 1 + 2;
41469570cc8Sopenharmony_ci    char *buffer = static_cast<char *>(malloc(length));
41569570cc8Sopenharmony_ci    CmdArgs *args = reinterpret_cast<CmdArgs *>(buffer);
41669570cc8Sopenharmony_ci    APPSPAWN_CHECK(buffer != nullptr, return nullptr, "Failed to alloc args");
41769570cc8Sopenharmony_ci    (void)memset_s(args, length, 0, length);
41869570cc8Sopenharmony_ci    char *start = buffer + sizeof(CmdArgs) + maxArgc * sizeof(char *);
41969570cc8Sopenharmony_ci    char *end = buffer + length;
42069570cc8Sopenharmony_ci    uint32_t index = 0;
42169570cc8Sopenharmony_ci    char *curr = const_cast<char *>(cmd);
42269570cc8Sopenharmony_ci    while (isspace(*curr)) {
42369570cc8Sopenharmony_ci        curr++;
42469570cc8Sopenharmony_ci    }
42569570cc8Sopenharmony_ci
42669570cc8Sopenharmony_ci    while (index < (maxArgc - 1) && *curr != '\0') {
42769570cc8Sopenharmony_ci        if (args->argv[index] == nullptr) {
42869570cc8Sopenharmony_ci            args->argv[index] = start;
42969570cc8Sopenharmony_ci        }
43069570cc8Sopenharmony_ci        *start = *curr;
43169570cc8Sopenharmony_ci        if (isspace(*curr)) {
43269570cc8Sopenharmony_ci            *start = '\0';
43369570cc8Sopenharmony_ci            // 为SetProcessName 预留空间
43469570cc8Sopenharmony_ci            start = (index == 0) ? start + APP_LEN_PROC_NAME : start + 1;
43569570cc8Sopenharmony_ci            while (isspace(*curr) && *curr != '\0') {
43669570cc8Sopenharmony_ci                curr++;
43769570cc8Sopenharmony_ci            }
43869570cc8Sopenharmony_ci            if (*curr != '\0') {
43969570cc8Sopenharmony_ci                index++;
44069570cc8Sopenharmony_ci            }
44169570cc8Sopenharmony_ci        } else {
44269570cc8Sopenharmony_ci            start++;
44369570cc8Sopenharmony_ci            curr++;
44469570cc8Sopenharmony_ci        }
44569570cc8Sopenharmony_ci    }
44669570cc8Sopenharmony_ci
44769570cc8Sopenharmony_ci    index++;
44869570cc8Sopenharmony_ci    args->argv[index] = end - 2;  // 2 last
44969570cc8Sopenharmony_ci    args->argv[index][0] = '#';
45069570cc8Sopenharmony_ci    args->argv[index][1] = '\0';
45169570cc8Sopenharmony_ci    args->argc = index + 1;
45269570cc8Sopenharmony_ci    return args;
45369570cc8Sopenharmony_ci}
45469570cc8Sopenharmony_ci
45569570cc8Sopenharmony_ciint AppSpawnTestHelper::AddDacInfo(AppSpawnReqMsgHandle &reqHandle)
45669570cc8Sopenharmony_ci{
45769570cc8Sopenharmony_ci    AppDacInfo dacInfo = {};
45869570cc8Sopenharmony_ci    dacInfo.uid = defaultTestUid_;
45969570cc8Sopenharmony_ci    dacInfo.gid = defaultTestGid_;
46069570cc8Sopenharmony_ci    dacInfo.gidCount = 2;  // 2 count
46169570cc8Sopenharmony_ci    dacInfo.gidTable[0] = defaultTestGidGroup_;
46269570cc8Sopenharmony_ci    dacInfo.gidTable[1] = defaultTestGidGroup_ + 1;
46369570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(strcpy_s(dacInfo.userName, sizeof(dacInfo.userName), "test-app-name") == 0,
46469570cc8Sopenharmony_ci        return APPSPAWN_ARG_INVALID);
46569570cc8Sopenharmony_ci    return AppSpawnReqMsgSetAppDacInfo(reqHandle, &dacInfo);
46669570cc8Sopenharmony_ci}
46769570cc8Sopenharmony_ci
46869570cc8Sopenharmony_ciint AppSpawnTestHelper::AddFdInfo(AppSpawnReqMsgHandle &reqHandle)
46969570cc8Sopenharmony_ci{
47069570cc8Sopenharmony_ci    if (fdArg < 0) {
47169570cc8Sopenharmony_ci        fdArg = open("/dev/random", O_RDONLY);
47269570cc8Sopenharmony_ci    }
47369570cc8Sopenharmony_ci    APPSPAWN_LOGE("Add fd info %d", fdArg);
47469570cc8Sopenharmony_ci    APPSPAWN_CHECK(fdArg >= 0, return -1, "open fd failed ");
47569570cc8Sopenharmony_ci    return AppSpawnReqMsgAddFd(reqHandle, "fdname", fdArg);
47669570cc8Sopenharmony_ci}
47769570cc8Sopenharmony_ci
47869570cc8Sopenharmony_ciAppSpawnReqMsgHandle AppSpawnTestHelper::CreateMsg(AppSpawnClientHandle handle, uint32_t msgType, int base)
47969570cc8Sopenharmony_ci{
48069570cc8Sopenharmony_ci    AppSpawnReqMsgHandle reqHandle = 0;
48169570cc8Sopenharmony_ci    int ret = AppSpawnReqMsgCreate(static_cast<AppSpawnMsgType>(msgType), processName_.c_str(), &reqHandle);
48269570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return INVALID_REQ_HANDLE, "Failed to create req %{public}s", processName_.c_str());
48369570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(msgType == MSG_APP_SPAWN || msgType == MSG_SPAWN_NATIVE_PROCESS, return reqHandle);
48469570cc8Sopenharmony_ci    do {
48569570cc8Sopenharmony_ci        ret = AddFdInfo(reqHandle);
48669570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, break, "Failed to add fd %{public}s", processName_.c_str());
48769570cc8Sopenharmony_ci        ret = AppSpawnReqMsgSetBundleInfo(reqHandle, 100, processName_.c_str());  // 100 test index
48869570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, break, "Failed to add bundle info req %{public}s", processName_.c_str());
48969570cc8Sopenharmony_ci        ret = AddDacInfo(reqHandle);
49069570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, break, "Failed to add dac %{public}s", processName_.c_str());
49169570cc8Sopenharmony_ci        ret = AppSpawnReqMsgSetAppAccessToken(reqHandle, 12345678);  // 12345678
49269570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, break, "Failed to add access token %{public}s", processName_.c_str());
49369570cc8Sopenharmony_ci
49469570cc8Sopenharmony_ci        if (defaultMsgFlags_ != 0) {
49569570cc8Sopenharmony_ci            (void)AppSpawnReqMsgSetFlags(reqHandle, TLV_MSG_FLAGS, defaultMsgFlags_);
49669570cc8Sopenharmony_ci        }
49769570cc8Sopenharmony_ci        if (base) {
49869570cc8Sopenharmony_ci            return reqHandle;
49969570cc8Sopenharmony_ci        }
50069570cc8Sopenharmony_ci        const char *testData = "ssssssssssssss sssssssss ssssssss";
50169570cc8Sopenharmony_ci        ret = AppSpawnReqMsgAddExtInfo(reqHandle, "tlv-name-1",
50269570cc8Sopenharmony_ci            reinterpret_cast<uint8_t *>(const_cast<char *>(testData)), strlen(testData));
50369570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, break, "Failed to ext tlv %{public}s", processName_.c_str());
50469570cc8Sopenharmony_ci        size_t count = permissions_.size();
50569570cc8Sopenharmony_ci        for (size_t i = 0; i < count; i++) {
50669570cc8Sopenharmony_ci            ret = AppSpawnReqMsgAddPermission(reqHandle, permissions_[i]);
50769570cc8Sopenharmony_ci            APPSPAWN_CHECK(ret == 0, break, "Failed to permission %{public}s", permissions_[i]);
50869570cc8Sopenharmony_ci        }
50969570cc8Sopenharmony_ci
51069570cc8Sopenharmony_ci        ret = AppSpawnReqMsgSetAppInternetPermissionInfo(reqHandle, 1, 0);
51169570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, break, "Failed to internet info %{public}s", processName_.c_str());
51269570cc8Sopenharmony_ci
51369570cc8Sopenharmony_ci        ret = AppSpawnReqMsgSetAppOwnerId(reqHandle, "ohos.permission.FILE_ACCESS_MANAGER");
51469570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, break, "Failed to ownerid %{public}s", processName_.c_str());
51569570cc8Sopenharmony_ci        const char *renderCmd = "/system/bin/sh ls -l ";
51669570cc8Sopenharmony_ci        ret = AppSpawnReqMsgAddExtInfo(reqHandle, MSG_EXT_NAME_RENDER_CMD,
51769570cc8Sopenharmony_ci            reinterpret_cast<const uint8_t *>(renderCmd), strlen(renderCmd));
51869570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, break, "Failed to render cmd %{public}s", processName_.c_str());
51969570cc8Sopenharmony_ci        ret = AppSpawnReqMsgSetAppDomainInfo(reqHandle, 1, defaultApl_.c_str());
52069570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, break, "Failed to domain info %{public}s", processName_.c_str());
52169570cc8Sopenharmony_ci        return reqHandle;
52269570cc8Sopenharmony_ci    } while (0);
52369570cc8Sopenharmony_ci    AppSpawnReqMsgFree(reqHandle);
52469570cc8Sopenharmony_ci    return INVALID_REQ_HANDLE;
52569570cc8Sopenharmony_ci}
52669570cc8Sopenharmony_ci
52769570cc8Sopenharmony_ciAppSpawnMsgNode *AppSpawnTestHelper::CreateAppSpawnMsg(AppSpawnMsg *msg)
52869570cc8Sopenharmony_ci{
52969570cc8Sopenharmony_ci    AppSpawnMsgNode *msgNode = static_cast<AppSpawnMsgNode *>(calloc(1, sizeof(AppSpawnMsgNode)));
53069570cc8Sopenharmony_ci    APPSPAWN_CHECK(msgNode != nullptr, return nullptr, "Failed to create receiver");
53169570cc8Sopenharmony_ci    int ret = memcpy_s(&msgNode->msgHeader, sizeof(msgNode->msgHeader), msg, sizeof(msgNode->msgHeader));
53269570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, free(msgNode);
53369570cc8Sopenharmony_ci        return nullptr, "Failed to memcpy msg");
53469570cc8Sopenharmony_ci    msgNode->buffer = static_cast<uint8_t *>(malloc(msg->msgLen));
53569570cc8Sopenharmony_ci    APPSPAWN_CHECK(msgNode->buffer != nullptr, free(msgNode);
53669570cc8Sopenharmony_ci        return nullptr, "Failed to memcpy msg");
53769570cc8Sopenharmony_ci    uint32_t totalCount = msg->tlvCount + TLV_MAX;
53869570cc8Sopenharmony_ci    msgNode->tlvOffset = static_cast<uint32_t *>(malloc(totalCount * sizeof(uint32_t)));
53969570cc8Sopenharmony_ci    APPSPAWN_CHECK(msgNode->tlvOffset != nullptr, free(msgNode);
54069570cc8Sopenharmony_ci        return nullptr, "Failed to alloc memory for recv message");
54169570cc8Sopenharmony_ci    for (uint32_t i = 0; i < totalCount; i++) {
54269570cc8Sopenharmony_ci        msgNode->tlvOffset[i] = INVALID_OFFSET;
54369570cc8Sopenharmony_ci    }
54469570cc8Sopenharmony_ci    return msgNode;
54569570cc8Sopenharmony_ci}
54669570cc8Sopenharmony_ci
54769570cc8Sopenharmony_ciAppSpawningCtx *AppSpawnTestHelper::GetAppProperty(AppSpawnClientHandle handle, AppSpawnReqMsgHandle reqHandle)
54869570cc8Sopenharmony_ci{
54969570cc8Sopenharmony_ci    AppSpawnReqMsgNode *reqNode = static_cast<AppSpawnReqMsgNode *>(reqHandle);
55069570cc8Sopenharmony_ci    APPSPAWN_CHECK(reqNode != nullptr && reqNode->msg != nullptr, AppSpawnReqMsgFree(reqHandle);
55169570cc8Sopenharmony_ci        return nullptr, "Invalid reqNode");
55269570cc8Sopenharmony_ci
55369570cc8Sopenharmony_ci    AppSpawnMsgNode *msgNode = CreateAppSpawnMsg(reqNode->msg);
55469570cc8Sopenharmony_ci    APPSPAWN_CHECK(msgNode != nullptr, return nullptr, "Failed to alloc for msg");
55569570cc8Sopenharmony_ci
55669570cc8Sopenharmony_ci    uint32_t bufferSize = reqNode->msg->msgLen;
55769570cc8Sopenharmony_ci    uint32_t currIndex = 0;
55869570cc8Sopenharmony_ci    uint32_t bufferStart = sizeof(AppSpawnMsg);
55969570cc8Sopenharmony_ci    ListNode *node = reqNode->msgBlocks.next;
56069570cc8Sopenharmony_ci    while (node != &reqNode->msgBlocks) {
56169570cc8Sopenharmony_ci        AppSpawnMsgBlock *block = ListEntry(node, AppSpawnMsgBlock, node);
56269570cc8Sopenharmony_ci        int ret = memcpy_s(msgNode->buffer + currIndex, bufferSize - currIndex,
56369570cc8Sopenharmony_ci            block->buffer + bufferStart, block->currentIndex - bufferStart);
56469570cc8Sopenharmony_ci        if (ret != 0) {
56569570cc8Sopenharmony_ci            AppSpawnReqMsgFree(reqHandle);
56669570cc8Sopenharmony_ci            DeleteAppSpawnMsg(msgNode);
56769570cc8Sopenharmony_ci            return nullptr;
56869570cc8Sopenharmony_ci        }
56969570cc8Sopenharmony_ci        currIndex += block->currentIndex - bufferStart;
57069570cc8Sopenharmony_ci        bufferStart = 0;
57169570cc8Sopenharmony_ci        node = node->next;
57269570cc8Sopenharmony_ci    }
57369570cc8Sopenharmony_ci    APPSPAWN_LOGV("GetAppProperty header magic 0x%{public}x type %{public}u id %{public}u len %{public}u %{public}s",
57469570cc8Sopenharmony_ci        msgNode->msgHeader.magic, msgNode->msgHeader.msgType,
57569570cc8Sopenharmony_ci        msgNode->msgHeader.msgId, msgNode->msgHeader.msgLen, msgNode->msgHeader.processName);
57669570cc8Sopenharmony_ci
57769570cc8Sopenharmony_ci    // delete reqHandle
57869570cc8Sopenharmony_ci    AppSpawnReqMsgFree(reqHandle);
57969570cc8Sopenharmony_ci    int ret = DecodeAppSpawnMsg(msgNode);
58069570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, DeleteAppSpawnMsg(msgNode);
58169570cc8Sopenharmony_ci        return nullptr, "Decode msg fail");
58269570cc8Sopenharmony_ci    AppSpawningCtx *property = CreateAppSpawningCtx();
58369570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(property != nullptr, DeleteAppSpawnMsg(msgNode);
58469570cc8Sopenharmony_ci        return nullptr);
58569570cc8Sopenharmony_ci    property->message = msgNode;
58669570cc8Sopenharmony_ci    SetDefaultTestData();
58769570cc8Sopenharmony_ci    return property;
58869570cc8Sopenharmony_ci}
58969570cc8Sopenharmony_ci
59069570cc8Sopenharmony_civoid AppSpawnTestHelper::SetDefaultTestData()
59169570cc8Sopenharmony_ci{
59269570cc8Sopenharmony_ci    processName_ = std::string("com.example.myapplication");
59369570cc8Sopenharmony_ci    defaultTestUid_ = 20010029;       // 20010029 test
59469570cc8Sopenharmony_ci    defaultTestGid_ = 20010029;       // 20010029 test
59569570cc8Sopenharmony_ci    defaultTestGidGroup_ = 20010029;  // 20010029 test
59669570cc8Sopenharmony_ci    defaultTestBundleIndex_ = 100;    // 100 test
59769570cc8Sopenharmony_ci    defaultApl_ = std::string("system_core");
59869570cc8Sopenharmony_ci    defaultMsgFlags_ = 0;
59969570cc8Sopenharmony_ci}
60069570cc8Sopenharmony_ci
60169570cc8Sopenharmony_ciint AppSpawnTestHelper::CreateSocket(int type)
60269570cc8Sopenharmony_ci{
60369570cc8Sopenharmony_ci    const uint32_t maxCount = 10;
60469570cc8Sopenharmony_ci    uint32_t count = 0;
60569570cc8Sopenharmony_ci    int socketId = -1;
60669570cc8Sopenharmony_ci    while ((socketId < 0) && (count < maxCount)) {
60769570cc8Sopenharmony_ci        usleep(20000);                        // 20000 20ms
60869570cc8Sopenharmony_ci        socketId = CreateClientSocket(type, 2);  // 2s
60969570cc8Sopenharmony_ci        if (socketId > 0) {
61069570cc8Sopenharmony_ci            return socketId;
61169570cc8Sopenharmony_ci        }
61269570cc8Sopenharmony_ci        count++;
61369570cc8Sopenharmony_ci    }
61469570cc8Sopenharmony_ci    return socketId;
61569570cc8Sopenharmony_ci}
61669570cc8Sopenharmony_ci
61769570cc8Sopenharmony_ciint AppSpawnTestHelper::CreateSendMsg(std::vector<uint8_t> &buffer, uint32_t msgType, uint32_t &msgLen,
61869570cc8Sopenharmony_ci    const std::vector<AddTlvFunction> &addTlvFuncs)
61969570cc8Sopenharmony_ci{
62069570cc8Sopenharmony_ci    if (buffer.size() < sizeof(AppSpawnMsg)) {
62169570cc8Sopenharmony_ci        return -1;
62269570cc8Sopenharmony_ci    }
62369570cc8Sopenharmony_ci    AppSpawnMsg *msg = reinterpret_cast<AppSpawnMsg *>(buffer.data());
62469570cc8Sopenharmony_ci    msg->magic = APPSPAWN_MSG_MAGIC;
62569570cc8Sopenharmony_ci    msg->msgType = msgType;
62669570cc8Sopenharmony_ci    msg->msgLen = sizeof(AppSpawnMsg);
62769570cc8Sopenharmony_ci    msg->msgId = 1;
62869570cc8Sopenharmony_ci    msg->tlvCount = 0;
62969570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(strcpy_s(msg->processName, sizeof(msg->processName), processName_.c_str()) == 0,
63069570cc8Sopenharmony_ci        return -1);
63169570cc8Sopenharmony_ci    // add tlv
63269570cc8Sopenharmony_ci    uint32_t currLen = sizeof(AppSpawnMsg);
63369570cc8Sopenharmony_ci    for (auto addTlvFunc : addTlvFuncs) {
63469570cc8Sopenharmony_ci        uint32_t realLen = 0;
63569570cc8Sopenharmony_ci        uint32_t tlvCount = 0;
63669570cc8Sopenharmony_ci        int ret = addTlvFunc(buffer.data() + currLen, buffer.size() - currLen, realLen, tlvCount);
63769570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0 && (currLen + realLen) < buffer.size(),
63869570cc8Sopenharmony_ci            return -1, "Failed add tlv to msg %{public}s", processName_.c_str());
63969570cc8Sopenharmony_ci        msg->msgLen += realLen;
64069570cc8Sopenharmony_ci        currLen += realLen;
64169570cc8Sopenharmony_ci        msg->tlvCount += tlvCount;
64269570cc8Sopenharmony_ci    }
64369570cc8Sopenharmony_ci    msgLen = msg->msgLen;
64469570cc8Sopenharmony_ci    APPSPAWN_LOGV("CreateSendMsg msgLen %{public}d", msgLen);
64569570cc8Sopenharmony_ci    return 0;
64669570cc8Sopenharmony_ci}
64769570cc8Sopenharmony_ci
64869570cc8Sopenharmony_cistatic int inline AddOneTlv(uint8_t *buffer, uint32_t bufferLen, const AppSpawnTlv &tlv, const uint8_t *data)
64969570cc8Sopenharmony_ci{
65069570cc8Sopenharmony_ci    if (tlv.tlvLen > bufferLen) {
65169570cc8Sopenharmony_ci        return -1;
65269570cc8Sopenharmony_ci    }
65369570cc8Sopenharmony_ci    int ret = memcpy_s(buffer, bufferLen, &tlv, sizeof(tlv));
65469570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed to memcpy_s bufferSize");
65569570cc8Sopenharmony_ci    ret = memcpy_s(buffer + sizeof(tlv), bufferLen - sizeof(tlv), data, tlv.tlvLen - sizeof(tlv));
65669570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed to memcpy_s bufferSize");
65769570cc8Sopenharmony_ci    return 0;
65869570cc8Sopenharmony_ci}
65969570cc8Sopenharmony_ci
66069570cc8Sopenharmony_ci#define ADD_TLV(type, value, currLen, tlvCount)  \
66169570cc8Sopenharmony_cido {    \
66269570cc8Sopenharmony_ci    AppSpawnTlv d_tlv = {}; \
66369570cc8Sopenharmony_ci    d_tlv.tlvType = (type);    \
66469570cc8Sopenharmony_ci    d_tlv.tlvLen = sizeof(AppSpawnTlv) + sizeof(value);   \
66569570cc8Sopenharmony_ci    ret = AddOneTlv(buffer + (currLen), bufferLen - (currLen), d_tlv, (uint8_t *)&(value));   \
66669570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed add tlv %{public}u", d_tlv.tlvType);  \
66769570cc8Sopenharmony_ci    (currLen) += d_tlv.tlvLen;    \
66869570cc8Sopenharmony_ci    (tlvCount)++;   \
66969570cc8Sopenharmony_ci} while (0)
67069570cc8Sopenharmony_ci
67169570cc8Sopenharmony_ciint AppSpawnTestHelper::AddBaseTlv(uint8_t *buffer, uint32_t bufferLen, uint32_t &realLen, uint32_t &tlvCount)
67269570cc8Sopenharmony_ci{
67369570cc8Sopenharmony_ci    // add app flage
67469570cc8Sopenharmony_ci    uint32_t currLen = 0;
67569570cc8Sopenharmony_ci    uint32_t flags[2] = {1, 0b1010};
67669570cc8Sopenharmony_ci    AppSpawnTlv tlv = {};
67769570cc8Sopenharmony_ci    tlv.tlvType = TLV_MSG_FLAGS;
67869570cc8Sopenharmony_ci    tlv.tlvLen = sizeof(AppSpawnTlv) + sizeof(flags);
67969570cc8Sopenharmony_ci    int ret = AddOneTlv(buffer + currLen, bufferLen - currLen, tlv, (uint8_t *)flags);
68069570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed add tlv %{public}u", tlv.tlvType);
68169570cc8Sopenharmony_ci    currLen += tlv.tlvLen;
68269570cc8Sopenharmony_ci    tlvCount++;
68369570cc8Sopenharmony_ci
68469570cc8Sopenharmony_ci    tlv.tlvType = TLV_PERMISSION;
68569570cc8Sopenharmony_ci    tlv.tlvLen = sizeof(AppSpawnTlv) + sizeof(flags);
68669570cc8Sopenharmony_ci    ret = AddOneTlv(buffer + currLen, bufferLen - currLen, tlv, (uint8_t *)flags);
68769570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return -1, "Failed add tlv %{public}u", tlv.tlvType);
68869570cc8Sopenharmony_ci    currLen += tlv.tlvLen;
68969570cc8Sopenharmony_ci    tlvCount++;
69069570cc8Sopenharmony_ci
69169570cc8Sopenharmony_ci    AppDomainInfo domainInfo = {0, "normal"};
69269570cc8Sopenharmony_ci    ADD_TLV(TLV_DOMAIN_INFO, domainInfo, currLen, tlvCount);
69369570cc8Sopenharmony_ci
69469570cc8Sopenharmony_ci    AppSpawnMsgAccessToken token = {12345678};  // 12345678
69569570cc8Sopenharmony_ci    ADD_TLV(TLV_ACCESS_TOKEN_INFO, token, currLen, tlvCount);
69669570cc8Sopenharmony_ci
69769570cc8Sopenharmony_ci    AppSpawnMsgInternetInfo internetInfo = {0, 1};
69869570cc8Sopenharmony_ci    ADD_TLV(TLV_INTERNET_INFO, internetInfo, currLen, tlvCount);
69969570cc8Sopenharmony_ci
70069570cc8Sopenharmony_ci    // add bundle info
70169570cc8Sopenharmony_ci    AppBundleInfo info = {};
70269570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(strcpy_s(info.bundleName, sizeof(info.bundleName), "test-bundleName") == 0,
70369570cc8Sopenharmony_ci        return -1);
70469570cc8Sopenharmony_ci    info.bundleIndex = 100;  // 100 test index
70569570cc8Sopenharmony_ci    ADD_TLV(TLV_BUNDLE_INFO, info, currLen, tlvCount);
70669570cc8Sopenharmony_ci
70769570cc8Sopenharmony_ci    // add dac
70869570cc8Sopenharmony_ci    AppDacInfo  dacInfo = {};
70969570cc8Sopenharmony_ci    dacInfo.uid = 20010029; // 20010029 test uid
71069570cc8Sopenharmony_ci    dacInfo.gid = 20010029; // 20010029 test gid
71169570cc8Sopenharmony_ci    dacInfo.gidCount = 2; // 2 count
71269570cc8Sopenharmony_ci    dacInfo.gidTable[0] = 20010029; // 20010029 test gid
71369570cc8Sopenharmony_ci    dacInfo.gidTable[1] = 20010030; // 20010030 test gid
71469570cc8Sopenharmony_ci    ADD_TLV(TLV_DAC_INFO, dacInfo, currLen, tlvCount);
71569570cc8Sopenharmony_ci    realLen = currLen;
71669570cc8Sopenharmony_ci    return 0;
71769570cc8Sopenharmony_ci}
71869570cc8Sopenharmony_ci
71969570cc8Sopenharmony_ciAppSpawnContent *AppSpawnTestHelper::StartSpawnServer(std::string &cmd, CmdArgs *&args)
72069570cc8Sopenharmony_ci{
72169570cc8Sopenharmony_ci    args = AppSpawnTestHelper::ToCmdList(cmd.c_str());
72269570cc8Sopenharmony_ci    APPSPAWN_CHECK(args != nullptr, return nullptr, "Failed to alloc args");
72369570cc8Sopenharmony_ci
72469570cc8Sopenharmony_ci    AppSpawnStartArg startRrg = {};
72569570cc8Sopenharmony_ci    startRrg.mode = MODE_FOR_APP_SPAWN;
72669570cc8Sopenharmony_ci    startRrg.socketName = APPSPAWN_SOCKET_NAME;
72769570cc8Sopenharmony_ci    startRrg.serviceName = APPSPAWN_SERVER_NAME;
72869570cc8Sopenharmony_ci    startRrg.moduleType = MODULE_APPSPAWN;
72969570cc8Sopenharmony_ci    startRrg.initArg = 1;
73069570cc8Sopenharmony_ci    if (args->argc <= MODE_VALUE_INDEX) {  // appspawn start
73169570cc8Sopenharmony_ci        startRrg.mode = MODE_FOR_APP_SPAWN;
73269570cc8Sopenharmony_ci    } else if (strcmp(args->argv[MODE_VALUE_INDEX], "app_cold") == 0) {  // cold start
73369570cc8Sopenharmony_ci        APPSPAWN_CHECK(args->argc >= ARG_NULL, free(args);
73469570cc8Sopenharmony_ci            return nullptr, "Invalid arg for cold start %{public}d", args->argc);
73569570cc8Sopenharmony_ci        startRrg.mode = MODE_FOR_APP_COLD_RUN;
73669570cc8Sopenharmony_ci        startRrg.initArg = 0;
73769570cc8Sopenharmony_ci    } else if (strcmp(args->argv[MODE_VALUE_INDEX], "nweb_cold") == 0) {  // cold start
73869570cc8Sopenharmony_ci        APPSPAWN_CHECK(args->argc >= ARG_NULL, free(args);
73969570cc8Sopenharmony_ci            return nullptr, "Invalid arg for cold start %{public}d", args->argc);
74069570cc8Sopenharmony_ci        startRrg.mode = MODE_FOR_NWEB_COLD_RUN;
74169570cc8Sopenharmony_ci        startRrg.serviceName = NWEBSPAWN_SERVER_NAME;
74269570cc8Sopenharmony_ci        startRrg.initArg = 0;
74369570cc8Sopenharmony_ci    } else if (strcmp(args->argv[MODE_VALUE_INDEX], NWEBSPAWN_SERVER_NAME) == 0) {  // nweb spawn start
74469570cc8Sopenharmony_ci        startRrg.mode = MODE_FOR_NWEB_SPAWN;
74569570cc8Sopenharmony_ci        startRrg.moduleType = MODULE_NWEBSPAWN;
74669570cc8Sopenharmony_ci        startRrg.socketName = NWEBSPAWN_SOCKET_NAME;
74769570cc8Sopenharmony_ci        startRrg.serviceName = NWEBSPAWN_SERVER_NAME;
74869570cc8Sopenharmony_ci    }
74969570cc8Sopenharmony_ci    APPSPAWN_LOGV("Start service %{public}s", startRrg.serviceName);
75069570cc8Sopenharmony_ci    AppSpawnContent *content = StartSpawnService(&startRrg, APP_LEN_PROC_NAME, args->argc, args->argv);
75169570cc8Sopenharmony_ci    if (content == nullptr) {
75269570cc8Sopenharmony_ci        free(args);
75369570cc8Sopenharmony_ci    }
75469570cc8Sopenharmony_ci    return content;
75569570cc8Sopenharmony_ci}
75669570cc8Sopenharmony_ci}  // namespace OHOS
75769570cc8Sopenharmony_ci
75869570cc8Sopenharmony_ciMODULE_CONSTRUCTOR(void)
75969570cc8Sopenharmony_ci{
76069570cc8Sopenharmony_ci    MakeDirRec(APPSPAWN_MSG_DIR "appspawn", 0771, 1);
76169570cc8Sopenharmony_ci    MakeDirRec(APPSPAWN_MSG_DIR "nwebspawn", 0771, 1);
76269570cc8Sopenharmony_ci}
763