1 /*
2  * Copyright (c) 2024 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 "gtest/gtest.h"
17 
18 #define private public
19 #define protected public
20 
21 #include "test/mock/core/common/mock_theme_manager.h"
22 #include "test/mock/core/pipeline/mock_pipeline_context.h"
23 #include "test/mock/core/render/mock_render_context.h"
24 #include "test/mock/core/rosen/mock_canvas.h"
25 #include "test/mock/core/rosen/testing_bitmap.h"
26 #include "test/mock/core/rosen/testing_canvas.h"
27 
28 #include "core/components_ng/pattern/model/model_adapter_wrapper.h"
29 #include "core/components_ng/pattern/model/model_layout_algorithm.h"
30 #include "core/components_ng/pattern/model/model_light.h"
31 #include "core/components_ng/pattern/model/model_paint_property.h"
32 #include "core/components_ng/pattern/model/model_paint_method.h"
33 #include "core/components_ng/pattern/model/model_pattern.h"
34 #include "core/components_ng/pattern/model/model_position.h"
35 #include "core/components_ng/pattern/model/model_property.h"
36 #include "core/components_ng/pattern/model/model_touch_handler.h"
37 #include "core/components_ng/pattern/model/model_view.h"
38 #include "core/components_ng/pattern/model/model_view_ng.h"
39 
40 #include "scene_adapter/intf_scene_adapter.h"
41 
42 using namespace testing;
43 using namespace testing::ext;
44 
45 namespace OHOS::Ace::NG {
46 namespace {
47     uint32_t testKey = UINT32_MAX / 2;
48     std::string testPath = "/data/local";
49     constexpr int32_t PLATFORM_VERSION_11 = 11;
50     Render3D::SurfaceType testSurfaceType = OHOS::Render3D::SurfaceType::SURFACE_WINDOW;
51     ModelViewContext testContext { "moudleTest", "moudleTest", testSurfaceType };
52 }
53 
54 class TestSceneAdapter : public Render3D::ISceneAdapter {
LoadPluginsAndInit()55     bool LoadPluginsAndInit()
56     {
57         return true;
58     }
CreateTextureLayer()59     std::shared_ptr<Render3D::TextureLayer> CreateTextureLayer()
60     {
61         return std::make_shared<Render3D::TextureLayer>();
62     }
OnWindowChange(const Render3D::WindowChangeInfo & windowChangeInfo)63     void OnWindowChange(const Render3D::WindowChangeInfo& windowChangeInfo)
64     {
65         return;
66     }
RenderFrame(bool needsSyncPaint=false)67     void RenderFrame(bool needsSyncPaint = false)
68     {
69         return;
70     }
Deinit()71     void Deinit()
72     {
73         return;
74     }
NeedsRepaint()75     bool NeedsRepaint()
76     {
77         return true;
78     }
79 };
80 
81 class ModelTestNg : public testing::Test {
82 public:
83     static void SetUpTestSuite();
84     static void TearDownTestSuite();
85 private:
86     ModelViewNG modelViewNG;
87 };
88 
SetUpTestSuite()89 void ModelTestNg::SetUpTestSuite()
90 {
91     MockPipelineContext::SetUp();
92 }
93 
TearDownTestSuite()94 void ModelTestNg::TearDownTestSuite()
95 {
96     MockPipelineContext::TearDown();
97 }
98 
99 /**
100  * @tc.name: ModelViewNgTest001
101  * @tc.desc: Test Without Setting Property
102  * @tc.type: FUNC
103  */
104 HWTEST_F(ModelTestNg, ModelViewNgTest001, TestSize.Level1)
105 {
106     auto pipeline = PipelineContext::GetCurrentContext();
107     ASSERT_NE(pipeline, nullptr);
108     pipeline->SetMinPlatformVersion(PLATFORM_VERSION_11);
109 
110     // Create ModelViewNG
111     modelViewNG.Create(testContext);
112 
113     // Get ModelPaintProperty
114     auto modelPaintProperty = modelViewNG.frameNode_.Upgrade()->GetPaintProperty<ModelPaintProperty>();
115     ASSERT_NE(modelPaintProperty, nullptr);
116 
117     // Get ModelPattern
118     auto modelPattern = modelViewNG.frameNode_.Upgrade()->GetPattern<ModelPattern>();
119     ASSERT_NE(modelPattern, nullptr);
120 
121     modelPattern->modelAdapter_->OnPaint3D(modelPaintProperty);
122 
123     // ToJsonValue Before Set Values
124     const InspectorFilter filter;
125     auto json = JsonUtil::Create(true);
126     modelPattern->ToJsonValue(json, filter);
127 
128     // ImageTexturePath and ShaderInputBuffers
129     modelPattern->modelAdapter_->sceneAdapter_ = std::make_shared<TestSceneAdapter>();
130     ASSERT_NE(modelPattern->modelAdapter_->sceneAdapter_, nullptr);
131     modelPattern->modelAdapter_->UpdateImageTexturePaths(modelPaintProperty);
132     modelPattern->modelAdapter_->UpdateShaderInputBuffers(modelPaintProperty);
133     modelPattern->modelAdapter_->sceneAdapter_.reset();
134     ASSERT_EQ(modelPattern->modelAdapter_->sceneAdapter_, nullptr);
135     modelPattern->modelAdapter_->UpdateImageTexturePaths(modelPaintProperty);
136     modelPattern->modelAdapter_->UpdateShaderInputBuffers(modelPaintProperty);
137 
138     // ShaderInputBuffer
139     // Buffer test begin
140     std::shared_ptr<OHOS::Render3D::ShaderInputBuffer> buffer = nullptr;
141     buffer = std::make_shared<OHOS::Render3D::ShaderInputBuffer>();
142     int length = 3; // 3: buffer length
143 
144     ASSERT_TRUE(buffer->Alloc(length));
145     for (uint32_t i = 0; i < static_cast<uint32_t>(length); i++) {
146         buffer->Update(1, i);
147     }
148     modelViewNG.AddShaderInputBuffer(buffer);
149     EXPECT_EQ(modelPaintProperty->GetModelShaderInputBufferValue(), buffer);
150     modelPattern->modelAdapter_->UpdateShaderInputBuffers(modelPaintProperty);
151     EXPECT_EQ(modelViewNG.GetShaderInputBuffer(), modelPaintProperty->propModelShaderInputBuffer_);
152     // Buffer test end
153 
154     // CustomRender
155     modelPattern->modelAdapter_->UpdateCustomRender(modelPaintProperty);
156     auto desc = std::make_shared<Render3D::CustomRenderDescriptor>("/data/local", true);
157     modelViewNG.AddCustomRender(desc);
158     EXPECT_EQ(modelPaintProperty->GetModelCustomRenderValue(), desc);
159     modelPattern->modelAdapter_->UpdateCustomRender(modelPaintProperty);
160 
161     // AddShaderImageTexture
162     // Case 1:: frameNode != nullptr
163     modelViewNG.AddShaderImageTexture("/data/local");
164     // Add Same Path
165     modelViewNG.AddShaderImageTexture("/data/local");
166     EXPECT_EQ(modelPaintProperty->GetModelImageTexturePathsValue().back(), "/data/local");
167     modelViewNG.AddShaderImageTexture("/data/local1");
168 
169     // case 2 frameNode == nullptr
170     modelViewNG.frameNode_.Reset();
171     modelViewNG.AddShaderImageTexture("/data/local2");
172     EXPECT_EQ(modelPaintProperty->GetModelImageTexturePathsValue().size(), 2);
173     modelViewNG.GetShaderInputBuffer();
174 
175     modelViewNG.AddCustomRender(desc);
176     desc.reset();
177     modelViewNG.AddCustomRender(desc);
178     modelPattern->modelAdapter_->UpdateCustomRender(modelPaintProperty);
179 }
180 
181 /**
182  * @tc.name: ModelViewNgTest002
183  * @tc.desc: Test ModelAdapterWrapper Functions and SceneAdapter == nullptr
184  * @tc.type: FUNC
185  */
186 HWTEST_F(ModelTestNg, ModelViewNgTest002, TestSize.Level1)
187 {
188     // Get FrameNode
189     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
190 
191     // Get ModelPaintProperty
192     auto modelPaintProperty = frameNode->GetPaintProperty<ModelPaintProperty>();
193     ASSERT_NE(modelPaintProperty, nullptr);
194 
195     // Get ModelPattern
196     auto modelPattern = frameNode->GetPattern<ModelPattern>();
197     ASSERT_NE(modelPattern, nullptr);
198 
199     std::shared_ptr<OHOS::Render3D::ShaderInputBuffer> buffer = nullptr;
200     buffer = std::make_shared<OHOS::Render3D::ShaderInputBuffer>();
201     int length = 3; // 3: buffer length
202 
203     ASSERT_TRUE(buffer->Alloc(length));
204     for (uint32_t i = 0; i < static_cast<uint32_t>(length); i++) {
205         buffer->Update(1, i);
206     }
207     FrameNode* frameNode1 = nullptr;
208     modelViewNG.AddShaderInputBuffer(frameNode1, buffer);
209 
210     // Create SceneAdapter
211     modelPattern->modelAdapter_->sceneAdapter_ = std::make_shared<TestSceneAdapter>();
212     ASSERT_NE(modelPattern->modelAdapter_->sceneAdapter_, nullptr);
213 
214     RefPtr<RenderContext> context;
215     modelPattern->modelAdapter_->OnAttachToFrameNode(context);
216     modelPattern->modelAdapter_->Deinit();
217     Render3D::PointerEvent event;
218     modelPattern->modelAdapter_->HandleCameraMove(event);
219     modelPattern->modelAdapter_->DrawFrame();
220     Render3D::WindowChangeInfo windowChangeInfo {};
221     modelPattern->modelAdapter_->OnDirtyLayoutWrapperSwap(windowChangeInfo);
222     modelPattern->modelAdapter_->CreateTextureLayer();
223     modelPattern->modelAdapter_->CreateWidgetAdapter();
224     modelPattern->modelAdapter_->UnloadSceneAndBackground();
225     modelPattern->modelAdapter_->UpdateScene(modelPaintProperty);
226     modelPattern->modelAdapter_->UpdateEnviroment(modelPaintProperty);
227     modelPattern->modelAdapter_->UpdateCustomRender(modelPaintProperty);
228     modelPattern->modelAdapter_->UpdateShaderPath(modelPaintProperty);
229 
230     modelPattern->modelAdapter_->sceneAdapter_.reset();
231     ASSERT_EQ(modelPattern->modelAdapter_->sceneAdapter_, nullptr);
232 }
233 
234 /**
235  * @tc.name: ModelViewNgTest003
236  * @tc.desc: Test ModelViewNG Functions
237  * @tc.type: FUNC
238  */
239 HWTEST_F(ModelTestNg, ModelViewNgTest003, TestSize.Level1)
240 {
241     // Get FrameNode
242     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
243 
244     // Get ModelPaintProperty
245     auto modelPaintProperty = frameNode->GetPaintProperty<ModelPaintProperty>();
246     ASSERT_NE(modelPaintProperty, nullptr);
247 
248     // Get ModelPattern
249     auto modelPattern = frameNode->GetPattern<ModelPattern>();
250     ASSERT_NE(modelPattern, nullptr);
251 
252     // Environment
253     modelPattern->modelAdapter_->UpdateEnviroment(modelPaintProperty);
254     modelViewNG.SetBackground(testPath);
255     EXPECT_EQ(modelPaintProperty->GetModelBackgroundValue(), testPath);
256     modelPattern->modelAdapter_->UpdateEnviroment(modelPaintProperty);
257 
258     // ModelSource
259     modelPattern->modelAdapter_->UpdateScene(modelPaintProperty);
260     modelViewNG.SetModelSource(testPath);
261     EXPECT_EQ(modelPaintProperty->GetModelSourceValue(), testPath);
262     modelPattern->modelAdapter_->UpdateScene(modelPaintProperty);
263 
264     // RenderWidth and RenderHeight
265     // Case 1 : Value < 0.0f
266     CalcDimension value;
267     value.SetValue(-1.0f);
268     modelViewNG.SetRenderWidth(value);
269     value.SetValue(-1.0f);
270     modelViewNG.SetRenderHeight(value);
271 
272     // Case 2 : Value > 0.0f
273     value.SetValue(1.0f);
274     modelViewNG.SetRenderWidth(value);
275     EXPECT_EQ(modelPaintProperty->GetRenderWidthValue(), 1.0f);
276     modelViewNG.SetRenderHeight(value);
277     EXPECT_EQ(modelPaintProperty->GetRenderHeightValue(), 1.0f);
278 
279     // Shader
280     modelPattern->modelAdapter_->UpdateShaderPath(modelPaintProperty);
281     modelViewNG.SetShader(testPath);
282     EXPECT_EQ(modelPaintProperty->GetShaderPathValue(), testPath);
283     modelPattern->modelAdapter_->UpdateShaderPath(modelPaintProperty);
284 
285     // HandleCameraMove
286     modelViewNG.SetHandleCameraMove(false);
287     EXPECT_EQ(modelPaintProperty->GetModelCameraMoveValue(), false);
288 
289     // RenderFrameRate
290     modelViewNG.SetRenderFrameRate(1.0f);
291     EXPECT_EQ(modelPaintProperty->GetRenderFrameRateValue(), 1.0f);
292 }
293 
294 /**
295  * @tc.name: ModelViewNgTest004
296  * @tc.desc: Test ModelPattern Functions
297  * @tc.type: FUNC
298  */
299 HWTEST_F(ModelTestNg, ModelViewNgTest004, TestSize.Level1)
300 {
301     // Get FrameNode
302     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
303 
304     // Get ModelPattern
305     auto modelPattern = frameNode->GetPattern<ModelPattern>();
306     ASSERT_NE(modelPattern, nullptr);
307 
308     // Get ModelPaintProperty
309     auto modelPaintProperty = frameNode->GetPaintProperty<ModelPaintProperty>();
310     ASSERT_NE(modelPaintProperty, nullptr);
311 
312     // OnPaint3D
313     // Case 1 : needsSynsPaint_ = true
314     modelPattern->modelAdapter_->OnPaint3D(modelPaintProperty);
315     // Case 2 : needsSynsPaint_ = false
316     modelPattern->modelAdapter_->OnPaint3D(modelPaintProperty);
317     modelPattern->modelAdapter_->OnPaintFinish();
318 
319     // HdleCameraMove
320     Render3D::PointerEvent event;
321     modelPattern->modelAdapter_->HandleCameraMove(event);
322 
323     // OnAttachToFrameNode
324     modelPattern->modelAdapter_->UnloadSceneAndBackground();
325     modelPattern->modelAdapter_->widgetAdapter_.reset();
326     modelPattern->modelAdapter_->textureLayer_.reset();
327     EXPECT_EQ(modelPattern->modelAdapter_->widgetAdapter_, nullptr);
328     EXPECT_EQ(modelPattern->modelAdapter_->textureLayer_, nullptr);
329     modelPattern->OnAttachToFrameNode();
330     modelPattern->modelAdapter_->OnPaint3D(modelPaintProperty);
331     EXPECT_NE(modelPattern->modelAdapter_->widgetAdapter_, nullptr);
332     EXPECT_NE(modelPattern->modelAdapter_->textureLayer_, nullptr);
333 
334     TouchEventInfo touchEventInfo("onTouch");
335     TouchLocationInfo touchLocationInfo(0);
336     touchLocationInfo.touchType_ = TouchType::MOVE;
337     touchLocationInfo.localLocation_ = Offset(1.0f, 1.0f);
338     touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo));
339     modelPattern->HandleTouchEvent(touchEventInfo);
340     EXPECT_NE(modelPattern->CreateNodePaintMethod(), nullptr);
341 
342     // OnModifyDone
343     modelPattern->OnModifyDone();
344     EXPECT_NE(modelPattern->modelAdapter_, nullptr);
345 
346     // OnDirtyLayoutWrapperSwap
347     RefPtr<GeometryNode> geometryNode = AceType::MakeRefPtr<GeometryNode>();
348     geometryNode->SetContentSize(SizeF(100.0f, 100.0f));
349     geometryNode->SetContentOffset(OffsetF(0.0f, 0.0f));
350     auto layoutWrapper =
351         AceType::MakeRefPtr<LayoutWrapperNode>(static_cast<WeakPtr<FrameNode>>(frameNode), geometryNode, nullptr);
352     ASSERT_NE(layoutWrapper, nullptr);
353     layoutWrapper->skipMeasureContent_ = std::make_optional(true);
354     DirtySwapConfig config;
355     EXPECT_FALSE(modelPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config));
356     config.skipMeasure = true;
357     EXPECT_FALSE(modelPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config));
358     config.skipLayout = true;
359     EXPECT_FALSE(modelPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config));
360 
361     // MarkDirtyNode
362     modelPattern->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
363 
364     // OnRebuildFrame
365     modelPattern->OnRebuildFrame();
366     EXPECT_NE(modelPattern->modelAdapter_->textureLayer_, nullptr);
367 
368     // NeedsRepaint
369     modelPattern->modelAdapter_->needsRepaint_ = true;
370     EXPECT_TRUE(modelPattern->NeedsRepaint());
371 }
372 
373 /**
374  * @tc.name: ModelViewNgTest005
375  * @tc.desc: Test Util Functions
376  * @tc.type: FUNC
377  */
378 HWTEST_F(ModelTestNg, ModelViewNgTest005, TestSize.Level1)
379 {
380     // Get FrameNode
381     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
382     ASSERT_NE(frameNode, nullptr);
383 
384     // Get ModelPattern
385     auto modelPattern = frameNode->GetPattern<ModelPattern>();
386     ASSERT_NE(modelPattern, nullptr);
387 
388     // Get ModelPaintProperty
389     auto modelPaintProperty = frameNode->GetPaintProperty<ModelPaintProperty>();
390     ASSERT_NE(modelPaintProperty, nullptr);
391 
392     // SetHapInfo
393     Render3D::HapInfo hapinfo = modelPattern->modelAdapter_->SetHapInfo();
394     EXPECT_EQ(hapinfo.hapPath_, "");
395     EXPECT_EQ(hapinfo.bundleName_, "");
396     EXPECT_EQ(hapinfo.moduleName_, "");
397 
398     const InspectorFilter filter1;
399     auto json1 = JsonUtil::Create(true);
400     modelPattern->ToJsonValue(json1, filter1);
401     ASSERT_NE(json1, nullptr);
402     EXPECT_EQ(json1->GetString("renderWidth"), "1.000000");
403     EXPECT_EQ(json1->GetString("renderHeight"), "1.000000");
404     EXPECT_EQ(json1->GetString("shaderInputBuffer"), "1.000000 1.000000 1.000000 ");
405     EXPECT_EQ(json1->GetString("shaderImageTexture"), "/data/local /data/local1 ");
406     EXPECT_EQ(json1->GetString("modelType"), "ModelType.SURFACE");
407     EXPECT_EQ(json1->GetString("environment"), testPath);
408     EXPECT_EQ(json1->GetString("customRender"), testPath);
409     EXPECT_EQ(json1->GetString("shader"), testPath);
410     EXPECT_EQ(json1->GetString("scene"), testPath);
411 
412     modelPattern->modelAdapter_->surfaceType_ = Render3D::SurfaceType::SURFACE_TEXTURE;
413     const InspectorFilter filter2;
414     auto json2 = JsonUtil::Create(true);
415     modelPattern->ToJsonValue(json2, filter2);
416 
417     modelPattern->modelAdapter_->surfaceType_ = Render3D::SurfaceType::UNDEFINE;
418     const InspectorFilter filter3;
419     auto json3 = JsonUtil::Create(true);
420     modelPattern->ToJsonValue(json3, filter3);
421 
422     modelPattern->modelAdapter_->surfaceType_ = Render3D::SurfaceType::SURFACE_BUFFER;
423     const InspectorFilter filter4;
424     auto json4 = JsonUtil::Create(true);
425     modelPattern->ToJsonValue(json4, filter4);
426 
427     auto ftr = modelPattern->modelAdapter_->Deinit();
428     if (ftr.valid()) {
429         ftr.get();
430     }
431     Render3D::GraphicsTask::GetInstance().Stop();
432 }
433 
434 /**
435  * @tc.name: ModelViewNgTest006
436  * @tc.desc: Test ModelTouchHandler Functions
437  * @tc.type: FUNC
438  */
439 HWTEST_F(ModelTestNg, ModelViewNgTest006, TestSize.Level1)
440 {
441     ModelTouchHandler modelTouchHandler;
442     TouchEventInfo touchEventInfo("onTouch");
443     TouchLocationInfo touchLocationInfo(0);
444     touchLocationInfo.touchType_ = TouchType::DOWN;
445     touchLocationInfo.localLocation_ = Offset(1.0f, 1.0f);
446     touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo));
447     EXPECT_EQ(modelTouchHandler.HandleTouchEvent(touchEventInfo, 1, 1), false);
448 
449     touchEventInfo.changedTouches_.clear();
450     touchLocationInfo.touchType_ = TouchType::MOVE;
451     touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo));
452     EXPECT_EQ(modelTouchHandler.HandleTouchEvent(touchEventInfo, 1, 1), false);
453 
454     modelTouchHandler.isHandleCameraMove_ = false;
455     touchEventInfo.changedTouches_.clear();
456     touchLocationInfo.touchType_ = TouchType::UP;
457     touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo));
458     EXPECT_EQ(modelTouchHandler.HandleTouchEvent(touchEventInfo, 1, 1), false);
459 
460     touchEventInfo.changedTouches_.clear();
461     touchLocationInfo.touchType_ = TouchType::CANCEL;
462     touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo));
463     EXPECT_EQ(modelTouchHandler.HandleTouchEvent(touchEventInfo, 1, 1), true);
464 
465     touchEventInfo.changedTouches_.clear();
466     touchLocationInfo.touchType_ = TouchType::UNKNOWN;
467     touchEventInfo.AddChangedTouchLocationInfo(std::move(touchLocationInfo));
468     EXPECT_EQ(modelTouchHandler.HandleTouchEvent(touchEventInfo, 1, 1), true);
469     EXPECT_EQ(modelTouchHandler.HandleTouchEvent(touchEventInfo, 1, 0), true);
470     EXPECT_EQ(modelTouchHandler.HandleTouchEvent(touchEventInfo, 0, 0), true);
471 }
472 } // namespace OHOS::Ace::NG
473 
474