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 32extern "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 56typedef struct AppSpawnContent AppSpawnContent; 57typedef struct AppSpawnClient AppSpawnClient; 58typedef struct TagAppSpawnConnection AppSpawnConnection; 59 60typedef struct TagAppSpawnMsgNode { 61 AppSpawnConnection *connection; 62 AppSpawnMsg msgHeader; 63 uint32_t tlvCount; 64 uint32_t *tlvOffset; // 记录属性的在msg中的偏移,不完全拷贝试消息完整 65 uint8_t *buffer; 66} AppSpawnMsgNode; 67 68typedef 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 78typedef 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 89typedef 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 bool isDebuggable; 101 char name[0]; 102} AppSpawnedProcess; 103 104typedef struct SpawnTime { 105 int minAppspawnTime; 106 int maxAppspawnTime; 107} SpawnTime; 108 109typedef struct TagAppSpawnMgr { 110 AppSpawnContent content; 111 TaskHandle server; 112 SignalHandle sigHandler; 113 pid_t servicePid; 114 struct ListNode appQueue; // save app pid and name 115 uint32_t diedAppCount; 116 uint32_t flags; 117 struct ListNode diedQueue; // save app pid and name 118 struct ListNode appSpawnQueue; // save app pid and name 119 struct timespec perLoadStart; 120 struct timespec perLoadEnd; 121 struct ListNode extData; 122 struct SpawnTime spawnTime; 123} AppSpawnMgr; 124 125/** 126 * @brief App Spawn Mgr object op 127 * 128 */ 129AppSpawnMgr *CreateAppSpawnMgr(int mode); 130AppSpawnMgr *GetAppSpawnMgr(void); 131void DeleteAppSpawnMgr(AppSpawnMgr *mgr); 132AppSpawnContent *GetAppSpawnContent(void); 133 134/** 135 * @brief 孵化成功后进程或者app实例的操作 136 * 137 */ 138typedef void (*AppTraversal)(const AppSpawnMgr *mgr, AppSpawnedProcess *appInfo, void *data); 139void TraversalSpawnedProcess(AppTraversal traversal, void *data); 140AppSpawnedProcess *AddSpawnedProcess(pid_t pid, const char *processName, bool isDebuggable); 141AppSpawnedProcess *GetSpawnedProcess(pid_t pid); 142AppSpawnedProcess *GetSpawnedProcessByName(const char *name); 143void TerminateSpawnedProcess(AppSpawnedProcess *node); 144 145/** 146 * @brief 孵化过程中的ctx对象的操作 147 * 148 */ 149typedef void (*ProcessTraversal)(const AppSpawnMgr *mgr, AppSpawningCtx *ctx, void *data); 150void AppSpawningCtxTraversal(ProcessTraversal traversal, void *data); 151AppSpawningCtx *GetAppSpawningCtxByPid(pid_t pid); 152AppSpawningCtx *CreateAppSpawningCtx(); 153void DeleteAppSpawningCtx(AppSpawningCtx *property); 154int KillAndWaitStatus(pid_t pid, int sig, int *exitStatus); 155 156/** 157 * @brief 消息解析、处理 158 * 159 */ 160void ProcessAppSpawnDumpMsg(const AppSpawnMsgNode *message); 161int ProcessTerminationStatusMsg(const AppSpawnMsgNode *message, AppSpawnResult *result); 162 163AppSpawnMsgNode *CreateAppSpawnMsg(void); 164void DeleteAppSpawnMsg(AppSpawnMsgNode *msgNode); 165int CheckAppSpawnMsg(const AppSpawnMsgNode *message); 166int DecodeAppSpawnMsg(AppSpawnMsgNode *message); 167int GetAppSpawnMsgFromBuffer(const uint8_t *buffer, uint32_t bufferLen, 168 AppSpawnMsgNode **outMsg, uint32_t *msgRecvLen, uint32_t *reminder); 169AppSpawnMsgNode *RebuildAppSpawnMsgNode(AppSpawnMsgNode *message, AppSpawnedProcess *appInfo); 170 171/** 172 * @brief 消息内容操作接口 173 * 174 */ 175void DumpAppSpawnMsg(const AppSpawnMsgNode *message); 176void *GetAppSpawnMsgInfo(const AppSpawnMsgNode *message, int type); 177void *GetAppSpawnMsgExtInfo(const AppSpawnMsgNode *message, const char *name, uint32_t *len); 178int CheckAppSpawnMsgFlag(const AppSpawnMsgNode *message, uint32_t type, uint32_t index); 179int SetAppSpawnMsgFlag(const AppSpawnMsgNode *message, uint32_t type, uint32_t index); 180 181APPSPAWN_INLINE int IsSpawnServer(const AppSpawnMgr *content) 182{ 183 return (content != NULL) && (content->servicePid == getpid()); 184} 185 186APPSPAWN_INLINE int IsNWebSpawnMode(const AppSpawnMgr *content) 187{ 188 return (content != NULL) && 189 (content->content.mode == MODE_FOR_NWEB_SPAWN || content->content.mode == MODE_FOR_NWEB_COLD_RUN); 190} 191 192APPSPAWN_INLINE int IsColdRunMode(const AppSpawnMgr *content) 193{ 194 return (content != NULL) && 195 (content->content.mode == MODE_FOR_APP_COLD_RUN || content->content.mode == MODE_FOR_NWEB_COLD_RUN); 196} 197 198APPSPAWN_INLINE int IsDeveloperModeOn(const AppSpawningCtx *property) 199{ 200 return (property != NULL && ((property->client.flags & APP_DEVELOPER_MODE) == APP_DEVELOPER_MODE)); 201} 202 203APPSPAWN_INLINE int IsJitFortModeOn(const AppSpawningCtx *property) 204{ 205 return (property != NULL && ((property->client.flags & APP_JITFORT_MODE) == APP_JITFORT_MODE)); 206} 207 208APPSPAWN_INLINE int GetAppSpawnMsgType(const AppSpawningCtx *appProperty) 209{ 210 return (appProperty != NULL && appProperty->message != NULL) ? 211 appProperty->message->msgHeader.msgType : MAX_TYPE_INVALID; 212} 213 214APPSPAWN_INLINE const char *GetProcessName(const AppSpawningCtx *property) 215{ 216 if (property == NULL || property->message == NULL) { 217 return NULL; 218 } 219 return property->message->msgHeader.processName; 220} 221 222APPSPAWN_INLINE const char *GetBundleName(const AppSpawningCtx *property) 223{ 224 if (property == NULL || property->message == NULL) { 225 return NULL; 226 } 227 AppSpawnMsgBundleInfo *info = (AppSpawnMsgBundleInfo *)GetAppSpawnMsgInfo(property->message, TLV_BUNDLE_INFO); 228 if (info != NULL) { 229 return info->bundleName; 230 } 231 return NULL; 232} 233 234APPSPAWN_INLINE void *GetAppProperty(const AppSpawningCtx *property, uint32_t type) 235{ 236 APPSPAWN_CHECK(property != NULL && property->message != NULL, 237 return NULL, "Invalid property for type %{public}u", type); 238 return GetAppSpawnMsgInfo(property->message, type); 239} 240 241APPSPAWN_INLINE void *GetAppPropertyExt(const AppSpawningCtx *property, const char *name, uint32_t *len) 242{ 243 APPSPAWN_CHECK(name != NULL, return NULL, "Invalid name "); 244 APPSPAWN_CHECK(property != NULL && property->message != NULL, 245 return NULL, "Invalid property for name %{public}s", name); 246 return GetAppSpawnMsgExtInfo(property->message, name, len); 247} 248 249APPSPAWN_INLINE int CheckAppMsgFlagsSet(const AppSpawningCtx *property, uint32_t index) 250{ 251 APPSPAWN_CHECK(property != NULL && property->message != NULL, 252 return 0, "Invalid property for name %{public}u", TLV_MSG_FLAGS); 253 return CheckAppSpawnMsgFlag(property->message, TLV_MSG_FLAGS, index); 254} 255 256APPSPAWN_INLINE int CheckAppPermissionFlagSet(const AppSpawningCtx *property, uint32_t index) 257{ 258 APPSPAWN_CHECK(property != NULL && property->message != NULL, 259 return 0, "Invalid property for name %{public}u", TLV_PERMISSION); 260 return CheckAppSpawnMsgFlag(property->message, TLV_PERMISSION, index); 261} 262 263APPSPAWN_INLINE int SetAppPermissionFlags(const AppSpawningCtx *property, uint32_t index) 264{ 265 APPSPAWN_CHECK(property != NULL && property->message != NULL, 266 return -1, "Invalid property for name %{public}u", TLV_PERMISSION); 267 return SetAppSpawnMsgFlag(property->message, TLV_PERMISSION, index); 268} 269 270APPSPAWN_INLINE int IsIsolatedNativeSpawnMode(const AppSpawnMgr *content, const AppSpawningCtx *property) 271{ 272 return (content != NULL) && (content->content.mode == MODE_FOR_NATIVE_SPAWN) && 273 CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE); 274} 275 276#ifdef __cplusplus 277} 278#endif 279#endif // APPSPAWN_MANAGER_H 280