* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mock_session_manager_service.h"
#include <cstdint>
#include <fcntl.h>
#include <securec.h>
#include <unistd.h>
#include <bundle_mgr_interface.h>
#include <system_ability_definition.h>
#include <cinttypes>
#include <csignal>
#include <iomanip>
#include <ipc_skeleton.h>
#include <iservice_registry.h>
#include <map>
#include <sstream>
#include "window_manager_hilog.h"
#include "unique_fd.h"
#include "parameters.h"
#include "root_scene.h"
#include "string_ex.h"
#include "wm_common.h"
#include "ws_common.h"
#include "scene_board_judgement.h"
#include "scene_session_manager_interface.h"
#include "scene_session_manager_lite_interface.h"
#include "session_manager_service_interface.h"
#include "screen_session_manager_lite.h"
#include "common/include/session_permission.h"
#include "display_manager.h"
#define PATH_LEN 1024
#define O_RDWR 02
namespace OHOS {
namespace Rosen {
namespace {
const std::u16string DEFAULT_USTRING = u"error";
const char DEFAULT_STRING[] = "error";
const std::string ARG_DUMP_HELP = "-h";
const std::string ARG_DUMP_ALL = "-a";
const std::string ARG_DUMP_WINDOW = "-w";
const std::string KEY_SCENE_BOARD_TEST_ENABLE = "persist.scb.testmode.enable";
const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
const std::string TEST_MODULE_NAME_SUFFIX = "_test";
const std::string BOOTEVENT_WMS_READY = "bootevent.wms.ready";
}
class ClientListenerDeathRecipient : public IRemoteObject::DeathRecipient {
public:
ClientListenerDeathRecipient(int32_t clientUserId, int32_t instanceUserId,
int32_t pid, bool isLite)
: clientUserId_(clientUserId), instanceUserId_(instanceUserId),
pid_(pid), isLite_(isLite)
{
}
void OnRemoteDied(const wptr<IRemoteObject>& wptrDeath) override
{
TLOGW(WmsLogTag::WMS_RECOVER, "Client died, pid = %{public}d, isLite = %{public}d", pid_, isLite_);
TLOGI(WmsLogTag::WMS_RECOVER,
"clientUserId: %{public}d, instanceUserId: %{public}d, "
"pid: %{public}d, isLite: %{public}d",
clientUserId_, instanceUserId_, pid_, isLite_);
MockSessionManagerService::GetInstance().RemoveSMSRecoverListener(
clientUserId_, pid_, instanceUserId_, isLite_);
if (!isLite_) {
MockSessionManagerService::GetInstance().ResetSpecificWindowZIndex(clientUserId_, pid_);
}
}
private:
int32_t clientUserId_;
int32_t instanceUserId_;
int32_t pid_;
bool isLite_;
};
WM_IMPLEMENT_SINGLE_INSTANCE(MockSessionManagerService)
MockSessionManagerService::SMSDeathRecipient::SMSDeathRecipient(int32_t userId)
: userId_(userId), screenId_(DEFAULT_SCREEN_ID)
{
}
void MockSessionManagerService::SMSDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& object)
{
TLOGI(WmsLogTag::WMS_MULTI_USER, "Scb died with userId_=%{public}d, screenId_=%{public}d", userId_, screenId_);
MockSessionManagerService::GetInstance().NotifyWMSConnectionChanged(
userId_, screenId_, false, INVALID_USER_ID, INVALID_PID);
MockSessionManagerService::GetInstance().RemoveScreenUserMappingIfMatched(screenId_, userId_);
MockSessionManagerService::GetInstance().RemoveSMSDeathRecipientByUserId(userId_);
MockSessionManagerService::GetInstance().RemoveSessionManagerServiceByUserId(userId_);
auto sessionManagerService = object.promote();
if (!sessionManagerService) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "sessionManagerService is null");
return;
}
if (IsSceneBoardTestMode()) {
TLOGI(WmsLogTag::WMS_MULTI_USER, "SceneBoard is testing, do not kill foundation.");
return;
}
TLOGI(WmsLogTag::WMS_MULTI_USER, "SessionManagerService died!");
}
void MockSessionManagerService::SMSDeathRecipient::SetScreenId(int32_t screenId)
{
TLOGI(WmsLogTag::WMS_MULTI_USER, "screenId=%{public}d", screenId);
screenId_ = screenId;
}
MockSessionManagerService::MockSessionManagerService()
: SystemAbility(WINDOW_MANAGER_SERVICE_ID, true), defaultWMSUserId_(INVALID_USER_ID)
{
defaultScreenId_ = DisplayManager::GetInstance().GetDefaultDisplayId();
TLOGI(WmsLogTag::WMS_MULTI_USER, "MockSessionManagerService initialized. Default screenId: %{public}" PRIu64,
defaultScreenId_);
}
MockSessionManagerService::~MockSessionManagerService()
{
TLOGI(WmsLogTag::WMS_MULTI_USER, "destoryed");
}
bool MockSessionManagerService::RegisterMockSessionManagerService()
{
static bool isRegistered = false;
static bool isPublished = false;
if (isRegistered && isPublished) {
TLOGW(WmsLogTag::WMS_MULTI_USER, "WindowManagerService SA has already been registered and published");
return true;
}
if (!isRegistered) {
isRegistered = SystemAbility::MakeAndRegisterAbility(this);
if (isRegistered) {
TLOGI(WmsLogTag::WMS_MULTI_USER, "Successfully registered WindowManagerService SA");
} else {
TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to register WindowManagerService SA");
}
}
if (!isPublished) {
isPublished = Publish(this);
if (isPublished) {
TLOGI(WmsLogTag::WMS_MULTI_USER, "Successfully published WindowManagerService SA");
} else {
TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to publish WindowManagerService SA");
}
}
return isRegistered && isPublished;
}
void MockSessionManagerService::OnStart()
{
WLOGFD("OnStart begin");
}
static std::string Str16ToStr8(const std::u16string& str)
{
if (str == DEFAULT_USTRING) {
return DEFAULT_STRING;
}
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert(DEFAULT_STRING);
std::string result = convert.to_bytes(str);
return result == DEFAULT_STRING ? "" : result;
}
int MockSessionManagerService::Dump(int fd, const std::vector<std::u16string>& args)
{
TLOGD(WmsLogTag::DEFAULT, "dump begin fd: %{public}d", fd);
if (fd < 0) {
return -1;
}
(void) signal(SIGPIPE, SIG_IGN);
std::vector<std::string> params;
for (auto& arg : args) {
params.emplace_back(Str16ToStr8(arg));
}
std::string dumpInfo;
if (params.empty()) {
ShowHelpInfo(dumpInfo);
} else if (params.size() == 1 && params[0] == ARG_DUMP_HELP) {
ShowHelpInfo(dumpInfo);
} else {
int errCode = DumpSessionInfo(params, dumpInfo);
if (errCode != 0) {
ShowIllegalArgsInfo(dumpInfo);
}
}
int ret = write(fd, dumpInfo.c_str(), dumpInfo.length());
if (ret < 0) {
WLOGFE("write error");
return -1;
}
TLOGD(WmsLogTag::DEFAULT, "dump end");
return 0;
}
bool MockSessionManagerService::SetSessionManagerService(sptr<IRemoteObject> sessionManagerService)
{
if (!sessionManagerService) {
TLOGE(WmsLogTag::WMS_SCB, "sessionManagerService is null");
return false;
}
int32_t currentWMSUserId = GetUserIdByCallingUid();
if (currentWMSUserId <= INVALID_USER_ID) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "userId is illegal: %{public}d", currentWMSUserId);
return false;
}
{
std::lock_guard<std::mutex> lock(defaultWMSUserIdMutex_);
if (defaultWMSUserId_ == INVALID_USER_ID) {
defaultWMSUserId_ = currentWMSUserId;
TLOGI(WmsLogTag::WMS_MULTI_USER, "Set defaultWMSUserId_=%{public}d", defaultWMSUserId_);
}
}
RecoverSCBSnapshotSkipByUserId(currentWMSUserId);
auto smsDeathRecipient = GetSMSDeathRecipientByUserId(currentWMSUserId);
if (!smsDeathRecipient) {
smsDeathRecipient = sptr<SMSDeathRecipient>::MakeSptr(currentWMSUserId);
std::unique_lock<std::shared_mutex> lock(smsDeathRecipientMapLock_);
smsDeathRecipientMap_[currentWMSUserId] = smsDeathRecipient;
TLOGI(WmsLogTag::WMS_MULTI_USER, "Create SMSDeathRecipient for userId: %{public}d", currentWMSUserId);
}
if (sessionManagerService->IsProxyObject() && !sessionManagerService->AddDeathRecipient(smsDeathRecipient)) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "Failed to add death recipient");
return false;
}
{
std::lock_guard<std::mutex> lock(sessionManagerServiceMapMutex_);
sessionManagerServiceMap_[currentWMSUserId] = sessionManagerService;
}
RegisterMockSessionManagerService();
system::SetParameter(BOOTEVENT_WMS_READY.c_str(), "true");
GetSceneSessionManager();
TLOGI(WmsLogTag::WMS_MULTI_USER, "Session manager service set success");
return true;
}
sptr<MockSessionManagerService::SMSDeathRecipient> MockSessionManagerService::GetSMSDeathRecipientByUserId(
int32_t userId)
{
std::shared_lock<std::shared_mutex> lock(smsDeathRecipientMapLock_);
auto iter = smsDeathRecipientMap_.find(userId);
return (iter != smsDeathRecipientMap_.end()) ? iter->second : nullptr;
}
void MockSessionManagerService::RemoveSMSDeathRecipientByUserId(int32_t userId)
{
TLOGI(WmsLogTag::WMS_MULTI_USER, "userId: %{public}d", userId);
auto sessionManagerService = GetSessionManagerServiceInner(userId);
if (sessionManagerService == nullptr) {
return;
}
std::unique_lock<std::shared_mutex> lock(smsDeathRecipientMapLock_);
auto iter = smsDeathRecipientMap_.find(userId);
if (iter != smsDeathRecipientMap_.end() && iter->second) {
sessionManagerService->RemoveDeathRecipient(iter->second);
}
}
ErrCode MockSessionManagerService::GetSessionManagerService(sptr<IRemoteObject>& sessionManagerService)
{
int32_t clientUserId = GetUserIdByCallingUid();
if (clientUserId <= INVALID_USER_ID) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "userId is illegal: %{public}d", clientUserId);
return ERR_INVALID_VALUE;
}
if (clientUserId == SYSTEM_USERID) {
std::lock_guard<std::mutex> lock(defaultWMSUserIdMutex_);
clientUserId = defaultWMSUserId_;
TLOGD(WmsLogTag::WMS_MULTI_USER, "use default sessionManagerService with %{public}d", clientUserId);
}
sessionManagerService = GetSessionManagerServiceInner(clientUserId);
if (!sessionManagerService) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "sessionManagerService is null");
return ERR_INVALID_VALUE;
}
return ERR_OK;
}
ErrCode MockSessionManagerService::GetSessionManagerServiceByUserId(int32_t userId,
sptr<IRemoteObject>& sessionManagerService)
{
int32_t clientUserId = GetUserIdByCallingUid();
TLOGI(WmsLogTag::WMS_MULTI_USER, "userId=%{public}d, clientUserId=%{public}d", userId, clientUserId);
if (clientUserId <= INVALID_USER_ID) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "clientUserId is illegal, clientUserId=%{public}d", clientUserId);
return ERR_INVALID_VALUE;
}
if (clientUserId != SYSTEM_USERID) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "clientUserId is not system, clientUserId=%{public}d", clientUserId);
return ERR_WOULD_BLOCK;
}
sessionManagerService = GetSessionManagerServiceInner(userId);
if (!sessionManagerService) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "sessionManagerService is null");
return ERR_INVALID_VALUE;
}
return ERR_OK;
}
sptr<IRemoteObject> MockSessionManagerService::GetSessionManagerServiceInner(int32_t userId)
{
std::lock_guard<std::mutex> lock(sessionManagerServiceMapMutex_);
auto iter = sessionManagerServiceMap_.find(userId);
if (iter != sessionManagerServiceMap_.end()) {
TLOGI(WmsLogTag::WMS_MULTI_USER, "Get session manager service success with userId=%{public}d", userId);
return iter->second;
} else {
TLOGE(WmsLogTag::WMS_MULTI_USER, "Get session manager service failed with userId=%{public}d", userId);
return nullptr;
}
}
void MockSessionManagerService::RemoveSessionManagerServiceByUserId(int32_t userId)
{
TLOGI(WmsLogTag::WMS_MULTI_USER, "userId: %{public}d", userId);
RemoveFromMap(sessionManagerServiceMap_, sessionManagerServiceMapMutex_, userId);
RemoveFromMap(sceneSessionManagerLiteMap_, sceneSessionManagerLiteMapMutex_, userId);
RemoveFromMap(sceneSessionManagerMap_, sceneSessionManagerMapMutex_, userId);
}
void MockSessionManagerService::RemoveFromMap(std::map<int32_t, sptr<IRemoteObject>>& map,
std::mutex& mutex,
int32_t userId)
{
std::lock_guard<std::mutex> lock(mutex);
auto iter = map.find(userId);
if (iter != map.end()) {
map.erase(iter);
TLOGI(WmsLogTag::WMS_MULTI_USER, "RemoveFromMap success, userId: %{public}d", userId);
}
}
ErrCode MockSessionManagerService::RegisterSMSRecoverListener(int32_t userId,
bool isLite, const sptr<IRemoteObject>& listener)
{
if (listener == nullptr) {
TLOGE(WmsLogTag::WMS_RECOVER, "listener is null");
return ERR_INVALID_VALUE;
}
int32_t clientUserId = GetUserIdByCallingUid();
if (clientUserId <= INVALID_USER_ID) {
TLOGE(WmsLogTag::WMS_RECOVER, "illegal clientUserId: %{public}d", clientUserId);
return ERR_INVALID_VALUE;
}
int32_t pid = IPCSkeleton::GetCallingRealPid();
auto smsListener = iface_cast<ISessionManagerServiceRecoverListener>(listener);
if (!smsListener) {
TLOGE(WmsLogTag::WMS_RECOVER, "IPC convert failed");
return ERR_INVALID_VALUE;
}
int32_t instanceUserId = userId;
int32_t wmsUserId = userId;
if (clientUserId == SYSTEM_USERID) {
if (userId == INVALID_USER_ID) {
std::lock_guard<std::mutex> lock(defaultWMSUserIdMutex_);
wmsUserId = defaultWMSUserId_;
}
TLOGI(WmsLogTag::WMS_RECOVER,
"clientUserId: %{public}d, wmsUserId: %{public}d, instanceUserId: %{public}d, "
"pid: %{public}d, isLite: %{public}d",
clientUserId, wmsUserId, instanceUserId, pid, isLite);
if (!AddClientDeathRecipient(listener, SYSTEM_USERID, instanceUserId, pid, isLite)) {
return ERR_INVALID_VALUE;
}
AddSMSRecoverListener(SYSTEM_USERID, pid, instanceUserId, isLite, smsListener);
return NotifyWMSConnectionStatus(wmsUserId, smsListener);
} else {
TLOGI(WmsLogTag::WMS_RECOVER,
"clientUserId: %{public}d, pid: %{public}d, isLite: %{public}d",
clientUserId, pid, isLite);
if (!AddClientDeathRecipient(listener, clientUserId, instanceUserId, pid, isLite)) {
return ERR_INVALID_VALUE;
}
AddSMSRecoverListener(clientUserId, pid, instanceUserId, isLite, smsListener);
return ERR_WOULD_BLOCK;
}
}
ErrCode MockSessionManagerService::UnregisterSMSRecoverListener(int32_t userId, bool isLite)
{
int32_t clientUserId = GetUserIdByCallingUid();
if (clientUserId <= INVALID_USER_ID) {
TLOGE(WmsLogTag::WMS_RECOVER, "illegal clientUserId: %{public}d", clientUserId);
return ERR_INVALID_VALUE;
}
int32_t instanceUserId = userId;
int32_t pid = IPCSkeleton::GetCallingRealPid();
TLOGI(WmsLogTag::WMS_RECOVER,
"clientUserId: %{public}d, instanceUserId: %{public}d, "
"pid: %{public}d, isLite: %{public}d",
clientUserId, instanceUserId, pid, isLite);
RemoveSMSRecoverListener(clientUserId, pid, instanceUserId, isLite);
return ERR_OK;
}
ErrCode MockSessionManagerService::NotifySetSpecificWindowZIndex()
{
int32_t pid = IPCSkeleton::GetCallingRealPid();
int32_t userId = GetUserIdByCallingUid();
std::lock_guard<std::mutex> lock(specificZIndexByPidMapMutex_);
specificZIndexByPidMap_[pid] = userId;
TLOGI(WmsLogTag::WMS_FOCUS, "pid: %{public}d", pid);
return ERR_OK;
}
void MockSessionManagerService::ResetSpecificWindowZIndex(int32_t clientUserId, int32_t pid)
{
TLOGI(WmsLogTag::WMS_FOCUS, "clientUserId: %{public}d, pid: %{public}d", clientUserId, pid);
{
std::lock_guard<std::mutex> lock(specificZIndexByPidMapMutex_);
auto iter = specificZIndexByPidMap_.find(pid);
if (iter == specificZIndexByPidMap_.end()) {
return;
}
}
sptr<IRemoteObject> remoteObject = GetSceneSessionManagerByUserId(clientUserId);
if (!remoteObject) {
TLOGE(WmsLogTag::WMS_FOCUS, "remoteObject is null");
return;
}
sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(remoteObject);
if (sceneSessionManagerProxy == nullptr) {
TLOGE(WmsLogTag::WMS_FOCUS, "sessionManagerServiceProxy is nullptr");
return;
}
sceneSessionManagerProxy->ResetSpecificWindowZIndex(pid);
{
std::lock_guard<std::mutex> lock(specificZIndexByPidMapMutex_);
specificZIndexByPidMap_.erase(pid);
}
}
ErrCode MockSessionManagerService::NotifySceneBoardAvailable()
{
if (!SessionPermission::IsSystemCalling()) {
TLOGE(WmsLogTag::WMS_RECOVER, "permission denied");
return ERR_PERMISSION_DENIED;
}
int32_t userId = GetUserIdByCallingUid();
if (userId <= INVALID_USER_ID) {
TLOGE(WmsLogTag::WMS_RECOVER, "userId is illegal: %{public}d", userId);
return ERR_INVALID_VALUE;
}
TLOGI(WmsLogTag::WMS_RECOVER, "scene board is available with userId=%{public}d", userId);
NotifySceneBoardAvailableToSystemAppClient(userId, true);
NotifySceneBoardAvailableToClient(userId, true);
NotifySceneBoardAvailableToSystemAppClient(userId, false);
NotifySceneBoardAvailableToClient(userId, false);
return ERR_OK;
}
void MockSessionManagerService::NotifySceneBoardAvailableToSystemAppClient(int32_t userId, bool isLite)
{
auto sessionManagerService = GetSessionManagerServiceInner(userId);
if (sessionManagerService == nullptr) {
TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
return;
}
auto listeners = CollectListenersByInstanceUserId(SYSTEM_USERID, userId, isLite);
int32_t defaultWMSUserId = GetDefaultWMSUserId();
if (userId == defaultWMSUserId) {
auto invalidUserIdListeners = CollectListenersByInstanceUserId(SYSTEM_USERID, INVALID_USER_ID, isLite);
listeners.insert(listeners.end(), invalidUserIdListeners.begin(), invalidUserIdListeners.end());
}
TLOGI(WmsLogTag::WMS_RECOVER,
"userId: %{public}d, isLite: %{public}d, Remote count: %{public}zu",
userId, isLite, listeners.size());
for (auto& [pid, listener] : listeners) {
TLOGI(WmsLogTag::WMS_RECOVER, "Call OnSessionManagerServiceRecover pid: %{public}d", pid);
listener->OnSessionManagerServiceRecover(sessionManagerService);
}
}
void MockSessionManagerService::NotifySceneBoardAvailableToClient(int32_t userId, bool isLite)
{
auto sessionManagerService = GetSessionManagerServiceInner(userId);
if (sessionManagerService == nullptr) {
TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
return;
}
auto listeners = CollectListenersByClientUserId(userId, isLite);
TLOGI(WmsLogTag::WMS_RECOVER, "userId: %{public}d, isLite: %{public}d, Remote count: %{public}zu",
userId, isLite, listeners.size());
for (auto& [pid, listener] : listeners) {
TLOGI(WmsLogTag::WMS_RECOVER, "Call OnSessionManagerServiceRecover pid = %{public}d", pid);
listener->OnSessionManagerServiceRecover(sessionManagerService);
}
}
void MockSessionManagerService::NotifyWMSConnected(int32_t userId, DisplayId screenId, bool isColdStart)
{
TLOGI(WmsLogTag::WMS_MULTI_USER, "userId: %{public}d, screenId: [%{public}" PRIu64"], isColdStart: %{public}d",
userId, screenId, isColdStart);
UpdateUserId2PidMapping(userId, IPCSkeleton::GetCallingPid());
int32_t fromUserId = INVALID_USER_ID;
int32_t fromPid = INVALID_PID;
fromUserId = GetUserIdOnScreen(screenId, userId);
fromPid = GetWmsPidByUserId(fromUserId);
TLOGI(WmsLogTag::WMS_MULTI_USER,
"userId: %{public}d, screenId: [%{public}" PRIu64"], isColdStart: %{public}d, "
"fromUserId: %{public}d, fromPid: %{public}d",
userId, screenId, isColdStart, fromUserId, fromPid);
UpdateScreenUserInfo(userId, screenId);
if (screenId == defaultScreenId_) {
std::lock_guard<std::mutex> lock(defaultWMSUserIdMutex_);
defaultWMSUserId_ = userId;
TLOGI(WmsLogTag::WMS_MULTI_USER, "Set defaultWMSUserId_=%{public}d", defaultWMSUserId_);
}
auto smsDeathRecipient = GetSMSDeathRecipientByUserId(userId);
if (smsDeathRecipient != nullptr) {
smsDeathRecipient->SetScreenId(screenId);
} else {
TLOGW(WmsLogTag::WMS_MULTI_USER, "failed to set screenId");
}
if (!isColdStart) {
TLOGI(WmsLogTag::WMS_MULTI_USER, "User switched");
GetSceneSessionManager();
}
NotifyWMSConnectionChanged(userId, screenId, true, fromUserId, fromPid);
}
void MockSessionManagerService::NotifyWMSConnectionChanged(int32_t wmsUserId,
DisplayId screenId, bool isConnected, int32_t fromUserId, int32_t fromPid)
{
int32_t pid = GetWmsPidByUserId(wmsUserId);
TLOGI(WmsLogTag::WMS_MULTI_USER,
"wmsUserId=%{public}d, isConnected=%{public}d, pid=%{public}d, "
"fromUserId=%{public}d, fromPid=%{public}d",
wmsUserId, isConnected, pid, fromUserId, fromPid);
{
std::lock_guard<std::mutex> lock(wmsConnectionStatusLock_);
wmsConnectionStatusMap_[wmsUserId] = isConnected;
}
NotifyWMSConnectionChangedToClient(wmsUserId, screenId, isConnected, true, pid, fromUserId, fromPid);
NotifyWMSConnectionChangedToClient(wmsUserId, screenId, isConnected, false, pid, fromUserId, fromPid);
}
void MockSessionManagerService::NotifyWMSConnectionChangedToClient(int32_t wmsUserId,
DisplayId screenId, bool isConnected, bool isLite,
int32_t wmsPid, int32_t fromUserId, int32_t fromPid)
{
auto sessionManagerService = GetSessionManagerServiceInner(wmsUserId);
if (!sessionManagerService) {
TLOGE(WmsLogTag::WMS_RECOVER, "sessionManagerService is null");
return;
}
auto listeners = CollectListenersByClientUserId(SYSTEM_USERID, isLite);
TLOGI(WmsLogTag::WMS_MULTI_USER,
"wmsUserId: %{public}d, isLite: %{public}d, isConnected: %{public}d, screenId: %{public}" PRIu64
" remote count: %{public}zu, fromUserId: %{public}d, fromPid: %{public}d",
wmsUserId, isLite, isConnected, screenId, listeners.size(), fromUserId, fromPid);
for (auto& [pid, listener] : listeners) {
TLOGI(WmsLogTag::WMS_MULTI_USER, "OnWMSConnectionChanged pid: %{public}d, wmsPid: %{public}d", pid, wmsPid);
listener->OnWMSConnectionChanged(wmsUserId, screenId,
isConnected, wmsPid, fromUserId, fromPid, sessionManagerService);
}
}
ErrCode MockSessionManagerService::GetScreenSessionManagerLite(sptr<IRemoteObject>& screenSessionManagerLite)
{
std::lock_guard<std::mutex> lock(screenSessionManagerMutex_);
if (screenSessionManager_) {
screenSessionManagerLite = screenSessionManager_;
return ERR_OK;
}
screenSessionManager_ = ScreenSessionManagerLite::GetInstance().AsObject();
screenSessionManagerLite = screenSessionManager_;
return ERR_OK;
}
void MockSessionManagerService::ShowIllegalArgsInfo(std::string& dumpInfo)
{
dumpInfo.append("The arguments are illegal and you can enter '-h' for help.");
}
sptr<IRemoteObject> MockSessionManagerService::GetSceneSessionManager()
{
int32_t defaultWMSUserId = GetDefaultWMSUserId();
TLOGI(WmsLogTag::DEFAULT, "defaultWMSUserId=%{public}d", defaultWMSUserId);
auto sessionManagerService = GetSessionManagerServiceInner(defaultWMSUserId);
if (sessionManagerService == nullptr) {
TLOGE(WmsLogTag::DEFAULT, "Get session mgr service remote failed");
return nullptr;
}
auto sessionManagerServiceProxy = iface_cast<ISessionManagerService>(sessionManagerService);
if (!sessionManagerServiceProxy) {
TLOGE(WmsLogTag::DEFAULT, "Get session mgr service proxy failed");
return nullptr;
}
sptr<IRemoteObject> remoteObject = sessionManagerServiceProxy->GetSceneSessionManager();
if (!remoteObject) {
TLOGE(WmsLogTag::DEFAULT, "Get scene session mgr remote failed");
return nullptr;
}
UpdateSceneSessionManagerFromCache(defaultWMSUserId, false, remoteObject);
std::lock_guard<std::mutex> lock(defaultSceneSessionManagerMutex_);
defaultSceneSessionManager_ = remoteObject;
return defaultSceneSessionManager_;
}
int MockSessionManagerService::DumpSessionInfo(const std::vector<std::string>& args, std::string& dumpInfo)
{
if (args.empty()) {
return -1;
}
int32_t defaultWMSUserId = GetDefaultWMSUserId();
auto sessionManagerService = GetSessionManagerServiceInner(defaultWMSUserId);
if (sessionManagerService == nullptr) {
TLOGE(WmsLogTag::DEFAULT, "sessionManagerService is null");
return -1;
}
sptr<IRemoteObject> defaultSSMRemote = GetSceneSessionManager();
if (!defaultSSMRemote) {
TLOGE(WmsLogTag::DEFAULT, "Get scene session mgr remote failed");
return -1;
}
auto sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(defaultSSMRemote);
if (sceneSessionManagerProxy == nullptr) {
WLOGFW("sessionManagerServiceProxy is nullptr");
return -1;
}
WSError ret = sceneSessionManagerProxy->GetSessionDumpInfo(args, dumpInfo);
if (ret != WSError::WS_OK) {
WLOGFD("sessionManagerService set success!");
return -1;
}
return 0;
}
void MockSessionManagerService::ShowHelpInfo(std::string& dumpInfo)
{
dumpInfo.append("Usage:\n")
.append(" -h ")
.append("|help text for the tool\n")
.append(" -a ")
.append("|dump all window information in the system\n")
.append(" -w {window id} [ArkUI Option] ")
.append("|dump specified window information\n")
.append(" ------------------------------------[ArkUI Option]------------------------------------ \n");
ShowAceDumpHelp(dumpInfo);
}
void MockSessionManagerService::ShowAceDumpHelp(std::string& dumpInfo)
{
}
bool MockSessionManagerService::SMSDeathRecipient::IsSceneBoardTestMode()
{
if (!OHOS::system::GetBoolParameter(KEY_SCENE_BOARD_TEST_ENABLE, false)) {
WLOGFD("SceneBoard testmode is disabled.");
return false;
}
auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (systemAbilityMgr == nullptr) {
WLOGFE("Failed to get SystemAbilityManager.");
return false;
}
auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
if (bmsObj == nullptr) {
WLOGFE("Failed to get BundleManagerService.");
return false;
}
sptr<AppExecFwk::IBundleMgr> bundleMgr_ = iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
AppExecFwk::BundleInfo bundleInfo;
int uid = IPCSkeleton::GetCallingUid();
int userId = uid / 200000;
bool result = bundleMgr_->GetBundleInfo(SCENE_BOARD_BUNDLE_NAME,
AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId);
if (!result) {
WLOGFE("Failed to query bundleInfo, userId:%{public}d", userId);
return true;
}
auto hapModulesList = bundleInfo.hapModuleInfos;
if (hapModulesList.empty()) {
WLOGFE("hapModulesList is empty");
return false;
}
std::string suffix = TEST_MODULE_NAME_SUFFIX;
for (auto hapModule: hapModulesList) {
std::string moduleName = hapModule.moduleName;
if (moduleName.length() < suffix.length()) {
continue;
}
if (moduleName.compare(moduleName.length() - suffix.length(), suffix.length(), suffix) == 0) {
WLOGFI("Found test module name: %{public}s", moduleName.c_str());
return true;
}
}
return false;
}
void MockSessionManagerService::GetProcessSurfaceNodeIdByPersistentId(const int32_t pid,
const std::vector<uint64_t>& windowIdList, std::vector<uint64_t>& surfaceNodeIds)
{
int32_t defaultUserId = GetDefaultWMSUserId();
auto sessionManagerService = GetSessionManagerServiceInner(defaultUserId);
if (sessionManagerService == nullptr) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Get session manager remote failed");
return;
}
sptr<IRemoteObject> defaultSSMRemote = GetSceneSessionManager();
if (!defaultSSMRemote) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Get scene session manager remote failed");
return;
}
if (windowIdList.empty()) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "windowIdList is null, no need to get surfaceNodeId");
return;
}
std::vector<int32_t> persistentIds(windowIdList.size());
std::transform(windowIdList.begin(), windowIdList.end(),
persistentIds.begin(), [](uint64_t id) { return static_cast<int32_t>(id); });
auto sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(defaultSSMRemote);
if (sceneSessionManagerProxy == nullptr) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Get session mgr proxy failed");
return;
}
WMError ret = sceneSessionManagerProxy->GetProcessSurfaceNodeIdByPersistentId(
pid, persistentIds, surfaceNodeIds);
if (ret != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Get process surfaceNodeId by persistentId failed!");
}
}
void MockSessionManagerService::AddSkipSelfWhenShowOnVirtualScreenList(
const std::vector<int32_t>& persistentIds, int32_t userId)
{
sptr<IRemoteObject> sceneSessionManager = GetSceneSessionManagerByUserId(userId);
if (!sceneSessionManager) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Get scene session manager failed");
return;
}
sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(sceneSessionManager);
if (sceneSessionManagerProxy == nullptr) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sessionManagerServiceProxy is nullptr");
return;
}
WMError ret = sceneSessionManagerProxy->AddSkipSelfWhenShowOnVirtualScreenList(persistentIds);
if (ret != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "add virtual screen black list failed!");
}
}
void MockSessionManagerService::RemoveSkipSelfWhenShowOnVirtualScreenList(
const std::vector<int32_t>& persistentIds, int32_t userId)
{
sptr<IRemoteObject> sceneSessionManager = GetSceneSessionManagerByUserId(userId);
if (!sceneSessionManager) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Get scene session manager failed");
return;
}
sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(sceneSessionManager);
if (sceneSessionManagerProxy == nullptr) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sessionManagerServiceProxy is nullptr");
return;
}
WMError ret = sceneSessionManagerProxy->RemoveSkipSelfWhenShowOnVirtualScreenList(persistentIds);
if (ret != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "remove virtual screen black list failed!");
}
}
void MockSessionManagerService::SetScreenPrivacyWindowTagSwitch(
uint64_t screenId, const std::vector<std::string>& privacyWindowTags, bool enable)
{
if (privacyWindowTags.empty()) {
TLOGI(WmsLogTag::WMS_ATTRIBUTE, "PrivacyWindowTags is empty");
return;
}
int32_t defaultWMSUserId;
{
std::lock_guard<std::mutex> lock(defaultWMSUserIdMutex_);
defaultWMSUserId = defaultWMSUserId_;
}
auto sessionManagerService = GetSessionManagerServiceInner(defaultWMSUserId);
if (sessionManagerService == nullptr) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sessionManagerService is nullptr");
return;
}
if (!defaultSceneSessionManager_) {
GetSceneSessionManager();
if (!defaultSceneSessionManager_) {
TLOGW(WmsLogTag::WMS_ATTRIBUTE, "get scene session manager proxy failed, nullptr");
return;
}
}
sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(defaultSceneSessionManager_);
if (sceneSessionManagerProxy == nullptr) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "sessionManagerServiceProxy is nullptr");
return;
}
WMError ret = sceneSessionManagerProxy->SetScreenPrivacyWindowTagSwitch(screenId, privacyWindowTags, enable);
if (ret != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "remove virtual screen black list failed!");
}
}
sptr<IRemoteObject> MockSessionManagerService::GetSceneSessionManagerByUserId(int32_t userId)
{
auto sessionManagerService = GetSessionManagerServiceInner(userId);
if (sessionManagerService == nullptr) {
WLOGFE("sessionManagerService is nullptr");
return nullptr;
}
sptr<ISessionManagerService> sessionManagerServiceProxy =
iface_cast<ISessionManagerService>(sessionManagerService);
if (sessionManagerServiceProxy == nullptr) {
WLOGFE("sessionManagerServiceProxy is nullptr");
return nullptr;
}
sptr<IRemoteObject> remoteObject = sessionManagerServiceProxy->GetSceneSessionManager();
if (remoteObject == nullptr) {
WLOGFW("Get scene session manager proxy failed");
}
return remoteObject;
}
ErrCode MockSessionManagerService::GetSceneSessionManagerLiteByClient(int32_t userId,
sptr<IRemoteObject>& sceneSessionManagerLite)
{
ErrCode code = CheckClientIsSystemUser();
if (code != ERR_OK) {
return code;
}
sceneSessionManagerLite = GetSceneSessionManagerInner(userId, true);
return ERR_OK;
}
ErrCode MockSessionManagerService::GetSceneSessionManagerByClient(int32_t userId,
sptr<IRemoteObject>& sceneSessionManager)
{
ErrCode code = CheckClientIsSystemUser();
if (code != ERR_OK) {
return code;
}
sceneSessionManager = GetSceneSessionManagerInner(userId, false);
return ERR_OK;
}
sptr<ISceneSessionManagerLite> MockSessionManagerService::GetSceneSessionManagerLiteBySA(int32_t userId)
{
sptr<ISceneSessionManagerLite> result;
GetSceneSessionManagerByUserIdImpl<ISceneSessionManagerLite>(userId, true, false, result);
return result;
}
sptr<ISceneSessionManager> MockSessionManagerService::GetSceneSessionManagerBySA(int32_t userId)
{
sptr<ISceneSessionManager> result;
GetSceneSessionManagerByUserIdImpl<ISceneSessionManager>(userId, false, false, result);
return result;
}
template ErrCode MockSessionManagerService::GetSceneSessionManagerByUserIdImpl<ISceneSessionManagerLite>(
int32_t userId,
bool isLite,
bool checkClient,
sptr<ISceneSessionManagerLite>& result);
template ErrCode MockSessionManagerService::GetSceneSessionManagerByUserIdImpl<ISceneSessionManager>(
int32_t userId,
bool isLite,
bool checkClient,
sptr<ISceneSessionManager>& result);
template <typename T>
ErrCode MockSessionManagerService::GetSceneSessionManagerByUserIdImpl(int32_t userId,
bool isLite,
bool checkClient,
sptr<T>& result)
{
TLOGD(WmsLogTag::WMS_MULTI_USER,
"userId: %{public}d, isLite: %{public}d, checkClient: %{public}d",
userId,
isLite,
checkClient);
if (checkClient) {
ErrCode err = CheckClientIsSystemUser();
if (err != ERR_OK) {
return err;
}
}
auto sceneSessionManagerProxyObject = GetSceneSessionManagerInner(userId, isLite);
if (sceneSessionManagerProxyObject == nullptr) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "smsProxy null");
return ERR_DEAD_OBJECT;
}
result = iface_cast<T>(sceneSessionManagerProxyObject);
if (!result) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "ssmProxy iface_cast null");
return ERR_DEAD_OBJECT;
}
return ERR_OK;
}
sptr<IRemoteObject> MockSessionManagerService::GetSceneSessionManagerInner(int32_t userId, bool isLite)
{
sptr<IRemoteObject> SSMRemoteObject = GetSceneSessionManagerFromCache(userId, isLite);
if (SSMRemoteObject != nullptr) {
return SSMRemoteObject;
}
auto sessionManagerService = GetSessionManagerServiceInner(userId);
if (sessionManagerService == nullptr) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "SMS is nullptr, userId: %{public}d", userId);
return nullptr;
}
sptr<ISessionManagerService> sessionManagerServiceProxy = iface_cast<ISessionManagerService>(sessionManagerService);
if (sessionManagerServiceProxy == nullptr) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "SMSProxy iface_cast null, userId: %{public}d", userId);
return nullptr;
}
SSMRemoteObject = isLite ? sessionManagerServiceProxy->GetSceneSessionManagerLite()
: sessionManagerServiceProxy->GetSceneSessionManager();
if (SSMRemoteObject == nullptr) {
TLOGE(WmsLogTag::WMS_MULTI_USER,
"SSMRemoteObject is null, userId: %{public}d, isLite: %{public}d",
userId,
isLite);
return nullptr;
}
UpdateSceneSessionManagerFromCache(userId, isLite, SSMRemoteObject);
return SSMRemoteObject;
}
sptr<IRemoteObject> MockSessionManagerService::GetSceneSessionManagerFromCache(int32_t userId, bool isLite)
{
TLOGD(WmsLogTag::WMS_MULTI_USER, "userId: %{public}d, isLite: %{public}d", userId, isLite);
if (isLite) {
std::lock_guard<std::mutex> lock(sceneSessionManagerLiteMapMutex_);
auto iter = sceneSessionManagerLiteMap_.find(userId);
if (iter != sceneSessionManagerLiteMap_.end()) {
TLOGD(WmsLogTag::WMS_MULTI_USER, "get success with userId: %{public}d, isLite: %{public}d", userId, isLite);
return iter->second;
}
} else {
std::lock_guard<std::mutex> lock(sceneSessionManagerMapMutex_);
auto iter = sceneSessionManagerMap_.find(userId);
if (iter != sceneSessionManagerMap_.end()) {
TLOGD(WmsLogTag::WMS_MULTI_USER, "get success with userId: %{public}d, isLite: %{public}d", userId, isLite);
return iter->second;
}
}
TLOGD(WmsLogTag::WMS_MULTI_USER,
"GetSceneSessionManagerFromCache miss, userId: %{public}d, isLite: %{public}d", userId, isLite);
return nullptr;
}
void MockSessionManagerService::UpdateSceneSessionManagerFromCache(int32_t userId,
bool isLite,
sptr<IRemoteObject>& sceneSessionManager)
{
if (sceneSessionManager == nullptr) {
TLOGW(WmsLogTag::WMS_MULTI_USER, "ssm is nullptr userId: %{public}d", userId);
return;
}
TLOGD(WmsLogTag::WMS_MULTI_USER, "update ssm cache, userId: %{public}d, isLite: %{public}d", userId, isLite);
if (isLite) {
std::lock_guard<std::mutex> lock(sceneSessionManagerLiteMapMutex_);
sceneSessionManagerLiteMap_[userId] = sceneSessionManager;
} else {
std::lock_guard<std::mutex> lock(sceneSessionManagerMapMutex_);
sceneSessionManagerMap_[userId] = sceneSessionManager;
}
}
ErrCode MockSessionManagerService::RecoverSCBSnapshotSkipByUserId(int32_t userId)
{
std::unique_lock<std::mutex> lock(userIdBundleNamesMapLock_);
auto iter = userIdBundleNamesMap_.find(userId);
if (iter == userIdBundleNamesMap_.end()) {
TLOGW(WmsLogTag::WMS_MULTI_USER,
"userId %{public}d not found in userIdBundleNamesMap, skip recover", userId);
return ERR_INVALID_VALUE;
}
sptr<IRemoteObject> remoteObject = GetSceneSessionManagerByUserId(userId);
if (!remoteObject) {
return ERR_DEAD_OBJECT;
}
return NotifySCBSnapshotSkipByUserIdAndBundleNames(userId, iter->second, remoteObject);
}
ErrCode MockSessionManagerService::NotifySCBSnapshotSkipByUserIdAndBundleNames(int32_t userId,
const std::vector<std::string>& bundleNameList, const sptr<IRemoteObject>& remoteObject)
{
sptr<ISceneSessionManager> sceneSessionManagerProxy = iface_cast<ISceneSessionManager>(remoteObject);
WMError ret = sceneSessionManagerProxy->SkipSnapshotByUserIdAndBundleNames(userId, bundleNameList);
if (ret != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_ATTRIBUTE, "failed!");
return ERR_INVALID_OPERATION;
}
return ERR_OK;
}
ErrCode MockSessionManagerService::SetSnapshotSkipByUserIdAndBundleNames(int32_t userId,
const std::vector<std::string>& bundleNameList)
{
if (!SceneBoardJudgement::IsSceneBoardEnabled()) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "service not supported!");
return ERR_WOULD_BLOCK;
}
if (!SessionPermission::VerifyCallingPermission("ohos.permission.MANAGE_EDM_POLICY")) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "permission denied!");
return ERR_PERMISSION_DENIED;
}
return SetSnapshotSkipByUserIdAndBundleNamesInner(userId, bundleNameList);
}
ErrCode MockSessionManagerService::SetSnapshotSkipByUserIdAndBundleNamesInner(int32_t userId,
const std::vector<std::string>& bundleNameList)
{
{
std::unique_lock<std::mutex> lock(userIdBundleNamesMapLock_);
userIdBundleNamesMap_[userId] = bundleNameList;
}
sptr<IRemoteObject> remoteObject = GetSceneSessionManagerByUserId(userId);
if (!remoteObject) {
TLOGW(WmsLogTag::WMS_MULTI_USER, "user:%{public}d isn't active.", userId);
return ERR_OK;
}
return NotifySCBSnapshotSkipByUserIdAndBundleNames(userId, bundleNameList, remoteObject);
}
ErrCode MockSessionManagerService::SetSnapshotSkipByIdNamesMap(
const std::unordered_map<int32_t, std::vector<std::string>>& userIdAndBunldeNames)
{
if (!SceneBoardJudgement::IsSceneBoardEnabled()) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "service not supported!");
return ERR_WOULD_BLOCK;
}
if (!SessionPermission::VerifyCallingPermission("ohos.permission.MANAGE_EDM_POLICY")) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "permission denied");
return ERR_PERMISSION_DENIED;
}
return SetSnapshotSkipByIdNamesMapInner(userIdAndBunldeNames);
}
ErrCode MockSessionManagerService::SetSnapshotSkipByIdNamesMapInner(
const std::unordered_map<int32_t, std::vector<std::string>>& userIdAndBunldeNames)
{
std::unique_lock<std::mutex> lock(userIdBundleNamesMapLock_);
userIdBundleNamesMap_ = userIdAndBunldeNames;
TLOGI(WmsLogTag::WMS_MULTI_USER,
"SetSnapshotSkipByIdNamesMapInner, total userIds: %{public}zu", userIdBundleNamesMap_.size());
for (const auto& [userId, bundleNameList] : userIdBundleNamesMap_) {
sptr<IRemoteObject> remoteObject = GetSceneSessionManagerByUserId(userId);
if (!remoteObject) {
TLOGW(WmsLogTag::WMS_MULTI_USER, "user:%{public}d isn't active", userId);
continue;
}
ErrCode err = NotifySCBSnapshotSkipByUserIdAndBundleNames(userId, bundleNameList, remoteObject);
if (err != ERR_OK) {
TLOGE(WmsLogTag::DEFAULT, "failed");
return err;
}
}
return ERR_OK;
}
ErrCode MockSessionManagerService::NotifyWMSConnectionStatus(int32_t userId,
const sptr<ISessionManagerServiceRecoverListener>& smsListener)
{
bool isWMSConnected = false;
{
std::lock_guard<std::mutex> lock(wmsConnectionStatusLock_);
if (wmsConnectionStatusMap_.find(userId) != wmsConnectionStatusMap_.end()) {
isWMSConnected = wmsConnectionStatusMap_[userId];
}
}
if (smsListener && isWMSConnected) {
auto sessionManagerService = GetSessionManagerServiceInner(userId);
if (sessionManagerService == nullptr) {
TLOGE(WmsLogTag::WMS_RECOVER, "SessionManagerService is null");
return ERR_DEAD_OBJECT;
}
TLOGI(WmsLogTag::WMS_MULTI_USER, "wms is already connected, notify client");
DisplayId screenId = DEFAULT_SCREEN_ID;
{
std::lock_guard<std::mutex> lock(userId2ScreenIdMutex_);
screenId = userId2ScreenId_[userId];
}
int32_t wmsPid = GetWmsPidByUserId(userId);
TLOGI(WmsLogTag::WMS_MULTI_USER,
"OnWMSConnectionChanged userId: %{public}d, wmsPid: %{public}d", userId, wmsPid);
smsListener->OnWMSConnectionChanged(userId, screenId, true,
wmsPid, INVALID_USER_ID, INVALID_PID, sessionManagerService);
}
return ERR_OK;
}
int32_t MockSessionManagerService::GetUserIdByCallingUid()
{
int32_t uid = IPCSkeleton::GetCallingUid();
if (uid <= INVALID_UID) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "uid is illegal: %{public}d", uid);
return INVALID_USER_ID;
}
return GetUserIdByUid(uid);
}
ErrCode MockSessionManagerService::CheckClientIsSystemUser()
{
int32_t clientUserId = GetUserIdByCallingUid();
if (clientUserId <= INVALID_USER_ID) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "userId is illegal: %{public}d", clientUserId);
return ERR_INVALID_VALUE;
}
if (clientUserId != SYSTEM_USERID) {
TLOGE(WmsLogTag::WMS_MULTI_USER, "clientUserId is not system user id: %{public}d", clientUserId);
return ERR_WOULD_BLOCK;
}
return ERR_OK;
}
void MockSessionManagerService::AddSMSRecoverListener(
int32_t clientUserId, int32_t pid, int32_t instanceUserId, bool isLite,
const sptr<ISessionManagerServiceRecoverListener>& smsListener)
{
auto& recoverListenerMap = isLite ? liteRecoverListenerMap_ : recoverListenerMap_;
auto& mutex = isLite ? liteRecoverListenerMutex_ : recoverListenerMutex_;
{
std::lock_guard<std::mutex> lock(mutex);
recoverListenerMap[clientUserId][pid][instanceUserId] = smsListener;
}
TLOGI(WmsLogTag::WMS_RECOVER,
"AddSMSRecoverListener success, clientUserId: %{public}d, pid: %{public}d, "
"instanceUserId: %{public}d, isLite: %{public}d",
clientUserId, pid, instanceUserId, isLite);
}
void MockSessionManagerService::UpdateUserId2PidMapping(int32_t userId, int32_t pid)
{
std::lock_guard<std::mutex> lock(userId2PidMapMutex_);
userId2PidMap_[userId] = pid;
TLOGD(WmsLogTag::WMS_MULTI_USER, "Update userId2PidMap: userId=%{public}d, pid=%{public}d", userId, pid);
}
int32_t MockSessionManagerService::GetWmsPidByUserId(int32_t userId)
{
std::lock_guard<std::mutex> lock(userId2PidMapMutex_);
auto iter = userId2PidMap_.find(userId);
return (iter != userId2PidMap_.end()) ? iter->second : INVALID_PID;
}
void MockSessionManagerService::RemoveUserId2PidMapping(int32_t userId)
{
std::lock_guard<std::mutex> lock(userId2PidMapMutex_);
auto iter = userId2PidMap_.find(userId);
if (iter != userId2PidMap_.end()) {
TLOGI(WmsLogTag::WMS_MULTI_USER, "Clean userId2PidMap for userId=%{public}d, pid=%{public}d",
userId, iter->second);
userId2PidMap_.erase(iter);
}
}
int32_t MockSessionManagerService::GetDefaultWMSUserId()
{
std::lock_guard<std::mutex> lock(defaultWMSUserIdMutex_);
return defaultWMSUserId_;
}
void MockSessionManagerService::RemoveSMSRecoverListener(int32_t clientUserId,
int32_t pid,
int32_t instanceUserId,
bool isLite)
{
auto& recoverListenerMap = isLite ? liteRecoverListenerMap_ : recoverListenerMap_;
std::lock_guard<std::mutex> lock(isLite ? liteRecoverListenerMutex_ : recoverListenerMutex_);
auto clientIter = recoverListenerMap.find(clientUserId);
if (clientIter == recoverListenerMap.end()) {
TLOGW(WmsLogTag::WMS_RECOVER,
"RemoveSMSRecoverListener: clientUserId %{public}d not found", clientUserId);
return;
}
auto& pidMap = clientIter->second;
auto pidIter = pidMap.find(pid);
if (pidIter == pidMap.end()) {
TLOGW(WmsLogTag::WMS_RECOVER,
"RemoveSMSRecoverListener: pid %{public}d not found for clientUserId %{public}d",
pid, clientUserId);
return;
}
auto& instanceMap = pidIter->second;
instanceMap.erase(instanceUserId);
if (instanceMap.empty()) {
pidMap.erase(pidIter);
}
if (pidMap.empty()) {
recoverListenerMap.erase(clientIter);
}
TLOGI(WmsLogTag::WMS_RECOVER,
"RemoveSMSRecoverListener success, clientUserId: %{public}d, pid: %{public}d, "
"instanceUserId: %{public}d, isLite: %{public}d",
clientUserId, pid, instanceUserId, isLite);
}
RecoverListenerPairs MockSessionManagerService::CollectListenersByClientUserId(int32_t clientUserId, bool isLite)
{
RecoverListenerPairs listeners;
auto& recoverListenerMap = isLite ? liteRecoverListenerMap_ : recoverListenerMap_;
std::lock_guard<std::mutex> lock(isLite ? liteRecoverListenerMutex_ : recoverListenerMutex_);
auto clientIter = recoverListenerMap.find(clientUserId);
if (clientIter == recoverListenerMap.end()) {
return listeners;
}
for (const auto& [pid, instanceMap] : clientIter->second) {
for (const auto& [instanceUserId, listener] : instanceMap) {
if (listener) {
TLOGD(WmsLogTag::WMS_RECOVER,
"CollectListenersByClientUserId: found listener, pid: %{public}d, instanceUserId: %{public}d",
pid, instanceUserId);
listeners.push_back({ pid, listener });
}
}
}
TLOGI(WmsLogTag::WMS_RECOVER,
"CollectListenersByClientUserId end, clientUserId: %{public}d, isLite: %{public}d, "
"collected listeners: %{public}zu", clientUserId, isLite, listeners.size());
return listeners;
}
RecoverListenerPairs MockSessionManagerService::CollectListenersByInstanceUserId(int32_t clientUserId,
int32_t instanceUserId,
bool isLite)
{
RecoverListenerPairs listeners;
auto& recoverListenerMap = isLite ? liteRecoverListenerMap_ : recoverListenerMap_;
std::lock_guard<std::mutex> lock(isLite ? liteRecoverListenerMutex_ : recoverListenerMutex_);
auto clientIter = recoverListenerMap.find(clientUserId);
if (clientIter == recoverListenerMap.end()) {
return listeners;
}
for (const auto& [pid, instanceMap] : clientIter->second) {
auto instanceIter = instanceMap.find(instanceUserId);
if (instanceIter != instanceMap.end() && instanceIter->second) {
TLOGD(WmsLogTag::WMS_RECOVER,
"CollectListenersByInstanceUserId: found listener, pid: %{public}d, instanceUserId: %{public}d",
pid, instanceUserId);
listeners.push_back({ pid, instanceIter->second });
}
}
TLOGI(WmsLogTag::WMS_RECOVER,
"CollectListenersByInstanceUserId end, clientUserId: %{public}d, "
"instanceUserId: %{public}d, isLite: %{public}d, collected listeners: %{public}zu",
clientUserId, instanceUserId, isLite, listeners.size());
return listeners;
}
bool MockSessionManagerService::AddClientDeathRecipient(const sptr<IRemoteObject>& listener,
int32_t clientUserId,
int32_t instanceUserId,
int32_t pid,
bool isLite)
{
auto clientDeathListener = sptr<ClientListenerDeathRecipient>::MakeSptr(clientUserId, instanceUserId, pid, isLite);
if (listener->IsProxyObject() && !listener->AddDeathRecipient(clientDeathListener)) {
TLOGE(WmsLogTag::WMS_RECOVER, "failed to add death recipient");
return false;
}
TLOGI(WmsLogTag::WMS_RECOVER,
"AddClientDeathRecipient success, clientUserId: %{public}d, pid: %{public}d, instanceUserId: %{public}d, "
"isLite: %{public}d", clientUserId, pid, instanceUserId, isLite);
return true;
}
ErrCode MockSessionManagerService::GetActiveUserIds(std::vector<int32_t>& activeUserIds)
{
activeUserIds.clear();
{
std::lock_guard<std::mutex> lock(screenId2UserIdMutex_);
for (const auto& [screenId, uid] : screenId2UserId_) {
if (uid > INVALID_USER_ID) {
activeUserIds.push_back(uid);
}
}
}
TLOGD(WmsLogTag::WMS_MULTI_USER,
"GetActiveUserIds returns %{public}zu active users",
activeUserIds.size());
return ERR_OK;
}
void MockSessionManagerService::UpdateScreenUserInfo(int32_t userId, DisplayId screenId)
{
TLOGD(WmsLogTag::WMS_MULTI_USER, "UpdateScreenUserInfo userId: %{public}d, screenId: %{public}" PRIu64,
userId, screenId);
{
std::lock_guard<std::mutex> lock(screenId2UserIdMutex_);
screenId2UserId_[screenId] = userId;
TLOGD(WmsLogTag::WMS_MULTI_USER,
"screenId2UserId_ updated: screenId=%{public}" PRIu64 " -> userId=%{public}d", screenId, userId);
}
{
std::lock_guard<std::mutex> lock(userId2ScreenIdMutex_);
userId2ScreenId_[userId] = screenId;
TLOGD(WmsLogTag::WMS_MULTI_USER,
"userId2ScreenId_ updated: userId=%{public}d -> screenId=%{public}" PRIu64, userId, screenId);
}
}
int32_t MockSessionManagerService::GetUserIdOnScreen(DisplayId screenId, int32_t userId)
{
int32_t prevUserId = INVALID_USER_ID;
{
std::lock_guard<std::mutex> lock(screenId2UserIdMutex_);
auto iter = screenId2UserId_.find(screenId);
if (iter != screenId2UserId_.end() && iter->second != userId) {
prevUserId = iter->second;
}
TLOGD(WmsLogTag::WMS_MULTI_USER,
"GetUserIdOnScreen: screenId=%{public}" PRIu64 ", userId=%{public}d, prevUserId=%{public}d",
screenId, userId, prevUserId);
}
return prevUserId;
}
void MockSessionManagerService::RemoveScreenUserMappingIfMatched(DisplayId screenId, int32_t userId)
{
std::lock_guard<std::mutex> lock(screenId2UserIdMutex_);
auto iter = screenId2UserId_.find(screenId);
if (iter != screenId2UserId_.end() && iter->second == userId) {
screenId2UserId_.erase(iter);
TLOGI(WmsLogTag::WMS_MULTI_USER,
"screenId2UserId_ erased: screenId=%{public}" PRIu64 " (userId=%{public}d matched)",
screenId, userId);
}
}
}
}