• 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 static pthread_mutex_t g_nativeSpawnListenMutex = PTHREAD_MUTEX_INITIALIZER;
45 static int g_nativeSpawnListenFd = 0;
46 static bool g_nativeSpawnListenStart = false;
47 
48 APPSPAWN_STATIC void SpawnListen(AppSpawnReqMsgMgr *reqMgr, const char *processName);
49 
GetDefaultTimeout(uint32_t def)50 static uint32_t GetDefaultTimeout(uint32_t def)
51 {
52     uint32_t value = def;
53     char data[32] = {};  // 32 length
54     int ret = GetParameter("persist.appspawn.reqMgr.timeout", "0", data, sizeof(data));
55     if (ret > 0 && strcmp(data, "0") != 0) {
56         errno = 0;
57         value = (uint32_t)atoi(data);
58         return (errno != 0) ? def : value;
59     }
60     return value;
61 }
62 
InitClientInstance(AppSpawnClientType type)63 static int InitClientInstance(AppSpawnClientType type)
64 {
65     pthread_mutex_lock(&g_mutex);
66     if (g_clientInstance[type] != NULL) {
67         pthread_mutex_unlock(&g_mutex);
68         return 0;
69     }
70     AppSpawnReqMsgMgr *clientInstance = malloc(sizeof(AppSpawnReqMsgMgr) + RECV_BLOCK_LEN);
71     if (clientInstance == NULL) {
72         pthread_mutex_unlock(&g_mutex);
73         return APPSPAWN_SYSTEM_ERROR;
74     }
75     // init
76     clientInstance->type = type;
77     clientInstance->msgNextId = 1;
78     clientInstance->timeout = GetDefaultTimeout(TIMEOUT_DEF);
79     clientInstance->maxRetryCount = MAX_RETRY_SEND_COUNT;
80     clientInstance->socketId = -1;
81     pthread_mutex_init(&clientInstance->mutex, NULL);
82     // init recvBlock
83     OH_ListInit(&clientInstance->recvBlock.node);
84     clientInstance->recvBlock.blockSize = RECV_BLOCK_LEN;
85     clientInstance->recvBlock.currentIndex = 0;
86     g_clientInstance[type] = clientInstance;
87     pthread_mutex_unlock(&g_mutex);
88     return 0;
89 }
90 
CloseClientSocket(int socketId)91 APPSPAWN_STATIC void CloseClientSocket(int socketId)
92 {
93     APPSPAWN_LOGV("Closed socket with fd %{public}d", socketId);
94     if (socketId >= 0) {
95         int flag = 0;
96         setsockopt(socketId, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
97         close(socketId);
98     }
99 }
100 
CreateClientSocket(uint32_t type,uint32_t timeout)101 APPSPAWN_STATIC int CreateClientSocket(uint32_t type, uint32_t timeout)
102 {
103     const char *socketName;
104 
105     switch (type) {
106         case CLIENT_FOR_APPSPAWN:
107             socketName = APPSPAWN_SOCKET_NAME;
108             break;
109         case CLIENT_FOR_CJAPPSPAWN:
110             socketName = CJAPPSPAWN_SOCKET_NAME;
111             break;
112         case CLIENT_FOR_NATIVESPAWN:
113             socketName = NATIVESPAWN_SOCKET_NAME;
114             break;
115         case CLIENT_FOR_HYBRIDSPAWN:
116             socketName = HYBRIDSPAWN_SOCKET_NAME;
117             break;
118         default:
119             socketName = NWEBSPAWN_SOCKET_NAME;
120             break;
121     }
122 
123     int socketFd = socket(AF_UNIX, SOCK_STREAM, 0);  // SOCK_SEQPACKET
124     APPSPAWN_CHECK(socketFd >= 0, return -1,
125         "Socket socket fd: %{public}s error: %{public}d", socketName, errno);
126     int ret = 0;
127     do {
128         int flag = 1;
129         ret = setsockopt(socketFd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
130         flag = 1;
131         ret = setsockopt(socketFd, SOL_SOCKET, SO_PASSCRED, &flag, sizeof(flag));
132         APPSPAWN_CHECK(ret == 0, break, "Set opt SO_PASSCRED name: %{public}s error: %{public}d", socketName, errno);
133 
134         struct timeval timeoutVal = {timeout, 0};
135         ret = setsockopt(socketFd, SOL_SOCKET, SO_SNDTIMEO, &timeoutVal, sizeof(timeoutVal));
136         APPSPAWN_CHECK(ret == 0, break, "Set opt SO_SNDTIMEO name: %{public}s error: %{public}d", socketName, errno);
137         ret = setsockopt(socketFd, SOL_SOCKET, SO_RCVTIMEO, &timeoutVal, sizeof(timeoutVal));
138         APPSPAWN_CHECK(ret == 0, break, "Set opt SO_RCVTIMEO name: %{public}s error: %{public}d", socketName, errno);
139 
140         ret = APPSPAWN_SYSTEM_ERROR;
141         struct sockaddr_un addr;
142         socklen_t pathSize = sizeof(addr.sun_path);
143         int pathLen = snprintf_s(addr.sun_path, pathSize, (pathSize - 1), "%s%s", APPSPAWN_SOCKET_DIR, socketName);
144         APPSPAWN_CHECK(pathLen > 0, break, "Format path %{public}s error: %{public}d", socketName, errno);
145         addr.sun_family = AF_LOCAL;
146         socklen_t socketAddrLen = (socklen_t)(offsetof(struct sockaddr_un, sun_path) + (socklen_t)pathLen + 1);
147         ret = connect(socketFd, (struct sockaddr *)(&addr), socketAddrLen);
148         APPSPAWN_CHECK(ret == 0, break,
149             "Failed to connect %{public}s error: %{public}d", addr.sun_path, errno);
150         APPSPAWN_LOGI("Create socket success %{public}s socketFd: %{public}d", addr.sun_path, socketFd);
151         return socketFd;
152     } while (0);
153     CloseClientSocket(socketFd);
154     return -1;
155 }
156 
UpdateSocketTimeout(uint32_t timeout,int socketFd)157 APPSPAWN_STATIC int UpdateSocketTimeout(uint32_t timeout, int socketFd)
158 {
159     struct timeval timeoutVal = {timeout, 0};
160     int ret = setsockopt(socketFd, SOL_SOCKET, SO_SNDTIMEO, &timeoutVal, sizeof(timeoutVal));
161     APPSPAWN_CHECK(ret == 0, return ret, "Set opt SO_SNDTIMEO error: %{public}d", errno);
162     ret = setsockopt(socketFd, SOL_SOCKET, SO_RCVTIMEO, &timeoutVal, sizeof(timeoutVal));
163     APPSPAWN_CHECK(ret == 0, return ret, "Set opt SO_RCVTIMEO error: %{public}d", errno);
164     return ret;
165 }
166 
ReadMessage(int socketFd,uint8_t * buf,int len,AppSpawnReqMsgNode * reqNode,AppSpawnResult * result)167 static int ReadMessage(int socketFd, uint8_t *buf, int len, AppSpawnReqMsgNode *reqNode, AppSpawnResult *result)
168 {
169     struct timespec readStart = { 0 };
170     clock_gettime(CLOCK_MONOTONIC, &readStart);
171     ssize_t rLen = TEMP_FAILURE_RETRY(read(socketFd, buf, len));
172     if (rLen == -1 && errno == EAGAIN) {
173         struct timespec readEnd = { 0 };
174         clock_gettime(CLOCK_MONOTONIC, &readEnd);
175         uint64_t diff = DiffTime(&readStart, &readEnd);
176         uint64_t timeout = reqNode->isAsan ? COLDRUN_READ_RETRY_TIME : NORMAL_READ_RETRY_TIME;
177         // If difftime is greater than timeout, it is considered that system hibernation or a time jump has occurred
178         if (diff > timeout) {
179             APPSPAWN_LOGW("Read message again from fd %{public}d, difftime %{public}" PRId64 " us", socketFd, diff);
180             rLen = TEMP_FAILURE_RETRY(read(socketFd, buf, len));
181         }
182     }
183     APPSPAWN_CHECK(rLen >= 0, return APPSPAWN_TIMEOUT,
184         "Read message from fd %{public}d rLen %{public}zd errno: %{public}d", socketFd, rLen, errno);
185     if ((size_t)rLen >= sizeof(AppSpawnResponseMsg)) {
186         AppSpawnResponseMsg *msg = (AppSpawnResponseMsg *)(buf);
187         APPSPAWN_CHECK_ONLY_LOG(reqNode->msg->msgId == msg->msgHdr.msgId,
188             "Invalid msg recvd %{public}u %{public}u", reqNode->msg->msgId, msg->msgHdr.msgId);
189         return memcpy_s(result, sizeof(AppSpawnResult), &msg->result, sizeof(msg->result));
190     }
191     return APPSPAWN_TIMEOUT;
192 }
193 
WriteMessage(int socketFd,const uint8_t * buf,ssize_t len,int * fds,int * fdCount)194 static int WriteMessage(int socketFd, const uint8_t *buf, ssize_t len, int *fds, int *fdCount)
195 {
196     ssize_t written = 0;
197     ssize_t remain = len;
198     const uint8_t *offset = buf;
199     struct iovec iov = {
200         .iov_base = (void *) offset,
201         .iov_len = len,
202     };
203     struct msghdr msg = {
204         .msg_iov = &iov,
205         .msg_iovlen = 1,
206     };
207     char *ctrlBuffer = NULL;
208     if (fdCount != NULL && fds != NULL && *fdCount > 0) {
209         msg.msg_controllen = CMSG_SPACE(*fdCount * sizeof(int));
210         ctrlBuffer = (char *) malloc(msg.msg_controllen);
211         APPSPAWN_CHECK(ctrlBuffer != NULL, return -1,
212             "WriteMessage fail to alloc memory for msg_control %{public}d %{public}d", msg.msg_controllen, errno);
213         msg.msg_control = ctrlBuffer;
214         struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
215         APPSPAWN_CHECK(cmsg != NULL, free(ctrlBuffer);
216             return -1, "WriteMessage fail to get CMSG_FIRSTHDR %{public}d", errno);
217         cmsg->cmsg_len = CMSG_LEN(*fdCount * sizeof(int));
218         cmsg->cmsg_type = SCM_RIGHTS;
219         cmsg->cmsg_level = SOL_SOCKET;
220         int ret = memcpy_s(CMSG_DATA(cmsg), cmsg->cmsg_len, fds, *fdCount * sizeof(int));
221         APPSPAWN_CHECK(ret == 0, free(ctrlBuffer);
222             return -1, "WriteMessage fail to memcpy_s fd %{public}d", errno);
223         APPSPAWN_LOGV("build fd info count %{public}d", *fdCount);
224     }
225     for (ssize_t wLen = 0; remain > 0; offset += wLen, remain -= wLen, written += wLen) {
226         errno = 0;
227         wLen = sendmsg(socketFd, &msg, MSG_NOSIGNAL);
228         APPSPAWN_LOGV("Write msg errno: %{public}d %{public}zd", errno, wLen);
229         APPSPAWN_CHECK((wLen > 0) || (errno == EINTR), free(ctrlBuffer);
230             return -errno,
231             "Failed to write message to fd %{public}d, wLen %{public}zd errno: %{public}d", socketFd, wLen, errno);
232     }
233     free(ctrlBuffer);
234     return written == len ? 0 : -EFAULT;
235 }
236 
HandleMsgSend(AppSpawnReqMsgMgr * reqMgr,int socketId,AppSpawnReqMsgNode * reqNode)237 static int HandleMsgSend(AppSpawnReqMsgMgr *reqMgr, int socketId, AppSpawnReqMsgNode *reqNode)
238 {
239     APPSPAWN_LOGV("HandleMsgSend reqId: %{public}u msgId: %{public}d", reqNode->reqId, reqNode->msg->msgId);
240     ListNode *sendNode = reqNode->msgBlocks.next;
241     uint32_t currentIndex = 0;
242     bool sendFd = true;
243     while (sendNode != NULL && sendNode != &reqNode->msgBlocks) {
244         AppSpawnMsgBlock *sendBlock = (AppSpawnMsgBlock *)ListEntry(sendNode, AppSpawnMsgBlock, node);
245         int ret = WriteMessage(socketId, sendBlock->buffer, sendBlock->currentIndex,
246             sendFd ? reqNode->fds : NULL,
247             sendFd ? &reqNode->fdCount : NULL);
248         currentIndex += sendBlock->currentIndex;
249         APPSPAWN_LOGV("Write msg ret: %{public}d msgId: %{public}u %{public}u %{public}u",
250             ret, reqNode->msg->msgId, reqNode->msg->msgLen, currentIndex);
251         if (ret == 0) {
252             sendFd = false;
253             sendNode = sendNode->next;
254             continue;
255         }
256         APPSPAWN_LOGE("Send msg fail reqId: %{public}u msgId: %{public}d ret: %{public}d",
257             reqNode->reqId, reqNode->msg->msgId, ret);
258         return ret;
259     }
260     return 0;
261 }
262 
TryCreateSocket(AppSpawnReqMsgMgr * reqMgr)263 APPSPAWN_STATIC void TryCreateSocket(AppSpawnReqMsgMgr *reqMgr)
264 {
265     uint32_t retryCount = 1;
266     while (retryCount <= reqMgr->maxRetryCount) {
267         if (reqMgr->socketId < 0) {
268             reqMgr->socketId = CreateClientSocket(reqMgr->type, reqMgr->timeout);
269         }
270         if (reqMgr->socketId < 0) {
271             APPSPAWN_LOGV("Failed to create socket, try again");
272             usleep(RETRY_TIME);
273             retryCount++;
274             continue;
275         }
276         break;
277     }
278 }
279 
SendSpawnListenMsg(AppSpawnReqMsgMgr * reqMgr,AppSpawnReqMsgNode * reqNode)280 static void SendSpawnListenMsg(AppSpawnReqMsgMgr *reqMgr, AppSpawnReqMsgNode *reqNode)
281 {
282     if (reqMgr->type == CLIENT_FOR_APPSPAWN && reqNode->msg->msgType != MSG_OBSERVE_PROCESS_SIGNAL_STATUS) {
283         pthread_mutex_lock(&g_spawnListenMutex);
284         SpawnListen(reqMgr, reqNode->msg->processName);
285         pthread_mutex_unlock(&g_spawnListenMutex);
286     }
287 
288     if (reqMgr->type == CLIENT_FOR_NATIVESPAWN && reqNode->msg->msgType != MSG_OBSERVE_PROCESS_SIGNAL_STATUS) {
289         pthread_mutex_lock(&g_nativeSpawnListenMutex);
290         SpawnListen(reqMgr, reqNode->msg->processName);
291         pthread_mutex_unlock(&g_nativeSpawnListenMutex);
292     }
293 }
294 
ClientSendMsg(AppSpawnReqMsgMgr * reqMgr,AppSpawnReqMsgNode * reqNode,AppSpawnResult * result)295 static int ClientSendMsg(AppSpawnReqMsgMgr *reqMgr, AppSpawnReqMsgNode *reqNode, AppSpawnResult *result)
296 {
297     uint32_t retryCount = 1;
298     int isColdRun = reqNode->isAsan;
299     while (retryCount <= reqMgr->maxRetryCount) {
300         if (reqMgr->socketId < 0) { // try create socket
301             TryCreateSocket(reqMgr);
302             if (reqMgr->socketId < 0) {
303                 usleep(RETRY_TIME);
304                 retryCount++;
305                 continue;
306             }
307         }
308         SendSpawnListenMsg(reqMgr, reqNode);
309 
310         if (isColdRun && reqMgr->timeout < ASAN_TIMEOUT) {
311             UpdateSocketTimeout(ASAN_TIMEOUT, reqMgr->socketId);
312         }
313 
314         if (reqNode->msg->msgId == 0) {
315             reqNode->msg->msgId = reqMgr->msgNextId++;
316         }
317         int ret = HandleMsgSend(reqMgr, reqMgr->socketId, reqNode);
318         if (ret == 0) {
319             ret = ReadMessage(reqMgr->socketId, reqMgr->recvBlock.buffer, reqMgr->recvBlock.blockSize, reqNode, result);
320         }
321         if (ret == 0) {
322             if (isColdRun && reqMgr->timeout < ASAN_TIMEOUT) {
323                 UpdateSocketTimeout(reqMgr->timeout, reqMgr->socketId);
324             }
325             return 0;
326         }
327         // retry
328         CloseClientSocket(reqMgr->socketId);
329         reqMgr->socketId = -1;
330         reqMgr->msgNextId = 1;
331         reqNode->msg->msgId = 0;
332         usleep(RETRY_TIME);
333         retryCount++;
334     }
335     return APPSPAWN_TIMEOUT;
336 }
337 
SpawnListenBase(AppSpawnReqMsgMgr * reqMgr,const char * processName,int fd,bool startFlag)338 APPSPAWN_STATIC int SpawnListenBase(AppSpawnReqMsgMgr *reqMgr, const char *processName, int fd, bool startFlag)
339 {
340     if (fd <= 0 || startFlag) {
341         APPSPAWN_LOGV("Spawn Listen fail, fd:%{public}d, startFlag:%{public}d", fd, startFlag);
342         return -1;
343     }
344     AppSpawnClientType type = reqMgr->type;
345     APPSPAWN_LOGI("Spawn Listen start type:%{public}d, fd:%{public}d", type, fd);
346 
347     AppSpawnReqMsgHandle reqHandle;
348     int ret = AppSpawnReqMsgCreate(MSG_OBSERVE_PROCESS_SIGNAL_STATUS, processName, &reqHandle);
349     APPSPAWN_CHECK(ret == 0, return ret, "Failed to create type:%{public}d req msg, ret %{public}d", type, ret);
350 
351     ret = AppSpawnReqMsgAddFd(reqHandle, SPAWN_LISTEN_FD_NAME, fd);
352     APPSPAWN_CHECK(ret == 0, AppSpawnReqMsgFree(reqHandle);
353         return ret, "Failed to add fd info to msg, ret %{public}d", ret);
354 
355     AppSpawnResult result = {0};
356     ret = ClientSendMsg(reqMgr, (AppSpawnReqMsgNode *)reqHandle, &result);
357     APPSPAWN_CHECK(ret == 0, return ret, "Send msg to type:%{public}d fail, ret %{public}d", type, ret);
358     APPSPAWN_CHECK(result.result == 0, return result.result,
359                    "Spawn failed to handle listen msg, result %{public}d", result.result);
360 
361     APPSPAWN_LOGI("Spawn Listen client type:%{public}d send fd:%{public}d success", type, fd);
362     return 0;
363 }
364 
SpawnListen(AppSpawnReqMsgMgr * reqMgr,const char * processName)365 APPSPAWN_STATIC void SpawnListen(AppSpawnReqMsgMgr *reqMgr, const char *processName)
366 {
367     APPSPAWN_CHECK(reqMgr != NULL, return, "Invalid reqMgr");
368     APPSPAWN_CHECK(processName != NULL, return, "Invalid process name");
369 
370     int ret = 0;
371     if (reqMgr->type == CLIENT_FOR_APPSPAWN) {
372         ret = SpawnListenBase(reqMgr, processName, g_spawnListenFd, g_spawnListenStart);
373         APPSPAWN_ONLY_EXPER(ret == 0, g_spawnListenStart = true);
374     }
375 
376     if (reqMgr->type == CLIENT_FOR_NATIVESPAWN) {
377         ret = SpawnListenBase(reqMgr, processName, g_nativeSpawnListenFd, g_nativeSpawnListenStart);
378         APPSPAWN_ONLY_EXPER(ret == 0, g_nativeSpawnListenStart = true);
379     }
380 }
381 
AppSpawnClientInit(const char * serviceName,AppSpawnClientHandle * handle)382 int AppSpawnClientInit(const char *serviceName, AppSpawnClientHandle *handle)
383 {
384     APPSPAWN_CHECK(serviceName != NULL, return APPSPAWN_ARG_INVALID, "Invalid service name");
385     APPSPAWN_CHECK(handle != NULL, return APPSPAWN_ARG_INVALID, "Invalid handle for %{public}s", serviceName);
386     APPSPAWN_LOGV("AppSpawnClientInit serviceName %{public}s", serviceName);
387     AppSpawnClientType type = CLIENT_FOR_APPSPAWN;
388     if (strcmp(serviceName, CJAPPSPAWN_SERVER_NAME) == 0) {
389         type = CLIENT_FOR_CJAPPSPAWN;
390     } else if (strcmp(serviceName, NWEBSPAWN_SERVER_NAME) == 0 || strstr(serviceName, NWEBSPAWN_SOCKET_NAME) != NULL) {
391         type = CLIENT_FOR_NWEBSPAWN;
392     } else if (strcmp(serviceName, NATIVESPAWN_SERVER_NAME) == 0 ||
393         strstr(serviceName, NATIVESPAWN_SOCKET_NAME) != NULL) {
394         type = CLIENT_FOR_NATIVESPAWN;
395     } else if (strcmp(serviceName, HYBRIDSPAWN_SERVER_NAME) == 0) {
396         type = CLIENT_FOR_HYBRIDSPAWN;
397     }
398     int ret = InitClientInstance(type);
399     APPSPAWN_CHECK(ret == 0, return APPSPAWN_SYSTEM_ERROR, "Failed to create reqMgr");
400     *handle = (AppSpawnClientHandle)g_clientInstance[type];
401     return 0;
402 }
403 
AppSpawnClientDestroy(AppSpawnClientHandle handle)404 int AppSpawnClientDestroy(AppSpawnClientHandle handle)
405 {
406     AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle;
407     APPSPAWN_CHECK(reqMgr != NULL, return APPSPAWN_SYSTEM_ERROR, "Invalid reqMgr");
408     pthread_mutex_lock(&g_mutex);
409     if (reqMgr->type < sizeof(g_clientInstance) / sizeof(g_clientInstance[0])) {
410         g_clientInstance[reqMgr->type] = NULL;
411     }
412     pthread_mutex_unlock(&g_mutex);
413     pthread_mutex_destroy(&reqMgr->mutex);
414     if (reqMgr->socketId >= 0) {
415         CloseClientSocket(reqMgr->socketId);
416         reqMgr->socketId = -1;
417     }
418     free(reqMgr);
419     return 0;
420 }
421 
AppSpawnClientSendMsg(AppSpawnClientHandle handle,AppSpawnReqMsgHandle reqHandle,AppSpawnResult * result)422 int AppSpawnClientSendMsg(AppSpawnClientHandle handle, AppSpawnReqMsgHandle reqHandle, AppSpawnResult *result)
423 {
424     APPSPAWN_CHECK(result != NULL, AppSpawnReqMsgFree(reqHandle);
425         return APPSPAWN_ARG_INVALID, "Invalid result");
426     result->result = APPSPAWN_ARG_INVALID;
427     result->pid = 0;
428     AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle;
429     APPSPAWN_CHECK(reqMgr != NULL, AppSpawnReqMsgFree(reqHandle);
430         return APPSPAWN_ARG_INVALID, "Invalid reqMgr");
431     AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
432     APPSPAWN_CHECK(reqNode != NULL && reqNode->msg != NULL, AppSpawnReqMsgFree(reqHandle);
433         return APPSPAWN_ARG_INVALID, "Invalid msgReq");
434 
435     APPSPAWN_LOGI("AppSpawnClientSendMsg reqId: %{public}u msgLen: %{public}u %{public}s",
436         reqNode->reqId, reqNode->msg->msgLen, reqNode->msg->processName);
437     pthread_mutex_lock(&reqMgr->mutex);
438     int ret = ClientSendMsg(reqMgr, reqNode, result);
439     if (ret != 0) {
440         result->result = ret;
441     }
442     pthread_mutex_unlock(&reqMgr->mutex);
443     APPSPAWN_LOGI("AppSpawnClientSendMsg reqId: %{public}u end result: 0x%{public}x pid: %{public}d",
444         reqNode->reqId, result->result, result->pid);
445     AppSpawnReqMsgFree(reqHandle);
446     return ret;
447 }
448 
AppSpawnClientSendUserLockStatus(uint32_t userId,bool isLocked)449 int AppSpawnClientSendUserLockStatus(uint32_t userId, bool isLocked)
450 {
451     char lockstatus[USER_LOCK_STATUS_SIZE] = {0};
452     int ret = snprintf_s(lockstatus, USER_LOCK_STATUS_SIZE, USER_LOCK_STATUS_SIZE - 1, "%u:%d", userId, isLocked);
453     APPSPAWN_CHECK(ret > 0, return ret, "Failed to build lockstatus req msg, ret = %{public}d", ret);
454     APPSPAWN_LOGI("Send lockstatus msg to appspawn %{public}s", lockstatus);
455 
456     AppSpawnReqMsgHandle reqHandle;
457     ret = AppSpawnReqMsgCreate(MSG_LOCK_STATUS, "storage_manager", &reqHandle);
458     APPSPAWN_CHECK(ret == 0, return ret, "Failed to create appspawn req msg, ret = %{public}d", ret);
459 
460     ret = AppSpawnReqMsgAddStringInfo(reqHandle, "lockstatus", lockstatus);
461     APPSPAWN_CHECK(ret == 0, AppSpawnReqMsgFree(reqHandle);
462         return ret, "Failed to add lockstatus message, ret=%{public}d", ret);
463 
464     AppSpawnClientHandle clientHandle;
465     ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle);
466     APPSPAWN_CHECK(ret == 0, AppSpawnReqMsgFree(reqHandle);
467         return ret, "Appspawn client failed to init, ret=%{public}d", ret);
468 
469     AppSpawnResult result = {0};
470     ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result);
471     AppSpawnClientDestroy(clientHandle);
472     APPSPAWN_CHECK(ret == 0, return ret, "Send msg to appspawn failed, ret=%{public}d", ret);
473 
474     if (result.result != 0) {
475         APPSPAWN_LOGE("Appspawn failed to handle message, result=%{public}d", result.result);
476         return result.result;
477     }
478     APPSPAWN_LOGI("Send lockstatus msg to appspawn success");
479     return 0;
480 }
481 
SpawnListenFdSet(int fd)482 int SpawnListenFdSet(int fd)
483 {
484     if (fd <= 0) {
485         APPSPAWN_LOGE("Spawn Listen fd set[%{public}d] failed", fd);
486         return APPSPAWN_ARG_INVALID;
487     }
488     g_spawnListenFd = fd;
489     APPSPAWN_LOGI("Spawn Listen fd set[%{public}d] success", fd);
490     return 0;
491 }
492 
NativeSpawnListenFdSet(int fd)493 int NativeSpawnListenFdSet(int fd)
494 {
495     if (fd <= 0) {
496         APPSPAWN_LOGE("NativeSpawn Listen fd set[%{public}d] failed", fd);
497         return APPSPAWN_ARG_INVALID;
498     }
499     g_nativeSpawnListenFd = fd;
500     APPSPAWN_LOGI("NativeSpawn Listen fd set[%{public}d] success", fd);
501     return 0;
502 }
503 
SpawnListenCloseSet(void)504 int SpawnListenCloseSet(void)
505 {
506     pthread_mutex_lock(&g_spawnListenMutex);
507     g_spawnListenStart = false;
508     pthread_mutex_unlock(&g_spawnListenMutex);
509     APPSPAWN_LOGI("Spawn Listen close set success");
510     return 0;
511 }
512 
NativeSpawnListenCloseSet(void)513 int NativeSpawnListenCloseSet(void)
514 {
515     pthread_mutex_lock(&g_nativeSpawnListenMutex);
516     g_nativeSpawnListenStart = false;
517     pthread_mutex_unlock(&g_nativeSpawnListenMutex);
518     APPSPAWN_LOGI("NativeSpawn Listen close set success");
519     return 0;
520 }
521