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
42namespace OHOS {
43typedef struct {
44    int argc;
45    char *argv[0];
46} CmdArgs;
47
48typedef struct AppSpawnClient AppSpawnClient;
49struct TestConnection;
50class LocalTestServer;
51using RecvMsgProcess = std::function<void(struct TestConnection *connection, const uint8_t *buffer, uint32_t buffLen)>;
52using AddTlvFunction = std::function<int(uint8_t *buffer, uint32_t bufferLen, uint32_t &realLen, uint32_t &tlvCount)>;
53
54class AppSpawnTestHelper {
55public:
56    AppSpawnTestHelper()
57    {
58        SetDefaultTestData();
59    }
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();
69    const char *GetDefaultTestAppBundleName()
70    {
71        return processName_.c_str();
72    }
73    uid_t GetTestUid()
74    {
75        return defaultTestUid_;
76    }
77    gid_t GetTestGid()
78    {
79        return defaultTestGid_;
80    }
81    gid_t GetTestGidGroup()
82    {
83        return defaultTestGidGroup_;
84    }
85    int32_t GetTestBundleIndex()
86    {
87        return defaultTestBundleIndex_;
88    }
89
90    void SetTestMsgFlags(uint32_t flags)
91    {
92        defaultMsgFlags_ = flags;
93    }
94    void SetTestApl(const char *apl)
95    {
96        defaultApl_ = std::string(apl);
97    }
98    void SetTestUid(uid_t uid)
99    {
100        defaultTestUid_ = uid;
101    }
102    void SetTestGid(gid_t gid)
103    {
104        defaultTestGid_ = gid;
105    }
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);
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
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    }
139private:
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
161class AppSpawnTestServer : public AppSpawnTestHelper {
162public:
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
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;
185private:
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
217struct 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 */
231class LocalTestServer {
232public:
233    LocalTestServer() {}
234    ~LocalTestServer() {}
235
236    int Run(const char *serverName, RecvMsgProcess recvMsg);
237    void Stop();
238
239private:
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