1 /*
2 * Copyright (c) 2024 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 "i18n_hilog.h"
17 #include "locale_config.h"
18 #include "os_account_manager.h"
19 #include "parameter.h"
20 #include "utils.h"
21
22 #include "multi_users.h"
23
24 namespace OHOS {
25 namespace Global {
26 namespace I18n {
27 const std::string MultiUsers::MULTI_USERS_LANGUAGE_KEY = "languageData";
28 const std::string MultiUsers::MULTI_USERS_LOCALE_KEY = "localeData";
29 const std::string MultiUsers::MULTI_USERS_HOUR_KEY = "is24HourData";
30 const std::string MultiUsers::INIT_KEY = "init";
31 const std::string MultiUsers::PREFERENCE_PATH = "/data/service/el1/public/i18n/global/GlobalParamData";
32 const int32_t MultiUsers::DEFAULT_LOCAL_ID = 100;
33 const int MultiUsers::CONFIG_LEN = 128;
34 std::shared_ptr<NativePreferences::Preferences> MultiUsers::preferences = nullptr;
35
InitMultiUser()36 void MultiUsers::InitMultiUser()
37 {
38 InitPreferences();
39 if (preferences == nullptr) {
40 HILOG_ERROR_I18N("InitMultiUser: InitPreferences failed");
41 return;
42 }
43 bool init = preferences->GetBool(INIT_KEY, false);
44 std::string localId;
45 I18nErrorCode errCode = GetForegroundLocalId(localId);
46 if (errCode != I18nErrorCode::SUCCESS) {
47 HILOG_ERROR_I18N("InitMultiUser: get foreground local id failed");
48 return;
49 }
50 if (!init) {
51 AddUser(localId);
52 preferences->PutBool(INIT_KEY, true);
53 preferences->Flush();
54 HILOG_INFO_I18N("InitMultiUser: init multi user data success");
55 }
56 }
57
SwitchUser(const std::string& curLocalId)58 void MultiUsers::SwitchUser(const std::string& curLocalId)
59 {
60 if (!IsValidLocalId(curLocalId)) {
61 HILOG_ERROR_I18N("SwitchUser: curLocalId is an invalid LocalId");
62 return;
63 }
64 I18nErrorCode errCode = LoadGlobalParam(curLocalId);
65 if (errCode != I18nErrorCode::SUCCESS) {
66 HILOG_ERROR_I18N("SwitchUser: load global params failed");
67 }
68 }
69
AddUser(const std::string& localId)70 void MultiUsers::AddUser(const std::string& localId)
71 {
72 if (!IsValidLocalId(localId)) {
73 HILOG_ERROR_I18N("AddUser: localId is invalid");
74 return;
75 }
76 I18nErrorCode errCode = SaveGlobalParam(localId);
77 if (errCode != I18nErrorCode::SUCCESS) {
78 HILOG_ERROR_I18N("AddUser: add global param failed");
79 }
80 }
81
RemoveUser(const std::string& localId)82 void MultiUsers::RemoveUser(const std::string& localId)
83 {
84 if (!IsValidLocalId(localId)) {
85 HILOG_ERROR_I18N("RemoveUser: localId is invalid");
86 return;
87 }
88 I18nErrorCode errCode = RemoveGlobalParam(localId);
89 if (errCode != I18nErrorCode::SUCCESS) {
90 HILOG_ERROR_I18N("RemoveUser: remove global param failed");
91 }
92 }
93
GetForegroundLocalId(std::string& localId)94 I18nErrorCode MultiUsers::GetForegroundLocalId(std::string& localId)
95 {
96 int id = 0;
97 int errCode = OHOS::AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(id);
98 if (errCode != 0) {
99 HILOG_ERROR_I18N("GetForegroundLocalId: get foreground locale Id failed, errCode is %{public}d", errCode);
100 return I18nErrorCode::FAILED;
101 }
102 localId = std::to_string(id);
103 return I18nErrorCode::SUCCESS;
104 }
105
SaveLanguage(const std::string& localId, const std::string& language)106 I18nErrorCode MultiUsers::SaveLanguage(const std::string& localId, const std::string& language)
107 {
108 std::string foregroundLocalId = localId;
109 I18nErrorCode errCode = I18nErrorCode::SUCCESS;
110 if (localId.empty()) {
111 errCode = MultiUsers::GetForegroundLocalId(foregroundLocalId);
112 }
113 if (errCode != I18nErrorCode::SUCCESS) {
114 HILOG_ERROR_I18N("SaveLanguage: get foreground locale Id failed");
115 return I18nErrorCode::FAILED;
116 }
117
118 errCode =
119 WriteMultiUsersParameter(MULTI_USERS_LANGUAGE_KEY, language, foregroundLocalId, false);
120 if (errCode != I18nErrorCode::SUCCESS) {
121 HILOG_ERROR_I18N("SaveLanguage: save language failed");
122 return I18nErrorCode::FAILED;
123 }
124 return I18nErrorCode::SUCCESS;
125 }
126
SaveLocale(const std::string& localId, const std::string& locale)127 I18nErrorCode MultiUsers::SaveLocale(const std::string& localId, const std::string& locale)
128 {
129 std::string foregroundLocalId = localId;
130 I18nErrorCode errCode = I18nErrorCode::SUCCESS;
131 if (localId.empty()) {
132 errCode = MultiUsers::GetForegroundLocalId(foregroundLocalId);
133 }
134 if (errCode != I18nErrorCode::SUCCESS) {
135 HILOG_ERROR_I18N("SaveLocale: get foreground locale Id failed");
136 return I18nErrorCode::FAILED;
137 }
138
139 errCode =
140 WriteMultiUsersParameter(MULTI_USERS_LOCALE_KEY, locale, foregroundLocalId, false);
141 if (errCode != I18nErrorCode::SUCCESS) {
142 HILOG_ERROR_I18N("SaveLocale: save locale failed");
143 return I18nErrorCode::FAILED;
144 }
145 return I18nErrorCode::SUCCESS;
146 }
147
SaveIs24Hour(const std::string& localId, const std::string& is24Hour)148 I18nErrorCode MultiUsers::SaveIs24Hour(const std::string& localId, const std::string& is24Hour)
149 {
150 std::string foregroundLocalId = localId;
151 I18nErrorCode errCode = I18nErrorCode::SUCCESS;
152 if (localId.empty()) {
153 errCode = MultiUsers::GetForegroundLocalId(foregroundLocalId);
154 }
155 if (errCode != I18nErrorCode::SUCCESS) {
156 HILOG_ERROR_I18N("SaveLanguage: get foreground locale Id failed");
157 return I18nErrorCode::FAILED;
158 }
159 errCode =
160 WriteMultiUsersParameter(MULTI_USERS_HOUR_KEY, is24Hour, foregroundLocalId, false);
161 if (errCode != I18nErrorCode::SUCCESS) {
162 HILOG_ERROR_I18N("SaveIs24Hour: save is24Hour failed");
163 return I18nErrorCode::FAILED;
164 }
165 return I18nErrorCode::SUCCESS;
166 }
167
SaveGlobalParam(const std::string& localId)168 I18nErrorCode MultiUsers::SaveGlobalParam(const std::string& localId)
169 {
170 std::string language = ReadSystemParameter(LocaleConfig::GetLanguageKey().data(), CONFIG_LEN);
171 std::string locale = ReadSystemParameter(LocaleConfig::GetLocaleKey().data(), CONFIG_LEN);
172 std::string is24Hour = ReadSystemParameter(LocaleConfig::GetHourKey().data(), CONFIG_LEN);
173 I18nErrorCode errCode = SaveLanguage(localId, language);
174 if (errCode != I18nErrorCode::SUCCESS) {
175 HILOG_ERROR_I18N("SaveGlobalParam: save language failed");
176 return I18nErrorCode::FAILED;
177 }
178 errCode = SaveLocale(localId, locale);
179 if (errCode != I18nErrorCode::SUCCESS) {
180 HILOG_ERROR_I18N("SaveGlobalParam: save locale failed");
181 return I18nErrorCode::FAILED;
182 }
183 errCode = SaveIs24Hour(localId, is24Hour);
184 if (errCode != I18nErrorCode::SUCCESS) {
185 HILOG_ERROR_I18N("SaveGlobalParam: save is24Hour failed");
186 return I18nErrorCode::FAILED;
187 }
188 return I18nErrorCode::SUCCESS;
189 }
190
LoadGlobalParam(const std::string& localId)191 I18nErrorCode MultiUsers::LoadGlobalParam(const std::string& localId)
192 {
193 std::string newLocale = ReadMultiUsersParameter(MULTI_USERS_LOCALE_KEY, localId);
194 if (!newLocale.empty() && SetParameter(LocaleConfig::GetLocaleKey().data(), newLocale.data()) != 0) {
195 HILOG_ERROR_I18N("LoadGlobalParam: set locale failed");
196 return I18nErrorCode::FAILED;
197 }
198
199 std::string newLanguage = ReadMultiUsersParameter(MULTI_USERS_LANGUAGE_KEY, localId);
200 if (!newLanguage.empty() && LocaleConfig::SetSystemLanguage(newLanguage) != 0) {
201 HILOG_ERROR_I18N("LoadGlobalParam: set language failed");
202 return I18nErrorCode::FAILED;
203 }
204
205 std::string newIs24Hour = ReadMultiUsersParameter(MULTI_USERS_HOUR_KEY, localId);
206 if (!newIs24Hour.empty() && LocaleConfig::Set24HourClock(newIs24Hour) != 0) {
207 HILOG_ERROR_I18N("LoadGlobalParam: set is24Hour failed");
208 return I18nErrorCode::FAILED;
209 }
210 return I18nErrorCode::SUCCESS;
211 }
212
RemoveGlobalParam(const std::string& localId)213 I18nErrorCode MultiUsers::RemoveGlobalParam(const std::string& localId)
214 {
215 I18nErrorCode errCode = WriteMultiUsersParameter(MULTI_USERS_LANGUAGE_KEY, "", localId, true);
216 if (errCode != I18nErrorCode::SUCCESS) {
217 HILOG_ERROR_I18N("RemoveGlobalParam: remove language failed");
218 return I18nErrorCode::FAILED;
219 }
220
221 errCode = WriteMultiUsersParameter(MULTI_USERS_LOCALE_KEY, "", localId, true);
222 if (errCode != I18nErrorCode::SUCCESS) {
223 HILOG_ERROR_I18N("RemoveGlobalParam: remove locale failed");
224 return I18nErrorCode::FAILED;
225 }
226
227 errCode = WriteMultiUsersParameter(MULTI_USERS_HOUR_KEY, "", localId, true);
228 if (errCode != I18nErrorCode::SUCCESS) {
229 HILOG_ERROR_I18N("RemoveGlobalParam: remove is24Hour failed");
230 return I18nErrorCode::FAILED;
231 }
232 return I18nErrorCode::SUCCESS;
233 }
234
ReadMultiUsersParameter(const std::string& paramKey, const std::string& localId)235 std::string MultiUsers::ReadMultiUsersParameter(const std::string& paramKey, const std::string& localId)
236 {
237 std::string param = GetParamFromPreferences(paramKey);
238 if (param.empty()) {
239 return "";
240 }
241 std::vector<std::string> multiUsersParam;
242 Split(param, ";", multiUsersParam);
243 for (auto& userParam : multiUsersParam) {
244 std::vector<std::string> content;
245 Split(userParam, ":", content);
246 // 2 is number of param
247 if (content.size() != 2) {
248 continue;
249 }
250 if (content[0] == localId) {
251 return content[1];
252 }
253 }
254 return "";
255 }
256
WriteMultiUsersParameter(const std::string& paramKey, const std::string& paramValue, const std::string& localId, bool isDel)257 I18nErrorCode MultiUsers::WriteMultiUsersParameter(const std::string& paramKey, const std::string& paramValue,
258 const std::string& localId, bool isDel)
259 {
260 std::string param = GetParamFromPreferences(paramKey);
261 std::vector<std::string> multiUsersParam;
262 Split(param, ";", multiUsersParam);
263 std::vector<std::string> newMultiUsersParam;
264 bool userIsExist = false;
265 for (auto& userParam : multiUsersParam) {
266 std::vector<std::string> content;
267 Split(userParam, ":", content);
268 // 2 is number of param
269 if (content.size() != 2) {
270 continue;
271 }
272 std::string userLocalId = content[0];
273 if (!isDel && userLocalId == localId) {
274 content[1] = paramValue;
275 Merge(content, ":", userParam);
276 userIsExist = true;
277 }
278 newMultiUsersParam.emplace_back(userParam);
279 if (isDel && userLocalId == localId) {
280 newMultiUsersParam.pop_back();
281 }
282 }
283 if (!isDel && !userIsExist) {
284 newMultiUsersParam.push_back(localId + ":" + paramValue);
285 }
286 std::string newParam;
287 Merge(newMultiUsersParam, ";", newParam);
288 if (SetParamFromPreferences(paramKey, newParam) != I18nErrorCode::SUCCESS) {
289 HILOG_ERROR_I18N("WriteMultiUsersParameter: set param %{public}s failed", paramKey.c_str());
290 return I18nErrorCode::FAILED;
291 }
292 return I18nErrorCode::SUCCESS;
293 }
294
IsValidLocalId(const std::string& localId)295 bool MultiUsers::IsValidLocalId(const std::string& localId)
296 {
297 if (std::atoi(localId.c_str()) < DEFAULT_LOCAL_ID) {
298 HILOG_ERROR_I18N("IsValidLocalId: invalid local ID");
299 return false;
300 }
301 return true;
302 }
303
InitPreferences()304 void MultiUsers::InitPreferences()
305 {
306 if (preferences == nullptr) {
307 HILOG_INFO_I18N("InitPreferences: preferences Init");
308 OHOS::NativePreferences::Options opt(PREFERENCE_PATH);
309 int status;
310 preferences = NativePreferences::PreferencesHelper::GetPreferences(opt, status);
311 if (status != 0) {
312 HILOG_ERROR_I18N("InitPreferences: get preferences failed");
313 preferences = nullptr;
314 }
315 }
316 }
317
GetParamFromPreferences(const std::string& paramKey)318 std::string MultiUsers::GetParamFromPreferences(const std::string& paramKey)
319 {
320 InitPreferences();
321 if (preferences == nullptr) {
322 HILOG_ERROR_I18N("GetParamFromPreferences: preferences is nullptr");
323 return "";
324 }
325 return preferences->GetString(paramKey, "");
326 }
327
SetParamFromPreferences(const std::string& paramKey, const std::string& paramValue)328 I18nErrorCode MultiUsers::SetParamFromPreferences(const std::string& paramKey, const std::string& paramValue)
329 {
330 InitPreferences();
331 if (preferences == nullptr) {
332 HILOG_ERROR_I18N("SetParamFromPreferences: preferences is nullptr");
333 return I18nErrorCode::FAILED;
334 }
335 int status = preferences->PutString(paramKey, paramValue);
336 if (status != 0) {
337 HILOG_ERROR_I18N("SetParamFromPreferences: put param %{public}s failed", paramKey.c_str());
338 return I18nErrorCode::FAILED;
339 }
340 preferences->Flush();
341 return I18nErrorCode::SUCCESS;
342 }
343 } // namespace I18n
344 } // namespace Global
345 } // namespace OHOS
346