• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 #include <hilog/log.h>
20 #include "hitrace_meter.h"
21 #include "napi_hitrace_meter.h"
22 
23 using namespace OHOS::HiviewDFX;
24 namespace {
25 constexpr int FIRST_ARG_INDEX = 0;
26 constexpr int SECOND_ARG_INDEX = 1;
27 constexpr int ARGC_NUMBER_TWO = 2;
28 constexpr int ARGC_NUMBER_THREE = 3;
29 #undef LOG_DOMAIN
30 #define LOG_DOMAIN 0xD002D33
31 
32 #undef LOG_TAG
33 #define LOG_TAG "HITRACE_METER_JS"
34 
35 using STR_NUM_PARAM_FUNC = std::function<bool(std::string, napi_value&)>;
36 
ParseParams(napi_env & env,napi_callback_info & info,size_t & argc,napi_value * argv)37 napi_value ParseParams(napi_env& env, napi_callback_info& info, size_t& argc, napi_value* argv)
38 {
39     napi_value thisVar;
40     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
41     return nullptr;
42 }
43 
TypeCheck(const napi_env & env,const napi_value & value,const napi_valuetype expectType)44 bool TypeCheck(const napi_env& env, const napi_value& value, const napi_valuetype expectType)
45 {
46     napi_valuetype valueType;
47     napi_status status = napi_typeof(env, value, &valueType);
48     if (status != napi_ok) {
49         HILOG_ERROR(LOG_CORE, "Failed to get the type of the argument.");
50         return false;
51     }
52     if (valueType != expectType) {
53         HILOG_ERROR(LOG_CORE, "Type of the parameter is invalid.");
54         return false;
55     }
56     return true;
57 }
58 
GetStringParam(const napi_env & env,const napi_value & value,std::string & dest)59 void GetStringParam(const napi_env& env, const napi_value& value, std::string& dest)
60 {
61     constexpr int nameMaxSize = 1024;
62     char buf[nameMaxSize] = {0};
63     size_t len = 0;
64     napi_get_value_string_utf8(env, value, buf, nameMaxSize, &len);
65     dest = std::string {buf};
66 }
67 
ParseStringParam(const napi_env & env,const napi_value & value,std::string & dest)68 bool ParseStringParam(const napi_env& env, const napi_value& value, std::string& dest)
69 {
70     if (TypeCheck(env, value, napi_string)) {
71         GetStringParam(env, value, dest);
72         return true;
73     }
74     if (TypeCheck(env, value, napi_number)) {
75         int64_t destI64;
76         napi_get_value_int64(env, value, &destI64);
77         dest = std::to_string(destI64);
78         return true;
79     }
80     if (TypeCheck(env, value, napi_undefined)) {
81         dest = "undefined";
82         return true;
83     }
84     if (TypeCheck(env, value, napi_null)) {
85         dest = "null";
86         return true;
87     }
88     return false;
89 }
90 
ParseInt32Param(const napi_env & env,const napi_value & value,int & dest)91 bool ParseInt32Param(const napi_env& env, const napi_value& value, int& dest)
92 {
93     if (!TypeCheck(env, value, napi_number)) {
94         return false;
95     }
96     napi_get_value_int32(env, value, &dest);
97     return true;
98 }
99 
ParseInt64Param(const napi_env & env,const napi_value & value,int64_t & dest)100 bool ParseInt64Param(const napi_env& env, const napi_value& value, int64_t& dest)
101 {
102     if (!TypeCheck(env, value, napi_number)) {
103         return false;
104     }
105     napi_get_value_int64(env, value, &dest);
106     return true;
107 }
108 
JsStrNumParamsFunc(napi_env & env,napi_callback_info & info,STR_NUM_PARAM_FUNC nativeCall)109 bool JsStrNumParamsFunc(napi_env& env, napi_callback_info& info, STR_NUM_PARAM_FUNC nativeCall)
110 {
111     size_t argc = ARGC_NUMBER_TWO;
112     napi_value argv[ARGC_NUMBER_TWO];
113     ParseParams(env, info, argc, argv);
114     if (argc != ARGC_NUMBER_TWO) {
115         HILOG_ERROR(LOG_CORE, "Wrong number of parameters.");
116         return false;
117     }
118     std::string name;
119     if (!ParseStringParam(env, argv[FIRST_ARG_INDEX], name)) {
120         return false;
121     }
122     if (!nativeCall(name, argv[SECOND_ARG_INDEX])) {
123         return false;
124     }
125     return true;
126 }
127 }
128 
JSTraceStart(napi_env env,napi_callback_info info)129 static napi_value JSTraceStart(napi_env env, napi_callback_info info)
130 {
131     size_t argc = ARGC_NUMBER_THREE;
132     napi_value argv[ARGC_NUMBER_THREE];
133     ParseParams(env, info, argc, argv);
134     NAPI_ASSERT(env, argc >= ARGC_NUMBER_TWO, "Wrong number of arguments");
135     if (argc < ARGC_NUMBER_TWO) {
136         HILOG_ERROR(LOG_CORE, "Wrong number of parameters.");
137     }
138     std::string name;
139     if (!ParseStringParam(env, argv[FIRST_ARG_INDEX], name)) {
140         return nullptr;
141     }
142     int taskId = 0;
143     if (!ParseInt32Param(env, argv[SECOND_ARG_INDEX], taskId)) {
144         return nullptr;
145     }
146     StartAsyncTrace(HITRACE_TAG_APP, name, taskId);
147     return nullptr;
148 }
149 
JSTraceFinish(napi_env env,napi_callback_info info)150 static napi_value JSTraceFinish(napi_env env, napi_callback_info info)
151 {
152     size_t argc = ARGC_NUMBER_TWO;
153     napi_value argv[ARGC_NUMBER_TWO];
154     napi_value thisVar;
155     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
156     NAPI_ASSERT(env, argc == ARGC_NUMBER_TWO, "Wrong number of arguments");
157     (void)JsStrNumParamsFunc(env, info, [&env] (std::string name, napi_value& nValue) -> bool {
158         int taskId = 0;
159         if (!ParseInt32Param(env, nValue, taskId)) {
160             return false;
161         }
162         FinishAsyncTrace(HITRACE_TAG_APP, name, taskId);
163         return true;
164     });
165     return nullptr;
166 }
167 
JSTraceCount(napi_env env,napi_callback_info info)168 static napi_value JSTraceCount(napi_env env, napi_callback_info info)
169 {
170     size_t argc = ARGC_NUMBER_TWO;
171     napi_value argv[ARGC_NUMBER_TWO];
172     napi_value thisVar;
173     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
174     NAPI_ASSERT(env, argc == ARGC_NUMBER_TWO, "Wrong number of arguments");
175     (void)JsStrNumParamsFunc(env, info, [&env] (std::string name, napi_value& nValue) -> bool {
176         int64_t count = 0;
177         if (!ParseInt64Param(env, nValue, count)) {
178             return false;
179         }
180         CountTrace(HITRACE_TAG_APP, name, count);
181         return true;
182     });
183     return nullptr;
184 }
185 
186 /*
187  * function for module exports
188  */
189 EXTERN_C_START
HiTraceMeterInit(napi_env env,napi_value exports)190 static napi_value HiTraceMeterInit(napi_env env, napi_value exports)
191 {
192     napi_property_descriptor desc[] = {
193         DECLARE_NAPI_FUNCTION("startTrace", JSTraceStart),
194         DECLARE_NAPI_FUNCTION("finishTrace", JSTraceFinish),
195         DECLARE_NAPI_FUNCTION("traceByValue", JSTraceCount),
196     };
197     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
198     return exports;
199 }
200 EXTERN_C_END
201 
202 /*
203  * hiTraceMeter module definition
204  */
205 static napi_module hitracemeter_module = {
206     .nm_version = 1,
207     .nm_flags = 0,
208     .nm_filename = nullptr,
209     .nm_register_func = HiTraceMeterInit,
210     .nm_modname = "hiTraceMeter",
211     .nm_priv = ((void *)0),
212     .reserved = {0}
213 };
214 
215 /*
216  * Module registration
217  */
RegisterModule(void)218 extern "C" __attribute__((constructor)) void RegisterModule(void)
219 {
220     napi_module_register(&hitracemeter_module);
221 }
222