1/*
2 * Copyright (c) 2023 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 "error_util.h"
17#include "i18n_hilog.h"
18#include "i18n_service_ability_client.h"
19#include "i18n_service_ability_load_manager.h"
20#include "i18n_system_addon.h"
21#include "js_utils.h"
22#include "locale_config.h"
23#include "locale_info.h"
24#include "preferred_language.h"
25#include "utils.h"
26#include "variable_convertor.h"
27
28namespace OHOS {
29namespace Global {
30namespace I18n {
31I18nSystemAddon::I18nSystemAddon() {}
32
33I18nSystemAddon::~I18nSystemAddon() {}
34
35void I18nSystemAddon::Destructor(napi_env env, void *nativeObject, void *finalize_hint)
36{
37    if (!nativeObject) {
38        return;
39    }
40    delete reinterpret_cast<I18nSystemAddon *>(nativeObject);
41    nativeObject = nullptr;
42}
43
44napi_value I18nSystemAddon::InitI18nSystem(napi_env env, napi_value exports)
45{
46    napi_property_descriptor properties[] = {
47        DECLARE_NAPI_STATIC_FUNCTION("getDisplayCountry", GetDisplayCountryWithError),
48        DECLARE_NAPI_STATIC_FUNCTION("getDisplayLanguage", GetDisplayLanguageWithError),
49        DECLARE_NAPI_STATIC_FUNCTION("getSystemLanguages", GetSystemLanguages),
50        DECLARE_NAPI_STATIC_FUNCTION("getSystemCountries", GetSystemCountriesWithError),
51        DECLARE_NAPI_STATIC_FUNCTION("isSuggested", IsSuggestedWithError),
52        DECLARE_NAPI_STATIC_FUNCTION("getSystemLanguage", GetSystemLanguage),
53        DECLARE_NAPI_STATIC_FUNCTION("setSystemLanguage", SetSystemLanguageWithError),
54        DECLARE_NAPI_STATIC_FUNCTION("getSystemRegion", GetSystemRegion),
55        DECLARE_NAPI_STATIC_FUNCTION("setSystemRegion", SetSystemRegionWithError),
56        DECLARE_NAPI_STATIC_FUNCTION("getSystemLocale", GetSystemLocale),
57        DECLARE_NAPI_STATIC_FUNCTION("setSystemLocale", SetSystemLocaleWithError),
58        DECLARE_NAPI_STATIC_FUNCTION("is24HourClock", Is24HourClock),
59        DECLARE_NAPI_STATIC_FUNCTION("set24HourClock", Set24HourClockWithError),
60        DECLARE_NAPI_STATIC_FUNCTION("addPreferredLanguage", AddPreferredLanguageWithError),
61        DECLARE_NAPI_STATIC_FUNCTION("removePreferredLanguage", RemovePreferredLanguageWithError),
62        DECLARE_NAPI_STATIC_FUNCTION("getPreferredLanguageList", GetPreferredLanguageList),
63        DECLARE_NAPI_STATIC_FUNCTION("setAppPreferredLanguage", SetAppPreferredLanguage),
64        DECLARE_NAPI_STATIC_FUNCTION("getFirstPreferredLanguage", GetFirstPreferredLanguage),
65        DECLARE_NAPI_STATIC_FUNCTION("getAppPreferredLanguage", GetAppPreferredLanguage),
66        DECLARE_NAPI_STATIC_FUNCTION("setUsingLocalDigit", SetUsingLocalDigitAddonWithError),
67        DECLARE_NAPI_STATIC_FUNCTION("getUsingLocalDigit", GetUsingLocalDigitAddon)
68    };
69    napi_value constructor = nullptr;
70    napi_status status = napi_define_class(env, "System", NAPI_AUTO_LENGTH, JSUtils::DefaultConstructor, nullptr,
71        sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
72    if (status != napi_ok) {
73        HILOG_ERROR_I18N("Define class failed when InitSystem.");
74        return nullptr;
75    }
76
77    status = napi_set_named_property(env, exports, "System", constructor);
78    if (status != napi_ok) {
79        HILOG_ERROR_I18N("Set property failed when InitSystem.");
80        return nullptr;
81    }
82    return exports;
83}
84
85napi_value I18nSystemAddon::GetDisplayCountry(napi_env env, napi_callback_info info)
86{
87    return I18nSystemAddon::GetDisplayCountryImpl(env, info, false);
88}
89
90napi_value I18nSystemAddon::GetDisplayCountryWithError(napi_env env, napi_callback_info info)
91{
92    return I18nSystemAddon::GetDisplayCountryImpl(env, info, true);
93}
94
95napi_value I18nSystemAddon::GetDisplayLanguage(napi_env env, napi_callback_info info)
96{
97    return I18nSystemAddon::GetDisplayLanguageImpl(env, info, false);
98}
99
100napi_value I18nSystemAddon::GetDisplayLanguageWithError(napi_env env, napi_callback_info info)
101{
102    return I18nSystemAddon::GetDisplayLanguageImpl(env, info, true);
103}
104
105napi_value I18nSystemAddon::GetSystemLanguages(napi_env env, napi_callback_info info)
106{
107    std::vector<std::string> systemLanguages;
108    LocaleConfig::GetSystemLanguages(systemLanguages);
109    napi_value result = nullptr;
110    napi_status status = napi_create_array_with_length(env, systemLanguages.size(), &result);
111    if (status != napi_ok) {
112        HILOG_ERROR_I18N("GetSystemLanguages: Failed to create array");
113        return nullptr;
114    }
115    for (size_t i = 0; i < systemLanguages.size(); i++) {
116        napi_value value = nullptr;
117        status = napi_create_string_utf8(env, systemLanguages[i].c_str(), NAPI_AUTO_LENGTH, &value);
118        if (status != napi_ok) {
119            HILOG_ERROR_I18N("GetSystemLanguages: Failed to create string item");
120            return nullptr;
121        }
122        status = napi_set_element(env, result, i, value);
123        if (status != napi_ok) {
124            HILOG_ERROR_I18N("GetSystemLanguages: Failed to set array item");
125            return nullptr;
126        }
127    }
128    return result;
129}
130
131napi_value I18nSystemAddon::GetSystemCountries(napi_env env, napi_callback_info info)
132{
133    return I18nSystemAddon::GetSystemCountriesImpl(env, info, false);
134}
135
136napi_value I18nSystemAddon::GetSystemCountriesWithError(napi_env env, napi_callback_info info)
137{
138    return I18nSystemAddon::GetSystemCountriesImpl(env, info, true);
139}
140
141napi_value I18nSystemAddon::IsSuggested(napi_env env, napi_callback_info info)
142{
143    return I18nSystemAddon::IsSuggestedImpl(env, info, false);
144}
145
146napi_value I18nSystemAddon::IsSuggestedWithError(napi_env env, napi_callback_info info)
147{
148    return I18nSystemAddon::IsSuggestedImpl(env, info, true);
149}
150
151napi_value I18nSystemAddon::GetSystemLanguage(napi_env env, napi_callback_info info)
152{
153    std::string value = LocaleConfig::GetSystemLanguage();
154    napi_value result = nullptr;
155    napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
156    if (status != napi_ok) {
157        HILOG_ERROR_I18N("GetSystemLanguage: Failed to create string item");
158        return nullptr;
159    }
160    return result;
161}
162
163napi_value I18nSystemAddon::SetSystemLanguage(napi_env env, napi_callback_info info)
164{
165    return I18nSystemAddon::SetSystemLanguageImpl(env, info, false);
166}
167
168napi_value I18nSystemAddon::SetSystemLanguageWithError(napi_env env, napi_callback_info info)
169{
170    return I18nSystemAddon::SetSystemLanguageImpl(env, info, true);
171}
172
173napi_value I18nSystemAddon::GetSystemRegion(napi_env env, napi_callback_info info)
174{
175    std::string value = LocaleConfig::GetSystemRegion();
176    napi_value result = nullptr;
177    napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
178    if (status != napi_ok) {
179        HILOG_ERROR_I18N("GetSystemRegion: Failed to create string item");
180        return nullptr;
181    }
182    return result;
183}
184
185napi_value I18nSystemAddon::SetSystemRegion(napi_env env, napi_callback_info info)
186{
187    return I18nSystemAddon::SetSystemRegionImpl(env, info, false);
188}
189
190napi_value I18nSystemAddon::SetSystemRegionWithError(napi_env env, napi_callback_info info)
191{
192    return I18nSystemAddon::SetSystemRegionImpl(env, info, true);
193}
194
195napi_value I18nSystemAddon::GetSystemLocale(napi_env env, napi_callback_info info)
196{
197    std::string value = LocaleConfig::GetSystemLocale();
198    napi_value result = nullptr;
199    napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
200    if (status != napi_ok) {
201        HILOG_ERROR_I18N("GetSystemLocale: Failed to create string item");
202        return nullptr;
203    }
204    return result;
205}
206
207napi_value I18nSystemAddon::SetSystemLocale(napi_env env, napi_callback_info info)
208{
209    return I18nSystemAddon::SetSystemLocaleImpl(env, info, false);
210}
211
212napi_value I18nSystemAddon::SetSystemLocaleWithError(napi_env env, napi_callback_info info)
213{
214    return I18nSystemAddon::SetSystemLocaleImpl(env, info, true);
215}
216
217napi_value I18nSystemAddon::Is24HourClock(napi_env env, napi_callback_info info)
218{
219    bool is24HourClock = LocaleConfig::Is24HourClock();
220    napi_value result = nullptr;
221    napi_status status = napi_get_boolean(env, is24HourClock, &result);
222    if (status != napi_ok) {
223        HILOG_ERROR_I18N("Failed to create boolean item");
224        return nullptr;
225    }
226    return result;
227}
228
229napi_value I18nSystemAddon::Set24HourClock(napi_env env, napi_callback_info info)
230{
231    return I18nSystemAddon::Set24HourClockImpl(env, info, false);
232}
233
234napi_value I18nSystemAddon::Set24HourClockWithError(napi_env env, napi_callback_info info)
235{
236    return I18nSystemAddon::Set24HourClockImpl(env, info, true);
237}
238
239napi_value I18nSystemAddon::AddPreferredLanguage(napi_env env, napi_callback_info info)
240{
241    return I18nSystemAddon::AddPreferredLanguageImpl(env, info, false);
242}
243
244napi_value I18nSystemAddon::AddPreferredLanguageWithError(napi_env env, napi_callback_info info)
245{
246    return I18nSystemAddon::AddPreferredLanguageImpl(env, info, true);
247}
248
249napi_value I18nSystemAddon::RemovePreferredLanguage(napi_env env, napi_callback_info info)
250{
251    return I18nSystemAddon::RemovePreferredLanguageImpl(env, info, false);
252}
253
254napi_value I18nSystemAddon::RemovePreferredLanguageWithError(napi_env env, napi_callback_info info)
255{
256    return I18nSystemAddon::RemovePreferredLanguageImpl(env, info, true);
257}
258
259napi_value I18nSystemAddon::GetPreferredLanguageList(napi_env env, napi_callback_info info)
260{
261    std::vector<std::string> languageList = PreferredLanguage::GetPreferredLanguageList();
262    napi_value result = nullptr;
263    napi_status status = napi_ok;
264    status = napi_create_array_with_length(env, languageList.size(), &result);
265    if (status != napi_ok) {
266        HILOG_ERROR_I18N("getPreferrdLanguageList: create array failed");
267        return nullptr;
268    }
269    for (size_t i = 0; i < languageList.size(); i++) {
270        napi_value value = nullptr;
271        status = napi_create_string_utf8(env, languageList[i].c_str(), NAPI_AUTO_LENGTH, &value);
272        if (status != napi_ok) {
273            HILOG_ERROR_I18N("getPreferrdLanguageList: create string failed");
274            return nullptr;
275        }
276        status = napi_set_element(env, result, i, value);
277        if (status != napi_ok) {
278            HILOG_ERROR_I18N("GetPreferredLanguageList: set array item failed");
279            return nullptr;
280        }
281    }
282    return result;
283}
284
285napi_value I18nSystemAddon::GetFirstPreferredLanguage(napi_env env, napi_callback_info info)
286{
287    std::string language = PreferredLanguage::GetFirstPreferredLanguage();
288    napi_value result = nullptr;
289    napi_status status = napi_ok;
290    status = napi_create_string_utf8(env, language.c_str(), NAPI_AUTO_LENGTH, &result);
291    if (status != napi_ok) {
292        HILOG_ERROR_I18N("getFirstPreferrdLanguage: create string result failed");
293        return nullptr;
294    }
295    return result;
296}
297
298napi_value I18nSystemAddon::SetAppPreferredLanguage(napi_env env, napi_callback_info info)
299{
300    size_t argc = 1;
301    napi_value argv[1] = { 0 };
302    napi_value thisVar = nullptr;
303    void *data = nullptr;
304    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
305    napi_valuetype valueType = napi_valuetype::napi_undefined;
306    napi_typeof(env, argv[0], &valueType);
307    if (valueType != napi_valuetype::napi_string) {
308        HILOG_ERROR_I18N("SetAppPreferredLanguage Parameter type is not string");
309        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "language", "string", true);
310        return nullptr;
311    }
312    int code = 0;
313    std::string localeTag = VariableConvertor::GetString(env, argv[0], code);
314    if (code) {
315        HILOG_ERROR_I18N("SetAppPreferredLanguage can't get string from js param");
316        return nullptr;
317    }
318    UErrorCode icuStatus = U_ZERO_ERROR;
319    icu::Locale locale = icu::Locale::forLanguageTag(localeTag.data(), icuStatus);
320    if (U_FAILURE(icuStatus) || !(IsValidLocaleTag(locale) || localeTag.compare("default") == 0)) {
321        HILOG_ERROR_I18N("SetAppPreferredLanguage does not support this locale");
322        ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "language", "a valid language", true);
323        return nullptr;
324    }
325#ifdef SUPPORT_APP_PREFERRED_LANGUAGE
326    I18nErrorCode errCode = I18nErrorCode::SUCCESS;
327    PreferredLanguage::SetAppPreferredLanguage(localeTag, errCode);
328    if (errCode != I18nErrorCode::SUCCESS) {
329        HILOG_ERROR_I18N("SetAppPreferredLanguage: set app language to i18n app preferences failed.");
330    }
331#endif
332    return nullptr;
333}
334
335napi_value I18nSystemAddon::GetAppPreferredLanguage(napi_env env, napi_callback_info info)
336{
337#ifdef SUPPORT_APP_PREFERRED_LANGUAGE
338    std::string language = PreferredLanguage::GetAppPreferredLanguage();
339#else
340    std::string language = PreferredLanguage::GetFirstPreferredLanguage();
341#endif
342    napi_value result = nullptr;
343    napi_status status = napi_ok;
344    status = napi_create_string_utf8(env, language.c_str(), NAPI_AUTO_LENGTH, &result);
345    if (status != napi_ok) {
346        HILOG_ERROR_I18N("getAppPreferrdLanguage: create string result failed");
347        return nullptr;
348    }
349    return result;
350}
351
352napi_value I18nSystemAddon::SetUsingLocalDigitAddon(napi_env env, napi_callback_info info)
353{
354    return I18nSystemAddon::SetUsingLocalDigitAddonImpl(env, info, false);
355}
356
357napi_value I18nSystemAddon::SetUsingLocalDigitAddonWithError(napi_env env, napi_callback_info info)
358{
359    return I18nSystemAddon::SetUsingLocalDigitAddonImpl(env, info, true);
360}
361
362napi_value I18nSystemAddon::GetUsingLocalDigitAddon(napi_env env, napi_callback_info info)
363{
364    bool res = LocaleConfig::GetUsingLocalDigit();
365    napi_value value = nullptr;
366    napi_status status = napi_get_boolean(env, res, &value);
367    if (status != napi_ok) {
368        return nullptr;
369    }
370    return value;
371}
372
373napi_value I18nSystemAddon::GetDisplayCountryImpl(napi_env env, napi_callback_info info, bool throwError)
374{
375    // Need to get three parameters to get the display country.
376    size_t argc = 3;
377    napi_value argv[3] = { nullptr };
378    napi_value thisVar = nullptr;
379    void *data = nullptr;
380    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
381    if (status != napi_ok) {
382        return VariableConvertor::CreateString(env, "");
383    } else if (argc < FUNC_ARGS_COUNT) {
384        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "country or locale", "", throwError);
385        return VariableConvertor::CreateString(env, "");
386    }
387    size_t len = 0;
388    VariableConvertor::VerifyType(env, "country", "string", argv[0]);
389    napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
390    std::vector<char> localeBuf(len + 1);
391    if (!GetCountryNapiValueWithError(env, argv[0], len, localeBuf.data(), "0")) {
392        return VariableConvertor::CreateString(env, "");
393    }
394    VariableConvertor::VerifyType(env, "locale", "string", argv[1]);
395    napi_get_value_string_utf8(env, argv[1], nullptr, 0, &len);
396    std::vector<char> displayLocaleBuf(len + 1);
397    if (!GetCountryNapiValueWithError(env, argv[1], len, displayLocaleBuf.data(), "1")) {
398        return VariableConvertor::CreateString(env, "");
399    }
400    LocaleInfo localeInfo(localeBuf.data());
401    if (!LocaleConfig::IsValidRegion(localeBuf.data()) && localeInfo.GetRegion() == "") {
402        ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "country", "a valid region", throwError);
403        return VariableConvertor::CreateString(env, "");
404    } else if (!LocaleConfig::IsValidTag(displayLocaleBuf.data())) {
405        ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "locale", "a valid locale", throwError);
406        return VariableConvertor::CreateString(env, "");
407    }
408    bool sentenceCase = true;
409    if (argc > FUNC_ARGS_COUNT) {
410        napi_get_value_bool(env, argv[FUNC_ARGS_COUNT], &sentenceCase);
411    }
412    std::string value = LocaleConfig::GetDisplayRegion(localeBuf.data(), displayLocaleBuf.data(), sentenceCase);
413    if (value.length() == 0) {
414        HILOG_ERROR_I18N("GetDisplayCountryImpl: result is empty.");
415        return VariableConvertor::CreateString(env, "");
416    }
417    napi_value result = nullptr;
418    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
419    if (status != napi_ok) {
420        HILOG_ERROR_I18N("GetDisplayCountryImpl: Failed to create string item");
421        return VariableConvertor::CreateString(env, "");
422    }
423    return result;
424}
425
426bool I18nSystemAddon::GetCountryNapiValueWithError(napi_env env, napi_value napiValue, size_t len, char* valueBuf,
427    std::string index)
428{
429    napi_status status = napi_get_value_string_utf8(env, napiValue, valueBuf, len + 1, &len);
430    if (status != napi_ok) {
431        HILOG_ERROR_I18N("GetDisplayCountryImpl: Failed to get string item argv[%{public}s]", index.c_str());
432        return false;
433    }
434    return true;
435}
436
437napi_value I18nSystemAddon::GetDisplayLanguageImpl(napi_env env, napi_callback_info info, bool throwError)
438{
439    // Need to get three parameters to get the display Language.
440    size_t argc = 3;
441    napi_value argv[3] = { nullptr };
442    napi_value thisVar = nullptr;
443    void *data = nullptr;
444    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
445    if (status != napi_ok) {
446        return nullptr;
447    } else if (argc < FUNC_ARGS_COUNT) {
448        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "language or locale", "", throwError);
449        return nullptr;
450    }
451    VariableConvertor::VerifyType(env, "language", "string", argv[0]);
452    size_t len = 0;
453    napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
454    std::vector<char> localeBuf(len + 1);
455    if (!GetNapiStringValueWithError(env, argv[0], len, localeBuf.data(), "0")) {
456        return nullptr;
457    }
458    VariableConvertor::VerifyType(env, "locale", "string", argv[1]);
459    napi_get_value_string_utf8(env, argv[1], nullptr, 0, &len);
460    std::vector<char> displayLocaleBuf(len + 1);
461    if (!GetNapiStringValueWithError(env, argv[1], len, displayLocaleBuf.data(), "1")) {
462        return nullptr;
463    }
464    if (!LocaleConfig::IsValidTag(displayLocaleBuf.data())) {
465        ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "locale", "a valid locale", throwError);
466        return nullptr;
467    }
468    bool sentenceCase = true;
469    if (argc > FUNC_ARGS_COUNT) {
470        napi_get_value_bool(env, argv[FUNC_ARGS_COUNT], &sentenceCase);
471    }
472    std::string value = LocaleConfig::GetDisplayLanguage(localeBuf.data(), displayLocaleBuf.data(), sentenceCase);
473    if (value.length() == 0) {
474        HILOG_ERROR_I18N("GetDisplayLanguageImpl: result is empty.");
475        return nullptr;
476    }
477    napi_value result = nullptr;
478    status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
479    if (status != napi_ok) {
480        HILOG_ERROR_I18N("GetDisplayLanguageImpl: Failed to create string item");
481        return nullptr;
482    }
483    return result;
484}
485
486bool I18nSystemAddon::GetNapiStringValueWithError(napi_env env, napi_value napiValue, size_t len, char* valueBuf,
487    std::string index)
488{
489    napi_status status = napi_get_value_string_utf8(env, napiValue, valueBuf, len + 1, &len);
490    if (status != napi_ok) {
491        HILOG_ERROR_I18N("GetDisplayLanguageImpl: Failed to get string item argv[%{public}s]", index.c_str());
492        return false;
493    }
494    return true;
495}
496
497napi_value I18nSystemAddon::GetSystemCountriesImpl(napi_env env, napi_callback_info info, bool throwError)
498{
499    size_t argc = 1;
500    napi_value argv[1] = { nullptr };
501    napi_value thisVar = nullptr;
502    void *data = nullptr;
503    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
504    if (status != napi_ok) {
505        return nullptr;
506    } else if (argc < 1) {
507        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "language", "", throwError);
508        return nullptr;
509    }
510    VariableConvertor::VerifyType(env, "language", "string", argv[0]);
511    size_t len = 0;
512    napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
513    std::vector<char> localeBuf(len + 1);
514    status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
515    if (status != napi_ok) {
516        HILOG_ERROR_I18N("GetSystemCountriesImpl: Failed to get string item.");
517        return nullptr;
518    }
519    std::vector<std::string> systemCountries;
520    LocaleConfig::GetSystemCountries(systemCountries);
521    napi_value result = nullptr;
522    status = napi_create_array_with_length(env, systemCountries.size(), &result);
523    if (status != napi_ok) {
524        HILOG_ERROR_I18N("GetSystemCountriesImpl: Failed to create array");
525        return nullptr;
526    }
527    for (size_t i = 0; i < systemCountries.size(); i++) {
528        napi_value value = nullptr;
529        status = napi_create_string_utf8(env, systemCountries[i].c_str(), NAPI_AUTO_LENGTH, &value);
530        if (status != napi_ok) {
531            HILOG_ERROR_I18N("GetSystemCountries: Failed to create string item");
532            return nullptr;
533        }
534        status = napi_set_element(env, result, i, value);
535        if (status != napi_ok) {
536            HILOG_ERROR_I18N("GetSystemCountries: Failed to set array item");
537            return nullptr;
538        }
539    }
540    return result;
541}
542
543napi_value I18nSystemAddon::IsSuggestedImpl(napi_env env, napi_callback_info info, bool throwError)
544{
545    // Need to get two parameters to check is suggested or not.
546    size_t argc = 2;
547    napi_value argv[2] = { nullptr };
548    napi_value thisVar = nullptr;
549    void *data = nullptr;
550    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
551    if (status != napi_ok) {
552        return nullptr;
553    } else if (argc < 1) {
554        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "language", "", throwError);
555        return nullptr;
556    }
557    VariableConvertor::VerifyType(env, "language", "string", argv[0]);
558    size_t len = 0;
559    napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
560    std::vector<char> languageBuf(len + 1);
561    status = napi_get_value_string_utf8(env, argv[0], languageBuf.data(), len + 1, &len);
562    if (status != napi_ok) {
563        HILOG_ERROR_I18N("isSuggested: Failed to get string item argv[0]");
564        return nullptr;
565    }
566    bool isSuggested = false;
567    if (VariableConvertor::CheckNapiValueType(env, argv[1])) {
568        napi_get_value_string_utf8(env, argv[1], nullptr, 0, &len);
569        std::vector<char> regionBuf(len + 1);
570        status = napi_get_value_string_utf8(env, argv[1], regionBuf.data(), len + 1, &len);
571        if (status != napi_ok) {
572            HILOG_ERROR_I18N("isSuggested: Failed to get string item argv[1]");
573            return nullptr;
574        }
575        isSuggested = LocaleConfig::IsSuggested(languageBuf.data(), regionBuf.data());
576    } else {
577        isSuggested = LocaleConfig::IsSuggested(languageBuf.data());
578    }
579    napi_value result = nullptr;
580    status = napi_get_boolean(env, isSuggested, &result);
581    if (status != napi_ok) {
582        HILOG_ERROR_I18N("Create case first boolean value failed");
583        return nullptr;
584    }
585    return result;
586}
587
588napi_value I18nSystemAddon::SetSystemLanguageImpl(napi_env env, napi_callback_info info, bool throwError)
589{
590    size_t argc = 1;
591    napi_value argv[1] = { 0 };
592    napi_value thisVar = nullptr;
593    void *data = nullptr;
594    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
595    if (status != napi_ok) {
596        return nullptr;
597    }
598    if (argc < 1) {
599        HILOG_ERROR_I18N("SetSystemLanguageImpl: Missing parameter");
600        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "language", "", throwError);
601        return nullptr;
602    }
603    size_t len = 0;
604    napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
605    std::vector<char> languageBuf(len + 1);
606    status = napi_get_value_string_utf8(env, argv[0], languageBuf.data(), len + 1, &len);
607    if (status != napi_ok) {
608        HILOG_ERROR_I18N("SetSystemLanguageImpl: Failed to get string item");
609        return nullptr;
610    }
611    I18nErrorCode err = I18nServiceAbilityClient::SetSystemLanguage(languageBuf.data());
612    HILOG_INFO_I18N("I18nSystemAddon::SetSystemLanguageImpl with code %{public}d", static_cast<int32_t>(err));
613    bool success = err == I18nErrorCode::SUCCESS;
614    if (throwError) {
615        if (!success) {
616            ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, "", "", throwError);
617        }
618        return nullptr;
619    }
620    napi_value result = nullptr;
621    status = napi_get_boolean(env, success, &result);
622    if (status != napi_ok) {
623        HILOG_ERROR_I18N("SetSystemLanguageImpl: Create set system language boolean value failed");
624        return nullptr;
625    }
626    return result;
627}
628
629napi_value I18nSystemAddon::SetSystemRegionImpl(napi_env env, napi_callback_info info, bool throwError)
630{
631    size_t argc = 1;
632    napi_value argv[1] = { nullptr };
633    napi_value thisVar = nullptr;
634    void *data = nullptr;
635    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
636    if (status != napi_ok) {
637        return nullptr;
638    }
639    if (argc < 1) {
640        HILOG_ERROR_I18N("SetSystemRegionImpl: Missing parameter");
641        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "region", "", throwError);
642        return nullptr;
643    }
644    size_t len = 0;
645    napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
646    std::vector<char> regionBuf(len + 1);
647    status = napi_get_value_string_utf8(env, argv[0], regionBuf.data(), len + 1, &len);
648    if (status != napi_ok) {
649        HILOG_ERROR_I18N("SetSystemRegionImpl: Failed to get string item");
650        return nullptr;
651    }
652    I18nErrorCode err = I18nServiceAbilityClient::SetSystemRegion(regionBuf.data());
653    HILOG_INFO_I18N("I18nSystemAddon::SetSystemRegionImpl with code %{public}d", static_cast<int32_t>(err));
654    bool success = err == I18nErrorCode::SUCCESS;
655    if (throwError) {
656        if (!success) {
657            ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, "", "", throwError);
658        }
659        return nullptr;
660    }
661    napi_value result = nullptr;
662    status = napi_get_boolean(env, success, &result);
663    if (status != napi_ok) {
664        HILOG_ERROR_I18N("SetSystemRegionImpl: Create set system language boolean value failed");
665        return nullptr;
666    }
667    return result;
668}
669
670napi_value I18nSystemAddon::SetSystemLocaleImpl(napi_env env, napi_callback_info info, bool throwError)
671{
672    size_t argc = 1;
673    napi_value argv[1] = { nullptr };
674    napi_value thisVar = nullptr;
675    void *data = nullptr;
676    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
677    if (status != napi_ok) {
678        return nullptr;
679    }
680    if (argc < 1) {
681        HILOG_ERROR_I18N("SetSystemLocaleImpl: Missing parameter");
682        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "locale", "", throwError);
683        return nullptr;
684    }
685    size_t len = 0;
686    napi_get_value_string_utf8(env, argv[0], nullptr, 0, &len);
687    std::vector<char> localeBuf(len + 1);
688    status = napi_get_value_string_utf8(env, argv[0], localeBuf.data(), len + 1, &len);
689    if (status != napi_ok) {
690        HILOG_ERROR_I18N("SetSystemLocaleImpl: Failed to get string item");
691        return nullptr;
692    }
693    I18nErrorCode err = I18nServiceAbilityClient::SetSystemLocale(localeBuf.data());
694    HILOG_INFO_I18N("I18nSystemAddon::SetSystemLocaleImpl with code %{public}d", static_cast<int32_t>(err));
695    bool success = err == I18nErrorCode::SUCCESS;
696    if (throwError) {
697        if (!success) {
698            ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, "", "", throwError);
699        }
700        return nullptr;
701    }
702    napi_value result = nullptr;
703    status = napi_get_boolean(env, success, &result);
704    if (status != napi_ok) {
705        HILOG_ERROR_I18N("SetSystemLocaleImpl: Create set system language boolean value failed");
706        return nullptr;
707    }
708    return result;
709}
710
711napi_value I18nSystemAddon::Set24HourClockImpl(napi_env env, napi_callback_info info, bool throwError)
712{
713    size_t argc = 1;
714    napi_value argv[1] = { nullptr };
715    napi_value thisVar = nullptr;
716    void *data = nullptr;
717    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
718    if (status != napi_ok) {
719        return nullptr;
720    }
721    if (argc < 1) {
722        HILOG_ERROR_I18N("Set24HourClockImpl: Missing parameter");
723        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "option", "", throwError);
724        return nullptr;
725    }
726
727    bool option = false;
728    status = napi_get_value_bool(env, argv[0], &option);
729    if (status != napi_ok) {
730        HILOG_ERROR_I18N("Set24HourClockImpl: Failed to get boolean item");
731        return nullptr;
732    }
733    std::string optionStr = option ? "true" : "false";
734    I18nErrorCode err = I18nServiceAbilityClient::Set24HourClock(optionStr);
735    HILOG_INFO_I18N("I18nSystemAddon::Set24HourClock with code %{public}d", static_cast<int32_t>(err));
736    bool success = err == I18nErrorCode::SUCCESS;
737    if (throwError) {
738        if (!success) {
739            ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, "", "", throwError);
740        }
741        return nullptr;
742    }
743    napi_value result = nullptr;
744    status = napi_get_boolean(env, success, &result);
745    if (status != napi_ok) {
746        HILOG_ERROR_I18N("Create set 24HourClock boolean value failed");
747        return nullptr;
748    }
749    return result;
750}
751
752napi_value I18nSystemAddon::AddPreferredLanguageImpl(napi_env env, napi_callback_info info, bool throwError)
753{
754    size_t argc = 2;
755    napi_value argv[2] = { 0 };
756    napi_value thisVar = nullptr;
757    void *data = nullptr;
758    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
759    if (status != napi_ok) {
760        return nullptr;
761    }
762
763    std::string language;
764    if (!ParseStringParam(env, argc > 0 ? argv[0] : nullptr, throwError, language)) {
765        return nullptr;
766    }
767
768    int index = 1000000;
769    if (VariableConvertor::CheckNapiValueType(env, argc > 1 ? argv[1] : nullptr)) {
770        status = napi_get_value_int32(env, argv[1], &index);
771        if (status != napi_ok) {
772            HILOG_ERROR_I18N("addPreferrdLanguage: get index failed");
773            return nullptr;
774        }
775    }
776    I18nErrorCode err = I18nServiceAbilityClient::AddPreferredLanguage(language.data(), index);
777    HILOG_INFO_I18N("I18nSystemAddon::AddPreferredLanguageImpl with code %{public}d", static_cast<int32_t>(err));
778    if (throwError) {
779        if (err == I18nErrorCode::NO_PERMISSION) {
780            ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, "", "", throwError);
781        }
782        if (err != I18nErrorCode::SUCCESS) {
783            ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "language", "a valid language", throwError);
784        }
785        return nullptr;
786    }
787    bool addResult = true;
788    if (err != I18nErrorCode::SUCCESS) {
789        addResult = false;
790    }
791    napi_value result = nullptr;
792    status = napi_get_boolean(env, addResult, &result);
793    if (status != napi_ok) {
794        HILOG_ERROR_I18N("addPreferrdLanguage: create boolean result failed");
795        return nullptr;
796    }
797    return result;
798}
799
800napi_value I18nSystemAddon::RemovePreferredLanguageImpl(napi_env env, napi_callback_info info, bool throwError)
801{
802    size_t argc = 1;
803    napi_value argv[1] = { nullptr };
804    napi_value thisVar = nullptr;
805    void *data = nullptr;
806    int len = 0;
807    napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
808    if (status != napi_ok) {
809        return nullptr;
810    }
811    if (argc < 1) {
812        HILOG_ERROR_I18N("RemovePreferredLanguageImpl: Missing parameter");
813        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "index", "", throwError);
814        return nullptr;
815    }
816
817    napi_valuetype valueType = napi_valuetype::napi_undefined;
818    napi_typeof(env, argv[0], &valueType);
819    if (valueType != napi_valuetype::napi_number) {
820        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "index", "number", throwError);
821        return nullptr;
822    }
823    int index = 1000000;
824    status = napi_get_value_int32(env, argv[0], &index);
825    if (status != napi_ok) {
826        HILOG_ERROR_I18N("removePreferrdLanguage: get index failed");
827        return nullptr;
828    }
829    len = static_cast<int>(PreferredLanguage::GetPreferredLanguageList().size());
830    if ((index < 0 || index > len - 1) && throwError) {
831        ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "index", "within the valid range", throwError);
832        return nullptr;
833    }
834    I18nErrorCode err = I18nServiceAbilityClient::RemovePreferredLanguage(index);
835    bool success = err == I18nErrorCode::SUCCESS;
836
837    if (throwError) {
838        if (!success) {
839            ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, "", "", throwError);
840        }
841        return nullptr;
842    }
843    napi_value result = nullptr;
844    status = napi_get_boolean(env, success, &result);
845    if (status != napi_ok) {
846        HILOG_ERROR_I18N("removePreferrdLanguage: create boolean result failed");
847        return nullptr;
848    }
849    return result;
850}
851
852napi_value I18nSystemAddon::SetUsingLocalDigitAddonImpl(napi_env env, napi_callback_info info, bool throwError)
853{
854    size_t argc = 1;
855    napi_value argv[1] = { nullptr };
856    napi_value thisVar = nullptr;
857    void *data = nullptr;
858    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
859
860    if (argc < 1) {
861        HILOG_ERROR_I18N("Invalid parameter nullptr");
862        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "flag", "", throwError);
863        return nullptr;
864    }
865    napi_valuetype valueType = napi_valuetype::napi_undefined;
866    napi_typeof(env, argv[0], &valueType);
867    if (valueType != napi_valuetype::napi_boolean) {
868        HILOG_ERROR_I18N("Invalid parameter type");
869        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "flag", "boolean", throwError);
870        return nullptr;
871    }
872    bool flag = false;
873    napi_status status = napi_get_value_bool(env, argv[0], &flag);
874    if (status != napi_ok) {
875        HILOG_ERROR_I18N("Get parameter flag failed");
876        return nullptr;
877    }
878    I18nErrorCode err = I18nServiceAbilityClient::SetUsingLocalDigit(flag);
879    HILOG_INFO_I18N("I18nSystemAddon::SetUsingLocalDigitAddonImpl with code %{public}d",
880        static_cast<int32_t>(err));
881    bool res = err == I18nErrorCode::SUCCESS;
882    if (throwError) {
883        if (!res) {
884            ErrorUtil::NapiThrow(env, I18N_NO_PERMISSION, "", "", throwError);
885        }
886        return nullptr;
887    }
888    napi_value value = nullptr;
889    status = napi_get_boolean(env, res, &value);
890    if (status != napi_ok) {
891        HILOG_ERROR_I18N("Invalid result");
892        return nullptr;
893    }
894    return value;
895}
896
897bool I18nSystemAddon::ParseStringParam(napi_env env, napi_value argv, bool throwError, std::string &strParam)
898{
899    if (argv == nullptr) {
900        HILOG_ERROR_I18N("ParseStringParam: Missing parameter");
901        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "language", "", throwError);
902        return false;
903    }
904    napi_valuetype valueType = napi_valuetype::napi_undefined;
905    napi_typeof(env, argv, &valueType);
906    if (valueType != napi_valuetype::napi_string) {
907        ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "language", "string", throwError);
908        return false;
909    }
910    size_t len = 0;
911    napi_status status = napi_get_value_string_utf8(env, argv, nullptr, 0, &len);
912    if (status != napi_ok) {
913        HILOG_ERROR_I18N("get string parameter length failed");
914        return false;
915    }
916    std::vector<char> res(len + 1);
917    status = napi_get_value_string_utf8(env, argv, res.data(), len + 1, &len);
918    if (status != napi_ok) {
919        HILOG_ERROR_I18N("get string parameter failed");
920        return false;
921    }
922    strParam = res.data();
923    return true;
924}
925} // namespace I18n
926} // namespace Global
927} // namespace OHOS