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 
28 namespace OHOS {
29 namespace Global {
30 namespace I18n {
I18nSystemAddon()31 I18nSystemAddon::I18nSystemAddon() {}
32 
~I18nSystemAddon()33 I18nSystemAddon::~I18nSystemAddon() {}
34 
Destructor(napi_env env,void * nativeObject,void * finalize_hint)35 void 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 
InitI18nSystem(napi_env env,napi_value exports)44 napi_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 
GetDisplayCountry(napi_env env,napi_callback_info info)85 napi_value I18nSystemAddon::GetDisplayCountry(napi_env env, napi_callback_info info)
86 {
87     return I18nSystemAddon::GetDisplayCountryImpl(env, info, false);
88 }
89 
GetDisplayCountryWithError(napi_env env,napi_callback_info info)90 napi_value I18nSystemAddon::GetDisplayCountryWithError(napi_env env, napi_callback_info info)
91 {
92     return I18nSystemAddon::GetDisplayCountryImpl(env, info, true);
93 }
94 
GetDisplayLanguage(napi_env env,napi_callback_info info)95 napi_value I18nSystemAddon::GetDisplayLanguage(napi_env env, napi_callback_info info)
96 {
97     return I18nSystemAddon::GetDisplayLanguageImpl(env, info, false);
98 }
99 
GetDisplayLanguageWithError(napi_env env,napi_callback_info info)100 napi_value I18nSystemAddon::GetDisplayLanguageWithError(napi_env env, napi_callback_info info)
101 {
102     return I18nSystemAddon::GetDisplayLanguageImpl(env, info, true);
103 }
104 
GetSystemLanguages(napi_env env,napi_callback_info info)105 napi_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 
GetSystemCountries(napi_env env,napi_callback_info info)131 napi_value I18nSystemAddon::GetSystemCountries(napi_env env, napi_callback_info info)
132 {
133     return I18nSystemAddon::GetSystemCountriesImpl(env, info, false);
134 }
135 
GetSystemCountriesWithError(napi_env env,napi_callback_info info)136 napi_value I18nSystemAddon::GetSystemCountriesWithError(napi_env env, napi_callback_info info)
137 {
138     return I18nSystemAddon::GetSystemCountriesImpl(env, info, true);
139 }
140 
IsSuggested(napi_env env,napi_callback_info info)141 napi_value I18nSystemAddon::IsSuggested(napi_env env, napi_callback_info info)
142 {
143     return I18nSystemAddon::IsSuggestedImpl(env, info, false);
144 }
145 
IsSuggestedWithError(napi_env env,napi_callback_info info)146 napi_value I18nSystemAddon::IsSuggestedWithError(napi_env env, napi_callback_info info)
147 {
148     return I18nSystemAddon::IsSuggestedImpl(env, info, true);
149 }
150 
GetSystemLanguage(napi_env env,napi_callback_info info)151 napi_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 
SetSystemLanguage(napi_env env,napi_callback_info info)163 napi_value I18nSystemAddon::SetSystemLanguage(napi_env env, napi_callback_info info)
164 {
165     return I18nSystemAddon::SetSystemLanguageImpl(env, info, false);
166 }
167 
SetSystemLanguageWithError(napi_env env,napi_callback_info info)168 napi_value I18nSystemAddon::SetSystemLanguageWithError(napi_env env, napi_callback_info info)
169 {
170     return I18nSystemAddon::SetSystemLanguageImpl(env, info, true);
171 }
172 
GetSystemRegion(napi_env env,napi_callback_info info)173 napi_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 
SetSystemRegion(napi_env env,napi_callback_info info)185 napi_value I18nSystemAddon::SetSystemRegion(napi_env env, napi_callback_info info)
186 {
187     return I18nSystemAddon::SetSystemRegionImpl(env, info, false);
188 }
189 
SetSystemRegionWithError(napi_env env,napi_callback_info info)190 napi_value I18nSystemAddon::SetSystemRegionWithError(napi_env env, napi_callback_info info)
191 {
192     return I18nSystemAddon::SetSystemRegionImpl(env, info, true);
193 }
194 
GetSystemLocale(napi_env env,napi_callback_info info)195 napi_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 
SetSystemLocale(napi_env env,napi_callback_info info)207 napi_value I18nSystemAddon::SetSystemLocale(napi_env env, napi_callback_info info)
208 {
209     return I18nSystemAddon::SetSystemLocaleImpl(env, info, false);
210 }
211 
SetSystemLocaleWithError(napi_env env,napi_callback_info info)212 napi_value I18nSystemAddon::SetSystemLocaleWithError(napi_env env, napi_callback_info info)
213 {
214     return I18nSystemAddon::SetSystemLocaleImpl(env, info, true);
215 }
216 
Is24HourClock(napi_env env,napi_callback_info info)217 napi_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 
Set24HourClock(napi_env env,napi_callback_info info)229 napi_value I18nSystemAddon::Set24HourClock(napi_env env, napi_callback_info info)
230 {
231     return I18nSystemAddon::Set24HourClockImpl(env, info, false);
232 }
233 
Set24HourClockWithError(napi_env env,napi_callback_info info)234 napi_value I18nSystemAddon::Set24HourClockWithError(napi_env env, napi_callback_info info)
235 {
236     return I18nSystemAddon::Set24HourClockImpl(env, info, true);
237 }
238 
AddPreferredLanguage(napi_env env,napi_callback_info info)239 napi_value I18nSystemAddon::AddPreferredLanguage(napi_env env, napi_callback_info info)
240 {
241     return I18nSystemAddon::AddPreferredLanguageImpl(env, info, false);
242 }
243 
AddPreferredLanguageWithError(napi_env env,napi_callback_info info)244 napi_value I18nSystemAddon::AddPreferredLanguageWithError(napi_env env, napi_callback_info info)
245 {
246     return I18nSystemAddon::AddPreferredLanguageImpl(env, info, true);
247 }
248 
RemovePreferredLanguage(napi_env env,napi_callback_info info)249 napi_value I18nSystemAddon::RemovePreferredLanguage(napi_env env, napi_callback_info info)
250 {
251     return I18nSystemAddon::RemovePreferredLanguageImpl(env, info, false);
252 }
253 
RemovePreferredLanguageWithError(napi_env env,napi_callback_info info)254 napi_value I18nSystemAddon::RemovePreferredLanguageWithError(napi_env env, napi_callback_info info)
255 {
256     return I18nSystemAddon::RemovePreferredLanguageImpl(env, info, true);
257 }
258 
GetPreferredLanguageList(napi_env env,napi_callback_info info)259 napi_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 
GetFirstPreferredLanguage(napi_env env,napi_callback_info info)285 napi_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 
SetAppPreferredLanguage(napi_env env,napi_callback_info info)298 napi_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 
GetAppPreferredLanguage(napi_env env,napi_callback_info info)335 napi_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 
SetUsingLocalDigitAddon(napi_env env,napi_callback_info info)352 napi_value I18nSystemAddon::SetUsingLocalDigitAddon(napi_env env, napi_callback_info info)
353 {
354     return I18nSystemAddon::SetUsingLocalDigitAddonImpl(env, info, false);
355 }
356 
SetUsingLocalDigitAddonWithError(napi_env env,napi_callback_info info)357 napi_value I18nSystemAddon::SetUsingLocalDigitAddonWithError(napi_env env, napi_callback_info info)
358 {
359     return I18nSystemAddon::SetUsingLocalDigitAddonImpl(env, info, true);
360 }
361 
GetUsingLocalDigitAddon(napi_env env,napi_callback_info info)362 napi_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 
GetDisplayCountryImpl(napi_env env,napi_callback_info info,bool throwError)373 napi_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 
GetCountryNapiValueWithError(napi_env env,napi_value napiValue,size_t len,char * valueBuf,std::string index)426 bool 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 
GetDisplayLanguageImpl(napi_env env,napi_callback_info info,bool throwError)437 napi_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 
GetNapiStringValueWithError(napi_env env,napi_value napiValue,size_t len,char * valueBuf,std::string index)486 bool 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 
GetSystemCountriesImpl(napi_env env,napi_callback_info info,bool throwError)497 napi_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 
IsSuggestedImpl(napi_env env,napi_callback_info info,bool throwError)543 napi_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 
SetSystemLanguageImpl(napi_env env,napi_callback_info info,bool throwError)588 napi_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 
SetSystemRegionImpl(napi_env env,napi_callback_info info,bool throwError)629 napi_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 
SetSystemLocaleImpl(napi_env env,napi_callback_info info,bool throwError)670 napi_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 
Set24HourClockImpl(napi_env env,napi_callback_info info,bool throwError)711 napi_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 
AddPreferredLanguageImpl(napi_env env,napi_callback_info info,bool throwError)752 napi_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 
RemovePreferredLanguageImpl(napi_env env,napi_callback_info info,bool throwError)800 napi_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 
SetUsingLocalDigitAddonImpl(napi_env env,napi_callback_info info,bool throwError)852 napi_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 
ParseStringParam(napi_env env,napi_value argv,bool throwError,std::string & strParam)897 bool 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