• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #include "napi/native_api.h"
17 #include "hicollie/hicollie.h"
18 #include <thread>
19 #include <string>
20 #include <unistd.h>
21 #include <atomic>
22 #include "hilog/log.h"
23 
24 #undef LOG_TAG
25 #define LOG_TAG "testTag"
26 
27 static OH_HiCollie_BeginFunc beginFunc_;
28 static OH_HiCollie_EndFunc endFunc_;
29 HiCollie_DetectionParam param {.sampleStackTriggerTime = 150, .reserved = 0};
30 int64_t lastWatchTime = 0;
31 const int64_t CHECK_INTERNAL_TIME = 3000;
32 std::shared_ptr<std::atomic<bool>> isReport = std::make_shared<std::atomic<bool>>(true);
33 int g_count = 0;
34 bool g_needReport = true;
35 int g_initResult = -1;
36 int result = 0;
37 // 自定义休眠时间,模拟卡死场景
38 const int64_t BLOCK_TIME = 5;
39 // 设置应用线程执行任务情况标志位, true-正常, false-卡死
40 std::shared_ptr<std::atomic<bool>> appThreadIsAlive_ = std::make_shared<std::atomic<bool>>(true);
41 // 设置上报应用线程卡死事件标志位
42 std::shared_ptr<std::atomic<bool>> isSixSecondEvent_ = std::make_shared<std::atomic<bool>>(false);
43 
InitBeginFunc(const char * eventName)44 void InitBeginFunc(const char* eventName)
45 {
46     std::string str(eventName);
47 }
InitEndFunc(const char * eventName)48 void InitEndFunc(const char* eventName)
49 {
50     std::string str(eventName);
51 }
52 
TestJankDetection()53 void TestJankDetection()
54 {
55     beginFunc_ = InitBeginFunc;
56     endFunc_ = InitEndFunc;
57     int initResult = OH_HiCollie_Init_JankDetection(&beginFunc_, &endFunc_, param);
58     int initcount = 0;
59     while (initcount < 2) { //as of 2
60         beginFunc_("TestBegin");
61         usleep(350 * 1000); //350ms转换为350*1000微秒
62         endFunc_("TestEnd");
63         initcount++;
64     }
65 }
66 
TestHiCollieJankC(napi_env env,napi_callback_info info)67 static napi_value TestHiCollieJankC(napi_env env, napi_callback_info info)
68 {
69     std::thread threadObj(TestJankDetection);
70     threadObj.join();
71     napi_value sum;
72     napi_create_double(env, 0, &sum);
73     return sum;
74 }
75 
GetCurrentTime()76 int64_t GetCurrentTime()
77 {
78     return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::
79     system_clock::now().time_since_epoch()).count();
80 }
81 
ReportEvent()82 bool ReportEvent()
83 {
84     if ((GetCurrentTime() - lastWatchTime) > CHECK_INTERNAL_TIME) {
85         return true;
86     }
87     return true;
88 }
89 
TestTask()90 void TestTask()
91 {
92     if (g_needReport && ReportEvent()) {
93         bool temp = isReport->load();
94         int reportResult = OH_HiCollie_Report(&temp);
95         g_needReport = false;
96     }
97     int64_t now = GetCurrentTime();
98     if ((now - lastWatchTime) >= (CHECK_INTERNAL_TIME / 2)) { //as of 2
99         lastWatchTime = now;
100     }
101 }
102 
TestStuckDetection()103 int  TestStuckDetection()
104 {
105     int initResult = -1;
106     if (g_count == 0) {
107         initResult = OH_HiCollie_Init_StuckDetection(TestTask);
108         TestTask();
109         g_count++;
110     }
111     return initResult;
112 }
113 
TestHiCollieStuckC(napi_env env,napi_callback_info info)114 static napi_value TestHiCollieStuckC(napi_env env, napi_callback_info info)
115 {
116     std::thread threadObj(TestStuckDetection);
117     threadObj.join();
118     napi_value sum;
119     napi_create_double(env, 0, &sum);
120     return sum;
121 }
122 
TestStuckCMThread(napi_env env,napi_callback_info info)123 static napi_value TestStuckCMThread(napi_env env, napi_callback_info info)
124 {
125     napi_value sum;
126     int initResult = OH_HiCollie_Init_StuckDetection(nullptr);
127     napi_create_int32(env, initResult, &sum);
128     return sum;
129 }
130 
TestJankCMThread(napi_env env,napi_callback_info info)131 static napi_value TestJankCMThread(napi_env env, napi_callback_info info)
132 {
133     napi_value sum;
134     int initResult = OH_HiCollie_Init_JankDetection(nullptr, &endFunc_, param);
135     napi_create_int32(env, initResult, &sum);
136     return sum;
137 }
138 
139 
TestReportCMThread(napi_env env,napi_callback_info info)140 static napi_value TestReportCMThread(napi_env env, napi_callback_info info)
141 {
142     napi_value sum;
143     int initResult = OH_HiCollie_Report(nullptr);
144     napi_create_int32(env, initResult, &sum);
145     return sum;
146 }
147 
148 
Test001()149 void Test001()
150 {
151     g_initResult = OH_HiCollie_Init_JankDetection(nullptr, &endFunc_, param);
152 }
153 
TestJankCerr401(napi_env env,napi_callback_info info)154 static napi_value TestJankCerr401(napi_env env, napi_callback_info info)
155 {
156     napi_value sum;
157     std::thread threadObj(Test001);
158     threadObj.join();
159     napi_create_int32(env, g_initResult, &sum);
160     return sum;
161 }
162 
163 
Add(napi_env env,napi_callback_info info)164 static napi_value Add(napi_env env, napi_callback_info info)
165 {
166     size_t argc = 2;
167     napi_value args[2] = {nullptr};
168 
169     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
170 
171     napi_valuetype valuetype0;
172     napi_typeof(env, args[0], &valuetype0);
173 
174     napi_valuetype valuetype1;
175     napi_typeof(env, args[1], &valuetype1);
176 
177     double value0;
178     napi_get_value_double(env, args[0], &value0);
179 
180     double value1;
181     napi_get_value_double(env, args[1], &value1);
182 
183     napi_value sum;
184     napi_create_double(env, value0 + value1, &sum);
185     return sum;
186 }
187 
CallBack(void *)188 void CallBack(void*)
189 {
190     // OH_LOG_INFO(LogType::LOG_APP, "HiCollieTimerNdk callBackParam:");
191 }
192 
TestHiCollieTimerNdkErr03(napi_env env,napi_callback_info info)193 static napi_value TestHiCollieTimerNdkErr03(napi_env env, napi_callback_info info)
194 {
195     napi_value sum;
196     int id;
197     HiCollie_SetTimerParam param = {nullptr, 1, nullptr, nullptr, HiCollie_Flag::HICOLLIE_FLAG_NOOP};
198     HiCollie_ErrorCode errorCode = OH_HiCollie_SetTimer(param, &id);
199     napi_create_int32(env, errorCode, &sum);
200     return sum;
201 }
202 
TestHiCollieTimerNdkErr04(napi_env env,napi_callback_info info)203 static napi_value TestHiCollieTimerNdkErr04(napi_env env, napi_callback_info info)
204 {
205     napi_value sum;
206     int id;
207     HiCollie_SetTimerParam param = {"testSetTimer", 0, nullptr, nullptr, HiCollie_Flag::HICOLLIE_FLAG_NOOP};
208     HiCollie_ErrorCode errorCode = OH_HiCollie_SetTimer(param, &id);
209     napi_create_int32(env, errorCode, &sum);
210     return sum;
211 }
212 
TestHiCollieTimerNdkErr05(napi_env env,napi_callback_info info)213 static napi_value TestHiCollieTimerNdkErr05(napi_env env, napi_callback_info info)
214 {
215     napi_value sum;
216     int id;
217     HiCollie_SetTimerParam param = {"testSetTimer", 1, nullptr, nullptr, HiCollie_Flag::HICOLLIE_FLAG_NOOP};
218     HiCollie_ErrorCode errorCode = OH_HiCollie_SetTimer(param, &id);
219     napi_create_int32(env, errorCode, &sum);
220     return sum;
221 }
222 
TestHiCollieTimerNdkErr06(napi_env env,napi_callback_info info)223 static napi_value TestHiCollieTimerNdkErr06(napi_env env, napi_callback_info info)
224 {
225     napi_value sum;
226     int id;
227     HiCollie_SetTimerParam param = {"testSetTimer", 1, nullptr, nullptr, HiCollie_Flag::HICOLLIE_FLAG_NOOP};
228     HiCollie_ErrorCode errorCode = OH_HiCollie_SetTimer(param, nullptr);
229     napi_create_int32(env, errorCode, &sum);
230     return sum;
231 }
232 
TestHiCollieTimerNdkSetSuc(napi_env env,napi_callback_info info)233 static napi_value TestHiCollieTimerNdkSetSuc(napi_env env, napi_callback_info info)
234 {
235     napi_value sum;
236     int id;
237     HiCollie_SetTimerParam param = {"testSetTimer", 1, CallBack, nullptr, HiCollie_Flag::HICOLLIE_FLAG_NOOP};
238     HiCollie_ErrorCode errorCode = OH_HiCollie_SetTimer(param, &id);
239     // OH_LOG_INFO(LogType::LOG_APP, "HiCollieTimer taskId: %{public}d", errorCode);
240     napi_create_int32(env, errorCode, &sum);
241     return sum;
242 }
243 
TestHiCollieTimerNdkCanSuc(napi_env env,napi_callback_info info)244 static napi_value TestHiCollieTimerNdkCanSuc(napi_env env, napi_callback_info info)
245 {
246     napi_value sum;
247     int id;
248     HiCollie_SetTimerParam param = {"testSetTimer", 1, CallBack, nullptr, HiCollie_Flag::HICOLLIE_FLAG_NOOP};
249     HiCollie_ErrorCode errorCode = OH_HiCollie_SetTimer(param, &id);
250     if (errorCode == HICOLLIE_SUCCESS) {
251         sleep(2);
252         OH_HiCollie_CancelTimer(id);
253         napi_create_int32(env, 0, &sum);
254     }
255     return sum;
256 }
257 
SetTimeout()258 void SetTimeout()
259 {
260 	int64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::
261     system_clock::now().time_since_epoch()).count();
262 	sleep(BLOCK_TIME);
263 	int64_t currentTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::
264     system_clock::now().time_since_epoch()).count();
265 	if (currentTime - now < BLOCK_TIME) {
266     appThreadIsAlive_->store(true);
267     return;
268   }
269   appThreadIsAlive_->store(false);
270 }
271 
272 // 开发者可自定义周期性检测任务
Timer()273 void Timer()
274 {
275 	// 每隔5s检查应用是否正常执行任务
276 	if (appThreadIsAlive_->load()) {
277     OH_LOG_INFO(LogType::LOG_APP, "Check appThread isAlive.");
278     // 更新appThreadIsAlive_,正常执行下次检测时为true
279     appThreadIsAlive_->store(false);
280     // 模拟超时场景
281     SetTimeout();
282     return;
283   }
284   ReportEvent();
285 }
286 
InitStuckDetectionWithTimeout()287 int InitStuckDetectionWithTimeout()
288 {
289 	// 初始化线程卡死监控函数
290 	int initResult = OH_HiCollie_Init_StuckDetectionWithTimeout(Timer, BLOCK_TIME);
291 	// 成功结果:0
292 	OH_LOG_INFO(LogType::LOG_APP, "OH_HiCollie_Init_StuckDetection: %{public}d", initResult);
293 	return initResult;
294 }
295 
296 //HICOLLIE_WRONG_THREAD_CONTEXT 29800001 - 调用线程错误。无法从主线程调用该函数
TestHiCollieStuckWithTimeoutNdk(napi_env env,napi_callback_info info)297 static napi_value TestHiCollieStuckWithTimeoutNdk(napi_env env, napi_callback_info info)
298 {
299 	napi_value sum;
300 	int initResult = OH_HiCollie_Init_StuckDetectionWithTimeout(Timer, BLOCK_TIME);
301     OH_LOG_INFO(LogType::LOG_APP, "OH_HiCollie_Init_StuckDetection: %{public}d", initResult);
302     napi_create_int32(env, initResult, &sum);
303 	return sum;
304 }
305 //HICOLLIE_SUCCESS 0 - 成功。
TestHiCollieStuckWithTimeoutNdk1(napi_env env,napi_callback_info info)306 static napi_value TestHiCollieStuckWithTimeoutNdk1(napi_env env, napi_callback_info info)
307 {
308     napi_value sum;
309 	// 创建子线程
310 	std::thread threadObj(InitStuckDetectionWithTimeout);
311 	// 执行任务
312 	threadObj.join();
313     napi_create_int32(env, result, &sum);
314 	return sum;
315 }
316 //HICOLLIE_INVALID_ARGUMENT 401 - 开始函数和结束函数两者都必须有值或为空,否则将返回该错误值;卡死时间<3s
TestHiCollieStuckWithTimeoutNdk2(napi_env env,napi_callback_info info)317 static napi_value TestHiCollieStuckWithTimeoutNdk2(napi_env env, napi_callback_info info)
318 {
319 	napi_value sum;
320 	// 创建子线程
321 	int initResult = OH_HiCollie_Init_StuckDetectionWithTimeout(Timer, 1);
322 	OH_LOG_INFO(LogType::LOG_APP, "OH_HiCollie_Init_StuckDetection: %{public}d", initResult);
323 	// 执行任务
324     napi_create_int32(env, initResult, &sum);
325 	return sum;
326 }
327 
328 EXTERN_C_START
Init(napi_env env,napi_value exports)329 static napi_value Init(napi_env env, napi_value exports)
330 {
331     napi_property_descriptor desc[] = {
332         { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr },
333         { "testHiCollieJankC", nullptr, TestHiCollieJankC, nullptr, nullptr, nullptr, napi_default, nullptr },
334         { "testHiCollieStuckC", nullptr, TestHiCollieStuckC, nullptr, nullptr, nullptr, napi_default, nullptr },
335         { "testJankCMThread", nullptr, TestJankCMThread, nullptr, nullptr, nullptr, napi_default, nullptr },
336         { "testStuckCMThread", nullptr, TestStuckCMThread, nullptr, nullptr, nullptr, napi_default, nullptr },
337         { "testReportCMThread", nullptr, TestReportCMThread, nullptr, nullptr, nullptr, napi_default, nullptr },
338         { "testJankCerr401", nullptr,  TestJankCerr401, nullptr, nullptr, nullptr, napi_default, nullptr },
339         { "TestHiCollieTimerNdkErr03", nullptr, TestHiCollieTimerNdkErr03, nullptr, nullptr, nullptr, napi_default, nullptr },
340         { "TestHiCollieTimerNdkErr04", nullptr, TestHiCollieTimerNdkErr04, nullptr, nullptr, nullptr, napi_default, nullptr },
341         { "TestHiCollieTimerNdkErr05", nullptr, TestHiCollieTimerNdkErr05, nullptr, nullptr, nullptr, napi_default, nullptr },
342         { "TestHiCollieTimerNdkErr06", nullptr, TestHiCollieTimerNdkErr05, nullptr, nullptr, nullptr, napi_default, nullptr },
343         { "TestHiCollieTimerNdkSetSuc", nullptr, TestHiCollieTimerNdkSetSuc, nullptr, nullptr, nullptr, napi_default, nullptr },
344         { "TestHiCollieTimerNdkCanSuc", nullptr, TestHiCollieTimerNdkCanSuc, nullptr, nullptr, nullptr, napi_default, nullptr },
345         { "testHiCollieStuckWithTimeoutNdk", nullptr, TestHiCollieStuckWithTimeoutNdk, nullptr, nullptr, nullptr, napi_default, nullptr },
346         { "testHiCollieStuckWithTimeoutNdk1", nullptr, TestHiCollieStuckWithTimeoutNdk1, nullptr, nullptr, nullptr, napi_default, nullptr },
347         { "testHiCollieStuckWithTimeoutNdk2", nullptr, TestHiCollieStuckWithTimeoutNdk2, nullptr, nullptr, nullptr, napi_default, nullptr },
348     };
349     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
350     return exports;
351 }
352 EXTERN_C_END
353 
354 static napi_module demoModule = {
355     .nm_version = 1,
356     .nm_flags = 0,
357     .nm_filename = nullptr,
358     .nm_register_func = Init,
359     .nm_modname = "hicollie",
360     .nm_priv = ((void*)0),
361     .reserved = { 0 },
362 };
363 
RegisterEntryModule(void)364 extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
365 {
366     napi_module_register(&demoModule);
367 }
368