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