diff --git a/dmserver/include/display_manager_interface_code.h b/dmserver/include/display_manager_interface_code.h index 6f6254a5495006a3781255fbad746bdab8cf5028..3b4839453603e42b055369d81c7f1898752eb879 100644 --- a/dmserver/include/display_manager_interface_code.h +++ b/dmserver/include/display_manager_interface_code.h @@ -180,6 +180,7 @@ enum class DisplayManagerMessage : unsigned int { TRANS_ID_SET_VIRTUAL_SCREEN_AUTO_ROTATION, TRANS_ID_SET_SCREEN_PRIVACY_WINDOW_TAG_SWITCH, TRANS_ID_SYNCHRONIZED_POWER_STATUS, + TRANS_ID_NOTIFY_SCREEN_CONNECT_COMPLETION, }; } #endif // FOUNDATION_DMSERVER_DISPLAY_MANAGER_INTERFACE_CODE_H diff --git a/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.cpp b/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.cpp index 8b77bacc9f3db3e91d40f9a2032fd8995eb4012a..a6f556f8783cb0c7fda053b97f22136b02321721 100644 --- a/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.cpp +++ b/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.cpp @@ -104,6 +104,8 @@ napi_value JsScreenSessionManager::Init(napi_env env, napi_value exportObj) JsScreenSessionManager::SetScreenOffDelayTime); BindNativeFunction(env, exportObj, "notifyFoldToExpandCompletion", moduleName, JsScreenSessionManager::NotifyFoldToExpandCompletion); + BindNativeFunction(env, exportObj, "notifyScreenConnectCompletion", moduleName, + JsScreenSessionManager::NotifyScreenConnectCompletion); BindNativeFunction(env, exportObj, "recordEventFromScb", moduleName, JsScreenSessionManager::RecordEventFromScb); BindNativeFunction(env, exportObj, "getFoldStatus", moduleName, JsScreenSessionManager::GetFoldStatus); @@ -255,6 +257,13 @@ napi_value JsScreenSessionManager::NotifyFoldToExpandCompletion(napi_env env, na return (me != nullptr) ? me->OnNotifyFoldToExpandCompletion(env, info) : nullptr; } +napi_value JsScreenSessionManager::NotifyScreenConnectCompletion(napi_env env, napi_callback_info info) +{ + TLOGD(WmsLogTag::DMS, "[NAPI]NotifyFoldToExpandCompletion"); + JsScreenSessionManager* me = CheckParamsAndGetThis(env, info); + return (me != nullptr) ? me->OnNotifyScreenConnectCompletion(env, info) : nullptr; +} + napi_value JsScreenSessionManager::RecordEventFromScb(napi_env env, napi_callback_info info) { TLOGD(WmsLogTag::DMS, "[NAPI]RecordEventFromScb"); @@ -879,6 +888,29 @@ napi_value JsScreenSessionManager::OnNotifyFoldToExpandCompletion(napi_env env, return NapiGetUndefined(env); } +napi_value JsScreenSessionManager::OnNotifyScreenConnectCompletion(napi_env, env, const napi_callback_info info) +{ + TLOGD(WmsLogTag::DMS, "[NAPI]OnNotifyScreenConnectCompletion"); + size_t argc = ARGC_ONE; + napi_value argv[ARGC_ONE] = {nullptr}; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + if (argc < ARGC_ONE) { + TLOGE(WmsLogTag::DMS, "[NAPI]Argc is invalid: %{public}zu", argc); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), + "Input parameter is missing or invalid")); + return NapiGetUndefined(env); + } + int32_t screenId; + if (!ConvertFromJsValue(env, argv[0], screenId) || (screenId < 0)) { + TLOGE(WmsLogTag::DMS, "[NAPI]Failed to convert parameter to screenId"); + napi_throw(env, CreateJsError(env, static_cast(WSErrorCode::WS_ERROR_INVALID_PARAM), + "Input parameter is missing or invalid")); + return NapiGetUndefined(env); + } + ScreenSessionManagerClient::GetInstance().NotifyScreenConnectCompletion(static_cast(screenId)); + return NapiGetUndefined(env); +} + napi_value JsScreenSessionManager::OnRecordEventFromScb(napi_env env, const napi_callback_info info) { TLOGD(WmsLogTag::DMS, "[NAPI]OnRecordEventFromScb"); diff --git a/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.h b/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.h index 7628f10b0ef801530d495695bb830cbe076a9eb6..b2a366fbd5d8de28a6d153c2e85c51d2f9344072 100644 --- a/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.h +++ b/window_scene/interfaces/kits/napi/screen_session_manager/js_screen_session_manager.h @@ -56,6 +56,7 @@ private: static napi_value SetScreenOnDelayTime(napi_env env, napi_callback_info info); static napi_value SetForceCloseHdr(napi_env env, napi_callback_info info); static napi_value NotifyFoldToExpandCompletion(napi_env env, napi_callback_info info); + static napi_value NotifyScreenConnectCompletion(napi_env env, napi_callback_info info); static napi_value RecordEventFromScb(napi_env env, napi_callback_info info); static napi_value SetCameraStatus(napi_env env, napi_callback_info info); static napi_value GetFoldStatus(napi_env env, napi_callback_info info); @@ -89,6 +90,7 @@ private: napi_value OnSetCameraStatus(napi_env env, napi_callback_info info); napi_value OnSetForceCloseHdr(napi_env env, const napi_callback_info info); napi_value OnNotifyFoldToExpandCompletion(napi_env env, const napi_callback_info info); + napi_value OnNotifyScreenConnectCompletion(napi_env env, const napi_callback_info info); napi_value OnRecordEventFromScb(napi_env env, const napi_callback_info info); napi_value OnGetFoldStatus(napi_env env, const napi_callback_info info); napi_value OnGetSuperFoldStatus(napi_env env, const napi_callback_info info); diff --git a/window_scene/screen_session_manager/include/multi_screen_manager.h b/window_scene/screen_session_manager/include/multi_screen_manager.h index 3ebd99c8bf1a72917683902454e5202b541c4d00..2ebe9acebf9fc3899021bcbd1c0cdc9fe9c4cc54 100644 --- a/window_scene/screen_session_manager/include/multi_screen_manager.h +++ b/window_scene/screen_session_manager/include/multi_screen_manager.h @@ -52,6 +52,7 @@ public: MultiScreenPositionOptions mainScreenOptions, MultiScreenPositionOptions secondScreenOption); void MultiScreenReportDataToRss(std::string multiScreenType, std::string status); + void NotifyScreenConnectCompletion(ScreenId screenId); private: MultiScreenManager(); ~MultiScreenManager(); @@ -89,6 +90,9 @@ private: void DoFirstExtendChangeMirror(sptr firstSession, sptr secondarySession); std::pair lastScreenMode_; // main screen id & secondary screen mode + std::mutex uniqueScreenMutex_; + std::condition_variable uniqueScreenCV_; + std::map uniqueScreenTimeoutMap_; }; } // namespace OHOS::Rosen #endif // OHOS_ROSEN_MULTI_SCREEN_MANAGER_H diff --git a/window_scene/screen_session_manager/include/screen_session_manager.h b/window_scene/screen_session_manager/include/screen_session_manager.h index 5c8de4839e069cb2ebce4d92af26f1c2b1bef913..fea9765057517cb89510756d34b49738dd4e7398 100644 --- a/window_scene/screen_session_manager/include/screen_session_manager.h +++ b/window_scene/screen_session_manager/include/screen_session_manager.h @@ -362,6 +362,7 @@ public: DMError GetExpandAvailableArea(DisplayId displayId, DMRect& area) override; void NotifyAvailableAreaChanged(DMRect area, DisplayId displayId); void NotifyFoldToExpandCompletion(bool foldToExpand) override; + void NotifyScreenConnectCompletion(ScreenId screenId) override; void RecordEventFromScb(std::string description, bool needRecordEvent) override; void SetCameraStatus(int32_t cameraStatus, int32_t cameraPosition) override; bool GetSnapshotArea(Media::Rect &rect, DmErrorCode* errorCode, ScreenId &screenId); diff --git a/window_scene/screen_session_manager/include/zidl/screen_session_manager_interface.h b/window_scene/screen_session_manager/include/zidl/screen_session_manager_interface.h index 5ee9e8fc25309dcdcd2f205eddd68711c8b347dc..66e290ff51c9389d3118ce9f807fac16c8fdeea5 100644 --- a/window_scene/screen_session_manager/include/zidl/screen_session_manager_interface.h +++ b/window_scene/screen_session_manager/include/zidl/screen_session_manager_interface.h @@ -296,6 +296,7 @@ public: return DMError::DM_ERROR_DEVICE_NOT_SUPPORT; } virtual void NotifyFoldToExpandCompletion(bool foldToExpand) {} + virtual void NotifyScreenConnectCompletion(ScreenId screenId) {} virtual void RecordEventFromScb(std::string description, bool needRecordEvent) {} virtual DeviceScreenConfig GetDeviceScreenConfig() { return {}; } virtual DMError SetVirtualScreenMaxRefreshRate(ScreenId id, uint32_t refreshRate, diff --git a/window_scene/screen_session_manager/include/zidl/screen_session_manager_proxy.h b/window_scene/screen_session_manager/include/zidl/screen_session_manager_proxy.h index 00e179d5d27a746c2d463e0ee5b6eced92a78dfe..4ad4cd818c198e262b4e02f3c6b122634512cbe5 100644 --- a/window_scene/screen_session_manager/include/zidl/screen_session_manager_proxy.h +++ b/window_scene/screen_session_manager/include/zidl/screen_session_manager_proxy.h @@ -199,6 +199,7 @@ public: virtual DMError GetAvailableArea(DisplayId displayId, DMRect& area) override; virtual DMError GetExpandAvailableArea(DisplayId displayId, DMRect& area) override; void NotifyFoldToExpandCompletion(bool foldToExpand) override; + void NotifyScreenConnectCompletion(ScreenId screenId) override; void RecordEventFromScb(std::string description, bool needRecordEvent) override; void SwitchUser() override; diff --git a/window_scene/screen_session_manager/src/multi_screen_manager.cpp b/window_scene/screen_session_manager/src/multi_screen_manager.cpp index f5916f573b20aa28e6a6f7dca684f9a5b12425ca..f3a51fe5156b32307a5b3affe2d0d96a063dedce 100644 --- a/window_scene/screen_session_manager/src/multi_screen_manager.cpp +++ b/window_scene/screen_session_manager/src/multi_screen_manager.cpp @@ -34,6 +34,7 @@ const std::string MULTI_SCREEN_EXIT_STR = "exit"; const std::string MULTI_SCREEN_ENTER_STR = "enter"; constexpr int32_t MULTI_SCREEN_EXIT = 0; constexpr int32_t MULTI_SCREEN_ENTER = 1; +constexpr uint32_t SCREEN_CONNECT_TIMEOUT = 500; } MultiScreenManager::MultiScreenManager() { @@ -148,6 +149,10 @@ DMError MultiScreenManager::PhysicalScreenUniqueSwitch(const std::vector(screenIds.size())); HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:PhysicalScreenUniqueSwitch start"); + { + std::unique_lock lock(uniqueScreenMutex_); + uniqueScreenTimeoutMap_.clear(); + } for (ScreenId physicalScreenId : screenIds) { auto screenSession = ScreenSessionManager::GetInstance().GetScreenSession(physicalScreenId); if (screenSession == nullptr) { @@ -158,6 +163,17 @@ DMError MultiScreenManager::PhysicalScreenUniqueSwitch(const std::vectorReuseDisplayNode(config); screenSession->SetVirtualPixelRatio(screenSession->GetScreenProperty().GetDefaultDensity()); ScreenSessionManager::GetInstance().OnVirtualScreenChange(physicalScreenId, ScreenEvent::CONNECTED); + std::unique_lock lock(uniqueScreenMutex_); + TLOGI(WmsLogTag::DMS, "innerName: %{public}s", screenSession->GetInnerName().c_str()); + if ((screenSession != nullptr) && (screenSession->GetInnerName() == "CustomScbScreen")) { + uniqueScreenTimeoutMap_[physicalScreenId] = true; + if (uniqueScreenCV_.wait_for(lock, std::chrono::milliseconds(SCREEN_CONNECT_TIMEOUT)) + == std::cv_status::timeout) { + uniqueScreenTimeoutMap_[physicalScreenId] = false; + TLOGE(WmsLogTag::DMS, "wait for unique screen connect timeout, screenId:%{public}" PRIu64, + physicalScreenId); + } + } ScreenSessionManager::GetInstance().RemoveScreenCastInfo(physicalScreenId); ScreenSessionManager::GetInstance().NotifyScreenChanged( screenSession->ConvertToScreenInfo(), ScreenChangeEvent::SCREEN_SOURCE_MODE_CHANGE); @@ -195,6 +211,10 @@ DMError MultiScreenManager::VirtualScreenUniqueSwitch(sptr screen ScreenSessionManager::GetInstance().ChangeScreenGroup(group, screenIds, startPoints, true, ScreenCombination::SCREEN_UNIQUE); + { + std::unique_lock lock(uniqueScreenMutex_); + uniqueScreenTimeoutMap_.clear(); + } for (ScreenId uniqueScreenId : screenIds) { auto uniqueScreen = ScreenSessionManager::GetInstance().GetScreenSession(uniqueScreenId); if (uniqueScreen != nullptr) { @@ -207,12 +227,34 @@ DMError MultiScreenManager::VirtualScreenUniqueSwitch(sptr screen ScreenSessionManager::GetInstance().RemoveScreenCastInfo(uniqueScreenId); // virtual screen create callback to notify scb ScreenSessionManager::GetInstance().OnVirtualScreenChange(uniqueScreenId, ScreenEvent::CONNECTED); + TLOGI(WmsLogTag::DMS, "innername: %{public}s", uniqueScreen->GetInnerName().c_str()); + if ((uniqueScreen != nullptr) && (uniqueScreen->GetInnerName() == "CustomScbScreen")) { + uniqueScreenTimeoutMap_[physicalScreenId] = true; + if (uniqueScreenCV_.wait_for(lock, std::chrono::milliseconds(SCREEN_CONNECT_TIMEOUT)) + == std::cv_status::timeout) { + uniqueScreenTimeoutMap_[physicalScreenId] = false; + TLOGE(WmsLogTag::DMS, "wait for screen connect timeout, screenId:%{public}" PRIu64, + physicalScreenId); + } + } } HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "dms:VirtualScreenUniqueSwitch end"); TLOGW(WmsLogTag::DMS, "to unique and notify scb end"); return DMError::DM_OK; } +void MultiScreenManager::NotifyScreenConnectCompletion(ScreenId screenId) +{ + std::unique_lock lock(uniqueScreenMutex_); + TLOGI(WmsLogTag::DMS, "ENTER, screenId:%{public}" PRIu64, screenId); + auto it = uniqueScreenTimeoutMap_.find(screenId); + if (it != uniqueScreenTimeoutMap_.end()) { + if (it->second) { + uniqueScreenCV_.notify_all(); + } + } +} + static void AddUniqueScreenDisplayId(std::vector& displayIds, std::vector& screenIds, DMError& switchStatus) { diff --git a/window_scene/screen_session_manager/src/screen_session_manager.cpp b/window_scene/screen_session_manager/src/screen_session_manager.cpp index d49eb0242204c6386b1ef5d3658057b5271cefc0..866302639b51fb0ea46b825c9b4f9831d541f334 100644 --- a/window_scene/screen_session_manager/src/screen_session_manager.cpp +++ b/window_scene/screen_session_manager/src/screen_session_manager.cpp @@ -5524,6 +5524,18 @@ DMError ScreenSessionManager::DoMakeUniqueScreenOld(const std::vector& return DMError::DM_OK; } +void ScreenSessionManager::NotifyScreenConnectCompletion(ScreenId screenId) +{ +#ifdef WM_MULTI_SCREEN_ENABLE + TLOGI(WmsLogTag::DMS, "ENTER, screenId:%{public}" PRIu64, screenId); + if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) { + TLOGE(WmsLogTag::DMS, "permission denied!"); + return; + } + MultiScreenManager::GetInstance().NotifyScreenConnectCompletion(screenId); +#endif +} + DMError ScreenSessionManager::MakeExpand(std::vector screenId, std::vector startPoint, ScreenId& screenGroupId) diff --git a/window_scene/screen_session_manager/src/zidl/screen_session_manager_proxy.cpp b/window_scene/screen_session_manager/src/zidl/screen_session_manager_proxy.cpp index dfe0b90cead47d6c4c25f82f87031c0f028f2658..e95081d391470e03251d87ba6e2537e86a37aab3 100644 --- a/window_scene/screen_session_manager/src/zidl/screen_session_manager_proxy.cpp +++ b/window_scene/screen_session_manager/src/zidl/screen_session_manager_proxy.cpp @@ -3600,6 +3600,33 @@ void ScreenSessionManagerProxy::NotifyFoldToExpandCompletion(bool foldToExpand) } } +void ScreenSessionManagerProxy::NotifyScreenConnectCompletion(ScreenId screenId) +{ + sptr remote = Remote(); + if (remote == nullptr) { + TLOGE(WmsLogTag::DMS, "remote is null"); + return; + } + + MessageOption option(MessageOption::TF_ASYNC); + MessageParcel reply; + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + TLOGE(WmsLogTag::DMS, "WriteInterfaceToken failed"); + return ; + } + if (!data.WriteUint64(screenId)) { + TLOGE(WmsLogTag::DMS, "Write screenId failed"); + return; + } + if (remote->SendRequest(static_cast(DisplayManagerMessage::TRANS_ID_SCREEN_CONNECT_COMPLETION), + data, reply, option) != ERR_NONE) { + TLOGE(WmsLogTag::DMS, "SendRequest failed"); + return; + } +} + + void ScreenSessionManagerProxy::RecordEventFromScb(std::string description, bool needRecordEvent) { sptr remote = Remote(); diff --git a/window_scene/screen_session_manager/src/zidl/screen_session_manager_stub.cpp b/window_scene/screen_session_manager/src/zidl/screen_session_manager_stub.cpp index c48e9a649387a8a602f0477f5e51ce3e394f7e73..8b1f04856bb33186ef8c7cf1cdf5b7f61ddacc39 100644 --- a/window_scene/screen_session_manager/src/zidl/screen_session_manager_stub.cpp +++ b/window_scene/screen_session_manager/src/zidl/screen_session_manager_stub.cpp @@ -1074,6 +1074,11 @@ int32_t ScreenSessionManagerStub::OnRemoteRequest(uint32_t code, MessageParcel& NotifyFoldToExpandCompletion(foldToExpand); break; } + case DisplayManagerMessage::TRANS_ID_SCREEN_CONNECT_COMPLETION: { + ScreenId screenId = static_cast(data.ReadUint64()); + NotifyScreenConnectCompletion(screenId); + break; + } case DisplayManagerMessage::TRANS_ID_GET_VIRTUAL_SCREEN_FLAG: { ProcGetVirtualScreenFlag(data, reply); break; diff --git a/window_scene/screen_session_manager_client/include/screen_session_manager_client.h b/window_scene/screen_session_manager_client/include/screen_session_manager_client.h index df3f53795b53f0a188fe097838aaa52af834e211..2ff562231177db5a96e04c1e27b1972d12499aba 100644 --- a/window_scene/screen_session_manager_client/include/screen_session_manager_client.h +++ b/window_scene/screen_session_manager_client/include/screen_session_manager_client.h @@ -84,6 +84,7 @@ public: int32_t SetScreenOnDelayTime(int32_t delay); void SetCameraStatus(int32_t cameraStatus, int32_t cameraPosition); void NotifyFoldToExpandCompletion(bool foldToExpand); + void NotifyScreenConnectCompletion(ScreenId screenId); void RecordEventFromScb(std::string description, bool needRecordEvent); FoldStatus GetFoldStatus(); SuperFoldStatus GetSuperFoldStatus(); diff --git a/window_scene/screen_session_manager_client/src/screen_session_manager_client.cpp b/window_scene/screen_session_manager_client/src/screen_session_manager_client.cpp index c931a3bf91e56d736abc58ead8a37c2988ef60dd..8e0fa42b441a09679c696a691a4d3a82f4a60290 100644 --- a/window_scene/screen_session_manager_client/src/screen_session_manager_client.cpp +++ b/window_scene/screen_session_manager_client/src/screen_session_manager_client.cpp @@ -564,6 +564,15 @@ void ScreenSessionManagerClient::NotifyFoldToExpandCompletion(bool foldToExpand) screenSessionManager_->NotifyFoldToExpandCompletion(foldToExpand); } +void ScreenSessionManagerClient::NotifyScreenConnectCompletion(ScreenId screenId) +{ + if (!screenSessionManager_) { + TLOGE(WmsLogTag::DMS, "screenSessionManager_ is null"); + return; + } + screenSessionManager_->NotifyScreenConnectCompletion(screenId); +} + void ScreenSessionManagerClient::RecordEventFromScb(std::string description, bool needRecordEvent) { if (!screenSessionManager_) {