• 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 #ifndef APPSPAWN_MANAGER_H
17 #define APPSPAWN_MANAGER_H
18 
19 #include <limits.h>
20 #include <stdbool.h>
21 #include <unistd.h>
22 
23 #include "appspawn.h"
24 #include "appspawn_hook.h"
25 #include "appspawn_msg.h"
26 #include "appspawn_server.h"
27 #include "appspawn_utils.h"
28 #include "list.h"
29 #include "loop_event.h"
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 #define MODE_ID_INDEX 1
36 #define MODE_VALUE_INDEX 2
37 #define FD_ID_INDEX 3
38 #define FD_VALUE_INDEX 4
39 #define FLAGS_VALUE_INDEX 5
40 #define SHM_SIZE_INDEX 6
41 #define PARAM_ID_INDEX 7
42 #define PARAM_VALUE_INDEX 8
43 #define CLIENT_ID_INDEX 9
44 #define ARG_NULL 10
45 
46 #define MAX_DIED_PROCESS_COUNT 5
47 
48 #define INVALID_OFFSET 0xffffffff
49 
50 #define APP_STATE_IDLE 1
51 #define APP_STATE_SPAWNING 2
52 #define APPSPAWN_MAX_TIME 3000000
53 
54 #define APPSPAWN_INLINE __attribute__((always_inline)) inline
55 
56 typedef struct AppSpawnContent AppSpawnContent;
57 typedef struct AppSpawnClient AppSpawnClient;
58 typedef struct TagAppSpawnConnection AppSpawnConnection;
59 
60 typedef struct TagAppSpawnMsgNode {
61     AppSpawnConnection *connection;
62     AppSpawnMsg msgHeader;
63     uint32_t tlvCount;
64     uint32_t *tlvOffset;  // 记录属性的在msg中的偏移,不完全拷贝试消息完整
65     uint8_t *buffer;
66 } AppSpawnMsgNode;
67 
68 typedef struct {
69     int32_t fd[2];  // 2 fd count
70     WatcherHandle watcherHandle;
71     WatcherHandle pidFdWatcherHandle;
72     TimerHandle timer;
73     char *childMsg;
74     uint32_t msgSize;
75     char *coldRunPath;
76 } AppSpawnForkCtx;
77 
78 typedef struct TagAppSpawningCtx {
79     AppSpawnClient client;
80     struct ListNode node;
81     AppSpawnForkCtx forkCtx;
82     AppSpawnMsgNode *message;
83     bool isPrefork;
84     pid_t pid;
85     int state;
86     struct timespec spawnStart;
87 } AppSpawningCtx;
88 
89 typedef struct TagAppSpawnedProcess {
90     struct ListNode node;
91     uid_t uid;
92     pid_t pid;
93     uint32_t max;
94     int exitStatus;
95     struct timespec spawnStart;
96     struct timespec spawnEnd;
97 #ifdef DEBUG_BEGETCTL_BOOT
98     AppSpawnMsgNode *message;
99 #endif
100     char name[0];
101 } AppSpawnedProcess;
102 
103 typedef struct SpawnTime {
104     int minAppspawnTime;
105     int maxAppspawnTime;
106 } SpawnTime;
107 
108 typedef struct TagAppSpawnMgr {
109     AppSpawnContent content;
110     TaskHandle server;
111     SignalHandle sigHandler;
112     pid_t servicePid;
113     struct ListNode appQueue;  // save app pid and name
114     uint32_t diedAppCount;
115     uint32_t flags;
116     struct ListNode diedQueue;      // save app pid and name
117     struct ListNode appSpawnQueue;  // save app pid and name
118     struct timespec perLoadStart;
119     struct timespec perLoadEnd;
120     struct ListNode extData;
121     struct SpawnTime spawnTime;
122 } AppSpawnMgr;
123 
124 /**
125  * @brief App Spawn Mgr object op
126  *
127  */
128 AppSpawnMgr *CreateAppSpawnMgr(int mode);
129 AppSpawnMgr *GetAppSpawnMgr(void);
130 void DeleteAppSpawnMgr(AppSpawnMgr *mgr);
131 AppSpawnContent *GetAppSpawnContent(void);
132 
133 /**
134  * @brief 孵化成功后进程或者app实例的操作
135  *
136  */
137 typedef void (*AppTraversal)(const AppSpawnMgr *mgr, AppSpawnedProcess *appInfo, void *data);
138 void TraversalSpawnedProcess(AppTraversal traversal, void *data);
139 AppSpawnedProcess *AddSpawnedProcess(pid_t pid, const char *processName);
140 AppSpawnedProcess *GetSpawnedProcess(pid_t pid);
141 AppSpawnedProcess *GetSpawnedProcessByName(const char *name);
142 void TerminateSpawnedProcess(AppSpawnedProcess *node);
143 
144 /**
145  * @brief 孵化过程中的ctx对象的操作
146  *
147  */
148 typedef void (*ProcessTraversal)(const AppSpawnMgr *mgr, AppSpawningCtx *ctx, void *data);
149 void AppSpawningCtxTraversal(ProcessTraversal traversal, void *data);
150 AppSpawningCtx *GetAppSpawningCtxByPid(pid_t pid);
151 AppSpawningCtx *CreateAppSpawningCtx();
152 void DeleteAppSpawningCtx(AppSpawningCtx *property);
153 int KillAndWaitStatus(pid_t pid, int sig, int *exitStatus);
154 
155 /**
156  * @brief 消息解析、处理
157  *
158  */
159 void ProcessAppSpawnDumpMsg(const AppSpawnMsgNode *message);
160 int ProcessTerminationStatusMsg(const AppSpawnMsgNode *message, AppSpawnResult *result);
161 
162 AppSpawnMsgNode *CreateAppSpawnMsg(void);
163 void DeleteAppSpawnMsg(AppSpawnMsgNode *msgNode);
164 int CheckAppSpawnMsg(const AppSpawnMsgNode *message);
165 int DecodeAppSpawnMsg(AppSpawnMsgNode *message);
166 int GetAppSpawnMsgFromBuffer(const uint8_t *buffer, uint32_t bufferLen,
167     AppSpawnMsgNode **outMsg, uint32_t *msgRecvLen, uint32_t *reminder);
168 AppSpawnMsgNode *RebuildAppSpawnMsgNode(AppSpawnMsgNode *message, AppSpawnedProcess *appInfo);
169 
170 /**
171  * @brief 消息内容操作接口
172  *
173  */
174 void DumpAppSpawnMsg(const AppSpawnMsgNode *message);
175 void *GetAppSpawnMsgInfo(const AppSpawnMsgNode *message, int type);
176 void *GetAppSpawnMsgExtInfo(const AppSpawnMsgNode *message, const char *name, uint32_t *len);
177 int CheckAppSpawnMsgFlag(const AppSpawnMsgNode *message, uint32_t type, uint32_t index);
178 int SetAppSpawnMsgFlag(const AppSpawnMsgNode *message, uint32_t type, uint32_t index);
179 
IsSpawnServer(const AppSpawnMgr * content)180 APPSPAWN_INLINE int IsSpawnServer(const AppSpawnMgr *content)
181 {
182     return (content != NULL) && (content->servicePid == getpid());
183 }
184 
IsAppSpawnMode(const AppSpawnMgr * content)185 APPSPAWN_INLINE int IsAppSpawnMode(const AppSpawnMgr *content)
186 {
187     return (content != NULL) &&
188         (content->content.mode == MODE_FOR_APP_SPAWN || content->content.mode == MODE_FOR_APP_COLD_RUN);
189 }
190 
IsNWebSpawnMode(const AppSpawnMgr * content)191 APPSPAWN_INLINE int IsNWebSpawnMode(const AppSpawnMgr *content)
192 {
193     return (content != NULL) &&
194         (content->content.mode == MODE_FOR_NWEB_SPAWN || content->content.mode == MODE_FOR_NWEB_COLD_RUN);
195 }
196 
IsColdRunMode(const AppSpawnMgr * content)197 APPSPAWN_INLINE int IsColdRunMode(const AppSpawnMgr *content)
198 {
199     return (content != NULL) &&
200         (content->content.mode == MODE_FOR_APP_COLD_RUN || content->content.mode == MODE_FOR_NWEB_COLD_RUN);
201 }
202 
IsDeveloperModeOn(const AppSpawningCtx * property)203 APPSPAWN_INLINE int IsDeveloperModeOn(const AppSpawningCtx *property)
204 {
205     return (property != NULL && ((property->client.flags & APP_DEVELOPER_MODE) == APP_DEVELOPER_MODE));
206 }
207 
IsJitFortModeOn(const AppSpawningCtx * property)208 APPSPAWN_INLINE int IsJitFortModeOn(const AppSpawningCtx *property)
209 {
210     return (property != NULL && ((property->client.flags & APP_JITFORT_MODE) == APP_JITFORT_MODE));
211 }
212 
GetAppSpawnMsgType(const AppSpawningCtx * appProperty)213 APPSPAWN_INLINE int GetAppSpawnMsgType(const AppSpawningCtx *appProperty)
214 {
215     return (appProperty != NULL && appProperty->message != NULL) ?
216         appProperty->message->msgHeader.msgType : MAX_TYPE_INVALID;
217 }
218 
GetProcessName(const AppSpawningCtx * property)219 APPSPAWN_INLINE const char *GetProcessName(const AppSpawningCtx *property)
220 {
221     if (property == NULL || property->message == NULL) {
222         return NULL;
223     }
224     return property->message->msgHeader.processName;
225 }
226 
GetBundleName(const AppSpawningCtx * property)227 APPSPAWN_INLINE const char *GetBundleName(const AppSpawningCtx *property)
228 {
229     if (property == NULL || property->message == NULL) {
230         return NULL;
231     }
232     AppSpawnMsgBundleInfo *info = (AppSpawnMsgBundleInfo *)GetAppSpawnMsgInfo(property->message, TLV_BUNDLE_INFO);
233     if (info != NULL) {
234         return info->bundleName;
235     }
236     return NULL;
237 }
238 
GetAppProperty(const AppSpawningCtx * property,uint32_t type)239 APPSPAWN_INLINE void *GetAppProperty(const AppSpawningCtx *property, uint32_t type)
240 {
241     APPSPAWN_CHECK(property != NULL && property->message != NULL,
242         return NULL, "Invalid property for type %{public}u", type);
243     return GetAppSpawnMsgInfo(property->message, type);
244 }
245 
GetAppPropertyExt(const AppSpawningCtx * property,const char * name,uint32_t * len)246 APPSPAWN_INLINE void *GetAppPropertyExt(const AppSpawningCtx *property, const char *name, uint32_t *len)
247 {
248     APPSPAWN_CHECK(name != NULL, return NULL, "Invalid name ");
249     APPSPAWN_CHECK(property != NULL && property->message != NULL,
250         return NULL, "Invalid property for name %{public}s", name);
251     return GetAppSpawnMsgExtInfo(property->message, name, len);
252 }
253 
CheckAppMsgFlagsSet(const AppSpawningCtx * property,uint32_t index)254 APPSPAWN_INLINE int CheckAppMsgFlagsSet(const AppSpawningCtx *property, uint32_t index)
255 {
256     APPSPAWN_CHECK(property != NULL && property->message != NULL,
257         return 0, "Invalid property for name %{public}u", TLV_MSG_FLAGS);
258     return CheckAppSpawnMsgFlag(property->message, TLV_MSG_FLAGS, index);
259 }
260 
CheckAppPermissionFlagSet(const AppSpawningCtx * property,uint32_t index)261 APPSPAWN_INLINE int CheckAppPermissionFlagSet(const AppSpawningCtx *property, uint32_t index)
262 {
263     APPSPAWN_CHECK(property != NULL && property->message != NULL,
264         return 0, "Invalid property for name %{public}u", TLV_PERMISSION);
265     return CheckAppSpawnMsgFlag(property->message, TLV_PERMISSION, index);
266 }
267 
SetAppPermissionFlags(const AppSpawningCtx * property,uint32_t index)268 APPSPAWN_INLINE int SetAppPermissionFlags(const AppSpawningCtx *property, uint32_t index)
269 {
270     APPSPAWN_CHECK(property != NULL && property->message != NULL,
271         return -1, "Invalid property for name %{public}u", TLV_PERMISSION);
272     return SetAppSpawnMsgFlag(property->message, TLV_PERMISSION, index);
273 }
274 
IsIsolatedNativeSpawnMode(const AppSpawnMgr * content,const AppSpawningCtx * property)275 APPSPAWN_INLINE int IsIsolatedNativeSpawnMode(const AppSpawnMgr *content, const AppSpawningCtx *property)
276 {
277     return (content != NULL) && (content->content.mode == MODE_FOR_NATIVE_SPAWN) &&
278         CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE);
279 }
280 
281 #ifdef __cplusplus
282 }
283 #endif
284 #endif  // APPSPAWN_MANAGER_H
285