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_HOOK_H
17#define APPSPAWN_HOOK_H
18#include <stdint.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <sys/stat.h>
22#include <sys/types.h>
23
24#include "appspawn_msg.h"
25#include "hookmgr.h"
26#include "list.h"
27
28#ifdef __cplusplus
29#if __cplusplus
30extern "C" {
31#endif
32#endif
33
34typedef struct TagAppSpawnMgr AppSpawnMgr;
35typedef struct TagAppSpawningCtx AppSpawningCtx;
36typedef struct AppSpawnContent AppSpawnContent;
37typedef struct AppSpawnClient AppSpawnClient;
38typedef struct TagAppSpawnedProcess AppSpawnedProcessInfo;
39
40typedef enum {
41    EXT_DATA_SANDBOX,
42    EXT_DATA_NAMESPACE,
43    EXT_DATA_ISOLATED_SANDBOX,
44} ExtDataType;
45
46struct TagAppSpawnExtData;
47typedef void (*AppSpawnExtDataFree)(struct TagAppSpawnExtData *data);
48typedef void (*AppSpawnExtDataDump)(struct TagAppSpawnExtData *data);
49typedef struct TagAppSpawnExtData {
50    ListNode node;
51    uint32_t dataId;
52    AppSpawnExtDataFree freeNode;
53    AppSpawnExtDataDump dumpNode;
54} AppSpawnExtData;
55
56typedef enum TagAppSpawnHookStage {
57    // 服务状态处理
58    STAGE_SERVER_PRELOAD  = 10,
59    STAGE_SERVER_EXIT,
60    // 应用状态处理
61    STAGE_SERVER_APP_ADD,
62    STAGE_SERVER_APP_DIED,
63    // run before fork
64    STAGE_PARENT_PRE_FORK = 20,
65    STAGE_PARENT_POST_FORK = 21,
66    STAGE_PARENT_PRE_RELY = 22,
67    STAGE_PARENT_POST_RELY = 23,
68
69    // run in child process
70    STAGE_CHILD_PRE_COLDBOOT = 30, // clear env, set token before cold boot
71    STAGE_CHILD_EXECUTE,
72    STAGE_CHILD_PRE_RELY,
73    STAGE_CHILD_POST_RELY,
74    STAGE_CHILD_PRE_RUN,
75    STAGE_MAX
76} AppSpawnHookStage;
77
78typedef enum TagAppSpawnHookPrio {
79    HOOK_PRIO_HIGHEST = 1000,
80    HOOK_PRIO_COMMON = 2000,
81    HOOK_PRIO_SANDBOX = 3000,
82    HOOK_PRIO_PROPERTY = 4000,
83    HOOK_PRIO_LOWEST = 5000,
84} AppSpawnHookPrio;
85
86/**
87 * @brief 预加载处理函数
88 *
89 * @param content appspawn appspawn管理数据
90 * @return int
91 */
92typedef int (*ServerStageHook)(AppSpawnMgr *content);
93
94/**
95 * @brief 应用孵化各阶段注册函数
96 *
97 * @param content appspawn appspawn管理数据
98 * @param property 业务孵化数据
99 * @return int
100 */
101typedef int (*AppSpawnHook)(AppSpawnMgr *content, AppSpawningCtx *property);
102
103/**
104 * @brief 业务进程变化注册函数
105 *
106 * @param content appspawn appspawn管理数据
107 * @param appInfo 业务进程信息
108 * @return int
109 */
110typedef int (*ProcessChangeHook)(const AppSpawnMgr *content, const AppSpawnedProcessInfo *appInfo);
111
112/**
113 * @brief 添加服务阶段的处理函数
114 *
115 * @param stage 阶段信息
116 * @param prio 优先级
117 * @param hook 预加载处理函数
118 * @return int
119 */
120int AddServerStageHook(AppSpawnHookStage stage, int prio, ServerStageHook hook);
121
122/**
123 * @brief 添加预加载处理函数
124 *
125 * @param prio 优先级
126 * @param hook 预加载处理函数
127 * @return int
128 */
129__attribute__((always_inline)) inline int AddPreloadHook(int prio, ServerStageHook hook)
130{
131    return AddServerStageHook(STAGE_SERVER_PRELOAD, prio, hook);
132}
133
134/**
135 * @brief 按阶段添加应用孵化处理函数
136 *
137 * @param stage 阶段信息
138 * @param prio 优先级
139 * @param hook 应用孵化阶段处理函数
140 * @return int
141 */
142int AddAppSpawnHook(AppSpawnHookStage stage, int prio, AppSpawnHook hook);
143
144/**
145 * @brief 添加业务进程处理函数
146 *
147 * @param stage 阶段信息
148 * @param prio 优先级
149 * @param hook 业务进程变化处理函数
150 * @return int
151 */
152int AddProcessMgrHook(AppSpawnHookStage stage, int prio, ProcessChangeHook hook);
153
154typedef int (*ChildLoop)(AppSpawnContent *content, AppSpawnClient *client);
155/**
156 * @brief 注册子进程run函数
157 *
158 * @param content
159 * @param loop
160 */
161void RegChildLooper(AppSpawnContent *content, ChildLoop loop);
162
163/**
164 * @brief 按mode创建文件件
165 *
166 * @param path 路径
167 * @param mode mode
168 * @param lastPath 是否文件名
169 * @return int 结果
170 */
171int MakeDirRec(const char *path, mode_t mode, int lastPath);
172__attribute__((always_inline)) inline int CreateSandboxDir(const char *path, mode_t mode)
173{
174    return MakeDirRec(path, mode, 1);
175}
176
177// 扩展变量
178typedef struct TagSandboxContext SandboxContext;
179typedef struct TagVarExtraData VarExtraData;
180typedef int (*ReplaceVarHandler)(const SandboxContext *context,
181    const char *buffer, uint32_t bufferLen, uint32_t *realLen, const VarExtraData *extraData);
182/**
183 * @brief 注册变量替换处理函数
184 *
185 * @param name 变量名
186 * @param handler 处理函数
187 * @return int
188 */
189int AddVariableReplaceHandler(const char *name, ReplaceVarHandler handler);
190
191typedef struct TagAppSpawnSandboxCfg AppSpawnSandboxCfg;
192typedef int (*ProcessExpandSandboxCfg)(const SandboxContext *context,
193    const AppSpawnSandboxCfg *appSandBox, const char *name);
194#define EXPAND_CFG_HANDLER_PRIO_START 3
195
196/**
197 * @brief 注册扩展属性处理函数
198 *
199 * @param name 扩展变量名
200 * @param handleExpandCfg  处理函数
201 * @return int
202 */
203int RegisterExpandSandboxCfgHandler(const char *name, int prio, ProcessExpandSandboxCfg handleExpandCfg);
204
205#ifndef MODULE_DESTRUCTOR
206#define MODULE_CONSTRUCTOR(void) static void _init(void) __attribute__((constructor)); static void _init(void)
207#define MODULE_DESTRUCTOR(void) static void _destroy(void) __attribute__((destructor)); static void _destroy(void)
208#endif
209
210#ifdef __cplusplus
211#if __cplusplus
212}
213#endif
214#endif
215#endif
216