1 /*
2 * Copyright (c) 2021-2024 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_hitrace_util.h"
17
18 #include "hilog/log.h"
19
20 namespace OHOS {
21 namespace HiviewDFX {
22 namespace {
23 #ifdef LOG_DOMAIN
24 #undef LOG_DOMAIN
25 #define LOG_DOMAIN 0xD002D33
26 #endif
27 #ifdef LOG_TAG
28 #undef LOG_TAG
29 #define LOG_TAG "HitraceUtilNapi"
30 #endif
31
32 constexpr uint32_t UINT32_T_PRO_DEFAULT_VALUE = 0;
33 constexpr uint64_t UINT64_T_PRO_DEFAULT_VALUE = 0;
34 constexpr uint64_t INVALID_CHAIN_ID = 0;
35 constexpr char CHAIN_ID_ATTR[] = "chainId";
36 constexpr char SPAN_ID_ATTR[] = "spanId";
37 constexpr char PARENT_SPAN_ID_ATTR[] = "parentSpanId";
38 constexpr char FLAGS_ATTR[] = "flags";
39
CreateInt32Value(const napi_env env,int32_t value)40 napi_value CreateInt32Value(const napi_env env, int32_t value)
41 {
42 napi_value result = nullptr;
43 NAPI_CALL(env, napi_create_int32(env, value, &result));
44 return result;
45 }
46
CreateInt64Value(const napi_env env,int64_t value)47 napi_value CreateInt64Value(const napi_env env, int64_t value)
48 {
49 napi_value result = nullptr;
50 NAPI_CALL(env, napi_create_int64(env, value, &result));
51 return result;
52 }
53
CreateBigInt64Value(const napi_env env,uint64_t value)54 napi_value CreateBigInt64Value(const napi_env env, uint64_t value)
55 {
56 napi_value result = nullptr;
57 NAPI_CALL(env, napi_create_bigint_uint64(env, value, &result));
58 return result;
59 }
60
SetNamedProperty(const napi_env env,napi_value & object,const std::string & propertyName,napi_value & propertyValue)61 napi_status SetNamedProperty(const napi_env env, napi_value& object,
62 const std::string& propertyName, napi_value& propertyValue)
63 {
64 napi_status status = napi_set_named_property(env, object, propertyName.c_str(), propertyValue);
65 if (status != napi_ok) {
66 HILOG_ERROR(LOG_CORE, "set property %{public}s failed.", propertyName.c_str());
67 }
68 return status;
69 }
70
GetPropertyByName(const napi_env env,const napi_value & object,const std::string & propertyName)71 napi_value GetPropertyByName(const napi_env env, const napi_value& object,
72 const std::string& propertyName)
73 {
74 napi_value result = nullptr;
75 NAPI_CALL(env, napi_get_named_property(env, object, propertyName.c_str(), &result));
76 return result;
77 }
78 }
79
CheckValueTypeValidity(const napi_env env,const napi_value & jsObj,const napi_valuetype typeName)80 bool NapiHitraceUtil::CheckValueTypeValidity(const napi_env env, const napi_value& jsObj,
81 const napi_valuetype typeName)
82 {
83 napi_valuetype valueType = napi_undefined;
84 napi_status ret = napi_typeof(env, jsObj, &valueType);
85 if (ret != napi_ok) {
86 HILOG_ERROR(LOG_CORE, "failed to parse the type of napi value.");
87 return false;
88 }
89 if (valueType != typeName) {
90 HILOG_ERROR(LOG_CORE, "you have called a function with parameters of wrong type.");
91 return false;
92 }
93 return true;
94 }
95
CreateHiTraceIdJsObject(const napi_env env,HiTraceId & traceId,napi_value & valueObject)96 void NapiHitraceUtil::CreateHiTraceIdJsObject(const napi_env env, HiTraceId& traceId,
97 napi_value& valueObject)
98 {
99 napi_create_object(env, &valueObject);
100 NapiHitraceUtil::SetPropertyBigInt64(env, valueObject, CHAIN_ID_ATTR,
101 traceId.GetChainId());
102 HILOG_DEBUG(LOG_CORE, "Native2Js: chainId is %{public}llx.",
103 static_cast<unsigned long long>(traceId.GetChainId()));
104 NapiHitraceUtil::SetPropertyInt64(env, valueObject, SPAN_ID_ATTR, traceId.GetSpanId());
105 HILOG_DEBUG(LOG_CORE, "Native2Js: spanId is %{public}llx.",
106 static_cast<unsigned long long>(traceId.GetSpanId()));
107 NapiHitraceUtil::SetPropertyInt64(env, valueObject, PARENT_SPAN_ID_ATTR,
108 traceId.GetParentSpanId());
109 HILOG_DEBUG(LOG_CORE, "Native2Js: parentSpanId is %{public}llx.",
110 static_cast<unsigned long long>(traceId.GetParentSpanId()));
111 NapiHitraceUtil::SetPropertyInt32(env, valueObject, FLAGS_ATTR,
112 traceId.GetFlags());
113 HILOG_DEBUG(LOG_CORE, "Native2Js: flags is %{public}d.", traceId.GetFlags());
114 }
115
TransHiTraceIdJsObjectToNative(const napi_env env,HiTraceId & traceId,const napi_value & valueObject)116 void NapiHitraceUtil::TransHiTraceIdJsObjectToNative(const napi_env env, HiTraceId& traceId,
117 const napi_value& valueObject)
118 {
119 uint64_t chainId = NapiHitraceUtil::GetPropertyBigInt64(env, valueObject, CHAIN_ID_ATTR);
120 HILOG_DEBUG(LOG_CORE, "Js2Native: chainId is %{public}llx.",
121 static_cast<unsigned long long>(chainId));
122 if (chainId == INVALID_CHAIN_ID) {
123 return;
124 }
125 traceId.SetChainId(chainId);
126 uint64_t spanId = NapiHitraceUtil::GetPropertyInt64(env, valueObject, SPAN_ID_ATTR);
127 HILOG_DEBUG(LOG_CORE, "Js2Native: spanId is %{public}llx.",
128 static_cast<unsigned long long>(spanId));
129 traceId.SetSpanId(spanId);
130 uint64_t parentSpanId = NapiHitraceUtil::GetPropertyInt64(env, valueObject,
131 PARENT_SPAN_ID_ATTR);
132 HILOG_DEBUG(LOG_CORE, "Js2Native: parentSpanId is %{public}llx.",
133 static_cast<unsigned long long>(parentSpanId));
134 traceId.SetParentSpanId(parentSpanId);
135 uint32_t flags = NapiHitraceUtil::GetPropertyInt32(env, valueObject, FLAGS_ATTR);
136 HILOG_DEBUG(LOG_CORE, "Js2Native: flags is %{public}d.", flags);
137 traceId.SetFlags(flags);
138 }
139
EnableTraceIdObjectFlag(const napi_env env,HiTraceId & traceId,napi_value & traceIdObject)140 void NapiHitraceUtil::EnableTraceIdObjectFlag(const napi_env env, HiTraceId& traceId,
141 napi_value& traceIdObject)
142 {
143 NapiHitraceUtil::SetPropertyInt32(env, traceIdObject, FLAGS_ATTR, traceId.GetFlags());
144 }
145
SetPropertyInt32(const napi_env env,napi_value & object,const std::string & propertyName,uint32_t value)146 void NapiHitraceUtil::SetPropertyInt32(const napi_env env, napi_value& object,
147 const std::string& propertyName, uint32_t value)
148 {
149 napi_value peropertyValue = CreateInt32Value(env, value);
150 SetNamedProperty(env, object, propertyName, peropertyValue);
151 }
152
SetPropertyInt64(const napi_env env,napi_value & object,const std::string & propertyName,uint64_t value)153 void NapiHitraceUtil::SetPropertyInt64(const napi_env env, napi_value& object,
154 const std::string& propertyName, uint64_t value)
155 {
156 napi_value peropertyValue = CreateInt64Value(env, value);
157 SetNamedProperty(env, object, propertyName, peropertyValue);
158 }
159
SetPropertyBigInt64(const napi_env env,napi_value & object,const std::string & propertyName,uint64_t value)160 void NapiHitraceUtil::SetPropertyBigInt64(const napi_env env, napi_value& object,
161 const std::string& propertyName, uint64_t value)
162 {
163 napi_value peropertyValue = CreateBigInt64Value(env, value);
164 SetNamedProperty(env, object, propertyName, peropertyValue);
165 }
166
GetPropertyInt32(const napi_env env,const napi_value & object,const std::string & propertyName)167 uint32_t NapiHitraceUtil::GetPropertyInt32(const napi_env env, const napi_value& object,
168 const std::string& propertyName)
169 {
170 napi_value propertyValue = GetPropertyByName(env, object, propertyName);
171 napi_valuetype type;
172 napi_status status = napi_typeof(env, propertyValue, &type);
173 if (status != napi_ok) {
174 HILOG_ERROR(LOG_CORE, "failed to get %{public}s from HiTraceId Js Object.",
175 propertyName.c_str());
176 return UINT32_T_PRO_DEFAULT_VALUE;
177 }
178 if (type != napi_valuetype::napi_number) {
179 HILOG_ERROR(LOG_CORE, "type is not napi_number property.");
180 return UINT32_T_PRO_DEFAULT_VALUE;
181 }
182 int32_t numberValue = 0;
183 status = napi_get_value_int32(env, propertyValue, &numberValue);
184 if (status == napi_ok) {
185 return numberValue;
186 }
187 HILOG_ERROR(LOG_CORE, "failed to get napi_number property from HiTraceId Js Object.");
188 return UINT32_T_PRO_DEFAULT_VALUE;
189 }
190
GetPropertyInt64(const napi_env env,const napi_value & object,const std::string & propertyName)191 uint64_t NapiHitraceUtil::GetPropertyInt64(const napi_env env, const napi_value& object,
192 const std::string& propertyName)
193 {
194 napi_value propertyValue = GetPropertyByName(env, object, propertyName);
195 napi_valuetype type;
196 napi_status status = napi_typeof(env, propertyValue, &type);
197 if (status != napi_ok) {
198 HILOG_ERROR(LOG_CORE, "failed to get %{public}s from HiTraceId Js Object.",
199 propertyName.c_str());
200 return UINT64_T_PRO_DEFAULT_VALUE;
201 }
202 if (type != napi_valuetype::napi_number) {
203 HILOG_ERROR(LOG_CORE, "type is not napi_number property.");
204 return UINT64_T_PRO_DEFAULT_VALUE;
205 }
206 int64_t numberValue = 0;
207 status = napi_get_value_int64(env, propertyValue, &numberValue);
208 if (status == napi_ok) {
209 return numberValue;
210 }
211 HILOG_ERROR(LOG_CORE, "failed to get napi_number property from HiTraceId Js Object.");
212 return UINT64_T_PRO_DEFAULT_VALUE;
213 }
214
GetPropertyBigInt64(const napi_env env,const napi_value & object,const std::string & propertyName)215 uint64_t NapiHitraceUtil::GetPropertyBigInt64(const napi_env env, const napi_value& object,
216 const std::string& propertyName)
217 {
218 napi_value propertyValue = GetPropertyByName(env, object, propertyName);
219 napi_valuetype type;
220 napi_status status = napi_typeof(env, propertyValue, &type);
221 if (status != napi_ok) {
222 HILOG_ERROR(LOG_CORE, "failed to get %{public}s from HiTraceId Js Object.",
223 propertyName.c_str());
224 return UINT64_T_PRO_DEFAULT_VALUE;
225 }
226 uint64_t bigInt64Value = 0;
227 bool lossless = true;
228 napi_get_value_bigint_uint64(env, propertyValue, &bigInt64Value, &lossless);
229 return bigInt64Value;
230 }
231 } // namespace HiviewDFX
232 } // namespace OHOS
233