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 
OnRemoteDied(const wptr<IRemoteObject> & wptrDeath)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 
WM_IMPLEMENT_SINGLE_INSTANCE(MockSessionManagerService)98 WM_IMPLEMENT_SINGLE_INSTANCE(MockSessionManagerService)
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     static bool isRegistered = false;
136     static bool isPublished = false;
137     if (isRegistered && isPublished) {
138         TLOGW(WmsLogTag::WMS_MULTI_USER, "WindowManagerService SA has already been registered and published");
139         return true;
140     }
141     if (!isRegistered) {
142         isRegistered = SystemAbility::MakeAndRegisterAbility(this);
143         if (isRegistered) {
144             TLOGI(WmsLogTag::WMS_MULTI_USER, "Successfully registered WindowManagerService SA");
145         } else {
146             TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to register WindowManagerService SA");
147         }
148     }
149     if (!isPublished) {
150         isPublished = Publish(this);
151         if (isPublished) {
152             TLOGI(WmsLogTag::WMS_MULTI_USER, "Successfully published WindowManagerService SA");
153         } else {
154             TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to publish WindowManagerService SA");
155         }
156     }
157     return isRegistered && isPublished;
158 }
159 
OnStart()160 void MockSessionManagerService::OnStart()
161 {
162     WLOGFD("OnStart begin");
163 }
164 
Str16ToStr8(const std::u16string & str)165 static std::string Str16ToStr8(const std::u16string& str)
166 {
167     if (str == DEFAULT_USTRING) {
168         return DEFAULT_STRING;
169     }
170     std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert(DEFAULT_STRING);
171     std::string result = convert.to_bytes(str);
172     return result == DEFAULT_STRING ? "" : result;
173 }
174 
Dump(int fd,const std::vector<std::u16string> & args)175 int MockSessionManagerService::Dump(int fd, const std::vector<std::u16string> &args)
176 {
177     WLOGI("dump begin fd: %{public}d", fd);
178     if (fd < 0) {
179         return -1;
180     }
181     (void) signal(SIGPIPE, SIG_IGN); // ignore SIGPIPE crash
182     std::vector<std::string> params;
183     for (auto& arg : args) {
184         params.emplace_back(Str16ToStr8(arg));
185     }
186 
187     std::string dumpInfo;
188     if (params.empty()) {
189         ShowHelpInfo(dumpInfo);
190     } else if (params.size() == 1 && params[0] == ARG_DUMP_HELP) { // 1: params num
191         ShowHelpInfo(dumpInfo);
192     } else {
193         int errCode = DumpSessionInfo(params, dumpInfo);
194         if (errCode != 0) {
195             ShowIllegalArgsInfo(dumpInfo);
196         }
197     }
198     int ret = dprintf(fd, "%s\n", dumpInfo.c_str());
199     if (ret < 0) {
200         WLOGFE("dprintf error");
201         return -1; // WMError::WM_ERROR_INVALID_OPERATION;
202     }
203     WLOGI("dump end");
204     return 0;
205 }
206 
SetSessionManagerService(const sptr<IRemoteObject> & sessionManagerService)207 bool MockSessionManagerService::SetSessionManagerService(const sptr<IRemoteObject>& sessionManagerService)
208 {
209     if (!sessionManagerService) {
210         WLOGFE("sessionManagerService is nullptr");
211         return false;
212     }
213     currentWMSUserId_ = GetUserIdByCallingUid();
214     if (currentWMSUserId_ <= INVALID_USER_ID) {
215         TLOGE(WmsLogTag::WMS_MULTI_USER, "userId is illegal: %{public}d", currentWMSUserId_);
216         return false;
217     }
218     {
219         std::unique_lock<std::shared_mutex> lock(sessionManagerServiceMapLock_);
220         sessionManagerServiceMap_[currentWMSUserId_] = sessionManagerService;
221     }
222     auto smsDeathRecipient = GetSMSDeathRecipientByUserId(currentWMSUserId_);
223     if (!smsDeathRecipient) {
224         smsDeathRecipient = new SMSDeathRecipient(currentWMSUserId_);
225         std::unique_lock<std::shared_mutex> lock(smsDeathRecipientMapLock_);
226         if (!smsDeathRecipient) {
227             TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to create death Recipient ptr smsDeathRecipient");
228             return false;
229         }
230         smsDeathRecipientMap_[currentWMSUserId_] = smsDeathRecipient;
231     }
232     if (sessionManagerService->IsProxyObject() && !sessionManagerService->AddDeathRecipient(smsDeathRecipient)) {
233         TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to add death recipient");
234         return false;
235     }
236     RegisterMockSessionManagerService();
237     TLOGI(WmsLogTag::WMS_MULTI_USER, "sessionManagerService set success!");
238     system::SetParameter(BOOTEVENT_WMS_READY.c_str(), "true");
239     GetSceneSessionManager();
240 
241     return true;
242 }
243 
GetSMSDeathRecipientByUserId(int32_t userId)244 sptr<MockSessionManagerService::SMSDeathRecipient> MockSessionManagerService::GetSMSDeathRecipientByUserId(
245     int32_t userId)
246 {
247     std::shared_lock<std::shared_mutex> lock(smsDeathRecipientMapLock_);
248     auto iter = smsDeathRecipientMap_.find(userId);
249     if (iter != smsDeathRecipientMap_.end()) {
250         TLOGI(WmsLogTag::WMS_MULTI_USER, "Get SMS death recipient with userId=%{public}d", userId);
251         return iter->second;
252     } else {
253         TLOGW(WmsLogTag::WMS_MULTI_USER, "Get SMS death recipient failed with userId=%{public}d", userId);
254         return nullptr;
255     }
256 }
257 
RemoveSMSDeathRecipientByUserId(int32_t userId)258 void MockSessionManagerService::RemoveSMSDeathRecipientByUserId(int32_t userId)
259 {
260     TLOGI(WmsLogTag::WMS_MULTI_USER, "userId: %{public}d", userId);
261     auto sessionManagerService = GetSessionManagerServiceByUserId(userId);
262     std::unique_lock<std::shared_mutex> lock(smsDeathRecipientMapLock_);
263     auto iter = smsDeathRecipientMap_.find(userId);
264     if (iter != smsDeathRecipientMap_.end() && iter->second) {
265         if (sessionManagerService != nullptr) {
266             sessionManagerService->RemoveDeathRecipient(iter->second);
267         }
268     }
269 }
270 
GetSessionManagerService()271 sptr<IRemoteObject> MockSessionManagerService::GetSessionManagerService()
272 {
273     int32_t clientUserId = GetUserIdByCallingUid();
274     if (clientUserId <= INVALID_USER_ID) {
275         TLOGE(WmsLogTag::WMS_MULTI_USER, "userId is illegal: %{public}d", clientUserId);
276         return nullptr;
277     }
278     if (clientUserId == SYSTEM_USERID) {
279         TLOGI(WmsLogTag::WMS_MULTI_USER, "System user, return current sessionManagerService with %{public}d",
280             currentWMSUserId_);
281         clientUserId = currentWMSUserId_;
282     }
283     return GetSessionManagerServiceByUserId(clientUserId);
284 }
285 
GetSessionManagerServiceByUserId(int32_t userId)286 sptr<IRemoteObject> MockSessionManagerService::GetSessionManagerServiceByUserId(int32_t userId)
287 {
288     std::shared_lock<std::shared_mutex> lock(sessionManagerServiceMapLock_);
289     auto iter = sessionManagerServiceMap_.find(userId);
290     if (iter != sessionManagerServiceMap_.end()) {
291         TLOGD(WmsLogTag::WMS_MULTI_USER, "Get session manager service success with userId=%{public}d", userId);
292         return iter->second;
293     } else {
294         TLOGE(WmsLogTag::WMS_MULTI_USER, "Get session manager service failed with userId=%{public}d", userId);
295         return nullptr;
296     }
297 }
298 
RemoveSessionManagerServiceByUserId(int32_t userId)299 void MockSessionManagerService::RemoveSessionManagerServiceByUserId(int32_t userId)
300 {
301     TLOGI(WmsLogTag::WMS_MULTI_USER, "userId: %{public}d", userId);
302     std::unique_lock<std::shared_mutex> lock(sessionManagerServiceMapLock_);
303     auto iter = sessionManagerServiceMap_.find(userId);
304     if (iter != sessionManagerServiceMap_.end()) {
305         sessionManagerServiceMap_.erase(iter);
306     }
307 }
308 
NotifySceneBoardAvailable()309 void MockSessionManagerService::NotifySceneBoardAvailable()
310 {
311     if (!SessionPermission::IsSystemCalling()) {
312         TLOGE(WmsLogTag::WMS_RECOVER, "permission denied");
313         return;
314     }
315     int32_t userId = GetUserIdByCallingUid();
316     if (userId <= INVALID_USER_ID) {
317         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", userId);
318         return;
319     }
320     TLOGI(WmsLogTag::WMS_RECOVER, "scene board is available with userId=%{public}d", userId);
321 
322     NotifySceneBoardAvailableToLiteClient(SYSTEM_USERID);
323     NotifySceneBoardAvailableToLiteClient(userId);
324 
325     NotifySceneBoardAvailableToClient(SYSTEM_USERID);
326     NotifySceneBoardAvailableToClient(userId);
327 }
328 
RegisterSMSRecoverListener(const sptr<IRemoteObject> & listener)329 void MockSessionManagerService::RegisterSMSRecoverListener(const sptr<IRemoteObject>& listener)
330 {
331     if (listener == nullptr) {
332         TLOGE(WmsLogTag::WMS_RECOVER, "listener is nullptr");
333         return;
334     }
335 
336     int32_t clientUserId = GetUserIdByCallingUid();
337     if (clientUserId <= INVALID_USER_ID) {
338         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", clientUserId);
339         return;
340     }
341     int32_t pid = IPCSkeleton::GetCallingRealPid();
342     TLOGI(WmsLogTag::WMS_RECOVER, "clientUserId = %{public}d, pid = %{public}d", clientUserId, pid);
343     sptr<ClientListenerDeathRecipient> clientDeathListener = new ClientListenerDeathRecipient(clientUserId, pid, false);
344     listener->AddDeathRecipient(clientDeathListener);
345     sptr<ISessionManagerServiceRecoverListener> smsListener;
346     {
347         std::unique_lock<std::shared_mutex> lock(smsRecoverListenerLock_);
348         smsListener = iface_cast<ISessionManagerServiceRecoverListener>(listener);
349         smsRecoverListenerMap_[clientUserId][pid] = smsListener;
350     }
351     if (clientUserId != SYSTEM_USERID) {
352         return;
353     }
354     bool isWMSConnected = false;
355     {
356         std::lock_guard<std::mutex> lock(wmsConnectionStatusLock_);
357         if (wmsConnectionStatusMap_.find(currentWMSUserId_) != wmsConnectionStatusMap_.end()) {
358             isWMSConnected = wmsConnectionStatusMap_[currentWMSUserId_];
359         }
360     }
361     if (smsListener && isWMSConnected) {
362         auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
363         if (sessionManagerService == nullptr) {
364             TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
365             return;
366         }
367         TLOGI(WmsLogTag::WMS_RECOVER, "WMS is already connected, notify client");
368         smsListener->OnWMSConnectionChanged(currentWMSUserId_, currentScreenId_, true, sessionManagerService);
369     }
370 }
371 
GetSMSRecoverListenerMap(int32_t userId)372 std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* MockSessionManagerService::GetSMSRecoverListenerMap(
373     int32_t userId)
374 {
375     auto iter = smsRecoverListenerMap_.find(userId);
376     if (iter != smsRecoverListenerMap_.end()) {
377         return &iter->second;
378     }
379     return nullptr;
380 }
381 
UnregisterSMSRecoverListener()382 void MockSessionManagerService::UnregisterSMSRecoverListener()
383 {
384     int32_t clientUserId = GetUserIdByCallingUid();
385     if (clientUserId <= INVALID_USER_ID) {
386         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", clientUserId);
387         return;
388     }
389     int32_t pid = IPCSkeleton::GetCallingRealPid();
390     TLOGD(WmsLogTag::WMS_RECOVER, "clientUserId = %{public}d, pid = %{public}d", clientUserId, pid);
391     UnregisterSMSRecoverListener(clientUserId, pid);
392 }
393 
UnregisterSMSRecoverListener(int32_t userId,int32_t pid)394 void MockSessionManagerService::UnregisterSMSRecoverListener(int32_t userId, int32_t pid)
395 {
396     TLOGD(WmsLogTag::WMS_RECOVER, "userId = %{public}d, pid = %{public}d", userId, pid);
397     std::unique_lock<std::shared_mutex> lock(smsRecoverListenerLock_);
398     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsRecoverListenerMap =
399         GetSMSRecoverListenerMap(userId);
400     if (!smsRecoverListenerMap) {
401         TLOGW(WmsLogTag::WMS_RECOVER, "smsRecoverListenerMap is null");
402         return;
403     }
404     auto iter = smsRecoverListenerMap->find(pid);
405     if (iter != smsRecoverListenerMap->end()) {
406         smsRecoverListenerMap->erase(iter);
407     }
408 }
409 
NotifySceneBoardAvailableToClient(int32_t userId)410 void MockSessionManagerService::NotifySceneBoardAvailableToClient(int32_t userId)
411 {
412     std::shared_lock<std::shared_mutex> lock(smsRecoverListenerLock_);
413     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsRecoverListenerMap =
414         GetSMSRecoverListenerMap(userId);
415     if (!smsRecoverListenerMap) {
416         TLOGW(WmsLogTag::WMS_RECOVER, "smsRecoverListenerMap is null");
417         return;
418     }
419     TLOGI(WmsLogTag::WMS_RECOVER, "userId=%{public}d, Remote process count = %{public}" PRIu64, userId,
420         static_cast<uint64_t>(smsRecoverListenerMap->size()));
421     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
422     if (sessionManagerService == nullptr) {
423         TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
424         return;
425     }
426     for (auto& iter : *smsRecoverListenerMap) {
427         if (iter.second != nullptr) {
428             TLOGI(WmsLogTag::WMS_RECOVER, "Call OnSessionManagerServiceRecover pid = %{public}d", iter.first);
429             iter.second->OnSessionManagerServiceRecover(sessionManagerService);
430         }
431     }
432 }
433 
RegisterSMSLiteRecoverListener(const sptr<IRemoteObject> & listener)434 void MockSessionManagerService::RegisterSMSLiteRecoverListener(const sptr<IRemoteObject>& listener)
435 {
436     if (listener == nullptr) {
437         TLOGE(WmsLogTag::WMS_RECOVER, "Lite listener is nullptr");
438         return;
439     }
440     int32_t clientUserId = GetUserIdByCallingUid();
441     if (clientUserId <= INVALID_USER_ID) {
442         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", clientUserId);
443         return;
444     }
445     int32_t pid = IPCSkeleton::GetCallingRealPid();
446     TLOGI(WmsLogTag::WMS_RECOVER, "clientUserId = %{public}d, pid = %{public}d", clientUserId, pid);
447     sptr<ClientListenerDeathRecipient> clientDeathListener = new ClientListenerDeathRecipient(clientUserId, pid, true);
448     listener->AddDeathRecipient(clientDeathListener);
449     sptr<ISessionManagerServiceRecoverListener> smsListener;
450     {
451         std::unique_lock<std::shared_mutex> lock(smsLiteRecoverListenerLock_);
452         smsListener = iface_cast<ISessionManagerServiceRecoverListener>(listener);
453         smsLiteRecoverListenerMap_[clientUserId][pid] = smsListener;
454     }
455     if (clientUserId != SYSTEM_USERID) {
456         return;
457     }
458     bool isWMSConnected = false;
459     {
460         std::lock_guard<std::mutex> lock(wmsConnectionStatusLock_);
461         if (wmsConnectionStatusMap_.find(currentWMSUserId_) != wmsConnectionStatusMap_.end()) {
462             isWMSConnected = wmsConnectionStatusMap_[currentWMSUserId_];
463         }
464     }
465     if (smsListener && isWMSConnected) {
466         auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
467         if (sessionManagerService == nullptr) {
468             TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
469             return;
470         }
471         TLOGI(WmsLogTag::WMS_MULTI_USER, "Lite wms is already connected, notify client");
472         smsListener->OnWMSConnectionChanged(currentWMSUserId_, currentScreenId_, true, sessionManagerService);
473     }
474 }
475 
GetSMSLiteRecoverListenerMap(int32_t userId)476 std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* MockSessionManagerService::GetSMSLiteRecoverListenerMap(
477     int32_t userId)
478 {
479     auto iter = smsLiteRecoverListenerMap_.find(userId);
480     if (iter != smsLiteRecoverListenerMap_.end()) {
481         return &iter->second;
482     }
483     return nullptr;
484 }
485 
UnregisterSMSLiteRecoverListener()486 void MockSessionManagerService::UnregisterSMSLiteRecoverListener()
487 {
488     int32_t clientUserId = GetUserIdByCallingUid();
489     if (clientUserId <= INVALID_USER_ID) {
490         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", clientUserId);
491         return;
492     }
493     int32_t pid = IPCSkeleton::GetCallingRealPid();
494     TLOGD(WmsLogTag::WMS_RECOVER, "clientUserId = %{public}d, pid = %{public}d", clientUserId, pid);
495     UnregisterSMSLiteRecoverListener(clientUserId, pid);
496 }
497 
UnregisterSMSLiteRecoverListener(int32_t userId,int32_t pid)498 void MockSessionManagerService::UnregisterSMSLiteRecoverListener(int32_t userId, int32_t pid)
499 {
500     TLOGD(WmsLogTag::WMS_RECOVER, "userId = %{public}d, pid = %{public}d", userId, pid);
501     std::unique_lock<std::shared_mutex> lock(smsLiteRecoverListenerLock_);
502     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsLiteRecoverListenerMap =
503         GetSMSLiteRecoverListenerMap(userId);
504     if (!smsLiteRecoverListenerMap) {
505         return;
506     }
507     auto iter = smsLiteRecoverListenerMap->find(pid);
508     if (iter != smsLiteRecoverListenerMap->end()) {
509         smsLiteRecoverListenerMap->erase(iter);
510     }
511 }
512 
NotifySceneBoardAvailableToLiteClient(int32_t userId)513 void MockSessionManagerService::NotifySceneBoardAvailableToLiteClient(int32_t userId)
514 {
515     std::shared_lock<std::shared_mutex> lock(smsLiteRecoverListenerLock_);
516     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsLiteRecoverListenerMap =
517         GetSMSLiteRecoverListenerMap(userId);
518     if (!smsLiteRecoverListenerMap) {
519         return;
520     }
521     TLOGI(WmsLogTag::WMS_RECOVER, "userId=%{public}d, Remote process count = %{public}" PRIu64, userId,
522         static_cast<uint64_t>(smsLiteRecoverListenerMap->size()));
523     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
524     if (sessionManagerService == nullptr) {
525         TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
526         return;
527     }
528     for (auto& iter : *smsLiteRecoverListenerMap) {
529         if (iter.second != nullptr) {
530             TLOGI(WmsLogTag::WMS_RECOVER,
531                 "Call OnSessionManagerServiceRecover Lite pid = %{public}d, ref count = %{public}" PRId32, iter.first,
532                 iter.second->GetSptrRefCount());
533             iter.second->OnSessionManagerServiceRecover(sessionManagerService);
534         }
535     }
536 }
537 
NotifyWMSConnected(int32_t userId,int32_t screenId,bool isColdStart)538 void MockSessionManagerService::NotifyWMSConnected(int32_t userId, int32_t screenId, bool isColdStart)
539 {
540     TLOGI(WmsLogTag::WMS_MULTI_USER, "userId = %{public}d, screenId = %{public}d, isColdStart = %{public}d", userId,
541         screenId, isColdStart);
542     currentScreenId_ = screenId;
543     currentWMSUserId_ = userId;
544     auto smsDeathRecipient = GetSMSDeathRecipientByUserId(currentWMSUserId_);
545     if (smsDeathRecipient != nullptr) {
546         smsDeathRecipient->SetScreenId(screenId);
547     }
548     if (!isColdStart) {
549         TLOGI(WmsLogTag::WMS_MULTI_USER, "User switched");
550         GetSceneSessionManager();
551     }
552     NotifyWMSConnectionChanged(userId, screenId, true);
553 }
554 
NotifyWMSConnectionChanged(int32_t wmsUserId,int32_t screenId,bool isConnected)555 void MockSessionManagerService::NotifyWMSConnectionChanged(int32_t wmsUserId, int32_t screenId, bool isConnected)
556 {
557     TLOGI(WmsLogTag::WMS_MULTI_USER, "wmsUserId = %{public}d, isConnected = %{public}d", wmsUserId, isConnected);
558     {
559         std::lock_guard<std::mutex> lock(wmsConnectionStatusLock_);
560         wmsConnectionStatusMap_[wmsUserId] = isConnected;
561     }
562     NotifyWMSConnectionChangedToLiteClient(wmsUserId, screenId, isConnected);
563     NotifyWMSConnectionChangedToClient(wmsUserId, screenId, isConnected);
564 }
565 
NotifyWMSConnectionChangedToClient(int32_t wmsUserId,int32_t screenId,bool isConnected)566 void MockSessionManagerService::NotifyWMSConnectionChangedToClient(
567     int32_t wmsUserId, int32_t screenId, bool isConnected)
568 {
569     std::shared_lock<std::shared_mutex> lock(smsRecoverListenerLock_);
570     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsRecoverListenerMap =
571         GetSMSRecoverListenerMap(SYSTEM_USERID);
572     if (!smsRecoverListenerMap) {
573         TLOGW(WmsLogTag::WMS_MULTI_USER, "smsRecoverListenerMap is null");
574         return;
575     }
576     TLOGD(WmsLogTag::WMS_MULTI_USER,
577         "wmsUserId = %{public}d, isConnected = %{public}d, remote process count = "
578         "%{public}" PRIu64,
579         wmsUserId, isConnected, static_cast<uint64_t>(smsRecoverListenerMap->size()));
580     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
581     if (sessionManagerService == nullptr) {
582         TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
583         return;
584     }
585     for (auto& iter : *smsRecoverListenerMap) {
586         if (iter.second != nullptr) {
587             TLOGI(WmsLogTag::WMS_MULTI_USER, "Call OnWMSConnectionChanged pid = %{public}d", iter.first);
588             iter.second->OnWMSConnectionChanged(wmsUserId, screenId, isConnected, sessionManagerService);
589         }
590     }
591 }
592 
NotifyWMSConnectionChangedToLiteClient(int32_t wmsUserId,int32_t screenId,bool isConnected)593 void MockSessionManagerService::NotifyWMSConnectionChangedToLiteClient(
594     int32_t wmsUserId, int32_t screenId, bool isConnected)
595 {
596     std::shared_lock<std::shared_mutex> lock(smsLiteRecoverListenerLock_);
597     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsLiteRecoverListenerMap =
598         GetSMSLiteRecoverListenerMap(SYSTEM_USERID);
599     if (!smsLiteRecoverListenerMap) {
600         return;
601     }
602     TLOGD(WmsLogTag::WMS_MULTI_USER, "wmsUserId = %{public}d, isConnected = %{public}d", wmsUserId, isConnected);
603     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
604     if (sessionManagerService == nullptr) {
605         TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
606         return;
607     }
608     for (auto& iter : *smsLiteRecoverListenerMap) {
609         if (iter.second != nullptr) {
610             TLOGI(WmsLogTag::WMS_MULTI_USER,
611                 "Call OnWMSConnectionChanged Lite pid = %{public}d, ref count = %{public}d", iter.first,
612                 iter.second->GetSptrRefCount());
613             iter.second->OnWMSConnectionChanged(wmsUserId, screenId, isConnected, sessionManagerService);
614         }
615     }
616 }
617 
GetScreenSessionManagerLite()618 sptr<IRemoteObject> MockSessionManagerService::GetScreenSessionManagerLite()
619 {
620     if (screenSessionManager_) {
621         return screenSessionManager_;
622     }
623     screenSessionManager_ = ScreenSessionManagerLite::GetInstance().AsObject();
624     return screenSessionManager_;
625 }
626 
ShowIllegalArgsInfo(std::string & dumpInfo)627 void MockSessionManagerService::ShowIllegalArgsInfo(std::string& dumpInfo)
628 {
629     dumpInfo.append("The arguments are illegal and you can enter '-h' for help.");
630 }
631 
GetSceneSessionManager()632 sptr<IRemoteObject> MockSessionManagerService::GetSceneSessionManager()
633 {
634     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
635     if (sessionManagerService == nullptr) {
636         WLOGFE("SessionManagerService is null");
637         return nullptr;
638     }
639     sptr<ISessionManagerService> sessionManagerServiceProxy = iface_cast<ISessionManagerService>(sessionManagerService);
640     if (!sessionManagerServiceProxy) {
641         WLOGFE("sessionManagerServiceProxy is nullptr");
642         return nullptr;
643     }
644     sptr<IRemoteObject> remoteObject = sessionManagerServiceProxy->GetSceneSessionManager();
645     if (!remoteObject) {
646         WLOGFW("Get scene session manager proxy failed, scene session manager service is null");
647         return sptr<IRemoteObject>(nullptr);
648     }
649     sceneSessionManager_ = remoteObject;
650     return sceneSessionManager_;
651 }
652 
DumpSessionInfo(const std::vector<std::string> & args,std::string & dumpInfo)653 int MockSessionManagerService::DumpSessionInfo(const std::vector<std::string>& args, std::string& dumpInfo)
654 {
655     if (args.empty()) {
656         return -1;  // WMError::WM_ERROR_INVALID_PARAM;
657     }
658     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
659     if (sessionManagerService == nullptr) {
660         WLOGFE("sessionManagerService is nullptr");
661         return -1;
662     }
663     if (!sceneSessionManager_) {
664         WLOGFW("Get scene session manager ...");
665         GetSceneSessionManager();
666         if (!sceneSessionManager_) {
667             WLOGFW("Get scene session manager proxy failed, nullptr");
668             return -1;
669         }
670     }
671     sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(sceneSessionManager_);
672     WSError ret = sceneSessionManagerProxy->GetSessionDumpInfo(args, dumpInfo);
673     if (ret != WSError::WS_OK) {
674         WLOGFD("sessionManagerService set success!");
675         return -1;
676     }
677     return 0; // WMError::WM_OK;
678 }
679 
ShowHelpInfo(std::string & dumpInfo)680 void MockSessionManagerService::ShowHelpInfo(std::string& dumpInfo)
681 {
682     dumpInfo.append("Usage:\n")
683         .append(" -h                             ")
684         .append("|help text for the tool\n")
685         .append(" -a                             ")
686         .append("|dump all window information in the system\n")
687         .append(" -w {window id} [ArkUI Option]  ")
688         .append("|dump specified window information\n")
689         .append(" ------------------------------------[ArkUI Option]------------------------------------ \n");
690     ShowAceDumpHelp(dumpInfo);
691 }
692 
ShowAceDumpHelp(std::string & dumpInfo)693 void MockSessionManagerService::ShowAceDumpHelp(std::string& dumpInfo)
694 {
695 }
696 
IsSceneBoardTestMode()697 bool MockSessionManagerService::SMSDeathRecipient::IsSceneBoardTestMode()
698 {
699     if (!OHOS::system::GetBoolParameter(KEY_SCENE_BOARD_TEST_ENABLE, false)) {
700         WLOGFD("SceneBoard testmode is disabled.");
701         return false;
702     }
703     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
704     if (systemAbilityMgr == nullptr) {
705         WLOGFE("Failed to get SystemAbilityManager.");
706         return false;
707     }
708 
709     auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
710     if (bmsObj == nullptr) {
711         WLOGFE("Failed to get BundleManagerService.");
712         return false;
713     }
714     sptr<AppExecFwk::IBundleMgr> bundleMgr_ = iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
715     AppExecFwk::BundleInfo bundleInfo;
716     int uid = IPCSkeleton::GetCallingUid();
717     int userId = uid / 200000;
718     bool result = bundleMgr_->GetBundleInfo(SCENE_BOARD_BUNDLE_NAME,
719         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId);
720     if (!result) {
721         WLOGFE("Failed to query bundleInfo, userId:%{public}d", userId);
722         return true;
723     }
724     auto hapModulesList = bundleInfo.hapModuleInfos;
725     if (hapModulesList.empty()) {
726         WLOGFE("hapModulesList is empty");
727         return false;
728     }
729     std::string suffix = TEST_MODULE_NAME_SUFFIX;
730     for (auto hapModule: hapModulesList) {
731         std::string moduleName = hapModule.moduleName;
732         if (moduleName.length() < suffix.length()) {
733             continue;
734         }
735         if (moduleName.compare(moduleName.length() - suffix.length(), suffix.length(), suffix) == 0) {
736             WLOGFI("Found test module name: %{public}s", moduleName.c_str());
737             return true;
738         }
739     }
740     return false;
741 }
742 
WriteStringToFile(int32_t pid,const char * str)743 void MockSessionManagerService::WriteStringToFile(int32_t pid, const char* str)
744 {
745     char file[PATH_LEN] = {0};
746     if (snprintf_s(file, PATH_LEN, PATH_LEN - 1, "/proc/%d/unexpected_die_catch", pid) == -1) {
747         WLOGFI("failed to build path for %d.", pid);
748     }
749     int fd = open(file, O_RDWR);
750     if (fd == -1) {
751         return;
752     }
753     if (write(fd, str, strlen(str)) < 0) {
754         WLOGFI("failed to write 0 for %s", file);
755         close(fd);
756         return;
757     }
758     close(fd);
759 }
760 
GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,const std::vector<uint64_t> & windowIdList,std::vector<uint64_t> & surfaceNodeIds)761 void MockSessionManagerService::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
762     const std::vector<uint64_t>& windowIdList, std::vector<uint64_t>& surfaceNodeIds)
763 {
764     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
765     if (sessionManagerService == nullptr) {
766         WLOGFE("sessionManagerService is nullptr");
767         return;
768     }
769     if (!sceneSessionManager_) {
770         WLOGFW("Get scene session manager ...");
771         GetSceneSessionManager();
772         if (!sceneSessionManager_) {
773             WLOGFW("Get scene session manager proxy failed, nullptr");
774             return;
775         }
776     }
777     if (windowIdList.empty()) {
778         TLOGE(WmsLogTag::DEFAULT, "windowIdList is null, no need to get surfaceNodeId");
779         return;
780     }
781     std::vector<int32_t> persistentIds(windowIdList.size());
782     std::transform(windowIdList.begin(), windowIdList.end(),
783         persistentIds.begin(), [](uint64_t id) { return static_cast<int32_t>(id); });
784     sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(sceneSessionManager_);
785     WMError ret = sceneSessionManagerProxy->GetProcessSurfaceNodeIdByPersistentId(
786         pid, persistentIds, surfaceNodeIds);
787     if (ret != WMError::WM_OK) {
788         TLOGE(WmsLogTag::DEFAULT, "Get process surfaceNodeId by persistentId failed!");
789     }
790 }
791 } // namespace Rosen
792 } // namespace OHOS