1d9f0492fSopenharmony_ci/*
2d9f0492fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License.
5d9f0492fSopenharmony_ci * You may obtain a copy of the License at
6d9f0492fSopenharmony_ci *
7d9f0492fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8d9f0492fSopenharmony_ci *
9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and
13d9f0492fSopenharmony_ci * limitations under the License.
14d9f0492fSopenharmony_ci */
15d9f0492fSopenharmony_ci
16d9f0492fSopenharmony_ci#ifndef OHOS_HOOK_MANAGER_H__
17d9f0492fSopenharmony_ci#define OHOS_HOOK_MANAGER_H__
18d9f0492fSopenharmony_ci
19d9f0492fSopenharmony_ci#ifdef __cplusplus
20d9f0492fSopenharmony_ci#if __cplusplus
21d9f0492fSopenharmony_ciextern "C" {
22d9f0492fSopenharmony_ci#endif
23d9f0492fSopenharmony_ci#endif
24d9f0492fSopenharmony_ci
25d9f0492fSopenharmony_ci/**
26d9f0492fSopenharmony_ci * @brief A Hook is a means of executing custom code (function) for existing running code.
27d9f0492fSopenharmony_ci *
28d9f0492fSopenharmony_ci * For a running process, it may consists of several stages.
29d9f0492fSopenharmony_ci * HookManager can help to add hooks to different stages with different priorities.
30d9f0492fSopenharmony_ci * The relationships for HookManager, HookStage and HookItem are shown as below:
31d9f0492fSopenharmony_ci *
32d9f0492fSopenharmony_ci * | ̄ ̄ ̄ ̄ ̄ ̄|
33d9f0492fSopenharmony_ci * |  HookMgr |
34d9f0492fSopenharmony_ci * |__________|
35d9f0492fSopenharmony_ci *      |
36d9f0492fSopenharmony_ci *      |    |▔▔▔▔▔▔▔▔▔▔▔|    |▔▔▔▔▔▔▔▔▔▔▔|
37d9f0492fSopenharmony_ci *      └--->| HookStage |--->| HookStage | ...
38d9f0492fSopenharmony_ci *           |___________|    |___________|
39d9f0492fSopenharmony_ci *               |
40d9f0492fSopenharmony_ci *               |    |▔▔▔▔▔▔▔▔▔▔|    |▔▔▔▔▔▔▔▔▔▔|
41d9f0492fSopenharmony_ci *               └--->| HookItem |--->| HookItem | ...
42d9f0492fSopenharmony_ci *                    |__________|    |__________|
43d9f0492fSopenharmony_ci *
44d9f0492fSopenharmony_ci * Usage example:
45d9f0492fSopenharmony_ci *
46d9f0492fSopenharmony_ci * For an existing module with several stages as below:
47d9f0492fSopenharmony_ci *      ExistingStage1(...);
48d9f0492fSopenharmony_ci *      ExistingStage2(...);
49d9f0492fSopenharmony_ci *      ExistingStage3(...);
50d9f0492fSopenharmony_ci * We can add hooks capability to it as below:
51d9f0492fSopenharmony_ci *      HookMgrExecute(hookMgr, PRE_STAGE1, ...);
52d9f0492fSopenharmony_ci *      ExistingStage1(...);
53d9f0492fSopenharmony_ci *      HookMgrExecute(hookMgr, PRE_STAGE2, ...);
54d9f0492fSopenharmony_ci *      ExistingStage2(...);
55d9f0492fSopenharmony_ci *      HookMgrExecute(hookMgr, PRE_STAGE3, ...);
56d9f0492fSopenharmony_ci *      ExistingStage3(...);
57d9f0492fSopenharmony_ci *      HookMgrExecute(hookMgr, POST_STAGE3, ...);
58d9f0492fSopenharmony_ci *
59d9f0492fSopenharmony_ci * For extending modules, we can add hooks without changing the existing module as below:
60d9f0492fSopenharmony_ci *      int sampleHook() {
61d9f0492fSopenharmony_ci *          ...
62d9f0492fSopenharmony_ci *      }
63d9f0492fSopenharmony_ci *      HookMgrAdd(hookMgr, PRE_STAGE1, priority, sampleHook);
64d9f0492fSopenharmony_ci */
65d9f0492fSopenharmony_ci
66d9f0492fSopenharmony_ci/* Forward declaration for HookManager */
67d9f0492fSopenharmony_citypedef struct tagHOOK_MGR HOOK_MGR;
68d9f0492fSopenharmony_ci
69d9f0492fSopenharmony_ci/* Forward declaration for HOOK_INFO */
70d9f0492fSopenharmony_citypedef struct tagHOOK_INFO HOOK_INFO;
71d9f0492fSopenharmony_ci
72d9f0492fSopenharmony_ci/**
73d9f0492fSopenharmony_ci * @brief Hook function prototype
74d9f0492fSopenharmony_ci *
75d9f0492fSopenharmony_ci * @param hookInfo hook information
76d9f0492fSopenharmony_ci * @param executionContext input arguments for running the hook execution context
77d9f0492fSopenharmony_ci * @return return 0 if succeed; other values if failed.
78d9f0492fSopenharmony_ci */
79d9f0492fSopenharmony_citypedef int (*OhosHook)(const HOOK_INFO *hookInfo, void *executionContext);
80d9f0492fSopenharmony_ci
81d9f0492fSopenharmony_cistruct tagHOOK_INFO {
82d9f0492fSopenharmony_ci    int stage;          /* hook stage */
83d9f0492fSopenharmony_ci    int prio;           /* hook priority */
84d9f0492fSopenharmony_ci    OhosHook hook;      /* hook function */
85d9f0492fSopenharmony_ci    void *hookCookie;   /* hook function cookie, for current hook only */
86d9f0492fSopenharmony_ci};
87d9f0492fSopenharmony_ci
88d9f0492fSopenharmony_ci/**
89d9f0492fSopenharmony_ci * @brief Add a hook function
90d9f0492fSopenharmony_ci *
91d9f0492fSopenharmony_ci * @param hookMgr HookManager handle.
92d9f0492fSopenharmony_ci *                If hookMgr is NULL, it will use default HookManager
93d9f0492fSopenharmony_ci * @param stage hook stage
94d9f0492fSopenharmony_ci * @param prio hook priority
95d9f0492fSopenharmony_ci * @param hook hook function pointer
96d9f0492fSopenharmony_ci * @return return 0 if succeed; other values if failed.
97d9f0492fSopenharmony_ci */
98d9f0492fSopenharmony_ciint HookMgrAdd(HOOK_MGR *hookMgr, int stage, int prio, OhosHook hook);
99d9f0492fSopenharmony_ci
100d9f0492fSopenharmony_ci/**
101d9f0492fSopenharmony_ci * @brief Add a hook function with full hook information
102d9f0492fSopenharmony_ci *
103d9f0492fSopenharmony_ci * @param hookMgr HookManager handle.
104d9f0492fSopenharmony_ci *                If hookMgr is NULL, it will use default HookManager
105d9f0492fSopenharmony_ci * @param hookInfo full hook information
106d9f0492fSopenharmony_ci * @return return 0 if succeed; other values if failed.
107d9f0492fSopenharmony_ci */
108d9f0492fSopenharmony_ciint HookMgrAddEx(HOOK_MGR *hookMgr, const HOOK_INFO *hookInfo);
109d9f0492fSopenharmony_ci
110d9f0492fSopenharmony_ci/**
111d9f0492fSopenharmony_ci * @brief Delete hook function
112d9f0492fSopenharmony_ci *
113d9f0492fSopenharmony_ci * @param hookMgr HookManager handle.
114d9f0492fSopenharmony_ci *                If hookMgr is NULL, it will use default HookManager
115d9f0492fSopenharmony_ci * @param stage hook stage
116d9f0492fSopenharmony_ci * @param hook hook function pointer
117d9f0492fSopenharmony_ci *                If hook is NULL, it will delete all hooks in the stage
118d9f0492fSopenharmony_ci * @return None
119d9f0492fSopenharmony_ci */
120d9f0492fSopenharmony_civoid HookMgrDel(HOOK_MGR *hookMgr, int stage, OhosHook hook);
121d9f0492fSopenharmony_ci
122d9f0492fSopenharmony_ci/**
123d9f0492fSopenharmony_ci * @brief preHook function prototype for HookMgrExecute each hook
124d9f0492fSopenharmony_ci *
125d9f0492fSopenharmony_ci * @param hookInfo HOOK_INFO for the each hook.
126d9f0492fSopenharmony_ci * @param executionContext input arguments for running the hook execution context.
127d9f0492fSopenharmony_ci * @return None
128d9f0492fSopenharmony_ci */
129d9f0492fSopenharmony_citypedef void (*OhosHookPreExecution)(const HOOK_INFO *hookInfo, void *executionContext);
130d9f0492fSopenharmony_ci
131d9f0492fSopenharmony_ci/**
132d9f0492fSopenharmony_ci * @brief postHook function prototype for HookMgrExecute each hook
133d9f0492fSopenharmony_ci *
134d9f0492fSopenharmony_ci * @param hookInfo HOOK_INFO for the each hook.
135d9f0492fSopenharmony_ci * @param executionContext input arguments for running the hook execution context.
136d9f0492fSopenharmony_ci * @param executionRetVal return value for running the hook.
137d9f0492fSopenharmony_ci * @return None
138d9f0492fSopenharmony_ci */
139d9f0492fSopenharmony_citypedef void (*OhosHookPostExecution)(const HOOK_INFO *hookInfo, void *executionContext, int executionRetVal);
140d9f0492fSopenharmony_ci
141d9f0492fSopenharmony_ci/* Executing hooks in descending priority order */
142d9f0492fSopenharmony_ci#define HOOK_EXEC_REVERSE_ORDER     0x01
143d9f0492fSopenharmony_ci/* Stop executing hooks when error returned for each hook */
144d9f0492fSopenharmony_ci#define HOOK_EXEC_EXIT_WHEN_ERROR   0x02
145d9f0492fSopenharmony_ci
146d9f0492fSopenharmony_ci/**
147d9f0492fSopenharmony_ci * @brief Extra execution arguments for HookMgrExecute
148d9f0492fSopenharmony_ci */
149d9f0492fSopenharmony_citypedef struct tagHOOK_EXEC_OPTIONS {
150d9f0492fSopenharmony_ci    /* Executing flags */
151d9f0492fSopenharmony_ci    int flags;
152d9f0492fSopenharmony_ci    /* preHook for before executing each hook */
153d9f0492fSopenharmony_ci    OhosHookPreExecution preHook;
154d9f0492fSopenharmony_ci    /* postHook for before executing each hook */
155d9f0492fSopenharmony_ci    OhosHookPostExecution postHook;
156d9f0492fSopenharmony_ci} HOOK_EXEC_OPTIONS;
157d9f0492fSopenharmony_ci
158d9f0492fSopenharmony_ci/**
159d9f0492fSopenharmony_ci * @brief Executing each hooks in specified stages
160d9f0492fSopenharmony_ci *
161d9f0492fSopenharmony_ci * @param hookMgr HookManager handle.
162d9f0492fSopenharmony_ci *                If hookMgr is NULL, it will use default HookManager
163d9f0492fSopenharmony_ci * @param stage hook stage
164d9f0492fSopenharmony_ci * @param extraArgs HOOK_EXEC_ARGS for executing each hook.
165d9f0492fSopenharmony_ci * @return return 0 if succeed; other values if failed.
166d9f0492fSopenharmony_ci */
167d9f0492fSopenharmony_ciint HookMgrExecute(HOOK_MGR *hookMgr, int stage, void *executionContext, const HOOK_EXEC_OPTIONS *extraArgs);
168d9f0492fSopenharmony_ci
169d9f0492fSopenharmony_ci/**
170d9f0492fSopenharmony_ci * @brief Create a HookManager handle
171d9f0492fSopenharmony_ci *
172d9f0492fSopenharmony_ci * @param name HookManager name.
173d9f0492fSopenharmony_ci * @return return HookManager handle; NULL if failed.
174d9f0492fSopenharmony_ci */
175d9f0492fSopenharmony_ciHOOK_MGR *HookMgrCreate(const char *name);
176d9f0492fSopenharmony_ci
177d9f0492fSopenharmony_ci/**
178d9f0492fSopenharmony_ci * @brief Destroy HookManager
179d9f0492fSopenharmony_ci *
180d9f0492fSopenharmony_ci * @param hookMgr HookManager handle.
181d9f0492fSopenharmony_ci *                If hookMgr is NULL, it will use default HookManager
182d9f0492fSopenharmony_ci * @return None.
183d9f0492fSopenharmony_ci */
184d9f0492fSopenharmony_civoid HookMgrDestroy(HOOK_MGR *hookMgr);
185d9f0492fSopenharmony_ci
186d9f0492fSopenharmony_ci/**
187d9f0492fSopenharmony_ci * @brief Hook traversal function prototype
188d9f0492fSopenharmony_ci *
189d9f0492fSopenharmony_ci * @param hookInfo HOOK_INFO for traversing each hook.
190d9f0492fSopenharmony_ci * @return None
191d9f0492fSopenharmony_ci */
192d9f0492fSopenharmony_citypedef void (*OhosHookTraversal)(const HOOK_INFO *hookInfo, void *traversalCookie);
193d9f0492fSopenharmony_ci
194d9f0492fSopenharmony_ci/**
195d9f0492fSopenharmony_ci * @brief Traversing all hooks in the HookManager
196d9f0492fSopenharmony_ci *
197d9f0492fSopenharmony_ci * @param hookMgr HookManager handle.
198d9f0492fSopenharmony_ci *                If hookMgr is NULL, it will use default HookManager
199d9f0492fSopenharmony_ci * @param traversalCookie traversal cookie.
200d9f0492fSopenharmony_ci * @param traversal traversal function.
201d9f0492fSopenharmony_ci * @return None.
202d9f0492fSopenharmony_ci */
203d9f0492fSopenharmony_civoid HookMgrTraversal(HOOK_MGR *hookMgr, void *traversalCookie, OhosHookTraversal traversal);
204d9f0492fSopenharmony_ci
205d9f0492fSopenharmony_ci/**
206d9f0492fSopenharmony_ci * @brief Get number of hooks in specified stage
207d9f0492fSopenharmony_ci *
208d9f0492fSopenharmony_ci * @param hookMgr HookManager handle.
209d9f0492fSopenharmony_ci *                If hookMgr is NULL, it will use default HookManager
210d9f0492fSopenharmony_ci * @param stage hook stage.
211d9f0492fSopenharmony_ci * @return number of hooks, return 0 if none
212d9f0492fSopenharmony_ci */
213d9f0492fSopenharmony_ciint HookMgrGetHooksCnt(HOOK_MGR *hookMgr, int stage);
214d9f0492fSopenharmony_ci
215d9f0492fSopenharmony_ci/**
216d9f0492fSopenharmony_ci * @brief Get number of stages in the HookManager
217d9f0492fSopenharmony_ci *
218d9f0492fSopenharmony_ci * @param hookMgr HookManager handle.
219d9f0492fSopenharmony_ci *                If hookMgr is NULL, it will use default HookManager
220d9f0492fSopenharmony_ci * @return number of stages, return 0 if none
221d9f0492fSopenharmony_ci */
222d9f0492fSopenharmony_ciint HookMgrGetStagesCnt(HOOK_MGR *hookMgr);
223d9f0492fSopenharmony_ci
224d9f0492fSopenharmony_ci#define HOOK_OK = 0
225d9f0492fSopenharmony_ci#define ERR_NO_HOOK_STAGE (-1000)
226d9f0492fSopenharmony_ci#ifdef __cplusplus
227d9f0492fSopenharmony_ci#if __cplusplus
228d9f0492fSopenharmony_ci}
229d9f0492fSopenharmony_ci#endif
230d9f0492fSopenharmony_ci#endif
231d9f0492fSopenharmony_ci#endif
232