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 "common_want.h"
17 #include "common.h"
18
19 #include "work_sched_errors.h"
20 #include "bool_wrapper.h"
21 #include "double_wrapper.h"
22 #include "int_wrapper.h"
23 #include "string_wrapper.h"
24 #include "want_params_wrapper.h"
25 #include "work_sched_hilog.h"
26 #include "napi/native_node_api.h"
27 #include "securec.h"
28
29 namespace OHOS {
30 namespace WorkScheduler {
UnwrapStringFromJS(napi_env env,napi_value param,const std::string & defaultValue="")31 std::string UnwrapStringFromJS(napi_env env, napi_value param, const std::string &defaultValue = "")
32 {
33 size_t size = 0;
34 if (napi_get_value_string_utf8(env, param, nullptr, 0, &size) != napi_ok) {
35 return defaultValue;
36 }
37
38 std::string value("");
39 if (size == 0) {
40 return defaultValue;
41 }
42
43 char *buf = new (std::nothrow) char[size + 1];
44 if (buf == nullptr) {
45 return value;
46 }
47 (void)memset_s(buf, size + 1, 0, size + 1);
48
49 bool rev = napi_get_value_string_utf8(env, param, buf, size + 1, &size) == napi_ok;
50 if (rev) {
51 value = buf;
52 } else {
53 value = defaultValue;
54 }
55
56 delete[] buf;
57 buf = nullptr;
58 return value;
59 }
60
InnerUnwrapJS(napi_env env,napi_value param,AAFwk::WantParams & wantParams,std::string strProName)61 bool InnerUnwrapJS(napi_env env, napi_value param, AAFwk::WantParams &wantParams, std::string strProName)
62 {
63 napi_valuetype jsValueType = napi_undefined;
64 napi_value jsProValue = nullptr;
65 napi_get_named_property(env, param, strProName.c_str(), &jsProValue);
66 napi_typeof(env, jsProValue, &jsValueType);
67 switch (jsValueType) {
68 case napi_string: {
69 std::string natValue = UnwrapStringFromJS(env, jsProValue, "");
70 wantParams.SetParam(strProName, AAFwk::String::Box(natValue));
71 break;
72 }
73 case napi_boolean: {
74 bool natValue = false;
75 napi_get_value_bool(env, jsProValue, &natValue);
76 wantParams.SetParam(strProName, AAFwk::Boolean::Box(natValue));
77 break;
78 }
79 case napi_number: {
80 int32_t natValue32 = 0;
81 double natValueDouble = 0.0;
82 bool isReadValue32 = false;
83 bool isReadDouble = false;
84 if (napi_get_value_int32(env, jsProValue, &natValue32) == napi_ok) {
85 isReadValue32 = true;
86 }
87 if (napi_get_value_double(env, jsProValue, &natValueDouble) == napi_ok) {
88 isReadDouble = true;
89 }
90 if (isReadValue32 && isReadDouble) {
91 if (abs(natValueDouble - natValue32 * 1.0) > 0.0) {
92 wantParams.SetParam(strProName, AAFwk::Double::Box(natValueDouble));
93 } else {
94 wantParams.SetParam(strProName, AAFwk::Integer::Box(natValue32));
95 }
96 } else if (isReadValue32) {
97 wantParams.SetParam(strProName, AAFwk::Integer::Box(natValue32));
98 } else if (isReadDouble) {
99 wantParams.SetParam(strProName, AAFwk::Double::Box(natValueDouble));
100 }
101 break;
102 }
103 default: {
104 WS_HILOGE("Param %{public}s is illegal. The value is only supported basic type(Number, String, Boolean).",
105 strProName.c_str());
106 Common::HandleParamErr(env, E_PARAMETERS_TYPE_ERR);
107 return false;
108 }
109 }
110 return true;
111 }
112
UnwrapWantParams(napi_env env,napi_value param,AAFwk::WantParams & wantParams)113 bool UnwrapWantParams(napi_env env, napi_value param, AAFwk::WantParams &wantParams)
114 {
115 if (param == nullptr) {
116 return false;
117 }
118 napi_valuetype valueType = napi_undefined;
119 if (napi_typeof(env, param, &valueType) != napi_ok) {
120 return false;
121 }
122 if (valueType == napi_undefined) {
123 WS_HILOGI("parameters not set.");
124 return true;
125 } else if (valueType != napi_object) {
126 WS_HILOGE("parameters should be {[key: string]: value} format.");
127 Common::HandleParamErr(env, E_PARAMETERS_TYPE_ERR);
128 return false;
129 }
130
131 napi_value jsProNameList = nullptr;
132 uint32_t jsProCount = 0;
133 napi_value jsProName = nullptr;
134 napi_get_property_names(env, param, &jsProNameList);
135 napi_get_array_length(env, jsProNameList, &jsProCount);
136 WS_HILOGI("Property size=%{public}d.", jsProCount);
137
138 for (uint32_t index = 0; index < jsProCount; index++) {
139 napi_get_element(env, jsProNameList, index, &jsProName);
140 std::string strProName = UnwrapStringFromJS(env, jsProName, "");
141 WS_HILOGD("Property name=%{public}s.", strProName.c_str());
142 if (!InnerUnwrapJS(env, param, wantParams, strProName)) {
143 return false;
144 }
145 }
146 return true;
147 }
148
InnerWrapWantParamsString(napi_env env,napi_value jsObject,const std::string & key,const AAFwk::WantParams & wantParams)149 bool InnerWrapWantParamsString(
150 napi_env env, napi_value jsObject, const std::string &key, const AAFwk::WantParams &wantParams)
151 {
152 auto value = wantParams.GetParam(key);
153 AAFwk::IString *ao = AAFwk::IString::Query(value);
154 if (ao == nullptr) {
155 return false;
156 }
157
158 std::string natValue = AAFwk::String::Unbox(ao);
159 napi_value jsValue;
160 napi_create_string_utf8(env, natValue.c_str(), NAPI_AUTO_LENGTH, &jsValue);
161 if (jsValue == nullptr) {
162 return false;
163 }
164
165 NAPI_CALL_BASE(env, napi_set_named_property(env, jsObject, key.c_str(), jsValue), false);
166 return true;
167 }
168
InnerWrapWantParamsBool(napi_env env,napi_value jsObject,const std::string & key,const AAFwk::WantParams & wantParams)169 bool InnerWrapWantParamsBool(
170 napi_env env, napi_value jsObject, const std::string &key, const AAFwk::WantParams &wantParams)
171 {
172 auto value = wantParams.GetParam(key);
173 AAFwk::IBoolean *bo = AAFwk::IBoolean::Query(value);
174 if (bo == nullptr) {
175 return false;
176 }
177
178 bool natValue = AAFwk::Boolean::Unbox(bo);
179 napi_value jsValue;
180 napi_get_boolean(env, natValue, &jsValue);
181 if (jsValue == nullptr) {
182 return false;
183 }
184
185 NAPI_CALL_BASE(env, napi_set_named_property(env, jsObject, key.c_str(), jsValue), false);
186 return true;
187 }
188
InnerWrapWantParamsInt(napi_env env,napi_value jsObject,const std::string & key,const AAFwk::WantParams & wantParams)189 bool InnerWrapWantParamsInt(
190 napi_env env, napi_value jsObject, const std::string &key, const AAFwk::WantParams &wantParams)
191 {
192 auto value = wantParams.GetParam(key);
193 AAFwk::IInteger *ao = AAFwk::IInteger::Query(value);
194 if (ao == nullptr) {
195 return false;
196 }
197
198 int natValue = AAFwk::Integer::Unbox(ao);
199 napi_value jsValue;
200 napi_create_int32(env, natValue, &jsValue);
201 if (jsValue == nullptr) {
202 return false;
203 }
204
205 NAPI_CALL_BASE(env, napi_set_named_property(env, jsObject, key.c_str(), jsValue), false);
206 return true;
207 }
208
InnerWrapWantParamsDouble(napi_env env,napi_value jsObject,const std::string & key,const AAFwk::WantParams & wantParams)209 bool InnerWrapWantParamsDouble(
210 napi_env env, napi_value jsObject, const std::string &key, const AAFwk::WantParams &wantParams)
211 {
212 auto value = wantParams.GetParam(key);
213 AAFwk::IDouble *ao = AAFwk::IDouble::Query(value);
214 if (ao == nullptr) {
215 return false;
216 }
217
218 double natValue = AAFwk::Double::Unbox(ao);
219 napi_value jsValue;
220 napi_create_double(env, natValue, &jsValue);
221 if (jsValue == nullptr) {
222 return false;
223 }
224
225 NAPI_CALL_BASE(env, napi_set_named_property(env, jsObject, key.c_str(), jsValue), false);
226 return true;
227 }
228
WrapWantParams(napi_env env,const AAFwk::WantParams & wantParams)229 napi_value WrapWantParams(napi_env env, const AAFwk::WantParams &wantParams)
230 {
231 WS_HILOGD("Start wrap wantParams.");
232 napi_value jsObject = nullptr;
233 NAPI_CALL(env, napi_create_object(env, &jsObject));
234
235 const std::map<std::string, sptr<AAFwk::IInterface>> paramList = wantParams.GetParams();
236 for (auto iter = paramList.begin(); iter != paramList.end(); iter++) {
237 if (AAFwk::IString::Query(iter->second) != nullptr) {
238 InnerWrapWantParamsString(env, jsObject, iter->first, wantParams);
239 } else if (AAFwk::IBoolean::Query(iter->second) != nullptr) {
240 InnerWrapWantParamsBool(env, jsObject, iter->first, wantParams);
241 } else if (AAFwk::IInteger::Query(iter->second) != nullptr) {
242 InnerWrapWantParamsInt(env, jsObject, iter->first, wantParams);
243 } else if (AAFwk::IDouble::Query(iter->second) != nullptr) {
244 InnerWrapWantParamsDouble(env, jsObject, iter->first, wantParams);
245 }
246 }
247 return jsObject;
248 }
249 } // namespace WorkScheduler
250 } // namespace OHOS
251