1 /*
2 * Copyright (c) 2024-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 #include "multi_user_manager.h"
16
17 #include "adapter/mmi_adapter.h"
18 #include "datashare_manager.h"
19 #include "dsched_continue_manager.h"
20 #include "distributed_sched_service.h"
21 #include "distributed_sched_utils.h"
22 #include "dtbschedmgr_log.h"
23 #include "mission/distributed_sched_mission_manager.h"
24 #include "mission/dms_continue_condition_manager.h"
25 #include "softbus_adapter/softbus_adapter.h"
26 #include "os_account_manager.h"
27
28 namespace OHOS {
29 namespace DistributedSchedule {
30 namespace {
31 constexpr static int32_t INVALID_ID = 0;
32 const std::string TAG = "MultiUserManager";
33 }
34
GetInstance()35 MultiUserManager& MultiUserManager::GetInstance()
36 {
37 static MultiUserManager instance;
38 return instance;
39 }
40
MultiUserManager()41 MultiUserManager::MultiUserManager()
42 {
43 HILOGI("Start.");
44 currentUserId_ = GetForegroundUser();
45 }
46
Init()47 void MultiUserManager::Init()
48 {
49 HILOGI("Init start.");
50 MMIAdapter::GetInstance().Init();
51 SoftbusAdapter::GetInstance().Init();
52 auto sendMgr = GetCurrentSendMgr();
53 CHECK_POINTER_RETURN(sendMgr, "sendMgr");
54 sendMgr->OnDeviceOnline();
55
56 auto recvMgr = GetCurrentRecvMgr();
57 CHECK_POINTER_RETURN(recvMgr, "recvMgr");
58 if (!CheckRegSoftbusListener()) {
59 RegisterSoftbusListener();
60 }
61
62 auto recomMgr = GetCurrentRecomMgr();
63 CHECK_POINTER_RETURN(recomMgr, "recomMgr");
64 HILOGI("Init end.");
65 }
66
UnInit()67 void MultiUserManager::UnInit()
68 {
69 HILOGI("UnInit start");
70 MMIAdapter::GetInstance().UnInit();
71 SoftbusAdapter::GetInstance().UnInit();
72
73 {
74 std::lock_guard<std::mutex> lock(sendMutex_);
75 if (!sendMgrMap_.empty()) {
76 auto it = sendMgrMap_.begin();
77 while (it != sendMgrMap_.end()) {
78 if (it->second == nullptr) {
79 sendMgrMap_.erase(it++);
80 continue;
81 }
82 sendMgrMap_.erase(it++);
83 }
84 }
85 }
86 {
87 std::lock_guard<std::mutex> lock(recvMutex_);
88 if (!recvMgrMap_.empty()) {
89 auto it = recvMgrMap_.begin();
90 while (it != recvMgrMap_.end()) {
91 if (it->second == nullptr) {
92 recvMgrMap_.erase(it++);
93 continue;
94 }
95 recvMgrMap_.erase(it++);
96 }
97 }
98 }
99 {
100 std::lock_guard<std::mutex> lock(recomMutex_);
101 if (!recomMgrMap_.empty()) {
102 auto it = recomMgrMap_.begin();
103 while (it != recomMgrMap_.end()) {
104 if (it->second == nullptr) {
105 recomMgrMap_.erase(it++);
106 continue;
107 }
108 recomMgrMap_.erase(it++);
109 }
110 }
111 }
112 HILOGI("UnInit end");
113 }
114
OnUserSwitched(int32_t accountId)115 void MultiUserManager::OnUserSwitched(int32_t accountId)
116 {
117 HILOGI("UserSwitched start");
118 SoftbusAdapter::GetInstance().ReRegister();
119 auto oldRecvMgr = GetCurrentRecvMgr();
120 if (oldRecvMgr == nullptr) {
121 HILOGI("GetRecvMgr failed.");
122 return;
123 }
124 oldRecvMgr->OnUserSwitch();
125 auto oldSendMgr = GetCurrentSendMgr();
126 if (oldSendMgr == nullptr) {
127 HILOGI("GetSendMgr failed.");
128 return;
129 }
130 oldSendMgr->OnUserSwitched();
131 currentUserId_ = accountId;
132
133 DataShareManager::GetInstance().SetCurrentContinueSwitch(SwitchStatusDependency::GetInstance()
134 .IsContinueSwitchOn());
135 DistributedSchedService::GetInstance()
136 .RegisterDataShareObserver(SwitchStatusDependency::GetInstance().CONTINUE_SWITCH_STATUS_KEY);
137 auto newSendMgr = GetCurrentSendMgr();
138 if (newSendMgr == nullptr) {
139 HILOGI("GetSendMgr failed.");
140 return;
141 }
142 auto newRecvMgr = GetCurrentRecvMgr();
143 if (newRecvMgr == nullptr) {
144 HILOGI("GetRecvMgr failed.");
145 return;
146 }
147 if (DataShareManager::GetInstance().IsCurrentContinueSwitchOn()) {
148 newSendMgr->OnDeviceOnline();
149 DSchedContinueManager::GetInstance().Init();
150 } else {
151 newRecvMgr->OnContinueSwitchOff();
152 HILOGI("ICurrentContinueSwitch is off, %{public}d", DataShareManager::GetInstance()
153 .IsCurrentContinueSwitchOn());
154 DSchedContinueManager::GetInstance().UnInit();
155 };
156 UserSwitchedOnRegisterListenerCache();
157 DmsContinueConditionMgr::GetInstance().OnUserSwitched(accountId);
158 HILOGI("UserSwitched end");
159 }
160
UserSwitchedOnRegisterListenerCache()161 void MultiUserManager::UserSwitchedOnRegisterListenerCache()
162 {
163 HILOGI("UserSwitchedOnRegisterListenerCache start");
164 {
165 std::lock_guard<std::mutex> lock(listenerMutex_);
166 if (!listenerCache_.empty()) {
167 HILOGI("Cache invoke register listener. userId: %{public}d.", currentUserId_);
168 auto recvMgr = GetCurrentRecvMgr();
169 if (recvMgr == nullptr) {
170 HILOGI("GetRecvMgr failed.");
171 return;
172 }
173 auto it = listenerCache_.find(currentUserId_);
174 if (it != listenerCache_.end() && !it->second.empty()) {
175 for (auto param = it->second.begin(); param != it->second.end(); param ++) {
176 std::string type = param->first;
177 sptr<IRemoteObject> obj = param->second;
178 recvMgr->RegisterOnListener(type, obj);
179 }
180 listenerCache_.erase(it);
181 HILOGI("Cache remove. userId: %{public}d.", currentUserId_);
182 }
183 }
184 }
185 HILOGI("UserSwitchedOnRegisterListenerCache end");
186 }
187
OnUserRemoved(int32_t accountId)188 void MultiUserManager::OnUserRemoved(int32_t accountId)
189 {
190 HILOGI("UserRemoved start");
191 {
192 std::lock_guard<std::mutex> lock(sendMutex_);
193 if (!sendMgrMap_.empty()) {
194 auto it = sendMgrMap_.find(accountId);
195 if (it != sendMgrMap_.end()) {
196 sendMgrMap_.erase(it);
197 }
198 }
199 }
200 {
201 std::lock_guard<std::mutex> lock(recvMutex_);
202 if (!recvMgrMap_.empty()) {
203 auto it = recvMgrMap_.find(accountId);
204 if (it != recvMgrMap_.end()) {
205 recvMgrMap_.erase(it);
206 }
207 }
208 }
209 DmsContinueConditionMgr::GetInstance().OnUserRemoved(accountId);
210 HILOGI("UserRemoved end");
211 }
212
CreateNewSendMgrLocked()213 int32_t MultiUserManager::CreateNewSendMgrLocked()
214 {
215 HILOGI("CreateNewSendMgr begin. accountId: %{public}d.", currentUserId_);
216 auto sendMgr = std::make_shared<DMSContinueSendMgr>();
217 sendMgr->Init(currentUserId_);
218 sendMgrMap_.emplace(currentUserId_, sendMgr);
219 HILOGI("CreateNewSendMgr end.");
220 return ERR_OK;
221 }
222
CreateNewRecvMgrLocked()223 int32_t MultiUserManager::CreateNewRecvMgrLocked()
224 {
225 HILOGI("CreateNewRecvMgr begin. accountId: %{public}d.", currentUserId_);
226 auto recvMgr = std::make_shared<DMSContinueRecvMgr>();
227 recvMgr->Init(currentUserId_);
228 recvMgrMap_.emplace(currentUserId_, recvMgr);
229 HILOGI("CreateNewRecvMgr end.");
230 return ERR_OK;
231 }
232
CreateNewRecomMgrLocked()233 int32_t MultiUserManager::CreateNewRecomMgrLocked()
234 {
235 HILOGI("CreateNewRecomMgr begin. accountId: %{public}d.", currentUserId_);
236 auto recomMgr = std::make_shared<DMSContinueRecomMgr>();
237 recomMgr->Init(currentUserId_);
238 recomMgrMap_.emplace(currentUserId_, recomMgr);
239 HILOGI("CreateNewRecomMgr end.");
240 return ERR_OK;
241 }
242
CreateNewSendMgrLocked(int32_t accountId)243 int32_t MultiUserManager::CreateNewSendMgrLocked(int32_t accountId)
244 {
245 HILOGI("CreateNewSendMgr by accountid begin. accountId: %{public}d.", accountId);
246 auto sendMgr = std::make_shared<DMSContinueSendMgr>();
247 sendMgr->Init(accountId);
248 sendMgrMap_.emplace(accountId, sendMgr);
249 HILOGI("CreateNewSendMgr by accountid end.");
250 return ERR_OK;
251 }
252
CreateNewRecvMgrLocked(int32_t accountId)253 int32_t MultiUserManager::CreateNewRecvMgrLocked(int32_t accountId)
254 {
255 HILOGI("CreateNewRecvMgr by accountid begin. accountId: %{public}d.", accountId);
256 auto recvMgr = std::make_shared<DMSContinueRecvMgr>();
257 recvMgr->Init(accountId);
258 recvMgrMap_.emplace(accountId, recvMgr);
259 HILOGI("CreateNewRecvMgr by accountid end.");
260 return ERR_OK;
261 }
262
CreateNewRecomMgrLocked(int32_t accountId)263 int32_t MultiUserManager::CreateNewRecomMgrLocked(int32_t accountId)
264 {
265 HILOGI("CreateNewRecomMgr by accountid begin. accountId: %{public}d.", accountId);
266 auto recomMgr = std::make_shared<DMSContinueRecomMgr>();
267 recomMgr->Init(accountId);
268 recomMgrMap_.emplace(accountId, recomMgr);
269 HILOGI("CreateNewRecomMgr by accountid end.");
270 return ERR_OK;
271 }
272
GetCurrentSendMgr()273 std::shared_ptr<DMSContinueSendMgr> MultiUserManager::GetCurrentSendMgr()
274 {
275 HILOGI("GetCurrentSendMgr. accountId: %{public}d.", currentUserId_);
276 std::lock_guard<std::mutex> lock(sendMutex_);
277 if (sendMgrMap_.empty() || sendMgrMap_.find(currentUserId_) == sendMgrMap_.end()) {
278 HILOGI("sendMgr need to create.");
279 CreateNewSendMgrLocked();
280 }
281 auto cur = sendMgrMap_.find(currentUserId_);
282 return cur->second;
283 }
284
GetCurrentRecvMgr()285 std::shared_ptr<DMSContinueRecvMgr> MultiUserManager::GetCurrentRecvMgr()
286 {
287 HILOGI("GetCurrentRecvMgr. accountId: %{public}d.", currentUserId_);
288 std::lock_guard<std::mutex> lock(recvMutex_);
289 if (recvMgrMap_.empty() || recvMgrMap_.find(currentUserId_) == recvMgrMap_.end()) {
290 HILOGI("recvMgr need to create.");
291 CreateNewRecvMgrLocked();
292 }
293 auto cur = recvMgrMap_.find(currentUserId_);
294 return cur->second;
295 }
296
GetCurrentRecomMgr()297 std::shared_ptr<DMSContinueRecomMgr> MultiUserManager::GetCurrentRecomMgr()
298 {
299 HILOGI("GetCurrentRecomMgr. accountId: %{public}d.", currentUserId_);
300 std::lock_guard<std::mutex> lock(recomMutex_);
301 if (recomMgrMap_.empty() || recomMgrMap_.find(currentUserId_) == recomMgrMap_.end()) {
302 HILOGI("recomMgr need to create.");
303 CreateNewRecomMgrLocked();
304 }
305 auto cur = recomMgrMap_.find(currentUserId_);
306 return cur->second;
307 }
308
GetSendMgrByCallingUid(int32_t callingUid)309 std::shared_ptr<DMSContinueSendMgr> MultiUserManager::GetSendMgrByCallingUid(int32_t callingUid)
310 {
311 int32_t accountId = -1;
312 OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, accountId);
313 HILOGI("GetSendMgrByCallingUid. accountId: %{public}d , callingUid: %{public}d.", accountId, callingUid);
314 std::lock_guard<std::mutex> lock(sendMutex_);
315 if (sendMgrMap_.empty() || sendMgrMap_.find(accountId) == sendMgrMap_.end()) {
316 HILOGI("sendMgr need to create.");
317 CreateNewSendMgrLocked(accountId);
318 }
319 auto cur = sendMgrMap_.find(accountId);
320 return cur->second;
321 }
322
GetRecvMgrByCallingUid(int32_t callingUid)323 std::shared_ptr<DMSContinueRecvMgr> MultiUserManager::GetRecvMgrByCallingUid(int32_t callingUid)
324 {
325 int32_t accountId = -1;
326 OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, accountId);
327 HILOGI("GetRecvMgrByCallingUid. userId: %{public}d , callingUid: %{public}d.", accountId, callingUid);
328 std::lock_guard<std::mutex> lock(recvMutex_);
329 if (recvMgrMap_.empty() || recvMgrMap_.find(accountId) == recvMgrMap_.end()) {
330 HILOGI("recvMgr need to create.");
331 CreateNewRecvMgrLocked(accountId);
332 }
333 auto cur = recvMgrMap_.find(accountId);
334 return cur->second;
335 }
336
GetRecomMgrByCallingUid(int32_t callingUid)337 std::shared_ptr<DMSContinueRecomMgr> MultiUserManager::GetRecomMgrByCallingUid(int32_t callingUid)
338 {
339 int32_t accountId = -1;
340 OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, accountId);
341 HILOGI("GetRecomMgrByCallingUid. userId: %{public}d , callingUid: %{public}d.", accountId, callingUid);
342 std::lock_guard<std::mutex> lock(recomMutex_);
343 if (recomMgrMap_.empty() || recomMgrMap_.find(accountId) == recomMgrMap_.end()) {
344 HILOGI("recomMgr need to create.");
345 CreateNewRecomMgrLocked(accountId);
346 }
347 auto cur = recomMgrMap_.find(accountId);
348 return cur->second;
349 }
350
OnRegisterOnListener(const std::string & type,const sptr<IRemoteObject> & obj,int32_t callingUid)351 int32_t MultiUserManager::OnRegisterOnListener(const std::string& type,
352 const sptr<IRemoteObject>& obj, int32_t callingUid)
353 {
354 int32_t accountId = -1;
355 OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, accountId);
356 HILOGI("OnRegisterOnListener. accountId: %{public}d , callingUid: %{public}d.", accountId, callingUid);
357 {
358 std::lock_guard<std::mutex> lock(listenerMutex_);
359 if (!IsUserForeground(accountId) || accountId != currentUserId_) {
360 HILOGW("The current user is not foreground. accountId: %{public}d , currentUserId_: %{public}d.",
361 accountId, currentUserId_);
362 std::map<std::string, sptr<IRemoteObject>> param;
363 param.emplace(type, obj);
364 listenerCache_.emplace(accountId, param);
365 return ERR_OK;
366 }
367 }
368 auto recvMgr = GetCurrentRecvMgr();
369 if (recvMgr == nullptr) {
370 HILOGI("GetRecvMgr failed.");
371 return DMS_NOT_GET_MANAGER;
372 }
373 return recvMgr->RegisterOnListener(type, obj);
374 }
375
OnRegisterOffListener(const std::string & type,const sptr<IRemoteObject> & obj,int32_t callingUid)376 int32_t MultiUserManager::OnRegisterOffListener(const std::string& type,
377 const sptr<IRemoteObject>& obj, int32_t callingUid)
378 {
379 int32_t accountId = -1;
380 OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, accountId);
381 HILOGI("OnRegisterOffListener. accountId: %{public}d , callingUid: %{public}d.", accountId, callingUid);
382 if (!IsUserForeground(accountId) || accountId != currentUserId_) {
383 HILOGW("The current user is not foreground. accountId: %{public}d , currentUserId_: %{public}d.",
384 accountId, currentUserId_);
385 return DMS_NOT_FOREGROUND_USER;
386 }
387 auto recvMgr = GetCurrentRecvMgr();
388 if (recvMgr == nullptr) {
389 HILOGI("GetRecvMgr failed.");
390 return DMS_NOT_GET_MANAGER;
391 }
392 return recvMgr->RegisterOffListener(type, obj);
393 }
394
GetForegroundUser()395 int32_t MultiUserManager::GetForegroundUser()
396 {
397 int32_t accountId = INVALID_ID;
398 ErrCode err = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(accountId);
399 if (err != ERR_OK || accountId == INVALID_ID) {
400 HILOGE("GetForegroundOsAccountLocalId passing param invalid or return error!, err : %{public}d", err);
401 return INVALID_PARAMETERS_ERR;
402 }
403 HILOGD("GetForegroundOsAccountLocalId accountId is: %{public}d", accountId);
404 return accountId;
405 }
406
IsUserForeground(int32_t accountId)407 bool MultiUserManager::IsUserForeground(int32_t accountId)
408 {
409 bool isForeground = false;
410 std::vector<AccountSA::ForegroundOsAccount> accounts;
411 ErrCode err = OHOS::AccountSA::OsAccountManager::GetForegroundOsAccounts(accounts);
412 if (err != ERR_OK) {
413 HILOGE("GetForegroundOsAccounts passing param inval id or return error!, err : %{public}d", err);
414 }
415 if (!accounts.empty() && accounts[0].localId == accountId) {
416 isForeground = true;
417 HILOGD("Current account. accounts[0].localId: %{public}d.", accounts[0].localId);
418 }
419 HILOGD("Current account. accountId: %{public}d.", accountId);
420 return isForeground;
421 }
422
IsCallerForeground(int32_t callingUid)423 bool MultiUserManager::IsCallerForeground(int32_t callingUid)
424 {
425 int32_t accountId = -1;
426 OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(callingUid, accountId);
427 return IsUserForeground(accountId);
428 }
429
RegisterSoftbusListener()430 void MultiUserManager::RegisterSoftbusListener()
431 {
432 #ifdef DMS_RECEIVE_BROADCAST
433 HILOGI("Register softbusListener start. accountId: %{public}d.", currentUserId_);
434 std::shared_ptr<SoftbusAdapterListener> missionBroadcastListener =
435 std::make_shared<DistributedMissionBroadcastListener>();
436 int32_t ret = SoftbusAdapter::GetInstance().RegisterSoftbusEventListener(missionBroadcastListener);
437 if (ret != ERR_OK) {
438 HILOGE("get RegisterSoftbusEventListener failed, ret: %{public}d", ret);
439 }
440 hasRegSoftbusEventListener_ = true;
441 HILOGI("Register softbusListener end.");
442 #else
443 HILOGW("Register softbusListener Disabled! accountId: %{public}d.", currentUserId_);
444 #endif
445 }
446
CheckRegSoftbusListener()447 bool MultiUserManager::CheckRegSoftbusListener()
448 {
449 return hasRegSoftbusEventListener_;
450 }
451 } // namespace DistributedSchedule
452 } // namespace OHOS
453