169570cc8Sopenharmony_ci/*
269570cc8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License.
569570cc8Sopenharmony_ci * You may obtain a copy of the License at
669570cc8Sopenharmony_ci *
769570cc8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
869570cc8Sopenharmony_ci *
969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and
1369570cc8Sopenharmony_ci * limitations under the License.
1469570cc8Sopenharmony_ci */
1569570cc8Sopenharmony_ci
1669570cc8Sopenharmony_ci#ifndef APPSPAWN_MANAGER_H
1769570cc8Sopenharmony_ci#define APPSPAWN_MANAGER_H
1869570cc8Sopenharmony_ci
1969570cc8Sopenharmony_ci#include <limits.h>
2069570cc8Sopenharmony_ci#include <stdbool.h>
2169570cc8Sopenharmony_ci#include <unistd.h>
2269570cc8Sopenharmony_ci
2369570cc8Sopenharmony_ci#include "appspawn.h"
2469570cc8Sopenharmony_ci#include "appspawn_hook.h"
2569570cc8Sopenharmony_ci#include "appspawn_msg.h"
2669570cc8Sopenharmony_ci#include "appspawn_server.h"
2769570cc8Sopenharmony_ci#include "appspawn_utils.h"
2869570cc8Sopenharmony_ci#include "list.h"
2969570cc8Sopenharmony_ci#include "loop_event.h"
3069570cc8Sopenharmony_ci
3169570cc8Sopenharmony_ci#ifdef __cplusplus
3269570cc8Sopenharmony_ciextern "C" {
3369570cc8Sopenharmony_ci#endif
3469570cc8Sopenharmony_ci
3569570cc8Sopenharmony_ci#define MODE_ID_INDEX 1
3669570cc8Sopenharmony_ci#define MODE_VALUE_INDEX 2
3769570cc8Sopenharmony_ci#define FD_ID_INDEX 3
3869570cc8Sopenharmony_ci#define FD_VALUE_INDEX 4
3969570cc8Sopenharmony_ci#define FLAGS_VALUE_INDEX 5
4069570cc8Sopenharmony_ci#define SHM_SIZE_INDEX 6
4169570cc8Sopenharmony_ci#define PARAM_ID_INDEX 7
4269570cc8Sopenharmony_ci#define PARAM_VALUE_INDEX 8
4369570cc8Sopenharmony_ci#define CLIENT_ID_INDEX 9
4469570cc8Sopenharmony_ci#define ARG_NULL 10
4569570cc8Sopenharmony_ci
4669570cc8Sopenharmony_ci#define MAX_DIED_PROCESS_COUNT 5
4769570cc8Sopenharmony_ci
4869570cc8Sopenharmony_ci#define INVALID_OFFSET 0xffffffff
4969570cc8Sopenharmony_ci
5069570cc8Sopenharmony_ci#define APP_STATE_IDLE 1
5169570cc8Sopenharmony_ci#define APP_STATE_SPAWNING 2
5269570cc8Sopenharmony_ci#define APPSPAWN_MAX_TIME 3000000
5369570cc8Sopenharmony_ci
5469570cc8Sopenharmony_ci#define APPSPAWN_INLINE __attribute__((always_inline)) inline
5569570cc8Sopenharmony_ci
5669570cc8Sopenharmony_citypedef struct AppSpawnContent AppSpawnContent;
5769570cc8Sopenharmony_citypedef struct AppSpawnClient AppSpawnClient;
5869570cc8Sopenharmony_citypedef struct TagAppSpawnConnection AppSpawnConnection;
5969570cc8Sopenharmony_ci
6069570cc8Sopenharmony_citypedef struct TagAppSpawnMsgNode {
6169570cc8Sopenharmony_ci    AppSpawnConnection *connection;
6269570cc8Sopenharmony_ci    AppSpawnMsg msgHeader;
6369570cc8Sopenharmony_ci    uint32_t tlvCount;
6469570cc8Sopenharmony_ci    uint32_t *tlvOffset;  // 记录属性的在msg中的偏移,不完全拷贝试消息完整
6569570cc8Sopenharmony_ci    uint8_t *buffer;
6669570cc8Sopenharmony_ci} AppSpawnMsgNode;
6769570cc8Sopenharmony_ci
6869570cc8Sopenharmony_citypedef struct {
6969570cc8Sopenharmony_ci    int32_t fd[2];  // 2 fd count
7069570cc8Sopenharmony_ci    WatcherHandle watcherHandle;
7169570cc8Sopenharmony_ci    WatcherHandle pidFdWatcherHandle;
7269570cc8Sopenharmony_ci    TimerHandle timer;
7369570cc8Sopenharmony_ci    char *childMsg;
7469570cc8Sopenharmony_ci    uint32_t msgSize;
7569570cc8Sopenharmony_ci    char *coldRunPath;
7669570cc8Sopenharmony_ci} AppSpawnForkCtx;
7769570cc8Sopenharmony_ci
7869570cc8Sopenharmony_citypedef struct TagAppSpawningCtx {
7969570cc8Sopenharmony_ci    AppSpawnClient client;
8069570cc8Sopenharmony_ci    struct ListNode node;
8169570cc8Sopenharmony_ci    AppSpawnForkCtx forkCtx;
8269570cc8Sopenharmony_ci    AppSpawnMsgNode *message;
8369570cc8Sopenharmony_ci    bool isPrefork;
8469570cc8Sopenharmony_ci    pid_t pid;
8569570cc8Sopenharmony_ci    int state;
8669570cc8Sopenharmony_ci    struct timespec spawnStart;
8769570cc8Sopenharmony_ci} AppSpawningCtx;
8869570cc8Sopenharmony_ci
8969570cc8Sopenharmony_citypedef struct TagAppSpawnedProcess {
9069570cc8Sopenharmony_ci    struct ListNode node;
9169570cc8Sopenharmony_ci    uid_t uid;
9269570cc8Sopenharmony_ci    pid_t pid;
9369570cc8Sopenharmony_ci    uint32_t max;
9469570cc8Sopenharmony_ci    int exitStatus;
9569570cc8Sopenharmony_ci    struct timespec spawnStart;
9669570cc8Sopenharmony_ci    struct timespec spawnEnd;
9769570cc8Sopenharmony_ci#ifdef DEBUG_BEGETCTL_BOOT
9869570cc8Sopenharmony_ci    AppSpawnMsgNode *message;
9969570cc8Sopenharmony_ci#endif
10069570cc8Sopenharmony_ci    bool isDebuggable;
10169570cc8Sopenharmony_ci    char name[0];
10269570cc8Sopenharmony_ci} AppSpawnedProcess;
10369570cc8Sopenharmony_ci
10469570cc8Sopenharmony_citypedef struct SpawnTime {
10569570cc8Sopenharmony_ci    int minAppspawnTime;
10669570cc8Sopenharmony_ci    int maxAppspawnTime;
10769570cc8Sopenharmony_ci} SpawnTime;
10869570cc8Sopenharmony_ci
10969570cc8Sopenharmony_citypedef struct TagAppSpawnMgr {
11069570cc8Sopenharmony_ci    AppSpawnContent content;
11169570cc8Sopenharmony_ci    TaskHandle server;
11269570cc8Sopenharmony_ci    SignalHandle sigHandler;
11369570cc8Sopenharmony_ci    pid_t servicePid;
11469570cc8Sopenharmony_ci    struct ListNode appQueue;  // save app pid and name
11569570cc8Sopenharmony_ci    uint32_t diedAppCount;
11669570cc8Sopenharmony_ci    uint32_t flags;
11769570cc8Sopenharmony_ci    struct ListNode diedQueue;      // save app pid and name
11869570cc8Sopenharmony_ci    struct ListNode appSpawnQueue;  // save app pid and name
11969570cc8Sopenharmony_ci    struct timespec perLoadStart;
12069570cc8Sopenharmony_ci    struct timespec perLoadEnd;
12169570cc8Sopenharmony_ci    struct ListNode extData;
12269570cc8Sopenharmony_ci    struct SpawnTime spawnTime;
12369570cc8Sopenharmony_ci} AppSpawnMgr;
12469570cc8Sopenharmony_ci
12569570cc8Sopenharmony_ci/**
12669570cc8Sopenharmony_ci * @brief App Spawn Mgr object op
12769570cc8Sopenharmony_ci *
12869570cc8Sopenharmony_ci */
12969570cc8Sopenharmony_ciAppSpawnMgr *CreateAppSpawnMgr(int mode);
13069570cc8Sopenharmony_ciAppSpawnMgr *GetAppSpawnMgr(void);
13169570cc8Sopenharmony_civoid DeleteAppSpawnMgr(AppSpawnMgr *mgr);
13269570cc8Sopenharmony_ciAppSpawnContent *GetAppSpawnContent(void);
13369570cc8Sopenharmony_ci
13469570cc8Sopenharmony_ci/**
13569570cc8Sopenharmony_ci * @brief 孵化成功后进程或者app实例的操作
13669570cc8Sopenharmony_ci *
13769570cc8Sopenharmony_ci */
13869570cc8Sopenharmony_citypedef void (*AppTraversal)(const AppSpawnMgr *mgr, AppSpawnedProcess *appInfo, void *data);
13969570cc8Sopenharmony_civoid TraversalSpawnedProcess(AppTraversal traversal, void *data);
14069570cc8Sopenharmony_ciAppSpawnedProcess *AddSpawnedProcess(pid_t pid, const char *processName, bool isDebuggable);
14169570cc8Sopenharmony_ciAppSpawnedProcess *GetSpawnedProcess(pid_t pid);
14269570cc8Sopenharmony_ciAppSpawnedProcess *GetSpawnedProcessByName(const char *name);
14369570cc8Sopenharmony_civoid TerminateSpawnedProcess(AppSpawnedProcess *node);
14469570cc8Sopenharmony_ci
14569570cc8Sopenharmony_ci/**
14669570cc8Sopenharmony_ci * @brief 孵化过程中的ctx对象的操作
14769570cc8Sopenharmony_ci *
14869570cc8Sopenharmony_ci */
14969570cc8Sopenharmony_citypedef void (*ProcessTraversal)(const AppSpawnMgr *mgr, AppSpawningCtx *ctx, void *data);
15069570cc8Sopenharmony_civoid AppSpawningCtxTraversal(ProcessTraversal traversal, void *data);
15169570cc8Sopenharmony_ciAppSpawningCtx *GetAppSpawningCtxByPid(pid_t pid);
15269570cc8Sopenharmony_ciAppSpawningCtx *CreateAppSpawningCtx();
15369570cc8Sopenharmony_civoid DeleteAppSpawningCtx(AppSpawningCtx *property);
15469570cc8Sopenharmony_ciint KillAndWaitStatus(pid_t pid, int sig, int *exitStatus);
15569570cc8Sopenharmony_ci
15669570cc8Sopenharmony_ci/**
15769570cc8Sopenharmony_ci * @brief 消息解析、处理
15869570cc8Sopenharmony_ci *
15969570cc8Sopenharmony_ci */
16069570cc8Sopenharmony_civoid ProcessAppSpawnDumpMsg(const AppSpawnMsgNode *message);
16169570cc8Sopenharmony_ciint ProcessTerminationStatusMsg(const AppSpawnMsgNode *message, AppSpawnResult *result);
16269570cc8Sopenharmony_ci
16369570cc8Sopenharmony_ciAppSpawnMsgNode *CreateAppSpawnMsg(void);
16469570cc8Sopenharmony_civoid DeleteAppSpawnMsg(AppSpawnMsgNode *msgNode);
16569570cc8Sopenharmony_ciint CheckAppSpawnMsg(const AppSpawnMsgNode *message);
16669570cc8Sopenharmony_ciint DecodeAppSpawnMsg(AppSpawnMsgNode *message);
16769570cc8Sopenharmony_ciint GetAppSpawnMsgFromBuffer(const uint8_t *buffer, uint32_t bufferLen,
16869570cc8Sopenharmony_ci    AppSpawnMsgNode **outMsg, uint32_t *msgRecvLen, uint32_t *reminder);
16969570cc8Sopenharmony_ciAppSpawnMsgNode *RebuildAppSpawnMsgNode(AppSpawnMsgNode *message, AppSpawnedProcess *appInfo);
17069570cc8Sopenharmony_ci
17169570cc8Sopenharmony_ci/**
17269570cc8Sopenharmony_ci * @brief 消息内容操作接口
17369570cc8Sopenharmony_ci *
17469570cc8Sopenharmony_ci */
17569570cc8Sopenharmony_civoid DumpAppSpawnMsg(const AppSpawnMsgNode *message);
17669570cc8Sopenharmony_civoid *GetAppSpawnMsgInfo(const AppSpawnMsgNode *message, int type);
17769570cc8Sopenharmony_civoid *GetAppSpawnMsgExtInfo(const AppSpawnMsgNode *message, const char *name, uint32_t *len);
17869570cc8Sopenharmony_ciint CheckAppSpawnMsgFlag(const AppSpawnMsgNode *message, uint32_t type, uint32_t index);
17969570cc8Sopenharmony_ciint SetAppSpawnMsgFlag(const AppSpawnMsgNode *message, uint32_t type, uint32_t index);
18069570cc8Sopenharmony_ci
18169570cc8Sopenharmony_ciAPPSPAWN_INLINE int IsSpawnServer(const AppSpawnMgr *content)
18269570cc8Sopenharmony_ci{
18369570cc8Sopenharmony_ci    return (content != NULL) && (content->servicePid == getpid());
18469570cc8Sopenharmony_ci}
18569570cc8Sopenharmony_ci
18669570cc8Sopenharmony_ciAPPSPAWN_INLINE int IsNWebSpawnMode(const AppSpawnMgr *content)
18769570cc8Sopenharmony_ci{
18869570cc8Sopenharmony_ci    return (content != NULL) &&
18969570cc8Sopenharmony_ci        (content->content.mode == MODE_FOR_NWEB_SPAWN || content->content.mode == MODE_FOR_NWEB_COLD_RUN);
19069570cc8Sopenharmony_ci}
19169570cc8Sopenharmony_ci
19269570cc8Sopenharmony_ciAPPSPAWN_INLINE int IsColdRunMode(const AppSpawnMgr *content)
19369570cc8Sopenharmony_ci{
19469570cc8Sopenharmony_ci    return (content != NULL) &&
19569570cc8Sopenharmony_ci        (content->content.mode == MODE_FOR_APP_COLD_RUN || content->content.mode == MODE_FOR_NWEB_COLD_RUN);
19669570cc8Sopenharmony_ci}
19769570cc8Sopenharmony_ci
19869570cc8Sopenharmony_ciAPPSPAWN_INLINE int IsDeveloperModeOn(const AppSpawningCtx *property)
19969570cc8Sopenharmony_ci{
20069570cc8Sopenharmony_ci    return (property != NULL && ((property->client.flags & APP_DEVELOPER_MODE) == APP_DEVELOPER_MODE));
20169570cc8Sopenharmony_ci}
20269570cc8Sopenharmony_ci
20369570cc8Sopenharmony_ciAPPSPAWN_INLINE int IsJitFortModeOn(const AppSpawningCtx *property)
20469570cc8Sopenharmony_ci{
20569570cc8Sopenharmony_ci    return (property != NULL && ((property->client.flags & APP_JITFORT_MODE) == APP_JITFORT_MODE));
20669570cc8Sopenharmony_ci}
20769570cc8Sopenharmony_ci
20869570cc8Sopenharmony_ciAPPSPAWN_INLINE int GetAppSpawnMsgType(const AppSpawningCtx *appProperty)
20969570cc8Sopenharmony_ci{
21069570cc8Sopenharmony_ci    return (appProperty != NULL && appProperty->message != NULL) ?
21169570cc8Sopenharmony_ci        appProperty->message->msgHeader.msgType : MAX_TYPE_INVALID;
21269570cc8Sopenharmony_ci}
21369570cc8Sopenharmony_ci
21469570cc8Sopenharmony_ciAPPSPAWN_INLINE const char *GetProcessName(const AppSpawningCtx *property)
21569570cc8Sopenharmony_ci{
21669570cc8Sopenharmony_ci    if (property == NULL || property->message == NULL) {
21769570cc8Sopenharmony_ci        return NULL;
21869570cc8Sopenharmony_ci    }
21969570cc8Sopenharmony_ci    return property->message->msgHeader.processName;
22069570cc8Sopenharmony_ci}
22169570cc8Sopenharmony_ci
22269570cc8Sopenharmony_ciAPPSPAWN_INLINE const char *GetBundleName(const AppSpawningCtx *property)
22369570cc8Sopenharmony_ci{
22469570cc8Sopenharmony_ci    if (property == NULL || property->message == NULL) {
22569570cc8Sopenharmony_ci        return NULL;
22669570cc8Sopenharmony_ci    }
22769570cc8Sopenharmony_ci    AppSpawnMsgBundleInfo *info = (AppSpawnMsgBundleInfo *)GetAppSpawnMsgInfo(property->message, TLV_BUNDLE_INFO);
22869570cc8Sopenharmony_ci    if (info != NULL) {
22969570cc8Sopenharmony_ci        return info->bundleName;
23069570cc8Sopenharmony_ci    }
23169570cc8Sopenharmony_ci    return NULL;
23269570cc8Sopenharmony_ci}
23369570cc8Sopenharmony_ci
23469570cc8Sopenharmony_ciAPPSPAWN_INLINE void *GetAppProperty(const AppSpawningCtx *property, uint32_t type)
23569570cc8Sopenharmony_ci{
23669570cc8Sopenharmony_ci    APPSPAWN_CHECK(property != NULL && property->message != NULL,
23769570cc8Sopenharmony_ci        return NULL, "Invalid property for type %{public}u", type);
23869570cc8Sopenharmony_ci    return GetAppSpawnMsgInfo(property->message, type);
23969570cc8Sopenharmony_ci}
24069570cc8Sopenharmony_ci
24169570cc8Sopenharmony_ciAPPSPAWN_INLINE void *GetAppPropertyExt(const AppSpawningCtx *property, const char *name, uint32_t *len)
24269570cc8Sopenharmony_ci{
24369570cc8Sopenharmony_ci    APPSPAWN_CHECK(name != NULL, return NULL, "Invalid name ");
24469570cc8Sopenharmony_ci    APPSPAWN_CHECK(property != NULL && property->message != NULL,
24569570cc8Sopenharmony_ci        return NULL, "Invalid property for name %{public}s", name);
24669570cc8Sopenharmony_ci    return GetAppSpawnMsgExtInfo(property->message, name, len);
24769570cc8Sopenharmony_ci}
24869570cc8Sopenharmony_ci
24969570cc8Sopenharmony_ciAPPSPAWN_INLINE int CheckAppMsgFlagsSet(const AppSpawningCtx *property, uint32_t index)
25069570cc8Sopenharmony_ci{
25169570cc8Sopenharmony_ci    APPSPAWN_CHECK(property != NULL && property->message != NULL,
25269570cc8Sopenharmony_ci        return 0, "Invalid property for name %{public}u", TLV_MSG_FLAGS);
25369570cc8Sopenharmony_ci    return CheckAppSpawnMsgFlag(property->message, TLV_MSG_FLAGS, index);
25469570cc8Sopenharmony_ci}
25569570cc8Sopenharmony_ci
25669570cc8Sopenharmony_ciAPPSPAWN_INLINE int CheckAppPermissionFlagSet(const AppSpawningCtx *property, uint32_t index)
25769570cc8Sopenharmony_ci{
25869570cc8Sopenharmony_ci    APPSPAWN_CHECK(property != NULL && property->message != NULL,
25969570cc8Sopenharmony_ci        return 0, "Invalid property for name %{public}u", TLV_PERMISSION);
26069570cc8Sopenharmony_ci    return CheckAppSpawnMsgFlag(property->message, TLV_PERMISSION, index);
26169570cc8Sopenharmony_ci}
26269570cc8Sopenharmony_ci
26369570cc8Sopenharmony_ciAPPSPAWN_INLINE int SetAppPermissionFlags(const AppSpawningCtx *property, uint32_t index)
26469570cc8Sopenharmony_ci{
26569570cc8Sopenharmony_ci    APPSPAWN_CHECK(property != NULL && property->message != NULL,
26669570cc8Sopenharmony_ci        return -1, "Invalid property for name %{public}u", TLV_PERMISSION);
26769570cc8Sopenharmony_ci    return SetAppSpawnMsgFlag(property->message, TLV_PERMISSION, index);
26869570cc8Sopenharmony_ci}
26969570cc8Sopenharmony_ci
27069570cc8Sopenharmony_ciAPPSPAWN_INLINE int IsIsolatedNativeSpawnMode(const AppSpawnMgr *content, const AppSpawningCtx *property)
27169570cc8Sopenharmony_ci{
27269570cc8Sopenharmony_ci    return (content != NULL) && (content->content.mode == MODE_FOR_NATIVE_SPAWN) &&
27369570cc8Sopenharmony_ci        CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE);
27469570cc8Sopenharmony_ci}
27569570cc8Sopenharmony_ci
27669570cc8Sopenharmony_ci#ifdef __cplusplus
27769570cc8Sopenharmony_ci}
27869570cc8Sopenharmony_ci#endif
27969570cc8Sopenharmony_ci#endif  // APPSPAWN_MANAGER_H
280