1 /*
2 * Copyright (C) 2023 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 "base/perfmonitor/perf_monitor.h"
17 #include "napi_perf_monitor.h"
18
19 namespace OHOS::Ace::Napi {
20 static constexpr uint32_t LAST_DOWN = 0;
21 static constexpr uint32_t LAST_UP = 1;
22 static constexpr uint32_t FIRST_MOVE = 2;
23 static constexpr uint32_t PERF_TOUCH_EVENT = 0;
24 static constexpr uint32_t PERF_MOUSE_EVENT = 1;
25 static constexpr uint32_t PERF_TOUCHPAD_EVENT = 2;
26 static constexpr uint32_t PERF_JOYSTICK_EVENT = 3;
27 static constexpr uint32_t PERF_KEY_EVENT = 4;
28 constexpr int FIRST_ARG_INDEX = 0;
29 constexpr int SECOND_ARG_INDEX = 1;
30 constexpr int THIRD_ARG_INDEX = 2;
31 constexpr int ARGC_NUMBER_ONE = 1;
32 constexpr int ARGC_NUMBER_TWO = 2;
33 constexpr int ARGC_NUMBER_THREE = 3;
34
PreParseParams(napi_env & env,napi_callback_info & info,size_t & argc,napi_value * argv)35 napi_value PreParseParams(napi_env& env, napi_callback_info& info, size_t& argc, napi_value* argv)
36 {
37 napi_value thisVar;
38 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
39 return nullptr;
40 }
41
PerfValueType(const napi_env & env,const napi_value & value,const napi_valuetype expectType)42 bool PerfValueType(const napi_env& env, const napi_value& value, const napi_valuetype expectType)
43 {
44 napi_valuetype valueType;
45 napi_status status = napi_typeof(env, value, &valueType);
46 if (status != napi_ok) {
47 return false;
48 }
49 if (valueType != expectType) {
50 return false;
51 }
52 return true;
53 }
54
GetStringParam(const napi_env & env,const napi_value & value,std::string & dest)55 void GetStringParam(const napi_env& env, const napi_value& value, std::string& dest)
56 {
57 constexpr int nameMaxSize = 1024;
58 char buf[nameMaxSize] = {0};
59 size_t len = 0;
60 napi_get_value_string_utf8(env, value, buf, nameMaxSize, &len);
61 dest = std::string {buf};
62 }
63
ParseStringParam(const napi_env & env,const napi_value & value,std::string & dest)64 bool ParseStringParam(const napi_env& env, const napi_value& value, std::string& dest)
65 {
66 if (PerfValueType(env, value, napi_string)) {
67 GetStringParam(env, value, dest);
68 return true;
69 }
70 if (PerfValueType(env, value, napi_number)) {
71 int64_t destI64;
72 napi_get_value_int64(env, value, &destI64);
73 dest = std::to_string(destI64);
74 return true;
75 }
76 if (PerfValueType(env, value, napi_undefined)) {
77 dest = "undefined";
78 return true;
79 }
80 if (PerfValueType(env, value, napi_null)) {
81 dest = "null";
82 return true;
83 }
84 return false;
85 }
86
ParseInt32Param(const napi_env & env,const napi_value & value,int & dest)87 bool ParseInt32Param(const napi_env& env, const napi_value& value, int& dest)
88 {
89 if (!PerfValueType(env, value, napi_number)) {
90 return false;
91 }
92 napi_get_value_int32(env, value, &dest);
93 return true;
94 }
95
ParseInt64Param(const napi_env & env,const napi_value & value,int64_t & dest)96 bool ParseInt64Param(const napi_env& env, const napi_value& value, int64_t& dest)
97 {
98 if (!PerfValueType(env, value, napi_number)) {
99 return false;
100 }
101 napi_get_value_int64(env, value, &dest);
102 return true;
103 }
104
SceneStart(std::string sceneId,int type,std::string note)105 static void SceneStart(std::string sceneId, int type, std::string note)
106 {
107 PerfMonitor* pMonitor = PerfMonitor::GetPerfMonitor();
108 if (pMonitor != nullptr) {
109 pMonitor->Start(sceneId, static_cast<PerfActionType>(type), note);
110 }
111 }
112
SceneEnd(std::string sceneId,bool isJsApi)113 static void SceneEnd(std::string sceneId, bool isJsApi)
114 {
115 PerfMonitor* pMonitor = PerfMonitor::GetPerfMonitor();
116 if (pMonitor != nullptr) {
117 pMonitor->End(sceneId, isJsApi);
118 }
119 }
120
InputEvent(int type,int sourceType,int64_t time)121 static void InputEvent(int type, int sourceType, int64_t time)
122 {
123 PerfMonitor* pMonitor = PerfMonitor::GetPerfMonitor();
124 if (pMonitor != nullptr) {
125 pMonitor->RecordInputEvent(static_cast<PerfActionType>(type), static_cast<PerfSourceType>(sourceType), time);
126 }
127 }
128
JSSceneStart(napi_env env,napi_callback_info info)129 static napi_value JSSceneStart(napi_env env, napi_callback_info info)
130 {
131 size_t argc = ARGC_NUMBER_THREE;
132 napi_value argv[ARGC_NUMBER_THREE];
133 PreParseParams(env, info, argc, argv);
134 NAPI_ASSERT(env, argc >= ARGC_NUMBER_TWO, "Wrong number of arguments");
135 if (argc < ARGC_NUMBER_TWO) {
136 return nullptr;
137 }
138
139 std::string sceneId = "";
140 if (!ParseStringParam(env, argv[FIRST_ARG_INDEX], sceneId)) {
141 return nullptr;
142 }
143
144 int inputType = 0;
145 if (!ParseInt32Param(env, argv[SECOND_ARG_INDEX], inputType)) {
146 return nullptr;
147 }
148
149 std::string note;
150 if (argc >= ARGC_NUMBER_THREE && !ParseStringParam(env, argv[THIRD_ARG_INDEX], note)) {
151 return nullptr;
152 }
153 SceneStart(sceneId, inputType, note);
154 return nullptr;
155 }
156
JSSceneEnd(napi_env env,napi_callback_info info)157 static napi_value JSSceneEnd(napi_env env, napi_callback_info info)
158 {
159 size_t argc = ARGC_NUMBER_ONE;
160 napi_value argv[ARGC_NUMBER_ONE];
161 PreParseParams(env, info, argc, argv);
162 NAPI_ASSERT(env, argc >= ARGC_NUMBER_ONE, "Wrong number of arguments");
163 if (argc < ARGC_NUMBER_ONE) {
164 return nullptr;
165 }
166
167 std::string sceneId = "";
168 if (!ParseStringParam(env, argv[FIRST_ARG_INDEX], sceneId)) {
169 return nullptr;
170 }
171 SceneEnd(sceneId, true);
172 return nullptr;
173 }
174
JSRecordInputEventTime(napi_env env,napi_callback_info info)175 static napi_value JSRecordInputEventTime(napi_env env, napi_callback_info info)
176 {
177 size_t argc = ARGC_NUMBER_THREE;
178 napi_value argv[ARGC_NUMBER_THREE];
179 PreParseParams(env, info, argc, argv);
180 NAPI_ASSERT(env, argc >= ARGC_NUMBER_TWO, "Wrong number of arguments");
181 if (argc < ARGC_NUMBER_TWO) {
182 return nullptr;
183 }
184
185 int type = 0;
186 if (!ParseInt32Param(env, argv[FIRST_ARG_INDEX], type)) {
187 return nullptr;
188 }
189
190 int sourceType = 0;
191 if (!ParseInt32Param(env, argv[SECOND_ARG_INDEX], sourceType)) {
192 return nullptr;
193 }
194
195 int64_t time = 0;
196 if (!ParseInt64Param(env, argv[THIRD_ARG_INDEX], time)) {
197 return nullptr;
198 }
199 InputEvent(type, sourceType, time);
200 return nullptr;
201 }
202
203
204 /*
205 * function for module exports
206 */
PerfMonitorInit(napi_env env,napi_value exports)207 static napi_value PerfMonitorInit(napi_env env, napi_value exports)
208 {
209 napi_value actionType = nullptr;
210 napi_create_object(env, &actionType);
211 napi_value prop = nullptr;
212 napi_create_uint32(env, LAST_DOWN, &prop);
213 napi_set_named_property(env, actionType, "LAST_DOWN", prop);
214 napi_create_uint32(env, LAST_UP, &prop);
215 napi_set_named_property(env, actionType, "LAST_UP", prop);
216 napi_create_uint32(env, FIRST_MOVE, &prop);
217 napi_set_named_property(env, actionType, "FIRST_MOVE", prop);
218
219 napi_value sourceType = nullptr;
220 napi_create_object(env, &sourceType);
221 prop = nullptr;
222 napi_create_uint32(env, PERF_TOUCH_EVENT, &prop);
223 napi_set_named_property(env, sourceType, "PERF_TOUCH_EVENT", prop);
224 napi_create_uint32(env, PERF_MOUSE_EVENT, &prop);
225 napi_set_named_property(env, sourceType, "PERF_MOUSE_EVENT", prop);
226 napi_create_uint32(env, PERF_TOUCHPAD_EVENT, &prop);
227 napi_set_named_property(env, sourceType, "PERF_TOUCHPAD_EVENT", prop);
228 napi_create_uint32(env, PERF_JOYSTICK_EVENT, &prop);
229 napi_set_named_property(env, sourceType, "PERF_JOYSTICK_EVENT", prop);
230 napi_create_uint32(env, PERF_KEY_EVENT, &prop);
231 napi_set_named_property(env, sourceType, "PERF_KEY_EVENT", prop);
232
233 napi_property_descriptor desc[] = {
234 DECLARE_NAPI_FUNCTION("begin", JSSceneStart),
235 DECLARE_NAPI_FUNCTION("end", JSSceneEnd),
236 DECLARE_NAPI_FUNCTION("recordInputEventTime", JSRecordInputEventTime),
237 DECLARE_NAPI_PROPERTY("ActionType", actionType),
238 DECLARE_NAPI_PROPERTY("SourceType", sourceType),
239 };
240 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
241 return exports;
242 }
243
244 /*
245 * performanceMonitor module definition
246 */
247 static napi_module perfmonitor_module = {
248 .nm_version = 1,
249 .nm_flags = 0,
250 .nm_filename = nullptr,
251 .nm_register_func = PerfMonitorInit,
252 .nm_modname = "arkui.performanceMonitor",
253 .nm_priv = ((void *)0),
254 .reserved = {0}
255 };
256
257 /*
258 * Module registration
259 */
RegisterModule(void)260 extern "C" __attribute__((constructor)) void RegisterModule(void)
261 {
262 napi_module_register(&perfmonitor_module);
263 }
264 }
265