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 "js_ui_appearance.h"
17 
18 #include <string>
19 #include "js_native_api.h"
20 #include "ui_appearance_log.h"
21 
22 namespace OHOS {
23 namespace ArkUi::UiAppearance {
24 namespace {
25 static constexpr size_t ARGC_WITH_ONE = 1;
26 static constexpr size_t ARGC_WITH_TWO = 2;
27 static constexpr size_t MAX_FONT_SCALE = 5;
28 static constexpr size_t MIN_FONT_SCALE = 0;
29 const std::string PERMISSION_ERR_MSG =
30     "An attempt was made to update configuration forbidden by permission: ohos.permission.UPDATE_CONFIGURATION.";
31 const std::string INVALID_ARG_MSG = "The type of 'mode' must be DarkMode.";
32 
33 static const std::unordered_map<int32_t, std::string> ERROR_CODE_TO_MSG {
34     { UiAppearanceAbilityInterface::ErrCode::PERMISSION_ERR, "Permission denied. " },
35     { UiAppearanceAbilityInterface::ErrCode::INVALID_ARG, "Parameter error. " },
36     { UiAppearanceAbilityInterface::ErrCode::SYS_ERR, "Internal error. " },
37 };
38 
NapiThrow(napi_env env,const std::string & message,int32_t errCode)39 void NapiThrow(napi_env env, const std::string& message, int32_t errCode)
40 {
41     napi_value code = nullptr;
42     std::string strCode = std::to_string(errCode);
43     napi_create_string_utf8(env, strCode.c_str(), strCode.length(), &code);
44 
45     napi_value msg = nullptr;
46     auto iter = ERROR_CODE_TO_MSG.find(errCode);
47     std::string strMsg = (iter != ERROR_CODE_TO_MSG.end() ? iter->second : "") + message;
48     LOGI("napi throw errCode %{public}d, strMsg %{public}s", errCode, strMsg.c_str());
49     napi_create_string_utf8(env, strMsg.c_str(), strMsg.length(), &msg);
50 
51     napi_value error = nullptr;
52     napi_create_error(env, code, msg, &error);
53     napi_throw(env, error);
54 }
55 } // namespace
56 
OnExecute(napi_env env,void * data)57 void JsUiAppearance::OnExecute(napi_env env, void* data)
58 {
59     LOGI("OnExecute begin.");
60     AsyncContext* asyncContext = static_cast<AsyncContext*>(data);
61     if (asyncContext == nullptr) {
62         NapiThrow(env, "asyncContext is null.", UiAppearanceAbilityInterface::ErrCode::SYS_ERR);
63         return;
64     }
65     auto resCode = UiAppearanceAbilityClient::GetInstance()->SetDarkMode(asyncContext->mode);
66     asyncContext->status = static_cast<UiAppearanceAbilityInterface::ErrCode>(resCode);
67     if (asyncContext->status == UiAppearanceAbilityInterface::ErrCode::PERMISSION_ERR) {
68         asyncContext->errMsg = PERMISSION_ERR_MSG;
69     } else if (asyncContext->status == UiAppearanceAbilityInterface::ErrCode::INVALID_ARG) {
70         asyncContext->errMsg = INVALID_ARG_MSG;
71     } else {
72         asyncContext->errMsg = "";
73     }
74 }
75 
OnSetFontScale(napi_env env,void * data)76 void JsUiAppearance::OnSetFontScale(napi_env env, void* data)
77 {
78     LOGI("OnSetFontScale begin.");
79     AsyncContext* asyncContext = static_cast<AsyncContext*>(data);
80     if (asyncContext == nullptr) {
81         NapiThrow(env, "asyncContext is null.", UiAppearanceAbilityInterface::ErrCode::SYS_ERR);
82         return;
83     }
84     int32_t resCode = 0;
85     if (asyncContext->jsFontScale <= MIN_FONT_SCALE || asyncContext->jsFontScale > MAX_FONT_SCALE) {
86         resCode = UiAppearanceAbilityInterface::ErrCode::INVALID_ARG;
87     } else {
88         resCode = UiAppearanceAbilityClient::GetInstance()->SetFontScale(asyncContext->fontScale);
89     }
90 
91     asyncContext->status = static_cast<UiAppearanceAbilityInterface::ErrCode>(resCode);
92     if (asyncContext->status == UiAppearanceAbilityInterface::ErrCode::PERMISSION_ERR) {
93         asyncContext->errMsg = PERMISSION_ERR_MSG;
94     } else if (asyncContext->status == UiAppearanceAbilityInterface::ErrCode::INVALID_ARG) {
95         asyncContext->errMsg = "fontScale must between 0 and 5";
96     } else {
97         asyncContext->errMsg = "";
98     }
99 }
100 
OnSetFontWeightScale(napi_env env,void * data)101 void JsUiAppearance::OnSetFontWeightScale(napi_env env, void* data)
102 {
103     LOGI("OnSetFontWeightScale begin.");
104     AsyncContext* asyncContext = static_cast<AsyncContext*>(data);
105     if (asyncContext == nullptr) {
106         NapiThrow(env, "asyncContext is null.", UiAppearanceAbilityInterface::ErrCode::SYS_ERR);
107         return;
108     }
109     int32_t resCode = 0;
110     if (asyncContext->jsFontWeightScale <= MIN_FONT_SCALE ||
111         asyncContext->jsFontWeightScale > MAX_FONT_SCALE) {
112         resCode = UiAppearanceAbilityInterface::ErrCode::INVALID_ARG;
113     } else {
114         resCode = UiAppearanceAbilityClient::GetInstance()
115             ->SetFontWeightScale(asyncContext->fontWeightScale);
116     }
117 
118     asyncContext->status = static_cast<UiAppearanceAbilityInterface::ErrCode>(resCode);
119     if (asyncContext->status == UiAppearanceAbilityInterface::ErrCode::PERMISSION_ERR) {
120         asyncContext->errMsg = PERMISSION_ERR_MSG;
121     } else if (asyncContext->status == UiAppearanceAbilityInterface::ErrCode::INVALID_ARG) {
122         asyncContext->errMsg = "fontWeightScale must between 0 and 5";
123     } else {
124         asyncContext->errMsg = "";
125     }
126 }
127 
OnComplete(napi_env env,napi_status status,void * data)128 void JsUiAppearance::OnComplete(napi_env env, napi_status status, void* data)
129 {
130     LOGI("OnComplete begin.");
131     napi_handle_scope scope = nullptr;
132     napi_open_handle_scope(env, &scope);
133     if (scope == nullptr) {
134         NapiThrow(env, "open handle scope failed.", UiAppearanceAbilityInterface::ErrCode::SYS_ERR);
135         return;
136     }
137     AsyncContext* asyncContext = static_cast<AsyncContext*>(data);
138     if (asyncContext == nullptr) {
139         NapiThrow(env, "asyncContext is null.", UiAppearanceAbilityInterface::ErrCode::SYS_ERR);
140         return;
141     }
142 
143     if (asyncContext->status == UiAppearanceAbilityInterface::ErrCode::SUCCEEDED) {
144         napi_value result = nullptr;
145         napi_get_null(env, &result);
146         if (asyncContext->deferred) { // promise
147             napi_resolve_deferred(env, asyncContext->deferred, result);
148         } else { // AsyncCallback
149             napi_value callback = nullptr;
150             napi_get_reference_value(env, asyncContext->callbackRef, &callback);
151             napi_value ret;
152             napi_call_function(env, nullptr, callback, 1, &result, &ret);
153         }
154     } else {
155         napi_value code = nullptr;
156         std::string strCode = std::to_string(asyncContext->status);
157         napi_create_string_utf8(env, strCode.c_str(), strCode.length(), &code);
158 
159         napi_value msg = nullptr;
160         auto iter = ERROR_CODE_TO_MSG.find(asyncContext->status);
161         std::string strMsg = (iter != ERROR_CODE_TO_MSG.end() ? iter->second : "") + asyncContext->errMsg;
162         LOGI("napi throw errCode %{public}d, strMsg %{public}s", asyncContext->status, strMsg.c_str());
163         napi_create_string_utf8(env, strMsg.c_str(), strMsg.length(), &msg);
164 
165         napi_value error = nullptr;
166         napi_create_error(env, code, msg, &error);
167         if (asyncContext->deferred) { // promise
168             napi_reject_deferred(env, asyncContext->deferred, error);
169         } else { // AsyncCallback
170             napi_value callback = nullptr;
171             napi_get_reference_value(env, asyncContext->callbackRef, &callback);
172             napi_value ret;
173             napi_call_function(env, nullptr, callback, 1, &error, &ret);
174         }
175     }
176     napi_delete_async_work(env, asyncContext->work);
177     delete asyncContext;
178     napi_close_handle_scope(env, scope);
179 }
180 
CheckArgs(napi_env env,size_t argc,napi_value * argv)181 napi_status JsUiAppearance::CheckArgs(napi_env env, size_t argc, napi_value* argv)
182 {
183     if (argc != ARGC_WITH_ONE && argc != ARGC_WITH_TWO) {
184         NapiThrow(
185             env, "the number of parameters can only be 1 or 2.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
186         return napi_invalid_arg;
187     }
188 
189     napi_valuetype valueType = napi_undefined;
190     switch (argc) {
191         case ARGC_WITH_TWO:
192             napi_typeof(env, argv[1], &valueType);
193             if (valueType != napi_function) {
194                 NapiThrow(env, "the second parameter must be a function.",
195                     UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
196                 return napi_invalid_arg;
197             }
198             [[fallthrough]];
199         case ARGC_WITH_ONE:
200             napi_typeof(env, argv[0], &valueType);
201             if (valueType != napi_number) {
202                 NapiThrow(
203                     env, "the first parameter must be DarkMode.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
204                 return napi_invalid_arg;
205             }
206             break;
207         default:
208             return napi_invalid_arg;
209     }
210     return napi_ok;
211 }
212 
CheckFontScaleArgs(napi_env env,size_t argc,napi_value * argv)213 napi_status JsUiAppearance::CheckFontScaleArgs(napi_env env, size_t argc, napi_value* argv)
214 {
215     if (argc != ARGC_WITH_ONE && argc != ARGC_WITH_TWO) {
216         NapiThrow(
217             env, "the number of parameters can only be 1 or 2.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
218         return napi_invalid_arg;
219     }
220 
221     napi_valuetype valueType = napi_undefined;
222     switch (argc) {
223         case ARGC_WITH_TWO:
224             napi_typeof(env, argv[1], &valueType);
225             if (valueType != napi_function) {
226                 NapiThrow(env, "the second parameter must be a function.",
227                     UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
228                 return napi_invalid_arg;
229             }
230             [[fallthrough]];
231         case ARGC_WITH_ONE:
232             napi_typeof(env, argv[0], &valueType);
233             if (valueType != napi_number) {
234                 NapiThrow(
235                     env, "the first parameter must be Number.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
236                 return napi_invalid_arg;
237             }
238             break;
239         default:
240             return napi_invalid_arg;
241     }
242     return napi_ok;
243 }
244 
ConvertJsDarkMode2Enum(int32_t jsVal)245 UiAppearanceAbilityInterface::DarkMode JsUiAppearance::ConvertJsDarkMode2Enum(int32_t jsVal)
246 {
247     switch (jsVal) {
248         case 0:
249             return UiAppearanceAbilityInterface::DarkMode::ALWAYS_DARK;
250         case 1:
251             return UiAppearanceAbilityInterface::DarkMode::ALWAYS_LIGHT;
252         default:
253             return UiAppearanceAbilityInterface::DarkMode::UNKNOWN;
254     }
255 }
256 
JSSetDarkMode(napi_env env,napi_callback_info info)257 static napi_value JSSetDarkMode(napi_env env, napi_callback_info info)
258 {
259     LOGI("JSSetDarkMode begin.");
260 
261     size_t argc = ARGC_WITH_TWO;
262     napi_value argv[ARGC_WITH_TWO] = { 0 };
263     napi_status napiStatus = napi_ok;
264     napi_value result = nullptr;
265     napi_get_undefined(env, &result);
266 
267     napiStatus = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
268     if (napiStatus != napi_ok) {
269         NapiThrow(env, "get callback info failed.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
270         return result;
271     }
272     napiStatus = JsUiAppearance::CheckArgs(env, argc, argv);
273     if (napiStatus != napi_ok) {
274         NapiThrow(env, "parameter parsing error.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
275         return result;
276     }
277 
278     auto asyncContext = new (std::nothrow) AsyncContext();
279     if (asyncContext == nullptr) {
280         NapiThrow(env, "create AsyncContext failed.", UiAppearanceAbilityInterface::ErrCode::SYS_ERR);
281         return result;
282     }
283 
284     napi_get_value_int32(env, argv[0], &asyncContext->jsSetArg);
285     asyncContext->mode = JsUiAppearance::ConvertJsDarkMode2Enum(asyncContext->jsSetArg);
286     if (argc == ARGC_WITH_TWO) {
287         napi_create_reference(env, argv[1], 1, &asyncContext->callbackRef);
288     }
289     if (asyncContext->callbackRef == nullptr) {
290         napi_create_promise(env, &asyncContext->deferred, &result);
291     }
292 
293     napi_value resource = nullptr;
294     napi_create_string_utf8(env, "JSSetDarkMode", NAPI_AUTO_LENGTH, &resource);
295     napi_create_async_work(env, nullptr, resource, JsUiAppearance::OnExecute, JsUiAppearance::OnComplete,
296         reinterpret_cast<void*>(asyncContext), &asyncContext->work);
297     napi_queue_async_work(env, asyncContext->work);
298 
299     return result;
300 }
301 
JSGetDarkMode(napi_env env,napi_callback_info info)302 static napi_value JSGetDarkMode(napi_env env, napi_callback_info info)
303 {
304     LOGI("JSGetDarkMode begin.");
305 
306     napi_value result = nullptr;
307     napi_get_undefined(env, &result);
308     size_t argc = 0;
309     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr));
310     if (argc != 0) {
311         NapiThrow(env, "requires no parameter.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
312         return result;
313     }
314 
315     auto mode = UiAppearanceAbilityClient::GetInstance()->GetDarkMode();
316     if (mode == UiAppearanceAbilityInterface::ErrCode::SYS_ERR) {
317         NapiThrow(env, "get dark-mode failed.", UiAppearanceAbilityInterface::ErrCode::SYS_ERR);
318         return result;
319     }
320     if (mode == UiAppearanceAbilityInterface::ErrCode::PERMISSION_ERR) {
321         NapiThrow(env,
322             "An attempt was made to get configuration forbidden by permission: ohos.permission.UPDATE_CONFIGURATION.",
323             UiAppearanceAbilityInterface::ErrCode::PERMISSION_ERR);
324         return result;
325     }
326     NAPI_CALL(env, napi_create_int32(env, mode, &result));
327     return result;
328 }
329 
JSGetFontScale(napi_env env,napi_callback_info info)330 static napi_value JSGetFontScale(napi_env env, napi_callback_info info)
331 {
332     LOGI("JSGetFontScale begin.");
333     napi_value result = nullptr;
334     napi_get_undefined(env, &result);
335     size_t argc = 0;
336     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr));
337     if (argc != 0) {
338         NapiThrow(env, "requires no parameter.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
339         return result;
340     }
341 
342     std::string fontScale;
343     auto ret = UiAppearanceAbilityClient::GetInstance()->GetFontScale(fontScale);
344     if (ret == UiAppearanceAbilityInterface::ErrCode::SYS_ERR) {
345         NapiThrow(env, "get font-scale failed.", UiAppearanceAbilityInterface::ErrCode::SYS_ERR);
346         return result;
347     }
348     if (ret == UiAppearanceAbilityInterface::ErrCode::PERMISSION_ERR) {
349         NapiThrow(env,
350             "An attempt was made to get configuration forbidden by permission: ohos.permission.UPDATE_CONFIGURATION.",
351             UiAppearanceAbilityInterface::ErrCode::PERMISSION_ERR);
352         return result;
353     }
354     double fontScaleNumber = std::stod(fontScale);
355     NAPI_CALL(env, napi_create_double(env, fontScaleNumber, &result));
356     return result;
357 }
358 
JSSetFontScale(napi_env env,napi_callback_info info)359 static napi_value JSSetFontScale(napi_env env, napi_callback_info info)
360 {
361     LOGI("JSSetFontScale begin.");
362 
363     size_t argc = ARGC_WITH_TWO;
364     napi_value argv[ARGC_WITH_TWO] = { 0 };
365     napi_status napiStatus = napi_ok;
366     napi_value result = nullptr;
367     napi_get_undefined(env, &result);
368 
369     napiStatus = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
370     if (napiStatus != napi_ok) {
371         NapiThrow(env, "get callback info failed.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
372         return result;
373     }
374     napiStatus = JsUiAppearance::CheckFontScaleArgs(env, argc, argv);
375     if (napiStatus != napi_ok) {
376         NapiThrow(env, "parameter parsing error.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
377         return result;
378     }
379     auto asyncContext = new (std::nothrow) AsyncContext();
380     if (asyncContext == nullptr) {
381         NapiThrow(env, "create AsyncContext failed.", UiAppearanceAbilityInterface::ErrCode::SYS_ERR);
382         return result;
383     }
384     napi_get_value_double(env, argv[0], &asyncContext->jsFontScale);
385 
386     asyncContext->fontScale = std::to_string(asyncContext->jsFontScale);
387     if (argc == ARGC_WITH_TWO) {
388         napi_create_reference(env, argv[1], 1, &asyncContext->callbackRef);
389     }
390     if (asyncContext->callbackRef == nullptr) {
391         napi_create_promise(env, &asyncContext->deferred, &result);
392     }
393 
394     napi_value resource = nullptr;
395     napi_create_string_utf8(env, "JSSetFontScale", NAPI_AUTO_LENGTH, &resource);
396     napi_create_async_work(env, nullptr, resource, JsUiAppearance::OnSetFontScale, JsUiAppearance::OnComplete,
397         reinterpret_cast<void*>(asyncContext), &asyncContext->work);
398     napi_queue_async_work(env, asyncContext->work);
399 
400     return result;
401 }
402 
JSGetFontWeightScale(napi_env env,napi_callback_info info)403 static napi_value JSGetFontWeightScale(napi_env env, napi_callback_info info)
404 {
405     LOGI("JSGetFontWeightScale begin.");
406     napi_value result = nullptr;
407     napi_get_undefined(env, &result);
408     size_t argc = 0;
409     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr));
410     if (argc != 0) {
411         NapiThrow(env, "requires no parameter.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
412         return result;
413     }
414 
415     std::string fontWeightScale;
416     auto ret = UiAppearanceAbilityClient::GetInstance()->GetFontWeightScale(fontWeightScale);
417     if (ret == UiAppearanceAbilityInterface::ErrCode::SYS_ERR) {
418         NapiThrow(env, "get font-Weight-scale failed.", UiAppearanceAbilityInterface::ErrCode::SYS_ERR);
419         return result;
420     }
421     if (ret == UiAppearanceAbilityInterface::ErrCode::PERMISSION_ERR) {
422         NapiThrow(env,
423             "An attempt was made to get configuration forbidden by permission: ohos.permission.UPDATE_CONFIGURATION.",
424             UiAppearanceAbilityInterface::ErrCode::PERMISSION_ERR);
425         return result;
426     }
427     double fontWeightScaleNumber = std::stod(fontWeightScale);
428     NAPI_CALL(env, napi_create_double(env, fontWeightScaleNumber, &result));
429     return result;
430 }
431 
JSSetFontWeightScale(napi_env env,napi_callback_info info)432 static napi_value JSSetFontWeightScale(napi_env env, napi_callback_info info)
433 {
434     LOGI("JSSetFontWeightScale begin.");
435 
436     size_t argc = ARGC_WITH_TWO;
437     napi_value argv[ARGC_WITH_TWO] = { 0 };
438     napi_status napiStatus = napi_ok;
439     napi_value result = nullptr;
440     napi_get_undefined(env, &result);
441 
442     napiStatus = napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
443     if (napiStatus != napi_ok) {
444         NapiThrow(env, "get callback info failed.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
445         return result;
446     }
447     napiStatus = JsUiAppearance::CheckFontScaleArgs(env, argc, argv);
448     if (napiStatus != napi_ok) {
449         NapiThrow(env, "parameter parsing error.", UiAppearanceAbilityInterface::ErrCode::INVALID_ARG);
450         return result;
451     }
452     auto asyncContext = new (std::nothrow) AsyncContext();
453     if (asyncContext == nullptr) {
454         NapiThrow(env, "create AsyncContext failed.", UiAppearanceAbilityInterface::ErrCode::SYS_ERR);
455         return result;
456     }
457     napi_get_value_double(env, argv[0], &asyncContext->jsFontWeightScale);
458 
459     asyncContext->fontWeightScale = std::to_string(asyncContext->jsFontWeightScale);
460     if (argc == ARGC_WITH_TWO) {
461         napi_create_reference(env, argv[1], 1, &asyncContext->callbackRef);
462     }
463     if (asyncContext->callbackRef == nullptr) {
464         napi_create_promise(env, &asyncContext->deferred, &result);
465     }
466 
467     napi_value resource = nullptr;
468     napi_create_string_utf8(env, "JSSetFontWeightScale", NAPI_AUTO_LENGTH, &resource);
469     napi_create_async_work(env, nullptr, resource, JsUiAppearance::OnSetFontWeightScale, JsUiAppearance::OnComplete,
470         reinterpret_cast<void*>(asyncContext), &asyncContext->work);
471     napi_queue_async_work(env, asyncContext->work);
472 
473     return result;
474 }
475 
476 EXTERN_C_START
UiAppearanceExports(napi_env env,napi_value exports)477 static napi_value UiAppearanceExports(napi_env env, napi_value exports)
478 {
479     napi_value DarkMode = nullptr;
480     napi_value alwaysDark = nullptr;
481     napi_value alwaysLight = nullptr;
482     NAPI_CALL(env, napi_create_int32(env, 0, &alwaysDark));
483     NAPI_CALL(env, napi_create_int32(env, 1, &alwaysLight));
484     NAPI_CALL(env, napi_create_object(env, &DarkMode));
485     NAPI_CALL(env, napi_set_named_property(env, DarkMode, "ALWAYS_DARK", alwaysDark));
486     NAPI_CALL(env, napi_set_named_property(env, DarkMode, "ALWAYS_LIGHT", alwaysLight));
487     napi_property_descriptor properties[] = {
488         DECLARE_NAPI_FUNCTION("setDarkMode", JSSetDarkMode),
489         DECLARE_NAPI_FUNCTION("getDarkMode", JSGetDarkMode),
490         DECLARE_NAPI_FUNCTION("getFontScale", JSGetFontScale),
491         DECLARE_NAPI_FUNCTION("setFontScale", JSSetFontScale),
492         DECLARE_NAPI_FUNCTION("getFontWeightScale", JSGetFontWeightScale),
493         DECLARE_NAPI_FUNCTION("setFontWeightScale", JSSetFontWeightScale),
494         DECLARE_NAPI_STATIC_PROPERTY("DarkMode", DarkMode),
495     };
496     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
497     return exports;
498 }
499 EXTERN_C_END
500 
501 static napi_module ui_appearance_module = {
502     .nm_version = 1,
503     .nm_flags = 0,
504     .nm_filename = nullptr,
505     .nm_register_func = UiAppearanceExports,
506     .nm_modname = "uiAppearance", // relative to the module name while import.
507     .nm_priv = nullptr,
508     .reserved = { 0 },
509 };
510 
UiAppearanceRegister()511 extern "C" __attribute__((constructor)) void UiAppearanceRegister()
512 {
513     napi_module_register(&ui_appearance_module);
514 }
515 } // namespace ArkUi::UiAppearance
516 } // namespace OHOS
517