• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "preferred_language.h"
16 
17 #include "locale_config.h"
18 #include "locale_info.h"
19 #include "parameter.h"
20 #include "vector"
21 
22 
23 namespace OHOS {
24 namespace Global {
25 namespace I18n {
26 const char *PreferredLanguage::RESOURCE_PATH_HEAD = "/data/accounts/account_0/applications/";
27 const char *PreferredLanguage::RESOURCE_PATH_TAILOR = "/assets/entry/resources.index";
28 const char *PreferredLanguage::RESOURCE_PATH_SPLITOR = "/";
29 const char *PreferredLanguage::PREFERRED_LANGUAGES = "persist.sys.preferredLanguages";
30 
AddPreferredLanguageExist(std::vector<std::string> & preferredLanguageList,int languageIdx,int index,const std::string & language)31 bool PreferredLanguage::AddPreferredLanguageExist(std::vector<std::string> &preferredLanguageList, int languageIdx,
32     int index, const std::string& language)
33 {
34     if (languageIdx == index) {
35         return false;
36     }
37     if (languageIdx < index) {
38         for (int i = languageIdx; i < index; i++) {
39             preferredLanguageList[i] = preferredLanguageList[i + 1];
40         }
41     }
42     if (languageIdx > index) {
43         for (int i = languageIdx; i > index; i--) {
44             preferredLanguageList[i] = preferredLanguageList[i - 1];
45         }
46     }
47     preferredLanguageList[index] = language;
48     if (!languageIdx || !index) {
49         bool status = LocaleConfig::SetSystemLanguage(preferredLanguageList[0]);
50         if (!status) {
51             return false;
52         }
53     }
54     return true;
55 }
56 
AddPreferredLanguageNonExist(std::vector<std::string> & preferredLanguageList,int index,const std::string & language)57 bool PreferredLanguage::AddPreferredLanguageNonExist(std::vector<std::string> &preferredLanguageList, int index,
58     const std::string& language)
59 {
60     preferredLanguageList.insert(preferredLanguageList.begin() + index, language);
61     if (!index) {
62         bool status = LocaleConfig::SetSystemLanguage(preferredLanguageList[0]);
63         if (!status) {
64             return false;
65         }
66     }
67     return true;
68 }
69 
AddPreferredLanguage(const std::string & language,int index)70 bool PreferredLanguage::AddPreferredLanguage(const std::string &language, int index)
71 {
72     if (!LocaleConfig::CheckPermission()) {
73         return false;
74     }
75     if (!IsValidTag(language)) {
76         return false;
77     }
78     std::vector<std::string> preferredLanguageList = GetPreferredLanguageList();
79     int idx = index;
80     if (index < 0) {
81         idx = 0;
82     }
83     if (index >= (int)preferredLanguageList.size()) {
84         idx = (int)preferredLanguageList.size();
85     }
86     int languageIdx = -1;
87     for (size_t i = 0; i < preferredLanguageList.size(); i++) {
88         if (preferredLanguageList[i] == language) {
89             languageIdx = (int)i;
90             break;
91         }
92     }
93     bool status = true;
94     if (languageIdx == -1) {
95         status = AddPreferredLanguageNonExist(preferredLanguageList, idx, language);
96     } else {
97         if (idx == (int)preferredLanguageList.size()) {
98             idx -= 1;
99         }
100         status = AddPreferredLanguageExist(preferredLanguageList, languageIdx, idx, language);
101     }
102     if (!status) {
103         return false;
104     }
105     std::string result = "";
106     for (size_t i = 0; i < preferredLanguageList.size(); i++) {
107         result += preferredLanguageList[i];
108         result += ";";
109     }
110     result.pop_back();
111     if (result.length() > CONFIG_LEN) {
112         return false;
113     }
114     status = SetParameter(PREFERRED_LANGUAGES, result.data()) == 0;
115     return status;
116 }
117 
RemovePreferredLanguage(int index)118 bool PreferredLanguage::RemovePreferredLanguage(int index)
119 {
120     if (!LocaleConfig::CheckPermission()) {
121         return false;
122     }
123     std::vector<std::string> preferredLanguageList = GetPreferredLanguageList();
124     int idx = index;
125     if (index < 0) {
126         idx = 0;
127     }
128     if (index >= (int)preferredLanguageList.size()) {
129         idx = (int)preferredLanguageList.size() - 1;
130     }
131     if (preferredLanguageList.size() == 1) {
132         return false;
133     }
134     std::vector<std::string>::iterator it = preferredLanguageList.begin();
135     preferredLanguageList.erase(it + idx);
136     bool status = false;
137     if (!idx) {
138         status = LocaleConfig::SetSystemLanguage(preferredLanguageList[0]);
139         if (!status) {
140             return false;
141         }
142     }
143     std::string result = "";
144     for (it = preferredLanguageList.begin(); it != preferredLanguageList.end(); ++it) {
145         result += *it;
146         result += ";";
147     }
148     result.pop_back();
149     status = SetParameter(PREFERRED_LANGUAGES, result.data()) == 0;
150     return status;
151 }
152 
GetPreferredLanguageList()153 std::vector<std::string> PreferredLanguage::GetPreferredLanguageList()
154 {
155     char preferredLanguageValue[CONFIG_LEN];
156     GetParameter(PREFERRED_LANGUAGES, "", preferredLanguageValue, CONFIG_LEN);
157     std::string systemLanguage = LocaleConfig::GetSystemLanguage();
158     std::vector<std::string> list;
159     Split(preferredLanguageValue, ";", list);
160     if (!list.size()) {
161         if (systemLanguage != "") {
162             list.push_back(systemLanguage);
163         }
164         return list;
165     }
166     if (list[0] == systemLanguage || systemLanguage == "") {
167         return list;
168     }
169     int systemLanguageIdx = -1;
170     for (size_t i = 0; i < list.size(); i++) {
171         if (list[i] == systemLanguage) {
172             systemLanguageIdx = (int)i;
173         }
174     }
175     if (systemLanguageIdx == -1) {
176         list.insert(list.begin(), systemLanguage);
177     } else {
178         for (size_t i = (size_t)systemLanguageIdx; i > 0; i--) {
179             list[i] = list[i - 1];
180         }
181         list[0] = systemLanguage;
182     }
183     return list;
184 }
185 
IsMatched(const std::string & preferred,const std::string & resource)186 bool PreferredLanguage::IsMatched(const std::string& preferred, const std::string& resource)
187 {
188     LocaleInfo preferredLocaleInfo(preferred);
189     LocaleInfo resourceLocaleInfo(resource);
190     if (preferred == resource) {
191         return true;
192     }
193     if (preferredLocaleInfo.GetLanguage() != resourceLocaleInfo.GetLanguage()) {
194         return false;
195     }
196     LocaleInfo maximizedResourceLocale(resourceLocaleInfo.Maximize());
197     std::string resourceScript = maximizedResourceLocale.GetScript();
198     if (resourceScript == "") {
199         std::string resourceCountry = maximizedResourceLocale.GetRegion();
200         if (resourceCountry == "") {
201             return true;
202         }
203         std::string preferredCountry = preferredLocaleInfo.GetRegion();
204         if (resourceCountry == preferredCountry) {
205             return true;
206         }
207         return false;
208     }
209     LocaleInfo maximizedPreferredLocale(preferredLocaleInfo.Maximize());
210     std::string preferredScript = maximizedResourceLocale.GetScript();
211     if (resourceScript == preferredScript) {
212         return true;
213     }
214     return false;
215 }
216 
GetFirstPreferredLanguage()217 std::string PreferredLanguage::GetFirstPreferredLanguage()
218 {
219     std::vector<std::string> preferredLanguageList = GetPreferredLanguageList();
220     return preferredLanguageList[0];
221 }
222 
GetPreferredLocale()223 std::string PreferredLanguage::GetPreferredLocale()
224 {
225     std::string systemLocale = LocaleConfig::GetSystemLocale();
226     LocaleInfo systemLocaleInfo(systemLocale);
227     std::string systemRegion = systemLocaleInfo.GetRegion();
228     std::string preferredLanguageLocale = GetFirstPreferredLanguage();
229     LocaleInfo preferredLanguageLocaleInfo(preferredLanguageLocale);
230     std::string preferredLanguage = preferredLanguageLocaleInfo.GetLanguage();
231     std::string preferredLocale = preferredLanguage + "-" + systemRegion;
232     return preferredLocale;
233 }
234 
IsValidLanguage(const std::string & language)235 bool PreferredLanguage::IsValidLanguage(const std::string &language)
236 {
237     std::string::size_type size = language.size();
238     if ((size != LANGUAGE_LEN) && (size != LANGUAGE_LEN + 1)) {
239         return false;
240     }
241     for (size_t i = 0; i < size; ++i) {
242         if ((language[i] > 'z') || (language[i] < 'a')) {
243             return false;
244         }
245     }
246     return true;
247 }
248 
IsValidTag(const std::string & tag)249 bool PreferredLanguage::IsValidTag(const std::string &tag)
250 {
251     if (!tag.size()) {
252         return false;
253     }
254     std::vector<std::string> splits;
255     Split(tag, "-", splits);
256     if (!IsValidLanguage(splits[0])) {
257         return false;
258     }
259     return true;
260 }
261 
Split(const std::string & src,const std::string & sep,std::vector<std::string> & dest)262 void PreferredLanguage::Split(const std::string &src, const std::string &sep, std::vector<std::string> &dest)
263 {
264     std::string::size_type begin = 0;
265     std::string::size_type end = src.find(sep);
266     while (end != std::string::npos) {
267         dest.push_back(src.substr(begin, end - begin));
268         begin = end + sep.size();
269         end = src.find(sep, begin);
270     }
271     if (begin != src.size()) {
272         dest.push_back(src.substr(begin));
273     }
274 }
275 } // namespace I18n
276 } // namespace Global
277 } // namespace OHOS