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
48namespace OHOS {
49namespace Rosen {
50namespace {
51constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "MockSessionManagerService" };
52
53const std::u16string DEFAULT_USTRING = u"error";
54const char DEFAULT_STRING[] = "error";
55const std::string ARG_DUMP_HELP = "-h";
56const std::string ARG_DUMP_ALL = "-a";
57const std::string ARG_DUMP_WINDOW = "-w";
58const std::string KEY_SCENE_BOARD_TEST_ENABLE = "persist.scb.testmode.enable";
59const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
60const std::string TEST_MODULE_NAME_SUFFIX = "_test";
61const std::string BOOTEVENT_WMS_READY = "bootevent.wms.ready";
62
63inline 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
76class ClientListenerDeathRecipient : public IRemoteObject::DeathRecipient {
77public:
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
92private:
93    int32_t userId_;
94    int32_t pid_;
95    bool isLite_;
96};
97
98WM_IMPLEMENT_SINGLE_INSTANCE(MockSessionManagerService)
99MockSessionManagerService::SMSDeathRecipient::SMSDeathRecipient(int32_t userId)
100    : userId_(userId), screenId_(DEFAULT_SCREEN_ID)
101{}
102
103void 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
122void MockSessionManagerService::SMSDeathRecipient::SetScreenId(int32_t screenId)
123{
124    TLOGI(WmsLogTag::WMS_MULTI_USER, "screenId=%{public}d", screenId);
125    screenId_ = screenId;
126}
127
128MockSessionManagerService::MockSessionManagerService()
129    : SystemAbility(WINDOW_MANAGER_SERVICE_ID, true), currentWMSUserId_(INVALID_USER_ID),
130      currentScreenId_(DEFAULT_SCREEN_ID)
131{}
132
133bool 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
146void MockSessionManagerService::OnStart()
147{
148    WLOGFD("OnStart begin");
149}
150
151static 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
161int 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
193bool 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
231sptr<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
245void 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
258sptr<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
273sptr<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
286void 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
296void 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
316void 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
359std::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
369void 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
381void 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
397void 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
421void 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
463std::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
473void 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
485void 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
500void 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
525void 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
542void 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
553void 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
580void 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
605sptr<IRemoteObject> MockSessionManagerService::GetScreenSessionManagerLite()
606{
607    if (screenSessionManager_) {
608        return screenSessionManager_;
609    }
610    screenSessionManager_ = ScreenSessionManagerLite::GetInstance().AsObject();
611    return screenSessionManager_;
612}
613
614void MockSessionManagerService::ShowIllegalArgsInfo(std::string& dumpInfo)
615{
616    dumpInfo.append("The arguments are illegal and you can enter '-h' for help.");
617}
618
619sptr<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
640int 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
667void 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
680void MockSessionManagerService::ShowAceDumpHelp(std::string& dumpInfo)
681{
682}
683
684bool 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
730void 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
748void 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
780sptr<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
800int32_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
814int32_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
826int32_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
844int32_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