1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "dm_language_manager.h"
17
18 #include "cJSON.h"
19 #include <map>
20
21 #include "dm_anonymous.h"
22 #include "dm_constants.h"
23 #include "dm_log.h"
24 #include "json_object.h"
25 #include "parameter.h"
26
27 namespace OHOS {
28 namespace DistributedHardware {
29 DM_IMPLEMENT_SINGLE_INSTANCE(DmLanguageManager);
30 const int32_t MAX_LEN = 128;
31 const std::string SYSTEM_LANGUAGE_KEY = "persist.global.language";
32 const std::string SYSTEM_LANGUAGE_LOCALE_KEY = "persist.global.locale";
33 const std::string DEFAULT_LANGUAGE = "zh-Hans";
34 const std::string LANGUAGE_EN = "en-Latn_US";
35 const std::string LANGUAGE_AND_LOCALE_STR =
36 R"({
37 "zh-Hant": [
38 {
39 "persist.global.locale": "zh-Hant-HK"
40 },
41 {
42 "persist.global.locale": "zh-Hant-TW"
43 }
44 ]
45 })";
46
GetSystemParam(const std::string & key)47 std::string DmLanguageManager::GetSystemParam(const std::string &key)
48 {
49 char value[MAX_LEN] = {0};
50 int32_t ret = GetParameter(key.c_str(), "", value, MAX_LEN);
51 if (ret <= 0) {
52 LOGE("GetSystemParam %{public}s failed", key.c_str());
53 return "";
54 }
55 return std::string(value);
56 }
57
GetLocaleByLanguage(const std::string & language,std::set<std::string> & localeSet)58 void DmLanguageManager::GetLocaleByLanguage(const std::string &language, std::set<std::string> &localeSet)
59 {
60 cJSON *languageAndLocaleObj = cJSON_Parse(LANGUAGE_AND_LOCALE_STR.c_str());
61 if (languageAndLocaleObj == NULL) {
62 LOGE("parse languageAndLocaleObj failed");
63 return;
64 }
65 cJSON *languageObj = cJSON_GetObjectItem(languageAndLocaleObj, language.c_str());
66 if (languageObj == NULL || !cJSON_IsArray(languageObj)) {
67 cJSON_Delete(languageAndLocaleObj);
68 return;
69 }
70 cJSON *item = NULL;
71 cJSON_ArrayForEach(item, languageObj) {
72 if (!cJSON_IsObject(item)) {
73 LOGE("item is not object!");
74 continue;
75 }
76 cJSON* localeObj = cJSON_GetObjectItemCaseSensitive(item, SYSTEM_LANGUAGE_LOCALE_KEY.c_str());
77 if (!cJSON_IsString(localeObj) || localeObj->valuestring == NULL) {
78 LOGE("Get localeObj fail!");
79 continue;
80 }
81 localeSet.insert(localeObj->valuestring);
82 }
83 cJSON_Delete(languageAndLocaleObj);
84 }
85
GetTextBySystemLanguage(const std::string & text)86 std::string DmLanguageManager::GetTextBySystemLanguage(const std::string &text)
87 {
88 if (text.empty()) {
89 return "";
90 }
91 cJSON *textObj = cJSON_Parse(text.c_str());
92 if (textObj == NULL) {
93 LOGE("parse text failed");
94 return text;
95 }
96 std::string resultText = text;
97 std::string language = GetSystemParam(SYSTEM_LANGUAGE_KEY);
98 language = language.empty() ? DEFAULT_LANGUAGE : language;
99 std::set<std::string> localeSet;
100 GetLocaleByLanguage(language, localeSet);
101 if (localeSet.size() > 0) {
102 resultText = GetTextBySystemLocale(textObj, localeSet);
103 if (!resultText.empty()) {
104 cJSON_Delete(textObj);
105 return resultText;
106 }
107 }
108 cJSON *languageJson = cJSON_GetObjectItem(textObj, language.c_str());
109 if (languageJson != NULL && cJSON_IsString(languageJson)) {
110 resultText = std::string(languageJson->valuestring);
111 cJSON_Delete(textObj);
112 return resultText;
113 }
114 cJSON *defaultJson = cJSON_GetObjectItem(textObj, DEFAULT_LANGUAGE.c_str());
115 if (defaultJson != NULL && cJSON_IsString(defaultJson)) {
116 resultText = std::string(defaultJson->valuestring);
117 cJSON_Delete(textObj);
118 return resultText;
119 }
120 cJSON *enJson = cJSON_GetObjectItem(textObj, LANGUAGE_EN.c_str());
121 if (enJson != NULL && cJSON_IsString(enJson)) {
122 resultText = std::string(enJson->valuestring);
123 cJSON_Delete(textObj);
124 return resultText;
125 }
126 cJSON_Delete(textObj);
127 return "";
128 }
129
GetTextBySystemLanguage(const std::string & text,const std::string & language)130 std::string DmLanguageManager::GetTextBySystemLanguage(const std::string &text, const std::string &language)
131 {
132 if (text.empty()) {
133 return "";
134 }
135 JsonObject jsonObject(text);
136 if (jsonObject.IsDiscarded()) {
137 LOGI("the text is not a jsonStr");
138 return text;
139 }
140 if (IsString(jsonObject, language)) {
141 return jsonObject[language].Get<std::string>();
142 }
143 if (IsString(jsonObject, DEFAULT_LANGUAGE)) {
144 return jsonObject[DEFAULT_LANGUAGE].Get<std::string>();
145 }
146 if (IsString(jsonObject, LANGUAGE_EN)) {
147 return jsonObject[LANGUAGE_EN].Get<std::string>();
148 }
149 return "";
150 }
151
GetTextBySystemLocale(const cJSON * const textObj,const std::set<std::string> & localeSet)152 std::string DmLanguageManager::GetTextBySystemLocale(const cJSON *const textObj,
153 const std::set<std::string> &localeSet)
154 {
155 std::string resultText = "";
156 std::string languageLocale = GetSystemParam(SYSTEM_LANGUAGE_LOCALE_KEY);
157 cJSON *languageLocaleson = cJSON_GetObjectItem(textObj, languageLocale.c_str());
158 if (languageLocaleson != NULL && cJSON_IsString(languageLocaleson)) {
159 resultText = std::string(languageLocaleson->valuestring);
160 return resultText;
161 }
162 for (std::string locale : localeSet) {
163 cJSON *localesonObj = cJSON_GetObjectItem(textObj, locale.c_str());
164 if (localesonObj != NULL && cJSON_IsString(localesonObj)) {
165 resultText = std::string(localesonObj->valuestring);
166 return resultText;
167 }
168 }
169 return "";
170 }
171
GetSystemLanguage()172 std::string DmLanguageManager::GetSystemLanguage()
173 {
174 std::string language = GetSystemParam(SYSTEM_LANGUAGE_KEY);
175 language = language.empty() ? DEFAULT_LANGUAGE : language;
176 std::set<std::string> localeSet;
177 GetLocaleByLanguage(language, localeSet);
178 if (localeSet.size() > 0) {
179 std::string languageLocale = GetSystemParam(SYSTEM_LANGUAGE_LOCALE_KEY);
180 if (localeSet.find(languageLocale) != localeSet.end()) {
181 return languageLocale;
182 }
183 return *localeSet.begin();
184 }
185 return language;
186 }
187
GetTextByLanguage(const std::string & text,const std::string & language)188 std::string DmLanguageManager::GetTextByLanguage(const std::string &text, const std::string &language)
189 {
190 if (text.empty()) {
191 return "";
192 }
193 cJSON *textObj = cJSON_Parse(text.c_str());
194 if (textObj == NULL) {
195 LOGE("parse text failed");
196 return text;
197 }
198 std::string resultText = text;
199
200 cJSON *languageJson = cJSON_GetObjectItem(textObj, language.c_str());
201 if (languageJson != NULL && cJSON_IsString(languageJson)) {
202 resultText = std::string(languageJson->valuestring);
203 cJSON_Delete(textObj);
204 return resultText;
205 }
206 cJSON *defaultJson = cJSON_GetObjectItem(textObj, DEFAULT_LANGUAGE.c_str());
207 if (defaultJson != NULL && cJSON_IsString(defaultJson)) {
208 resultText = std::string(defaultJson->valuestring);
209 cJSON_Delete(textObj);
210 return resultText;
211 }
212 cJSON *enJson = cJSON_GetObjectItem(textObj, LANGUAGE_EN.c_str());
213 if (enJson != NULL && cJSON_IsString(enJson)) {
214 resultText = std::string(enJson->valuestring);
215 cJSON_Delete(textObj);
216 return resultText;
217 }
218 cJSON_Delete(textObj);
219 return "";
220 }
221
222 } // namespace DistributedHardware
223 } // namespace OHOS