• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef SUPPORT_GRAPHICS
17 #include "app_mgr_client.h"
18 #include "ability_manager_client.h"
19 #include <common_event_manager.h>
20 #include <common_event_publish_info.h>
21 #include <common_event_support.h>
22 #endif
23 #include "i18n_hilog.h"
24 #include "locale_config.h"
25 #include "os_account_manager.h"
26 #include "parameter.h"
27 #include "utils.h"
28 
29 #include "multi_users.h"
30 
31 namespace OHOS {
32 namespace Global {
33 namespace I18n {
34 const std::string MultiUsers::MULTI_USERS_LANGUAGE_KEY = "languageData";
35 const std::string MultiUsers::MULTI_USERS_LOCALE_KEY = "localeData";
36 const std::string MultiUsers::MULTI_USERS_HOUR_KEY = "is24HourData";
37 const std::string MultiUsers::INIT_KEY = "init";
38 const std::string MultiUsers::PREFERENCE_PATH = "/data/service/el1/public/i18n/global/GlobalParamData";
39 const int32_t MultiUsers::DEFAULT_LOCAL_ID = 100;
40 const int MultiUsers::CONFIG_LEN = 128;
41 std::shared_ptr<NativePreferences::Preferences> MultiUsers::preferences = nullptr;
42 
InitMultiUser()43 void MultiUsers::InitMultiUser()
44 {
45     InitPreferences();
46     if (preferences == nullptr) {
47         HILOG_ERROR_I18N("InitMultiUser: InitPreferences failed");
48         return;
49     }
50     bool init = preferences->GetBool(INIT_KEY, false);
51     std::string localId;
52     I18nErrorCode errCode = GetForegroundLocalId(localId);
53     if (errCode != I18nErrorCode::SUCCESS) {
54         HILOG_ERROR_I18N("InitMultiUser: get foreground local id failed");
55         return;
56     }
57     if (!init) {
58         AddUser(localId);
59         preferences->PutBool(INIT_KEY, true);
60         preferences->Flush();
61         HILOG_INFO_I18N("InitMultiUser: init multi user data success");
62     }
63 }
64 
SwitchUser(const std::string & curLocalId)65 void MultiUsers::SwitchUser(const std::string& curLocalId)
66 {
67     if (!IsValidLocalId(curLocalId)) {
68         HILOG_ERROR_I18N("SwitchUser: curLocalId is an invalid LocalId");
69         return;
70     }
71     I18nErrorCode errCode = LoadGlobalParam(curLocalId);
72     if (errCode != I18nErrorCode::SUCCESS) {
73         HILOG_ERROR_I18N("SwitchUser: load global params failed");
74     }
75 }
76 
AddUser(const std::string & localId)77 void MultiUsers::AddUser(const std::string& localId)
78 {
79     if (!IsValidLocalId(localId)) {
80         HILOG_ERROR_I18N("AddUser: localId is invalid");
81         return;
82     }
83     I18nErrorCode errCode = SaveGlobalParam(localId);
84     if (errCode != I18nErrorCode::SUCCESS) {
85         HILOG_ERROR_I18N("AddUser: add global param failed");
86     }
87 }
88 
RemoveUser(const std::string & localId)89 void MultiUsers::RemoveUser(const std::string& localId)
90 {
91     if (!IsValidLocalId(localId)) {
92         HILOG_ERROR_I18N("RemoveUser: localId is invalid");
93         return;
94     }
95     I18nErrorCode errCode = RemoveGlobalParam(localId);
96     if (errCode != I18nErrorCode::SUCCESS) {
97         HILOG_ERROR_I18N("RemoveUser: remove global param failed");
98     }
99 }
100 
GetForegroundLocalId(std::string & localId)101 I18nErrorCode MultiUsers::GetForegroundLocalId(std::string& localId)
102 {
103     int id = 0;
104     int errCode = OHOS::AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(id);
105     if (errCode != 0) {
106         HILOG_ERROR_I18N("GetForegroundLocalId: get foreground locale Id failed, errCode is %{public}d", errCode);
107         return I18nErrorCode::FAILED;
108     }
109     localId = std::to_string(id);
110     return I18nErrorCode::SUCCESS;
111 }
112 
SaveLanguage(const std::string & localId,const std::string & language)113 I18nErrorCode MultiUsers::SaveLanguage(const std::string& localId, const std::string& language)
114 {
115     std::string foregroundLocalId = localId;
116     I18nErrorCode errCode = I18nErrorCode::SUCCESS;
117     if (localId.empty()) {
118         errCode = MultiUsers::GetForegroundLocalId(foregroundLocalId);
119     }
120     if (errCode != I18nErrorCode::SUCCESS) {
121         HILOG_ERROR_I18N("SaveLanguage: get foreground locale Id failed");
122         return I18nErrorCode::FAILED;
123     }
124 
125     errCode =
126         WriteMultiUsersParameter(MULTI_USERS_LANGUAGE_KEY, language, foregroundLocalId, false);
127     if (errCode != I18nErrorCode::SUCCESS) {
128         HILOG_ERROR_I18N("SaveLanguage: save language failed");
129         return I18nErrorCode::FAILED;
130     }
131     return I18nErrorCode::SUCCESS;
132 }
133 
SaveLocale(const std::string & localId,const std::string & locale)134 I18nErrorCode MultiUsers::SaveLocale(const std::string& localId, const std::string& locale)
135 {
136     std::string foregroundLocalId = localId;
137     I18nErrorCode errCode = I18nErrorCode::SUCCESS;
138     if (localId.empty()) {
139         errCode = MultiUsers::GetForegroundLocalId(foregroundLocalId);
140     }
141     if (errCode != I18nErrorCode::SUCCESS) {
142         HILOG_ERROR_I18N("SaveLocale: get foreground locale Id failed");
143         return I18nErrorCode::FAILED;
144     }
145 
146     errCode =
147         WriteMultiUsersParameter(MULTI_USERS_LOCALE_KEY, locale, foregroundLocalId, false);
148     if (errCode != I18nErrorCode::SUCCESS) {
149         HILOG_ERROR_I18N("SaveLocale: save locale failed");
150         return I18nErrorCode::FAILED;
151     }
152     return I18nErrorCode::SUCCESS;
153 }
154 
SaveIs24Hour(const std::string & localId,const std::string & is24Hour)155 I18nErrorCode MultiUsers::SaveIs24Hour(const std::string& localId, const std::string& is24Hour)
156 {
157     std::string foregroundLocalId = localId;
158     I18nErrorCode errCode = I18nErrorCode::SUCCESS;
159     if (localId.empty()) {
160         errCode = MultiUsers::GetForegroundLocalId(foregroundLocalId);
161     }
162     if (errCode != I18nErrorCode::SUCCESS) {
163         HILOG_ERROR_I18N("SaveLanguage: get foreground locale Id failed");
164         return I18nErrorCode::FAILED;
165     }
166     errCode =
167         WriteMultiUsersParameter(MULTI_USERS_HOUR_KEY, is24Hour, foregroundLocalId, false);
168     if (errCode != I18nErrorCode::SUCCESS) {
169         HILOG_ERROR_I18N("SaveIs24Hour: save is24Hour failed");
170         return I18nErrorCode::FAILED;
171     }
172     return I18nErrorCode::SUCCESS;
173 }
174 
SaveGlobalParam(const std::string & localId)175 I18nErrorCode MultiUsers::SaveGlobalParam(const std::string& localId)
176 {
177     std::string language = LocaleConfig::GetSystemLanguage();
178     std::string locale = LocaleConfig::GetSystemLocale();
179     std::string is24Hour = ReadSystemParameter(LocaleConfig::HOUR_KEY.c_str(), CONFIG_LEN);
180     if (is24Hour.empty()) {
181         HILOG_ERROR_I18N("SaveIs24Hour: Get is24Hour failed");
182         return I18nErrorCode::FAILED;
183     }
184     I18nErrorCode errCode = SaveLanguage(localId, language);
185     if (errCode != I18nErrorCode::SUCCESS) {
186         HILOG_ERROR_I18N("SaveGlobalParam: save language failed");
187         return I18nErrorCode::FAILED;
188     }
189     errCode = SaveLocale(localId, locale);
190     if (errCode != I18nErrorCode::SUCCESS) {
191         HILOG_ERROR_I18N("SaveGlobalParam: save locale failed");
192         return I18nErrorCode::FAILED;
193     }
194     errCode = SaveIs24Hour(localId, is24Hour);
195     if (errCode != I18nErrorCode::SUCCESS) {
196         HILOG_ERROR_I18N("SaveGlobalParam: save is24Hour failed");
197         return I18nErrorCode::FAILED;
198     }
199     return I18nErrorCode::SUCCESS;
200 }
201 
LoadGlobalParam(const std::string & localId)202 I18nErrorCode MultiUsers::LoadGlobalParam(const std::string& localId)
203 {
204     std::string newLocale = ReadMultiUsersParameter(MULTI_USERS_LOCALE_KEY, localId);
205     if (!newLocale.empty() && SetParameter(LocaleConfig::LOCALE_KEY.c_str(), newLocale.c_str()) != 0) {
206         HILOG_ERROR_I18N("LoadGlobalParam: set locale failed");
207         return I18nErrorCode::FAILED;
208     }
209 
210     std::string newLanguage = ReadMultiUsersParameter(MULTI_USERS_LANGUAGE_KEY, localId);
211     if (!newLanguage.empty() && SetParameter(LocaleConfig::LANGUAGE_KEY.c_str(), newLanguage.c_str()) != 0) {
212         HILOG_ERROR_I18N("LoadGlobalParam: set language failed");
213         return I18nErrorCode::FAILED;
214     }
215 
216     std::string newIs24Hour = ReadMultiUsersParameter(MULTI_USERS_HOUR_KEY, localId);
217     if (!newIs24Hour.empty() && SetParameter(LocaleConfig::HOUR_KEY.c_str(), newIs24Hour.c_str()) != 0) {
218         HILOG_ERROR_I18N("LoadGlobalParam: set is24Hour failed");
219         return I18nErrorCode::FAILED;
220     }
221 #ifdef SUPPORT_GRAPHICS
222     int32_t status = 0;
223     int32_t userId = ConvertString2Int(localId, status);
224     if (status == -1) {
225         HILOG_ERROR_I18N("LoadGlobalParam: convert userId failed");
226         return I18nErrorCode::FAILED;
227     }
228     UpdateConfiguration(newLocale, newIs24Hour, userId);
229     return PublishCommonEvent(userId);
230 #endif
231     return I18nErrorCode::SUCCESS;
232 }
233 
RemoveGlobalParam(const std::string & localId)234 I18nErrorCode MultiUsers::RemoveGlobalParam(const std::string& localId)
235 {
236     I18nErrorCode errCode = WriteMultiUsersParameter(MULTI_USERS_LANGUAGE_KEY, "", localId, true);
237     if (errCode != I18nErrorCode::SUCCESS) {
238         HILOG_ERROR_I18N("RemoveGlobalParam: remove language failed");
239         return I18nErrorCode::FAILED;
240     }
241 
242     errCode = WriteMultiUsersParameter(MULTI_USERS_LOCALE_KEY, "", localId, true);
243     if (errCode != I18nErrorCode::SUCCESS) {
244         HILOG_ERROR_I18N("RemoveGlobalParam: remove locale failed");
245         return I18nErrorCode::FAILED;
246     }
247 
248     errCode = WriteMultiUsersParameter(MULTI_USERS_HOUR_KEY, "", localId, true);
249     if (errCode != I18nErrorCode::SUCCESS) {
250         HILOG_ERROR_I18N("RemoveGlobalParam: remove is24Hour failed");
251         return I18nErrorCode::FAILED;
252     }
253 
254     return I18nErrorCode::SUCCESS;
255 }
256 
ReadMultiUsersParameter(const std::string & paramKey,const std::string & localId)257 std::string MultiUsers::ReadMultiUsersParameter(const std::string& paramKey, const std::string& localId)
258 {
259     std::string param = GetParamFromPreferences(paramKey);
260     if (param.empty()) {
261         return "";
262     }
263     std::vector<std::string> multiUsersParam;
264     Split(param, ";", multiUsersParam);
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         if (content[0] == localId) {
273             return content[1];
274         }
275     }
276     return "";
277 }
278 
WriteMultiUsersParameter(const std::string & paramKey,const std::string & paramValue,const std::string & localId,bool isDel)279 I18nErrorCode MultiUsers::WriteMultiUsersParameter(const std::string& paramKey, const std::string& paramValue,
280     const std::string& localId, bool isDel)
281 {
282     std::string param = GetParamFromPreferences(paramKey);
283     std::vector<std::string> multiUsersParam;
284     Split(param, ";", multiUsersParam);
285     std::vector<std::string> newMultiUsersParam;
286     bool userIsExist = false;
287     for (auto& userParam : multiUsersParam) {
288         std::vector<std::string> content;
289         Split(userParam, ":", content);
290         // 2 is number of param
291         if (content.size() != 2) {
292             continue;
293         }
294         std::string userLocalId = content[0];
295         if (!isDel && userLocalId == localId) {
296             content[1] = paramValue;
297             Merge(content, ":", userParam);
298             userIsExist = true;
299         }
300         newMultiUsersParam.emplace_back(userParam);
301         if (isDel && userLocalId == localId) {
302             newMultiUsersParam.pop_back();
303         }
304     }
305     if (!isDel && !userIsExist) {
306         newMultiUsersParam.push_back(localId + ":" + paramValue);
307     }
308     std::string newParam;
309     Merge(newMultiUsersParam, ";", newParam);
310     if (SetParamFromPreferences(paramKey, newParam) != I18nErrorCode::SUCCESS) {
311         HILOG_ERROR_I18N("WriteMultiUsersParameter: set param %{public}s failed", paramKey.c_str());
312         return I18nErrorCode::FAILED;
313     }
314     return I18nErrorCode::SUCCESS;
315 }
316 
IsValidLocalId(const std::string & localId)317 bool MultiUsers::IsValidLocalId(const std::string& localId)
318 {
319     if (std::atoi(localId.c_str()) < DEFAULT_LOCAL_ID) {
320         HILOG_ERROR_I18N("IsValidLocalId: invalid local ID");
321         return false;
322     }
323     return true;
324 }
325 
InitPreferences()326 void MultiUsers::InitPreferences()
327 {
328     if (preferences == nullptr) {
329         HILOG_INFO_I18N("InitPreferences: preferences Init");
330         OHOS::NativePreferences::Options opt(PREFERENCE_PATH);
331         int status = 0;
332         preferences = NativePreferences::PreferencesHelper::GetPreferences(opt, status);
333         if (status != 0) {
334             HILOG_ERROR_I18N("InitPreferences: get preferences failed");
335             preferences = nullptr;
336         }
337     }
338 }
339 
GetParamFromPreferences(const std::string & paramKey)340 std::string MultiUsers::GetParamFromPreferences(const std::string& paramKey)
341 {
342     InitPreferences();
343     if (preferences == nullptr) {
344         HILOG_ERROR_I18N("GetParamFromPreferences: preferences is nullptr");
345         return "";
346     }
347     return preferences->GetString(paramKey, "");
348 }
349 
SetParamFromPreferences(const std::string & paramKey,const std::string & paramValue)350 I18nErrorCode MultiUsers::SetParamFromPreferences(const std::string& paramKey, const std::string& paramValue)
351 {
352     InitPreferences();
353     if (preferences == nullptr) {
354         HILOG_ERROR_I18N("SetParamFromPreferences: preferences is nullptr");
355         return I18nErrorCode::FAILED;
356     }
357     int status = preferences->PutString(paramKey, paramValue);
358     if (status != 0) {
359         HILOG_ERROR_I18N("SetParamFromPreferences: put param %{public}s failed", paramKey.c_str());
360         return I18nErrorCode::FAILED;
361     }
362     preferences->Flush();
363     return I18nErrorCode::SUCCESS;
364 }
365 
366 #ifdef SUPPORT_GRAPHICS
UpdateConfiguration(const std::string & locale,const std::string & is24Hour,int32_t userId)367 void MultiUsers::UpdateConfiguration(const std::string& locale, const std::string& is24Hour,
368     int32_t userId)
369 {
370     AppExecFwk::Configuration configuration;
371     configuration.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_LANGUAGE, locale);
372     configuration.AddItem(AAFwk::GlobalConfigurationKey::SYSTEM_HOUR, is24Hour);
373     auto appMgrClient = std::make_unique<AppExecFwk::AppMgrClient>();
374 
375     AppExecFwk::AppMgrResultCode status = appMgrClient->UpdateConfiguration(configuration, userId);
376     if (status != AppExecFwk::AppMgrResultCode::RESULT_OK) {
377         HILOG_ERROR_I18N("MultiUsers::UpdateConfiguration: Update configuration userId %{public}d failed.", userId);
378         return;
379     }
380     HILOG_INFO_I18N("MultiUsers::UpdateConfiguration: Update configuration userId %{public}d success.", userId);
381 }
382 
PublishCommonEvent(int32_t userId)383 I18nErrorCode MultiUsers::PublishCommonEvent(int32_t userId)
384 {
385     OHOS::AAFwk::Want localeChangeWant;
386     localeChangeWant.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_LOCALE_CHANGED);
387     OHOS::EventFwk::CommonEventData localeChangeEvent(localeChangeWant);
388     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEventAsUser(localeChangeEvent, userId)) {
389         HILOG_ERROR_I18N("MultiUsers::PublishCommonEvent: Failed to publish locale change event, userId %{public}d.",
390             userId);
391         return I18nErrorCode::PUBLISH_COMMON_EVENT_FAILED;
392     }
393 
394     OHOS::AAFwk::Want is24HourChangeWant;
395     is24HourChangeWant.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_LOCALE_CHANGED);
396     OHOS::EventFwk::CommonEventData is24HourChangeEvent(is24HourChangeWant);
397     is24HourChangeEvent.SetData(LocaleConfig::HOUR_EVENT_DATA);
398     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEventAsUser(is24HourChangeEvent, userId)) {
399         HILOG_ERROR_I18N("MultiUsers::PublishCommonEvent: Failed to publish is24Hour change event, userId %{public}d.",
400             userId);
401         return I18nErrorCode::PUBLISH_COMMON_EVENT_FAILED;
402     }
403 
404     HILOG_INFO_I18N("MultiUsers::PublishCommonEvent: Publish event finished,  userId %{public}d.", userId);
405     return I18nErrorCode::SUCCESS;
406 }
407 #endif
408 } // namespace I18n
409 } // namespace Global
410 } // namespace OHOS
411