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