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