1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "rs_adapter.h" 17 18 #include <gtest/gtest.h> 19 #include <gmock/gmock.h> 20 21 #include "modifier_render_thread/rs_modifiers_draw_thread.h" 22 #include "ui/rs_surface_node.h" 23 24 using namespace testing; 25 using namespace testing::ext; 26 27 namespace OHOS { 28 namespace Rosen { 29 class RSAdapterTest : public Test { 30 public: SetUpTestCase()31 static void SetUpTestCase() 32 { 33 rsClientMultiInstanceEnabled_ = RSAdapterUtil::IsClientMultiInstanceEnabled(); 34 if (rsClientMultiInstanceEnabled_) { 35 rsUIDirector_ = RSUIDirector::Create(); 36 rsUIDirector_->Init(true, true); 37 rsUIContext_ = rsUIDirector_->GetRSUIContext(); 38 } 39 struct RSSurfaceNodeConfig config; 40 rsNode_ = RSSurfaceNode::Create(config, true, rsUIContext_); 41 } 42 TearDownTestCase()43 static void TearDownTestCase() 44 { 45 rsNode_.reset(); 46 rsUIContext_.reset(); 47 rsUIDirector_.reset(); 48 #ifdef RS_ENABLE_VK 49 RSModifiersDrawThread::Destroy(); 50 #endif 51 } 52 SetUp()53 void SetUp() override {} TearDown()54 void TearDown() override {} 55 56 private: 57 static bool rsClientMultiInstanceEnabled_; 58 static std::shared_ptr<RSNode> rsNode_; 59 static std::shared_ptr<RSUIContext> rsUIContext_; 60 static std::shared_ptr<RSUIDirector> rsUIDirector_; 61 }; 62 63 std::shared_ptr<RSNode> RSAdapterTest::rsNode_ = nullptr; 64 std::shared_ptr<RSUIContext> RSAdapterTest::rsUIContext_ = nullptr; 65 std::shared_ptr<RSUIDirector> RSAdapterTest::rsUIDirector_ = nullptr; 66 bool RSAdapterTest::rsClientMultiInstanceEnabled_ = false; 67 68 class MockRSTransactionAdapter : public RSTransactionAdapter { 69 public: MockRSTransactionAdapter(const std::shared_ptr<RSUIContext> & rsUIContext)70 explicit MockRSTransactionAdapter(const std::shared_ptr<RSUIContext>& rsUIContext) 71 : RSTransactionAdapter(rsUIContext) {} 72 MOCK_METHOD(void, Begin, (), (override)); 73 MOCK_METHOD(void, Commit, (uint64_t timestamp), (override)); 74 }; 75 76 class MockRSSyncTransactionAdapter : public RSSyncTransactionAdapter { 77 public: MockRSSyncTransactionAdapter(const std::shared_ptr<RSUIContext> & rsUIContext)78 explicit MockRSSyncTransactionAdapter(const std::shared_ptr<RSUIContext>& rsUIContext) 79 : RSSyncTransactionAdapter(rsUIContext) {} 80 MOCK_METHOD(void, OpenSyncTransaction, (const std::shared_ptr<AppExecFwk::EventHandler>& handler), (override)); 81 MOCK_METHOD(void, CloseSyncTransaction, (const std::shared_ptr<AppExecFwk::EventHandler>& handler), (override)); 82 }; 83 84 /** 85 * @tc.name: RSTransactionAdapterConstructor 86 * @tc.desc: Verify RSTransactionAdapter constructed with RSUIContext. 87 * @tc.type: FUNC 88 */ 89 HWTEST_F(RSAdapterTest, RSTransactionAdapterConstructor, Function | SmallTest | Level1) 90 { 91 RSTransactionAdapter adapter(rsUIContext_); 92 if (rsClientMultiInstanceEnabled_) { 93 EXPECT_NE(adapter.rsTransHandler_, nullptr); 94 EXPECT_EQ(adapter.rsTransProxy_, nullptr); 95 } else { 96 EXPECT_EQ(adapter.rsTransHandler_, nullptr); 97 EXPECT_NE(adapter.rsTransProxy_, nullptr); 98 } 99 } 100 101 /** 102 * @tc.name: RSTransactionAdapterBegin 103 * @tc.desc: Verify RSTransactionAdapter::Begin works. 104 * @tc.type: FUNC 105 */ 106 HWTEST_F(RSAdapterTest, RSTransactionAdapterBegin, Function | SmallTest | Level1) 107 { 108 RSTransactionAdapter adapter(rsUIContext_); 109 adapter.Begin(); 110 if (rsClientMultiInstanceEnabled_) { 111 EXPECT_EQ(RSTransactionAdapter::invokerType_, InvokerType::RS_TRANSACTION_HANDLER); 112 } else { 113 EXPECT_EQ(RSTransactionAdapter::invokerType_, InvokerType::RS_TRANSACTION_PROXY); 114 } 115 } 116 117 /** 118 * @tc.name: RSTransactionAdapterCommit 119 * @tc.desc: Verify RSTransactionAdapter::Commit works. 120 * @tc.type: FUNC 121 */ 122 HWTEST_F(RSAdapterTest, RSTransactionAdapterCommit, Function | SmallTest | Level1) 123 { 124 RSTransactionAdapter adapter(rsUIContext_); 125 adapter.Commit(); 126 if (rsClientMultiInstanceEnabled_) { 127 EXPECT_EQ(RSTransactionAdapter::invokerType_, InvokerType::RS_TRANSACTION_HANDLER); 128 } else { 129 EXPECT_EQ(RSTransactionAdapter::invokerType_, InvokerType::RS_TRANSACTION_PROXY); 130 } 131 } 132 133 /** 134 * @tc.name: RSTransactionAdapterFlushImplicitTransaction 135 * @tc.desc: Verify RSTransactionAdapter::FlushImplicitTransaction (member function). 136 * @tc.type: FUNC 137 */ 138 HWTEST_F(RSAdapterTest, RSTransactionAdapterFlushImplicitTransaction, Function | SmallTest | Level1) 139 { 140 RSTransactionAdapter adapter(rsUIContext_); 141 adapter.FlushImplicitTransaction(); 142 if (rsClientMultiInstanceEnabled_) { 143 EXPECT_EQ(RSTransactionAdapter::invokerType_, InvokerType::RS_TRANSACTION_HANDLER); 144 } else { 145 EXPECT_EQ(RSTransactionAdapter::invokerType_, InvokerType::RS_TRANSACTION_PROXY); 146 } 147 } 148 149 /** 150 * @tc.name: RSTransactionAdapterStaticFlushImplicitTransaction 151 * @tc.desc: Verify static FlushImplicitTransaction with RSUIContext. 152 * @tc.type: FUNC 153 */ 154 HWTEST_F(RSAdapterTest, RSTransactionAdapterStaticFlushImplicitTransaction, Function | SmallTest | Level1) 155 { 156 RSTransactionAdapter::FlushImplicitTransaction(rsUIContext_); 157 if (rsClientMultiInstanceEnabled_) { 158 EXPECT_EQ(RSTransactionAdapter::invokerType_, InvokerType::RS_TRANSACTION_HANDLER); 159 } else { 160 EXPECT_EQ(RSTransactionAdapter::invokerType_, InvokerType::RS_TRANSACTION_PROXY); 161 } 162 } 163 164 /** 165 * @tc.name: AutoRSTransactionLifecycle 166 * @tc.desc: Verify AutoRSTransaction lifecycle (Begin + Commit). 167 * @tc.type: FUNC 168 */ 169 HWTEST_F(RSAdapterTest, AutoRSTransactionLifecycle, Function | SmallTest | Level1) 170 { 171 auto mockAdapter = std::make_shared<MockRSTransactionAdapter>(rsUIContext_); 172 EXPECT_CALL(*mockAdapter, Begin()) 173 .Times(1); 174 EXPECT_CALL(*mockAdapter, Commit(_)) 175 .Times(1); 176 177 { 178 AutoRSTransaction autoTransaction(mockAdapter, true); 179 } 180 } 181 182 /** 183 * @tc.name: RSSyncTransactionAdapterConstructor 184 * @tc.desc: Verify RSSyncTransactionAdapter constructed with RSUIContext. 185 * @tc.type: FUNC 186 */ 187 HWTEST_F(RSAdapterTest, RSSyncTransactionAdapterConstructor, Function | SmallTest | Level1) 188 { 189 RSSyncTransactionAdapter adapter(rsUIContext_); 190 if (rsClientMultiInstanceEnabled_) { 191 EXPECT_NE(adapter.rsSyncTransHandler_, nullptr); 192 EXPECT_EQ(adapter.rsSyncTransController_, nullptr); 193 } else { 194 EXPECT_EQ(adapter.rsSyncTransHandler_, nullptr); 195 EXPECT_NE(adapter.rsSyncTransController_, nullptr); 196 } 197 } 198 199 /** 200 * @tc.name: RSSyncTransactionAdapterGetRSTransaction 201 * @tc.desc: Verify RSSyncTransactionAdapter::GetRSTransaction. 202 * @tc.type: FUNC 203 */ 204 HWTEST_F(RSAdapterTest, RSSyncTransactionAdapterGetRSTransaction, Function | SmallTest | Level1) 205 { 206 RSSyncTransactionAdapter adapter(rsUIContext_); 207 adapter.GetRSTransaction(); 208 if (rsClientMultiInstanceEnabled_) { 209 EXPECT_EQ(RSSyncTransactionAdapter::invokerType_, InvokerType::RS_SYNC_TRANSACTION_HANDLER); 210 } else { 211 EXPECT_EQ(RSSyncTransactionAdapter::invokerType_, InvokerType::RS_SYNC_TRANSACTION_CONTROLLER); 212 } 213 } 214 215 /** 216 * @tc.name: RSSyncTransactionAdapterOpenTransaction 217 * @tc.desc: Verify RSSyncTransactionAdapter::OpenSyncTransaction. 218 * @tc.type: FUNC 219 */ 220 HWTEST_F(RSAdapterTest, RSSyncTransactionAdapterOpenTransaction, Function | SmallTest | Level1) 221 { 222 RSSyncTransactionAdapter adapter(rsUIContext_); 223 adapter.OpenSyncTransaction(); 224 if (rsClientMultiInstanceEnabled_) { 225 EXPECT_EQ(RSSyncTransactionAdapter::invokerType_, InvokerType::RS_SYNC_TRANSACTION_HANDLER); 226 } else { 227 EXPECT_EQ(RSSyncTransactionAdapter::invokerType_, InvokerType::RS_SYNC_TRANSACTION_CONTROLLER); 228 } 229 } 230 231 /** 232 * @tc.name: RSSyncTransactionAdapterCloseTransaction 233 * @tc.desc: Verify RSSyncTransactionAdapter::CloseSyncTransaction. 234 * @tc.type: FUNC 235 */ 236 HWTEST_F(RSAdapterTest, RSSyncTransactionAdapterCloseTransaction, Function | SmallTest | Level1) 237 { 238 RSSyncTransactionAdapter adapter(rsUIContext_); 239 adapter.CloseSyncTransaction(); 240 if (rsClientMultiInstanceEnabled_) { 241 EXPECT_EQ(RSSyncTransactionAdapter::invokerType_, InvokerType::RS_SYNC_TRANSACTION_HANDLER); 242 } else { 243 EXPECT_EQ(RSSyncTransactionAdapter::invokerType_, InvokerType::RS_SYNC_TRANSACTION_CONTROLLER); 244 } 245 } 246 247 /** 248 * @tc.name: RSSyncTransactionAdapterStaticGetRSTransaction 249 * @tc.desc: Verify static GetRSTransaction with RSUIContext. 250 * @tc.type: FUNC 251 */ 252 HWTEST_F(RSAdapterTest, RSSyncTransactionAdapterStaticGetRSTransaction, Function | SmallTest | Level1) 253 { 254 RSSyncTransactionAdapter::GetRSTransaction(rsUIContext_); 255 if (rsClientMultiInstanceEnabled_) { 256 EXPECT_EQ(RSSyncTransactionAdapter::invokerType_, InvokerType::RS_SYNC_TRANSACTION_HANDLER); 257 } else { 258 EXPECT_EQ(RSSyncTransactionAdapter::invokerType_, InvokerType::RS_SYNC_TRANSACTION_CONTROLLER); 259 } 260 } 261 262 /** 263 * @tc.name: RSSyncTransactionAdapterStaticOpenSyncTransaction 264 * @tc.desc: Verify static OpenSyncTransaction with RSUIContext. 265 * @tc.type: FUNC 266 */ 267 HWTEST_F(RSAdapterTest, RSSyncTransactionAdapterStaticOpenSyncTransaction, Function | SmallTest | Level1) 268 { 269 RSSyncTransactionAdapter::OpenSyncTransaction(rsUIContext_); 270 if (rsClientMultiInstanceEnabled_) { 271 EXPECT_EQ(RSSyncTransactionAdapter::invokerType_, InvokerType::RS_SYNC_TRANSACTION_HANDLER); 272 } else { 273 EXPECT_EQ(RSSyncTransactionAdapter::invokerType_, InvokerType::RS_SYNC_TRANSACTION_CONTROLLER); 274 } 275 } 276 277 /** 278 * @tc.name: RSSyncTransactionAdapterStaticCloseSyncTransaction 279 * @tc.desc: Verify static CloseSyncTransaction with RSUIContext. 280 * @tc.type: FUNC 281 */ 282 HWTEST_F(RSAdapterTest, RSSyncTransactionAdapterStaticCloseSyncTransaction, Function | SmallTest | Level1) 283 { 284 RSSyncTransactionAdapter::CloseSyncTransaction(rsUIContext_); 285 if (rsClientMultiInstanceEnabled_) { 286 EXPECT_EQ(RSSyncTransactionAdapter::invokerType_, InvokerType::RS_SYNC_TRANSACTION_HANDLER); 287 } else { 288 EXPECT_EQ(RSSyncTransactionAdapter::invokerType_, InvokerType::RS_SYNC_TRANSACTION_CONTROLLER); 289 } 290 } 291 292 /** 293 * @tc.name: AutoRSSyncTransactionLifecycle 294 * @tc.desc: Verify AutoRSSyncTransaction lifecycle (Open + Close). 295 * @tc.type: FUNC 296 */ 297 HWTEST_F(RSAdapterTest, AutoRSSyncTransactionLifecycle, Function | SmallTest | Level1) 298 { 299 auto mockAdapter = std::make_shared<MockRSSyncTransactionAdapter>(rsUIContext_); 300 EXPECT_CALL(*mockAdapter, OpenSyncTransaction(_)) 301 .Times(1); 302 EXPECT_CALL(*mockAdapter, CloseSyncTransaction(_)) 303 .Times(1); 304 305 { 306 AutoRSSyncTransaction autoSyncTransaction(mockAdapter); 307 } 308 } 309 310 /** 311 * @tc.name: AllowInMultiThreadGuardLifecycle 312 * @tc.desc: Verify AllowInMultiThreadGuard lifecycle (skip check toggle). 313 * @tc.type: FUNC 314 */ 315 HWTEST_F(RSAdapterTest, AllowInMultiThreadGuardLifecycle, Function | SmallTest | Level1) 316 { 317 { 318 AllowInMultiThreadGuard allowMulti(rsNode_); 319 EXPECT_TRUE(rsNode_->isSkipCheckInMultiInstance_); 320 } 321 EXPECT_FALSE(rsNode_->isSkipCheckInMultiInstance_); 322 } 323 324 /** 325 * @tc.name: RSAdapterUtilInitRSUIDirectorTest 326 * @tc.desc: Verify InitRSUIDirector initializes RSUIDirector correctly. 327 * @tc.type: FUNC 328 */ 329 HWTEST_F(RSAdapterTest, RSAdapterUtilInitRSUIDirectorTest, Function | SmallTest | Level1) 330 { 331 std::shared_ptr<RSUIDirector> rsUIDirector; 332 RSAdapterUtil::InitRSUIDirector(rsUIDirector, true, true); 333 if (rsClientMultiInstanceEnabled_) { 334 EXPECT_NE(rsUIDirector, nullptr); 335 } else { 336 EXPECT_EQ(rsUIDirector, nullptr); 337 } 338 } 339 340 /** 341 * @tc.name: RSAdapterUtilSetRSUIContextTest 342 * @tc.desc: Verify SetRSUIContext behavior in various conditions. 343 * @tc.type: FUNC 344 */ 345 HWTEST_F(RSAdapterTest, RSAdapterUtilSetRSUIContextTest, Function | SmallTest | Level1) 346 { 347 if (!rsClientMultiInstanceEnabled_) { 348 GTEST_SKIP() << "Skip test when RS client multi-instance is disabled."; 349 } 350 351 // Case 1: rsNode is nullptr 352 { 353 RSAdapterUtil::SetRSUIContext(nullptr, rsUIContext_, true); 354 // Expect: no crash, no change, just early return 355 } 356 357 // Case 2: rsUIContext is nullptr 358 { 359 struct RSSurfaceNodeConfig config; 360 auto newNode = RSSurfaceNode::Create(config); 361 RSAdapterUtil::SetRSUIContext(newNode, nullptr, true); 362 EXPECT_EQ(newNode->GetRSUIContext(), nullptr); 363 } 364 365 // Case 3: rsUIContext is same as original 366 { 367 RSAdapterUtil::SetRSUIContext(rsNode_, rsUIContext_, true); 368 EXPECT_EQ(rsNode_->GetRSUIContext(), rsUIContext_); 369 } 370 371 // Case 4: normal set case, different RSUIContext 372 { 373 struct RSSurfaceNodeConfig config; 374 auto newNode = RSSurfaceNode::Create(config); 375 RSAdapterUtil::SetRSUIContext(newNode, rsUIContext_, true); 376 EXPECT_EQ(newNode->GetRSUIContext(), rsUIContext_); 377 } 378 } 379 380 /** 381 * @tc.name: RSAdapterUtilSetSkipCheckInMultiInstance 382 * @tc.desc: Verify SetSkipCheckInMultiInstance sets flag correctly. 383 * @tc.type: FUNC 384 */ 385 HWTEST_F(RSAdapterTest, RSAdapterUtilSetSkipCheckInMultiInstance, Function | SmallTest | Level1) 386 { 387 if (!rsClientMultiInstanceEnabled_) { 388 GTEST_SKIP() << "Skip test when RS client multi-instance is disabled."; 389 } 390 391 RSAdapterUtil::SetSkipCheckInMultiInstance(rsNode_, true); 392 EXPECT_TRUE(rsNode_->isSkipCheckInMultiInstance_); 393 394 RSAdapterUtil::SetSkipCheckInMultiInstance(rsNode_, false); 395 EXPECT_FALSE(rsNode_->isSkipCheckInMultiInstance_); 396 } 397 398 /** 399 * @tc.name: RSAdapterUtilGetRSNodeTest 400 * @tc.desc: Verify GetRSNode returns correct node based on multi-instance flag and context. 401 * @tc.type: FUNC 402 */ 403 HWTEST_F(RSAdapterTest, RSAdapterUtilGetRSNodeTest, Function | SmallTest | Level1) 404 { 405 auto node = RSAdapterUtil::GetRSNode(rsUIContext_, rsNode_->GetId()); 406 EXPECT_NE(node, nullptr); 407 EXPECT_EQ(node->GetId(), rsNode_->GetId()); 408 } 409 410 /** 411 * @tc.name: RSAdapterUtilToStringMethods 412 * @tc.desc: Verify RSAdapterUtil ToString methods. 413 * @tc.type: FUNC 414 */ 415 HWTEST_F(RSAdapterTest, RSAdapterUtilToStringMethods, Function | SmallTest | Level1) 416 { 417 auto nodeStr = RSAdapterUtil::RSNodeToStr(rsNode_); 418 EXPECT_THAT(nodeStr, HasSubstr("RSNode")); 419 420 auto ctxStr = RSAdapterUtil::RSUIContextToStr(rsUIContext_); 421 EXPECT_THAT(ctxStr, HasSubstr("RSUIContext")); 422 423 auto directorStr = RSAdapterUtil::RSUIDirectorToStr(rsUIDirector_); 424 EXPECT_THAT(directorStr, HasSubstr("RSUIDirector")); 425 } 426 } // namespace Rosen 427 } // namespace OHOS 428