From 90e66a1d5d4b13db6dcccd0344060a1750215391 Mon Sep 17 00:00:00 2001 From: cloud_nine Date: Tue, 16 Jul 2024 10:56:04 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9A=90=E7=A7=81=E7=A9=BA=E9=97=B4=E9=80=80?= =?UTF-8?q?=E5=87=BA=E5=88=A0=E9=99=A4=E5=9C=BA=E6=99=AFbugfix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenyunjiu --- .../include/screen_session_dumper.h | 1 + .../include/screen_session_manager.h | 7 +- .../src/screen_session_dumper.cpp | 14 ++ .../src/screen_session_manager.cpp | 134 ++++++++++-------- 4 files changed, 97 insertions(+), 59 deletions(-) diff --git a/window_scene/session_manager/include/screen_session_dumper.h b/window_scene/session_manager/include/screen_session_dumper.h index c390fb3343..fccf862d05 100644 --- a/window_scene/session_manager/include/screen_session_dumper.h +++ b/window_scene/session_manager/include/screen_session_dumper.h @@ -39,6 +39,7 @@ public: void ExcuteDumpCmd(); void DumpEventTracker(EventTracker& tracker); void DumpFreezedPidList(std::set pidList); + void DumpMultiUserInfo(std::vector oldScbPids, int32_t userId, int32_t ScbPid); private: void ShowHelpInfo(); diff --git a/window_scene/session_manager/include/screen_session_manager.h b/window_scene/session_manager/include/screen_session_manager.h index 083a0f786f..06bb8f36c7 100644 --- a/window_scene/session_manager/include/screen_session_manager.h +++ b/window_scene/session_manager/include/screen_session_manager.h @@ -294,7 +294,8 @@ private: void AddVirtualScreenDeathRecipient(const sptr& displayManagerAgent, ScreenId smsScreenId); void PublishCastEvent(const bool &isPlugIn); void HandleScreenEvent(sptr screenSession, ScreenId screenId, ScreenEvent screenEvent); - void ScbStatusRecoveryWhenSwitchUser(int32_t newScbPid); + void ScbStatusRecoveryWhenSwitchUser(std::vector oldScbPids, int32_t newScbPid); + void SwitchScbNodeHandle(int32_t userId, int32_t newScbPid, bool coldBoot); void SetClientInner(); void GetCurrentScreenPhyBounds(float& phyWidth, float& phyHeight, bool& isReset, const ScreenId& screenid); @@ -353,11 +354,11 @@ private: std::shared_ptr taskScheduler_; std::shared_ptr screenPowerTaskScheduler_; + std::mutex oldScbPidsMutex_; + std::condition_variable scbSwitchCV_; int32_t currentUserId_ { 0 }; int32_t currentScbPId_ { -1 }; - std::mutex oldScbPidsMutex_; std::vector oldScbPids_ {}; - mutable std::mutex currentUserIdMutex_; std::map> clientProxyMap_; sptr clientProxy_; diff --git a/window_scene/session_manager/src/screen_session_dumper.cpp b/window_scene/session_manager/src/screen_session_dumper.cpp index 207e979ed7..4566ee6a04 100644 --- a/window_scene/session_manager/src/screen_session_dumper.cpp +++ b/window_scene/session_manager/src/screen_session_dumper.cpp @@ -114,6 +114,20 @@ void ScreenSessionDumper::DumpEventTracker(EventTracker& tracker) dumpInfo_.append(oss.str()); } +void ScreenSessionDumper::DumpMultiUserInfo(std::vector oldScbPids, int32_t userId, int32_t ScbPid) +{ + std::ostringstream oss; + oss << "-------------- DMS Multi User Info --------------" << std::endl; + oss << std::left << "[oldScbPid:] "; + for (auto oldScbPid : oldScbPids) { + oss << oldScbPid << " "; + } + oss << std::endl; + oss << std::left << "[userId:] " << userId << std::endl; + oss << std::left << "[ScbPid:] " << ScbPid << std::endl; + dumpInfo_.append(oss.str()); +} + void ScreenSessionDumper::DumpFreezedPidList(std::set pidList) { std::ostringstream oss; diff --git a/window_scene/session_manager/src/screen_session_manager.cpp b/window_scene/session_manager/src/screen_session_manager.cpp index 5f30162d7b..5065fc8145 100644 --- a/window_scene/session_manager/src/screen_session_manager.cpp +++ b/window_scene/session_manager/src/screen_session_manager.cpp @@ -67,6 +67,7 @@ const int32_t SLEEP_10_MS = 10 * 1000; // 10ms const int32_t CV_WAIT_SCREENON_MS = 300; const int32_t CV_WAIT_SCREENOFF_MS = 1500; const int32_t CV_WAIT_SCREENOFF_MS_MAX = 3000; +const int32_t CV_WAIT_SCBSWITCH_MS = 3000; const std::u16string DEFAULT_USTRING = u"error"; const std::string DEFAULT_STRING = "error"; const std::string ARG_DUMP_HELP = "-h"; @@ -88,6 +89,7 @@ const ScreenId SCREEN_ID_PC_MAIN = 9; const std::vector displayModeCommands = {"-f", "-m", "-sub", "-coor"}; constexpr int32_t INVALID_UID = -1; constexpr int32_t INVALID_USER_ID = -1; +constexpr int32_t INVALID_SCB_PID = -1; constexpr int32_t BASE_USER_RANGE = 200000; static bool g_foldScreenFlag = system::GetParameter("const.window.foldscreen.type", "") != ""; static const int32_t g_screenRotationOffSet = system::GetIntParameter("const.fold.screen_rotation.offset", 0); @@ -4254,11 +4256,20 @@ void ScreenSessionManager::NotifyClientProxyUpdateFoldDisplayMode(FoldDisplayMod void ScreenSessionManager::ScbClientDeathCallback(int32_t deathScbPid) { - std::lock_guard lock(oldScbPidsMutex_); - if (oldScbPids_.empty()) { - return; + std::unique_lock lock(oldScbPidsMutex_); + if (deathScbPid == currentScbPId_ || currentScbPId_ == INVALID_SCB_PID) { + clientProxy_ = nullptr; + TLOGE(WmsLogTag::DMS, "death callback, clientProxy is set null"); } - TLOGI(WmsLogTag::DMS, "old scb: %{public}d death", deathScbPid); + if (scbSwitchCV_.wait_for(lock, std::chrono::milliseconds(CV_WAIT_SCBSWITCH_MS)) + == std::cv_status::timeout) { + TLOGE(WmsLogTag::DMS, "set client task deathScbPid:%{public}d, timeout: %{public}d", + deathScbPid, CV_WAIT_SCBSWITCH_MS); + } + std::ostringstream oss; + oss << "Scb client death: " << deathScbPid; + TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str()); + screenEventTracker_.RecordEvent(oss.str()); oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), deathScbPid), oldScbPids_.end()); } @@ -4287,35 +4298,11 @@ void ScreenSessionManager::SwitchUser() } auto userId = GetUserIdByCallingUid(); auto newScbPid = IPCSkeleton::GetCallingPid(); - TLOGI(WmsLogTag::DMS, "switch userId:%{public}d, currentId:%{public}d", userId, currentUserId_); - { - std::lock_guard lock(currentUserIdMutex_); - if (userId == currentUserId_) { - TLOGI(WmsLogTag::DMS, "switch user not change"); - return; - } - std::lock_guard lockScb(oldScbPidsMutex_); - if (clientProxy_) { - auto pidIter = std::find(oldScbPids_.begin(), oldScbPids_.end(), currentScbPId_); - if (pidIter == oldScbPids_.end() && currentScbPId_ > 0) { - oldScbPids_.emplace_back(currentScbPId_); - } - oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), newScbPid), oldScbPids_.end()); - } - currentUserId_ = userId; - currentScbPId_ = newScbPid; - auto it = clientProxyMap_.find(currentUserId_); - if (it != clientProxyMap_.end()) { - clientProxy_ = it->second; - } - if (clientProxy_) { - ScbStatusRecoveryWhenSwitchUser(newScbPid); - } - } - MockSessionManagerService::GetInstance().NotifyWMSConnected(currentUserId_, GetDefaultScreenId(), false); + SwitchScbNodeHandle(userId, newScbPid, false); + MockSessionManagerService::GetInstance().NotifyWMSConnected(newScbPid, GetDefaultScreenId(), false); } -void ScreenSessionManager::ScbStatusRecoveryWhenSwitchUser(int32_t newScbPid) +void ScreenSessionManager::ScbStatusRecoveryWhenSwitchUser(std::vector oldScbPids, int32_t newScbPid) { NotifyFoldStatusChanged(GetFoldStatus()); NotifyDisplayModeChanged(GetFoldDisplayMode()); @@ -4341,12 +4328,7 @@ void ScreenSessionManager::ScbStatusRecoveryWhenSwitchUser(int32_t newScbPid) } else { screenSession->UpdateRotationAfterBoot(true); } - if (oldScbPids_.size() == 0) { - screenEventTracker_.RecordEvent("swicth user failed, oldScbPids is null"); - TLOGE(WmsLogTag::DMS, "swicth user failed, oldScbPids is null"); - return; - } - auto delayTask = [this, oldScbPids = oldScbPids_, newScbPid] { + auto delayTask = [this, oldScbPids, newScbPid] { if (!clientProxy_) { TLOGE(WmsLogTag::DMS, "clientProxy is null"); return; @@ -4360,8 +4342,7 @@ void ScreenSessionManager::ScbStatusRecoveryWhenSwitchUser(int32_t newScbPid) void ScreenSessionManager::SetClient(const sptr& client) { if (!SessionPermission::IsSystemCalling()) { - TLOGE(WmsLogTag::DMS, "permission denied"); - TLOGE(WmsLogTag::DMS, "calling clientName: %{public}s, calling pid: %{public}d", + TLOGE(WmsLogTag::DMS, "permission denied, calling clientName: %{public}s, calling pid: %{public}d", SysCapUtil::GetClientName().c_str(), IPCSkeleton::GetCallingPid()); return; } @@ -4369,33 +4350,69 @@ void ScreenSessionManager::SetClient(const sptr& cl TLOGE(WmsLogTag::DMS, "SetClient client is null"); return; } + clientProxy_ = client; + auto userId = GetUserIdByCallingUid(); auto newScbPid = IPCSkeleton::GetCallingPid(); + MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, GetDefaultScreenId(), true); + NotifyClientProxyUpdateFoldDisplayMode(GetFoldDisplayMode()); + SetClientInner(); + SwitchScbNodeHandle(userId, newScbPid, true); + AddScbClientDeathRecipient(client, newScbPid); std::ostringstream oss; oss << "set client userId: " << userId << " clientName: " << SysCapUtil::GetClientName(); TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str()); screenEventTracker_.RecordEvent(oss.str()); - { - std::lock_guard lock(currentUserIdMutex_); - if (clientProxy_ != nullptr && userId != currentUserId_ && currentUserId_ > 0) { - auto pidIter = std::find(oldScbPids_.begin(), oldScbPids_.end(), currentScbPId_); - if (pidIter == oldScbPids_.end() && currentScbPId_ > 0) { - oldScbPids_.emplace_back(currentScbPId_); - } - oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), newScbPid), oldScbPids_.end()); - clientProxy_->SwitchUserCallback(oldScbPids_, newScbPid); +} + +void ScreenSessionManager::SwitchScbNodeHandle(int32_t newUserId, int32_t newScbPid, bool coldBoot) +{ + std::ostringstream oss; + oss << "currentUserId: " << currentUserId_ + << " currentScbPId" << currentScbPId_ + << " newUserId: " << newUserId + << " newScbPid: " << newScbPid + << " coldBoot: " << static_cast(coldBoot); + TLOGI(WmsLogTag::DMS, "%{public}s", oss.str().c_str()); + screenEventTracker_.RecordEvent(oss.str()); + + std::unique_lock lock(oldScbPidsMutex_); + if (currentScbPId_ != INVALID_SCB_PID) { + auto pidIter = std::find(oldScbPids_.begin(), oldScbPids_.end(), currentScbPId_); + if (pidIter == oldScbPids_.end() && currentScbPId_ > 0) { + oldScbPids_.emplace_back(currentScbPId_); + } + oldScbPids_.erase(std::remove(oldScbPids_.begin(), oldScbPids_.end(), newScbPid), oldScbPids_.end()); + if (oldScbPids_.size() == 0) { + TLOGE(WmsLogTag::DMS, "swicth user failed, oldScbPids is null"); + screenEventTracker_.RecordEvent("swicth user failed, oldScbPids is null"); } - currentUserId_ = userId; - currentScbPId_ = newScbPid; - clientProxy_ = client; - clientProxyMap_[currentUserId_] = client; } - MockSessionManagerService::GetInstance().NotifyWMSConnected(userId, GetDefaultScreenId(), true); - NotifyClientProxyUpdateFoldDisplayMode(GetFoldDisplayMode()); - SetClientInner(); - AddScbClientDeathRecipient(client, newScbPid); + if (!clientProxy_) { + TLOGE(WmsLogTag::DMS, "clientProxy is null"); + return; + } + if (coldBoot) { + clientProxy_->SwitchUserCallback(oldScbPids_, newScbPid); + clientProxyMap_[newUserId] = clientProxy_; + } else { + // hot switch + if (clientProxyMap_.count(newUserId) == 0) { + TLOGE(WmsLogTag::DMS, "not found client proxy. userId:%{public}d.", newUserId); + return; + } + if (newUserId == currentUserId_) { + TLOGI(WmsLogTag::DMS, "switch user not change"); + return; + } + clientProxy_ = clientProxyMap_[newUserId]; + ScbStatusRecoveryWhenSwitchUser(oldScbPids_, newScbPid); + } + currentUserId_ = newUserId; + currentScbPId_ = newScbPid; + scbSwitchCV_.notify_all(); } void ScreenSessionManager::SetClientInner() @@ -4419,6 +4436,10 @@ void ScreenSessionManager::SetClientInner() SetRotation(iter.first, Rotation::ROTATION_0, false); iter.second->SetDisplayBoundary(RectF(0, 0, phyWidth, phyHeight), 0); } + if (!clientProxy_) { + TLOGE(WmsLogTag::DMS, "clientProxy is null"); + return; + } clientProxy_->OnScreenConnectionChanged(iter.first, ScreenEvent::CONNECTED, iter.second->GetRSScreenId(), iter.second->GetName()); } @@ -4566,6 +4587,7 @@ int ScreenSessionManager::Dump(int fd, const std::vector& args) } dumper->DumpFreezedPidList(freezedPidList_); dumper->DumpEventTracker(screenEventTracker_); + dumper->DumpMultiUserInfo(oldScbPids_, currentUserId_, currentScbPId_); dumper->ExcuteDumpCmd(); std::vector params;