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