• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #include "native_parameters_js.h"
16 
17 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "StartupParametersJs" };
18 using namespace OHOS::HiviewDFX;
19 static constexpr int MAX_LENGTH = 128;
20 static constexpr int ARGC_NUMBER = 2;
21 static constexpr int ARGC_THREE_NUMBER = 3;
22 static constexpr int BUF_LENGTH = 256;
23 
24 using StorageAsyncContext = struct StorageAsyncContext {
25     napi_env env = nullptr;
26     napi_async_work work = nullptr;
27 
28     char key[BUF_LENGTH] = { 0 };
29     size_t keyLen = 0;
30     char value[BUF_LENGTH] = { 0 };
31     size_t valueLen = 0;
32     napi_deferred deferred = nullptr;
33     napi_ref callbackRef = nullptr;
34 
35     int status = -1;
36     std::string getValue;
37 };
38 
39 using StorageAsyncContextPtr = StorageAsyncContext *;
40 
SetCallbackWork(napi_env env,StorageAsyncContextPtr asyncContext)41 static void SetCallbackWork(napi_env env, StorageAsyncContextPtr asyncContext)
42 {
43     napi_value resource = nullptr;
44     napi_create_string_utf8(env, "JSStartupSet", NAPI_AUTO_LENGTH, &resource);
45     napi_create_async_work(
46         env, nullptr, resource,
47         [](napi_env env, void *data) {
48             StorageAsyncContext *asyncContext = (StorageAsyncContext *)data;
49             asyncContext->status = SetParameter(asyncContext->key, asyncContext->value);
50             HiLog::Debug(LABEL,
51                 "JSApp set::asyncContext-> status = %{public}d, asyncContext->key = %{public}s, asyncContext->value = "
52                 "%{public}s.",
53                 asyncContext->status, asyncContext->key, asyncContext->value);
54         },
55         [](napi_env env, napi_status status, void *data) {
56             StorageAsyncContext *asyncContext = (StorageAsyncContext *)data;
57             napi_value result[ARGC_NUMBER] = { 0 };
58             if (asyncContext->status == 0) {
59                 napi_get_undefined(env, &result[0]);
60                 napi_get_undefined(env, &result[1]);
61             } else {
62                 napi_value value = nullptr;
63                 napi_create_object(env, &result[0]);
64                 napi_create_int32(env, asyncContext->status, &value);
65                 napi_set_named_property(env, result[0], "code", value);
66                 napi_get_undefined(env, &result[1]);
67             }
68 
69             if (asyncContext->deferred) {
70                 if (asyncContext->status == 0) {
71                     napi_resolve_deferred(env, asyncContext->deferred, result[1]);
72                 } else {
73                     napi_reject_deferred(env, asyncContext->deferred, result[0]);
74                 }
75             } else {
76                 napi_value callback = nullptr;
77                 napi_value callResult = nullptr;
78                 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
79                 napi_call_function(env, nullptr, callback, ARGC_NUMBER, result, &callResult);
80                 napi_delete_reference(env, asyncContext->callbackRef);
81             }
82             napi_delete_async_work(env, asyncContext->work);
83             delete asyncContext;
84         },
85         (void *)asyncContext, &asyncContext->work);
86     napi_queue_async_work(env, asyncContext->work);
87 }
88 
Set(napi_env env,napi_callback_info info)89 static napi_value Set(napi_env env, napi_callback_info info)
90 {
91     size_t argc = ARGC_THREE_NUMBER;
92     napi_value argv[ARGC_THREE_NUMBER] = { nullptr };
93     napi_value thisVar = nullptr;
94     void *data = nullptr;
95     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
96     NAPI_ASSERT(env, argc >= ARGC_NUMBER, "requires 2 parameter");
97     StorageAsyncContextPtr asyncContext = new StorageAsyncContext();
98     asyncContext->env = env;
99     for (size_t i = 0; i < argc; i++) {
100         napi_valuetype valueType = napi_null;
101         napi_typeof(env, argv[i], &valueType);
102 
103         if (i == 0 && valueType == napi_string) {
104             napi_get_value_string_utf8(env, argv[i], asyncContext->key,
105                 BUF_LENGTH - 1, &asyncContext->keyLen);
106         } else if (i == 1 && valueType == napi_string) {
107             napi_get_value_string_utf8(env, argv[i], asyncContext->value,
108                 BUF_LENGTH - 1, &asyncContext->valueLen);
109         } else if (i == ARGC_NUMBER && valueType == napi_function) {
110             napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef);
111         } else {
112             delete asyncContext;
113             NAPI_ASSERT(env, false, "type mismatch");
114         }
115     }
116 
117     napi_value result = nullptr;
118     if (asyncContext->callbackRef == nullptr) {
119         napi_create_promise(env, &asyncContext->deferred, &result);
120     } else {
121         napi_get_undefined(env, &result);
122     }
123 
124     SetCallbackWork(env, asyncContext);
125     return result;
126 }
127 
SetSync(napi_env env,napi_callback_info info)128 static napi_value SetSync(napi_env env, napi_callback_info info)
129 {
130     size_t argc = ARGC_NUMBER;
131     napi_value args[ARGC_NUMBER] = { nullptr };
132     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
133     NAPI_ASSERT(env, argc == ARGC_NUMBER, "Wrong number of arguments");
134     napi_valuetype valuetype0 = napi_null;
135     NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
136     napi_valuetype valuetype1 = napi_null;
137     NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));
138     NAPI_ASSERT(env, valuetype0 == napi_string && valuetype1 == napi_string, "Wrong argument type. string expected.");
139 
140     char keyBuf[BUF_LENGTH] = { 0 };
141     size_t keySize = 0;
142     NAPI_CALL(env, napi_get_value_string_utf8(env, args[0], keyBuf, BUF_LENGTH - 1, &keySize));
143     if (keySize >= MAX_LENGTH) {
144         return nullptr;
145     }
146 
147     char valueBuf[BUF_LENGTH] = { 0 };
148     size_t valueSize = 0;
149     NAPI_CALL(env, napi_get_value_string_utf8(env, args[1], valueBuf, BUF_LENGTH - 1, &valueSize));
150     if (valueSize >= MAX_LENGTH) {
151         return nullptr;
152     }
153 
154     std::string keyStr = keyBuf;
155     std::string valueStr = valueBuf;
156     int setResult = SetParameter(keyStr.c_str(), valueStr.c_str());
157     HiLog::Debug(LABEL, "JSApp SetSync::setResult = %{public}d, input keyBuf = %{public}s.", setResult, keyBuf);
158 
159     napi_value napiValue = nullptr;
160     if (setResult != 0) { // set failed
161         std::stringstream ss;
162         ss << "set: " << keyStr << " failed, error code: " << setResult;
163         napi_throw_error((env), nullptr, ss.str().c_str());
164     } else {
165         napi_get_undefined(env, &napiValue);
166     }
167     return napiValue;
168 }
169 
GetSync(napi_env env,napi_callback_info info)170 static napi_value GetSync(napi_env env, napi_callback_info info)
171 {
172     size_t argc = ARGC_NUMBER;
173     napi_value args[ARGC_NUMBER] = { nullptr };
174     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
175     NAPI_ASSERT(env, argc == 1 || argc == ARGC_NUMBER, "Wrong number of arguments");
176     napi_valuetype valuetype0 = napi_null;
177     NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
178     NAPI_ASSERT(env, valuetype0 == napi_string, "Wrong argument type. Numbers expected.");
179     if (argc == ARGC_NUMBER) {
180         napi_valuetype valuetype1 = napi_null;
181         NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));
182         NAPI_ASSERT(env, valuetype1 == napi_string, "Wrong argument type. string expected.");
183     }
184 
185     char keyBuf[BUF_LENGTH] = { 0 };
186     size_t keySize = 0;
187     NAPI_CALL(env, napi_get_value_string_utf8(env, args[0], keyBuf, BUF_LENGTH - 1, &keySize));
188     if (keySize >= MAX_LENGTH) {
189         return nullptr;
190     }
191 
192     std::string keyStr = keyBuf;
193     std::string valueStr = "";
194     std::string getValue = "";
195     if (argc == ARGC_NUMBER) {
196         char valueBuf[BUF_LENGTH] = { 0 };
197         size_t valueSize = 0;
198         NAPI_CALL(env, napi_get_value_string_utf8(env, args[1], valueBuf, BUF_LENGTH - 1, &valueSize));
199         if (valueSize >= MAX_LENGTH) {
200             return nullptr;
201         }
202         valueStr = valueBuf;
203     }
204     int ret = OHOS::system::GetStringParameter(keyStr, getValue, valueStr);
205     HiLog::Debug(LABEL, "JSApp GetSync::getValue = %{public}s, input keyStr = %{public}s.", getValue.c_str(), keyBuf);
206 
207     napi_value napiValue = nullptr;
208     if (ret == 0) {
209         const char *value = getValue.c_str();
210         NAPI_CALL(env, napi_create_string_utf8(env, value, strlen(value), &napiValue));
211     }
212     return napiValue;
213 }
214 
GetCallbackWork(napi_env env,StorageAsyncContextPtr asyncContext)215 static void GetCallbackWork(napi_env env, StorageAsyncContextPtr asyncContext)
216 {
217     napi_value resource = nullptr;
218     napi_create_string_utf8(env, "JSStartupGet", NAPI_AUTO_LENGTH, &resource);
219     napi_create_async_work(
220         env, nullptr, resource,
221         [](napi_env env, void *data) {
222             StorageAsyncContext *asyncContext = (StorageAsyncContext *)data;
223             asyncContext->status =
224                 OHOS::system::GetStringParameter(asyncContext->key, asyncContext->getValue, asyncContext->value);
225             HiLog::Debug(LABEL,
226                 "JSApp get::asyncContext->status = %{public}d, asyncContext->getValue = %{public}s, asyncContext->key "
227                 "= %{public}s, value = %{public}s.",
228                 asyncContext->status, asyncContext->getValue.c_str(), asyncContext->key, asyncContext->value);
229         },
230         [](napi_env env, napi_status status, void *data) {
231             StorageAsyncContext *asyncContext = (StorageAsyncContext *)data;
232             napi_value result[ARGC_NUMBER] = { 0 };
233             if (asyncContext->status == 0) {
234                 napi_get_undefined(env, &result[0]);
235                 napi_create_string_utf8(env, asyncContext->getValue.c_str(), strlen(asyncContext->getValue.c_str()),
236                     &result[1]);
237             } else {
238                 napi_value message = nullptr;
239                 napi_create_object(env, &result[0]);
240                 napi_create_int32(env, asyncContext->status, &message);
241                 napi_set_named_property(env, result[0], "code", message);
242                 napi_get_undefined(env, &result[1]);
243             }
244 
245             if (asyncContext->deferred) {
246                 if (asyncContext->status == 0) {
247                     napi_resolve_deferred(env, asyncContext->deferred, result[1]);
248                 } else {
249                     napi_reject_deferred(env, asyncContext->deferred, result[0]);
250                 }
251             } else {
252                 napi_value callback = nullptr;
253                 napi_value callResult = nullptr;
254                 napi_get_reference_value(env, asyncContext->callbackRef, &callback);
255                 napi_call_function(env, nullptr, callback, ARGC_NUMBER, result, &callResult);
256                 napi_delete_reference(env, asyncContext->callbackRef);
257             }
258             napi_delete_async_work(env, asyncContext->work);
259             delete asyncContext;
260         },
261         (void *)asyncContext, &asyncContext->work);
262     napi_queue_async_work(env, asyncContext->work);
263 }
264 
Get(napi_env env,napi_callback_info info)265 static napi_value Get(napi_env env, napi_callback_info info)
266 {
267     size_t argc = ARGC_THREE_NUMBER;
268     napi_value argv[ARGC_THREE_NUMBER] = { nullptr };
269     napi_value thisVar = nullptr;
270     void *data = nullptr;
271     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
272     NAPI_ASSERT(env, argc >= 1, "requires 1 parameter");
273     StorageAsyncContextPtr asyncContext = new StorageAsyncContext();
274     asyncContext->env = env;
275     for (size_t i = 0; i < argc; i++) {
276         napi_valuetype valueType = napi_null;
277         napi_typeof(env, argv[i], &valueType);
278 
279         if (i == 0 && valueType == napi_string) {
280             napi_get_value_string_utf8(env, argv[i], asyncContext->key,
281                 BUF_LENGTH - 1, &asyncContext->keyLen);
282         } else if (i == 1 && valueType == napi_string) {
283             napi_get_value_string_utf8(env, argv[i], asyncContext->value,
284                 BUF_LENGTH - 1, &asyncContext->valueLen);
285         } else if (i == 1 && valueType == napi_function) {
286             napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef);
287             break;
288         } else if (i == ARGC_NUMBER && valueType == napi_function) {
289             napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef);
290         } else {
291             delete asyncContext;
292             NAPI_ASSERT(env, false, "type mismatch");
293         }
294     }
295 
296     napi_value result = nullptr;
297     if (asyncContext->callbackRef == nullptr) {
298         napi_create_promise(env, &asyncContext->deferred, &result);
299     } else {
300         napi_get_undefined(env, &result);
301     }
302 
303     GetCallbackWork(env, asyncContext);
304     return result;
305 }
306 
307 EXTERN_C_START
308 /*
309  * Module init
310  */
Init(napi_env env,napi_value exports)311 static napi_value Init(napi_env env, napi_value exports)
312 {
313     /*
314      * Attribute definition
315      */
316     napi_property_descriptor desc[] = {
317         DECLARE_NAPI_FUNCTION("set", Set),
318         DECLARE_NAPI_FUNCTION("setSync", SetSync),
319         DECLARE_NAPI_FUNCTION("get", Get),
320         DECLARE_NAPI_FUNCTION("getSync", GetSync),
321         DECLARE_NAPI_FUNCTION("wait", ParamWait),
322         DECLARE_NAPI_FUNCTION("getWatcher", GetWatcher)
323     };
324     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(napi_property_descriptor), desc));
325     return RegisterWatcher(env, exports);
326 }
327 EXTERN_C_END
328 
329 /*
330  * Module definition
331  */
332 static napi_module _module = {
333     .nm_version = 1,
334     .nm_flags = 0,
335     .nm_filename = NULL,
336     .nm_register_func = Init,
337     .nm_modname = "systemParameter",
338     .nm_priv = ((void *)0),
339     .reserved = { 0 }
340 };
341 
342 /*
343  * Module registration function
344  */
RegisterModule(void)345 extern "C" __attribute__((constructor)) void RegisterModule(void)
346 {
347     napi_module_register(&_module);
348 }
349