19596a2c1Sopenharmony_ci/* 29596a2c1Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 39596a2c1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 49596a2c1Sopenharmony_ci * you may not use this file except in compliance with the License. 59596a2c1Sopenharmony_ci * You may obtain a copy of the License at 69596a2c1Sopenharmony_ci * 79596a2c1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 89596a2c1Sopenharmony_ci * 99596a2c1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 109596a2c1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 119596a2c1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 129596a2c1Sopenharmony_ci * See the License for the specific language governing permissions and 139596a2c1Sopenharmony_ci * limitations under the License. 149596a2c1Sopenharmony_ci */ 159596a2c1Sopenharmony_ci#include <regex> 169596a2c1Sopenharmony_ci#include "accesstoken_kit.h" 179596a2c1Sopenharmony_ci#ifdef SUPPORT_GRAPHICS 189596a2c1Sopenharmony_ci#include "app_mgr_client.h" 199596a2c1Sopenharmony_ci#include "ability_manager_client.h" 209596a2c1Sopenharmony_ci#include <common_event_manager.h> 219596a2c1Sopenharmony_ci#include <common_event_publish_info.h> 229596a2c1Sopenharmony_ci#include <common_event_support.h> 239596a2c1Sopenharmony_ci#endif 249596a2c1Sopenharmony_ci#include <cctype> 259596a2c1Sopenharmony_ci#include "config_policy_utils.h" 269596a2c1Sopenharmony_ci#include "i18n_hilog.h" 279596a2c1Sopenharmony_ci#include "ipc_skeleton.h" 289596a2c1Sopenharmony_ci#include "libxml/parser.h" 299596a2c1Sopenharmony_ci#include "locale_info.h" 309596a2c1Sopenharmony_ci#include "multi_users.h" 319596a2c1Sopenharmony_ci#include "unicode/localebuilder.h" 329596a2c1Sopenharmony_ci#include "unicode/locdspnm.h" 339596a2c1Sopenharmony_ci#include "unicode/locid.h" 349596a2c1Sopenharmony_ci#include "unicode/smpdtfmt.h" 359596a2c1Sopenharmony_ci#include "ohos/init_data.h" 369596a2c1Sopenharmony_ci#include "parameter.h" 379596a2c1Sopenharmony_ci#include "securec.h" 389596a2c1Sopenharmony_ci#include "string_ex.h" 399596a2c1Sopenharmony_ci#include "ucase.h" 409596a2c1Sopenharmony_ci#include "ulocimp.h" 419596a2c1Sopenharmony_ci#include "unicode/unistr.h" 429596a2c1Sopenharmony_ci#include "ureslocs.h" 439596a2c1Sopenharmony_ci#include "unicode/ustring.h" 449596a2c1Sopenharmony_ci#include "ustr_imp.h" 459596a2c1Sopenharmony_ci#include "utils.h" 469596a2c1Sopenharmony_ci#include "tokenid_kit.h" 479596a2c1Sopenharmony_ci#include "locale_config.h" 489596a2c1Sopenharmony_ci 499596a2c1Sopenharmony_cinamespace OHOS { 509596a2c1Sopenharmony_cinamespace Global { 519596a2c1Sopenharmony_cinamespace I18n { 529596a2c1Sopenharmony_ciusing namespace std; 539596a2c1Sopenharmony_ciconst char *LocaleConfig::LANGUAGE_KEY = "persist.global.language"; 549596a2c1Sopenharmony_ciconst char *LocaleConfig::LOCALE_KEY = "persist.global.locale"; 559596a2c1Sopenharmony_ciconst char *LocaleConfig::HOUR_KEY = "persist.global.is24Hour"; 569596a2c1Sopenharmony_ciconst char *LocaleConfig::DEFAULT_LOCALE_KEY = "const.global.locale"; 579596a2c1Sopenharmony_ciconst char *LocaleConfig::DEFAULT_LANGUAGE_KEY = "const.global.language"; 589596a2c1Sopenharmony_ciconst char *LocaleConfig::DEFAULT_REGION_KEY = "const.global.region"; 599596a2c1Sopenharmony_ciconst char *LocaleConfig::SIM_COUNTRY_CODE_KEY = "telephony.sim.countryCode0"; 609596a2c1Sopenharmony_ciconst char *LocaleConfig::SUPPORTED_LOCALES_NAME = "supported_locales"; 619596a2c1Sopenharmony_ciconst char *LocaleConfig::REGIONS_LANGUAGES_PATH = "etc/xml/i18n_param_config.xml"; 629596a2c1Sopenharmony_ciconst char *LocaleConfig::REGIONS_LANGUAGES_NAME = "i18n_param_config"; 639596a2c1Sopenharmony_ciconst char *LocaleConfig::SUPPORTED_REGIONS_NAME = "supported_regions"; 649596a2c1Sopenharmony_ciconst char *LocaleConfig::WHITE_LANGUAGES_NAME = "white_languages"; 659596a2c1Sopenharmony_ciconst char *LocaleConfig::FORBIDDEN_LANGUAGES_NAME = "forbidden_languages"; 669596a2c1Sopenharmony_ciconst char *LocaleConfig::FORBIDDEN_REGIONS_NAME = "forbidden_regions"; 679596a2c1Sopenharmony_ciconst char *LocaleConfig::SUPPORTED_LOCALES_PATH = "/system/usr/ohos_locale_config/supported_locales.xml"; 689596a2c1Sopenharmony_ciconst char *LocaleConfig::SUPPORT_LOCALES_PATH = "/etc/ohos_lang_config/supported_locales.xml"; 699596a2c1Sopenharmony_ciconst char *LocaleConfig::SUPPORT_LOCALES_NAME = "supported_locales"; 709596a2c1Sopenharmony_ciconst char *LocaleConfig::DIALECT_LANGS_PATH = "/system/usr/ohos_locale_config/dialect_languages.xml"; 719596a2c1Sopenharmony_ciconst char *LocaleConfig::DIALECT_LANGS_NAME = "dialect_langs"; 729596a2c1Sopenharmony_ciconst char *LocaleConfig::OVERRIDE_SUPPORTED_REGIONS_NAME = "supported_regions"; 739596a2c1Sopenharmony_ciconst char *LocaleConfig::OVERRIDE_SUPPORTED_REGIONS_PATH = 749596a2c1Sopenharmony_ci "/system/usr/ohos_locale_config/region/supported_regions.xml"; 759596a2c1Sopenharmony_ciconst char *LocaleConfig::DEFAULT_LOCALE = "en-Latn"; 769596a2c1Sopenharmony_ciconst char *LocaleConfig::supportLocalesTag = "supported_locales"; 779596a2c1Sopenharmony_ciconst char *LocaleConfig::LANG_PATH = "/etc/ohos_lang_config/"; 789596a2c1Sopenharmony_ciconst char *LocaleConfig::REGION_PATH = "/system/usr/ohos_locale_config/region/"; 799596a2c1Sopenharmony_ciconst char *LocaleConfig::rootTag = "languages"; 809596a2c1Sopenharmony_ciconst char *LocaleConfig::secondRootTag = "lang"; 819596a2c1Sopenharmony_ciconst char *LocaleConfig::rootRegion = "regions"; 829596a2c1Sopenharmony_ciconst char *LocaleConfig::secondRootRegion = "region"; 839596a2c1Sopenharmony_ciconst char *LocaleConfig::NUMBER_SYSTEM_KEY = "-nu-"; 849596a2c1Sopenharmony_ciunordered_set<string> LocaleConfig::supportedLocales; 859596a2c1Sopenharmony_ciunordered_set<string> LocaleConfig::supportLocales; 869596a2c1Sopenharmony_ciunordered_set<string> LocaleConfig::supportedRegions; 879596a2c1Sopenharmony_ciunordered_set<string> LocaleConfig::overrideSupportedRegions; 889596a2c1Sopenharmony_ciunordered_set<string> LocaleConfig::dialectLang; 899596a2c1Sopenharmony_ciunordered_set<string> LocaleConfig::blockedLanguages; 909596a2c1Sopenharmony_ciunordered_set<string> LocaleConfig::blockedRegions; 919596a2c1Sopenharmony_ciunordered_map<string, unordered_set<string>> LocaleConfig::blockedLanguageRegions; 929596a2c1Sopenharmony_ciunordered_set<string> LocaleConfig::whiteLanguages; 939596a2c1Sopenharmony_cistd::set<std::string> LocaleConfig::extendWhiteLanguageList; 949596a2c1Sopenharmony_ciunordered_map<string, string> LocaleConfig::dialectMap { 959596a2c1Sopenharmony_ci { "es-Latn-419", "es-Latn-419" }, 969596a2c1Sopenharmony_ci { "es-Latn-BO", "es-Latn-419" }, 979596a2c1Sopenharmony_ci { "es-Latn-BR", "es-Latn-419" }, 989596a2c1Sopenharmony_ci { "es-Latn-BZ", "es-Latn-419" }, 999596a2c1Sopenharmony_ci { "es-Latn-CL", "es-Latn-419" }, 1009596a2c1Sopenharmony_ci { "es-Latn-CO", "es-Latn-419" }, 1019596a2c1Sopenharmony_ci { "es-Latn-CR", "es-Latn-419" }, 1029596a2c1Sopenharmony_ci { "es-Latn-CU", "es-Latn-419" }, 1039596a2c1Sopenharmony_ci { "es-Latn-DO", "es-Latn-419" }, 1049596a2c1Sopenharmony_ci { "es-Latn-EC", "es-Latn-419" }, 1059596a2c1Sopenharmony_ci { "es-Latn-GT", "es-Latn-419" }, 1069596a2c1Sopenharmony_ci { "es-Latn-HN", "es-Latn-419" }, 1079596a2c1Sopenharmony_ci { "es-Latn-MX", "es-Latn-419" }, 1089596a2c1Sopenharmony_ci { "es-Latn-NI", "es-Latn-419" }, 1099596a2c1Sopenharmony_ci { "es-Latn-PA", "es-Latn-419" }, 1109596a2c1Sopenharmony_ci { "es-Latn-PE", "es-Latn-419" }, 1119596a2c1Sopenharmony_ci { "es-Latn-PR", "es-Latn-419" }, 1129596a2c1Sopenharmony_ci { "es-Latn-PY", "es-Latn-419" }, 1139596a2c1Sopenharmony_ci { "es-Latn-SV", "es-Latn-419" }, 1149596a2c1Sopenharmony_ci { "es-Latn-US", "es-Latn-419" }, 1159596a2c1Sopenharmony_ci { "es-Latn-UY", "es-Latn-419" }, 1169596a2c1Sopenharmony_ci { "es-Latn-VE", "es-Latn-419" }, 1179596a2c1Sopenharmony_ci { "pt-Latn-PT", "pt-Latn-PT" }, 1189596a2c1Sopenharmony_ci { "en-Latn-US", "en-Latn-US" } 1199596a2c1Sopenharmony_ci}; 1209596a2c1Sopenharmony_ci 1219596a2c1Sopenharmony_ciunordered_map<string, string> LocaleConfig::localDigitMap { 1229596a2c1Sopenharmony_ci { "ar", "arab" }, 1239596a2c1Sopenharmony_ci { "as", "beng" }, 1249596a2c1Sopenharmony_ci { "bn", "beng" }, 1259596a2c1Sopenharmony_ci { "fa", "arabext" }, 1269596a2c1Sopenharmony_ci { "mr", "deva" }, 1279596a2c1Sopenharmony_ci { "my", "mymr" }, 1289596a2c1Sopenharmony_ci { "ne", "deva" }, 1299596a2c1Sopenharmony_ci { "ur", "latn" } 1309596a2c1Sopenharmony_ci}; 1319596a2c1Sopenharmony_ci 1329596a2c1Sopenharmony_cistd::map<std::string, std::string> LocaleConfig::supportedDialectLocales; 1339596a2c1Sopenharmony_cistd::map<string, string> LocaleConfig::locale2DisplayName {}; 1349596a2c1Sopenharmony_cistd::map<string, string> LocaleConfig::region2DisplayName {}; 1359596a2c1Sopenharmony_cistd::string LocaleConfig::currentDialectLocale = ""; 1369596a2c1Sopenharmony_cistd::string LocaleConfig::currentOverrideRegion = ""; 1379596a2c1Sopenharmony_cistd::mutex LocaleConfig::dialectLocaleMutex; 1389596a2c1Sopenharmony_cistd::mutex LocaleConfig::region2DisplayNameMutex; 1399596a2c1Sopenharmony_cistd::mutex LocaleConfig::locale2DisplayNameMutex; 1409596a2c1Sopenharmony_ci 1419596a2c1Sopenharmony_ciset<std::string> LocaleConfig::validCaTag { 1429596a2c1Sopenharmony_ci "buddhist", 1439596a2c1Sopenharmony_ci "chinese", 1449596a2c1Sopenharmony_ci "coptic", 1459596a2c1Sopenharmony_ci "dangi", 1469596a2c1Sopenharmony_ci "ethioaa", 1479596a2c1Sopenharmony_ci "ethiopic", 1489596a2c1Sopenharmony_ci "gregory", 1499596a2c1Sopenharmony_ci "hebrew", 1509596a2c1Sopenharmony_ci "indian", 1519596a2c1Sopenharmony_ci "islamic", 1529596a2c1Sopenharmony_ci "islamic-umalqura", 1539596a2c1Sopenharmony_ci "islamic-tbla", 1549596a2c1Sopenharmony_ci "islamic-civil", 1559596a2c1Sopenharmony_ci "islamic-rgsa", 1569596a2c1Sopenharmony_ci "iso8601", 1579596a2c1Sopenharmony_ci "japanese", 1589596a2c1Sopenharmony_ci "persian", 1599596a2c1Sopenharmony_ci "roc", 1609596a2c1Sopenharmony_ci "islamicc", 1619596a2c1Sopenharmony_ci}; 1629596a2c1Sopenharmony_ciset<std::string> LocaleConfig::validCoTag { 1639596a2c1Sopenharmony_ci "big5han", 1649596a2c1Sopenharmony_ci "compat", 1659596a2c1Sopenharmony_ci "dict", 1669596a2c1Sopenharmony_ci "direct", 1679596a2c1Sopenharmony_ci "ducet", 1689596a2c1Sopenharmony_ci "eor", 1699596a2c1Sopenharmony_ci "gb2312", 1709596a2c1Sopenharmony_ci "phonebk", 1719596a2c1Sopenharmony_ci "phonetic", 1729596a2c1Sopenharmony_ci "pinyin", 1739596a2c1Sopenharmony_ci "reformed", 1749596a2c1Sopenharmony_ci "searchjl", 1759596a2c1Sopenharmony_ci "stroke", 1769596a2c1Sopenharmony_ci "trad", 1779596a2c1Sopenharmony_ci "unihan", 1789596a2c1Sopenharmony_ci "zhuyin", 1799596a2c1Sopenharmony_ci}; 1809596a2c1Sopenharmony_ciset<std::string> LocaleConfig::validKnTag { 1819596a2c1Sopenharmony_ci "true", 1829596a2c1Sopenharmony_ci "false", 1839596a2c1Sopenharmony_ci}; 1849596a2c1Sopenharmony_ciset<std::string> LocaleConfig::validKfTag { 1859596a2c1Sopenharmony_ci "upper", 1869596a2c1Sopenharmony_ci "lower", 1879596a2c1Sopenharmony_ci "false", 1889596a2c1Sopenharmony_ci}; 1899596a2c1Sopenharmony_ciset<std::string> LocaleConfig::validNuTag { 1909596a2c1Sopenharmony_ci "adlm", "ahom", "arab", "arabext", "bali", "beng", 1919596a2c1Sopenharmony_ci "bhks", "brah", "cakm", "cham", "deva", "diak", 1929596a2c1Sopenharmony_ci "fullwide", "gong", "gonm", "gujr", "guru", "hanidec", 1939596a2c1Sopenharmony_ci "hmng", "hmnp", "java", "kali", "khmr", "knda", 1949596a2c1Sopenharmony_ci "lana", "lanatham", "laoo", "latn", "lepc", "limb", 1959596a2c1Sopenharmony_ci "mathbold", "mathdbl", "mathmono", "mathsanb", "mathsans", "mlym", 1969596a2c1Sopenharmony_ci "modi", "mong", "mroo", "mtei", "mymr", "mymrshan", 1979596a2c1Sopenharmony_ci "mymrtlng", "newa", "nkoo", "olck", "orya", "osma", 1989596a2c1Sopenharmony_ci "rohg", "saur", "segment", "shrd", "sind", "sinh", 1999596a2c1Sopenharmony_ci "sora", "sund", "takr", "talu", "tamldec", "telu", 2009596a2c1Sopenharmony_ci "thai", "tibt", "tirh", "vaii", "wara", "wcho", 2019596a2c1Sopenharmony_ci}; 2029596a2c1Sopenharmony_ciset<std::string> LocaleConfig::validHcTag { 2039596a2c1Sopenharmony_ci "h12", 2049596a2c1Sopenharmony_ci "h23", 2059596a2c1Sopenharmony_ci "h11", 2069596a2c1Sopenharmony_ci "h24", 2079596a2c1Sopenharmony_ci}; 2089596a2c1Sopenharmony_ci 2099596a2c1Sopenharmony_cistatic unordered_map<string, string> g_languageMap = { 2109596a2c1Sopenharmony_ci { "zh-Hans", "zh-Hans" }, 2119596a2c1Sopenharmony_ci { "zh-Hant-HK", "zh-Hant-HK" }, 2129596a2c1Sopenharmony_ci { "zh-Hant", "zh-Hant" }, 2139596a2c1Sopenharmony_ci { "my-Qaag", "my-Qaag" }, 2149596a2c1Sopenharmony_ci { "es-Latn-419", "es-419" }, 2159596a2c1Sopenharmony_ci { "es-Latn-US", "es-419" }, 2169596a2c1Sopenharmony_ci { "az-Latn", "az-Latn" }, 2179596a2c1Sopenharmony_ci { "bs-Latn", "bs-Latn" }, 2189596a2c1Sopenharmony_ci { "en-Latn-US", "en" }, 2199596a2c1Sopenharmony_ci { "en-Qaag", "en-Qaag" }, 2209596a2c1Sopenharmony_ci { "uz-Latn", "uz-Latn" }, 2219596a2c1Sopenharmony_ci { "sr-Latn", "sr-Latn" }, 2229596a2c1Sopenharmony_ci { "jv-Latn", "jv-Latn" }, 2239596a2c1Sopenharmony_ci { "pt-Latn-BR", "pt-BR" }, 2249596a2c1Sopenharmony_ci { "pa-Guru", "pa-Guru" }, 2259596a2c1Sopenharmony_ci { "mai-Deva", "mai-Deva" } 2269596a2c1Sopenharmony_ci}; 2279596a2c1Sopenharmony_ci 2289596a2c1Sopenharmony_cistring Adjust(const string &origin) 2299596a2c1Sopenharmony_ci{ 2309596a2c1Sopenharmony_ci auto iter = g_languageMap.find(origin); 2319596a2c1Sopenharmony_ci if (iter != g_languageMap.end()) { 2329596a2c1Sopenharmony_ci return iter->second; 2339596a2c1Sopenharmony_ci } 2349596a2c1Sopenharmony_ci for (iter = g_languageMap.begin(); iter != g_languageMap.end(); ++iter) { 2359596a2c1Sopenharmony_ci string key = iter->first; 2369596a2c1Sopenharmony_ci if (!origin.compare(0, key.length(), key)) { 2379596a2c1Sopenharmony_ci return iter->second; 2389596a2c1Sopenharmony_ci } 2399596a2c1Sopenharmony_ci } 2409596a2c1Sopenharmony_ci return origin; 2419596a2c1Sopenharmony_ci} 2429596a2c1Sopenharmony_ci 2439596a2c1Sopenharmony_cistring GetDisplayLanguageInner(const string &language, const string &displayLocaleTag, bool sentenceCase) 2449596a2c1Sopenharmony_ci{ 2459596a2c1Sopenharmony_ci icu::UnicodeString unistr; 2469596a2c1Sopenharmony_ci // 0 is the start position of language, 2 is the length of zh and fa 2479596a2c1Sopenharmony_ci if (!language.compare(0, 2, "zh") || !language.compare(0, 2, "fa") || !language.compare(0, 2, "ro")) { 2489596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 2499596a2c1Sopenharmony_ci icu::Locale displayLocale = icu::Locale::forLanguageTag(displayLocaleTag.c_str(), status); 2509596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 2519596a2c1Sopenharmony_ci return ""; 2529596a2c1Sopenharmony_ci } 2539596a2c1Sopenharmony_ci icu::LocaleDisplayNames *dspNames = icu::LocaleDisplayNames::createInstance(displayLocale, 2549596a2c1Sopenharmony_ci UDialectHandling::ULDN_DIALECT_NAMES); 2559596a2c1Sopenharmony_ci icu::Locale tempLocale = icu::Locale::forLanguageTag(language.c_str(), status); 2569596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 2579596a2c1Sopenharmony_ci return ""; 2589596a2c1Sopenharmony_ci } 2599596a2c1Sopenharmony_ci if (dspNames != nullptr) { 2609596a2c1Sopenharmony_ci dspNames->localeDisplayName(tempLocale, unistr); 2619596a2c1Sopenharmony_ci delete dspNames; 2629596a2c1Sopenharmony_ci } 2639596a2c1Sopenharmony_ci } else { 2649596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 2659596a2c1Sopenharmony_ci icu::Locale displayLoc = icu::Locale::forLanguageTag(displayLocaleTag, status); 2669596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 2679596a2c1Sopenharmony_ci return ""; 2689596a2c1Sopenharmony_ci } 2699596a2c1Sopenharmony_ci icu::Locale locale = icu::Locale::forLanguageTag(language, status); 2709596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 2719596a2c1Sopenharmony_ci return ""; 2729596a2c1Sopenharmony_ci } 2739596a2c1Sopenharmony_ci locale.getDisplayName(displayLoc, unistr); 2749596a2c1Sopenharmony_ci } 2759596a2c1Sopenharmony_ci if (sentenceCase) { 2769596a2c1Sopenharmony_ci UChar32 ch = ucase_toupper(unistr.char32At(0)); 2779596a2c1Sopenharmony_ci unistr.replace(0, 1, ch); 2789596a2c1Sopenharmony_ci } 2799596a2c1Sopenharmony_ci string out; 2809596a2c1Sopenharmony_ci unistr.toUTF8String(out); 2819596a2c1Sopenharmony_ci return out; 2829596a2c1Sopenharmony_ci} 2839596a2c1Sopenharmony_ci 2849596a2c1Sopenharmony_cibool LocaleConfig::listsInitialized = LocaleConfig::InitializeLists(); 2859596a2c1Sopenharmony_ci 2869596a2c1Sopenharmony_cistring LocaleConfig::GetSystemLanguage() 2879596a2c1Sopenharmony_ci{ 2889596a2c1Sopenharmony_ci std::string systemLanguage = ReadSystemParameter(LANGUAGE_KEY, CONFIG_LEN); 2899596a2c1Sopenharmony_ci if (systemLanguage.empty()) { 2909596a2c1Sopenharmony_ci systemLanguage = ReadSystemParameter(DEFAULT_LANGUAGE_KEY, CONFIG_LEN); 2919596a2c1Sopenharmony_ci } 2929596a2c1Sopenharmony_ci return systemLanguage; 2939596a2c1Sopenharmony_ci} 2949596a2c1Sopenharmony_ci 2959596a2c1Sopenharmony_cistring LocaleConfig::GetSystemRegion() 2969596a2c1Sopenharmony_ci{ 2979596a2c1Sopenharmony_ci std::string systemRegion = GetCountry(LOCALE_KEY); 2989596a2c1Sopenharmony_ci if (systemRegion.empty()) { 2999596a2c1Sopenharmony_ci systemRegion = GetCountry(DEFAULT_LOCALE_KEY); 3009596a2c1Sopenharmony_ci } 3019596a2c1Sopenharmony_ci if (systemRegion.empty()) { 3029596a2c1Sopenharmony_ci return "CN"; 3039596a2c1Sopenharmony_ci } 3049596a2c1Sopenharmony_ci return systemRegion; 3059596a2c1Sopenharmony_ci} 3069596a2c1Sopenharmony_ci 3079596a2c1Sopenharmony_cistring LocaleConfig::GetCountry(const string& parameter) 3089596a2c1Sopenharmony_ci{ 3099596a2c1Sopenharmony_ci std::string systemRegion = ReadSystemParameter(parameter.c_str(), CONFIG_LEN); 3109596a2c1Sopenharmony_ci if (systemRegion.empty()) { 3119596a2c1Sopenharmony_ci HILOG_INFO_I18N("GetCountry: ReadSystemParameter %{public}s failed", parameter.c_str()); 3129596a2c1Sopenharmony_ci return systemRegion; 3139596a2c1Sopenharmony_ci } 3149596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 3159596a2c1Sopenharmony_ci icu::Locale origin = icu::Locale::forLanguageTag(systemRegion, status); 3169596a2c1Sopenharmony_ci if (U_SUCCESS(status)) { 3179596a2c1Sopenharmony_ci const char* country = origin.getCountry(); 3189596a2c1Sopenharmony_ci if (country != nullptr) { 3199596a2c1Sopenharmony_ci return country; 3209596a2c1Sopenharmony_ci } 3219596a2c1Sopenharmony_ci HILOG_INFO_I18N("GetCountry: %{public}s get failed, country is nullptr", parameter.c_str()); 3229596a2c1Sopenharmony_ci } else { 3239596a2c1Sopenharmony_ci HILOG_INFO_I18N("GetCountry: %{public}s get failed, U_SUCCESS is false", parameter.c_str()); 3249596a2c1Sopenharmony_ci } 3259596a2c1Sopenharmony_ci return ""; 3269596a2c1Sopenharmony_ci} 3279596a2c1Sopenharmony_ci 3289596a2c1Sopenharmony_cistring LocaleConfig::GetSystemLocale() 3299596a2c1Sopenharmony_ci{ 3309596a2c1Sopenharmony_ci std::string systemLocale = ReadSystemParameter(LOCALE_KEY, CONFIG_LEN); 3319596a2c1Sopenharmony_ci if (systemLocale.empty()) { 3329596a2c1Sopenharmony_ci systemLocale = ReadSystemParameter(DEFAULT_LOCALE_KEY, CONFIG_LEN); 3339596a2c1Sopenharmony_ci } 3349596a2c1Sopenharmony_ci return systemLocale; 3359596a2c1Sopenharmony_ci} 3369596a2c1Sopenharmony_ci 3379596a2c1Sopenharmony_cibool LocaleConfig::IsValidLanguage(const string &language) 3389596a2c1Sopenharmony_ci{ 3399596a2c1Sopenharmony_ci string::size_type size = language.size(); 3409596a2c1Sopenharmony_ci if ((size != LANGUAGE_LEN) && (size != LANGUAGE_LEN + 1)) { 3419596a2c1Sopenharmony_ci return false; 3429596a2c1Sopenharmony_ci } 3439596a2c1Sopenharmony_ci for (size_t i = 0; i < size; ++i) { 3449596a2c1Sopenharmony_ci if ((language[i] > 'z') || (language[i] < 'a')) { 3459596a2c1Sopenharmony_ci return false; 3469596a2c1Sopenharmony_ci } 3479596a2c1Sopenharmony_ci } 3489596a2c1Sopenharmony_ci return true; 3499596a2c1Sopenharmony_ci} 3509596a2c1Sopenharmony_ci 3519596a2c1Sopenharmony_cibool LocaleConfig::IsValidRegion(const string ®ion) 3529596a2c1Sopenharmony_ci{ 3539596a2c1Sopenharmony_ci string::size_type size = region.size(); 3549596a2c1Sopenharmony_ci if (size != LocaleInfo::REGION_LEN) { 3559596a2c1Sopenharmony_ci return false; 3569596a2c1Sopenharmony_ci } 3579596a2c1Sopenharmony_ci for (size_t i = 0; i < LocaleInfo::REGION_LEN; ++i) { 3589596a2c1Sopenharmony_ci if ((region[i] > 'Z') || (region[i] < 'A')) { 3599596a2c1Sopenharmony_ci return false; 3609596a2c1Sopenharmony_ci } 3619596a2c1Sopenharmony_ci } 3629596a2c1Sopenharmony_ci return true; 3639596a2c1Sopenharmony_ci} 3649596a2c1Sopenharmony_ci 3659596a2c1Sopenharmony_cibool LocaleConfig::IsValidTag(const string &tag) 3669596a2c1Sopenharmony_ci{ 3679596a2c1Sopenharmony_ci if (!tag.size()) { 3689596a2c1Sopenharmony_ci return false; 3699596a2c1Sopenharmony_ci } 3709596a2c1Sopenharmony_ci vector<string> splits; 3719596a2c1Sopenharmony_ci Split(tag, "-", splits); 3729596a2c1Sopenharmony_ci if (!IsValidLanguage(splits[0])) { 3739596a2c1Sopenharmony_ci return false; 3749596a2c1Sopenharmony_ci } 3759596a2c1Sopenharmony_ci return true; 3769596a2c1Sopenharmony_ci} 3779596a2c1Sopenharmony_ci 3789596a2c1Sopenharmony_civoid LocaleConfig::Split(const string &src, const string &sep, vector<string> &dest) 3799596a2c1Sopenharmony_ci{ 3809596a2c1Sopenharmony_ci string::size_type begin = 0; 3819596a2c1Sopenharmony_ci string::size_type end = src.find(sep); 3829596a2c1Sopenharmony_ci while (end != string::npos) { 3839596a2c1Sopenharmony_ci dest.push_back(src.substr(begin, end - begin)); 3849596a2c1Sopenharmony_ci begin = end + sep.size(); 3859596a2c1Sopenharmony_ci end = src.find(sep, begin); 3869596a2c1Sopenharmony_ci } 3879596a2c1Sopenharmony_ci if (begin != src.size()) { 3889596a2c1Sopenharmony_ci dest.push_back(src.substr(begin)); 3899596a2c1Sopenharmony_ci } 3909596a2c1Sopenharmony_ci} 3919596a2c1Sopenharmony_ci 3929596a2c1Sopenharmony_civoid LocaleConfig::Split(const string &src, const string &sep, std::unordered_set<string> &dest) 3939596a2c1Sopenharmony_ci{ 3949596a2c1Sopenharmony_ci string::size_type begin = 0; 3959596a2c1Sopenharmony_ci string::size_type end = src.find(sep); 3969596a2c1Sopenharmony_ci while (end != string::npos) { 3979596a2c1Sopenharmony_ci dest.insert(src.substr(begin, end - begin)); 3989596a2c1Sopenharmony_ci begin = end + sep.size(); 3999596a2c1Sopenharmony_ci end = src.find(sep, begin); 4009596a2c1Sopenharmony_ci } 4019596a2c1Sopenharmony_ci if (begin != src.size()) { 4029596a2c1Sopenharmony_ci dest.insert(src.substr(begin)); 4039596a2c1Sopenharmony_ci } 4049596a2c1Sopenharmony_ci} 4059596a2c1Sopenharmony_ci 4069596a2c1Sopenharmony_ci// language in white languages should have script. 4079596a2c1Sopenharmony_civoid LocaleConfig::GetSystemLanguages(vector<string> &ret) 4089596a2c1Sopenharmony_ci{ 4099596a2c1Sopenharmony_ci std::copy(whiteLanguages.begin(), whiteLanguages.end(), std::back_inserter(ret)); 4109596a2c1Sopenharmony_ci} 4119596a2c1Sopenharmony_ci 4129596a2c1Sopenharmony_ciconst unordered_set<string>& LocaleConfig::GetSupportedLocales() 4139596a2c1Sopenharmony_ci{ 4149596a2c1Sopenharmony_ci return supportedLocales; 4159596a2c1Sopenharmony_ci} 4169596a2c1Sopenharmony_ci 4179596a2c1Sopenharmony_ciconst unordered_set<string>& LocaleConfig::GetSupportedRegions() 4189596a2c1Sopenharmony_ci{ 4199596a2c1Sopenharmony_ci return supportedRegions; 4209596a2c1Sopenharmony_ci} 4219596a2c1Sopenharmony_ci 4229596a2c1Sopenharmony_civoid LocaleConfig::GetSystemCountries(vector<string> &ret) 4239596a2c1Sopenharmony_ci{ 4249596a2c1Sopenharmony_ci std::copy(supportedRegions.begin(), supportedRegions.end(), std::back_inserter(ret)); 4259596a2c1Sopenharmony_ci} 4269596a2c1Sopenharmony_ci 4279596a2c1Sopenharmony_cibool LocaleConfig::IsSuggested(const string &language) 4289596a2c1Sopenharmony_ci{ 4299596a2c1Sopenharmony_ci unordered_set<string> relatedLocales; 4309596a2c1Sopenharmony_ci vector<string> simCountries; 4319596a2c1Sopenharmony_ci GetCountriesFromSim(simCountries); 4329596a2c1Sopenharmony_ci GetRelatedLocales(relatedLocales, simCountries); 4339596a2c1Sopenharmony_ci for (auto iter = relatedLocales.begin(); iter != relatedLocales.end();) { 4349596a2c1Sopenharmony_ci if (extendWhiteLanguageList.find(*iter) == extendWhiteLanguageList.end()) { 4359596a2c1Sopenharmony_ci iter = relatedLocales.erase(iter); 4369596a2c1Sopenharmony_ci } else { 4379596a2c1Sopenharmony_ci ++iter; 4389596a2c1Sopenharmony_ci } 4399596a2c1Sopenharmony_ci } 4409596a2c1Sopenharmony_ci string mainLanguage = GetMainLanguage(language); 4419596a2c1Sopenharmony_ci return relatedLocales.find(mainLanguage) != relatedLocales.end(); 4429596a2c1Sopenharmony_ci} 4439596a2c1Sopenharmony_ci 4449596a2c1Sopenharmony_cibool LocaleConfig::IsSuggested(const std::string &language, const std::string ®ion) 4459596a2c1Sopenharmony_ci{ 4469596a2c1Sopenharmony_ci unordered_set<string> relatedLocales; 4479596a2c1Sopenharmony_ci vector<string> countries { region }; 4489596a2c1Sopenharmony_ci GetRelatedLocales(relatedLocales, countries); 4499596a2c1Sopenharmony_ci for (auto iter = relatedLocales.begin(); iter != relatedLocales.end();) { 4509596a2c1Sopenharmony_ci if (extendWhiteLanguageList.find(*iter) == extendWhiteLanguageList.end()) { 4519596a2c1Sopenharmony_ci iter = relatedLocales.erase(iter); 4529596a2c1Sopenharmony_ci } else { 4539596a2c1Sopenharmony_ci ++iter; 4549596a2c1Sopenharmony_ci } 4559596a2c1Sopenharmony_ci } 4569596a2c1Sopenharmony_ci string mainLanguage = GetMainLanguage(language); 4579596a2c1Sopenharmony_ci return relatedLocales.find(mainLanguage) != relatedLocales.end(); 4589596a2c1Sopenharmony_ci} 4599596a2c1Sopenharmony_ci 4609596a2c1Sopenharmony_civoid LocaleConfig::ExtendWhiteLanguages() 4619596a2c1Sopenharmony_ci{ 4629596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 4639596a2c1Sopenharmony_ci for (auto iter = whiteLanguages.begin(); iter != whiteLanguages.end(); ++iter) { 4649596a2c1Sopenharmony_ci extendWhiteLanguageList.insert(*iter); 4659596a2c1Sopenharmony_ci icu::Locale locale = icu::Locale::forLanguageTag((*iter).c_str(), status); 4669596a2c1Sopenharmony_ci locale.addLikelySubtags(status); 4679596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 4689596a2c1Sopenharmony_ci HILOG_INFO_I18N("create Locale object for %{public}s failed.", (*iter).c_str()); 4699596a2c1Sopenharmony_ci continue; 4709596a2c1Sopenharmony_ci } 4719596a2c1Sopenharmony_ci const char* baseName = locale.getBaseName(); 4729596a2c1Sopenharmony_ci if (baseName != nullptr) { 4739596a2c1Sopenharmony_ci std::string baseNameStr(baseName); 4749596a2c1Sopenharmony_ci std::replace(baseNameStr.begin(), baseNameStr.end(), '_', '-'); 4759596a2c1Sopenharmony_ci extendWhiteLanguageList.insert(baseNameStr); 4769596a2c1Sopenharmony_ci } 4779596a2c1Sopenharmony_ci } 4789596a2c1Sopenharmony_ci} 4799596a2c1Sopenharmony_ci 4809596a2c1Sopenharmony_civoid LocaleConfig::GetRelatedLocales(unordered_set<string> &relatedLocales, vector<string> countries) 4819596a2c1Sopenharmony_ci{ 4829596a2c1Sopenharmony_ci // remove unsupported countries 4839596a2c1Sopenharmony_ci const unordered_set<string> ®ions = GetSupportedRegions(); 4849596a2c1Sopenharmony_ci for (auto iter = countries.begin(); iter != countries.end();) { 4859596a2c1Sopenharmony_ci if (regions.find(*iter) == regions.end()) { 4869596a2c1Sopenharmony_ci iter = countries.erase(iter); 4879596a2c1Sopenharmony_ci } else { 4889596a2c1Sopenharmony_ci ++iter; 4899596a2c1Sopenharmony_ci } 4909596a2c1Sopenharmony_ci } 4919596a2c1Sopenharmony_ci const unordered_set<string> &locales = GetSupportedLocales(); 4929596a2c1Sopenharmony_ci for (string locale : locales) { 4939596a2c1Sopenharmony_ci bool find = false; 4949596a2c1Sopenharmony_ci for (string country : countries) { 4959596a2c1Sopenharmony_ci if (locale.find(country) != string::npos) { 4969596a2c1Sopenharmony_ci find = true; 4979596a2c1Sopenharmony_ci break; 4989596a2c1Sopenharmony_ci } 4999596a2c1Sopenharmony_ci } 5009596a2c1Sopenharmony_ci if (!find) { 5019596a2c1Sopenharmony_ci continue; 5029596a2c1Sopenharmony_ci } 5039596a2c1Sopenharmony_ci string mainLanguage = GetMainLanguage(locale); 5049596a2c1Sopenharmony_ci if (mainLanguage != "") { 5059596a2c1Sopenharmony_ci relatedLocales.insert(mainLanguage); 5069596a2c1Sopenharmony_ci } 5079596a2c1Sopenharmony_ci } 5089596a2c1Sopenharmony_ci} 5099596a2c1Sopenharmony_ci 5109596a2c1Sopenharmony_civoid LocaleConfig::GetCountriesFromSim(vector<string> &simCountries) 5119596a2c1Sopenharmony_ci{ 5129596a2c1Sopenharmony_ci simCountries.push_back(GetSystemRegion()); 5139596a2c1Sopenharmony_ci char value[CONFIG_LEN]; 5149596a2c1Sopenharmony_ci int code = GetParameter(SIM_COUNTRY_CODE_KEY, "", value, CONFIG_LEN); 5159596a2c1Sopenharmony_ci if (code > 0) { 5169596a2c1Sopenharmony_ci simCountries.push_back(value); 5179596a2c1Sopenharmony_ci } 5189596a2c1Sopenharmony_ci} 5199596a2c1Sopenharmony_ci 5209596a2c1Sopenharmony_civoid LocaleConfig::GetListFromFile(const char *path, const char *resourceName, unordered_set<string> &ret) 5219596a2c1Sopenharmony_ci{ 5229596a2c1Sopenharmony_ci xmlKeepBlanksDefault(0); 5239596a2c1Sopenharmony_ci if (!path) { 5249596a2c1Sopenharmony_ci return; 5259596a2c1Sopenharmony_ci } 5269596a2c1Sopenharmony_ci xmlDocPtr doc = xmlParseFile(path); 5279596a2c1Sopenharmony_ci if (!doc) { 5289596a2c1Sopenharmony_ci return; 5299596a2c1Sopenharmony_ci } 5309596a2c1Sopenharmony_ci xmlNodePtr cur = xmlDocGetRootElement(doc); 5319596a2c1Sopenharmony_ci if (!cur || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(resourceName))) { 5329596a2c1Sopenharmony_ci xmlFreeDoc(doc); 5339596a2c1Sopenharmony_ci return; 5349596a2c1Sopenharmony_ci } 5359596a2c1Sopenharmony_ci cur = cur->xmlChildrenNode; 5369596a2c1Sopenharmony_ci xmlChar *content = nullptr; 5379596a2c1Sopenharmony_ci while (cur != nullptr) { 5389596a2c1Sopenharmony_ci content = xmlNodeGetContent(cur); 5399596a2c1Sopenharmony_ci if (content != nullptr) { 5409596a2c1Sopenharmony_ci ret.insert(reinterpret_cast<const char*>(content)); 5419596a2c1Sopenharmony_ci xmlFree(content); 5429596a2c1Sopenharmony_ci cur = cur->next; 5439596a2c1Sopenharmony_ci } else { 5449596a2c1Sopenharmony_ci break; 5459596a2c1Sopenharmony_ci } 5469596a2c1Sopenharmony_ci } 5479596a2c1Sopenharmony_ci xmlFreeDoc(doc); 5489596a2c1Sopenharmony_ci} 5499596a2c1Sopenharmony_ci 5509596a2c1Sopenharmony_civoid LocaleConfig::ProcessForbiddenRegions(const unordered_set<string> &forbiddenRegions) 5519596a2c1Sopenharmony_ci{ 5529596a2c1Sopenharmony_ci for (auto it = forbiddenRegions.begin(); it != forbiddenRegions.end(); ++it) { 5539596a2c1Sopenharmony_ci size_t pos = it->rfind("-"); 5549596a2c1Sopenharmony_ci std::string language = it->substr(0, pos); 5559596a2c1Sopenharmony_ci std::string region = it->substr(pos + 1); 5569596a2c1Sopenharmony_ci if (language.compare("*") == 0) { 5579596a2c1Sopenharmony_ci blockedRegions.insert(region); 5589596a2c1Sopenharmony_ci } else { 5599596a2c1Sopenharmony_ci if (blockedLanguageRegions.find(language) == blockedLanguageRegions.end()) { 5609596a2c1Sopenharmony_ci blockedLanguageRegions[language] = { region }; 5619596a2c1Sopenharmony_ci } else { 5629596a2c1Sopenharmony_ci blockedLanguageRegions[language].insert(region); 5639596a2c1Sopenharmony_ci } 5649596a2c1Sopenharmony_ci } 5659596a2c1Sopenharmony_ci } 5669596a2c1Sopenharmony_ci} 5679596a2c1Sopenharmony_ci 5689596a2c1Sopenharmony_civoid LocaleConfig::Expunge(unordered_set<string> &src, const unordered_set<string> &another) 5699596a2c1Sopenharmony_ci{ 5709596a2c1Sopenharmony_ci for (auto iter = src.begin(); iter != src.end();) { 5719596a2c1Sopenharmony_ci if (another.find(*iter) != another.end()) { 5729596a2c1Sopenharmony_ci iter = src.erase(iter); 5739596a2c1Sopenharmony_ci } else { 5749596a2c1Sopenharmony_ci ++iter; 5759596a2c1Sopenharmony_ci } 5769596a2c1Sopenharmony_ci } 5779596a2c1Sopenharmony_ci} 5789596a2c1Sopenharmony_ci 5799596a2c1Sopenharmony_cibool LocaleConfig::InitializeLists() 5809596a2c1Sopenharmony_ci{ 5819596a2c1Sopenharmony_ci SetHwIcuDirectory(); 5829596a2c1Sopenharmony_ci unordered_set<string> forbiddenRegions; 5839596a2c1Sopenharmony_ci LoadRegionsLanguages(forbiddenRegions); 5849596a2c1Sopenharmony_ci ProcessForbiddenRegions(forbiddenRegions); 5859596a2c1Sopenharmony_ci Expunge(supportedRegions, blockedRegions); 5869596a2c1Sopenharmony_ci Expunge(whiteLanguages, blockedLanguages); 5879596a2c1Sopenharmony_ci GetListFromFile(SUPPORTED_LOCALES_PATH, SUPPORTED_LOCALES_NAME, supportedLocales); 5889596a2c1Sopenharmony_ci GetListFromFile(SUPPORT_LOCALES_PATH, SUPPORT_LOCALES_NAME, supportLocales); 5899596a2c1Sopenharmony_ci GetListFromFile(OVERRIDE_SUPPORTED_REGIONS_PATH, OVERRIDE_SUPPORTED_REGIONS_NAME, overrideSupportedRegions); 5909596a2c1Sopenharmony_ci GetListFromFile(DIALECT_LANGS_PATH, DIALECT_LANGS_NAME, dialectLang); 5919596a2c1Sopenharmony_ci ExtendWhiteLanguages(); 5929596a2c1Sopenharmony_ci return true; 5939596a2c1Sopenharmony_ci} 5949596a2c1Sopenharmony_ci 5959596a2c1Sopenharmony_civoid LocaleConfig::LoadRegionsLanguages(unordered_set<std::string>& forbiddenRegions) 5969596a2c1Sopenharmony_ci{ 5979596a2c1Sopenharmony_ci char buf[MAX_PATH_LEN] = {0}; 5989596a2c1Sopenharmony_ci char* path = GetOneCfgFile(REGIONS_LANGUAGES_PATH, buf, MAX_PATH_LEN); 5999596a2c1Sopenharmony_ci xmlKeepBlanksDefault(0); 6009596a2c1Sopenharmony_ci if (!path) { 6019596a2c1Sopenharmony_ci return; 6029596a2c1Sopenharmony_ci } 6039596a2c1Sopenharmony_ci xmlDocPtr doc = xmlParseFile(path); 6049596a2c1Sopenharmony_ci if (!doc) { 6059596a2c1Sopenharmony_ci return; 6069596a2c1Sopenharmony_ci } 6079596a2c1Sopenharmony_ci xmlNodePtr cur = xmlDocGetRootElement(doc); 6089596a2c1Sopenharmony_ci if (!cur || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(REGIONS_LANGUAGES_NAME))) { 6099596a2c1Sopenharmony_ci xmlFreeDoc(doc); 6109596a2c1Sopenharmony_ci return; 6119596a2c1Sopenharmony_ci } 6129596a2c1Sopenharmony_ci cur = cur->xmlChildrenNode; 6139596a2c1Sopenharmony_ci xmlChar *content = nullptr; 6149596a2c1Sopenharmony_ci while (cur != nullptr) { 6159596a2c1Sopenharmony_ci content = xmlNodeGetContent(cur); 6169596a2c1Sopenharmony_ci if (content != nullptr && !xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(SUPPORTED_REGIONS_NAME))) { 6179596a2c1Sopenharmony_ci Split(reinterpret_cast<const char*>(content), ",", supportedRegions); 6189596a2c1Sopenharmony_ci } else if (content != nullptr && !xmlStrcmp(cur->name, 6199596a2c1Sopenharmony_ci reinterpret_cast<const xmlChar *>(WHITE_LANGUAGES_NAME))) { 6209596a2c1Sopenharmony_ci Split(reinterpret_cast<const char*>(content), ",", whiteLanguages); 6219596a2c1Sopenharmony_ci } else if (content != nullptr && !xmlStrcmp(cur->name, 6229596a2c1Sopenharmony_ci reinterpret_cast<const xmlChar *>(FORBIDDEN_REGIONS_NAME))) { 6239596a2c1Sopenharmony_ci Split(reinterpret_cast<const char*>(content), ",", forbiddenRegions); 6249596a2c1Sopenharmony_ci } else if (content != nullptr && !xmlStrcmp(cur->name, 6259596a2c1Sopenharmony_ci reinterpret_cast<const xmlChar *>(FORBIDDEN_LANGUAGES_NAME))) { 6269596a2c1Sopenharmony_ci Split(reinterpret_cast<const char*>(content), ",", blockedLanguages); 6279596a2c1Sopenharmony_ci } 6289596a2c1Sopenharmony_ci if (content != nullptr) { 6299596a2c1Sopenharmony_ci xmlFree(content); 6309596a2c1Sopenharmony_ci } 6319596a2c1Sopenharmony_ci cur = cur->next; 6329596a2c1Sopenharmony_ci } 6339596a2c1Sopenharmony_ci xmlFreeDoc(doc); 6349596a2c1Sopenharmony_ci} 6359596a2c1Sopenharmony_ci 6369596a2c1Sopenharmony_cistring LocaleConfig::GetMainLanguage(const string &language) 6379596a2c1Sopenharmony_ci{ 6389596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 6399596a2c1Sopenharmony_ci icu::Locale origin = icu::Locale::forLanguageTag(language, status); 6409596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 6419596a2c1Sopenharmony_ci return ""; 6429596a2c1Sopenharmony_ci } 6439596a2c1Sopenharmony_ci origin.addLikelySubtags(status); 6449596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 6459596a2c1Sopenharmony_ci return ""; 6469596a2c1Sopenharmony_ci } 6479596a2c1Sopenharmony_ci icu::LocaleBuilder builder = icu::LocaleBuilder().setLanguage(origin.getLanguage()). 6489596a2c1Sopenharmony_ci setScript(origin.getScript()).setRegion(origin.getCountry()); 6499596a2c1Sopenharmony_ci icu::Locale temp = builder.setExtension('u', "").build(status); 6509596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 6519596a2c1Sopenharmony_ci return ""; 6529596a2c1Sopenharmony_ci } 6539596a2c1Sopenharmony_ci string fullLanguage = temp.toLanguageTag<string>(status); 6549596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 6559596a2c1Sopenharmony_ci return ""; 6569596a2c1Sopenharmony_ci } 6579596a2c1Sopenharmony_ci if (dialectMap.find(fullLanguage) != dialectMap.end()) { 6589596a2c1Sopenharmony_ci return dialectMap[fullLanguage]; 6599596a2c1Sopenharmony_ci } 6609596a2c1Sopenharmony_ci builder.setRegion(""); 6619596a2c1Sopenharmony_ci temp = builder.build(status); 6629596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 6639596a2c1Sopenharmony_ci return ""; 6649596a2c1Sopenharmony_ci } 6659596a2c1Sopenharmony_ci fullLanguage = temp.toLanguageTag<string>(status); 6669596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 6679596a2c1Sopenharmony_ci return ""; 6689596a2c1Sopenharmony_ci } 6699596a2c1Sopenharmony_ci return fullLanguage; 6709596a2c1Sopenharmony_ci} 6719596a2c1Sopenharmony_ci 6729596a2c1Sopenharmony_cistring LocaleConfig::GetDisplayLanguage(const string &language, const string &displayLocale, bool sentenceCase) 6739596a2c1Sopenharmony_ci{ 6749596a2c1Sopenharmony_ci std::string result; 6759596a2c1Sopenharmony_ci string adjust = Adjust(language); 6769596a2c1Sopenharmony_ci if (adjust == language) { 6779596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 6789596a2c1Sopenharmony_ci icu::Locale displayLoc = icu::Locale::forLanguageTag(displayLocale, status); 6799596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 6809596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(""); 6819596a2c1Sopenharmony_ci } 6829596a2c1Sopenharmony_ci icu::Locale locale = icu::Locale::forLanguageTag(language, status); 6839596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 6849596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(""); 6859596a2c1Sopenharmony_ci } 6869596a2c1Sopenharmony_ci icu::UnicodeString unistr; 6879596a2c1Sopenharmony_ci std::string lang(locale.getLanguage()); 6889596a2c1Sopenharmony_ci if (dialectLang.find(lang) != dialectLang.end()) { 6899596a2c1Sopenharmony_ci result = GetDisplayLanguageWithDialect(language, displayLocale); 6909596a2c1Sopenharmony_ci } 6919596a2c1Sopenharmony_ci } 6929596a2c1Sopenharmony_ci if (result.empty()) { 6939596a2c1Sopenharmony_ci result = GetDisplayLanguageInner(adjust, displayLocale, sentenceCase); 6949596a2c1Sopenharmony_ci } 6959596a2c1Sopenharmony_ci if (sentenceCase && !result.empty()) { 6969596a2c1Sopenharmony_ci char ch = static_cast<char>(toupper(result[0])); 6979596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(result.replace(0, 1, 1, ch)); 6989596a2c1Sopenharmony_ci } 6999596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(result); 7009596a2c1Sopenharmony_ci} 7019596a2c1Sopenharmony_ci 7029596a2c1Sopenharmony_cistd::string LocaleConfig::ComputeLocale(const std::string &displayLocale) 7039596a2c1Sopenharmony_ci{ 7049596a2c1Sopenharmony_ci if (supportedDialectLocales.size() == 0) { 7059596a2c1Sopenharmony_ci xmlKeepBlanksDefault(0); 7069596a2c1Sopenharmony_ci xmlDocPtr doc = xmlParseFile(SUPPORT_LOCALES_PATH); 7079596a2c1Sopenharmony_ci if (!doc) { 7089596a2c1Sopenharmony_ci return ""; 7099596a2c1Sopenharmony_ci } 7109596a2c1Sopenharmony_ci xmlNodePtr cur = xmlDocGetRootElement(doc); 7119596a2c1Sopenharmony_ci if (!cur || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(supportLocalesTag))) { 7129596a2c1Sopenharmony_ci xmlFreeDoc(doc); 7139596a2c1Sopenharmony_ci HILOG_INFO_I18N("can not parse language supported locale file"); 7149596a2c1Sopenharmony_ci return ""; 7159596a2c1Sopenharmony_ci } 7169596a2c1Sopenharmony_ci cur = cur->xmlChildrenNode; 7179596a2c1Sopenharmony_ci while (cur != nullptr) { 7189596a2c1Sopenharmony_ci xmlChar *content = xmlNodeGetContent(cur); 7199596a2c1Sopenharmony_ci if (content == nullptr) { 7209596a2c1Sopenharmony_ci HILOG_INFO_I18N("get xml node content failed"); 7219596a2c1Sopenharmony_ci break; 7229596a2c1Sopenharmony_ci } 7239596a2c1Sopenharmony_ci std::map<std::string, std::string> localeInfoConfigs = {}; 7249596a2c1Sopenharmony_ci LocaleInfo localeinfo(reinterpret_cast<const char*>(content), localeInfoConfigs); 7259596a2c1Sopenharmony_ci std::string maximizeLocale = localeinfo.Maximize(); 7269596a2c1Sopenharmony_ci const char* key = maximizeLocale.c_str(); 7279596a2c1Sopenharmony_ci const char* value = reinterpret_cast<const char*>(content); 7289596a2c1Sopenharmony_ci SetSupportedDialectLocales(key, value); 7299596a2c1Sopenharmony_ci xmlFree(content); 7309596a2c1Sopenharmony_ci cur = cur->next; 7319596a2c1Sopenharmony_ci } 7329596a2c1Sopenharmony_ci xmlFreeDoc(doc); 7339596a2c1Sopenharmony_ci } 7349596a2c1Sopenharmony_ci std::map<std::string, std::string> configs = {}; 7359596a2c1Sopenharmony_ci LocaleInfo localeinfo(displayLocale, configs); 7369596a2c1Sopenharmony_ci std::string maximizeLocale = localeinfo.Maximize(); 7379596a2c1Sopenharmony_ci if (supportedDialectLocales.find(maximizeLocale) != supportedDialectLocales.end()) { 7389596a2c1Sopenharmony_ci return supportedDialectLocales.at(maximizeLocale); 7399596a2c1Sopenharmony_ci } 7409596a2c1Sopenharmony_ci return ""; 7419596a2c1Sopenharmony_ci} 7429596a2c1Sopenharmony_ci 7439596a2c1Sopenharmony_civoid LocaleConfig::SetSupportedDialectLocales(const char* key, const char* value) 7449596a2c1Sopenharmony_ci{ 7459596a2c1Sopenharmony_ci std::lock_guard<std::mutex> dialectLocaleLock(dialectLocaleMutex); 7469596a2c1Sopenharmony_ci supportedDialectLocales.insert( 7479596a2c1Sopenharmony_ci std::make_pair<std::string, std::string>(key, value)); 7489596a2c1Sopenharmony_ci} 7499596a2c1Sopenharmony_ci 7509596a2c1Sopenharmony_civoid LocaleConfig::ReadLangData(const char *langDataPath) 7519596a2c1Sopenharmony_ci{ 7529596a2c1Sopenharmony_ci xmlKeepBlanksDefault(0); 7539596a2c1Sopenharmony_ci if (langDataPath == nullptr) { 7549596a2c1Sopenharmony_ci return; 7559596a2c1Sopenharmony_ci } 7569596a2c1Sopenharmony_ci xmlDocPtr doc = xmlParseFile(langDataPath); 7579596a2c1Sopenharmony_ci if (!doc) { 7589596a2c1Sopenharmony_ci HILOG_INFO_I18N("can not open language data file"); 7599596a2c1Sopenharmony_ci return; 7609596a2c1Sopenharmony_ci } 7619596a2c1Sopenharmony_ci xmlNodePtr cur = xmlDocGetRootElement(doc); 7629596a2c1Sopenharmony_ci if (!cur || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(rootTag))) { 7639596a2c1Sopenharmony_ci xmlFreeDoc(doc); 7649596a2c1Sopenharmony_ci HILOG_INFO_I18N("parse language data file failed"); 7659596a2c1Sopenharmony_ci return; 7669596a2c1Sopenharmony_ci } 7679596a2c1Sopenharmony_ci cur = cur->xmlChildrenNode; 7689596a2c1Sopenharmony_ci while (cur != nullptr && !xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(secondRootTag))) { 7699596a2c1Sopenharmony_ci xmlChar *langContents[ELEMENT_NUM] = { 0 }; // 2 represent langid, displayname; 7709596a2c1Sopenharmony_ci xmlNodePtr langValue = cur->xmlChildrenNode; 7719596a2c1Sopenharmony_ci bool xmlNodeNull = false; 7729596a2c1Sopenharmony_ci for (size_t i = 0; i < ELEMENT_NUM && langValue != nullptr; i++) { 7739596a2c1Sopenharmony_ci langContents[i] = xmlNodeGetContent(langValue); 7749596a2c1Sopenharmony_ci langValue = langValue->next; 7759596a2c1Sopenharmony_ci if (langContents[i] == nullptr) { 7769596a2c1Sopenharmony_ci xmlNodeNull = true; 7779596a2c1Sopenharmony_ci } 7789596a2c1Sopenharmony_ci } 7799596a2c1Sopenharmony_ci if (!xmlNodeNull) { 7809596a2c1Sopenharmony_ci // 0 represents langid index, 1 represents displayname index 7819596a2c1Sopenharmony_ci const char* key = reinterpret_cast<const char *>(langContents[0]); 7829596a2c1Sopenharmony_ci const char* value = reinterpret_cast<const char *>(langContents[1]); 7839596a2c1Sopenharmony_ci SetLocale2DisplayName(key, value); 7849596a2c1Sopenharmony_ci } 7859596a2c1Sopenharmony_ci for (size_t i = 0; i < ELEMENT_NUM; i++) { 7869596a2c1Sopenharmony_ci if (langContents[i] != nullptr) { 7879596a2c1Sopenharmony_ci xmlFree(langContents[i]); 7889596a2c1Sopenharmony_ci } 7899596a2c1Sopenharmony_ci } 7909596a2c1Sopenharmony_ci cur = cur->next; 7919596a2c1Sopenharmony_ci } 7929596a2c1Sopenharmony_ci xmlFreeDoc(doc); 7939596a2c1Sopenharmony_ci} 7949596a2c1Sopenharmony_ci 7959596a2c1Sopenharmony_civoid LocaleConfig::SetRegion2DisplayName(const char* key, const char* value) 7969596a2c1Sopenharmony_ci{ 7979596a2c1Sopenharmony_ci std::lock_guard<std::mutex> regionDisplayLock(region2DisplayNameMutex); 7989596a2c1Sopenharmony_ci region2DisplayName.insert( 7999596a2c1Sopenharmony_ci std::make_pair<std::string, std::string>(key, value)); 8009596a2c1Sopenharmony_ci} 8019596a2c1Sopenharmony_ci 8029596a2c1Sopenharmony_civoid LocaleConfig::SetLocale2DisplayName(const char* key, const char* value) 8039596a2c1Sopenharmony_ci{ 8049596a2c1Sopenharmony_ci std::lock_guard<std::mutex> localeDisplayLock(locale2DisplayNameMutex); 8059596a2c1Sopenharmony_ci locale2DisplayName.insert( 8069596a2c1Sopenharmony_ci std::make_pair<std::string, std::string>(key, value)); 8079596a2c1Sopenharmony_ci} 8089596a2c1Sopenharmony_ci 8099596a2c1Sopenharmony_civoid LocaleConfig::ReadRegionData(const char *regionDataPath) 8109596a2c1Sopenharmony_ci{ 8119596a2c1Sopenharmony_ci xmlKeepBlanksDefault(0); 8129596a2c1Sopenharmony_ci if (regionDataPath == nullptr) { 8139596a2c1Sopenharmony_ci return; 8149596a2c1Sopenharmony_ci } 8159596a2c1Sopenharmony_ci xmlDocPtr doc = xmlParseFile(regionDataPath); 8169596a2c1Sopenharmony_ci if (!doc) { 8179596a2c1Sopenharmony_ci HILOG_INFO_I18N("can not open region data file"); 8189596a2c1Sopenharmony_ci return; 8199596a2c1Sopenharmony_ci } 8209596a2c1Sopenharmony_ci xmlNodePtr cur = xmlDocGetRootElement(doc); 8219596a2c1Sopenharmony_ci if (cur) { 8229596a2c1Sopenharmony_ci HILOG_INFO_I18N("cur pointer is true"); 8239596a2c1Sopenharmony_ci } 8249596a2c1Sopenharmony_ci if (!cur || xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(rootRegion))) { 8259596a2c1Sopenharmony_ci xmlFreeDoc(doc); 8269596a2c1Sopenharmony_ci HILOG_INFO_I18N("parse region data file failed"); 8279596a2c1Sopenharmony_ci return; 8289596a2c1Sopenharmony_ci } 8299596a2c1Sopenharmony_ci cur = cur->xmlChildrenNode; 8309596a2c1Sopenharmony_ci while (cur != nullptr && !xmlStrcmp(cur->name, reinterpret_cast<const xmlChar *>(secondRootRegion))) { 8319596a2c1Sopenharmony_ci xmlChar *regionContents[ELEMENT_NUM] = { 0 }; 8329596a2c1Sopenharmony_ci xmlNodePtr regionValue = cur->xmlChildrenNode; 8339596a2c1Sopenharmony_ci bool xmlNodeNull = false; 8349596a2c1Sopenharmony_ci for (size_t i = 0; i < ELEMENT_NUM && regionValue != nullptr; i++) { 8359596a2c1Sopenharmony_ci regionContents[i] = xmlNodeGetContent(regionValue); 8369596a2c1Sopenharmony_ci regionValue = regionValue->next; 8379596a2c1Sopenharmony_ci if (regionContents[i] == nullptr) { 8389596a2c1Sopenharmony_ci xmlNodeNull = true; 8399596a2c1Sopenharmony_ci } 8409596a2c1Sopenharmony_ci } 8419596a2c1Sopenharmony_ci if (!xmlNodeNull) { 8429596a2c1Sopenharmony_ci // 0 represents langid index, 1 represents displayname index 8439596a2c1Sopenharmony_ci const char* regionKey = reinterpret_cast<const char *>(regionContents[0]); 8449596a2c1Sopenharmony_ci const char* regionVal = reinterpret_cast<const char *>(regionContents[1]); 8459596a2c1Sopenharmony_ci SetRegion2DisplayName(regionKey, regionVal); 8469596a2c1Sopenharmony_ci } 8479596a2c1Sopenharmony_ci for (size_t i = 0; i < ELEMENT_NUM; i++) { 8489596a2c1Sopenharmony_ci if (regionContents[i] != nullptr) { 8499596a2c1Sopenharmony_ci xmlFree(regionContents[i]); 8509596a2c1Sopenharmony_ci } 8519596a2c1Sopenharmony_ci } 8529596a2c1Sopenharmony_ci cur = cur->next; 8539596a2c1Sopenharmony_ci } 8549596a2c1Sopenharmony_ci xmlFreeDoc(doc); 8559596a2c1Sopenharmony_ci} 8569596a2c1Sopenharmony_ci 8579596a2c1Sopenharmony_cistring LocaleConfig::GetDisplayLanguageWithDialect(const std::string &localeStr, const std::string &displayLocale) 8589596a2c1Sopenharmony_ci{ 8599596a2c1Sopenharmony_ci std::string finalLocale = ComputeLocale(displayLocale); 8609596a2c1Sopenharmony_ci if (finalLocale.empty()) { 8619596a2c1Sopenharmony_ci return ""; 8629596a2c1Sopenharmony_ci } 8639596a2c1Sopenharmony_ci if (finalLocale.compare(currentDialectLocale) != 0) { 8649596a2c1Sopenharmony_ci std::string xmlPath = LANG_PATH + finalLocale + ".xml"; 8659596a2c1Sopenharmony_ci locale2DisplayName.clear(); 8669596a2c1Sopenharmony_ci ReadLangData(xmlPath.c_str()); 8679596a2c1Sopenharmony_ci currentDialectLocale = finalLocale; 8689596a2c1Sopenharmony_ci } 8699596a2c1Sopenharmony_ci if (locale2DisplayName.find(localeStr) != locale2DisplayName.end()) { 8709596a2c1Sopenharmony_ci return locale2DisplayName.at(localeStr); 8719596a2c1Sopenharmony_ci } 8729596a2c1Sopenharmony_ci std::map<std::string, std::string> configs = {}; 8739596a2c1Sopenharmony_ci LocaleInfo locale(localeStr, configs); 8749596a2c1Sopenharmony_ci std::string language = locale.GetLanguage(); 8759596a2c1Sopenharmony_ci std::string scripts = locale.GetScript(); 8769596a2c1Sopenharmony_ci std::string region = locale.GetRegion(); 8779596a2c1Sopenharmony_ci if (scripts.length() != 0) { 8789596a2c1Sopenharmony_ci std::string languageAndScripts = language + "-" + scripts; 8799596a2c1Sopenharmony_ci if (locale2DisplayName.find(languageAndScripts) != locale2DisplayName.end()) { 8809596a2c1Sopenharmony_ci return locale2DisplayName.at(languageAndScripts); 8819596a2c1Sopenharmony_ci } 8829596a2c1Sopenharmony_ci } 8839596a2c1Sopenharmony_ci if (region.length() != 0) { 8849596a2c1Sopenharmony_ci std::string languageAndRegion = language + "-" + region; 8859596a2c1Sopenharmony_ci if (locale2DisplayName.find(languageAndRegion) != locale2DisplayName.end()) { 8869596a2c1Sopenharmony_ci return locale2DisplayName.at(languageAndRegion); 8879596a2c1Sopenharmony_ci } 8889596a2c1Sopenharmony_ci } 8899596a2c1Sopenharmony_ci if (locale2DisplayName.find(language) != locale2DisplayName.end()) { 8909596a2c1Sopenharmony_ci return locale2DisplayName.at(language); 8919596a2c1Sopenharmony_ci } 8929596a2c1Sopenharmony_ci return ""; 8939596a2c1Sopenharmony_ci} 8949596a2c1Sopenharmony_ci 8959596a2c1Sopenharmony_cistring LocaleConfig::GetDisplayOverrideRegion(const std::string ®ion, const std::string &displayLocale) 8969596a2c1Sopenharmony_ci{ 8979596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 8989596a2c1Sopenharmony_ci icu::Locale originLocale; 8999596a2c1Sopenharmony_ci icu::UnicodeString displayRegion; 9009596a2c1Sopenharmony_ci if (displayLocale.compare(currentOverrideRegion) != 0) { 9019596a2c1Sopenharmony_ci std::string xmlPath = REGION_PATH + displayLocale + ".xml"; 9029596a2c1Sopenharmony_ci region2DisplayName.clear(); 9039596a2c1Sopenharmony_ci ReadRegionData(xmlPath.c_str()); 9049596a2c1Sopenharmony_ci currentOverrideRegion = displayLocale; 9059596a2c1Sopenharmony_ci } 9069596a2c1Sopenharmony_ci if (region2DisplayName.find(region) != region2DisplayName.end()) { 9079596a2c1Sopenharmony_ci return region2DisplayName.at(region); 9089596a2c1Sopenharmony_ci } else { 9099596a2c1Sopenharmony_ci icu::Locale locale = icu::Locale::forLanguageTag(displayLocale, status); 9109596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 9119596a2c1Sopenharmony_ci return ""; 9129596a2c1Sopenharmony_ci } 9139596a2c1Sopenharmony_ci if (IsValidRegion(region)) { 9149596a2c1Sopenharmony_ci icu::LocaleBuilder builder = icu::LocaleBuilder().setRegion(region); 9159596a2c1Sopenharmony_ci originLocale = builder.build(status); 9169596a2c1Sopenharmony_ci } else { 9179596a2c1Sopenharmony_ci originLocale = icu::Locale::forLanguageTag(region, status); 9189596a2c1Sopenharmony_ci } 9199596a2c1Sopenharmony_ci originLocale.getDisplayCountry(locale, displayRegion); 9209596a2c1Sopenharmony_ci std::string result; 9219596a2c1Sopenharmony_ci displayRegion.toUTF8String(result); 9229596a2c1Sopenharmony_ci return result; 9239596a2c1Sopenharmony_ci } 9249596a2c1Sopenharmony_ci} 9259596a2c1Sopenharmony_ci 9269596a2c1Sopenharmony_cistring LocaleConfig::GetDisplayRegion(const string ®ion, const string &displayLocale, bool sentenceCase) 9279596a2c1Sopenharmony_ci{ 9289596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 9299596a2c1Sopenharmony_ci icu::Locale originLocale; 9309596a2c1Sopenharmony_ci if (IsValidRegion(region)) { 9319596a2c1Sopenharmony_ci icu::LocaleBuilder builder = icu::LocaleBuilder().setRegion(region); 9329596a2c1Sopenharmony_ci originLocale = builder.build(status); 9339596a2c1Sopenharmony_ci } else { 9349596a2c1Sopenharmony_ci originLocale = icu::Locale::forLanguageTag(region, status); 9359596a2c1Sopenharmony_ci } 9369596a2c1Sopenharmony_ci std::string country(originLocale.getCountry()); 9379596a2c1Sopenharmony_ci if (country.length() == 0) { 9389596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(""); 9399596a2c1Sopenharmony_ci } 9409596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 9419596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(""); 9429596a2c1Sopenharmony_ci } 9439596a2c1Sopenharmony_ci icu::Locale locale = icu::Locale::forLanguageTag(displayLocale, status); 9449596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 9459596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(""); 9469596a2c1Sopenharmony_ci } 9479596a2c1Sopenharmony_ci icu::UnicodeString unistr; 9489596a2c1Sopenharmony_ci icu::UnicodeString displayRegion; 9499596a2c1Sopenharmony_ci std::string result; 9509596a2c1Sopenharmony_ci if (overrideSupportedRegions.find(displayLocale) != overrideSupportedRegions.end()) { 9519596a2c1Sopenharmony_ci result = GetDisplayOverrideRegion(region, displayLocale); 9529596a2c1Sopenharmony_ci } else { 9539596a2c1Sopenharmony_ci originLocale.getDisplayCountry(locale, displayRegion); 9549596a2c1Sopenharmony_ci displayRegion.toUTF8String(result); 9559596a2c1Sopenharmony_ci } 9569596a2c1Sopenharmony_ci if (sentenceCase) { 9579596a2c1Sopenharmony_ci char ch = static_cast<char>(toupper(result[0])); 9589596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(result.replace(0, 1, 1, ch)); 9599596a2c1Sopenharmony_ci } 9609596a2c1Sopenharmony_ci return PseudoLocalizationProcessor(result); 9619596a2c1Sopenharmony_ci} 9629596a2c1Sopenharmony_ci 9639596a2c1Sopenharmony_cibool LocaleConfig::IsRTL(const string &locale) 9649596a2c1Sopenharmony_ci{ 9659596a2c1Sopenharmony_ci icu::Locale curLocale(locale.c_str()); 9669596a2c1Sopenharmony_ci return curLocale.isRightToLeft(); 9679596a2c1Sopenharmony_ci} 9689596a2c1Sopenharmony_ci 9699596a2c1Sopenharmony_civoid parseExtension(const std::string &extension, std::map<std::string, std::string> &map) 9709596a2c1Sopenharmony_ci{ 9719596a2c1Sopenharmony_ci std::string pattern = "-..-"; 9729596a2c1Sopenharmony_ci std::regex express(pattern); 9739596a2c1Sopenharmony_ci 9749596a2c1Sopenharmony_ci std::regex_token_iterator<std::string::const_iterator> begin1(extension.cbegin(), extension.cend(), express); 9759596a2c1Sopenharmony_ci std::regex_token_iterator<std::string::const_iterator> begin2(extension.cbegin(), extension.cend(), express, -1); 9769596a2c1Sopenharmony_ci begin2++; 9779596a2c1Sopenharmony_ci for (; begin1 != std::sregex_token_iterator() && begin2 != std::sregex_token_iterator(); begin1++, begin2++) { 9789596a2c1Sopenharmony_ci map.insert(std::pair<std::string, std::string>(begin1->str(), begin2->str())); 9799596a2c1Sopenharmony_ci } 9809596a2c1Sopenharmony_ci} 9819596a2c1Sopenharmony_ci 9829596a2c1Sopenharmony_civoid setExtension(std::string &extension, const std::string &tag, const std::set<string> &validValue, 9839596a2c1Sopenharmony_ci const std::map<std::string, std::string> &extensionMap, 9849596a2c1Sopenharmony_ci const std::map<std::string, std::string> &defaultExtensionMap) 9859596a2c1Sopenharmony_ci{ 9869596a2c1Sopenharmony_ci std::string value; 9879596a2c1Sopenharmony_ci auto it = extensionMap.find(tag); 9889596a2c1Sopenharmony_ci if (it != extensionMap.end()) { 9899596a2c1Sopenharmony_ci value = it->second; 9909596a2c1Sopenharmony_ci if (validValue.find(value) == validValue.end()) { 9919596a2c1Sopenharmony_ci return; 9929596a2c1Sopenharmony_ci } else { 9939596a2c1Sopenharmony_ci extension += tag; 9949596a2c1Sopenharmony_ci extension += value; 9959596a2c1Sopenharmony_ci } 9969596a2c1Sopenharmony_ci } else { 9979596a2c1Sopenharmony_ci it = defaultExtensionMap.find(tag); 9989596a2c1Sopenharmony_ci if (it != defaultExtensionMap.end()) { 9999596a2c1Sopenharmony_ci value = it->second; 10009596a2c1Sopenharmony_ci if (validValue.find(value) == validValue.end()) { 10019596a2c1Sopenharmony_ci return; 10029596a2c1Sopenharmony_ci } else { 10039596a2c1Sopenharmony_ci extension += tag; 10049596a2c1Sopenharmony_ci extension += value; 10059596a2c1Sopenharmony_ci } 10069596a2c1Sopenharmony_ci } 10079596a2c1Sopenharmony_ci } 10089596a2c1Sopenharmony_ci} 10099596a2c1Sopenharmony_ci 10109596a2c1Sopenharmony_civoid setOtherExtension(std::string &extension, std::map<std::string, std::string> &extensionMap, 10119596a2c1Sopenharmony_ci std::map<std::string, std::string> &defaultExtensionMap) 10129596a2c1Sopenharmony_ci{ 10139596a2c1Sopenharmony_ci std::set<std::string> tags; 10149596a2c1Sopenharmony_ci tags.insert("-ca-"); 10159596a2c1Sopenharmony_ci tags.insert("-co-"); 10169596a2c1Sopenharmony_ci tags.insert("-kn-"); 10179596a2c1Sopenharmony_ci tags.insert("-kf-"); 10189596a2c1Sopenharmony_ci tags.insert("-nu-"); 10199596a2c1Sopenharmony_ci tags.insert("-hc-"); 10209596a2c1Sopenharmony_ci 10219596a2c1Sopenharmony_ci for (auto it = tags.begin(); it != tags.end(); it++) { 10229596a2c1Sopenharmony_ci extensionMap.erase(*it); 10239596a2c1Sopenharmony_ci defaultExtensionMap.erase(*it); 10249596a2c1Sopenharmony_ci } 10259596a2c1Sopenharmony_ci 10269596a2c1Sopenharmony_ci for (auto it = defaultExtensionMap.begin(); it != defaultExtensionMap.end(); it++) { 10279596a2c1Sopenharmony_ci extensionMap.insert(std::pair<std::string, std::string>(it->first, it->second)); 10289596a2c1Sopenharmony_ci } 10299596a2c1Sopenharmony_ci 10309596a2c1Sopenharmony_ci for (auto it = extensionMap.begin(); it != extensionMap.end(); it++) { 10319596a2c1Sopenharmony_ci extension += it->first; 10329596a2c1Sopenharmony_ci extension += it->second; 10339596a2c1Sopenharmony_ci } 10349596a2c1Sopenharmony_ci} 10359596a2c1Sopenharmony_ci 10369596a2c1Sopenharmony_cistd::string LocaleConfig::GetValidLocale(const std::string &localeTag) 10379596a2c1Sopenharmony_ci{ 10389596a2c1Sopenharmony_ci std::string baseLocale = ""; 10399596a2c1Sopenharmony_ci std::string extension = ""; 10409596a2c1Sopenharmony_ci std::size_t found = localeTag.find("-u-"); 10419596a2c1Sopenharmony_ci baseLocale = localeTag.substr(0, found); 10429596a2c1Sopenharmony_ci if (found != std::string::npos) { 10439596a2c1Sopenharmony_ci extension = localeTag.substr(found); 10449596a2c1Sopenharmony_ci } 10459596a2c1Sopenharmony_ci std::map<std::string, std::string> extensionMap; 10469596a2c1Sopenharmony_ci if (extension != "") { 10479596a2c1Sopenharmony_ci parseExtension(extension, extensionMap); 10489596a2c1Sopenharmony_ci } 10499596a2c1Sopenharmony_ci 10509596a2c1Sopenharmony_ci std::string systemLocaleTag = GetSystemLocale(); 10519596a2c1Sopenharmony_ci std::string defaultExtension = ""; 10529596a2c1Sopenharmony_ci found = systemLocaleTag.find("-u-"); 10539596a2c1Sopenharmony_ci if (found != std::string::npos) { 10549596a2c1Sopenharmony_ci defaultExtension = systemLocaleTag.substr(found); 10559596a2c1Sopenharmony_ci } 10569596a2c1Sopenharmony_ci std::map<std::string, std::string> defaultExtensionMap; 10579596a2c1Sopenharmony_ci if (defaultExtension != "") { 10589596a2c1Sopenharmony_ci parseExtension(defaultExtension, defaultExtensionMap); 10599596a2c1Sopenharmony_ci } 10609596a2c1Sopenharmony_ci 10619596a2c1Sopenharmony_ci std::string ext = ""; 10629596a2c1Sopenharmony_ci setExtension(ext, "-ca-", validCaTag, extensionMap, defaultExtensionMap); 10639596a2c1Sopenharmony_ci setExtension(ext, "-co-", validCoTag, extensionMap, defaultExtensionMap); 10649596a2c1Sopenharmony_ci setExtension(ext, "-kn-", validKnTag, extensionMap, defaultExtensionMap); 10659596a2c1Sopenharmony_ci setExtension(ext, "-kf-", validKfTag, extensionMap, defaultExtensionMap); 10669596a2c1Sopenharmony_ci setExtension(ext, "-nu-", validNuTag, extensionMap, defaultExtensionMap); 10679596a2c1Sopenharmony_ci setExtension(ext, "-hc-", validHcTag, extensionMap, defaultExtensionMap); 10689596a2c1Sopenharmony_ci 10699596a2c1Sopenharmony_ci std::string otherExt = ""; 10709596a2c1Sopenharmony_ci setOtherExtension(otherExt, extensionMap, defaultExtensionMap); 10719596a2c1Sopenharmony_ci if (ext != "" || otherExt != "") { 10729596a2c1Sopenharmony_ci return baseLocale + "-u" + ext + otherExt; 10739596a2c1Sopenharmony_ci } else { 10749596a2c1Sopenharmony_ci return baseLocale; 10759596a2c1Sopenharmony_ci } 10769596a2c1Sopenharmony_ci} 10779596a2c1Sopenharmony_ci 10789596a2c1Sopenharmony_cibool LocaleConfig::IsEmpty24HourClock() 10799596a2c1Sopenharmony_ci{ 10809596a2c1Sopenharmony_ci std::string is24Hour = ReadSystemParameter(HOUR_KEY, CONFIG_LEN); 10819596a2c1Sopenharmony_ci if (is24Hour.compare("default") == 0) { 10829596a2c1Sopenharmony_ci return true; 10839596a2c1Sopenharmony_ci } 10849596a2c1Sopenharmony_ci return false; 10859596a2c1Sopenharmony_ci} 10869596a2c1Sopenharmony_ci 10879596a2c1Sopenharmony_cibool LocaleConfig::Is24HourClock() 10889596a2c1Sopenharmony_ci{ 10899596a2c1Sopenharmony_ci std::string is24Hour = ReadSystemParameter(HOUR_KEY, CONFIG_LEN); 10909596a2c1Sopenharmony_ci if (is24Hour.compare("default") == 0) { 10919596a2c1Sopenharmony_ci std::string systemLocale = GetSystemLocale(); 10929596a2c1Sopenharmony_ci return Is24HourLocale(systemLocale); 10939596a2c1Sopenharmony_ci } 10949596a2c1Sopenharmony_ci if (is24Hour.compare("true") == 0) { 10959596a2c1Sopenharmony_ci return true; 10969596a2c1Sopenharmony_ci } 10979596a2c1Sopenharmony_ci return false; 10989596a2c1Sopenharmony_ci} 10999596a2c1Sopenharmony_ci 11009596a2c1Sopenharmony_cistd::string LocaleConfig::GetSystemHour() 11019596a2c1Sopenharmony_ci{ 11029596a2c1Sopenharmony_ci bool is24Hour = Is24HourClock(); 11039596a2c1Sopenharmony_ci return is24Hour ? "true" : "false"; 11049596a2c1Sopenharmony_ci} 11059596a2c1Sopenharmony_ci 11069596a2c1Sopenharmony_cibool LocaleConfig::Is24HourLocale(const std::string& systemLocale) 11079596a2c1Sopenharmony_ci{ 11089596a2c1Sopenharmony_ci static std::unordered_map<std::string, bool> is24HourLocaleMap; 11099596a2c1Sopenharmony_ci if (is24HourLocaleMap.find(systemLocale) != is24HourLocaleMap.end()) { 11109596a2c1Sopenharmony_ci return is24HourLocaleMap[systemLocale]; 11119596a2c1Sopenharmony_ci } 11129596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 11139596a2c1Sopenharmony_ci icu::Locale locale = icu::Locale::forLanguageTag(icu::StringPiece(systemLocale), status); 11149596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 11159596a2c1Sopenharmony_ci HILOG_INFO_I18N("Is24HourLocale: %{public}s create locale failed", systemLocale.c_str()); 11169596a2c1Sopenharmony_ci return false; 11179596a2c1Sopenharmony_ci } 11189596a2c1Sopenharmony_ci 11199596a2c1Sopenharmony_ci icu::UnicodeString formatPattern; 11209596a2c1Sopenharmony_ci icu::DateFormat* dateFormat = icu::DateFormat::createTimeInstance(icu::DateFormat::EStyle::kLong, locale); 11219596a2c1Sopenharmony_ci if (dateFormat == nullptr) { 11229596a2c1Sopenharmony_ci HILOG_INFO_I18N("Is24HourLocale: createTimeInstance failed"); 11239596a2c1Sopenharmony_ci return false; 11249596a2c1Sopenharmony_ci } 11259596a2c1Sopenharmony_ci icu::SimpleDateFormat* simDateFormat = static_cast<icu::SimpleDateFormat*>(dateFormat); 11269596a2c1Sopenharmony_ci if (simDateFormat == nullptr) { 11279596a2c1Sopenharmony_ci HILOG_INFO_I18N("Is24HourLocale: failed to convert dateFormat"); 11289596a2c1Sopenharmony_ci return false; 11299596a2c1Sopenharmony_ci } 11309596a2c1Sopenharmony_ci simDateFormat->toPattern(formatPattern); 11319596a2c1Sopenharmony_ci delete dateFormat; 11329596a2c1Sopenharmony_ci std::string pattern; 11339596a2c1Sopenharmony_ci formatPattern.toUTF8String(pattern); 11349596a2c1Sopenharmony_ci bool result = HasDesignator(pattern, 'H'); 11359596a2c1Sopenharmony_ci is24HourLocaleMap[systemLocale] = result; 11369596a2c1Sopenharmony_ci return result; 11379596a2c1Sopenharmony_ci} 11389596a2c1Sopenharmony_ci 11399596a2c1Sopenharmony_cibool LocaleConfig::HasDesignator(const std::string& pattern, const char designator) 11409596a2c1Sopenharmony_ci{ 11419596a2c1Sopenharmony_ci if (pattern.empty()) { 11429596a2c1Sopenharmony_ci HILOG_INFO_I18N("HasDesignator: pattern is empty"); 11439596a2c1Sopenharmony_ci return false; 11449596a2c1Sopenharmony_ci } 11459596a2c1Sopenharmony_ci bool insideQuote = false; 11469596a2c1Sopenharmony_ci for (const auto& c : pattern) { 11479596a2c1Sopenharmony_ci if (c == '\'') { 11489596a2c1Sopenharmony_ci insideQuote = !insideQuote; 11499596a2c1Sopenharmony_ci } else if (!insideQuote) { 11509596a2c1Sopenharmony_ci if (c == designator) { 11519596a2c1Sopenharmony_ci return true; 11529596a2c1Sopenharmony_ci } 11539596a2c1Sopenharmony_ci } 11549596a2c1Sopenharmony_ci } 11559596a2c1Sopenharmony_ci return false; 11569596a2c1Sopenharmony_ci} 11579596a2c1Sopenharmony_ci 11589596a2c1Sopenharmony_cibool LocaleConfig::GetUsingLocalDigit() 11599596a2c1Sopenharmony_ci{ 11609596a2c1Sopenharmony_ci std::string locale = GetSystemLocale(); 11619596a2c1Sopenharmony_ci LocaleInfo localeInfo(locale); 11629596a2c1Sopenharmony_ci std::string language = localeInfo.GetLanguage(); 11639596a2c1Sopenharmony_ci if (localDigitMap.find(language) == localDigitMap.end()) { 11649596a2c1Sopenharmony_ci return false; 11659596a2c1Sopenharmony_ci } 11669596a2c1Sopenharmony_ci std::string localNumberSystem = localDigitMap.at(language); 11679596a2c1Sopenharmony_ci if (localNumberSystem.compare(localeInfo.GetNumberingSystem()) != 0) { 11689596a2c1Sopenharmony_ci return false; 11699596a2c1Sopenharmony_ci } 11709596a2c1Sopenharmony_ci return true; 11719596a2c1Sopenharmony_ci} 11729596a2c1Sopenharmony_ci 11739596a2c1Sopenharmony_cistd::unordered_set<std::string> LocaleConfig::GetBlockedLanguages() 11749596a2c1Sopenharmony_ci{ 11759596a2c1Sopenharmony_ci return blockedLanguages; 11769596a2c1Sopenharmony_ci} 11779596a2c1Sopenharmony_ci 11789596a2c1Sopenharmony_cistd::unordered_set<std::string> LocaleConfig::GetBlockedRegions() 11799596a2c1Sopenharmony_ci{ 11809596a2c1Sopenharmony_ci return blockedRegions; 11819596a2c1Sopenharmony_ci} 11829596a2c1Sopenharmony_ci 11839596a2c1Sopenharmony_cistd::unordered_set<std::string> LocaleConfig::GetLanguageBlockedRegions() 11849596a2c1Sopenharmony_ci{ 11859596a2c1Sopenharmony_ci std::string systemLanguage = LocaleConfig::GetSystemLanguage(); 11869596a2c1Sopenharmony_ci if (blockedLanguageRegions.find(systemLanguage) != blockedLanguageRegions.end()) { 11879596a2c1Sopenharmony_ci return blockedLanguageRegions[systemLanguage]; 11889596a2c1Sopenharmony_ci } 11899596a2c1Sopenharmony_ci std::unordered_set<std::string> emptyResult; 11909596a2c1Sopenharmony_ci return emptyResult; 11919596a2c1Sopenharmony_ci} 11929596a2c1Sopenharmony_ci 11939596a2c1Sopenharmony_ciI18nErrorCode LocaleConfig::SetSystemLanguage(const std::string &languageTag) 11949596a2c1Sopenharmony_ci{ 11959596a2c1Sopenharmony_ci if (!IsValidTag(languageTag)) { 11969596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::SetSystemLanguage %{public}s is not valid language tag.", 11979596a2c1Sopenharmony_ci languageTag.c_str()); 11989596a2c1Sopenharmony_ci return I18nErrorCode::INVALID_LANGUAGE_TAG; 11999596a2c1Sopenharmony_ci } 12009596a2c1Sopenharmony_ci // save old language, reset system language to old language if update locale failed. 12019596a2c1Sopenharmony_ci std::string oldLanguageTag = GetSystemLanguage(); 12029596a2c1Sopenharmony_ci if (SetParameter(LANGUAGE_KEY, languageTag.data()) != 0) { 12039596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::SetSystemLanguage update system language failed."); 12049596a2c1Sopenharmony_ci return I18nErrorCode::UPDATE_SYSTEM_LANGUAGE_FAILED; 12059596a2c1Sopenharmony_ci } 12069596a2c1Sopenharmony_ci std::string newLocaleTag = UpdateLanguageOfLocale(languageTag); 12079596a2c1Sopenharmony_ci if (SetSystemLocale(newLocaleTag) == I18nErrorCode::SUCCESS) { 12089596a2c1Sopenharmony_ci#ifdef SUPPORT_MULTI_USER 12099596a2c1Sopenharmony_ci MultiUsers::SaveLanguage("", languageTag); 12109596a2c1Sopenharmony_ci#endif 12119596a2c1Sopenharmony_ci return I18nErrorCode::SUCCESS; 12129596a2c1Sopenharmony_ci } 12139596a2c1Sopenharmony_ci // reset system language to old language in case that system language is inconsist with system locale's lanuage. 12149596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::SetSystemLanguage update system locale failed."); 12159596a2c1Sopenharmony_ci SetParameter(LANGUAGE_KEY, oldLanguageTag.data()); 12169596a2c1Sopenharmony_ci return I18nErrorCode::UPDATE_SYSTEM_LANGUAGE_FAILED; 12179596a2c1Sopenharmony_ci} 12189596a2c1Sopenharmony_ci 12199596a2c1Sopenharmony_ciI18nErrorCode LocaleConfig::SetSystemRegion(const std::string ®ionTag) 12209596a2c1Sopenharmony_ci{ 12219596a2c1Sopenharmony_ci if (!IsValidRegion(regionTag)) { 12229596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::SetSystemRegion %{public}s is not valid region tag.", regionTag.c_str()); 12239596a2c1Sopenharmony_ci return I18nErrorCode::INVALID_REGION_TAG; 12249596a2c1Sopenharmony_ci } 12259596a2c1Sopenharmony_ci return SetSystemLocale(UpdateRegionOfLocale(regionTag)); 12269596a2c1Sopenharmony_ci} 12279596a2c1Sopenharmony_ci 12289596a2c1Sopenharmony_ciI18nErrorCode LocaleConfig::SetSystemLocale(const std::string &localeTag) 12299596a2c1Sopenharmony_ci{ 12309596a2c1Sopenharmony_ci if (!IsValidTag(localeTag)) { 12319596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::SetSystemLocale %{public}s is not a valid locale tag.", localeTag.c_str()); 12329596a2c1Sopenharmony_ci return I18nErrorCode::INVALID_LOCALE_TAG; 12339596a2c1Sopenharmony_ci } 12349596a2c1Sopenharmony_ci if (SetParameter(LOCALE_KEY, localeTag.data()) != 0) { 12359596a2c1Sopenharmony_ci return I18nErrorCode::UPDATE_SYSTEM_LOCALE_FAILED; 12369596a2c1Sopenharmony_ci } 12379596a2c1Sopenharmony_ci#ifdef SUPPORT_MULTI_USER 12389596a2c1Sopenharmony_ci MultiUsers::SaveLocale("", localeTag); 12399596a2c1Sopenharmony_ci#endif 12409596a2c1Sopenharmony_ci#ifdef SUPPORT_GRAPHICS 12419596a2c1Sopenharmony_ci UpdateConfiguration(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE, localeTag); 12429596a2c1Sopenharmony_ci return PublishCommonEvent(EventFwk::CommonEventSupport::COMMON_EVENT_LOCALE_CHANGED); 12439596a2c1Sopenharmony_ci#else 12449596a2c1Sopenharmony_ci return I18nErrorCode::SUCCESS; 12459596a2c1Sopenharmony_ci#endif 12469596a2c1Sopenharmony_ci} 12479596a2c1Sopenharmony_ci 12489596a2c1Sopenharmony_cibool LocaleConfig::IsValid24HourClockValue(const std::string &tag) 12499596a2c1Sopenharmony_ci{ 12509596a2c1Sopenharmony_ci if (tag.compare("true") == 0 || tag.compare("false") == 0 || tag.compare("default") == 0) { 12519596a2c1Sopenharmony_ci return true; 12529596a2c1Sopenharmony_ci } 12539596a2c1Sopenharmony_ci return false; 12549596a2c1Sopenharmony_ci} 12559596a2c1Sopenharmony_ci 12569596a2c1Sopenharmony_ciI18nErrorCode LocaleConfig::Set24HourClock(const std::string &option) 12579596a2c1Sopenharmony_ci{ 12589596a2c1Sopenharmony_ci if (!IsValid24HourClockValue(option)) { 12599596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::Set24HourClock invalid 24 Hour clock tag: %{public}s", option.c_str()); 12609596a2c1Sopenharmony_ci return I18nErrorCode::INVALID_24_HOUR_CLOCK_TAG; 12619596a2c1Sopenharmony_ci } 12629596a2c1Sopenharmony_ci if (SetParameter(HOUR_KEY, option.data()) != 0) { 12639596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::Set24HourClock update 24 hour clock failed with option=%{public}s", 12649596a2c1Sopenharmony_ci option.c_str()); 12659596a2c1Sopenharmony_ci return I18nErrorCode::UPDATE_24_HOUR_CLOCK_FAILED; 12669596a2c1Sopenharmony_ci } 12679596a2c1Sopenharmony_ci#ifdef SUPPORT_MULTI_USER 12689596a2c1Sopenharmony_ci MultiUsers::SaveIs24Hour("", option); 12699596a2c1Sopenharmony_ci#endif 12709596a2c1Sopenharmony_ci#ifdef SUPPORT_GRAPHICS 12719596a2c1Sopenharmony_ci UpdateConfiguration(AAFwk::GlobalConfigurationKey::SYSTEM_HOUR, option); 12729596a2c1Sopenharmony_ci return PublishCommonEvent(EventFwk::CommonEventSupport::COMMON_EVENT_TIME_CHANGED); 12739596a2c1Sopenharmony_ci#else 12749596a2c1Sopenharmony_ci return I18nErrorCode::SUCCESS; 12759596a2c1Sopenharmony_ci#endif 12769596a2c1Sopenharmony_ci} 12779596a2c1Sopenharmony_ci 12789596a2c1Sopenharmony_ciI18nErrorCode LocaleConfig::SetUsingLocalDigit(bool flag) 12799596a2c1Sopenharmony_ci{ 12809596a2c1Sopenharmony_ci // check whether current language support local digit. 12819596a2c1Sopenharmony_ci std::string localeTag = GetSystemLocale(); 12829596a2c1Sopenharmony_ci std::string languageTag = localeTag.substr(0, 2); // obtain 2 length language code. 12839596a2c1Sopenharmony_ci auto it = localDigitMap.find(languageTag); 12849596a2c1Sopenharmony_ci if (it == localDigitMap.end()) { 12859596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::SetUsingLocalDigit current system doesn't support set local digit"); 12869596a2c1Sopenharmony_ci return I18nErrorCode::UPDATE_LOCAL_DIGIT_FAILED; 12879596a2c1Sopenharmony_ci } 12889596a2c1Sopenharmony_ci // update system locale. 12899596a2c1Sopenharmony_ci return SetSystemLocale(UpdateNumberSystemOfLocale(it->second, flag)); 12909596a2c1Sopenharmony_ci} 12919596a2c1Sopenharmony_ci 12929596a2c1Sopenharmony_cistd::string LocaleConfig::UpdateNumberSystemOfLocale(const std::string &localDigitTag, bool flag) 12939596a2c1Sopenharmony_ci{ 12949596a2c1Sopenharmony_ci if (flag) { 12959596a2c1Sopenharmony_ci // add local digit tag to number system param of locale 12969596a2c1Sopenharmony_ci return AddLocalDigitToLocale(localDigitTag); 12979596a2c1Sopenharmony_ci } 12989596a2c1Sopenharmony_ci // remove local digit tag to number system param of locale 12999596a2c1Sopenharmony_ci return RemoveLocalDigitFromLocale(localDigitTag); 13009596a2c1Sopenharmony_ci} 13019596a2c1Sopenharmony_ci 13029596a2c1Sopenharmony_cistd::string LocaleConfig::AddLocalDigitToLocale(const std::string &localDigitTag) 13039596a2c1Sopenharmony_ci{ 13049596a2c1Sopenharmony_ci std::string localeTag = GetSystemLocale(); 13059596a2c1Sopenharmony_ci // Case: no extend param, add '-u-' and number system tag. 13069596a2c1Sopenharmony_ci if (localeTag.find("-u-") == std::string::npos) { 13079596a2c1Sopenharmony_ci localeTag += "-u" + std::string(NUMBER_SYSTEM_KEY) + localDigitTag; 13089596a2c1Sopenharmony_ci return localeTag; 13099596a2c1Sopenharmony_ci } 13109596a2c1Sopenharmony_ci // Case: has extend param but doesn't hava number system param, add number system tag. 13119596a2c1Sopenharmony_ci if (localeTag.find(NUMBER_SYSTEM_KEY) == std::string::npos) { 13129596a2c1Sopenharmony_ci localeTag += std::string(NUMBER_SYSTEM_KEY) + localDigitTag; 13139596a2c1Sopenharmony_ci return localeTag; 13149596a2c1Sopenharmony_ci } 13159596a2c1Sopenharmony_ci // Case: has number system param, replace local digit tag to localDigitTag. 13169596a2c1Sopenharmony_ci LocaleInfo localeInfo(localeTag); 13179596a2c1Sopenharmony_ci std::string oldNumberSystem = localeInfo.GetNumberingSystem(); 13189596a2c1Sopenharmony_ci localeTag.replace(localeTag.find(oldNumberSystem), oldNumberSystem.length(), localDigitTag); 13199596a2c1Sopenharmony_ci return localeTag; 13209596a2c1Sopenharmony_ci} 13219596a2c1Sopenharmony_ci 13229596a2c1Sopenharmony_cistd::string LocaleConfig::RemoveLocalDigitFromLocale(const std::string &localDigitTag) 13239596a2c1Sopenharmony_ci{ 13249596a2c1Sopenharmony_ci // remove number system tag from locale 13259596a2c1Sopenharmony_ci std::string localeTag = GetSystemLocale(); 13269596a2c1Sopenharmony_ci std::string numberSystemTag = NUMBER_SYSTEM_KEY + localDigitTag; 13279596a2c1Sopenharmony_ci size_t pos = localeTag.find(numberSystemTag); 13289596a2c1Sopenharmony_ci if (pos != std::string::npos) { 13299596a2c1Sopenharmony_ci localeTag.replace(pos, numberSystemTag.length(), ""); 13309596a2c1Sopenharmony_ci } 13319596a2c1Sopenharmony_ci // remove "-u" if localeTag ends with "-u" 13329596a2c1Sopenharmony_ci size_t uLength = 2; 13339596a2c1Sopenharmony_ci if (localeTag.find("-u") == (localeTag.length() - uLength)) { 13349596a2c1Sopenharmony_ci localeTag.resize(localeTag.length() - uLength); 13359596a2c1Sopenharmony_ci } 13369596a2c1Sopenharmony_ci return localeTag; 13379596a2c1Sopenharmony_ci} 13389596a2c1Sopenharmony_ci 13399596a2c1Sopenharmony_ci#ifdef SUPPORT_GRAPHICS 13409596a2c1Sopenharmony_civoid LocaleConfig::UpdateConfiguration(const char *key, const std::string &value) 13419596a2c1Sopenharmony_ci{ 13429596a2c1Sopenharmony_ci AppExecFwk::Configuration configuration; 13439596a2c1Sopenharmony_ci configuration.AddItem(key, value); 13449596a2c1Sopenharmony_ci auto appMgrClient = std::make_unique<AppExecFwk::AppMgrClient>(); 13459596a2c1Sopenharmony_ci appMgrClient->UpdateConfiguration(configuration); 13469596a2c1Sopenharmony_ci HILOG_INFO_I18N("LocaleConfig::UpdateLanguageConfiguration update configuration finished."); 13479596a2c1Sopenharmony_ci} 13489596a2c1Sopenharmony_ci 13499596a2c1Sopenharmony_ciI18nErrorCode LocaleConfig::PublishCommonEvent(const std::string &eventType) 13509596a2c1Sopenharmony_ci{ 13519596a2c1Sopenharmony_ci OHOS::AAFwk::Want localeChangeWant; 13529596a2c1Sopenharmony_ci localeChangeWant.SetAction(eventType); 13539596a2c1Sopenharmony_ci OHOS::EventFwk::CommonEventData event(localeChangeWant); 13549596a2c1Sopenharmony_ci if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(event)) { 13559596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::PublishCommonEvent Failed to Publish event %{public}s", 13569596a2c1Sopenharmony_ci localeChangeWant.GetAction().c_str()); 13579596a2c1Sopenharmony_ci return I18nErrorCode::PUBLISH_COMMON_EVENT_FAILED; 13589596a2c1Sopenharmony_ci } 13599596a2c1Sopenharmony_ci HILOG_INFO_I18N("LocaleConfig::PublishCommonEvent publish event finished."); 13609596a2c1Sopenharmony_ci return I18nErrorCode::SUCCESS; 13619596a2c1Sopenharmony_ci} 13629596a2c1Sopenharmony_ci#endif 13639596a2c1Sopenharmony_ci 13649596a2c1Sopenharmony_cistd::string LocaleConfig::UpdateLanguageOfLocale(const std::string &languageTag) 13659596a2c1Sopenharmony_ci{ 13669596a2c1Sopenharmony_ci // Compute language and script part from languageTag. 13679596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 13689596a2c1Sopenharmony_ci icu::Locale languageLocale = icu::Locale::forLanguageTag(languageTag.c_str(), status); 13699596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 13709596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::UpdateLanguageOfLocale init icu Locale for language %{public}s failed.", 13719596a2c1Sopenharmony_ci languageTag.c_str()); 13729596a2c1Sopenharmony_ci return ""; 13739596a2c1Sopenharmony_ci } 13749596a2c1Sopenharmony_ci std::string langTag = languageLocale.getLanguage(); 13759596a2c1Sopenharmony_ci std::string scriptTag = languageLocale.getScript(); 13769596a2c1Sopenharmony_ci // Compute region and extend param part from current system locale. 13779596a2c1Sopenharmony_ci std::string systemLocaleTag = GetSystemLocale(); 13789596a2c1Sopenharmony_ci icu::Locale systemLocale = icu::Locale::forLanguageTag(systemLocaleTag.c_str(), status); 13799596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 13809596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::UpdateSystemLocale init icu Locale for locale %{public}s failed.", 13819596a2c1Sopenharmony_ci systemLocaleTag.c_str()); 13829596a2c1Sopenharmony_ci return ""; 13839596a2c1Sopenharmony_ci } 13849596a2c1Sopenharmony_ci std::string regionTag = systemLocale.getCountry(); 13859596a2c1Sopenharmony_ci std::string extendParamTag; 13869596a2c1Sopenharmony_ci size_t pos = systemLocaleTag.find("-u-"); 13879596a2c1Sopenharmony_ci if (pos != std::string::npos) { 13889596a2c1Sopenharmony_ci extendParamTag = systemLocaleTag.substr(pos); 13899596a2c1Sopenharmony_ci } 13909596a2c1Sopenharmony_ci // Combine above elements. 13919596a2c1Sopenharmony_ci return CreateLocale(langTag, scriptTag, regionTag, extendParamTag); 13929596a2c1Sopenharmony_ci} 13939596a2c1Sopenharmony_ci 13949596a2c1Sopenharmony_cistd::string LocaleConfig::CreateLocale(const std::string &languageTag, const std::string &scriptTag, 13959596a2c1Sopenharmony_ci const std::string ®ionTag, const std::string &extendParamTag) 13969596a2c1Sopenharmony_ci{ 13979596a2c1Sopenharmony_ci // combine language, script, region and extend param with '-' 13989596a2c1Sopenharmony_ci std::string localeTag = languageTag; 13999596a2c1Sopenharmony_ci std::string splitor = "-"; 14009596a2c1Sopenharmony_ci if (scriptTag.length() > 0) { 14019596a2c1Sopenharmony_ci localeTag += splitor + scriptTag; 14029596a2c1Sopenharmony_ci } 14039596a2c1Sopenharmony_ci if (regionTag.length() > 0) { 14049596a2c1Sopenharmony_ci localeTag += splitor + regionTag; 14059596a2c1Sopenharmony_ci } 14069596a2c1Sopenharmony_ci if (extendParamTag.length() > 0) { 14079596a2c1Sopenharmony_ci localeTag += extendParamTag; 14089596a2c1Sopenharmony_ci } 14099596a2c1Sopenharmony_ci return localeTag; 14109596a2c1Sopenharmony_ci} 14119596a2c1Sopenharmony_ci 14129596a2c1Sopenharmony_cistd::string LocaleConfig::UpdateRegionOfLocale(const std::string ®ionTag) 14139596a2c1Sopenharmony_ci{ 14149596a2c1Sopenharmony_ci std::string localeTag = GetSystemLocale(); 14159596a2c1Sopenharmony_ci // if current system locale is null, contruct a locale from region tag. 14169596a2c1Sopenharmony_ci if (localeTag.length() == 0) { 14179596a2c1Sopenharmony_ci return CreateLocaleFromRegion(regionTag); 14189596a2c1Sopenharmony_ci } 14199596a2c1Sopenharmony_ci // combine locale with origin locale's language and script with regionTag. 14209596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 14219596a2c1Sopenharmony_ci const icu::Locale origin = icu::Locale::forLanguageTag(localeTag, status); 14229596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 14239596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::UpdateRegionOfLocale init origin locale failed."); 14249596a2c1Sopenharmony_ci return ""; 14259596a2c1Sopenharmony_ci } 14269596a2c1Sopenharmony_ci icu::LocaleBuilder builder = icu::LocaleBuilder().setLanguage(origin.getLanguage()). 14279596a2c1Sopenharmony_ci setScript(origin.getScript()).setRegion(regionTag); 14289596a2c1Sopenharmony_ci icu::Locale temp = builder.setExtension('u', "").build(status); 14299596a2c1Sopenharmony_ci string ret = temp.toLanguageTag<string>(status); 14309596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 14319596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::UpdateRegionOfLocale obtain new locale's tag failed."); 14329596a2c1Sopenharmony_ci return ""; 14339596a2c1Sopenharmony_ci } 14349596a2c1Sopenharmony_ci return ret; 14359596a2c1Sopenharmony_ci} 14369596a2c1Sopenharmony_ci 14379596a2c1Sopenharmony_cistd::string LocaleConfig::CreateLocaleFromRegion(const std::string ®ionTag) 14389596a2c1Sopenharmony_ci{ 14399596a2c1Sopenharmony_ci // fill locale with icu 14409596a2c1Sopenharmony_ci icu::Locale locale("", regionTag.c_str()); 14419596a2c1Sopenharmony_ci UErrorCode status = U_ZERO_ERROR; 14429596a2c1Sopenharmony_ci locale.addLikelySubtags(status); 14439596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 14449596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::CreateLocaleFromRegion init new locale failed."); 14459596a2c1Sopenharmony_ci return ""; 14469596a2c1Sopenharmony_ci } 14479596a2c1Sopenharmony_ci std::string localeTag = locale.toLanguageTag<string>(status); 14489596a2c1Sopenharmony_ci if (U_FAILURE(status)) { 14499596a2c1Sopenharmony_ci HILOG_ERROR_I18N("LocaleConfig::CreateLocaleFromRegion obtain new locale's tag failed."); 14509596a2c1Sopenharmony_ci return ""; 14519596a2c1Sopenharmony_ci } 14529596a2c1Sopenharmony_ci return localeTag; 14539596a2c1Sopenharmony_ci} 14549596a2c1Sopenharmony_ci 14559596a2c1Sopenharmony_cistd::string LocaleConfig::GetLanguageKey() 14569596a2c1Sopenharmony_ci{ 14579596a2c1Sopenharmony_ci return LANGUAGE_KEY; 14589596a2c1Sopenharmony_ci} 14599596a2c1Sopenharmony_ci 14609596a2c1Sopenharmony_cistd::string LocaleConfig::GetLocaleKey() 14619596a2c1Sopenharmony_ci{ 14629596a2c1Sopenharmony_ci return LOCALE_KEY; 14639596a2c1Sopenharmony_ci} 14649596a2c1Sopenharmony_ci 14659596a2c1Sopenharmony_cistd::string LocaleConfig::GetHourKey() 14669596a2c1Sopenharmony_ci{ 14679596a2c1Sopenharmony_ci return HOUR_KEY; 14689596a2c1Sopenharmony_ci} 14699596a2c1Sopenharmony_ci} // namespace I18n 14709596a2c1Sopenharmony_ci} // namespace Global 14719596a2c1Sopenharmony_ci} // namespace OHOS 1472