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