1 /*
2  * Copyright (c) 2023 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 "mock_session_manager_service.h"
17 
18 #include <cstdint>
19 #include <fcntl.h>
20 #include <securec.h>
21 #include <unistd.h>
22 
23 #include <bundle_mgr_interface.h>
24 #include <system_ability_definition.h>
25 #include <cinttypes>
26 #include <csignal>
27 #include <iomanip>
28 #include <ipc_skeleton.h>
29 #include <iservice_registry.h>
30 #include <map>
31 #include <sstream>
32 
33 #include "window_manager_hilog.h"
34 #include "unique_fd.h"
35 #include "parameters.h"
36 #include "root_scene.h"
37 #include "string_ex.h"
38 #include "wm_common.h"
39 #include "ws_common.h"
40 #include "session_manager_service_interface.h"
41 #include "scene_session_manager_interface.h"
42 #include "screen_session_manager_lite.h"
43 #include "common/include/session_permission.h"
44 
45 #define PATH_LEN 1024
46 #define O_RDWR   02
47 
48 namespace OHOS {
49 namespace Rosen {
50 namespace {
51 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "MockSessionManagerService" };
52 
53 const std::u16string DEFAULT_USTRING = u"error";
54 const char DEFAULT_STRING[] = "error";
55 const std::string ARG_DUMP_HELP = "-h";
56 const std::string ARG_DUMP_ALL = "-a";
57 const std::string ARG_DUMP_WINDOW = "-w";
58 const std::string KEY_SCENE_BOARD_TEST_ENABLE = "persist.scb.testmode.enable";
59 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
60 const std::string TEST_MODULE_NAME_SUFFIX = "_test";
61 const std::string BOOTEVENT_WMS_READY = "bootevent.wms.ready";
62 
GetUserIdByCallingUid()63 inline int32_t GetUserIdByCallingUid()
64 {
65     int32_t uid = IPCSkeleton::GetCallingUid();
66     TLOGD(WmsLogTag::WMS_MULTI_USER, "get calling uid(%{public}d)", uid);
67     if (uid <= INVALID_UID) {
68         TLOGE(WmsLogTag::WMS_MULTI_USER, "uid is illegal: %{public}d", uid);
69         return INVALID_USER_ID;
70     }
71     return GetUserIdByUid(uid);
72 }
73 } // namespace
74 
75 
76 class ClientListenerDeathRecipient : public IRemoteObject::DeathRecipient {
77 public:
ClientListenerDeathRecipient(int32_t userId, int32_t pid, bool isLite)78     explicit ClientListenerDeathRecipient(int32_t userId, int32_t pid, bool isLite)
79         : userId_(userId), pid_(pid), isLite_(isLite)
80     {}
81 
82     void OnRemoteDied(const wptr<IRemoteObject>& wptrDeath) override
83     {
84         TLOGD(WmsLogTag::WMS_RECOVER, "Client died, pid = %{public}d, isLite = %{public}d", pid_, isLite_);
85         if (isLite_) {
86             MockSessionManagerService::GetInstance().UnregisterSMSLiteRecoverListener(userId_, pid_);
87         } else {
88             MockSessionManagerService::GetInstance().UnregisterSMSRecoverListener(userId_, pid_);
89         }
90     }
91 
92 private:
93     int32_t userId_;
94     int32_t pid_;
95     bool isLite_;
96 };
97 
98 WM_IMPLEMENT_SINGLE_INSTANCE(MockSessionManagerService)
SMSDeathRecipient(int32_t userId)99 MockSessionManagerService::SMSDeathRecipient::SMSDeathRecipient(int32_t userId)
100     : userId_(userId), screenId_(DEFAULT_SCREEN_ID)
101 {}
102 
OnRemoteDied(const wptr<IRemoteObject>& object)103 void MockSessionManagerService::SMSDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& object)
104 {
105     TLOGI(WmsLogTag::WMS_MULTI_USER, "Scb died with userId_=%{public}d, screenId_=%{public}d", userId_, screenId_);
106     MockSessionManagerService::GetInstance().NotifyWMSConnectionChanged(userId_, screenId_, false);
107     MockSessionManagerService::GetInstance().RemoveSMSDeathRecipientByUserId(userId_);
108     MockSessionManagerService::GetInstance().RemoveSessionManagerServiceByUserId(userId_);
109     auto sessionManagerService = object.promote();
110     if (!sessionManagerService) {
111         TLOGE(WmsLogTag::WMS_MULTI_USER, "sessionManagerService is null");
112         return;
113     }
114 
115     if (IsSceneBoardTestMode()) {
116         TLOGI(WmsLogTag::WMS_MULTI_USER, "SceneBoard is testing, do not kill foundation.");
117         return;
118     }
119     TLOGW(WmsLogTag::WMS_MULTI_USER, "SessionManagerService died!");
120 }
121 
SetScreenId(int32_t screenId)122 void MockSessionManagerService::SMSDeathRecipient::SetScreenId(int32_t screenId)
123 {
124     TLOGI(WmsLogTag::WMS_MULTI_USER, "screenId=%{public}d", screenId);
125     screenId_ = screenId;
126 }
127 
MockSessionManagerService()128 MockSessionManagerService::MockSessionManagerService()
129     : SystemAbility(WINDOW_MANAGER_SERVICE_ID, true), currentWMSUserId_(INVALID_USER_ID),
130       currentScreenId_(DEFAULT_SCREEN_ID)
131 {}
132 
RegisterMockSessionManagerService()133 bool MockSessionManagerService::RegisterMockSessionManagerService()
134 {
135     bool res = SystemAbility::MakeAndRegisterAbility(this);
136     if (!res) {
137         WLOGFE("register failed");
138     }
139     if (!Publish(this)) {
140         WLOGFE("Publish failed");
141     }
142     WLOGFI("Publish mock session manager service success");
143     return true;
144 }
145 
OnStart()146 void MockSessionManagerService::OnStart()
147 {
148     WLOGFD("OnStart begin");
149 }
150 
Str16ToStr8(const std::u16string& str)151 static std::string Str16ToStr8(const std::u16string& str)
152 {
153     if (str == DEFAULT_USTRING) {
154         return DEFAULT_STRING;
155     }
156     std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert(DEFAULT_STRING);
157     std::string result = convert.to_bytes(str);
158     return result == DEFAULT_STRING ? "" : result;
159 }
160 
Dump(int fd, const std::vector<std::u16string>& args)161 int MockSessionManagerService::Dump(int fd, const std::vector<std::u16string>& args)
162 {
163     WLOGI("dump begin fd: %{public}d", fd);
164     if (fd < 0) {
165         return -1;
166     }
167     (void) signal(SIGPIPE, SIG_IGN); // ignore SIGPIPE crash
168     std::vector<std::string> params;
169     for (auto& arg : args) {
170         params.emplace_back(Str16ToStr8(arg));
171     }
172 
173     std::string dumpInfo;
174     if (params.empty()) {
175         ShowHelpInfo(dumpInfo);
176     } else if (params.size() == 1 && params[0] == ARG_DUMP_HELP) { // 1: params num
177         ShowHelpInfo(dumpInfo);
178     } else {
179         int errCode = DumpSessionInfo(params, dumpInfo);
180         if (errCode != 0) {
181             ShowIllegalArgsInfo(dumpInfo);
182         }
183     }
184     int ret = dprintf(fd, "%s\n", dumpInfo.c_str());
185     if (ret < 0) {
186         WLOGFE("dprintf error");
187         return -1; // WMError::WM_ERROR_INVALID_OPERATION;
188     }
189     WLOGI("dump end");
190     return 0;
191 }
192 
SetSessionManagerService(const sptr<IRemoteObject>& sessionManagerService)193 bool MockSessionManagerService::SetSessionManagerService(const sptr<IRemoteObject>& sessionManagerService)
194 {
195     if (!sessionManagerService) {
196         WLOGFE("sessionManagerService is nullptr");
197         return false;
198     }
199     currentWMSUserId_ = GetUserIdByCallingUid();
200     if (currentWMSUserId_ <= INVALID_USER_ID) {
201         TLOGE(WmsLogTag::WMS_MULTI_USER, "userId is illegal: %{public}d", currentWMSUserId_);
202         return false;
203     }
204     {
205         std::unique_lock<std::shared_mutex> lock(sessionManagerServiceMapLock_);
206         sessionManagerServiceMap_[currentWMSUserId_] = sessionManagerService;
207     }
208     RecoverSCBSnapshotSkipByUserId(currentWMSUserId_);
209     auto smsDeathRecipient = GetSMSDeathRecipientByUserId(currentWMSUserId_);
210     if (!smsDeathRecipient) {
211         smsDeathRecipient = new SMSDeathRecipient(currentWMSUserId_);
212         std::unique_lock<std::shared_mutex> lock(smsDeathRecipientMapLock_);
213         if (!smsDeathRecipient) {
214             TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to create death Recipient ptr smsDeathRecipient");
215             return false;
216         }
217         smsDeathRecipientMap_[currentWMSUserId_] = smsDeathRecipient;
218     }
219     if (sessionManagerService->IsProxyObject() && !sessionManagerService->AddDeathRecipient(smsDeathRecipient)) {
220         TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to add death recipient");
221         return false;
222     }
223     RegisterMockSessionManagerService();
224     TLOGI(WmsLogTag::WMS_MULTI_USER, "sessionManagerService set success!");
225     system::SetParameter(BOOTEVENT_WMS_READY.c_str(), "true");
226     GetSceneSessionManager();
227 
228     return true;
229 }
230 
GetSMSDeathRecipientByUserId( int32_t userId)231 sptr<MockSessionManagerService::SMSDeathRecipient> MockSessionManagerService::GetSMSDeathRecipientByUserId(
232     int32_t userId)
233 {
234     std::shared_lock<std::shared_mutex> lock(smsDeathRecipientMapLock_);
235     auto iter = smsDeathRecipientMap_.find(userId);
236     if (iter != smsDeathRecipientMap_.end()) {
237         TLOGI(WmsLogTag::WMS_MULTI_USER, "Get SMS death recipient with userId=%{public}d", userId);
238         return iter->second;
239     } else {
240         TLOGW(WmsLogTag::WMS_MULTI_USER, "Get SMS death recipient failed with userId=%{public}d", userId);
241         return nullptr;
242     }
243 }
244 
RemoveSMSDeathRecipientByUserId(int32_t userId)245 void MockSessionManagerService::RemoveSMSDeathRecipientByUserId(int32_t userId)
246 {
247     TLOGI(WmsLogTag::WMS_MULTI_USER, "userId: %{public}d", userId);
248     auto sessionManagerService = GetSessionManagerServiceByUserId(userId);
249     std::unique_lock<std::shared_mutex> lock(smsDeathRecipientMapLock_);
250     auto iter = smsDeathRecipientMap_.find(userId);
251     if (iter != smsDeathRecipientMap_.end() && iter->second) {
252         if (sessionManagerService != nullptr) {
253             sessionManagerService->RemoveDeathRecipient(iter->second);
254         }
255     }
256 }
257 
GetSessionManagerService()258 sptr<IRemoteObject> MockSessionManagerService::GetSessionManagerService()
259 {
260     int32_t clientUserId = GetUserIdByCallingUid();
261     if (clientUserId <= INVALID_USER_ID) {
262         TLOGE(WmsLogTag::WMS_MULTI_USER, "userId is illegal: %{public}d", clientUserId);
263         return nullptr;
264     }
265     if (clientUserId == SYSTEM_USERID) {
266         TLOGI(WmsLogTag::WMS_MULTI_USER, "System user, return current sessionManagerService with %{public}d",
267             currentWMSUserId_);
268         clientUserId = currentWMSUserId_;
269     }
270     return GetSessionManagerServiceByUserId(clientUserId);
271 }
272 
GetSessionManagerServiceByUserId(int32_t userId)273 sptr<IRemoteObject> MockSessionManagerService::GetSessionManagerServiceByUserId(int32_t userId)
274 {
275     std::shared_lock<std::shared_mutex> lock(sessionManagerServiceMapLock_);
276     auto iter = sessionManagerServiceMap_.find(userId);
277     if (iter != sessionManagerServiceMap_.end()) {
278         TLOGD(WmsLogTag::WMS_MULTI_USER, "Get session manager service success with userId=%{public}d", userId);
279         return iter->second;
280     } else {
281         TLOGE(WmsLogTag::WMS_MULTI_USER, "Get session manager service failed with userId=%{public}d", userId);
282         return nullptr;
283     }
284 }
285 
RemoveSessionManagerServiceByUserId(int32_t userId)286 void MockSessionManagerService::RemoveSessionManagerServiceByUserId(int32_t userId)
287 {
288     TLOGI(WmsLogTag::WMS_MULTI_USER, "userId: %{public}d", userId);
289     std::unique_lock<std::shared_mutex> lock(sessionManagerServiceMapLock_);
290     auto iter = sessionManagerServiceMap_.find(userId);
291     if (iter != sessionManagerServiceMap_.end()) {
292         sessionManagerServiceMap_.erase(iter);
293     }
294 }
295 
NotifySceneBoardAvailable()296 void MockSessionManagerService::NotifySceneBoardAvailable()
297 {
298     if (!SessionPermission::IsSystemCalling()) {
299         TLOGE(WmsLogTag::WMS_RECOVER, "permission denied");
300         return;
301     }
302     int32_t userId = GetUserIdByCallingUid();
303     if (userId <= INVALID_USER_ID) {
304         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", userId);
305         return;
306     }
307     TLOGI(WmsLogTag::WMS_RECOVER, "scene board is available with userId=%{public}d", userId);
308 
309     NotifySceneBoardAvailableToLiteClient(SYSTEM_USERID);
310     NotifySceneBoardAvailableToLiteClient(userId);
311 
312     NotifySceneBoardAvailableToClient(SYSTEM_USERID);
313     NotifySceneBoardAvailableToClient(userId);
314 }
315 
RegisterSMSRecoverListener(const sptr<IRemoteObject>& listener)316 void MockSessionManagerService::RegisterSMSRecoverListener(const sptr<IRemoteObject>& listener)
317 {
318     if (listener == nullptr) {
319         TLOGE(WmsLogTag::WMS_RECOVER, "listener is nullptr");
320         return;
321     }
322 
323     int32_t clientUserId = GetUserIdByCallingUid();
324     if (clientUserId <= INVALID_USER_ID) {
325         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", clientUserId);
326         return;
327     }
328     int32_t pid = IPCSkeleton::GetCallingRealPid();
329     TLOGI(WmsLogTag::WMS_RECOVER, "clientUserId = %{public}d, pid = %{public}d", clientUserId, pid);
330     sptr<ClientListenerDeathRecipient> clientDeathListener = new ClientListenerDeathRecipient(clientUserId, pid, false);
331     listener->AddDeathRecipient(clientDeathListener);
332     sptr<ISessionManagerServiceRecoverListener> smsListener;
333     {
334         std::unique_lock<std::shared_mutex> lock(smsRecoverListenerLock_);
335         smsListener = iface_cast<ISessionManagerServiceRecoverListener>(listener);
336         smsRecoverListenerMap_[clientUserId][pid] = smsListener;
337     }
338     if (clientUserId != SYSTEM_USERID) {
339         return;
340     }
341     bool isWMSConnected = false;
342     {
343         std::lock_guard<std::mutex> lock(wmsConnectionStatusLock_);
344         if (wmsConnectionStatusMap_.find(currentWMSUserId_) != wmsConnectionStatusMap_.end()) {
345             isWMSConnected = wmsConnectionStatusMap_[currentWMSUserId_];
346         }
347     }
348     if (smsListener && isWMSConnected) {
349         auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
350         if (sessionManagerService == nullptr) {
351             TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
352             return;
353         }
354         TLOGI(WmsLogTag::WMS_RECOVER, "WMS is already connected, notify client");
355         smsListener->OnWMSConnectionChanged(currentWMSUserId_, currentScreenId_, true, sessionManagerService);
356     }
357 }
358 
GetSMSRecoverListenerMap( int32_t userId)359 std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* MockSessionManagerService::GetSMSRecoverListenerMap(
360     int32_t userId)
361 {
362     auto iter = smsRecoverListenerMap_.find(userId);
363     if (iter != smsRecoverListenerMap_.end()) {
364         return &iter->second;
365     }
366     return nullptr;
367 }
368 
UnregisterSMSRecoverListener()369 void MockSessionManagerService::UnregisterSMSRecoverListener()
370 {
371     int32_t clientUserId = GetUserIdByCallingUid();
372     if (clientUserId <= INVALID_USER_ID) {
373         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", clientUserId);
374         return;
375     }
376     int32_t pid = IPCSkeleton::GetCallingRealPid();
377     TLOGD(WmsLogTag::WMS_RECOVER, "clientUserId = %{public}d, pid = %{public}d", clientUserId, pid);
378     UnregisterSMSRecoverListener(clientUserId, pid);
379 }
380 
UnregisterSMSRecoverListener(int32_t userId, int32_t pid)381 void MockSessionManagerService::UnregisterSMSRecoverListener(int32_t userId, int32_t pid)
382 {
383     TLOGD(WmsLogTag::WMS_RECOVER, "userId = %{public}d, pid = %{public}d", userId, pid);
384     std::unique_lock<std::shared_mutex> lock(smsRecoverListenerLock_);
385     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsRecoverListenerMap =
386         GetSMSRecoverListenerMap(userId);
387     if (!smsRecoverListenerMap) {
388         TLOGW(WmsLogTag::WMS_RECOVER, "smsRecoverListenerMap is null");
389         return;
390     }
391     auto iter = smsRecoverListenerMap->find(pid);
392     if (iter != smsRecoverListenerMap->end()) {
393         smsRecoverListenerMap->erase(iter);
394     }
395 }
396 
NotifySceneBoardAvailableToClient(int32_t userId)397 void MockSessionManagerService::NotifySceneBoardAvailableToClient(int32_t userId)
398 {
399     std::shared_lock<std::shared_mutex> lock(smsRecoverListenerLock_);
400     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsRecoverListenerMap =
401         GetSMSRecoverListenerMap(userId);
402     if (!smsRecoverListenerMap) {
403         TLOGW(WmsLogTag::WMS_RECOVER, "smsRecoverListenerMap is null");
404         return;
405     }
406     TLOGI(WmsLogTag::WMS_RECOVER, "userId=%{public}d, Remote process count = %{public}" PRIu64, userId,
407         static_cast<uint64_t>(smsRecoverListenerMap->size()));
408     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
409     if (sessionManagerService == nullptr) {
410         TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
411         return;
412     }
413     for (auto& iter : *smsRecoverListenerMap) {
414         if (iter.second != nullptr) {
415             TLOGI(WmsLogTag::WMS_RECOVER, "Call OnSessionManagerServiceRecover pid = %{public}d", iter.first);
416             iter.second->OnSessionManagerServiceRecover(sessionManagerService);
417         }
418     }
419 }
420 
RegisterSMSLiteRecoverListener(const sptr<IRemoteObject>& listener)421 void MockSessionManagerService::RegisterSMSLiteRecoverListener(const sptr<IRemoteObject>& listener)
422 {
423     if (listener == nullptr) {
424         TLOGE(WmsLogTag::WMS_RECOVER, "Lite listener is nullptr");
425         return;
426     }
427     int32_t clientUserId = GetUserIdByCallingUid();
428     if (clientUserId <= INVALID_USER_ID) {
429         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", clientUserId);
430         return;
431     }
432     int32_t pid = IPCSkeleton::GetCallingRealPid();
433     TLOGI(WmsLogTag::WMS_RECOVER, "clientUserId = %{public}d, pid = %{public}d", clientUserId, pid);
434     sptr<ClientListenerDeathRecipient> clientDeathListener = new ClientListenerDeathRecipient(clientUserId, pid, true);
435     listener->AddDeathRecipient(clientDeathListener);
436     sptr<ISessionManagerServiceRecoverListener> smsListener;
437     {
438         std::unique_lock<std::shared_mutex> lock(smsLiteRecoverListenerLock_);
439         smsListener = iface_cast<ISessionManagerServiceRecoverListener>(listener);
440         smsLiteRecoverListenerMap_[clientUserId][pid] = smsListener;
441     }
442     if (clientUserId != SYSTEM_USERID) {
443         return;
444     }
445     bool isWMSConnected = false;
446     {
447         std::lock_guard<std::mutex> lock(wmsConnectionStatusLock_);
448         if (wmsConnectionStatusMap_.find(currentWMSUserId_) != wmsConnectionStatusMap_.end()) {
449             isWMSConnected = wmsConnectionStatusMap_[currentWMSUserId_];
450         }
451     }
452     if (smsListener && isWMSConnected) {
453         auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
454         if (sessionManagerService == nullptr) {
455             TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
456             return;
457         }
458         TLOGI(WmsLogTag::WMS_MULTI_USER, "Lite wms is already connected, notify client");
459         smsListener->OnWMSConnectionChanged(currentWMSUserId_, currentScreenId_, true, sessionManagerService);
460     }
461 }
462 
GetSMSLiteRecoverListenerMap( int32_t userId)463 std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* MockSessionManagerService::GetSMSLiteRecoverListenerMap(
464     int32_t userId)
465 {
466     auto iter = smsLiteRecoverListenerMap_.find(userId);
467     if (iter != smsLiteRecoverListenerMap_.end()) {
468         return &iter->second;
469     }
470     return nullptr;
471 }
472 
UnregisterSMSLiteRecoverListener()473 void MockSessionManagerService::UnregisterSMSLiteRecoverListener()
474 {
475     int32_t clientUserId = GetUserIdByCallingUid();
476     if (clientUserId <= INVALID_USER_ID) {
477         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", clientUserId);
478         return;
479     }
480     int32_t pid = IPCSkeleton::GetCallingRealPid();
481     TLOGD(WmsLogTag::WMS_RECOVER, "clientUserId = %{public}d, pid = %{public}d", clientUserId, pid);
482     UnregisterSMSLiteRecoverListener(clientUserId, pid);
483 }
484 
UnregisterSMSLiteRecoverListener(int32_t userId, int32_t pid)485 void MockSessionManagerService::UnregisterSMSLiteRecoverListener(int32_t userId, int32_t pid)
486 {
487     TLOGD(WmsLogTag::WMS_RECOVER, "userId = %{public}d, pid = %{public}d", userId, pid);
488     std::unique_lock<std::shared_mutex> lock(smsLiteRecoverListenerLock_);
489     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsLiteRecoverListenerMap =
490         GetSMSLiteRecoverListenerMap(userId);
491     if (!smsLiteRecoverListenerMap) {
492         return;
493     }
494     auto iter = smsLiteRecoverListenerMap->find(pid);
495     if (iter != smsLiteRecoverListenerMap->end()) {
496         smsLiteRecoverListenerMap->erase(iter);
497     }
498 }
499 
NotifySceneBoardAvailableToLiteClient(int32_t userId)500 void MockSessionManagerService::NotifySceneBoardAvailableToLiteClient(int32_t userId)
501 {
502     std::shared_lock<std::shared_mutex> lock(smsLiteRecoverListenerLock_);
503     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsLiteRecoverListenerMap =
504         GetSMSLiteRecoverListenerMap(userId);
505     if (!smsLiteRecoverListenerMap) {
506         return;
507     }
508     TLOGI(WmsLogTag::WMS_RECOVER, "userId=%{public}d, Remote process count = %{public}" PRIu64, userId,
509         static_cast<uint64_t>(smsLiteRecoverListenerMap->size()));
510     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
511     if (sessionManagerService == nullptr) {
512         TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
513         return;
514     }
515     for (auto& iter : *smsLiteRecoverListenerMap) {
516         if (iter.second != nullptr) {
517             TLOGI(WmsLogTag::WMS_RECOVER,
518                 "Call OnSessionManagerServiceRecover Lite pid = %{public}d, ref count = %{public}" PRId32, iter.first,
519                 iter.second->GetSptrRefCount());
520             iter.second->OnSessionManagerServiceRecover(sessionManagerService);
521         }
522     }
523 }
524 
NotifyWMSConnected(int32_t userId, int32_t screenId, bool isColdStart)525 void MockSessionManagerService::NotifyWMSConnected(int32_t userId, int32_t screenId, bool isColdStart)
526 {
527     TLOGI(WmsLogTag::WMS_MULTI_USER, "userId = %{public}d, screenId = %{public}d, isColdStart = %{public}d", userId,
528         screenId, isColdStart);
529     currentScreenId_ = screenId;
530     currentWMSUserId_ = userId;
531     auto smsDeathRecipient = GetSMSDeathRecipientByUserId(currentWMSUserId_);
532     if (smsDeathRecipient != nullptr) {
533         smsDeathRecipient->SetScreenId(screenId);
534     }
535     if (!isColdStart) {
536         TLOGI(WmsLogTag::WMS_MULTI_USER, "User switched");
537         GetSceneSessionManager();
538     }
539     NotifyWMSConnectionChanged(userId, screenId, true);
540 }
541 
NotifyWMSConnectionChanged(int32_t wmsUserId, int32_t screenId, bool isConnected)542 void MockSessionManagerService::NotifyWMSConnectionChanged(int32_t wmsUserId, int32_t screenId, bool isConnected)
543 {
544     TLOGI(WmsLogTag::WMS_MULTI_USER, "wmsUserId = %{public}d, isConnected = %{public}d", wmsUserId, isConnected);
545     {
546         std::lock_guard<std::mutex> lock(wmsConnectionStatusLock_);
547         wmsConnectionStatusMap_[wmsUserId] = isConnected;
548     }
549     NotifyWMSConnectionChangedToLiteClient(wmsUserId, screenId, isConnected);
550     NotifyWMSConnectionChangedToClient(wmsUserId, screenId, isConnected);
551 }
552 
NotifyWMSConnectionChangedToClient( int32_t wmsUserId, int32_t screenId, bool isConnected)553 void MockSessionManagerService::NotifyWMSConnectionChangedToClient(
554     int32_t wmsUserId, int32_t screenId, bool isConnected)
555 {
556     std::shared_lock<std::shared_mutex> lock(smsRecoverListenerLock_);
557     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsRecoverListenerMap =
558         GetSMSRecoverListenerMap(SYSTEM_USERID);
559     if (!smsRecoverListenerMap) {
560         TLOGW(WmsLogTag::WMS_MULTI_USER, "smsRecoverListenerMap is null");
561         return;
562     }
563     TLOGD(WmsLogTag::WMS_MULTI_USER,
564         "wmsUserId = %{public}d, isConnected = %{public}d, remote process count = "
565         "%{public}" PRIu64,
566         wmsUserId, isConnected, static_cast<uint64_t>(smsRecoverListenerMap->size()));
567     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
568     if (sessionManagerService == nullptr) {
569         TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
570         return;
571     }
572     for (auto& iter : *smsRecoverListenerMap) {
573         if (iter.second != nullptr) {
574             TLOGI(WmsLogTag::WMS_MULTI_USER, "Call OnWMSConnectionChanged pid = %{public}d", iter.first);
575             iter.second->OnWMSConnectionChanged(wmsUserId, screenId, isConnected, sessionManagerService);
576         }
577     }
578 }
579 
NotifyWMSConnectionChangedToLiteClient( int32_t wmsUserId, int32_t screenId, bool isConnected)580 void MockSessionManagerService::NotifyWMSConnectionChangedToLiteClient(
581     int32_t wmsUserId, int32_t screenId, bool isConnected)
582 {
583     std::shared_lock<std::shared_mutex> lock(smsLiteRecoverListenerLock_);
584     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsLiteRecoverListenerMap =
585         GetSMSLiteRecoverListenerMap(SYSTEM_USERID);
586     if (!smsLiteRecoverListenerMap) {
587         return;
588     }
589     TLOGD(WmsLogTag::WMS_MULTI_USER, "wmsUserId = %{public}d, isConnected = %{public}d", wmsUserId, isConnected);
590     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
591     if (sessionManagerService == nullptr) {
592         TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
593         return;
594     }
595     for (auto& iter : *smsLiteRecoverListenerMap) {
596         if (iter.second != nullptr) {
597             TLOGI(WmsLogTag::WMS_MULTI_USER,
598                 "Call OnWMSConnectionChanged Lite pid = %{public}d, ref count = %{public}d", iter.first,
599                 iter.second->GetSptrRefCount());
600             iter.second->OnWMSConnectionChanged(wmsUserId, screenId, isConnected, sessionManagerService);
601         }
602     }
603 }
604 
GetScreenSessionManagerLite()605 sptr<IRemoteObject> MockSessionManagerService::GetScreenSessionManagerLite()
606 {
607     if (screenSessionManager_) {
608         return screenSessionManager_;
609     }
610     screenSessionManager_ = ScreenSessionManagerLite::GetInstance().AsObject();
611     return screenSessionManager_;
612 }
613 
ShowIllegalArgsInfo(std::string& dumpInfo)614 void MockSessionManagerService::ShowIllegalArgsInfo(std::string& dumpInfo)
615 {
616     dumpInfo.append("The arguments are illegal and you can enter '-h' for help.");
617 }
618 
GetSceneSessionManager()619 sptr<IRemoteObject> MockSessionManagerService::GetSceneSessionManager()
620 {
621     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
622     if (sessionManagerService == nullptr) {
623         WLOGFE("SessionManagerService is null");
624         return nullptr;
625     }
626     sptr<ISessionManagerService> sessionManagerServiceProxy = iface_cast<ISessionManagerService>(sessionManagerService);
627     if (!sessionManagerServiceProxy) {
628         WLOGFE("sessionManagerServiceProxy is nullptr");
629         return nullptr;
630     }
631     sptr<IRemoteObject> remoteObject = sessionManagerServiceProxy->GetSceneSessionManager();
632     if (!remoteObject) {
633         WLOGFW("Get scene session manager proxy failed, scene session manager service is null");
634         return sptr<IRemoteObject>(nullptr);
635     }
636     sceneSessionManager_ = remoteObject;
637     return sceneSessionManager_;
638 }
639 
DumpSessionInfo(const std::vector<std::string>& args, std::string& dumpInfo)640 int MockSessionManagerService::DumpSessionInfo(const std::vector<std::string>& args, std::string& dumpInfo)
641 {
642     if (args.empty()) {
643         return -1;  // WMError::WM_ERROR_INVALID_PARAM;
644     }
645     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
646     if (sessionManagerService == nullptr) {
647         WLOGFE("sessionManagerService is nullptr");
648         return -1;
649     }
650     if (!sceneSessionManager_) {
651         WLOGFW("Get scene session manager ...");
652         GetSceneSessionManager();
653         if (!sceneSessionManager_) {
654             WLOGFW("Get scene session manager proxy failed, nullptr");
655             return -1;
656         }
657     }
658     sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(sceneSessionManager_);
659     WSError ret = sceneSessionManagerProxy->GetSessionDumpInfo(args, dumpInfo);
660     if (ret != WSError::WS_OK) {
661         WLOGFD("sessionManagerService set success!");
662         return -1;
663     }
664     return 0; // WMError::WM_OK;
665 }
666 
ShowHelpInfo(std::string& dumpInfo)667 void MockSessionManagerService::ShowHelpInfo(std::string& dumpInfo)
668 {
669     dumpInfo.append("Usage:\n")
670         .append(" -h                             ")
671         .append("|help text for the tool\n")
672         .append(" -a                             ")
673         .append("|dump all window information in the system\n")
674         .append(" -w {window id} [ArkUI Option]  ")
675         .append("|dump specified window information\n")
676         .append(" ------------------------------------[ArkUI Option]------------------------------------ \n");
677     ShowAceDumpHelp(dumpInfo);
678 }
679 
ShowAceDumpHelp(std::string& dumpInfo)680 void MockSessionManagerService::ShowAceDumpHelp(std::string& dumpInfo)
681 {
682 }
683 
IsSceneBoardTestMode()684 bool MockSessionManagerService::SMSDeathRecipient::IsSceneBoardTestMode()
685 {
686     if (!OHOS::system::GetBoolParameter(KEY_SCENE_BOARD_TEST_ENABLE, false)) {
687         WLOGFD("SceneBoard testmode is disabled.");
688         return false;
689     }
690     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
691     if (systemAbilityMgr == nullptr) {
692         WLOGFE("Failed to get SystemAbilityManager.");
693         return false;
694     }
695 
696     auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
697     if (bmsObj == nullptr) {
698         WLOGFE("Failed to get BundleManagerService.");
699         return false;
700     }
701     sptr<AppExecFwk::IBundleMgr> bundleMgr_ = iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
702     AppExecFwk::BundleInfo bundleInfo;
703     int uid = IPCSkeleton::GetCallingUid();
704     int userId = uid / 200000;
705     bool result = bundleMgr_->GetBundleInfo(SCENE_BOARD_BUNDLE_NAME,
706         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId);
707     if (!result) {
708         WLOGFE("Failed to query bundleInfo, userId:%{public}d", userId);
709         return true;
710     }
711     auto hapModulesList = bundleInfo.hapModuleInfos;
712     if (hapModulesList.empty()) {
713         WLOGFE("hapModulesList is empty");
714         return false;
715     }
716     std::string suffix = TEST_MODULE_NAME_SUFFIX;
717     for (auto hapModule: hapModulesList) {
718         std::string moduleName = hapModule.moduleName;
719         if (moduleName.length() < suffix.length()) {
720             continue;
721         }
722         if (moduleName.compare(moduleName.length() - suffix.length(), suffix.length(), suffix) == 0) {
723             WLOGFI("Found test module name: %{public}s", moduleName.c_str());
724             return true;
725         }
726     }
727     return false;
728 }
729 
WriteStringToFile(int32_t pid, const char* str)730 void MockSessionManagerService::WriteStringToFile(int32_t pid, const char* str)
731 {
732     char file[PATH_LEN] = {0};
733     if (snprintf_s(file, PATH_LEN, PATH_LEN - 1, "/proc/%d/unexpected_die_catch", pid) == -1) {
734         WLOGFI("failed to build path for %d.", pid);
735     }
736     int fd = open(file, O_RDWR);
737     if (fd == -1) {
738         return;
739     }
740     if (write(fd, str, strlen(str)) < 0) {
741         WLOGFI("failed to write 0 for %s", file);
742         close(fd);
743         return;
744     }
745     close(fd);
746 }
747 
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid, const std::vector<uint64_t>& windowIdList, std::vector<uint64_t>& surfaceNodeIds)748 void MockSessionManagerService::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
749     const std::vector<uint64_t>& windowIdList, std::vector<uint64_t>& surfaceNodeIds)
750 {
751     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
752     if (sessionManagerService == nullptr) {
753         WLOGFE("sessionManagerService is nullptr");
754         return;
755     }
756     if (!sceneSessionManager_) {
757         WLOGFW("Get scene session manager ...");
758         GetSceneSessionManager();
759         if (!sceneSessionManager_) {
760             WLOGFW("Get scene session manager proxy failed, nullptr");
761             return;
762         }
763     }
764     if (windowIdList.empty()) {
765         TLOGE(WmsLogTag::DEFAULT, "windowIdList is null, no need to get surfaceNodeId");
766         return;
767     }
768     std::vector<int32_t> persistentIds;
769     for (uint64_t id : windowIdList) {
770         persistentIds.push_back(static_cast<int32_t>(id));
771     }
772     sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(sceneSessionManager_);
773     WMError ret = sceneSessionManagerProxy->GetProcessSurfaceNodeIdByPersistentId(
774         pid, persistentIds, surfaceNodeIds);
775     if (ret != WMError::WM_OK) {
776         TLOGE(WmsLogTag::DEFAULT, "Get process surfaceNodeId by persistentId failed!");
777     }
778 }
779 
GetSceneSessionManagerByUserId(int32_t userId)780 sptr<IRemoteObject> MockSessionManagerService::GetSceneSessionManagerByUserId(int32_t userId)
781 {
782     auto sessionManagerService = GetSessionManagerServiceByUserId(userId);
783     if (sessionManagerService == nullptr) {
784         WLOGFE("sessionManagerService is nullptr");
785         return nullptr;
786     }
787     sptr<ISessionManagerService> sessionManagerServiceProxy =
788         iface_cast<ISessionManagerService>(sessionManagerService);
789     if (sessionManagerServiceProxy == nullptr) {
790         WLOGFE("sessionManagerServiceProxy is nullptr");
791         return nullptr;
792     }
793     sptr<IRemoteObject> remoteObject = sessionManagerServiceProxy->GetSceneSessionManager();
794     if (remoteObject == nullptr) {
795         WLOGFW("Get scene session manager proxy failed");
796     }
797     return remoteObject;
798 }
799 
RecoverSCBSnapshotSkipByUserId(int32_t userId)800 int32_t MockSessionManagerService::RecoverSCBSnapshotSkipByUserId(int32_t userId)
801 {
802     std::unique_lock<std::mutex> lock(userIdBundleNamesMapLock_);
803     auto iter = userIdBundleNamesMap_.find(userId);
804     if (iter == userIdBundleNamesMap_.end()) {
805         return ERR_INVALID_VALUE;
806     }
807     sptr<IRemoteObject> remoteObject = GetSceneSessionManagerByUserId(userId);
808     if (!remoteObject) {
809         return ERR_NULL_OBJECT;
810     }
811     return NotifySCBSnapshotSkipByUserIdAndBundleNames(userId, iter->second, remoteObject);
812 }
813 
NotifySCBSnapshotSkipByUserIdAndBundleNames(int32_t userId, const std::vector<std::string>& bundleNameList, const sptr<IRemoteObject>& remoteObject)814 int32_t MockSessionManagerService::NotifySCBSnapshotSkipByUserIdAndBundleNames(int32_t userId,
815     const std::vector<std::string>& bundleNameList, const sptr<IRemoteObject>& remoteObject)
816 {
817     sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(remoteObject);
818     WMError ret = sceneSessionManagerProxy->SkipSnapshotByUserIdAndBundleNames(userId, bundleNameList);
819     if (ret != WMError::WM_OK) {
820         TLOGE(WmsLogTag::DEFAULT, "failed!");
821         return ERR_TRANSACTION_FAILED;
822     }
823     return ERR_NONE;
824 }
825 
SetSnapshotSkipByUserIdAndBundleNames(int32_t userId, const std::vector<std::string>& bundleNameList)826 int32_t MockSessionManagerService::SetSnapshotSkipByUserIdAndBundleNames(int32_t userId,
827     const std::vector<std::string>& bundleNameList)
828 {
829     if (!SessionPermission::IsSystemCalling()) {
830         TLOGE(WmsLogTag::WMS_MULTI_USER, "permission denied!");
831         return ERR_UNKNOWN_TRANSACTION;
832     }
833     sptr<IRemoteObject> remoteObject = GetSceneSessionManagerByUserId(userId);
834     if (!remoteObject) {
835         return ERR_NULL_OBJECT;
836     }
837     {
838         std::unique_lock<std::mutex> lock(userIdBundleNamesMapLock_);
839         userIdBundleNamesMap_[userId] = bundleNameList;
840     }
841     return NotifySCBSnapshotSkipByUserIdAndBundleNames(userId, bundleNameList, remoteObject);
842 }
843 
SetSnapshotSkipByIdNamesMap( const std::unordered_map<int32_t, std::vector<std::string>>& userIdAndBunldeNames)844 int32_t MockSessionManagerService::SetSnapshotSkipByIdNamesMap(
845     const std::unordered_map<int32_t, std::vector<std::string>>& userIdAndBunldeNames)
846 {
847     if (!SessionPermission::IsSystemCalling()) {
848         TLOGE(WmsLogTag::WMS_MULTI_USER, "permission denied");
849         return ERR_UNKNOWN_TRANSACTION;
850     }
851     std::unique_lock<std::mutex> lock(userIdBundleNamesMapLock_);
852     userIdBundleNamesMap_ = userIdAndBunldeNames;
853     for (auto it = userIdBundleNamesMap_.begin(); it != userIdBundleNamesMap_.end(); ++it) {
854         sptr<IRemoteObject> remoteObject = GetSceneSessionManagerByUserId(it->first);
855         if (!remoteObject) {
856             return ERR_NULL_OBJECT;
857         }
858         int32_t err = NotifySCBSnapshotSkipByUserIdAndBundleNames(it->first, it->second, remoteObject);
859         if (err != ERR_NONE) {
860             TLOGE(WmsLogTag::DEFAULT, "failed");
861             return err;
862         }
863     }
864     return ERR_NONE;
865 }
866 } // namespace Rosen
867 } // namespace OHOS