/* * Copyright (c) 2025 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 "rs_adapter.h" #include #include "window_manager_hilog.h" #define RETURN_IF_PARAM_IS_NULL(param, ...) \ do { \ if (!param) { \ TLOGE(WmsLogTag::WMS_SCB, "The %{public}s is null", #param); \ return __VA_ARGS__; \ } \ } while (false) \ namespace OHOS { namespace Rosen { InvokerType RSTransactionAdapter::invokerType_ = InvokerType::NONE; // LCOV_EXCL_START RSTransactionAdapter::RSTransactionAdapter(const std::shared_ptr& rsUIContext) { rsUIContext_ = rsUIContext; if (RSAdapterUtil::IsClientMultiInstanceEnabled()) { rsTransHandler_ = rsUIContext_ ? rsUIContext_->GetRSTransaction() : nullptr; rsTransProxy_ = nullptr; TLOGD(WmsLogTag::WMS_SCB, "Use RSTransactionHandler: %{public}s", RSAdapterUtil::RSUIContextToStr(rsUIContext_).c_str()); } else { rsTransHandler_ = nullptr; rsTransProxy_ = RSTransactionProxy::GetInstance(); TLOGD(WmsLogTag::WMS_SCB, "Fallback to RSTransactionProxy"); } } RSTransactionAdapter::RSTransactionAdapter(const std::shared_ptr& rsNode) : RSTransactionAdapter(rsNode ? rsNode->GetRSUIContext() : nullptr) {} RSTransactionAdapter::RSTransactionAdapter(const std::shared_ptr& rsUIDirector) : RSTransactionAdapter(rsUIDirector ? rsUIDirector->GetRSUIContext() : nullptr) {} std::shared_ptr RSTransactionAdapter::GetRSUIContext() const { RETURN_IF_RS_CLIENT_MULTI_INSTANCE_DISABLED(nullptr); return rsUIContext_; } template void RSTransactionAdapter::InvokeTransaction(Func&& func, const char* caller) { invokerType_ = InvokerType::NONE; if (RSAdapterUtil::IsClientMultiInstanceEnabled()) { RETURN_IF_PARAM_IS_NULL(rsTransHandler_); invokerType_ = InvokerType::RS_TRANSACTION_HANDLER; TLOGND(WmsLogTag::WMS_SCB, "%{public}s: Use RSTransactionHandler: %{public}s", caller, RSAdapterUtil::RSUIContextToStr(rsUIContext_).c_str()); func(rsTransHandler_); } else { RETURN_IF_PARAM_IS_NULL(rsTransProxy_); invokerType_ = InvokerType::RS_TRANSACTION_PROXY; TLOGND(WmsLogTag::WMS_SCB, "%{public}s: Fallback to RSTransactionProxy", caller); func(rsTransProxy_); } } void RSTransactionAdapter::Begin() { InvokeTransaction( [](auto& invoker) { RETURN_IF_PARAM_IS_NULL(invoker); invoker->Begin(); }, __func__); } void RSTransactionAdapter::Commit(uint64_t timestamp) { InvokeTransaction( [timestamp](auto& invoker) { RETURN_IF_PARAM_IS_NULL(invoker); invoker->Commit(timestamp); }, __func__); } void RSTransactionAdapter::FlushImplicitTransaction(uint64_t timestamp, const std::string& abilityName) { InvokeTransaction( [timestamp, &abilityName](auto& invoker) { RETURN_IF_PARAM_IS_NULL(invoker); invoker->FlushImplicitTransaction(timestamp, abilityName); }, __func__); } // LCOV_EXCL_STOP void RSTransactionAdapter::FlushImplicitTransaction( const std::shared_ptr& rsUIContext, uint64_t timestamp, const std::string& abilityName) { invokerType_ = InvokerType::NONE; if (RSAdapterUtil::IsClientMultiInstanceEnabled()) { auto rsTransHandler = rsUIContext ? rsUIContext->GetRSTransaction() : nullptr; RETURN_IF_PARAM_IS_NULL(rsTransHandler); invokerType_ = InvokerType::RS_TRANSACTION_HANDLER; TLOGD(WmsLogTag::WMS_SCB, "Use RSTransactionHandler: %{public}s", RSAdapterUtil::RSUIContextToStr(rsUIContext).c_str()); rsTransHandler->FlushImplicitTransaction(timestamp, abilityName); } else { auto rsTransProxy = RSTransactionProxy::GetInstance(); RETURN_IF_PARAM_IS_NULL(rsTransProxy); invokerType_ = InvokerType::RS_TRANSACTION_PROXY; TLOGD(WmsLogTag::WMS_SCB, "Fallback to RSTransactionProxy"); rsTransProxy->FlushImplicitTransaction(timestamp, abilityName); } } // LCOV_EXCL_START void RSTransactionAdapter::FlushImplicitTransaction( const std::unordered_set>& rsUIContexts, uint64_t timestamp, const std::string& abilityName) { if (!RSAdapterUtil::IsClientMultiInstanceEnabled()) { FlushImplicitTransaction(std::shared_ptr(nullptr), timestamp, abilityName); return; } for (const auto& rsUIContext : rsUIContexts) { FlushImplicitTransaction(rsUIContext, timestamp, abilityName); } } void RSTransactionAdapter::FlushImplicitTransaction( std::initializer_list> rsUIContexts, uint64_t timestamp, const std::string& abilityName) { if (!RSAdapterUtil::IsClientMultiInstanceEnabled()) { FlushImplicitTransaction(std::shared_ptr(nullptr), timestamp, abilityName); return; } std::unordered_set> rsUIContextSet; for (const auto& rsUIContext : rsUIContexts) { rsUIContextSet.insert(rsUIContext); } FlushImplicitTransaction(rsUIContextSet, timestamp, abilityName); } void RSTransactionAdapter::FlushImplicitTransaction( const std::shared_ptr& rsUIDirector, uint64_t timestamp, const std::string& abilityName) { FlushImplicitTransaction(rsUIDirector ? rsUIDirector->GetRSUIContext() : nullptr, timestamp, abilityName); } void RSTransactionAdapter::FlushImplicitTransaction( std::initializer_list> rsUIDirectors, uint64_t timestamp, const std::string& abilityName) { if (!RSAdapterUtil::IsClientMultiInstanceEnabled()) { FlushImplicitTransaction(std::shared_ptr(nullptr), timestamp, abilityName); return; } std::unordered_set> rsUIContexts; for (const auto& rsUIDirector : rsUIDirectors) { rsUIContexts.insert(rsUIDirector ? rsUIDirector->GetRSUIContext() : nullptr); } FlushImplicitTransaction(rsUIContexts, timestamp, abilityName); } // LCOV_EXCL_STOP void RSTransactionAdapter::FlushImplicitTransaction( const std::shared_ptr& rsNode, uint64_t timestamp, const std::string& abilityName) { TLOGD(WmsLogTag::WMS_SCB, "%{public}s", RSAdapterUtil::RSNodeToStr(rsNode).c_str()); FlushImplicitTransaction(rsNode ? rsNode->GetRSUIContext() : nullptr, timestamp, abilityName); } // LCOV_EXCL_START void RSTransactionAdapter::FlushImplicitTransaction( std::initializer_list> rsNodes, uint64_t timestamp, const std::string& abilityName) { if (!RSAdapterUtil::IsClientMultiInstanceEnabled()) { FlushImplicitTransaction(std::shared_ptr(nullptr), timestamp, abilityName); return; } std::unordered_set> rsUIContexts; for (const auto& rsNode : rsNodes) { TLOGD(WmsLogTag::WMS_SCB, "%{public}s", RSAdapterUtil::RSNodeToStr(rsNode).c_str()); rsUIContexts.insert(rsNode ? rsNode->GetRSUIContext() : nullptr); } FlushImplicitTransaction(rsUIContexts, timestamp, abilityName); } AutoRSTransaction::AutoRSTransaction(const std::shared_ptr& rsUIContext, bool enable) { if (enable) { rsTransAdapter_ = std::make_shared(rsUIContext); rsTransAdapter_->Begin(); } else { rsTransAdapter_ = nullptr; } } AutoRSTransaction::AutoRSTransaction(const std::shared_ptr& rsNode, bool enable) : AutoRSTransaction(rsNode ? rsNode->GetRSUIContext() : nullptr, enable) { TLOGD(WmsLogTag::WMS_SCB, "%{public}s", RSAdapterUtil::RSNodeToStr(rsNode).c_str()); } AutoRSTransaction::AutoRSTransaction(const std::shared_ptr& rsTransAdapter, bool enable) { if (rsTransAdapter != nullptr && enable) { rsTransAdapter_ = rsTransAdapter; rsTransAdapter_->Begin(); } else { rsTransAdapter_ = nullptr; } } AutoRSTransaction::~AutoRSTransaction() { if (rsTransAdapter_) { rsTransAdapter_->Commit(); } } InvokerType RSSyncTransactionAdapter::invokerType_ = InvokerType::NONE; RSSyncTransactionAdapter::RSSyncTransactionAdapter(const std::shared_ptr& rsUIContext) { rsUIContext_ = rsUIContext; if (RSAdapterUtil::IsClientMultiInstanceEnabled()) { rsSyncTransHandler_ = rsUIContext_ ? rsUIContext_->GetSyncTransactionHandler() : nullptr; rsSyncTransController_ = nullptr; TLOGD(WmsLogTag::WMS_SCB, "Use RSSyncTransactionHandler: %{public}s", RSAdapterUtil::RSUIContextToStr(rsUIContext_).c_str()); } else { rsSyncTransHandler_ = nullptr; rsSyncTransController_ = RSSyncTransactionController::GetInstance(); TLOGD(WmsLogTag::WMS_SCB, "Fallback to RSSyncTransactionController"); } } RSSyncTransactionAdapter::RSSyncTransactionAdapter(const std::shared_ptr& rsNode) : RSSyncTransactionAdapter(rsNode ? rsNode->GetRSUIContext() : nullptr) {} template ReturnType RSSyncTransactionAdapter::InvokeSyncTransaction(Func&& func, const char* caller) { invokerType_ = InvokerType::NONE; if (RSAdapterUtil::IsClientMultiInstanceEnabled()) { if (rsSyncTransHandler_) { invokerType_ = InvokerType::RS_SYNC_TRANSACTION_HANDLER; TLOGND(WmsLogTag::WMS_SCB, "%{public}s: Use RSSyncTransactionHandler: %{public}s", caller, RSAdapterUtil::RSUIContextToStr(rsUIContext_).c_str()); return func(rsSyncTransHandler_); } } else { if (rsSyncTransController_) { invokerType_ = InvokerType::RS_SYNC_TRANSACTION_CONTROLLER; TLOGND(WmsLogTag::WMS_SCB, "%{public}s: Fallback to RSSyncTransactionController", caller); return func(rsSyncTransController_); } } TLOGNE(WmsLogTag::WMS_SCB, "%{public}s: Failed to invoke RSSyncTransaction", caller); if constexpr (!std::is_void_v) { return nullptr; } } std::shared_ptr RSSyncTransactionAdapter::GetRSUIContext() const { RETURN_IF_RS_CLIENT_MULTI_INSTANCE_DISABLED(nullptr); TLOGD(WmsLogTag::WMS_SCB, "%{public}s", RSAdapterUtil::RSUIContextToStr(rsUIContext_).c_str()); return rsUIContext_; } std::shared_ptr RSSyncTransactionAdapter::GetRSTransaction() { return InvokeSyncTransaction>( [](auto& invoker) { RETURN_IF_PARAM_IS_NULL(invoker, std::shared_ptr(nullptr)); return invoker->GetRSTransaction(); }, __func__); } void RSSyncTransactionAdapter::OpenSyncTransaction(const std::shared_ptr& handler) { InvokeSyncTransaction( [handler](auto& invoker) { RETURN_IF_PARAM_IS_NULL(invoker); invoker->OpenSyncTransaction(handler); }, __func__); } void RSSyncTransactionAdapter::CloseSyncTransaction(const std::shared_ptr& handler) { InvokeSyncTransaction( [handler](auto& invoker) { RETURN_IF_PARAM_IS_NULL(invoker); invoker->CloseSyncTransaction(handler); }, __func__); } template ReturnType RSSyncTransactionAdapter::InvokeSyncTransaction( const std::shared_ptr& rsUIContext, Func&& func, const char* caller) { invokerType_ = InvokerType::NONE; if (RSAdapterUtil::IsClientMultiInstanceEnabled()) { auto rsSyncTransHandler = rsUIContext ? rsUIContext->GetSyncTransactionHandler() : nullptr; if (rsSyncTransHandler) { invokerType_ = InvokerType::RS_SYNC_TRANSACTION_HANDLER; TLOGND(WmsLogTag::WMS_SCB, "%{public}s: Use RSSyncTransactionHandler: %{public}s", caller, RSAdapterUtil::RSUIContextToStr(rsUIContext).c_str()); return func(rsSyncTransHandler); } } else { auto rsSyncTransController = RSSyncTransactionController::GetInstance(); if (rsSyncTransController) { invokerType_ = InvokerType::RS_SYNC_TRANSACTION_CONTROLLER; TLOGND(WmsLogTag::WMS_SCB, "%{public}s: Fallback to RSSyncTransactionController", caller); return func(rsSyncTransController); } } TLOGNE(WmsLogTag::WMS_SCB, "%{public}s: Failed to invoke RSSyncTransaction", caller); if constexpr (!std::is_void_v) { return nullptr; } } std::shared_ptr RSSyncTransactionAdapter::GetRSTransaction( const std::shared_ptr& rsUIContext) { return InvokeSyncTransaction>( rsUIContext, [](auto& invoker) { RETURN_IF_PARAM_IS_NULL(invoker, std::shared_ptr(nullptr)); return invoker->GetRSTransaction(); }, __func__); } std::shared_ptr RSSyncTransactionAdapter::GetRSTransaction(const std::shared_ptr& rsNode) { TLOGD(WmsLogTag::WMS_SCB, "%{public}s", RSAdapterUtil::RSNodeToStr(rsNode).c_str()); return GetRSTransaction(rsNode ? rsNode->GetRSUIContext() : nullptr); } void RSSyncTransactionAdapter::OpenSyncTransaction( const std::shared_ptr& rsUIContext, const std::shared_ptr& handler) { InvokeSyncTransaction( rsUIContext, [handler](auto& invoker) { RETURN_IF_PARAM_IS_NULL(invoker); invoker->OpenSyncTransaction(handler); }, __func__); } void RSSyncTransactionAdapter::OpenSyncTransaction( const std::shared_ptr& rsNode, const std::shared_ptr& handler) { TLOGD(WmsLogTag::WMS_SCB, "%{public}s", RSAdapterUtil::RSNodeToStr(rsNode).c_str()); OpenSyncTransaction(rsNode ? rsNode->GetRSUIContext() : nullptr, handler); } void RSSyncTransactionAdapter::CloseSyncTransaction( const std::shared_ptr& rsUIContext, const std::shared_ptr& handler) { InvokeSyncTransaction( rsUIContext, [handler](auto& invoker) { RETURN_IF_PARAM_IS_NULL(invoker); invoker->CloseSyncTransaction(handler); }, __func__); } void RSSyncTransactionAdapter::CloseSyncTransaction( const std::shared_ptr& rsNode, const std::shared_ptr& handler) { TLOGD(WmsLogTag::WMS_SCB, "%{public}s", RSAdapterUtil::RSNodeToStr(rsNode).c_str()); CloseSyncTransaction(rsNode ? rsNode->GetRSUIContext() : nullptr, handler); } AutoRSSyncTransaction::AutoRSSyncTransaction( const std::shared_ptr& rsUIContext, bool needFlushImplicitTransaction, const std::shared_ptr& handler) : handler_(handler) { if (needFlushImplicitTransaction) { RSTransactionAdapter::FlushImplicitTransaction(rsUIContext); } rsSyncTransAdapter_ = std::make_shared(rsUIContext); rsSyncTransAdapter_->OpenSyncTransaction(handler_); } AutoRSSyncTransaction::AutoRSSyncTransaction( const std::shared_ptr& rsNode, bool needFlushImplicitTransaction, const std::shared_ptr& handler) : AutoRSSyncTransaction(rsNode ? rsNode->GetRSUIContext() : nullptr, needFlushImplicitTransaction, handler) { TLOGD(WmsLogTag::WMS_SCB, "%{public}s", RSAdapterUtil::RSNodeToStr(rsNode).c_str()); } AutoRSSyncTransaction::AutoRSSyncTransaction( const std::shared_ptr& rsSyncTransAdapter, bool needFlushImplicitTransaction, const std::shared_ptr& handler) : rsSyncTransAdapter_(rsSyncTransAdapter), handler_(handler) { if (rsSyncTransAdapter_) { if (needFlushImplicitTransaction) { RSTransactionAdapter::FlushImplicitTransaction(rsSyncTransAdapter_->GetRSUIContext()); } rsSyncTransAdapter_->OpenSyncTransaction(handler); } } AutoRSSyncTransaction::~AutoRSSyncTransaction() { if (rsSyncTransAdapter_) { rsSyncTransAdapter_->CloseSyncTransaction(handler_); } } AllowInMultiThreadGuard::AllowInMultiThreadGuard(const std::shared_ptr& rsNode) : rsNode_(rsNode) { if (rsNode_) { TLOGD(WmsLogTag::WMS_SCB, "Skip check in RS multi-instance: %{public}s", RSAdapterUtil::RSNodeToStr(rsNode_).c_str()); rsNode_->SetSkipCheckInMultiInstance(true); } } AllowInMultiThreadGuard::~AllowInMultiThreadGuard() { if (rsNode_) { TLOGD(WmsLogTag::WMS_SCB, "Reopen check in RS multi-instance: %{public}s", RSAdapterUtil::RSNodeToStr(rsNode_).c_str()); rsNode_->SetSkipCheckInMultiInstance(false); } } // LCOV_EXCL_STOP bool RSAdapterUtil::IsClientMultiInstanceEnabled() { static bool enabled = [] { bool value = system::GetParameter("persist.rosen.rsclientmultiinstance.enabled", "0") != "0"; TLOGNI(WmsLogTag::WMS_SCB, "RS multi-instance enabled: %{public}d", value); return value; }(); return enabled; } void RSAdapterUtil::InitRSUIDirector(std::shared_ptr& rsUIDirector, bool shouldCreateRenderThread, bool isMultiInstance) { RETURN_IF_RS_CLIENT_MULTI_INSTANCE_DISABLED(); if (rsUIDirector) { TLOGW(WmsLogTag::WMS_SCB, "RSUIDirector already exists: %{public}s", RSAdapterUtil::RSUIDirectorToStr(rsUIDirector).c_str()); return; } rsUIDirector = RSUIDirector::Create(); if (rsUIDirector) { rsUIDirector->Init(shouldCreateRenderThread, isMultiInstance); TLOGI(WmsLogTag::WMS_SCB, "Create RSUIDirector: %{public}s", RSAdapterUtil::RSUIDirectorToStr(rsUIDirector).c_str()); } else { TLOGE(WmsLogTag::WMS_SCB, "Failed to create RSUIDirector"); } } // LCOV_EXCL_START void RSAdapterUtil::SetRSUIContext(const std::shared_ptr& rsNode, const std::shared_ptr& rsUIContext, bool skipCheckInMultiInstance) { RETURN_IF_RS_CLIENT_MULTI_INSTANCE_DISABLED(); if (!rsNode) { TLOGE(WmsLogTag::WMS_SCB, "RSNode is null"); return; } // The creation of RSUIContext and the use of RSNode may occur in different // threads, so skip checks can be set. rsNode->SetSkipCheckInMultiInstance(skipCheckInMultiInstance); if (!rsUIContext) { TLOGE(WmsLogTag::WMS_SCB, "RSUIContext is null, %{public}s", RSAdapterUtil::RSNodeToStr(rsNode).c_str()); return; } auto originalRSUIContext = rsNode->GetRSUIContext(); if (rsUIContext == originalRSUIContext) { TLOGD(WmsLogTag::WMS_SCB, "RSNode already has the same RSUIContext, %{public}s", RSAdapterUtil::RSNodeToStr(rsNode).c_str()); return; } rsNode->SetRSUIContext(rsUIContext); TLOGD(WmsLogTag::WMS_SCB, "%{public}s, skipCheckInMultiInstance = %{public}d, original %{public}s", RSAdapterUtil::RSNodeToStr(rsNode).c_str(), skipCheckInMultiInstance, RSAdapterUtil::RSUIContextToStr(originalRSUIContext).c_str()); } // LCOV_EXCL_STOP void RSAdapterUtil::SetRSTransactionHandler(const std::shared_ptr& rsTransaction, const std::shared_ptr& rsUIContext) { RETURN_IF_RS_CLIENT_MULTI_INSTANCE_DISABLED(); RETURN_IF_PARAM_IS_NULL(rsTransaction); RETURN_IF_PARAM_IS_NULL(rsUIContext); auto rsTransHandler = rsUIContext->GetRSTransaction(); RETURN_IF_PARAM_IS_NULL(rsTransHandler); rsTransaction->SetTransactionHandler(rsTransHandler); TLOGD(WmsLogTag::WMS_SCB, "syncId: %{public}" PRIu64 ", %{public}s", rsTransaction->GetSyncId(), RSAdapterUtil::RSUIContextToStr(rsUIContext).c_str()); } void RSAdapterUtil::SetSkipCheckInMultiInstance(const std::shared_ptr& rsNode, bool skipCheckInMultiInstance) { RETURN_IF_RS_CLIENT_MULTI_INSTANCE_DISABLED(); RETURN_IF_PARAM_IS_NULL(rsNode); rsNode->SetSkipCheckInMultiInstance(skipCheckInMultiInstance); TLOGD(WmsLogTag::WMS_SCB, "%{public}s, skipCheckInMultiInstance = %{public}d", RSAdapterUtil::RSNodeToStr(rsNode).c_str(), skipCheckInMultiInstance); } // LCOV_EXCL_START const std::shared_ptr RSAdapterUtil::GetRSNode( const std::shared_ptr& rsUIContext, NodeId id) { if (!RSAdapterUtil::IsClientMultiInstanceEnabled()) { return RSNodeMap::Instance().GetNode(id); } RETURN_IF_PARAM_IS_NULL(rsUIContext, nullptr); return rsUIContext->GetNodeMap().GetNode(id); } // LCOV_EXCL_STOP std::string RSAdapterUtil::RSUIContextToStr(const std::shared_ptr& rsUIContext) { if (!rsUIContext) { return "RSUIContext is null"; } std::ostringstream oss; oss << "RSUIContext [token: " << rsUIContext->GetToken() << ", tid: " << static_cast(rsUIContext->GetToken() >> 32) // 32: tid's offset position in the token << "]"; return oss.str(); } std::string RSAdapterUtil::RSNodeToStr(const std::shared_ptr& rsNode) { if (!rsNode) { return "RSNode is null"; } std::ostringstream oss; oss << "RSNode [id: " << rsNode->GetId() << "], " << RSUIContextToStr(rsNode->GetRSUIContext()); return oss.str(); } std::string RSAdapterUtil::RSUIDirectorToStr(const std::shared_ptr& rsUIDirector) { if (!rsUIDirector) { return "RSUIDirector is null"; } std::ostringstream oss; oss << "RSUIDirector's " << RSUIContextToStr(rsUIDirector->GetRSUIContext()); return oss.str(); } } // namespace Rosen } // namespace OHOS