• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "appspawn_client.h"
17 
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <pthread.h>
21 #include <string.h>
22 #include <unistd.h>
23 
24 #include <linux/in.h>
25 #include <linux/socket.h>
26 #include <linux/tcp.h>
27 #include <sys/socket.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <sys/un.h>
31 
32 #include "appspawn_mount_permission.h"
33 #include "appspawn_hook.h"
34 #include "appspawn_utils.h"
35 #include "parameter.h"
36 #include "securec.h"
37 
38 #define USER_LOCK_STATUS_SIZE 8
39 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
40 static AppSpawnReqMsgMgr *g_clientInstance[CLIENT_MAX] = {NULL};
41 static pthread_mutex_t g_spawnListenMutex = PTHREAD_MUTEX_INITIALIZER;
42 static int g_spawnListenFd = 0;
43 static bool g_spawnListenStart = false;
44 
45 APPSPAWN_STATIC void SpawnListen(AppSpawnReqMsgMgr *reqMgr, const char *processName);
46 
GetDefaultTimeout(uint32_t def)47 static uint32_t GetDefaultTimeout(uint32_t def)
48 {
49     uint32_t value = def;
50     char data[32] = {};  // 32 length
51     int ret = GetParameter("persist.appspawn.reqMgr.timeout", "0", data, sizeof(data));
52     if (ret > 0 && strcmp(data, "0") != 0) {
53         errno = 0;
54         value = (uint32_t)atoi(data);
55         return (errno != 0) ? def : value;
56     }
57     return value;
58 }
59 
InitClientInstance(AppSpawnClientType type)60 static int InitClientInstance(AppSpawnClientType type)
61 {
62     pthread_mutex_lock(&g_mutex);
63     if (g_clientInstance[type] != NULL) {
64         pthread_mutex_unlock(&g_mutex);
65         return 0;
66     }
67     AppSpawnReqMsgMgr *clientInstance = malloc(sizeof(AppSpawnReqMsgMgr) + RECV_BLOCK_LEN);
68     if (clientInstance == NULL) {
69         pthread_mutex_unlock(&g_mutex);
70         return APPSPAWN_SYSTEM_ERROR;
71     }
72     // init
73     clientInstance->type = type;
74     clientInstance->msgNextId = 1;
75     clientInstance->timeout = GetDefaultTimeout(TIMEOUT_DEF);
76     clientInstance->maxRetryCount = MAX_RETRY_SEND_COUNT;
77     clientInstance->socketId = -1;
78     pthread_mutex_init(&clientInstance->mutex, NULL);
79     // init recvBlock
80     OH_ListInit(&clientInstance->recvBlock.node);
81     clientInstance->recvBlock.blockSize = RECV_BLOCK_LEN;
82     clientInstance->recvBlock.currentIndex = 0;
83     g_clientInstance[type] = clientInstance;
84     pthread_mutex_unlock(&g_mutex);
85     return 0;
86 }
87 
CloseClientSocket(int socketId)88 APPSPAWN_STATIC void CloseClientSocket(int socketId)
89 {
90     APPSPAWN_LOGV("Closed socket with fd %{public}d", socketId);
91     if (socketId >= 0) {
92         int flag = 0;
93         setsockopt(socketId, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
94         close(socketId);
95     }
96 }
97 
CreateClientSocket(uint32_t type,uint32_t timeout)98 APPSPAWN_STATIC int CreateClientSocket(uint32_t type, uint32_t timeout)
99 {
100     const char *socketName;
101 
102     switch (type) {
103         case CLIENT_FOR_APPSPAWN:
104             socketName = APPSPAWN_SOCKET_NAME;
105             break;
106         case CLIENT_FOR_CJAPPSPAWN:
107             socketName = CJAPPSPAWN_SOCKET_NAME;
108             break;
109         case CLIENT_FOR_NATIVESPAWN:
110             socketName = NATIVESPAWN_SOCKET_NAME;
111             break;
112         default:
113             socketName = NWEBSPAWN_SOCKET_NAME;
114             break;
115     }
116 
117     int socketFd = socket(AF_UNIX, SOCK_STREAM, 0);  // SOCK_SEQPACKET
118     APPSPAWN_CHECK(socketFd >= 0, return -1,
119         "Socket socket fd: %{public}s error: %{public}d", socketName, errno);
120     int ret = 0;
121     do {
122         int flag = 1;
123         ret = setsockopt(socketFd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
124         flag = 1;
125         ret = setsockopt(socketFd, SOL_SOCKET, SO_PASSCRED, &flag, sizeof(flag));
126         APPSPAWN_CHECK(ret == 0, break, "Set opt SO_PASSCRED name: %{public}s error: %{public}d", socketName, errno);
127 
128         struct timeval timeoutVal = {timeout, 0};
129         ret = setsockopt(socketFd, SOL_SOCKET, SO_SNDTIMEO, &timeoutVal, sizeof(timeoutVal));
130         APPSPAWN_CHECK(ret == 0, break, "Set opt SO_SNDTIMEO name: %{public}s error: %{public}d", socketName, errno);
131         ret = setsockopt(socketFd, SOL_SOCKET, SO_RCVTIMEO, &timeoutVal, sizeof(timeoutVal));
132         APPSPAWN_CHECK(ret == 0, break, "Set opt SO_RCVTIMEO name: %{public}s error: %{public}d", socketName, errno);
133 
134         ret = APPSPAWN_SYSTEM_ERROR;
135         struct sockaddr_un addr;
136         socklen_t pathSize = sizeof(addr.sun_path);
137         int pathLen = snprintf_s(addr.sun_path, pathSize, (pathSize - 1), "%s%s", APPSPAWN_SOCKET_DIR, socketName);
138         APPSPAWN_CHECK(pathLen > 0, break, "Format path %{public}s error: %{public}d", socketName, errno);
139         addr.sun_family = AF_LOCAL;
140         socklen_t socketAddrLen = (socklen_t)(offsetof(struct sockaddr_un, sun_path) + (socklen_t)pathLen + 1);
141         ret = connect(socketFd, (struct sockaddr *)(&addr), socketAddrLen);
142         APPSPAWN_CHECK(ret == 0, break,
143             "Failed to connect %{public}s error: %{public}d", addr.sun_path, errno);
144         APPSPAWN_LOGI("Create socket success %{public}s socketFd: %{public}d", addr.sun_path, socketFd);
145         return socketFd;
146     } while (0);
147     CloseClientSocket(socketFd);
148     return -1;
149 }
150 
UpdateSocketTimeout(uint32_t timeout,int socketFd)151 APPSPAWN_STATIC int UpdateSocketTimeout(uint32_t timeout, int socketFd)
152 {
153     struct timeval timeoutVal = {timeout, 0};
154     int ret = setsockopt(socketFd, SOL_SOCKET, SO_SNDTIMEO, &timeoutVal, sizeof(timeoutVal));
155     APPSPAWN_CHECK(ret == 0, return ret, "Set opt SO_SNDTIMEO error: %{public}d", errno);
156     ret = setsockopt(socketFd, SOL_SOCKET, SO_RCVTIMEO, &timeoutVal, sizeof(timeoutVal));
157     APPSPAWN_CHECK(ret == 0, return ret, "Set opt SO_RCVTIMEO error: %{public}d", errno);
158     return ret;
159 }
160 
ReadMessage(int socketFd,uint8_t * buf,int len,AppSpawnReqMsgNode * reqNode,AppSpawnResult * result)161 static int ReadMessage(int socketFd, uint8_t *buf, int len, AppSpawnReqMsgNode *reqNode, AppSpawnResult *result)
162 {
163     struct timespec readStart = { 0 };
164     clock_gettime(CLOCK_MONOTONIC, &readStart);
165     ssize_t rLen = TEMP_FAILURE_RETRY(read(socketFd, buf, len));
166     if (rLen == -1 && errno == EAGAIN) {
167         struct timespec readEnd = { 0 };
168         clock_gettime(CLOCK_MONOTONIC, &readEnd);
169         uint64_t diff = DiffTime(&readStart, &readEnd);
170         uint64_t timeout = reqNode->isAsan ? COLDRUN_READ_RETRY_TIME : NORMAL_READ_RETRY_TIME;
171         // If difftime is greater than timeout, it is considered that system hibernation or a time jump has occurred
172         if (diff > timeout) {
173             APPSPAWN_LOGW("Read message again from fd %{public}d, difftime %{public}" PRId64 " us", socketFd, diff);
174             rLen = TEMP_FAILURE_RETRY(read(socketFd, buf, len));
175         }
176     }
177     APPSPAWN_CHECK(rLen >= 0, return APPSPAWN_TIMEOUT,
178         "Read message from fd %{public}d rLen %{public}zd errno: %{public}d", socketFd, rLen, errno);
179     if ((size_t)rLen >= sizeof(AppSpawnResponseMsg)) {
180         AppSpawnResponseMsg *msg = (AppSpawnResponseMsg *)(buf);
181         APPSPAWN_CHECK_ONLY_LOG(reqNode->msg->msgId == msg->msgHdr.msgId,
182             "Invalid msg recvd %{public}u %{public}u", reqNode->msg->msgId, msg->msgHdr.msgId);
183         return memcpy_s(result, sizeof(AppSpawnResult), &msg->result, sizeof(msg->result));
184     }
185     return APPSPAWN_TIMEOUT;
186 }
187 
WriteMessage(int socketFd,const uint8_t * buf,ssize_t len,int * fds,int * fdCount)188 static int WriteMessage(int socketFd, const uint8_t *buf, ssize_t len, int *fds, int *fdCount)
189 {
190     ssize_t written = 0;
191     ssize_t remain = len;
192     const uint8_t *offset = buf;
193     struct iovec iov = {
194         .iov_base = (void *) offset,
195         .iov_len = len,
196     };
197     struct msghdr msg = {
198         .msg_iov = &iov,
199         .msg_iovlen = 1,
200     };
201     char *ctrlBuffer = NULL;
202     if (fdCount != NULL && fds != NULL && *fdCount > 0) {
203         msg.msg_controllen = CMSG_SPACE(*fdCount * sizeof(int));
204         ctrlBuffer = (char *) malloc(msg.msg_controllen);
205         APPSPAWN_CHECK(ctrlBuffer != NULL, return -1,
206             "WriteMessage fail to alloc memory for msg_control %{public}d %{public}d", msg.msg_controllen, errno);
207         msg.msg_control = ctrlBuffer;
208         struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
209         APPSPAWN_CHECK(cmsg != NULL, free(ctrlBuffer);
210             return -1, "WriteMessage fail to get CMSG_FIRSTHDR %{public}d", errno);
211         cmsg->cmsg_len = CMSG_LEN(*fdCount * sizeof(int));
212         cmsg->cmsg_type = SCM_RIGHTS;
213         cmsg->cmsg_level = SOL_SOCKET;
214         int ret = memcpy_s(CMSG_DATA(cmsg), cmsg->cmsg_len, fds, *fdCount * sizeof(int));
215         APPSPAWN_CHECK(ret == 0, free(ctrlBuffer);
216             return -1, "WriteMessage fail to memcpy_s fd %{public}d", errno);
217         APPSPAWN_LOGV("build fd info count %{public}d", *fdCount);
218     }
219     for (ssize_t wLen = 0; remain > 0; offset += wLen, remain -= wLen, written += wLen) {
220         errno = 0;
221         wLen = sendmsg(socketFd, &msg, MSG_NOSIGNAL);
222         APPSPAWN_LOGV("Write msg errno: %{public}d %{public}zd", errno, wLen);
223         APPSPAWN_CHECK((wLen > 0) || (errno == EINTR), free(ctrlBuffer);
224             return -errno,
225             "Failed to write message to fd %{public}d, wLen %{public}zd errno: %{public}d", socketFd, wLen, errno);
226     }
227     free(ctrlBuffer);
228     return written == len ? 0 : -EFAULT;
229 }
230 
HandleMsgSend(AppSpawnReqMsgMgr * reqMgr,int socketId,AppSpawnReqMsgNode * reqNode)231 static int HandleMsgSend(AppSpawnReqMsgMgr *reqMgr, int socketId, AppSpawnReqMsgNode *reqNode)
232 {
233     APPSPAWN_LOGV("HandleMsgSend reqId: %{public}u msgId: %{public}d", reqNode->reqId, reqNode->msg->msgId);
234     ListNode *sendNode = reqNode->msgBlocks.next;
235     uint32_t currentIndex = 0;
236     bool sendFd = true;
237     while (sendNode != NULL && sendNode != &reqNode->msgBlocks) {
238         AppSpawnMsgBlock *sendBlock = (AppSpawnMsgBlock *)ListEntry(sendNode, AppSpawnMsgBlock, node);
239         int ret = WriteMessage(socketId, sendBlock->buffer, sendBlock->currentIndex,
240             sendFd ? reqNode->fds : NULL,
241             sendFd ? &reqNode->fdCount : NULL);
242         currentIndex += sendBlock->currentIndex;
243         APPSPAWN_LOGV("Write msg ret: %{public}d msgId: %{public}u %{public}u %{public}u",
244             ret, reqNode->msg->msgId, reqNode->msg->msgLen, currentIndex);
245         if (ret == 0) {
246             sendFd = false;
247             sendNode = sendNode->next;
248             continue;
249         }
250         APPSPAWN_LOGE("Send msg fail reqId: %{public}u msgId: %{public}d ret: %{public}d",
251             reqNode->reqId, reqNode->msg->msgId, ret);
252         return ret;
253     }
254     return 0;
255 }
256 
TryCreateSocket(AppSpawnReqMsgMgr * reqMgr)257 APPSPAWN_STATIC void TryCreateSocket(AppSpawnReqMsgMgr *reqMgr)
258 {
259     uint32_t retryCount = 1;
260     while (retryCount <= reqMgr->maxRetryCount) {
261         if (reqMgr->socketId < 0) {
262             reqMgr->socketId = CreateClientSocket(reqMgr->type, reqMgr->timeout);
263         }
264         if (reqMgr->socketId < 0) {
265             APPSPAWN_LOGV("Failed to create socket, try again");
266             usleep(RETRY_TIME);
267             retryCount++;
268             continue;
269         }
270         break;
271     }
272 }
273 
ClientSendMsg(AppSpawnReqMsgMgr * reqMgr,AppSpawnReqMsgNode * reqNode,AppSpawnResult * result)274 static int ClientSendMsg(AppSpawnReqMsgMgr *reqMgr, AppSpawnReqMsgNode *reqNode, AppSpawnResult *result)
275 {
276     uint32_t retryCount = 1;
277     int isColdRun = reqNode->isAsan;
278     while (retryCount <= reqMgr->maxRetryCount) {
279         if (reqMgr->socketId < 0) { // try create socket
280             TryCreateSocket(reqMgr);
281             if (reqMgr->socketId < 0) {
282                 usleep(RETRY_TIME);
283                 retryCount++;
284                 continue;
285             }
286         }
287         if (reqNode->msg->msgType != MSG_OBSERVE_PROCESS_SIGNAL_STATUS) {
288             pthread_mutex_lock(&g_spawnListenMutex);
289             SpawnListen(reqMgr, reqNode->msg->processName);
290             pthread_mutex_unlock(&g_spawnListenMutex);
291         }
292         if (isColdRun && reqMgr->timeout < ASAN_TIMEOUT) {
293             UpdateSocketTimeout(ASAN_TIMEOUT, reqMgr->socketId);
294         }
295 
296         if (reqNode->msg->msgId == 0) {
297             reqNode->msg->msgId = reqMgr->msgNextId++;
298         }
299         int ret = HandleMsgSend(reqMgr, reqMgr->socketId, reqNode);
300         if (ret == 0) {
301             ret = ReadMessage(reqMgr->socketId, reqMgr->recvBlock.buffer, reqMgr->recvBlock.blockSize, reqNode, result);
302         }
303         if (ret == 0) {
304             if (isColdRun && reqMgr->timeout < ASAN_TIMEOUT) {
305                 UpdateSocketTimeout(reqMgr->timeout, reqMgr->socketId);
306             }
307             return 0;
308         }
309         // retry
310         CloseClientSocket(reqMgr->socketId);
311         reqMgr->socketId = -1;
312         reqMgr->msgNextId = 1;
313         reqNode->msg->msgId = 0;
314         usleep(RETRY_TIME);
315         retryCount++;
316     }
317     return APPSPAWN_TIMEOUT;
318 }
319 
SpawnListen(AppSpawnReqMsgMgr * reqMgr,const char * processName)320 APPSPAWN_STATIC void SpawnListen(AppSpawnReqMsgMgr *reqMgr, const char *processName)
321 {
322     AppSpawnClientType type = reqMgr->type;
323     if (g_spawnListenFd <= 0 || g_spawnListenStart) {
324         APPSPAWN_LOGV("Spawn Listen fail,fd:%{public}d,start:%{public}d", g_spawnListenFd, g_spawnListenStart);
325         return;
326     }
327     APPSPAWN_CHECK((type == CLIENT_FOR_APPSPAWN), return, "Invalid type");
328     APPSPAWN_CHECK(processName != NULL, return, "Invalid process name");
329 
330     APPSPAWN_LOGI("Spawn Listen start type:%{public}d,fd:%{public}d", type, g_spawnListenFd);
331 
332     AppSpawnReqMsgHandle reqHandle;
333     int ret = AppSpawnReqMsgCreate(MSG_OBSERVE_PROCESS_SIGNAL_STATUS, processName, &reqHandle);
334     APPSPAWN_CHECK(ret == 0, return, "Failed to create type:%{public}d req msg, ret = %{public}d", type, ret);
335 
336     ret = AppSpawnReqMsgAddFd(reqHandle, SPAWN_LISTEN_FD_NAME, g_spawnListenFd);
337     APPSPAWN_CHECK(ret == 0, AppSpawnReqMsgFree(reqHandle);
338         return, "Failed to add info message, ret=%{public}d", ret);
339 
340     AppSpawnResult result = {0};
341     ret = ClientSendMsg(reqMgr, (AppSpawnReqMsgNode *)reqHandle, &result);
342     APPSPAWN_CHECK(ret == 0, return, "Send msg to type:%{public}d failed, ret=%{public}d", type, ret);
343     APPSPAWN_CHECK(result.result == 0, return, "Appspawn failed to handle message, result=%{public}d", result.result);
344 
345     g_spawnListenStart = true;
346     APPSPAWN_LOGI("Spawn Listen client type[%{public}d] Send fd[%{public}d] success", type, g_spawnListenFd);
347 }
348 
AppSpawnClientInit(const char * serviceName,AppSpawnClientHandle * handle)349 int AppSpawnClientInit(const char *serviceName, AppSpawnClientHandle *handle)
350 {
351     APPSPAWN_CHECK(serviceName != NULL, return APPSPAWN_ARG_INVALID, "Invalid service name");
352     APPSPAWN_CHECK(handle != NULL, return APPSPAWN_ARG_INVALID, "Invalid handle for %{public}s", serviceName);
353     APPSPAWN_LOGV("AppSpawnClientInit serviceName %{public}s", serviceName);
354     AppSpawnClientType type = CLIENT_FOR_APPSPAWN;
355     if (strcmp(serviceName, CJAPPSPAWN_SERVER_NAME) == 0) {
356         type = CLIENT_FOR_CJAPPSPAWN;
357     } else if (strcmp(serviceName, NWEBSPAWN_SERVER_NAME) == 0 || strstr(serviceName, NWEBSPAWN_SOCKET_NAME) != NULL) {
358         type = CLIENT_FOR_NWEBSPAWN;
359     } else if (strcmp(serviceName, NATIVESPAWN_SERVER_NAME) == 0 ||
360         strstr(serviceName, NATIVESPAWN_SOCKET_NAME) != NULL) {
361         type = CLIENT_FOR_NATIVESPAWN;
362     }
363     int ret = InitClientInstance(type);
364     APPSPAWN_CHECK(ret == 0, return APPSPAWN_SYSTEM_ERROR, "Failed to create reqMgr");
365     *handle = (AppSpawnClientHandle)g_clientInstance[type];
366     return 0;
367 }
368 
AppSpawnClientDestroy(AppSpawnClientHandle handle)369 int AppSpawnClientDestroy(AppSpawnClientHandle handle)
370 {
371     AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle;
372     APPSPAWN_CHECK(reqMgr != NULL, return APPSPAWN_SYSTEM_ERROR, "Invalid reqMgr");
373     pthread_mutex_lock(&g_mutex);
374     if (reqMgr->type < sizeof(g_clientInstance) / sizeof(g_clientInstance[0])) {
375         g_clientInstance[reqMgr->type] = NULL;
376     }
377     pthread_mutex_unlock(&g_mutex);
378     pthread_mutex_destroy(&reqMgr->mutex);
379     if (reqMgr->socketId >= 0) {
380         CloseClientSocket(reqMgr->socketId);
381         reqMgr->socketId = -1;
382     }
383     free(reqMgr);
384     return 0;
385 }
386 
AppSpawnClientSendMsg(AppSpawnClientHandle handle,AppSpawnReqMsgHandle reqHandle,AppSpawnResult * result)387 int AppSpawnClientSendMsg(AppSpawnClientHandle handle, AppSpawnReqMsgHandle reqHandle, AppSpawnResult *result)
388 {
389     APPSPAWN_CHECK(result != NULL, AppSpawnReqMsgFree(reqHandle);
390         return APPSPAWN_ARG_INVALID, "Invalid result");
391     result->result = APPSPAWN_ARG_INVALID;
392     result->pid = 0;
393     AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle;
394     APPSPAWN_CHECK(reqMgr != NULL, AppSpawnReqMsgFree(reqHandle);
395         return APPSPAWN_ARG_INVALID, "Invalid reqMgr");
396     AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
397     APPSPAWN_CHECK(reqNode != NULL && reqNode->msg != NULL, AppSpawnReqMsgFree(reqHandle);
398         return APPSPAWN_ARG_INVALID, "Invalid msgReq");
399 
400     APPSPAWN_LOGI("AppSpawnClientSendMsg reqId: %{public}u msgLen: %{public}u %{public}s",
401         reqNode->reqId, reqNode->msg->msgLen, reqNode->msg->processName);
402     pthread_mutex_lock(&reqMgr->mutex);
403     int ret = ClientSendMsg(reqMgr, reqNode, result);
404     if (ret != 0) {
405         result->result = ret;
406     }
407     pthread_mutex_unlock(&reqMgr->mutex);
408     APPSPAWN_LOGI("AppSpawnClientSendMsg reqId: %{public}u end result: 0x%{public}x pid: %{public}d",
409         reqNode->reqId, result->result, result->pid);
410     AppSpawnReqMsgFree(reqHandle);
411     return ret;
412 }
413 
AppSpawnClientSendUserLockStatus(uint32_t userId,bool isLocked)414 int AppSpawnClientSendUserLockStatus(uint32_t userId, bool isLocked)
415 {
416     char lockstatus[USER_LOCK_STATUS_SIZE] = {0};
417     int ret = snprintf_s(lockstatus, USER_LOCK_STATUS_SIZE, USER_LOCK_STATUS_SIZE - 1, "%u:%d", userId, isLocked);
418     APPSPAWN_CHECK(ret > 0, return ret, "Failed to build lockstatus req msg, ret = %{public}d", ret);
419     APPSPAWN_LOGI("Send lockstatus msg to appspawn %{public}s", lockstatus);
420 
421     AppSpawnReqMsgHandle reqHandle;
422     ret = AppSpawnReqMsgCreate(MSG_LOCK_STATUS, "storage_manager", &reqHandle);
423     APPSPAWN_CHECK(ret == 0, return ret, "Failed to create appspawn req msg, ret = %{public}d", ret);
424 
425     ret = AppSpawnReqMsgAddStringInfo(reqHandle, "lockstatus", lockstatus);
426     APPSPAWN_CHECK(ret == 0, AppSpawnReqMsgFree(reqHandle);
427         return ret, "Failed to add lockstatus message, ret=%{public}d", ret);
428 
429     AppSpawnClientHandle clientHandle;
430     ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
431     APPSPAWN_CHECK(ret == 0, AppSpawnReqMsgFree(reqHandle);
432         return ret, "Appspawn client failed to init, ret=%{public}d", ret);
433 
434     AppSpawnResult result = {0};
435     ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
436     AppSpawnClientDestroy(clientHandle);
437     APPSPAWN_CHECK(ret == 0, return ret, "Send msg to appspawn failed, ret=%{public}d", ret);
438 
439     if (result.result != 0) {
440         APPSPAWN_LOGE("Appspawn failed to handle message, result=%{public}d", result.result);
441         return result.result;
442     }
443     APPSPAWN_LOGI("Send lockstatus msg to appspawn success");
444     return 0;
445 }
446 
SpawnListenFdSet(int fd)447 int SpawnListenFdSet(int fd)
448 {
449     if (fd <= 0) {
450         APPSPAWN_LOGE("Spawn Listen fd set[%{public}d] failed", fd);
451         return APPSPAWN_ARG_INVALID;
452     }
453     g_spawnListenFd = fd;
454     APPSPAWN_LOGI("Spawn Listen fd set[%{public}d] success", fd);
455     return 0;
456 }
457 
SpawnListenCloseSet(void)458 int SpawnListenCloseSet(void)
459 {
460     pthread_mutex_lock(&g_spawnListenMutex);
461     g_spawnListenStart = false;
462     pthread_mutex_unlock(&g_spawnListenMutex);
463     APPSPAWN_LOGI("Spawn Listen close set success");
464     return 0;
465 }