1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <regex>
16 #include "accesstoken_kit.h"
17 #ifdef SUPPORT_GRAPHICS
18 #include "app_mgr_client.h"
19 #include "ability_manager_client.h"
20 #include "configuration.h"
21 #include <common_event_data.h>
22 #include <common_event_manager.h>
23 #include <common_event_publish_info.h>
24 #include <common_event_support.h>
25 #endif
26 #include <cctype>
27 #include "hilog/log.h"
28 #include "ipc_skeleton.h"
29 #include "libxml/parser.h"
30 #include "locale_info.h"
31 #include "localebuilder.h"
32 #include "locdspnm.h"
33 #include "locid.h"
34 #include "ohos/init_data.h"
35 #include "parameter.h"
36 #include "securec.h"
37 #include "string_ex.h"
38 #include "ucase.h"
39 #include "ulocimp.h"
40 #include "unistr.h"
41 #include "ureslocs.h"
42 #include "ustring.h"
43 #include "ustr_imp.h"
44 #include "utils.h"
45 #include "tokenid_kit.h"
46 #include "locale_config.h"
47
48 namespace OHOS {
49 namespace Global {
50 namespace I18n {
51 using namespace std;
52 using namespace OHOS::HiviewDFX;
53
54 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0xD001E00, "LocaleConfig" };
55 const char *LocaleConfig::LANGUAGE_KEY = "persist.global.language";
56 const char *LocaleConfig::LOCALE_KEY = "persist.global.locale";
57 const char *LocaleConfig::HOUR_KEY = "persist.global.is24Hour";
58 const char *LocaleConfig::DEFAULT_LOCALE_KEY = "const.global.locale";
59 const char *LocaleConfig::DEFAULT_LANGUAGE_KEY = "const.global.language";
60 const char *LocaleConfig::DEFAULT_REGION_KEY = "const.global.region";
61 const char *LocaleConfig::SIM_COUNTRY_CODE_KEY = "telephony.sim.countryCode0";
62 const char *LocaleConfig::SUPPORTED_LOCALES_NAME = "supported_locales";
63 const char *LocaleConfig::SUPPORTED_REGIONS_NAME = "supported_regions";
64 const char *LocaleConfig::WHITE_LANGUAGES_NAME = "white_languages";
65 const char *LocaleConfig::FORBIDDEN_LANGUAGES_NAME = "forbidden_languages";
66 const char *LocaleConfig::FORBIDDEN_REGIONS_NAME = "forbidden_regions";
67 const char *LocaleConfig::FORBIDDEN_LANGUAGES_PATH = "/system/usr/ohos_locale_config/forbidden_languages.xml";
68 const char *LocaleConfig::FORBIDDEN_REGIONS_PATH = "/system/usr/ohos_locale_config/forbidden_regions.xml";
69 const char *LocaleConfig::SUPPORTED_LOCALES_PATH = "/system/usr/ohos_locale_config/supported_locales.xml";
70 const char *LocaleConfig::SUPPORTED_REGIONS_PATH = "/system/usr/ohos_locale_config/supported_regions.xml";
71 const char *LocaleConfig::WHITE_LANGUAGES_PATH = "/system/usr/ohos_locale_config/white_languages.xml";
72 const char *LocaleConfig::SUPPORT_LOCALES_PATH = "/etc/ohos_lang_config/supported_locales.xml";
73 const char *LocaleConfig::SUPPORT_LOCALES_NAME = "supported_locales";
74 const char *LocaleConfig::DIALECT_LANGS_PATH = "/system/usr/ohos_locale_config/dialect_languages.xml";
75 const char *LocaleConfig::DIALECT_LANGS_NAME = "dialect_langs";
76 const char *LocaleConfig::OVERRIDE_SUPPORTED_REGIONS_NAME = "supported_regions";
77 const char *LocaleConfig::OVERRIDE_SUPPORTED_REGIONS_PATH =
78 "/system/usr/ohos_locale_config/region/supported_regions.xml";
79 const char *LocaleConfig::DEFAULT_LOCALE = "en-Latn";
80 const char *LocaleConfig::supportLocalesTag = "supported_locales";
81 const char *LocaleConfig::LANG_PATH = "/etc/ohos_lang_config/";
82 const char *LocaleConfig::REGION_PATH = "/system/usr/ohos_locale_config/region/";
83 const char *LocaleConfig::rootTag = "languages";
84 const char *LocaleConfig::secondRootTag = "lang";
85 const char *LocaleConfig::rootRegion = "regions";
86 const char *LocaleConfig::secondRootRegion = "region";
87 unordered_set<string> LocaleConfig::supportedLocales;
88 unordered_set<string> LocaleConfig::supportLocales;
89 unordered_set<string> LocaleConfig::supportedRegions;
90 unordered_set<string> LocaleConfig::overrideSupportedRegions;
91 unordered_set<string> LocaleConfig::dialectLang;
92 unordered_set<string> LocaleConfig::blockedLanguages;
93 unordered_set<string> LocaleConfig::blockedRegions;
94 unordered_map<string, unordered_set<string>> LocaleConfig::blockedLanguageRegions;
95 unordered_set<string> LocaleConfig::whiteLanguages;
96 unordered_map<string, string> LocaleConfig::dialectMap {
97 { "es-Latn-419", "es-Latn-419" },
98 { "es-Latn-BO", "es-Latn-419" },
99 { "es-Latn-BR", "es-Latn-419" },
100 { "es-Latn-BZ", "es-Latn-419" },
101 { "es-Latn-CL", "es-Latn-419" },
102 { "es-Latn-CO", "es-Latn-419" },
103 { "es-Latn-CR", "es-Latn-419" },
104 { "es-Latn-CU", "es-Latn-419" },
105 { "es-Latn-DO", "es-Latn-419" },
106 { "es-Latn-EC", "es-Latn-419" },
107 { "es-Latn-GT", "es-Latn-419" },
108 { "es-Latn-HN", "es-Latn-419" },
109 { "es-Latn-MX", "es-Latn-419" },
110 { "es-Latn-NI", "es-Latn-419" },
111 { "es-Latn-PA", "es-Latn-419" },
112 { "es-Latn-PE", "es-Latn-419" },
113 { "es-Latn-PR", "es-Latn-419" },
114 { "es-Latn-PY", "es-Latn-419" },
115 { "es-Latn-SV", "es-Latn-419" },
116 { "es-Latn-US", "es-Latn-419" },
117 { "es-Latn-UY", "es-Latn-419" },
118 { "es-Latn-VE", "es-Latn-419" },
119 { "pt-Latn-PT", "pt-Latn-PT" },
120 { "en-Latn-US", "en-Latn-US" }
121 };
122
123 unordered_map<string, string> LocaleConfig::localDigitMap {
124 { "ar", "arab" },
125 { "as", "beng" },
126 { "bn", "beng" },
127 { "fa", "arabext" },
128 { "mr", "deva" },
129 { "my", "mymr" },
130 { "ne", "deva" },
131 { "ur", "latn" }
132 };
133
134 std::map<std::string, std::string> LocaleConfig::supportedDialectLocales;
135 std::map<string, string> LocaleConfig::locale2DisplayName {};
136 std::map<string, string> LocaleConfig::region2DisplayName {};
137 std::string LocaleConfig::currentDialectLocale = "";
138 std::string LocaleConfig::currentOverrideRegion = "";
139
140 set<std::string> LocaleConfig::validCaTag {
141 "buddhist",
142 "chinese",
143 "coptic",
144 "dangi",
145 "ethioaa",
146 "ethiopic",
147 "gregory",
148 "hebrew",
149 "indian",
150 "islamic",
151 "islamic-umalqura",
152 "islamic-tbla",
153 "islamic-civil",
154 "islamic-rgsa",
155 "iso8601",
156 "japanese",
157 "persian",
158 "roc",
159 "islamicc",
160 };
161 set<std::string> LocaleConfig::validCoTag {
162 "big5han",
163 "compat",
164 "dict",
165 "direct",
166 "ducet",
167 "eor",
168 "gb2312",
169 "phonebk",
170 "phonetic",
171 "pinyin",
172 "reformed",
173 "searchjl",
174 "stroke",
175 "trad",
176 "unihan",
177 "zhuyin",
178 };
179 set<std::string> LocaleConfig::validKnTag {
180 "true",
181 "false",
182 };
183 set<std::string> LocaleConfig::validKfTag {
184 "upper",
185 "lower",
186 "false",
187 };
188 set<std::string> LocaleConfig::validNuTag {
189 "adlm", "ahom", "arab", "arabext", "bali", "beng",
190 "bhks", "brah", "cakm", "cham", "deva", "diak",
191 "fullwide", "gong", "gonm", "gujr", "guru", "hanidec",
192 "hmng", "hmnp", "java", "kali", "khmr", "knda",
193 "lana", "lanatham", "laoo", "latn", "lepc", "limb",
194 "mathbold", "mathdbl", "mathmono", "mathsanb", "mathsans", "mlym",
195 "modi", "mong", "mroo", "mtei", "mymr", "mymrshan",
196 "mymrtlng", "newa", "nkoo", "olck", "orya", "osma",
197 "rohg", "saur", "segment", "shrd", "sind", "sinh",
198 "sora", "sund", "takr", "talu", "tamldec", "telu",
199 "thai", "tibt", "tirh", "vaii", "wara", "wcho",
200 };
201 set<std::string> LocaleConfig::validHcTag {
202 "h12",
203 "h23",
204 "h11",
205 "h24",
206 };
207
208 static unordered_map<string, string> g_languageMap = {
209 { "zh-Hans", "zh-Hans" },
210 { "zh-Hant", "zh-Hant" },
211 { "my-Qaag", "my-Qaag" },
212 { "es-Latn-419", "es-419" },
213 { "es-Latn-US", "es-419" },
214 { "az-Latn", "az-Latn" },
215 { "bs-Latn", "bs-Latn" },
216 { "en-Qaag", "en-Qaag" },
217 { "uz-Latn", "uz-Latn" },
218 { "sr-Latn", "sr-Latn" },
219 { "jv-Latn", "jv-Latn" },
220 { "pt-Latn-BR", "pt-BR" },
221 { "pa-Guru", "pa-Guru" },
222 { "mai-Deva", "mai-Deva" }
223 };
224
Adjust(const string & origin)225 string Adjust(const string &origin)
226 {
227 for (auto iter = g_languageMap.begin(); iter != g_languageMap.end(); ++iter) {
228 string key = iter->first;
229 if (!origin.compare(0, key.length(), key)) {
230 return iter->second;
231 }
232 }
233 return origin;
234 }
235
GetDisplayLanguageInner(const string & language,const string & displayLocaleTag,bool sentenceCase)236 string GetDisplayLanguageInner(const string &language, const string &displayLocaleTag, bool sentenceCase)
237 {
238 icu::UnicodeString unistr;
239 // 0 is the start position of language, 2 is the length of zh and fa
240 if (!language.compare(0, 2, "zh") || !language.compare(0, 2, "fa") || !language.compare(0, 2, "ro")) {
241 UErrorCode status = U_ZERO_ERROR;
242 icu::Locale displayLocale = icu::Locale::forLanguageTag(displayLocaleTag.c_str(), status);
243 if (status != U_ZERO_ERROR) {
244 return "";
245 }
246 icu::LocaleDisplayNames *dspNames = icu::LocaleDisplayNames::createInstance(displayLocale,
247 UDialectHandling::ULDN_DIALECT_NAMES);
248 icu::Locale tempLocale = icu::Locale::forLanguageTag(language.c_str(), status);
249 if (status != U_ZERO_ERROR) {
250 return "";
251 }
252 if (dspNames != nullptr) {
253 dspNames->localeDisplayName(tempLocale, unistr);
254 delete dspNames;
255 }
256 } else {
257 UErrorCode status = U_ZERO_ERROR;
258 icu::Locale displayLoc = icu::Locale::forLanguageTag(displayLocaleTag, status);
259 if (status != U_ZERO_ERROR) {
260 return "";
261 }
262 icu::Locale locale = icu::Locale::forLanguageTag(language, status);
263 if (status != U_ZERO_ERROR) {
264 return "";
265 }
266 locale.getDisplayName(displayLoc, unistr);
267 }
268 if (sentenceCase) {
269 UChar32 ch = ucase_toupper(unistr.char32At(0));
270 unistr.replace(0, 1, ch);
271 }
272 string out;
273 unistr.toUTF8String(out);
274 return out;
275 }
276
277 bool LocaleConfig::listsInitialized = LocaleConfig::InitializeLists();
278
GetSystemLanguage()279 string LocaleConfig::GetSystemLanguage()
280 {
281 std::string systemLanguage = ReadSystemParameter(LANGUAGE_KEY, CONFIG_LEN);
282 if (systemLanguage.empty()) {
283 systemLanguage = ReadSystemParameter(DEFAULT_LANGUAGE_KEY, CONFIG_LEN);
284 }
285 return systemLanguage;
286 }
287
GetSystemRegion()288 string LocaleConfig::GetSystemRegion()
289 {
290 UErrorCode status = U_ZERO_ERROR;
291 const char *country = nullptr;
292 std::string systemRegion = ReadSystemParameter(LOCALE_KEY, CONFIG_LEN);
293 if (!systemRegion.empty()) {
294 icu::Locale origin = icu::Locale::forLanguageTag(systemRegion, status);
295 if (U_SUCCESS(status)) {
296 country = origin.getCountry();
297 if (country != nullptr) {
298 return country;
299 }
300 }
301 }
302 systemRegion = ReadSystemParameter(DEFAULT_LOCALE_KEY, CONFIG_LEN);
303 if (!systemRegion.empty()) {
304 status = U_ZERO_ERROR;
305 icu::Locale origin = icu::Locale::forLanguageTag(systemRegion, status);
306 if (U_SUCCESS(status)) {
307 country = origin.getCountry();
308 if (country != nullptr) {
309 return country;
310 }
311 }
312 }
313 return "";
314 }
315
GetSystemLocale()316 string LocaleConfig::GetSystemLocale()
317 {
318 std::string systemLocale = ReadSystemParameter(LOCALE_KEY, CONFIG_LEN);
319 if (systemLocale.empty()) {
320 systemLocale = ReadSystemParameter(DEFAULT_LOCALE_KEY, CONFIG_LEN);
321 }
322 return systemLocale;
323 }
324
CheckPermission()325 bool LocaleConfig::CheckPermission()
326 {
327 uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID();
328 bool isSystemApp = OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(tokenId);
329 if (!isSystemApp) {
330 HiLog::Info(LABEL,
331 "LocaleConfig::CheckPermission: Get permission failed, because current app is not system app");
332 return false;
333 }
334 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
335 int result = Security::AccessToken::PermissionState::PERMISSION_GRANTED;
336 if (Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken) ==
337 Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) {
338 result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken,
339 "ohos.permission.UPDATE_CONFIGURATION");
340 } else {
341 HiLog::Info(LABEL, "Invlid tokenID");
342 return false;
343 }
344 if (result != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
345 HiLog::Info(LABEL, "Verify permission failed");
346 return false;
347 }
348 return true;
349 }
350
SetSystemLanguage(const string & language)351 bool LocaleConfig::SetSystemLanguage(const string &language)
352 {
353 if (!CheckPermission()) {
354 return false;
355 }
356 if (!IsValidTag(language)) {
357 return false;
358 }
359 std::string oldLanguage = GetSystemLanguage();
360 if (SetParameter(LANGUAGE_KEY, language.data()) == 0) {
361 bool isUpdateSuccess = UpdateSystemLocale(language);
362 if (isUpdateSuccess) {
363 #ifdef SUPPORT_GRAPHICS
364 auto appMgrClient = std::make_unique<AppExecFwk::AppMgrClient>();
365 AppExecFwk::Configuration configuration;
366 configuration.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE, language);
367 appMgrClient->UpdateConfiguration(configuration);
368
369 OHOS::AAFwk::Want localeChangeWant;
370 localeChangeWant.SetAction(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_LOCALE_CHANGED);
371 OHOS::EventFwk::CommonEventData event(localeChangeWant);
372 if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(event)) {
373 HiLog::Info(LABEL, "Failed to Publish event %{public}s", localeChangeWant.GetAction().c_str());
374 return false;
375 }
376 #endif
377 return true;
378 } else {
379 SetParameter(LANGUAGE_KEY, oldLanguage.data());
380 return false;
381 }
382 }
383 return false;
384 }
385
SetSystemRegion(const string & region)386 bool LocaleConfig::SetSystemRegion(const string ®ion)
387 {
388 if (!CheckPermission()) {
389 return false;
390 }
391 if (!IsValidRegion(region)) {
392 return false;
393 }
394 char value[CONFIG_LEN];
395 int code = GetParameter(LOCALE_KEY, "", value, CONFIG_LEN);
396 string newLocale;
397 if (code > 0) {
398 string tag(value, code);
399 newLocale = GetRegionChangeLocale(tag, region);
400 if (newLocale == "") {
401 return false;
402 }
403 } else {
404 icu::Locale temp("", region.c_str());
405 UErrorCode status = U_ZERO_ERROR;
406 temp.addLikelySubtags(status);
407 if (status != U_ZERO_ERROR) {
408 return false;
409 }
410 newLocale = temp.toLanguageTag<string>(status);
411 if (status != U_ZERO_ERROR) {
412 return false;
413 }
414 }
415 return SetParameter(LOCALE_KEY, newLocale.data()) == 0;
416 }
417
SetSystemLocale(const string & locale)418 bool LocaleConfig::SetSystemLocale(const string &locale)
419 {
420 if (!CheckPermission()) {
421 return false;
422 }
423 if (!IsValidTag(locale)) {
424 return false;
425 }
426 return SetParameter(LOCALE_KEY, locale.data()) == 0;
427 }
428
IsValidLanguage(const string & language)429 bool LocaleConfig::IsValidLanguage(const string &language)
430 {
431 string::size_type size = language.size();
432 if ((size != LANGUAGE_LEN) && (size != LANGUAGE_LEN + 1)) {
433 return false;
434 }
435 for (size_t i = 0; i < size; ++i) {
436 if ((language[i] > 'z') || (language[i] < 'a')) {
437 return false;
438 }
439 }
440 return true;
441 }
442
IsValidRegion(const string & region)443 bool LocaleConfig::IsValidRegion(const string ®ion)
444 {
445 string::size_type size = region.size();
446 if (size != LocaleInfo::REGION_LEN) {
447 return false;
448 }
449 for (size_t i = 0; i < LocaleInfo::REGION_LEN; ++i) {
450 if ((region[i] > 'Z') || (region[i] < 'A')) {
451 return false;
452 }
453 }
454 return true;
455 }
456
IsValidTag(const string & tag)457 bool LocaleConfig::IsValidTag(const string &tag)
458 {
459 if (!tag.size()) {
460 return false;
461 }
462 vector<string> splits;
463 Split(tag, "-", splits);
464 if (!IsValidLanguage(splits[0])) {
465 return false;
466 }
467 return true;
468 }
469
Split(const string & src,const string & sep,vector<string> & dest)470 void LocaleConfig::Split(const string &src, const string &sep, vector<string> &dest)
471 {
472 string::size_type begin = 0;
473 string::size_type end = src.find(sep);
474 while (end != string::npos) {
475 dest.push_back(src.substr(begin, end - begin));
476 begin = end + sep.size();
477 end = src.find(sep, begin);
478 }
479 if (begin != src.size()) {
480 dest.push_back(src.substr(begin));
481 }
482 }
483
484 // language in white languages should have script.
GetSystemLanguages(vector<string> & ret)485 void LocaleConfig::GetSystemLanguages(vector<string> &ret)
486 {
487 std::copy(whiteLanguages.begin(), whiteLanguages.end(), std::back_inserter(ret));
488 }
489
GetSupportedLocales()490 const unordered_set<string>& LocaleConfig::GetSupportedLocales()
491 {
492 return supportedLocales;
493 }
494
GetSupportedRegions()495 const unordered_set<string>& LocaleConfig::GetSupportedRegions()
496 {
497 return supportedRegions;
498 }
499
GetSystemCountries(vector<string> & ret)500 void LocaleConfig::GetSystemCountries(vector<string> &ret)
501 {
502 std::copy(supportedRegions.begin(), supportedRegions.end(), std::back_inserter(ret));
503 }
504
IsSuggested(const string & language)505 bool LocaleConfig::IsSuggested(const string &language)
506 {
507 unordered_set<string> relatedLocales;
508 vector<string> simCountries;
509 GetCountriesFromSim(simCountries);
510 GetRelatedLocales(relatedLocales, simCountries);
511 for (auto iter = relatedLocales.begin(); iter != relatedLocales.end();) {
512 if (whiteLanguages.find(*iter) == whiteLanguages.end()) {
513 iter = relatedLocales.erase(iter);
514 } else {
515 ++iter;
516 }
517 }
518 string mainLanguage = GetMainLanguage(language);
519 return relatedLocales.find(mainLanguage) != relatedLocales.end();
520 }
521
IsSuggested(const std::string & language,const std::string & region)522 bool LocaleConfig::IsSuggested(const std::string &language, const std::string ®ion)
523 {
524 unordered_set<string> relatedLocales;
525 vector<string> countries { region };
526 GetRelatedLocales(relatedLocales, countries);
527 for (auto iter = relatedLocales.begin(); iter != relatedLocales.end();) {
528 if (whiteLanguages.find(*iter) == whiteLanguages.end()) {
529 iter = relatedLocales.erase(iter);
530 } else {
531 ++iter;
532 }
533 }
534 string mainLanguage = GetMainLanguage(language);
535 return relatedLocales.find(mainLanguage) != relatedLocales.end();
536 }
537
GetRelatedLocales(unordered_set<string> & relatedLocales,vector<string> countries)538 void LocaleConfig::GetRelatedLocales(unordered_set<string> &relatedLocales, vector<string> countries)
539 {
540 // remove unsupported countries
541 const unordered_set<string> ®ions = GetSupportedRegions();
542 for (auto iter = countries.begin(); iter != countries.end();) {
543 if (regions.find(*iter) == regions.end()) {
544 iter = countries.erase(iter);
545 } else {
546 ++iter;
547 }
548 }
549 const unordered_set<string> &locales = GetSupportedLocales();
550 for (string locale : locales) {
551 bool find = false;
552 for (string country : countries) {
553 if (locale.find(country) != string::npos) {
554 find = true;
555 break;
556 }
557 }
558 if (!find) {
559 continue;
560 }
561 string mainLanguage = GetMainLanguage(locale);
562 if (mainLanguage != "") {
563 relatedLocales.insert(mainLanguage);
564 }
565 }
566 }
567
GetCountriesFromSim(vector<string> & simCountries)568 void LocaleConfig::GetCountriesFromSim(vector<string> &simCountries)
569 {
570 simCountries.push_back(GetSystemRegion());
571 char value[CONFIG_LEN];
572 int code = GetParameter(SIM_COUNTRY_CODE_KEY, "", value, CONFIG_LEN);
573 if (code > 0) {
574 simCountries.push_back(value);
575 }
576 }
577
GetListFromFile(const char * path,const char * resourceName,unordered_set<string> & ret)578 void LocaleConfig::GetListFromFile(const char *path, const char *resourceName, unordered_set<string> &ret)
579 {
580 xmlKeepBlanksDefault(0);
581 if (!path) {
582 return;
583 }
584 xmlDocPtr doc = xmlParseFile(path);
585 if (!doc) {
586 return;
587 }
588 xmlNodePtr cur = xmlDocGetRootElement(doc);
589 if (!cur || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(resourceName))) {
590 xmlFreeDoc(doc);
591 return;
592 }
593 cur = cur->xmlChildrenNode;
594 xmlChar *content = nullptr;
595 while (cur != nullptr) {
596 content = xmlNodeGetContent(cur);
597 if (content != nullptr) {
598 ret.insert(reinterpret_cast<const char*>(content));
599 xmlFree(content);
600 cur = cur->next;
601 } else {
602 break;
603 }
604 }
605 xmlFreeDoc(doc);
606 }
607
ProcessForbiddenRegions(const unordered_set<string> & forbiddenRegions)608 void LocaleConfig::ProcessForbiddenRegions(const unordered_set<string> &forbiddenRegions)
609 {
610 for (auto it = forbiddenRegions.begin(); it != forbiddenRegions.end(); ++it) {
611 size_t pos = it->rfind("-");
612 std::string language = it->substr(0, pos);
613 std::string region = it->substr(pos + 1);
614 if (language.compare("*") == 0) {
615 blockedRegions.insert(region);
616 } else {
617 if (blockedLanguageRegions.find(language) == blockedLanguageRegions.end()) {
618 blockedLanguageRegions[language] = { region };
619 } else {
620 blockedLanguageRegions[language].insert(region);
621 }
622 }
623 }
624 }
625
Expunge(unordered_set<string> & src,const unordered_set<string> & another)626 void LocaleConfig::Expunge(unordered_set<string> &src, const unordered_set<string> &another)
627 {
628 for (auto iter = src.begin(); iter != src.end();) {
629 if (another.find(*iter) != another.end()) {
630 iter = src.erase(iter);
631 } else {
632 ++iter;
633 }
634 }
635 }
636
InitializeLists()637 bool LocaleConfig::InitializeLists()
638 {
639 SetHwIcuDirectory();
640 GetListFromFile(SUPPORTED_REGIONS_PATH, SUPPORTED_REGIONS_NAME, supportedRegions);
641 unordered_set<string> forbiddenRegions;
642 GetListFromFile(FORBIDDEN_REGIONS_PATH, FORBIDDEN_REGIONS_NAME, forbiddenRegions);
643 ProcessForbiddenRegions(forbiddenRegions);
644 Expunge(supportedRegions, blockedRegions);
645 GetListFromFile(WHITE_LANGUAGES_PATH, WHITE_LANGUAGES_NAME, whiteLanguages);
646 GetListFromFile(FORBIDDEN_LANGUAGES_PATH, FORBIDDEN_LANGUAGES_NAME, blockedLanguages);
647 Expunge(whiteLanguages, blockedLanguages);
648 GetListFromFile(SUPPORTED_LOCALES_PATH, SUPPORTED_LOCALES_NAME, supportedLocales);
649 GetListFromFile(SUPPORT_LOCALES_PATH, SUPPORT_LOCALES_NAME, supportLocales);
650 GetListFromFile(OVERRIDE_SUPPORTED_REGIONS_PATH, OVERRIDE_SUPPORTED_REGIONS_NAME, overrideSupportedRegions);
651 GetListFromFile(DIALECT_LANGS_PATH, DIALECT_LANGS_NAME, dialectLang);
652 return true;
653 }
654
GetRegionChangeLocale(const string & languageTag,const string & region)655 string LocaleConfig::GetRegionChangeLocale(const string &languageTag, const string ®ion)
656 {
657 UErrorCode status = U_ZERO_ERROR;
658 const icu::Locale origin = icu::Locale::forLanguageTag(languageTag, status);
659 if (status != U_ZERO_ERROR) {
660 return "";
661 }
662 icu::LocaleBuilder builder = icu::LocaleBuilder().setLanguage(origin.getLanguage()).
663 setScript(origin.getScript()).setRegion(region);
664 icu::Locale temp = builder.setExtension('u', "").build(status);
665 if (status != U_ZERO_ERROR) {
666 return "";
667 }
668 string ret = temp.toLanguageTag<string>(status);
669 return (status != U_ZERO_ERROR) ? "" : ret;
670 }
671
GetMainLanguage(const string & language)672 string LocaleConfig::GetMainLanguage(const string &language)
673 {
674 UErrorCode status = U_ZERO_ERROR;
675 icu::Locale origin = icu::Locale::forLanguageTag(language, status);
676 if (status != U_ZERO_ERROR) {
677 return "";
678 }
679 origin.addLikelySubtags(status);
680 if (status != U_ZERO_ERROR) {
681 return "";
682 }
683 icu::LocaleBuilder builder = icu::LocaleBuilder().setLanguage(origin.getLanguage()).
684 setScript(origin.getScript()).setRegion(origin.getCountry());
685 icu::Locale temp = builder.setExtension('u', "").build(status);
686 if (status != U_ZERO_ERROR) {
687 return "";
688 }
689 string fullLanguage = temp.toLanguageTag<string>(status);
690 if (status != U_ZERO_ERROR) {
691 return "";
692 }
693 if (dialectMap.find(fullLanguage) != dialectMap.end()) {
694 return dialectMap[fullLanguage];
695 }
696 builder.setRegion("");
697 temp = builder.build(status);
698 if (status != U_ZERO_ERROR) {
699 return "";
700 }
701 fullLanguage = temp.toLanguageTag<string>(status);
702 if (status != U_ZERO_ERROR) {
703 return "";
704 }
705 return fullLanguage;
706 }
707
GetDisplayLanguage(const string & language,const string & displayLocale,bool sentenceCase)708 string LocaleConfig::GetDisplayLanguage(const string &language, const string &displayLocale, bool sentenceCase)
709 {
710 string adjust = Adjust(language);
711 if (adjust == language) {
712 UErrorCode status = U_ZERO_ERROR;
713 icu::Locale displayLoc = icu::Locale::forLanguageTag(displayLocale, status);
714 if (status != U_ZERO_ERROR) {
715 return "";
716 }
717 icu::Locale locale = icu::Locale::forLanguageTag(language, status);
718 if (status != U_ZERO_ERROR) {
719 return "";
720 }
721 icu::UnicodeString unistr;
722 std::string lang(locale.getLanguage());
723 std::string result;
724 if (dialectLang.find(lang) != dialectLang.end()) {
725 result = GetDsiplayLanguageWithDialect(language, displayLocale);
726 } else {
727 locale.getDisplayLanguage(displayLoc, unistr);
728 unistr.toUTF8String(result);
729 }
730 if (sentenceCase) {
731 char ch = static_cast<char>(toupper(result[0]));
732 return result.replace(0, 1, 1, ch);
733 }
734 return result;
735 }
736 return GetDisplayLanguageInner(adjust, displayLocale, sentenceCase);
737 }
738
ComputeLocale(const std::string & displayLocale)739 std::string LocaleConfig::ComputeLocale(const std::string &displayLocale)
740 {
741 if (supportedDialectLocales.size() == 0) {
742 xmlKeepBlanksDefault(0);
743 xmlDocPtr doc = xmlParseFile(SUPPORT_LOCALES_PATH);
744 if (!doc) {
745 return DEFAULT_LOCALE;
746 }
747 xmlNodePtr cur = xmlDocGetRootElement(doc);
748 if (!cur || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(supportLocalesTag))) {
749 xmlFreeDoc(doc);
750 HiLog::Info(LABEL, "can not parse language supported locale file");
751 return DEFAULT_LOCALE;
752 }
753 cur = cur->xmlChildrenNode;
754 while (cur != nullptr) {
755 xmlChar *content = xmlNodeGetContent(cur);
756 if (content == nullptr) {
757 HiLog::Info(LABEL, "get xml node content failed");
758 break;
759 }
760 std::map<std::string, std::string> localeInfoConfigs = {};
761 LocaleInfo localeinfo(reinterpret_cast<const char*>(content), localeInfoConfigs);
762 std::string language = localeinfo.GetLanguage();
763 std::string script = localeinfo.GetScript();
764 std::string languageAndScript = (script.length() == 0) ? language : language + "-" + script;
765 LocaleInfo newLocaleInfo(languageAndScript, localeInfoConfigs);
766 std::string maximizeLocale = newLocaleInfo.Maximize();
767 supportedDialectLocales.insert(
768 std::make_pair<std::string, std::string>(maximizeLocale.c_str(),
769 reinterpret_cast<const char*>(content)));
770 xmlFree(content);
771 cur = cur->next;
772 }
773 }
774 std::map<std::string, std::string> configs = {};
775 LocaleInfo localeinfo(displayLocale, configs);
776 std::string language = localeinfo.GetLanguage();
777 std::string script = localeinfo.GetScript();
778 std::string languageAndScript = (script.length() == 0) ? language : language + "-" + script;
779 LocaleInfo newLocaleInfo(languageAndScript, configs);
780 std::string maximizeLocale = newLocaleInfo.Maximize();
781 if (supportedDialectLocales.find(maximizeLocale) != supportedDialectLocales.end()) {
782 return supportedDialectLocales.at(maximizeLocale);
783 }
784 return DEFAULT_LOCALE;
785 }
786
ReadLangData(const char * langDataPath)787 void LocaleConfig::ReadLangData(const char *langDataPath)
788 {
789 xmlKeepBlanksDefault(0);
790 if (langDataPath == nullptr) {
791 return;
792 }
793 xmlDocPtr doc = xmlParseFile(langDataPath);
794 if (!doc) {
795 HiLog::Info(LABEL, "can not open language data file");
796 return;
797 }
798 xmlNodePtr cur = xmlDocGetRootElement(doc);
799 if (!cur || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(rootTag))) {
800 xmlFreeDoc(doc);
801 HiLog::Info(LABEL, "parse language data file failed");
802 return;
803 }
804 cur = cur->xmlChildrenNode;
805 while (cur != nullptr && !xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(secondRootTag))) {
806 xmlChar *langContents[ELEMENT_NUM] = { 0 }; // 2 represent langid, displayname;
807 xmlNodePtr langValue = cur->xmlChildrenNode;
808 for (size_t i = 0; i < ELEMENT_NUM; i++) {
809 if (langValue != nullptr) {
810 langContents[i] = xmlNodeGetContent(langValue);
811 langValue = langValue->next;
812 } else {
813 break;
814 }
815 }
816 // 0 represents langid index, 1 represents displayname index
817 locale2DisplayName.insert(
818 std::make_pair<std::string, std::string>(reinterpret_cast<const char *>(langContents[0]),
819 reinterpret_cast<const char *>(langContents[1])));
820 for (size_t i = 0; i < ELEMENT_NUM; i++) {
821 if (langContents[i] != nullptr) {
822 xmlFree(langContents[i]);
823 }
824 }
825 cur = cur->next;
826 }
827 xmlFreeDoc(doc);
828 }
829
ReadRegionData(const char * regionDataPath)830 void LocaleConfig::ReadRegionData(const char *regionDataPath)
831 {
832 xmlKeepBlanksDefault(0);
833 if (regionDataPath == nullptr) {
834 return;
835 }
836 xmlDocPtr doc = xmlParseFile(regionDataPath);
837 if (!doc) {
838 HiLog::Info(LABEL, "can not open region data file");
839 return;
840 }
841 xmlNodePtr cur = xmlDocGetRootElement(doc);
842 if (cur) {
843 HiLog::Info(LABEL, "cur pointer is true");
844 }
845 if (!cur || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(rootRegion))) {
846 xmlFreeDoc(doc);
847 HiLog::Info(LABEL, "parse region data file failed");
848 return;
849 }
850 cur = cur->xmlChildrenNode;
851 while (cur != nullptr && !xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(secondRootRegion))) {
852 xmlChar *regionContents[ELEMENT_NUM] = { 0 };
853 xmlNodePtr regionValue = cur->xmlChildrenNode;
854 for (size_t i = 0; i < ELEMENT_NUM; i++) {
855 if (regionValue != nullptr) {
856 regionContents[i] = xmlNodeGetContent(regionValue);
857 regionValue = regionValue->next;
858 } else {
859 break;
860 }
861 }
862 // 0 represents langid index, 1 represents displayname index
863 region2DisplayName.insert(
864 std::make_pair<std::string, std::string>(reinterpret_cast<const char *>(regionContents[0]),
865 reinterpret_cast<const char *>(regionContents[1])));
866 for (size_t i = 0; i < ELEMENT_NUM; i++) {
867 if (regionContents[i] != nullptr) {
868 xmlFree(regionContents[i]);
869 }
870 }
871 cur = cur->next;
872 }
873 xmlFreeDoc(doc);
874 }
875
GetDsiplayLanguageWithDialect(const std::string & localeStr,const std::string & displayLocale)876 string LocaleConfig::GetDsiplayLanguageWithDialect(const std::string &localeStr, const std::string &displayLocale)
877 {
878 std::string finalLocale = ComputeLocale(displayLocale);
879 if (finalLocale.compare(currentDialectLocale) != 0) {
880 std::string xmlPath = LANG_PATH + finalLocale + ".xml";
881 locale2DisplayName.clear();
882 ReadLangData(xmlPath.c_str());
883 currentDialectLocale = finalLocale;
884 }
885 if (locale2DisplayName.find(localeStr) != locale2DisplayName.end()) {
886 return locale2DisplayName.at(localeStr);
887 }
888 std::map<std::string, std::string> configs = {};
889 LocaleInfo locale(localeStr, configs);
890 std::string language = locale.GetLanguage();
891 std::string scripts = locale.GetScript();
892 std::string region = locale.GetRegion();
893 if (scripts.length() != 0) {
894 std::string languageAndScripts = language + "-" + scripts;
895 if (locale2DisplayName.find(languageAndScripts) != locale2DisplayName.end()) {
896 return locale2DisplayName.at(languageAndScripts);
897 }
898 }
899 if (region.length() != 0) {
900 std::string languageAndRegion = language + "-" + region;
901 if (locale2DisplayName.find(languageAndRegion) != locale2DisplayName.end()) {
902 return locale2DisplayName.at(languageAndRegion);
903 }
904 }
905 if (locale2DisplayName.find(language) != locale2DisplayName.end()) {
906 return locale2DisplayName.at(language);
907 }
908 return "";
909 }
910
GetDisplayOverrideRegion(const std::string & region,const std::string & displayLocale)911 string LocaleConfig::GetDisplayOverrideRegion(const std::string ®ion, const std::string &displayLocale)
912 {
913 UErrorCode status = U_ZERO_ERROR;
914 icu::Locale originLocale;
915 icu::UnicodeString displayRegion;
916 if (displayLocale.compare(currentOverrideRegion) != 0) {
917 std::string xmlPath = REGION_PATH + displayLocale + ".xml";
918 region2DisplayName.clear();
919 ReadRegionData(xmlPath.c_str());
920 currentOverrideRegion = displayLocale;
921 }
922 if (region2DisplayName.find(region) != region2DisplayName.end()) {
923 return region2DisplayName.at(region);
924 } else {
925 icu::Locale locale = icu::Locale::forLanguageTag(displayLocale, status);
926 if (status != U_ZERO_ERROR) {
927 return "";
928 }
929 if (IsValidRegion(region)) {
930 icu::LocaleBuilder builder = icu::LocaleBuilder().setRegion(region);
931 originLocale = builder.build(status);
932 } else {
933 originLocale = icu::Locale::forLanguageTag(region, status);
934 }
935 originLocale.getDisplayCountry(locale, displayRegion);
936 std::string result;
937 displayRegion.toUTF8String(result);
938 return result;
939 }
940 }
941
GetDisplayRegion(const string & region,const string & displayLocale,bool sentenceCase)942 string LocaleConfig::GetDisplayRegion(const string ®ion, const string &displayLocale, bool sentenceCase)
943 {
944 UErrorCode status = U_ZERO_ERROR;
945 icu::Locale originLocale;
946 if (IsValidRegion(region)) {
947 icu::LocaleBuilder builder = icu::LocaleBuilder().setRegion(region);
948 originLocale = builder.build(status);
949 } else {
950 originLocale = icu::Locale::forLanguageTag(region, status);
951 }
952 std::string country(originLocale.getCountry());
953 if (country.length() == 0) {
954 return "";
955 }
956 if (status != U_ZERO_ERROR) {
957 return "";
958 }
959 icu::Locale locale = icu::Locale::forLanguageTag(displayLocale, status);
960 if (status != U_ZERO_ERROR) {
961 return "";
962 }
963 icu::UnicodeString unistr;
964 icu::UnicodeString displayRegion;
965 std::string result;
966 if (overrideSupportedRegions.find(displayLocale) != overrideSupportedRegions.end()) {
967 result = GetDisplayOverrideRegion(region, displayLocale);
968 } else {
969 originLocale.getDisplayCountry(locale, displayRegion);
970 displayRegion.toUTF8String(result);
971 }
972 if (sentenceCase) {
973 char ch = static_cast<char>(toupper(result[0]));
974 return result.replace(0, 1, 1, ch);
975 }
976 return result;
977 }
978
IsRTL(const string & locale)979 bool LocaleConfig::IsRTL(const string &locale)
980 {
981 icu::Locale curLocale(locale.c_str());
982 return curLocale.isRightToLeft();
983 }
984
parseExtension(const std::string & extension,std::map<std::string,std::string> & map)985 void parseExtension(const std::string &extension, std::map<std::string, std::string> &map)
986 {
987 std::string pattern = "-..-";
988 std::regex express(pattern);
989
990 std::regex_token_iterator<std::string::const_iterator> begin1(extension.cbegin(), extension.cend(), express);
991 std::regex_token_iterator<std::string::const_iterator> begin2(extension.cbegin(), extension.cend(), express, -1);
992 begin2++;
993 for (; begin1 != std::sregex_token_iterator() && begin2 != std::sregex_token_iterator(); begin1++, begin2++) {
994 map.insert(std::pair<std::string, std::string>(begin1->str(), begin2->str()));
995 }
996 }
997
setExtension(std::string & extension,const std::string & tag,const std::set<string> & validValue,const std::map<std::string,std::string> & extensionMap,const std::map<std::string,std::string> & defaultExtensionMap)998 void setExtension(std::string &extension, const std::string &tag, const std::set<string> &validValue,
999 const std::map<std::string, std::string> &extensionMap,
1000 const std::map<std::string, std::string> &defaultExtensionMap)
1001 {
1002 std::string value;
1003 auto it = extensionMap.find(tag);
1004 if (it != extensionMap.end()) {
1005 value = it->second;
1006 if (validValue.find(value) == validValue.end()) {
1007 return;
1008 } else {
1009 extension += tag;
1010 extension += value;
1011 }
1012 } else {
1013 it = defaultExtensionMap.find(tag);
1014 if (it != defaultExtensionMap.end()) {
1015 value = it->second;
1016 if (validValue.find(value) == validValue.end()) {
1017 return;
1018 } else {
1019 extension += tag;
1020 extension += value;
1021 }
1022 }
1023 }
1024 }
1025
setOtherExtension(std::string & extension,std::map<std::string,std::string> & extensionMap,std::map<std::string,std::string> & defaultExtensionMap)1026 void setOtherExtension(std::string &extension, std::map<std::string, std::string> &extensionMap,
1027 std::map<std::string, std::string> &defaultExtensionMap)
1028 {
1029 std::set<std::string> tags;
1030 tags.insert("-ca-");
1031 tags.insert("-co-");
1032 tags.insert("-kn-");
1033 tags.insert("-kf-");
1034 tags.insert("-nu-");
1035 tags.insert("-hc-");
1036
1037 for (auto it = tags.begin(); it != tags.end(); it++) {
1038 extensionMap.erase(*it);
1039 defaultExtensionMap.erase(*it);
1040 }
1041
1042 for (auto it = defaultExtensionMap.begin(); it != defaultExtensionMap.end(); it++) {
1043 extensionMap.insert(std::pair<std::string, std::string>(it->first, it->second));
1044 }
1045
1046 for (auto it = extensionMap.begin(); it != extensionMap.end(); it++) {
1047 extension += it->first;
1048 extension += it->second;
1049 }
1050 }
1051
GetValidLocale(const std::string & localeTag)1052 std::string LocaleConfig::GetValidLocale(const std::string &localeTag)
1053 {
1054 std::string baseLocale = "";
1055 std::string extension = "";
1056 std::size_t found = localeTag.find("-u-");
1057 baseLocale = localeTag.substr(0, found);
1058 if (found != std::string::npos) {
1059 extension = localeTag.substr(found);
1060 }
1061 std::map<std::string, std::string> extensionMap;
1062 if (extension != "") {
1063 parseExtension(extension, extensionMap);
1064 }
1065
1066 std::string systemLocaleTag = GetSystemLocale();
1067 std::string defaultExtension = "";
1068 found = systemLocaleTag.find("-u-");
1069 if (found != std::string::npos) {
1070 defaultExtension = systemLocaleTag.substr(found);
1071 }
1072 std::map<std::string, std::string> defaultExtensionMap;
1073 if (defaultExtension != "") {
1074 parseExtension(defaultExtension, defaultExtensionMap);
1075 }
1076
1077 std::string ext = "";
1078 setExtension(ext, "-ca-", validCaTag, extensionMap, defaultExtensionMap);
1079 setExtension(ext, "-co-", validCoTag, extensionMap, defaultExtensionMap);
1080 setExtension(ext, "-kn-", validKnTag, extensionMap, defaultExtensionMap);
1081 setExtension(ext, "-kf-", validKfTag, extensionMap, defaultExtensionMap);
1082 setExtension(ext, "-nu-", validNuTag, extensionMap, defaultExtensionMap);
1083 setExtension(ext, "-hc-", validHcTag, extensionMap, defaultExtensionMap);
1084
1085 std::string otherExt = "";
1086 setOtherExtension(otherExt, extensionMap, defaultExtensionMap);
1087 if (ext != "" || otherExt != "") {
1088 return baseLocale + "-u" + ext + otherExt;
1089 } else {
1090 return baseLocale;
1091 }
1092 }
1093
Is24HourClock()1094 bool LocaleConfig::Is24HourClock()
1095 {
1096 std::string is24Hour = ReadSystemParameter(HOUR_KEY, CONFIG_LEN);
1097 if (is24Hour.empty()) {
1098 return false;
1099 }
1100 if (is24Hour.compare("true") == 0) {
1101 return true;
1102 }
1103 return false;
1104 }
1105
Set24HourClock(bool option)1106 bool LocaleConfig::Set24HourClock(bool option)
1107 {
1108 if (!CheckPermission()) {
1109 return false;
1110 }
1111 std::string optionStr = "";
1112 if (option) {
1113 optionStr = "true";
1114 } else {
1115 optionStr = "false";
1116 }
1117 if (SetParameter(HOUR_KEY, optionStr.data()) == 0) {
1118 #ifdef SUPPORT_GRAPHICS
1119 auto appMgrClient = std::make_unique<AppExecFwk::AppMgrClient>();
1120 AppExecFwk::Configuration configuration;
1121 configuration.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_HOUR, optionStr);
1122 appMgrClient->UpdateConfiguration(configuration);
1123
1124 OHOS::AAFwk::Want timeChangeWant;
1125 timeChangeWant.SetAction(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED);
1126 OHOS::EventFwk::CommonEventData event(timeChangeWant);
1127 if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(event)) {
1128 HiLog::Info(LABEL, "Failed to Publish event %{public}s", timeChangeWant.GetAction().c_str());
1129 return false;
1130 }
1131 #endif
1132 return true;
1133 }
1134 return false;
1135 }
1136
SetUsingLocalDigit(bool flag)1137 bool LocaleConfig::SetUsingLocalDigit(bool flag)
1138 {
1139 if (!CheckPermission()) {
1140 return false;
1141 }
1142 std::string locale = GetSystemLocale();
1143 LocaleInfo localeInfo(locale);
1144 std::string language = localeInfo.GetLanguage();
1145 if (localDigitMap.find(language) == localDigitMap.end()) {
1146 return false;
1147 }
1148 std::string numberSystem = "-nu-" + localDigitMap.at(language);
1149 if (flag) {
1150 if (locale.find("-u-") == std::string::npos) {
1151 locale += "-u" + numberSystem;
1152 } else if (locale.find("-nu-") == std::string::npos) {
1153 locale += numberSystem;
1154 } else {
1155 std::string oldNumberSystem = "-nu-" + localeInfo.GetNumberingSystem();
1156 locale.replace(locale.find("-nu-"), oldNumberSystem.length(), numberSystem);
1157 }
1158 } else {
1159 size_t pos = locale.find(numberSystem);
1160 if (pos != std::string::npos) {
1161 locale.replace(pos, numberSystem.length(), "");
1162 }
1163 // 2 is string -u length
1164 if (locale.find("-u") == (locale.length() - 2)) {
1165 // 2 is string -u length
1166 locale.resize(locale.length() - 2);
1167 }
1168 }
1169 if (!SetSystemLocale(locale)) {
1170 return false;
1171 }
1172 return true;
1173 }
1174
GetUsingLocalDigit()1175 bool LocaleConfig::GetUsingLocalDigit()
1176 {
1177 std::string locale = GetSystemLocale();
1178 LocaleInfo localeInfo(locale);
1179 std::string language = localeInfo.GetLanguage();
1180 if (localDigitMap.find(language) == localDigitMap.end()) {
1181 return false;
1182 }
1183 std::string localNumberSystem = localDigitMap.at(language);
1184 if (localNumberSystem.compare(localeInfo.GetNumberingSystem()) != 0) {
1185 return false;
1186 }
1187 return true;
1188 }
1189
UpdateSystemLocale(const std::string & language)1190 bool LocaleConfig::UpdateSystemLocale(const std::string &language)
1191 {
1192 UErrorCode status = U_ZERO_ERROR;
1193 icu::Locale languageLocale = icu::Locale::forLanguageTag(language.c_str(), status);
1194 if (U_FAILURE(status)) {
1195 return false;
1196 }
1197 std::string lang = languageLocale.getLanguage();
1198 std::string script = languageLocale.getScript();
1199
1200 std::string systemLocaleTag = GetSystemLocale();
1201 icu::Locale systemLocale = icu::Locale::forLanguageTag(systemLocaleTag.c_str(), status);
1202 if (U_FAILURE(status)) {
1203 return false;
1204 }
1205 std::string region = systemLocale.getCountry();
1206
1207 std::string extendParam;
1208 size_t pos = systemLocaleTag.find("-u-");
1209 if (pos < systemLocaleTag.length()) {
1210 extendParam = systemLocaleTag.substr(pos);
1211 }
1212
1213 std::string finalLocaleTag = lang;
1214 std::string splitor = "-";
1215 if (script.length() > 0) {
1216 finalLocaleTag += splitor + script;
1217 }
1218 if (region.length() > 0) {
1219 finalLocaleTag += splitor + region;
1220 }
1221 if (extendParam.length() > 0) {
1222 finalLocaleTag += extendParam;
1223 }
1224 return SetSystemLocale(finalLocaleTag);
1225 }
1226
GetBlockedLanguages()1227 std::unordered_set<std::string> LocaleConfig::GetBlockedLanguages()
1228 {
1229 return blockedLanguages;
1230 }
1231
GetBlockedRegions()1232 std::unordered_set<std::string> LocaleConfig::GetBlockedRegions()
1233 {
1234 return blockedRegions;
1235 }
1236
GetLanguageBlockedRegions()1237 std::unordered_set<std::string> LocaleConfig::GetLanguageBlockedRegions()
1238 {
1239 std::string systemLanguage = LocaleConfig::GetSystemLanguage();
1240 if (blockedLanguageRegions.find(systemLanguage) != blockedLanguageRegions.end()) {
1241 return blockedLanguageRegions[systemLanguage];
1242 }
1243 std::unordered_set<std::string> emptyResult;
1244 return emptyResult;
1245 }
1246 } // namespace I18n
1247 } // namespace Global
1248 } // namespace OHOS
1249