1209bc2fbSopenharmony_ci/*
2209bc2fbSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3209bc2fbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4209bc2fbSopenharmony_ci * you may not use this file except in compliance with the License.
5209bc2fbSopenharmony_ci * You may obtain a copy of the License at
6209bc2fbSopenharmony_ci *
7209bc2fbSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8209bc2fbSopenharmony_ci *
9209bc2fbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10209bc2fbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11209bc2fbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12209bc2fbSopenharmony_ci * See the License for the specific language governing permissions and
13209bc2fbSopenharmony_ci * limitations under the License.
14209bc2fbSopenharmony_ci */
15209bc2fbSopenharmony_ci
16209bc2fbSopenharmony_ci#ifndef RELIABILITY_WATCHDOG_INNER_H
17209bc2fbSopenharmony_ci#define RELIABILITY_WATCHDOG_INNER_H
18209bc2fbSopenharmony_ci
19209bc2fbSopenharmony_ci#include <atomic>
20209bc2fbSopenharmony_ci#include <condition_variable>
21209bc2fbSopenharmony_ci#include <memory>
22209bc2fbSopenharmony_ci#include <mutex>
23209bc2fbSopenharmony_ci#include <queue>
24209bc2fbSopenharmony_ci#include <set>
25209bc2fbSopenharmony_ci#include <string>
26209bc2fbSopenharmony_ci#include <thread>
27209bc2fbSopenharmony_ci
28209bc2fbSopenharmony_ci#include "watchdog_task.h"
29209bc2fbSopenharmony_ci#include "c/ffrt_dump.h"
30209bc2fbSopenharmony_ci#include "singleton.h"
31209bc2fbSopenharmony_ci#include "client/trace_collector_client.h"
32209bc2fbSopenharmony_ci
33209bc2fbSopenharmony_cinamespace OHOS {
34209bc2fbSopenharmony_cinamespace HiviewDFX {
35209bc2fbSopenharmony_ci
36209bc2fbSopenharmony_ciusing TimePoint = AppExecFwk::InnerEvent::TimePoint;
37209bc2fbSopenharmony_cistruct TimeContent {
38209bc2fbSopenharmony_ci    int64_t reportBegin;
39209bc2fbSopenharmony_ci    int64_t reportEnd;
40209bc2fbSopenharmony_ci    int64_t curBegin;
41209bc2fbSopenharmony_ci    int64_t curEnd;
42209bc2fbSopenharmony_ci};
43209bc2fbSopenharmony_ci
44209bc2fbSopenharmony_cistruct StackContent {
45209bc2fbSopenharmony_ci    int stackState;
46209bc2fbSopenharmony_ci    int detectorCount;
47209bc2fbSopenharmony_ci    int collectCount;
48209bc2fbSopenharmony_ci};
49209bc2fbSopenharmony_ci
50209bc2fbSopenharmony_cistruct TraceContent {
51209bc2fbSopenharmony_ci    int traceState;
52209bc2fbSopenharmony_ci    int traceCount;
53209bc2fbSopenharmony_ci    int dumpCount;
54209bc2fbSopenharmony_ci};
55209bc2fbSopenharmony_ci
56209bc2fbSopenharmony_citypedef void (*WatchdogInnerBeginFunc)(const char* eventName);
57209bc2fbSopenharmony_citypedef void (*WatchdogInnerEndFunc)(const char* eventName);
58209bc2fbSopenharmony_ci
59209bc2fbSopenharmony_ciclass WatchdogInner : public Singleton<WatchdogInner> {
60209bc2fbSopenharmony_ci    DECLARE_SINGLETON(WatchdogInner);
61209bc2fbSopenharmony_cipublic:
62209bc2fbSopenharmony_ci    static const int XCOLLIE_CALLBACK_HISTORY_MAX = 5;
63209bc2fbSopenharmony_ci    static const int XCOLLIE_CALLBACK_TIMEWIN_MAX = 60;
64209bc2fbSopenharmony_ci    std::map<int64_t, int> taskIdCnt;
65209bc2fbSopenharmony_ci    int AddThread(const std::string &name, std::shared_ptr<AppExecFwk::EventHandler> handler, uint64_t interval);
66209bc2fbSopenharmony_ci    int AddThread(const std::string &name, std::shared_ptr<AppExecFwk::EventHandler> handler,
67209bc2fbSopenharmony_ci        TimeOutCallback timeOutCallback, uint64_t interval);
68209bc2fbSopenharmony_ci    void RunOneShotTask(const std::string& name, Task&& task, uint64_t delay);
69209bc2fbSopenharmony_ci    void RunPeriodicalTask(const std::string& name, Task&& task, uint64_t interval, uint64_t delay);
70209bc2fbSopenharmony_ci    int64_t RunXCollieTask(const std::string& name, uint64_t timeout, XCollieCallback func, void *arg,
71209bc2fbSopenharmony_ci        unsigned int flag);
72209bc2fbSopenharmony_ci    void RemoveXCollieTask(int64_t id);
73209bc2fbSopenharmony_ci    int64_t SetTimerCountTask(const std::string &name, uint64_t timeLimit, int countLimit);
74209bc2fbSopenharmony_ci    void TriggerTimerCountTask(const std::string &name, bool bTrigger, const std::string &message);
75209bc2fbSopenharmony_ci    void StopWatchdog();
76209bc2fbSopenharmony_ci    bool IsCallbackLimit(unsigned int flag);
77209bc2fbSopenharmony_ci    void IpcCheck();
78209bc2fbSopenharmony_ci    void InitFfrtWatchdog();
79209bc2fbSopenharmony_ci    static void WriteStringToFile(uint32_t pid, const char *str);
80209bc2fbSopenharmony_ci    static void FfrtCallback(uint64_t taskId, const char *taskInfo, uint32_t delayedTaskCount);
81209bc2fbSopenharmony_ci    static void SendFfrtEvent(const std::string &msg, const std::string &eventName, const char *taskInfo);
82209bc2fbSopenharmony_ci    static void LeftTimeExitProcess(const std::string &description);
83209bc2fbSopenharmony_ci    static void KillPeerBinderProcess(const std::string &description);
84209bc2fbSopenharmony_ci    int32_t StartProfileMainThread(int32_t interval);
85209bc2fbSopenharmony_ci    bool CollectStack(std::string& stack);
86209bc2fbSopenharmony_ci    void CollectTrace();
87209bc2fbSopenharmony_ci    bool Deinit();
88209bc2fbSopenharmony_ci    void SetBundleInfo(const std::string& bundleName, const std::string& bundleVersion);
89209bc2fbSopenharmony_ci    void SetForeground(const bool& isForeground);
90209bc2fbSopenharmony_ci    void ChangeState(int& state, int targetState);
91209bc2fbSopenharmony_ci    void DayChecker(int& state, TimePoint currenTime, TimePoint lastEndTime, int64_t checkTimer);
92209bc2fbSopenharmony_ci    void RemoveInnerTask(const std::string& name);
93209bc2fbSopenharmony_ci    void InitMainLooperWatcher(WatchdogInnerBeginFunc* beginFunc, WatchdogInnerEndFunc* endFunc);
94209bc2fbSopenharmony_ci    void SetAppDebug(bool isAppDebug);
95209bc2fbSopenharmony_ci    bool GetAppDebug();
96209bc2fbSopenharmony_ci    std::string currentScene_;
97209bc2fbSopenharmony_ci    TimePoint lastTraceTime_;
98209bc2fbSopenharmony_ci    TimePoint lastStackTime_;
99209bc2fbSopenharmony_ci    TimePoint bussinessBeginTime_;
100209bc2fbSopenharmony_ci    TimeContent timeContent_ {0};
101209bc2fbSopenharmony_ci    StackContent stackContent_ {0};
102209bc2fbSopenharmony_ci    TraceContent traceContent_ {0};
103209bc2fbSopenharmony_ci
104209bc2fbSopenharmony_ciprivate:
105209bc2fbSopenharmony_ci    bool Start();
106209bc2fbSopenharmony_ci    bool Stop();
107209bc2fbSopenharmony_ci    bool SendMsgToHungtask(const std::string& msg);
108209bc2fbSopenharmony_ci    bool KickWatchdog();
109209bc2fbSopenharmony_ci    bool IsTaskExistLocked(const std::string& name);
110209bc2fbSopenharmony_ci    bool IsExceedMaxTaskLocked();
111209bc2fbSopenharmony_ci    int64_t InsertWatchdogTaskLocked(const std::string& name, WatchdogTask&& task);
112209bc2fbSopenharmony_ci    uint64_t FetchNextTask(uint64_t now, WatchdogTask& task);
113209bc2fbSopenharmony_ci    void ReInsertTaskIfNeed(WatchdogTask& task);
114209bc2fbSopenharmony_ci    void CreateWatchdogThreadIfNeed();
115209bc2fbSopenharmony_ci    bool ReportMainThreadEvent();
116209bc2fbSopenharmony_ci    bool CheckEventTimer(const int64_t& currentTime);
117209bc2fbSopenharmony_ci    void StartTraceProfile(int32_t interval);
118209bc2fbSopenharmony_ci    void ThreadSampleTask(int (*threadSamplerInitFunc)(int), int32_t (*threadSamplerSampleFunc)());
119209bc2fbSopenharmony_ci    static void GetFfrtTaskTid(int32_t& tid, const std::string& msg);
120209bc2fbSopenharmony_ci
121209bc2fbSopenharmony_ci    static const unsigned int MAX_WATCH_NUM = 128; // 128: max handler thread
122209bc2fbSopenharmony_ci    std::priority_queue<WatchdogTask> checkerQueue_; // protected by lock_
123209bc2fbSopenharmony_ci    std::unique_ptr<std::thread> threadLoop_;
124209bc2fbSopenharmony_ci    std::mutex lock_;
125209bc2fbSopenharmony_ci    static std::mutex lockFfrt_;
126209bc2fbSopenharmony_ci    std::condition_variable condition_;
127209bc2fbSopenharmony_ci    std::atomic_bool isNeedStop_ = false;
128209bc2fbSopenharmony_ci    std::once_flag flag_;
129209bc2fbSopenharmony_ci    std::set<std::string> taskNameSet_;
130209bc2fbSopenharmony_ci    std::set<int64_t> buissnessThreadInfo_;
131209bc2fbSopenharmony_ci    std::shared_ptr<AppExecFwk::EventRunner> mainRunner_;
132209bc2fbSopenharmony_ci    std::shared_ptr<AppExecFwk::EventHandler> binderCheckHander_;
133209bc2fbSopenharmony_ci    int cntCallback_;
134209bc2fbSopenharmony_ci    time_t timeCallback_;
135209bc2fbSopenharmony_ci    bool isHmos = false;
136209bc2fbSopenharmony_ci    void* funcHandler_ = nullptr;
137209bc2fbSopenharmony_ci    uint64_t watchdogStartTime_ {0};
138209bc2fbSopenharmony_ci
139209bc2fbSopenharmony_ci    bool isMainThreadProfileTaskEnabled_ {false};
140209bc2fbSopenharmony_ci    bool isMainThreadTraceEnabled_ {false};
141209bc2fbSopenharmony_ci    std::string bundleName_;
142209bc2fbSopenharmony_ci    std::string bundleVersion_;
143209bc2fbSopenharmony_ci    bool isForeground_ {false};
144209bc2fbSopenharmony_ci    bool isAppDebug_ {false};
145209bc2fbSopenharmony_ci    int sampleTaskState_;
146209bc2fbSopenharmony_ci    std::shared_ptr<UCollectClient::TraceCollector> traceCollector_;
147209bc2fbSopenharmony_ci    UCollectClient::AppCaller appCaller_ {
148209bc2fbSopenharmony_ci        .actionId = 0,
149209bc2fbSopenharmony_ci        .foreground = 0,
150209bc2fbSopenharmony_ci        .uid = 0,
151209bc2fbSopenharmony_ci        .pid = 0,
152209bc2fbSopenharmony_ci        .happenTime = 0,
153209bc2fbSopenharmony_ci        .beginTime = 0,
154209bc2fbSopenharmony_ci        .endTime = 0,
155209bc2fbSopenharmony_ci        .isBusinessJank = false,
156209bc2fbSopenharmony_ci    };
157209bc2fbSopenharmony_ci};
158209bc2fbSopenharmony_ci} // end of namespace HiviewDFX
159209bc2fbSopenharmony_ci} // end of namespace OHOS
160209bc2fbSopenharmony_ci#endif
161