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_TEST_HELPER_H
17 #define APPSPAWN_TEST_HELPER_H
18 
19 #include <atomic>
20 #include <cstdint>
21 #include <cstdio>
22 #include <cstdlib>
23 #include <cstring>
24 #include <functional>
25 #include <mutex>
26 #include <pthread.h>
27 #include <string>
28 #include <unistd.h>
29 #include <vector>
30 
31 #include "appspawn.h"
32 #include "appspawn_client.h"
33 #include "appspawn_hook.h"
34 #include "appspawn_server.h"
35 #include "appspawn_service.h"
36 #include "appspawn_utils.h"
37 #include "list.h"
38 #include "loop_event.h"
39 
40 #include "app_spawn_stub.h"
41 
42 namespace OHOS {
43 typedef struct {
44     int argc;
45     char *argv[0];
46 } CmdArgs;
47 
48 typedef struct AppSpawnClient AppSpawnClient;
49 struct TestConnection;
50 class LocalTestServer;
51 using RecvMsgProcess = std::function<void(struct TestConnection *connection, const uint8_t *buffer, uint32_t buffLen)>;
52 using AddTlvFunction = std::function<int(uint8_t *buffer, uint32_t bufferLen, uint32_t &realLen, uint32_t &tlvCount)>;
53 
54 class AppSpawnTestHelper {
55 public:
AppSpawnTestHelper()56     AppSpawnTestHelper()
57     {
58         SetDefaultTestData();
59     }
~AppSpawnTestHelper()60     ~AppSpawnTestHelper()
61     {
62         if (fdArg >= 0) {
63             APPSPAWN_LOGE("destory test helper close fd %d", fdArg);
64             close(fdArg);
65         }
66     }
67 
68     void SetDefaultTestData();
GetDefaultTestAppBundleName()69     const char *GetDefaultTestAppBundleName()
70     {
71         return processName_.c_str();
72     }
GetTestUid()73     uid_t GetTestUid()
74     {
75         return defaultTestUid_;
76     }
GetTestGid()77     gid_t GetTestGid()
78     {
79         return defaultTestGid_;
80     }
GetTestGidGroup()81     gid_t GetTestGidGroup()
82     {
83         return defaultTestGidGroup_;
84     }
GetTestBundleIndex()85     int32_t GetTestBundleIndex()
86     {
87         return defaultTestBundleIndex_;
88     }
89 
SetTestMsgFlags(uint32_t flags)90     void SetTestMsgFlags(uint32_t flags)
91     {
92         defaultMsgFlags_ = flags;
93     }
SetTestApl(const char * apl)94     void SetTestApl(const char *apl)
95     {
96         defaultApl_ = std::string(apl);
97     }
SetTestUid(uid_t uid)98     void SetTestUid(uid_t uid)
99     {
100         defaultTestUid_ = uid;
101     }
SetTestGid(gid_t gid)102     void SetTestGid(gid_t gid)
103     {
104         defaultTestGid_ = gid;
105     }
SetProcessName(const char * name)106     void SetProcessName(const char *name)
107     {
108         processName_ = std::string(name);
109     }
110 
111     AppSpawnReqMsgHandle CreateMsg(AppSpawnClientHandle handle, uint32_t msgType = MSG_APP_SPAWN, int base = 0);
112     AppSpawningCtx *GetAppProperty(AppSpawnClientHandle handle, AppSpawnReqMsgHandle reqHandle);
113     int AddDacInfo(AppSpawnReqMsgHandle &reqHandle);
114     int AddFdInfo(AppSpawnReqMsgHandle &reqHandle);
115     int CreateSocket(int type = 0);
116     int CreateSendMsg(std::vector<uint8_t> &buffer, uint32_t msgType, uint32_t &msgLen,
117         const std::vector<AddTlvFunction> &addTlvFuncs);
GetPermissions()118     const std::vector<const char *> &GetPermissions()
119     {
120         return permissions_;
121     }
122 
123     static int AddBaseTlv(uint8_t *buffer, uint32_t bufferLen, uint32_t &realLen, uint32_t &tlvCount);
124     static uint32_t GenRandom(void);
125     static CmdArgs *ToCmdList(const char *cmd);
126     static AppSpawnContent *StartSpawnServer(std::string &cmd, CmdArgs *&args);
127 
AppSpawnReqMsgSetFlags(AppSpawnReqMsgHandle reqHandle,uint32_t tlv,uint32_t flags)128     int AppSpawnReqMsgSetFlags(AppSpawnReqMsgHandle reqHandle, uint32_t tlv, uint32_t flags)
129     {
130         AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle;
131         APPSPAWN_CHECK_ONLY_EXPER(reqNode != nullptr, return APPSPAWN_ARG_INVALID);
132         if (tlv == TLV_MSG_FLAGS) {
133             *(uint32_t *)reqNode->msgFlags->flags = flags;
134         } else if (tlv == TLV_PERMISSION) {
135             *(uint32_t *)reqNode->permissionFlags->flags = flags;
136         }
137         return 0;
138     }
139 private:
140     AppSpawnMsgNode *CreateAppSpawnMsg(AppSpawnMsg *msg);
141 
142     std::string processName_ = {};
143     std::string defaultApl_ = "system_core";
144     uid_t defaultTestUid_;
145     gid_t defaultTestGid_;
146     gid_t defaultTestGidGroup_;
147     int32_t defaultTestBundleIndex_;
148     uint32_t defaultMsgFlags_ = 0;
149     int fdArg = -1;
150     std::vector<const char *> permissions_ = {
151         const_cast<char *>("ohos.permission.READ_IMAGEVIDEO"),
152         const_cast<char *>("ohos.permission.FILE_CROSS_APP"),
153         const_cast<char *>("ohos.permission.ACTIVATE_THEME_PACKAGE"),
154         const_cast<char *>("ohos.permission.GET_WALLPAPER"),
155         const_cast<char *>("ohos.permission.ACCESS_DATA"),
156         const_cast<char *>("ohos.permission.ACCESS_DEV_FUSE"),
157         const_cast<char *>("ohos.permission.FILE_ACCESS_MANAGER")
158     };
159 };
160 
161 class AppSpawnTestServer : public AppSpawnTestHelper {
162 public:
AppSpawnTestServer(const char * cmd,bool testServer)163     explicit AppSpawnTestServer(const char *cmd, bool testServer)
164         : AppSpawnTestHelper(), serviceCmd_(cmd), testServer_(testServer), protectTime_(defaultProtectTime)
165     {
166         serverId_ = AppSpawnTestServer::serverId;
167         AppSpawnTestServer::serverId++;
168     }
169 
AppSpawnTestServer(const char * cmd)170     explicit AppSpawnTestServer(const char *cmd)
171         : AppSpawnTestHelper(), serviceCmd_(cmd), testServer_(true), protectTime_(defaultProtectTime)
172     {
173         serverId_ = AppSpawnTestServer::serverId;
174         AppSpawnTestServer::serverId++;
175     }
176     ~AppSpawnTestServer();
177 
178     void Start(void);
179     void Start(RecvMsgProcess process, uint32_t time = defaultProtectTime);
180     void Stop();
181     void ServiceThread();
182     void KillNWebSpawnServer();
183 
184     static const uint32_t defaultProtectTime;
185 private:
186     void CloseCheckHandler(void);
187     void StartCheckHandler(void);
188     void StopSpawnService(void);
189 
190     static uint32_t serverId;
191 #ifdef USER_TIMER_TO_CHECK
192     static void ProcessIdle(const TimerHandle taskHandle, void *context);
193 #else
194     static void ProcessIdle(const IdleHandle taskHandle, void *context);
195 #endif
196 
197     AppSpawnContent *content_ = nullptr;
198     std::atomic<long> appPid_{-1};
199     std::string serviceCmd_{};
200     bool running_{false};
201 #ifdef USER_TIMER_TO_CHECK
202     TimerHandle timer_;
203 #else
204     IdleHandle idle_ = nullptr;
205 #endif
206     pthread_t threadId_ = 0;
207     std::atomic<bool> stop_{false};
208     RecvMsgProcess recvMsgProcess_ = nullptr;
209     bool testServer_ = false;
210     bool serverStoped = false;
211     struct timespec startTime_ {};
212     uint32_t protectTime_;
213     uint32_t serverId_ = 0;
214     LocalTestServer *localServer_ = nullptr;
215 };
216 
217 struct TestConnection {
218     uint32_t connectionId;
219     TaskHandle stream;
220     uint32_t msgRecvLen;  // 已经接收的长度
221     AppSpawnMsg msg;      // 保存不完整的消息,额外保存消息头信息
222     uint8_t *buffer = nullptr;
223     RecvMsgProcess recvMsgProcess = nullptr;
224     int SendResponse(const AppSpawnMsg *msg, int result, pid_t pid);
225 };
226 
227 /**
228  * @brief 用于client端测试,构建服务程序
229  *
230  */
231 class LocalTestServer {
232 public:
LocalTestServer()233     LocalTestServer() {}
~LocalTestServer()234     ~LocalTestServer() {}
235 
236     int Run(const char *serverName, RecvMsgProcess recvMsg);
237     void Stop();
238 
239 private:
240     using ServerInfo = struct ServerInfo_ {
241         LocalTestServer *local = nullptr;
242         RecvMsgProcess recvMsgProcess = nullptr;
243     };
244 
245     static int OnConnection(const LoopHandle loopHandle, const TaskHandle server);
246     static void SendMessageComplete(const TaskHandle taskHandle, BufferHandle handle);
247     static void OnClose(const TaskHandle taskHandle);
248     static void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t *buffer, uint32_t buffLen);
249     TaskHandle serverHandle_ = 0;
250 };
251 }  // namespace OHOS
252 #endif  // APPSPAWN_TEST_HELPER_H
253