• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     TLOGD(WmsLogTag::DEFAULT, "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 = write(fd, dumpInfo.c_str(), dumpInfo.length());
199     if (ret < 0) {
200         WLOGFE("write error");
201         return -1; // WMError::WM_ERROR_INVALID_OPERATION;
202     }
203     TLOGD(WmsLogTag::DEFAULT, "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     RecoverSCBSnapshotSkipByUserId(currentWMSUserId_);
223     auto smsDeathRecipient = GetSMSDeathRecipientByUserId(currentWMSUserId_);
224     if (!smsDeathRecipient) {
225         smsDeathRecipient = new SMSDeathRecipient(currentWMSUserId_);
226         std::unique_lock<std::shared_mutex> lock(smsDeathRecipientMapLock_);
227         if (!smsDeathRecipient) {
228             TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to create death Recipient ptr smsDeathRecipient");
229             return false;
230         }
231         smsDeathRecipientMap_[currentWMSUserId_] = smsDeathRecipient;
232     }
233     if (sessionManagerService->IsProxyObject() && !sessionManagerService->AddDeathRecipient(smsDeathRecipient)) {
234         TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to add death recipient");
235         return false;
236     }
237     RegisterMockSessionManagerService();
238     TLOGI(WmsLogTag::WMS_MULTI_USER, "sessionManagerService set success!");
239     system::SetParameter(BOOTEVENT_WMS_READY.c_str(), "true");
240     GetSceneSessionManager();
241 
242     return true;
243 }
244 
GetSMSDeathRecipientByUserId(int32_t userId)245 sptr<MockSessionManagerService::SMSDeathRecipient> MockSessionManagerService::GetSMSDeathRecipientByUserId(
246     int32_t userId)
247 {
248     std::shared_lock<std::shared_mutex> lock(smsDeathRecipientMapLock_);
249     auto iter = smsDeathRecipientMap_.find(userId);
250     if (iter != smsDeathRecipientMap_.end()) {
251         TLOGD(WmsLogTag::WMS_MULTI_USER, "Get SMS death recipient with userId=%{public}d", userId);
252         return iter->second;
253     } else {
254         TLOGW(WmsLogTag::WMS_MULTI_USER, "Get SMS death recipient failed with userId=%{public}d", userId);
255         return nullptr;
256     }
257 }
258 
RemoveSMSDeathRecipientByUserId(int32_t userId)259 void MockSessionManagerService::RemoveSMSDeathRecipientByUserId(int32_t userId)
260 {
261     TLOGI(WmsLogTag::WMS_MULTI_USER, "userId: %{public}d", userId);
262     auto sessionManagerService = GetSessionManagerServiceByUserId(userId);
263     std::unique_lock<std::shared_mutex> lock(smsDeathRecipientMapLock_);
264     auto iter = smsDeathRecipientMap_.find(userId);
265     if (iter != smsDeathRecipientMap_.end() && iter->second) {
266         if (sessionManagerService != nullptr) {
267             sessionManagerService->RemoveDeathRecipient(iter->second);
268         }
269     }
270 }
271 
GetSessionManagerService()272 sptr<IRemoteObject> MockSessionManagerService::GetSessionManagerService()
273 {
274     int32_t clientUserId = GetUserIdByCallingUid();
275     if (clientUserId <= INVALID_USER_ID) {
276         TLOGE(WmsLogTag::WMS_MULTI_USER, "userId is illegal: %{public}d", clientUserId);
277         return nullptr;
278     }
279     if (clientUserId == SYSTEM_USERID) {
280         TLOGD(WmsLogTag::WMS_MULTI_USER, "System user, return current sessionManagerService with %{public}d",
281               currentWMSUserId_);
282         clientUserId = currentWMSUserId_;
283     }
284     return GetSessionManagerServiceByUserId(clientUserId);
285 }
286 
GetSessionManagerServiceByUserId(int32_t userId)287 sptr<IRemoteObject> MockSessionManagerService::GetSessionManagerServiceByUserId(int32_t userId)
288 {
289     std::shared_lock<std::shared_mutex> lock(sessionManagerServiceMapLock_);
290     auto iter = sessionManagerServiceMap_.find(userId);
291     if (iter != sessionManagerServiceMap_.end()) {
292         TLOGD(WmsLogTag::WMS_MULTI_USER, "Get session manager service success with userId=%{public}d", userId);
293         return iter->second;
294     } else {
295         TLOGE(WmsLogTag::WMS_MULTI_USER, "Get session manager service failed with userId=%{public}d", userId);
296         return nullptr;
297     }
298 }
299 
RemoveSessionManagerServiceByUserId(int32_t userId)300 void MockSessionManagerService::RemoveSessionManagerServiceByUserId(int32_t userId)
301 {
302     TLOGI(WmsLogTag::WMS_MULTI_USER, "userId: %{public}d", userId);
303     std::unique_lock<std::shared_mutex> lock(sessionManagerServiceMapLock_);
304     auto iter = sessionManagerServiceMap_.find(userId);
305     if (iter != sessionManagerServiceMap_.end()) {
306         sessionManagerServiceMap_.erase(iter);
307     }
308 }
309 
NotifySceneBoardAvailable()310 void MockSessionManagerService::NotifySceneBoardAvailable()
311 {
312     if (!SessionPermission::IsSystemCalling()) {
313         TLOGE(WmsLogTag::WMS_RECOVER, "permission denied");
314         return;
315     }
316     int32_t userId = GetUserIdByCallingUid();
317     if (userId <= INVALID_USER_ID) {
318         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", userId);
319         return;
320     }
321     TLOGI(WmsLogTag::WMS_RECOVER, "scene board is available with userId=%{public}d", userId);
322 
323     NotifySceneBoardAvailableToLiteClient(SYSTEM_USERID);
324     NotifySceneBoardAvailableToLiteClient(userId);
325 
326     NotifySceneBoardAvailableToClient(SYSTEM_USERID);
327     NotifySceneBoardAvailableToClient(userId);
328 }
329 
RegisterSMSRecoverListener(const sptr<IRemoteObject> & listener)330 void MockSessionManagerService::RegisterSMSRecoverListener(const sptr<IRemoteObject>& listener)
331 {
332     if (listener == nullptr) {
333         TLOGE(WmsLogTag::WMS_RECOVER, "listener is nullptr");
334         return;
335     }
336 
337     int32_t clientUserId = GetUserIdByCallingUid();
338     if (clientUserId <= INVALID_USER_ID) {
339         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", clientUserId);
340         return;
341     }
342     int32_t pid = IPCSkeleton::GetCallingRealPid();
343     TLOGI(WmsLogTag::WMS_RECOVER, "clientUserId = %{public}d, pid = %{public}d", clientUserId, pid);
344     sptr<ClientListenerDeathRecipient> clientDeathListener = new ClientListenerDeathRecipient(clientUserId, pid, false);
345     listener->AddDeathRecipient(clientDeathListener);
346     sptr<ISessionManagerServiceRecoverListener> smsListener;
347     {
348         std::unique_lock<std::shared_mutex> lock(smsRecoverListenerLock_);
349         smsListener = iface_cast<ISessionManagerServiceRecoverListener>(listener);
350         smsRecoverListenerMap_[clientUserId][pid] = smsListener;
351     }
352     if (clientUserId != SYSTEM_USERID) {
353         return;
354     }
355     bool isWMSConnected = false;
356     {
357         std::lock_guard<std::mutex> lock(wmsConnectionStatusLock_);
358         if (wmsConnectionStatusMap_.find(currentWMSUserId_) != wmsConnectionStatusMap_.end()) {
359             isWMSConnected = wmsConnectionStatusMap_[currentWMSUserId_];
360         }
361     }
362     if (smsListener && isWMSConnected) {
363         auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
364         if (sessionManagerService == nullptr) {
365             TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
366             return;
367         }
368         TLOGI(WmsLogTag::WMS_RECOVER, "WMS ready,notify client");
369         smsListener->OnWMSConnectionChanged(currentWMSUserId_, currentScreenId_, true, sessionManagerService);
370     }
371 }
372 
GetSMSRecoverListenerMap(int32_t userId)373 std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* MockSessionManagerService::GetSMSRecoverListenerMap(
374     int32_t userId)
375 {
376     auto iter = smsRecoverListenerMap_.find(userId);
377     if (iter != smsRecoverListenerMap_.end()) {
378         return &iter->second;
379     }
380     return nullptr;
381 }
382 
UnregisterSMSRecoverListener()383 void MockSessionManagerService::UnregisterSMSRecoverListener()
384 {
385     int32_t clientUserId = GetUserIdByCallingUid();
386     if (clientUserId <= INVALID_USER_ID) {
387         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", clientUserId);
388         return;
389     }
390     int32_t pid = IPCSkeleton::GetCallingRealPid();
391     TLOGD(WmsLogTag::WMS_RECOVER, "clientUserId = %{public}d, pid = %{public}d", clientUserId, pid);
392     UnregisterSMSRecoverListener(clientUserId, pid);
393 }
394 
UnregisterSMSRecoverListener(int32_t userId,int32_t pid)395 void MockSessionManagerService::UnregisterSMSRecoverListener(int32_t userId, int32_t pid)
396 {
397     TLOGD(WmsLogTag::WMS_RECOVER, "userId = %{public}d, pid = %{public}d", userId, pid);
398     std::unique_lock<std::shared_mutex> lock(smsRecoverListenerLock_);
399     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsRecoverListenerMap =
400         GetSMSRecoverListenerMap(userId);
401     if (!smsRecoverListenerMap) {
402         TLOGW(WmsLogTag::WMS_RECOVER, "smsRecoverListenerMap is null");
403         return;
404     }
405     auto iter = smsRecoverListenerMap->find(pid);
406     if (iter != smsRecoverListenerMap->end()) {
407         smsRecoverListenerMap->erase(iter);
408     }
409 }
410 
NotifySceneBoardAvailableToClient(int32_t userId)411 void MockSessionManagerService::NotifySceneBoardAvailableToClient(int32_t userId)
412 {
413     std::shared_lock<std::shared_mutex> lock(smsRecoverListenerLock_);
414     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsRecoverListenerMap =
415         GetSMSRecoverListenerMap(userId);
416     if (!smsRecoverListenerMap) {
417         TLOGW(WmsLogTag::WMS_RECOVER, "smsRecoverListenerMap is null");
418         return;
419     }
420     TLOGI(WmsLogTag::WMS_RECOVER, "userId=%{public}d, Remote process count = %{public}" PRIu64, userId,
421         static_cast<uint64_t>(smsRecoverListenerMap->size()));
422     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
423     if (sessionManagerService == nullptr) {
424         TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
425         return;
426     }
427     for (auto& iter : *smsRecoverListenerMap) {
428         if (iter.second != nullptr) {
429             TLOGI(WmsLogTag::WMS_RECOVER, "Call OnSessionManagerServiceRecover pid = %{public}d", iter.first);
430             iter.second->OnSessionManagerServiceRecover(sessionManagerService);
431         }
432     }
433 }
434 
RegisterSMSLiteRecoverListener(const sptr<IRemoteObject> & listener)435 void MockSessionManagerService::RegisterSMSLiteRecoverListener(const sptr<IRemoteObject>& listener)
436 {
437     if (listener == nullptr) {
438         TLOGE(WmsLogTag::WMS_RECOVER, "Lite listener is nullptr");
439         return;
440     }
441     int32_t clientUserId = GetUserIdByCallingUid();
442     if (clientUserId <= INVALID_USER_ID) {
443         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", clientUserId);
444         return;
445     }
446     int32_t pid = IPCSkeleton::GetCallingRealPid();
447     TLOGI(WmsLogTag::WMS_RECOVER, "clientUserId = %{public}d, pid = %{public}d", clientUserId, pid);
448     sptr<ClientListenerDeathRecipient> clientDeathListener = new ClientListenerDeathRecipient(clientUserId, pid, true);
449     listener->AddDeathRecipient(clientDeathListener);
450     sptr<ISessionManagerServiceRecoverListener> smsListener;
451     {
452         std::unique_lock<std::shared_mutex> lock(smsLiteRecoverListenerLock_);
453         smsListener = iface_cast<ISessionManagerServiceRecoverListener>(listener);
454         smsLiteRecoverListenerMap_[clientUserId][pid] = smsListener;
455     }
456     if (clientUserId != SYSTEM_USERID) {
457         return;
458     }
459     bool isWMSConnected = false;
460     {
461         std::lock_guard<std::mutex> lock(wmsConnectionStatusLock_);
462         if (wmsConnectionStatusMap_.find(currentWMSUserId_) != wmsConnectionStatusMap_.end()) {
463             isWMSConnected = wmsConnectionStatusMap_[currentWMSUserId_];
464         }
465     }
466     if (smsListener && isWMSConnected) {
467         auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
468         if (sessionManagerService == nullptr) {
469             TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
470             return;
471         }
472         TLOGD(WmsLogTag::WMS_MULTI_USER, "Lite wms is already connected, notify client");
473         smsListener->OnWMSConnectionChanged(currentWMSUserId_, currentScreenId_, true, sessionManagerService);
474     }
475 }
476 
GetSMSLiteRecoverListenerMap(int32_t userId)477 std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* MockSessionManagerService::GetSMSLiteRecoverListenerMap(
478     int32_t userId)
479 {
480     auto iter = smsLiteRecoverListenerMap_.find(userId);
481     if (iter != smsLiteRecoverListenerMap_.end()) {
482         return &iter->second;
483     }
484     return nullptr;
485 }
486 
UnregisterSMSLiteRecoverListener()487 void MockSessionManagerService::UnregisterSMSLiteRecoverListener()
488 {
489     int32_t clientUserId = GetUserIdByCallingUid();
490     if (clientUserId <= INVALID_USER_ID) {
491         TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", clientUserId);
492         return;
493     }
494     int32_t pid = IPCSkeleton::GetCallingRealPid();
495     TLOGD(WmsLogTag::WMS_RECOVER, "clientUserId = %{public}d, pid = %{public}d", clientUserId, pid);
496     UnregisterSMSLiteRecoverListener(clientUserId, pid);
497 }
498 
UnregisterSMSLiteRecoverListener(int32_t userId,int32_t pid)499 void MockSessionManagerService::UnregisterSMSLiteRecoverListener(int32_t userId, int32_t pid)
500 {
501     TLOGD(WmsLogTag::WMS_RECOVER, "userId = %{public}d, pid = %{public}d", userId, pid);
502     std::unique_lock<std::shared_mutex> lock(smsLiteRecoverListenerLock_);
503     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsLiteRecoverListenerMap =
504         GetSMSLiteRecoverListenerMap(userId);
505     if (!smsLiteRecoverListenerMap) {
506         return;
507     }
508     auto iter = smsLiteRecoverListenerMap->find(pid);
509     if (iter != smsLiteRecoverListenerMap->end()) {
510         smsLiteRecoverListenerMap->erase(iter);
511     }
512 }
513 
NotifySceneBoardAvailableToLiteClient(int32_t userId)514 void MockSessionManagerService::NotifySceneBoardAvailableToLiteClient(int32_t userId)
515 {
516     std::shared_lock<std::shared_mutex> lock(smsLiteRecoverListenerLock_);
517     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsLiteRecoverListenerMap =
518         GetSMSLiteRecoverListenerMap(userId);
519     if (!smsLiteRecoverListenerMap) {
520         return;
521     }
522     TLOGI(WmsLogTag::WMS_RECOVER, "userId=%{public}d, Remote process count = %{public}" PRIu64, userId,
523         static_cast<uint64_t>(smsLiteRecoverListenerMap->size()));
524     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
525     if (sessionManagerService == nullptr) {
526         TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
527         return;
528     }
529     for (auto& iter : *smsLiteRecoverListenerMap) {
530         if (iter.second != nullptr) {
531             TLOGI(WmsLogTag::WMS_RECOVER,
532                 "Call OnSessionManagerServiceRecover Lite pid = %{public}d, ref count = %{public}" PRId32, iter.first,
533                 iter.second->GetSptrRefCount());
534             iter.second->OnSessionManagerServiceRecover(sessionManagerService);
535         }
536     }
537 }
538 
NotifyWMSConnected(int32_t userId,int32_t screenId,bool isColdStart)539 void MockSessionManagerService::NotifyWMSConnected(int32_t userId, int32_t screenId, bool isColdStart)
540 {
541     TLOGI(WmsLogTag::WMS_MULTI_USER, "userId = %{public}d, screenId = %{public}d, isColdStart = %{public}d", userId,
542         screenId, isColdStart);
543     currentScreenId_ = screenId;
544     currentWMSUserId_ = userId;
545     auto smsDeathRecipient = GetSMSDeathRecipientByUserId(currentWMSUserId_);
546     if (smsDeathRecipient != nullptr) {
547         smsDeathRecipient->SetScreenId(screenId);
548     }
549     if (!isColdStart) {
550         TLOGI(WmsLogTag::WMS_MULTI_USER, "User switched");
551         GetSceneSessionManager();
552     }
553     NotifyWMSConnectionChanged(userId, screenId, true);
554 }
555 
NotifyWMSConnectionChanged(int32_t wmsUserId,int32_t screenId,bool isConnected)556 void MockSessionManagerService::NotifyWMSConnectionChanged(int32_t wmsUserId, int32_t screenId, bool isConnected)
557 {
558     TLOGI(WmsLogTag::WMS_MULTI_USER, "wmsUserId = %{public}d, isConnected = %{public}d", wmsUserId, isConnected);
559     {
560         std::lock_guard<std::mutex> lock(wmsConnectionStatusLock_);
561         wmsConnectionStatusMap_[wmsUserId] = isConnected;
562     }
563     NotifyWMSConnectionChangedToLiteClient(wmsUserId, screenId, isConnected);
564     NotifyWMSConnectionChangedToClient(wmsUserId, screenId, isConnected);
565 }
566 
NotifyWMSConnectionChangedToClient(int32_t wmsUserId,int32_t screenId,bool isConnected)567 void MockSessionManagerService::NotifyWMSConnectionChangedToClient(
568     int32_t wmsUserId, int32_t screenId, bool isConnected)
569 {
570     std::shared_lock<std::shared_mutex> lock(smsRecoverListenerLock_);
571     std::map<int32_t, sptr<ISessionManagerServiceRecoverListener>>* smsRecoverListenerMap =
572         GetSMSRecoverListenerMap(SYSTEM_USERID);
573     if (!smsRecoverListenerMap) {
574         TLOGW(WmsLogTag::WMS_MULTI_USER, "smsRecoverListenerMap is null");
575         return;
576     }
577     TLOGD(WmsLogTag::WMS_MULTI_USER,
578           "wmsUserId = %{public}d, isConnected = %{public}d, remote process count = %{public}zu",
579           wmsUserId, isConnected, 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             TLOGD(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             TLOGD(WmsLogTag::WMS_MULTI_USER,
611                   "Call OnWMSConnectionChanged Lite pid = %{public}d, ref count = %{public}d",
612                   iter.first, 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::WMS_ATTRIBUTE, "windowIdList is null, no need to get surfaceNodeId");
779         return;
780     }
781     std::vector<int32_t> persistentIds;
782     for (uint64_t id : windowIdList) {
783         persistentIds.push_back(static_cast<int32_t>(id));
784     }
785     sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(sceneSessionManager_);
786     WMError ret = sceneSessionManagerProxy->GetProcessSurfaceNodeIdByPersistentId(
787         pid, persistentIds, surfaceNodeIds);
788     if (ret != WMError::WM_OK) {
789         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Get process surfaceNodeId by persistentId failed!");
790     }
791 }
792 
AddSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t> & persistentIds)793 void MockSessionManagerService::AddSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t>& persistentIds)
794 {
795     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
796     if (sessionManagerService == nullptr) {
797         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sessionManagerService is nullptr");
798         return;
799     }
800     if (!sceneSessionManager_) {
801         GetSceneSessionManager();
802         if (!sceneSessionManager_) {
803             TLOGW(WmsLogTag::WMS_ATTRIBUTE, "get scene session manager proxy failed, nullptr");
804             return;
805         }
806     }
807     sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(sceneSessionManager_);
808     if (sceneSessionManagerProxy == nullptr) {
809         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sessionManagerServiceProxy is nullptr");
810         return;
811     }
812     WMError ret = sceneSessionManagerProxy->AddSkipSelfWhenShowOnVirtualScreenList(persistentIds);
813     if (ret != WMError::WM_OK) {
814         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "add virtual screen black list failed!");
815     }
816 }
817 
RemoveSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t> & persistentIds)818 void MockSessionManagerService::RemoveSkipSelfWhenShowOnVirtualScreenList(const std::vector<int32_t>& persistentIds)
819 {
820     auto sessionManagerService = GetSessionManagerServiceByUserId(currentWMSUserId_);
821     if (sessionManagerService == nullptr) {
822         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sessionManagerService is nullptr");
823         return;
824     }
825     if (!sceneSessionManager_) {
826         GetSceneSessionManager();
827         if (!sceneSessionManager_) {
828             TLOGW(WmsLogTag::WMS_ATTRIBUTE, "get scene session manager proxy failed, nullptr");
829             return;
830         }
831     }
832     sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(sceneSessionManager_);
833     if (sceneSessionManagerProxy == nullptr) {
834         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sessionManagerServiceProxy is nullptr");
835         return;
836     }
837     WMError ret = sceneSessionManagerProxy->RemoveSkipSelfWhenShowOnVirtualScreenList(persistentIds);
838     if (ret != WMError::WM_OK) {
839         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "remove virtual screen black list failed!");
840     }
841 }
842 
GetSceneSessionManagerByUserId(int32_t userId)843 sptr<IRemoteObject> MockSessionManagerService::GetSceneSessionManagerByUserId(int32_t userId)
844 {
845     auto sessionManagerService = GetSessionManagerServiceByUserId(userId);
846     if (sessionManagerService == nullptr) {
847         WLOGFE("sessionManagerService is nullptr");
848         return nullptr;
849     }
850     sptr<ISessionManagerService> sessionManagerServiceProxy =
851         iface_cast<ISessionManagerService>(sessionManagerService);
852     if (sessionManagerServiceProxy == nullptr) {
853         WLOGFE("sessionManagerServiceProxy is nullptr");
854         return nullptr;
855     }
856     sptr<IRemoteObject> remoteObject = sessionManagerServiceProxy->GetSceneSessionManager();
857     if (remoteObject == nullptr) {
858         WLOGFW("Get scene session manager proxy failed");
859     }
860     return remoteObject;
861 }
862 
RecoverSCBSnapshotSkipByUserId(int32_t userId)863 int32_t MockSessionManagerService::RecoverSCBSnapshotSkipByUserId(int32_t userId)
864 {
865     std::unique_lock<std::mutex> lock(userIdBundleNamesMapLock_);
866     auto iter = userIdBundleNamesMap_.find(userId);
867     if (iter == userIdBundleNamesMap_.end()) {
868         return ERR_INVALID_VALUE;
869     }
870     sptr<IRemoteObject> remoteObject = GetSceneSessionManagerByUserId(userId);
871     if (!remoteObject) {
872         return ERR_NULL_OBJECT;
873     }
874     return NotifySCBSnapshotSkipByUserIdAndBundleNames(userId, iter->second, remoteObject);
875 }
876 
NotifySCBSnapshotSkipByUserIdAndBundleNames(int32_t userId,const std::vector<std::string> & bundleNameList,const sptr<IRemoteObject> & remoteObject)877 int32_t MockSessionManagerService::NotifySCBSnapshotSkipByUserIdAndBundleNames(int32_t userId,
878     const std::vector<std::string>& bundleNameList, const sptr<IRemoteObject>& remoteObject)
879 {
880     sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(remoteObject);
881     WMError ret = sceneSessionManagerProxy->SkipSnapshotByUserIdAndBundleNames(userId, bundleNameList);
882     if (ret != WMError::WM_OK) {
883         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "failed!");
884         return ERR_TRANSACTION_FAILED;
885     }
886     return ERR_NONE;
887 }
888 
SetSnapshotSkipByUserIdAndBundleNames(int32_t userId,const std::vector<std::string> & bundleNameList)889 int32_t MockSessionManagerService::SetSnapshotSkipByUserIdAndBundleNames(int32_t userId,
890     const std::vector<std::string>& bundleNameList)
891 {
892     if (!SessionPermission::IsSystemCalling()) {
893         TLOGE(WmsLogTag::WMS_MULTI_USER, "permission denied!");
894         return ERR_UNKNOWN_TRANSACTION;
895     }
896     {
897         std::unique_lock<std::mutex> lock(userIdBundleNamesMapLock_);
898         userIdBundleNamesMap_[userId] = bundleNameList;
899     }
900     sptr<IRemoteObject> remoteObject = GetSceneSessionManagerByUserId(userId);
901     if (!remoteObject) {
902         TLOGW(WmsLogTag::WMS_MULTI_USER, "user:%{public}d isn't active.", userId);
903         return ERR_NONE;
904     }
905     return NotifySCBSnapshotSkipByUserIdAndBundleNames(userId, bundleNameList, remoteObject);
906 }
907 
SetSnapshotSkipByIdNamesMap(const std::unordered_map<int32_t,std::vector<std::string>> & userIdAndBunldeNames)908 int32_t MockSessionManagerService::SetSnapshotSkipByIdNamesMap(
909     const std::unordered_map<int32_t, std::vector<std::string>>& userIdAndBunldeNames)
910 {
911     if (!SessionPermission::IsSystemCalling()) {
912         TLOGE(WmsLogTag::WMS_MULTI_USER, "permission denied");
913         return ERR_UNKNOWN_TRANSACTION;
914     }
915     std::unique_lock<std::mutex> lock(userIdBundleNamesMapLock_);
916     userIdBundleNamesMap_ = userIdAndBunldeNames;
917     for (auto it = userIdBundleNamesMap_.begin(); it != userIdBundleNamesMap_.end(); ++it) {
918         sptr<IRemoteObject> remoteObject = GetSceneSessionManagerByUserId(it->first);
919         if (!remoteObject) {
920             return ERR_NULL_OBJECT;
921         }
922         int32_t err = NotifySCBSnapshotSkipByUserIdAndBundleNames(it->first, it->second, remoteObject);
923         if (err != ERR_NONE) {
924             TLOGE(WmsLogTag::DEFAULT, "failed");
925             return err;
926         }
927     }
928     return ERR_NONE;
929 }
930 } // namespace Rosen
931 } // namespace OHOS