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