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 24namespace OHOS { 25namespace Global { 26namespace I18n { 27const std::string MultiUsers::MULTI_USERS_LANGUAGE_KEY = "languageData"; 28const std::string MultiUsers::MULTI_USERS_LOCALE_KEY = "localeData"; 29const std::string MultiUsers::MULTI_USERS_HOUR_KEY = "is24HourData"; 30const std::string MultiUsers::INIT_KEY = "init"; 31const std::string MultiUsers::PREFERENCE_PATH = "/data/service/el1/public/i18n/global/GlobalParamData"; 32const int32_t MultiUsers::DEFAULT_LOCAL_ID = 100; 33const int MultiUsers::CONFIG_LEN = 128; 34std::shared_ptr<NativePreferences::Preferences> MultiUsers::preferences = nullptr; 35 36void 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 58void 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 70void 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 82void 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 94I18nErrorCode 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 106I18nErrorCode 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 127I18nErrorCode 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 148I18nErrorCode 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 168I18nErrorCode 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 191I18nErrorCode 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 213I18nErrorCode 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 235std::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 257I18nErrorCode 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 295bool 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 304void 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 318std::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 328I18nErrorCode 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