• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "locale_config.h"
19 #include "utils.h"
20 #include "variable_convertor.h"
21 #include "system_locale_manager_addon.h"
22 
23 namespace OHOS {
24 namespace Global {
25 namespace I18n {
SystemLocaleManagerAddon()26 SystemLocaleManagerAddon::SystemLocaleManagerAddon() : env_(nullptr) {}
27 
~SystemLocaleManagerAddon()28 SystemLocaleManagerAddon::~SystemLocaleManagerAddon()
29 {
30 }
31 
Destructor(napi_env env,void * nativeObject,void * hint)32 void SystemLocaleManagerAddon::Destructor(napi_env env, void *nativeObject, void *hint)
33 {
34     if (!nativeObject) {
35         return;
36     }
37     delete reinterpret_cast<SystemLocaleManagerAddon *>(nativeObject);
38     nativeObject = nullptr;
39 }
40 
InitSystemLocaleManager(napi_env env,napi_value exports)41 napi_value SystemLocaleManagerAddon::InitSystemLocaleManager(napi_env env, napi_value exports)
42 {
43     napi_property_descriptor properties[] = {
44         DECLARE_NAPI_FUNCTION("getLanguageInfoArray", GetLanguageInfoArray),
45         DECLARE_NAPI_FUNCTION("getRegionInfoArray", GetCountryInfoArray),
46         DECLARE_NAPI_STATIC_FUNCTION("getTimeZoneCityItemArray", GetTimeZoneCityInfoArray)
47     };
48 
49     napi_value constructor = nullptr;
50     napi_status status = napi_define_class(env, "SystemLocaleManager", NAPI_AUTO_LENGTH,
51         SystemLocaleManagerConstructor, nullptr, sizeof(properties) / sizeof(napi_property_descriptor),
52         properties, &constructor);
53     if (status != napi_ok) {
54         HILOG_ERROR_I18N("Define class failed when InitSystemLocaleManager");
55         return nullptr;
56     }
57 
58     status = napi_set_named_property(env, exports, "SystemLocaleManager", constructor);
59     if (status != napi_ok) {
60         HILOG_ERROR_I18N("Set property failed when InitSystemLocaleManager");
61         return nullptr;
62     }
63     return exports;
64 }
65 
SystemLocaleManagerConstructor(napi_env env,napi_callback_info info)66 napi_value SystemLocaleManagerAddon::SystemLocaleManagerConstructor(napi_env env, napi_callback_info info)
67 {
68     if (!CheckSystemPermission()) {
69         HILOG_ERROR_I18N("Permission verification failed. A non-system application calls a system API.");
70         return nullptr;
71     }
72     napi_value thisVar = nullptr;
73     void *data = nullptr;
74     napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
75     if (status != napi_ok) {
76         return nullptr;
77     }
78     std::unique_ptr<SystemLocaleManagerAddon> obj = std::make_unique<SystemLocaleManagerAddon>();
79     if (obj == nullptr) {
80         return nullptr;
81     }
82     status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), SystemLocaleManagerAddon::Destructor,
83         nullptr, nullptr);
84     if (status != napi_ok) {
85         HILOG_ERROR_I18N("Wrap SystemLocaleManagerAddon failed");
86         return nullptr;
87     }
88     if (!obj->InitSystemLocaleManagerContext(env, info)) {
89         HILOG_ERROR_I18N("Init SystemLocaleManager failed");
90         return nullptr;
91     }
92     obj.release();
93     return thisVar;
94 }
95 
InitSystemLocaleManagerContext(napi_env env,napi_callback_info info)96 bool SystemLocaleManagerAddon::InitSystemLocaleManagerContext(napi_env env, napi_callback_info info)
97 {
98     napi_value global = nullptr;
99     napi_status status = napi_get_global(env, &global);
100     if (status != napi_ok) {
101         HILOG_ERROR_I18N("Get global failed");
102         return false;
103     }
104     env_ = env;
105     systemLocaleManager_ = std::make_unique<SystemLocaleManager>();
106 
107     return systemLocaleManager_ != nullptr;
108 }
109 
GetLanguageInfoArray(napi_env env,napi_callback_info info)110 napi_value SystemLocaleManagerAddon::GetLanguageInfoArray(napi_env env, napi_callback_info info)
111 {
112     size_t argc = 2;
113     napi_value argv[2] = { 0 };
114     napi_value thisVar = nullptr;
115     void *data = nullptr;
116     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
117     if (status != napi_ok) {
118         HILOG_ERROR_I18N("can not obtain getLanguageInfoArray function param.");
119         return nullptr;
120     }
121     if (argc < 1) {
122         ErrorUtil::NapiNotFoundError(env, I18N_NOT_FOUND, "languages", true);
123         return nullptr;
124     }
125     std::vector<std::string> languageList;
126     bool isSuccess = VariableConvertor::GetStringArrayFromJsParam(env, argv[0], "languages", languageList);
127     if (!isSuccess) {
128         return nullptr;
129     }
130     SortOptions options;
131     GetSortOptionsFromJsParam(env, argv[1], options, false);
132     SystemLocaleManagerAddon *obj = nullptr;
133     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
134     if (status != napi_ok || !obj || !obj->systemLocaleManager_) {
135         HILOG_ERROR_I18N("GetLanguageInfoArray: Get SystemLocaleManager object failed");
136         return nullptr;
137     }
138     I18nErrorCode err;
139     std::vector<LocaleItem> localeItemList =
140         obj->systemLocaleManager_->GetLanguageInfoArray(languageList, options, err);
141     if (err == I18nErrorCode::NOT_SYSTEM_APP) {
142         ErrorUtil::NapiThrow(env, I18N_NOT_SYSTEM_APP, "", "", true);
143         return nullptr;
144     }
145     napi_value result = CreateLocaleItemArray(env, localeItemList);
146     return result;
147 }
148 
GetCountryInfoArray(napi_env env,napi_callback_info info)149 napi_value SystemLocaleManagerAddon::GetCountryInfoArray(napi_env env, napi_callback_info info)
150 {
151     size_t argc = 2;
152     napi_value argv[2] = { 0 };
153     napi_value thisVar = nullptr;
154     void *data = nullptr;
155     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
156     if (status != napi_ok) {
157         HILOG_ERROR_I18N("can not obtain getCountryInfoArray function param.");
158         return nullptr;
159     }
160     if (argc < 1) {
161         ErrorUtil::NapiNotFoundError(env, I18N_NOT_FOUND, "regions", true);
162         return nullptr;
163     }
164     std::vector<std::string> countryList;
165     bool isSuccess = VariableConvertor::GetStringArrayFromJsParam(env, argv[0], "regions", countryList);
166     if (!isSuccess) {
167         return nullptr;
168     }
169     SortOptions options;
170     GetSortOptionsFromJsParam(env, argv[1], options, true);
171     SystemLocaleManagerAddon *obj = nullptr;
172     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
173     if (status != napi_ok || !obj || !obj->systemLocaleManager_) {
174         HILOG_ERROR_I18N("GetCountryInfoArray: Get SystemLocaleManager object failed");
175         return nullptr;
176     }
177     I18nErrorCode err;
178     std::vector<LocaleItem> localeItemList = obj->systemLocaleManager_->GetCountryInfoArray(countryList, options, err);
179     if (err == I18nErrorCode::NOT_SYSTEM_APP) {
180         ErrorUtil::NapiThrow(env, I18N_NOT_SYSTEM_APP, "", "", true);
181         return nullptr;
182     }
183     napi_value result = CreateLocaleItemArray(env, localeItemList);
184     return result;
185 }
186 
GetTimeZoneCityInfoArray(napi_env env,napi_callback_info info)187 napi_value SystemLocaleManagerAddon::GetTimeZoneCityInfoArray(napi_env env, napi_callback_info info)
188 {
189     I18nErrorCode err;
190     std::vector<TimeZoneCityItem> timezoneCityItemList = SystemLocaleManager::GetTimezoneCityInfoArray(err);
191     if (err == I18nErrorCode::NOT_SYSTEM_APP) {
192         ErrorUtil::NapiThrow(env, I18N_NOT_SYSTEM_APP, "", "", true);
193         return nullptr;
194     }
195     napi_value result = nullptr;
196     napi_status status = napi_create_array_with_length(env, timezoneCityItemList.size(), &result);
197     if (status != napi_ok) {
198         HILOG_ERROR_I18N("create TimeZoneCityItem array failed.");
199         return nullptr;
200     }
201     for (size_t i = 0; i < timezoneCityItemList.size(); ++i) {
202         napi_value item = CreateTimeZoneCityItem(env, timezoneCityItemList[i]);
203         status = napi_set_element(env, result, i, item);
204         if (status != napi_ok) {
205             HILOG_ERROR_I18N("Failed to set TimeZoneCityItem element.");
206             return nullptr;
207         }
208     }
209     return result;
210 }
211 
CreateTimeZoneCityItem(napi_env env,const TimeZoneCityItem & timezoneCityItem)212 napi_value SystemLocaleManagerAddon::CreateTimeZoneCityItem(napi_env env, const TimeZoneCityItem &timezoneCityItem)
213 {
214     napi_value result;
215     napi_status status = napi_create_object(env, &result);
216     if (status != napi_ok) {
217         HILOG_ERROR_I18N("CreateTimeZoneCityItem: Create Locale Item object failed.");
218         return nullptr;
219     }
220     status = napi_set_named_property(env, result, "zoneId",
221         VariableConvertor::CreateString(env, timezoneCityItem.zoneId));
222     if (status != napi_ok) {
223         HILOG_ERROR_I18N("Failed to set element zoneId.");
224         return nullptr;
225     }
226     status = napi_set_named_property(env, result, "cityId",
227         VariableConvertor::CreateString(env, timezoneCityItem.cityId));
228     if (status != napi_ok) {
229         HILOG_ERROR_I18N("Failed to set element cityId.");
230         return nullptr;
231     }
232     status = napi_set_named_property(env, result, "cityDisplayName",
233         VariableConvertor::CreateString(env, timezoneCityItem.cityDisplayName));
234     if (status != napi_ok) {
235         HILOG_ERROR_I18N("Failed to set element cityDisplayName.");
236         return nullptr;
237     }
238     status = napi_set_named_property(env, result, "offset",
239         VariableConvertor::CreateNumber(env, timezoneCityItem.offset));
240     if (status != napi_ok) {
241         HILOG_ERROR_I18N("Failed to set element offset.");
242         return nullptr;
243     }
244     status = napi_set_named_property(env, result, "zoneDisplayName",
245         VariableConvertor::CreateString(env, timezoneCityItem.zoneDisplayName));
246     if (status != napi_ok) {
247         HILOG_ERROR_I18N("Failed to set element zoneDisplayName.");
248         return nullptr;
249     }
250     if (timezoneCityItem.rawOffset != 0) {
251         status = napi_set_named_property(env, result, "rawOffset",
252             VariableConvertor::CreateNumber(env, timezoneCityItem.rawOffset));
253         if (status != napi_ok) {
254             HILOG_ERROR_I18N("Failed to set element rawOffset.");
255             return nullptr;
256         }
257     }
258     return result;
259 }
260 
GetSortOptionsFromJsParam(napi_env env,napi_value & jsOptions,SortOptions & options,bool isRegion)261 void SystemLocaleManagerAddon::GetSortOptionsFromJsParam(napi_env env, napi_value &jsOptions, SortOptions &options,
262     bool isRegion)
263 {
264     std::string localeTag;
265     bool isUseLocalName = true;
266     bool isSuggestedFirst = true;
267     if (jsOptions == nullptr) {
268         localeTag = LocaleConfig::GetEffectiveLocale();
269         if (isRegion) {
270             isUseLocalName = false;
271         }
272     } else {
273         VariableConvertor::GetOptionValue(env, jsOptions, "locale", localeTag);
274         if (localeTag.length() == 0) {
275             localeTag = LocaleConfig::GetEffectiveLocale();
276         }
277         bool isSuccess = VariableConvertor::GetBoolOptionValue(env, jsOptions, "isUseLocalName", isUseLocalName);
278         if (!isSuccess && isRegion) {
279             isUseLocalName = false;
280         }
281         VariableConvertor::GetBoolOptionValue(env, jsOptions, "isSuggestedFirst", isSuggestedFirst);
282     }
283     options.localeTag = localeTag;
284     options.isUseLocalName = isUseLocalName;
285     options.isSuggestedFirst = isSuggestedFirst;
286 }
287 
CreateLocaleItemArray(napi_env env,const std::vector<LocaleItem> & localeItemList)288 napi_value SystemLocaleManagerAddon::CreateLocaleItemArray(napi_env env, const std::vector<LocaleItem> &localeItemList)
289 {
290     napi_value result = nullptr;
291     napi_status status = napi_create_array_with_length(env, localeItemList.size(), &result);
292     if (status != napi_ok) {
293         HILOG_ERROR_I18N("create LocaleItem array failed.");
294         return nullptr;
295     }
296     for (size_t i = 0; i < localeItemList.size(); ++i) {
297         napi_value item = CreateLocaleItem(env, localeItemList[i]);
298         status = napi_set_element(env, result, i, item);
299         if (status != napi_ok) {
300             HILOG_ERROR_I18N("Failed to set LocaleItem element.");
301             return nullptr;
302         }
303     }
304     return result;
305 }
306 
CreateLocaleItem(napi_env env,const LocaleItem & localeItem)307 napi_value SystemLocaleManagerAddon::CreateLocaleItem(napi_env env, const LocaleItem &localeItem)
308 {
309     napi_value result;
310     napi_status status = napi_create_object(env, &result);
311     if (status != napi_ok) {
312         HILOG_ERROR_I18N("CreateLocaleItem: Create Locale Item object failed.");
313         return nullptr;
314     }
315     status = napi_set_named_property(env, result, "id", VariableConvertor::CreateString(env, localeItem.id));
316     if (status != napi_ok) {
317         HILOG_ERROR_I18N("Failed to set element id.");
318         return nullptr;
319     }
320     status = napi_set_named_property(env, result, "displayName",
321         VariableConvertor::CreateString(env, localeItem.displayName));
322     if (status != napi_ok) {
323         HILOG_ERROR_I18N("Failed to set element displayName.");
324         return nullptr;
325     }
326     if (localeItem.localName.length() != 0) {
327         status = napi_set_named_property(env, result, "localName",
328             VariableConvertor::CreateString(env, localeItem.localName));
329         if (status != napi_ok) {
330             HILOG_ERROR_I18N("Failed to set element localName.");
331             return nullptr;
332         }
333     }
334     status = napi_set_named_property(env, result, "suggestionType", CreateSuggestionType(env,
335         localeItem.suggestionType));
336     if (status != napi_ok) {
337         HILOG_ERROR_I18N("Failed to set element suggestionType.");
338         return nullptr;
339     }
340     return result;
341 }
342 
CreateSuggestionType(napi_env env,SuggestionType suggestionType)343 napi_value SystemLocaleManagerAddon::CreateSuggestionType(napi_env env, SuggestionType suggestionType)
344 {
345     napi_value result;
346     napi_status status = napi_create_int32(env, static_cast<int32_t>(suggestionType), &result);
347     if (status != napi_ok) {
348         HILOG_ERROR_I18N("create SuggestionType failed.");
349         return nullptr;
350     }
351     return result;
352 }
353 } // namespace I18n
354 } // namespace Global
355 } // namespace OHOS