• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "gtest/gtest.h"
17 #define private public
18 #include "effect/blend_shader_obj.h"
19 #undef private
20 #include "effect/shader_effect.h"
21 #include "effect/shader_effect_lazy.h"
22 #ifdef ROSEN_OHOS
23 #include <parcel.h>
24 #include <message_parcel.h>
25 #include "utils/object_helper.h"
26 #endif
27 #include "transaction/rs_marshalling_helper.h"
28 
29 using namespace testing;
30 using namespace testing::ext;
31 using namespace OHOS::Rosen;
32 
33 namespace OHOS {
34 namespace Rosen {
35 namespace Drawing {
36 class BlendShaderObjTest : public testing::Test {
37 public:
38     static void SetUpTestCase();
39     static void TearDownTestCase();
40     void SetUp() override;
41     void TearDown() override;
42 };
43 
SetUpTestCase()44 void BlendShaderObjTest::SetUpTestCase() {}
TearDownTestCase()45 void BlendShaderObjTest::TearDownTestCase() {}
SetUp()46 void BlendShaderObjTest::SetUp() {}
TearDown()47 void BlendShaderObjTest::TearDown() {}
48 
49 /*
50  * @tc.name: Constructor001
51  * @tc.desc: Test BlendShaderObj constructor scenarios
52  * @tc.type: FUNC
53  * @tc.require: AR000GGNV3
54  * @tc.author:
55  */
56 HWTEST_F(BlendShaderObjTest, Constructor001, TestSize.Level1)
57 {
58     // Test 1: CreateForUnmarshalling
59     auto shaderObj = BlendShaderObj::CreateForUnmarshalling();
60     EXPECT_TRUE(shaderObj != nullptr);
61     EXPECT_EQ(shaderObj->GetType(), static_cast<int32_t>(Drawing::Object::ObjectType::SHADER_EFFECT));
62     EXPECT_EQ(shaderObj->GetSubType(), static_cast<int32_t>(ShaderEffect::ShaderEffectType::BLEND));
63 
64     // Test 2: Parameterized constructor with valid shaders
65     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
66     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
67     BlendMode mode = BlendMode::SRC_OVER;
68     auto validShaderObj = BlendShaderObj::Create(dstShader, srcShader, mode);
69     EXPECT_TRUE(validShaderObj != nullptr);
70     EXPECT_EQ(validShaderObj->GetType(), static_cast<int32_t>(Drawing::Object::ObjectType::SHADER_EFFECT));
71     EXPECT_EQ(validShaderObj->GetSubType(), static_cast<int32_t>(ShaderEffect::ShaderEffectType::BLEND));
72 
73     // Test 3: Constructor with null dst shader
74     std::shared_ptr<ShaderEffect> nullDst = nullptr;
75     auto nullTestShader = ShaderEffect::CreateColorShader(0xFFFF0000);
76     BlendMode nullTestMode = BlendMode::MULTIPLY;
77     auto nullShaderObj = BlendShaderObj::Create(nullDst, nullTestShader, nullTestMode);
78     EXPECT_TRUE(nullShaderObj == nullptr); // Should return nullptr when dst shader is null
79 }
80 
81 /*
82  * @tc.name: GenerateBaseObject001
83  * @tc.desc: Test BlendShaderObj::GenerateBaseObject with valid shaders
84  * @tc.type: FUNC
85  * @tc.require: AR000GGNV3
86  * @tc.author:
87  */
88 HWTEST_F(BlendShaderObjTest, GenerateBaseObject001, TestSize.Level1)
89 {
90     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
91     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
92     BlendMode mode = BlendMode::OVERLAY;
93 
94     auto shaderObj = BlendShaderObj::Create(dstShader, srcShader, mode);
95     auto baseObject = shaderObj->GenerateBaseObject();
96     EXPECT_TRUE(baseObject != nullptr);
97 
98     // Try to cast to ShaderEffect
99     auto generatedShader = std::static_pointer_cast<ShaderEffect>(baseObject);
100     EXPECT_TRUE(generatedShader != nullptr);
101     if (generatedShader) {
102         EXPECT_EQ(generatedShader->GetType(), ShaderEffect::ShaderEffectType::BLEND);
103         EXPECT_FALSE(generatedShader->IsLazy());
104     }
105 }
106 
107 /*
108  * @tc.name: GenerateBaseObject002
109  * @tc.desc: Test BlendShaderObj::GenerateBaseObject with null dst shader
110  * @tc.type: FUNC
111  * @tc.require: AR000GGNV3
112  * @tc.author:
113  */
114 HWTEST_F(BlendShaderObjTest, GenerateBaseObject002, TestSize.Level1)
115 {
116     std::shared_ptr<ShaderEffect> nullDst = nullptr;
117     auto srcShader = ShaderEffect::CreateColorShader(0xFFFF0000);
118     BlendMode mode = BlendMode::SCREEN;
119     auto shaderObj = BlendShaderObj::Create(nullDst, srcShader, mode);
120     EXPECT_TRUE(shaderObj == nullptr); // Should return nullptr when dst shader is null
121 }
122 
123 /*
124  * @tc.name: GenerateBaseObject003
125  * @tc.desc: Test BlendShaderObj::GenerateBaseObject with null src shader
126  * @tc.type: FUNC
127  * @tc.require: AR000GGNV3
128  * @tc.author:
129  */
130 HWTEST_F(BlendShaderObjTest, GenerateBaseObject003, TestSize.Level1)
131 {
132     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
133     std::shared_ptr<ShaderEffect> nullSrc = nullptr;
134     BlendMode mode = BlendMode::DARKEN;
135     auto shaderObj = BlendShaderObj::Create(dstShader, nullSrc, mode);
136     EXPECT_TRUE(shaderObj == nullptr); // Should return nullptr when src shader is null
137 }
138 
139 /*
140  * @tc.name: GenerateBaseObject004
141  * @tc.desc: Test BlendShaderObj::GenerateBaseObject with different blend modes
142  * @tc.type: FUNC
143  * @tc.require: AR000GGNV3
144  * @tc.author:
145  */
146 HWTEST_F(BlendShaderObjTest, GenerateBaseObject004, TestSize.Level1)
147 {
148     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
149     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
150     // Test different blend modes
151     std::vector<BlendMode> blendModes = {
152         BlendMode::SRC_OVER,
153         BlendMode::MULTIPLY,
154         BlendMode::SCREEN,
155         BlendMode::OVERLAY,
156         BlendMode::DARKEN,
157         BlendMode::LIGHTEN
158     };
159     for (const auto& mode : blendModes) {
160         auto shaderObj = BlendShaderObj::Create(dstShader, srcShader, mode);
161         auto baseObject = shaderObj->GenerateBaseObject();
162         EXPECT_TRUE(baseObject != nullptr);
163         auto generatedShader = std::static_pointer_cast<ShaderEffect>(baseObject);
164         EXPECT_TRUE(generatedShader != nullptr);
165         if (generatedShader) {
166             EXPECT_EQ(generatedShader->GetType(), ShaderEffect::ShaderEffectType::BLEND);
167         }
168     }
169 }
170 
171 #ifdef ROSEN_OHOS
172 /*
173  * @tc.name: Marshalling001
174  * @tc.desc: Test BlendShaderObj::Marshalling with valid non-Lazy shaders
175  * @tc.type: FUNC
176  * @tc.require: AR000GGNV3
177  * @tc.author:
178  */
179 HWTEST_F(BlendShaderObjTest, Marshalling001, TestSize.Level1)
180 {
181     ObjectHelper::Instance().SetDataMarshallingCallback(
__anon441abdaa0102(Parcel& parcel, std::shared_ptr<Drawing::Data> data) 182         [](Parcel& parcel, std::shared_ptr<Drawing::Data> data) -> bool {
183             return RSMarshallingHelper::Marshalling(parcel, data);
184         });
185     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
186     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
187     BlendMode mode = BlendMode::MULTIPLY;
188     auto shaderObj = BlendShaderObj::Create(dstShader, srcShader, mode);
189     MessageParcel parcel;
190     bool result = shaderObj->Marshalling(parcel);
191     EXPECT_TRUE(result); // Should succeed with registered DataMarshallingCallback
192     ObjectHelper::Instance().SetDataMarshallingCallback(nullptr);
193 }
194 
195 /*
196  * @tc.name: Marshalling002
197  * @tc.desc: Test BlendShaderObj::Marshalling with null dst shader (failure case)
198  * @tc.type: FUNC
199  * @tc.require: AR000GGNV3
200  * @tc.author:
201  */
202 HWTEST_F(BlendShaderObjTest, Marshalling002, TestSize.Level1)
203 {
204     std::shared_ptr<ShaderEffect> nullDst = nullptr;
205     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
206     BlendMode mode = BlendMode::SCREEN;
207     auto shaderObj = BlendShaderObj::Create(nullDst, srcShader, mode);
208     EXPECT_TRUE(shaderObj == nullptr); // Should return nullptr when dst shader is null
209 }
210 
211 /*
212  * @tc.name: Marshalling003
213  * @tc.desc: Test BlendShaderObj::Marshalling with null src shader (failure case)
214  * @tc.type: FUNC
215  * @tc.require: AR000GGNV3
216  * @tc.author:
217  */
218 HWTEST_F(BlendShaderObjTest, Marshalling003, TestSize.Level1)
219 {
220     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
221     std::shared_ptr<ShaderEffect> nullSrc = nullptr;
222     BlendMode mode = BlendMode::OVERLAY;
223     auto shaderObj = BlendShaderObj::Create(dstShader, nullSrc, mode);
224     EXPECT_TRUE(shaderObj == nullptr); // Should return nullptr when src shader is null
225 }
226 
227 /*
228  * @tc.name: Unmarshalling001
229  * @tc.desc: Test BlendShaderObj::Unmarshalling with non-Lazy shader data
230  * @tc.type: FUNC
231  * @tc.require: AR000GGNV3
232  * @tc.author:
233  */
234 HWTEST_F(BlendShaderObjTest, Unmarshalling001, TestSize.Level1)
235 {
236     MessageParcel parcel;
237     // Write test data to parcel for non-Lazy shaders
238     parcel.WriteInt32(static_cast<int32_t>(BlendMode::DARKEN)); // blendMode
239     parcel.WriteBool(false); // isDstLazy = false
240     parcel.WriteBool(false); // isSrcLazy = false
241     auto shaderObj = BlendShaderObj::CreateForUnmarshalling();
242     EXPECT_TRUE(shaderObj != nullptr);
243     bool isValid = true;
244     bool result = shaderObj->Unmarshalling(parcel, isValid);
245     // May fail due to missing DataUnmarshallingCallback, but test the code path
246     EXPECT_FALSE(result); // Expected to fail without proper callback registration
247 }
248 
249 /*
250  * @tc.name: Unmarshalling002
251  * @tc.desc: Test BlendShaderObj::Unmarshalling with Lazy shader data
252  * @tc.type: FUNC
253  * @tc.require: AR000GGNV3
254  * @tc.author:
255  */
256 HWTEST_F(BlendShaderObjTest, Unmarshalling002, TestSize.Level1)
257 {
258     MessageParcel parcel;
259     // Write test data to parcel for Lazy shaders
260     parcel.WriteInt32(static_cast<int32_t>(BlendMode::LIGHTEN)); // blendMode
261     parcel.WriteBool(true); // isDstLazy = true
262     parcel.WriteInt32(static_cast<int32_t>(Drawing::Object::ObjectType::SHADER_EFFECT));
263     parcel.WriteInt32(static_cast<int32_t>(ShaderEffect::ShaderEffectType::LIGHT_UP));
264     parcel.WriteBool(true); // isSrcLazy = true
265     parcel.WriteInt32(static_cast<int32_t>(Drawing::Object::ObjectType::SHADER_EFFECT));
266     parcel.WriteInt32(static_cast<int32_t>(ShaderEffect::ShaderEffectType::LIGHT_UP));
267     auto shaderObj = BlendShaderObj::CreateForUnmarshalling();
268     EXPECT_TRUE(shaderObj != nullptr);
269     bool isValid = true;
270     bool result = shaderObj->Unmarshalling(parcel, isValid);
271     // May fail due to missing nested object creation, but test the code path
272     EXPECT_FALSE(result); // Expected to fail without proper object creation
273 }
274 
275 /*
276  * @tc.name: GenerateBaseObject005
277  * @tc.desc: Test BlendShaderObj::GenerateBaseObject with different BlendModes
278  * @tc.type: FUNC
279  * @tc.require: AR000GGNV3
280  * @tc.author:
281  */
282 HWTEST_F(BlendShaderObjTest, GenerateBaseObject005, TestSize.Level1)
283 {
284     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
285     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
286 
287     // Test additional blend modes not covered in GenerateBaseObject004
288     std::vector<BlendMode> additionalModes = {
289         BlendMode::CLEAR,
290         BlendMode::SRC,
291         BlendMode::DST,
292         BlendMode::SRC_IN,
293         BlendMode::DST_IN
294     };
295 
296     for (const auto& mode : additionalModes) {
297         auto shaderObj = BlendShaderObj::Create(dstShader, srcShader, mode);
298         EXPECT_TRUE(shaderObj != nullptr);
299 
300         auto baseObject = shaderObj->GenerateBaseObject();
301         EXPECT_TRUE(baseObject != nullptr);
302 
303         auto generatedShader = std::static_pointer_cast<ShaderEffect>(baseObject);
304         EXPECT_TRUE(generatedShader != nullptr);
305         if (generatedShader) {
306             EXPECT_EQ(generatedShader->GetType(), ShaderEffect::ShaderEffectType::BLEND);
307         }
308     }
309 }
310 
311 /*
312  * @tc.name: Marshalling004
313  * @tc.desc: Test BlendShaderObj::Marshalling without DataMarshallingCallback
314  * @tc.type: FUNC
315  * @tc.require: AR000GGNV3
316  * @tc.author:
317  */
318 HWTEST_F(BlendShaderObjTest, Marshalling004, TestSize.Level1)
319 {
320     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
321     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
322     BlendMode mode = BlendMode::MULTIPLY;
323 
324     auto shaderObj = BlendShaderObj::Create(dstShader, srcShader, mode);
325     EXPECT_TRUE(shaderObj != nullptr);
326 
327     // Ensure no DataMarshallingCallback is set
328     ObjectHelper::Instance().SetDataMarshallingCallback(nullptr);
329 
330     MessageParcel parcel;
331     bool result = shaderObj->Marshalling(parcel);
332     EXPECT_FALSE(result); // Should fail without DataMarshallingCallback
333 }
334 
335 /*
336  * @tc.name: Unmarshalling003
337  * @tc.desc: Test BlendShaderObj::Unmarshalling without DataUnmarshallingCallback
338  * @tc.type: FUNC
339  * @tc.require: AR000GGNV3
340  * @tc.author:
341  */
342 HWTEST_F(BlendShaderObjTest, Unmarshalling003, TestSize.Level1)
343 {
344     MessageParcel parcel;
345     // Write test data for non-Lazy shaders
346     parcel.WriteInt32(static_cast<int32_t>(BlendMode::SCREEN)); // blendMode
347     parcel.WriteBool(false); // isDstLazy = false
348     parcel.WriteBool(false); // isSrcLazy = false
349 
350     // Ensure no DataUnmarshallingCallback is set
351     ObjectHelper::Instance().SetDataUnmarshallingCallback(nullptr);
352 
353     auto shaderObj = BlendShaderObj::CreateForUnmarshalling();
354     EXPECT_TRUE(shaderObj != nullptr);
355 
356     bool isValid = true;
357     bool result = shaderObj->Unmarshalling(parcel, isValid);
358     EXPECT_FALSE(result); // Should fail without DataUnmarshallingCallback
359 }
360 
361 /*
362  * @tc.name: Unmarshalling004
363  * @tc.desc: Test BlendShaderObj::Unmarshalling with invalid nested object
364  * @tc.type: FUNC
365  * @tc.require: AR000GGNV3
366  * @tc.author:
367  */
368 HWTEST_F(BlendShaderObjTest, Unmarshalling004, TestSize.Level1)
369 {
370     MessageParcel parcel;
371     // Write test data for Lazy shaders with invalid type
372     parcel.WriteInt32(static_cast<int32_t>(BlendMode::OVERLAY)); // blendMode
373     parcel.WriteBool(true); // isDstLazy = true
374     parcel.WriteInt32(999); // Invalid type
375     parcel.WriteInt32(888); // Invalid subType
376 
377     auto shaderObj = BlendShaderObj::CreateForUnmarshalling();
378     EXPECT_TRUE(shaderObj != nullptr);
379 
380     bool isValid = true;
381     bool result = shaderObj->Unmarshalling(parcel, isValid);
382     EXPECT_FALSE(result); // Should fail with invalid nested object type
383 }
384 
385 /*
386  * @tc.name: MarshallingUnmarshallingRoundTrip001
387  * @tc.desc: Test complete marshalling/unmarshalling round trip for BlendShaderObj
388  * @tc.type: FUNC
389  * @tc.require: AR000GGNV3
390  * @tc.author:
391  */
392 HWTEST_F(BlendShaderObjTest, MarshallingUnmarshallingRoundTrip001, TestSize.Level1)
393 {
394     // Create original BlendShaderObj
395     auto originalDstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
396     auto originalSrcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
397     BlendMode originalMode = BlendMode::MULTIPLY;
398     auto originalShaderObj = BlendShaderObj::Create(originalDstShader, originalSrcShader, originalMode);
399     EXPECT_TRUE(originalShaderObj != nullptr);
400 
401     // Set up DataMarshallingCallback for successful marshalling
402     ObjectHelper::Instance().SetDataMarshallingCallback(
__anon441abdaa0202(Parcel& parcel, std::shared_ptr<Drawing::Data> data) 403         [](Parcel& parcel, std::shared_ptr<Drawing::Data> data) -> bool {
404             return RSMarshallingHelper::Marshalling(parcel, data);
405         });
406     // Set up DataUnmarshallingCallback for successful unmarshalling
407     ObjectHelper::Instance().SetDataUnmarshallingCallback(
__anon441abdaa0302(Parcel& parcel) 408         [](Parcel& parcel) -> std::shared_ptr<Drawing::Data> {
409             std::shared_ptr<Drawing::Data> data;
410             if (RSMarshallingHelper::Unmarshalling(parcel, data)) {
411                 return data;
412             }
413             return nullptr;
414         });
415     // Marshal
416     MessageParcel parcel;
417     // Write type and subType externally (as done by MarshallingDrawingObjectFromDrawCmdList)
418     parcel.WriteInt32(originalShaderObj->GetType());
419     parcel.WriteInt32(originalShaderObj->GetSubType());
420     bool marshalResult = originalShaderObj->Marshalling(parcel);
421     EXPECT_TRUE(marshalResult);
422 
423     // Unmarshal
424     auto newShaderObj = BlendShaderObj::CreateForUnmarshalling();
425     EXPECT_TRUE(newShaderObj != nullptr);
426 
427     // Read type and subType that were written externally
428     int32_t type = parcel.ReadInt32();
429     int32_t subType = parcel.ReadInt32();
430     EXPECT_EQ(type, static_cast<int32_t>(Drawing::Object::ObjectType::SHADER_EFFECT));
431     EXPECT_EQ(subType, static_cast<int32_t>(ShaderEffect::ShaderEffectType::BLEND));
432     bool isValid = true;
433     bool unmarshalResult = newShaderObj->Unmarshalling(parcel, isValid);
434     EXPECT_TRUE(unmarshalResult);
435     EXPECT_TRUE(isValid);
436 
437     // Verify consistency
438     EXPECT_EQ(originalShaderObj->GetType(), newShaderObj->GetType());
439     EXPECT_EQ(originalShaderObj->GetSubType(), newShaderObj->GetSubType());
440     // Test that both can generate base objects
441     auto originalBaseObject = originalShaderObj->GenerateBaseObject();
442     auto newBaseObject = newShaderObj->GenerateBaseObject();
443     EXPECT_TRUE(originalBaseObject != nullptr);
444     EXPECT_TRUE(newBaseObject != nullptr);
445     auto originalShader = std::static_pointer_cast<ShaderEffect>(originalBaseObject);
446     auto newShader = std::static_pointer_cast<ShaderEffect>(newBaseObject);
447     EXPECT_EQ(originalShader->GetType(), newShader->GetType());
448     EXPECT_FALSE(originalShader->IsLazy());
449     EXPECT_FALSE(newShader->IsLazy());
450 
451     // Clean up callbacks
452     ObjectHelper::Instance().SetDataMarshallingCallback(nullptr);
453     ObjectHelper::Instance().SetDataUnmarshallingCallback(nullptr);
454 }
455 
456 /*
457  * @tc.name: UnmarshallingWithLazyShader001
458  * @tc.desc: Test BlendShaderObj::Unmarshalling with Lazy shader round trip
459  * @tc.type: FUNC
460  * @tc.require: AR000GGNV3
461  * @tc.author:
462  */
463 HWTEST_F(BlendShaderObjTest, UnmarshallingWithLazyShader001, TestSize.Level1)
464 {
465     // Create a BlendShaderObj with Lazy shaders
466     auto normalDstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
467     auto normalSrcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
468 
469     // Create Lazy shaders using ShaderEffectLazy factory methods
470     auto lazyDstShader = ShaderEffectLazy::CreateBlendShader(normalDstShader, normalSrcShader, BlendMode::SRC_OVER);
471     auto lazySrcShader = ShaderEffectLazy::CreateBlendShader(normalSrcShader, normalDstShader, BlendMode::MULTIPLY);
472     EXPECT_TRUE(lazyDstShader != nullptr);
473     EXPECT_TRUE(lazySrcShader != nullptr);
474     EXPECT_TRUE(lazyDstShader->IsLazy());
475     EXPECT_TRUE(lazySrcShader->IsLazy());
476 
477     // Set up callbacks for marshalling test
478     ObjectHelper::Instance().SetDataMarshallingCallback(
__anon441abdaa0402(Parcel& parcel, std::shared_ptr<Drawing::Data> data) 479         [](Parcel& parcel, std::shared_ptr<Drawing::Data> data) -> bool {
480             return RSMarshallingHelper::Marshalling(parcel, data);
481         });
482     ObjectHelper::Instance().SetDataUnmarshallingCallback(
__anon441abdaa0502(Parcel& parcel) 483         [](Parcel& parcel) -> std::shared_ptr<Drawing::Data> {
484             std::shared_ptr<Drawing::Data> data;
485             if (RSMarshallingHelper::Unmarshalling(parcel, data)) {
486                 return data;
487             }
488             return nullptr;
489         });
490 
491     auto originalShaderObj = BlendShaderObj::Create(lazyDstShader, lazySrcShader, BlendMode::OVERLAY);
492     EXPECT_TRUE(originalShaderObj != nullptr);
493 
494     // Marshal
495     MessageParcel parcel;
496     // Write type and subType externally (as done by MarshallingDrawingObjectFromDrawCmdList)
497     parcel.WriteInt32(originalShaderObj->GetType());
498     parcel.WriteInt32(originalShaderObj->GetSubType());
499     bool marshalResult = originalShaderObj->Marshalling(parcel);
500     EXPECT_TRUE(marshalResult);
501 
502     // Unmarshal
503     auto newShaderObj = BlendShaderObj::CreateForUnmarshalling();
504     EXPECT_TRUE(newShaderObj != nullptr);
505 
506     // Read type and subType that were written externally
507     int32_t type = parcel.ReadInt32();
508     int32_t subType = parcel.ReadInt32();
509     EXPECT_EQ(type, static_cast<int32_t>(Drawing::Object::ObjectType::SHADER_EFFECT));
510     EXPECT_EQ(subType, static_cast<int32_t>(ShaderEffect::ShaderEffectType::BLEND));
511 
512     bool isValid = true;
513     bool unmarshalResult = newShaderObj->Unmarshalling(parcel, isValid);
514     EXPECT_TRUE(unmarshalResult);
515     EXPECT_TRUE(isValid);
516     // Verify consistency
517     EXPECT_EQ(originalShaderObj->GetType(), newShaderObj->GetType());
518     EXPECT_EQ(originalShaderObj->GetSubType(), newShaderObj->GetSubType());
519     // Test that both can generate base objects
520     auto originalBaseObject = originalShaderObj->GenerateBaseObject();
521     auto newBaseObject = newShaderObj->GenerateBaseObject();
522     EXPECT_TRUE(originalBaseObject != nullptr);
523     EXPECT_TRUE(newBaseObject != nullptr);
524     auto originalShader = std::static_pointer_cast<ShaderEffect>(originalBaseObject);
525     auto newShader = std::static_pointer_cast<ShaderEffect>(newBaseObject);
526     EXPECT_TRUE(originalShader != nullptr);
527     EXPECT_TRUE(newShader != nullptr);
528     // Real memory content comparison through Serialize
529     auto originalData = originalShader->Serialize();
530     auto newData = newShader->Serialize();
531     EXPECT_TRUE(originalData != nullptr);
532     EXPECT_TRUE(newData != nullptr);
533     // Compare serialized data size
534     EXPECT_EQ(originalData->GetSize(), newData->GetSize());
535     EXPECT_GT(originalData->GetSize(), 0);
536     EXPECT_GT(newData->GetSize(), 0);
537     // Compare serialized memory content
538     if (originalData->GetSize() > 0 && newData->GetSize() > 0) {
539         const void* originalMemory = originalData->GetData();
540         const void* newMemory = newData->GetData();
541         EXPECT_TRUE(originalMemory != nullptr);
542         EXPECT_TRUE(newMemory != nullptr);
543         // Byte-level memory comparison
544         int memResult = memcmp(originalMemory, newMemory, originalData->GetSize());
545         EXPECT_EQ(memResult, 0);
546     }
547     // Clean up callbacks
548     ObjectHelper::Instance().SetDataMarshallingCallback(nullptr);
549     ObjectHelper::Instance().SetDataUnmarshallingCallback(nullptr);
550 }
551 
552 /*
553  * @tc.name: MixedLazyNonLazyShader001
554  * @tc.desc: Test BlendShaderObj with Lazy dst and non-Lazy src shader
555  * @tc.type: FUNC
556  * @tc.require: AR000GGNV3
557  * @tc.author:
558  */
559 HWTEST_F(BlendShaderObjTest, MixedLazyNonLazyShader001, TestSize.Level1)
560 {
561     // Create mixed shader types: Lazy dst, non-Lazy src
562     auto normalDstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
563     auto nonLazySrcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
564     auto lazyDstShader = ShaderEffectLazy::CreateBlendShader(normalDstShader, nonLazySrcShader, BlendMode::SRC_IN);
565     EXPECT_TRUE(lazyDstShader != nullptr);
566     EXPECT_TRUE(lazyDstShader->IsLazy());
567     EXPECT_TRUE(nonLazySrcShader != nullptr);
568     EXPECT_FALSE(nonLazySrcShader->IsLazy());
569 
570     auto shaderObj = BlendShaderObj::Create(lazyDstShader, nonLazySrcShader, BlendMode::SCREEN);
571     EXPECT_TRUE(shaderObj != nullptr);
572 
573     // Test GenerateBaseObject with mixed types
574     auto baseObject = shaderObj->GenerateBaseObject();
575     EXPECT_TRUE(baseObject != nullptr);
576 
577     auto generatedShader = std::static_pointer_cast<ShaderEffect>(baseObject);
578     EXPECT_TRUE(generatedShader != nullptr);
579     if (generatedShader) {
580         EXPECT_EQ(generatedShader->GetType(), ShaderEffect::ShaderEffectType::BLEND);
581         EXPECT_FALSE(generatedShader->IsLazy());
582     }
583 
584     // Set up callbacks for marshalling test
585     ObjectHelper::Instance().SetDataMarshallingCallback(
__anon441abdaa0602(Parcel& parcel, std::shared_ptr<Drawing::Data> data) 586         [](Parcel& parcel, std::shared_ptr<Drawing::Data> data) -> bool {
587             return RSMarshallingHelper::Marshalling(parcel, data);
588         });
589     ObjectHelper::Instance().SetDataUnmarshallingCallback(
__anon441abdaa0702(Parcel& parcel) 590         [](Parcel& parcel) -> std::shared_ptr<Drawing::Data> {
591             std::shared_ptr<Drawing::Data> data;
592             if (RSMarshallingHelper::Unmarshalling(parcel, data)) {
593                 return data;
594             }
595             return nullptr;
596         });
597 
598     // Test marshalling/unmarshalling with mixed types
599     MessageParcel parcel;
600     // Write type and subType externally (as done by MarshallingDrawingObjectFromDrawCmdList)
601     parcel.WriteInt32(shaderObj->GetType());
602     parcel.WriteInt32(shaderObj->GetSubType());
603     bool marshalResult = shaderObj->Marshalling(parcel);
604     EXPECT_TRUE(marshalResult);
605     auto newShaderObj = BlendShaderObj::CreateForUnmarshalling();
606     // Read type and subType that were written externally
607     int32_t type = parcel.ReadInt32();
608     int32_t subType = parcel.ReadInt32();
609     EXPECT_EQ(type, static_cast<int32_t>(Drawing::Object::ObjectType::SHADER_EFFECT));
610     EXPECT_EQ(subType, static_cast<int32_t>(ShaderEffect::ShaderEffectType::BLEND));
611 
612     bool isValid = true;
613     bool unmarshalResult = newShaderObj->Unmarshalling(parcel, isValid);
614     EXPECT_TRUE(unmarshalResult);
615     EXPECT_TRUE(isValid);
616     // Verify consistency
617     EXPECT_EQ(shaderObj->GetType(), newShaderObj->GetType());
618     EXPECT_EQ(shaderObj->GetSubType(), newShaderObj->GetSubType());
619     // Clean up callbacks
620     ObjectHelper::Instance().SetDataMarshallingCallback(nullptr);
621     ObjectHelper::Instance().SetDataUnmarshallingCallback(nullptr);
622 }
623 
624 /*
625  * @tc.name: MixedLazyNonLazyShader002
626  * @tc.desc: Test BlendShaderObj with non-Lazy dst and Lazy src shader
627  * @tc.type: FUNC
628  * @tc.require: AR000GGNV3
629  * @tc.author:
630  */
631 HWTEST_F(BlendShaderObjTest, MixedLazyNonLazyShader002, TestSize.Level1)
632 {
633     // Create mixed shader types: non-Lazy dst, Lazy src
634     auto nonLazyDstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
635     auto normalSrcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
636     auto lazySrcShader = ShaderEffectLazy::CreateBlendShader(normalSrcShader, nonLazyDstShader, BlendMode::DST_IN);
637     EXPECT_TRUE(nonLazyDstShader != nullptr);
638     EXPECT_FALSE(nonLazyDstShader->IsLazy());
639     EXPECT_TRUE(lazySrcShader != nullptr);
640     EXPECT_TRUE(lazySrcShader->IsLazy());
641 
642     auto shaderObj = BlendShaderObj::Create(nonLazyDstShader, lazySrcShader, BlendMode::DARKEN);
643     EXPECT_TRUE(shaderObj != nullptr);
644 
645     // Test GenerateBaseObject with mixed types
646     auto baseObject = shaderObj->GenerateBaseObject();
647     EXPECT_TRUE(baseObject != nullptr);
648 
649     auto generatedShader = std::static_pointer_cast<ShaderEffect>(baseObject);
650     EXPECT_TRUE(generatedShader != nullptr);
651     if (generatedShader) {
652         EXPECT_EQ(generatedShader->GetType(), ShaderEffect::ShaderEffectType::BLEND);
653         EXPECT_FALSE(generatedShader->IsLazy());
654     }
655 
656     // Set up callbacks for marshalling test
657     ObjectHelper::Instance().SetDataMarshallingCallback(
__anon441abdaa0802(Parcel& parcel, std::shared_ptr<Drawing::Data> data) 658         [](Parcel& parcel, std::shared_ptr<Drawing::Data> data) -> bool {
659             return RSMarshallingHelper::Marshalling(parcel, data);
660         });
661     ObjectHelper::Instance().SetDataUnmarshallingCallback(
__anon441abdaa0902(Parcel& parcel) 662         [](Parcel& parcel) -> std::shared_ptr<Drawing::Data> {
663             std::shared_ptr<Drawing::Data> data;
664             if (RSMarshallingHelper::Unmarshalling(parcel, data)) {
665                 return data;
666             }
667             return nullptr;
668         });
669 
670     // Test marshalling/unmarshalling with mixed types
671     MessageParcel parcel;
672     // Write type and subType externally (as done by MarshallingDrawingObjectFromDrawCmdList)
673     parcel.WriteInt32(shaderObj->GetType());
674     parcel.WriteInt32(shaderObj->GetSubType());
675     bool marshalResult = shaderObj->Marshalling(parcel);
676     EXPECT_TRUE(marshalResult);
677     auto newShaderObj = BlendShaderObj::CreateForUnmarshalling();
678     // Read type and subType that were written externally
679     int32_t type = parcel.ReadInt32();
680     int32_t subType = parcel.ReadInt32();
681     EXPECT_EQ(type, static_cast<int32_t>(Drawing::Object::ObjectType::SHADER_EFFECT));
682     EXPECT_EQ(subType, static_cast<int32_t>(ShaderEffect::ShaderEffectType::BLEND));
683 
684     bool isValid = true;
685     bool unmarshalResult = newShaderObj->Unmarshalling(parcel, isValid);
686     EXPECT_TRUE(unmarshalResult);
687     EXPECT_TRUE(isValid);
688 
689     // Verify consistency
690     EXPECT_EQ(shaderObj->GetType(), newShaderObj->GetType());
691     EXPECT_EQ(shaderObj->GetSubType(), newShaderObj->GetSubType());
692 
693     // Test that both can generate base objects
694     auto originalBaseObject = shaderObj->GenerateBaseObject();
695     auto newBaseObject = newShaderObj->GenerateBaseObject();
696     EXPECT_TRUE(originalBaseObject != nullptr);
697     EXPECT_TRUE(newBaseObject != nullptr);
698 
699     // Clean up callbacks
700     ObjectHelper::Instance().SetDataMarshallingCallback(nullptr);
701     ObjectHelper::Instance().SetDataUnmarshallingCallback(nullptr);
702 }
703 
704 /*
705  * @tc.name: DepthProtectionTest001
706  * @tc.desc: Test BlendShaderObj depth protection against malicious nesting
707  * @tc.type: FUNC
708  * @tc.require: AR000GGNV3
709  * @tc.author:
710  */
711 HWTEST_F(BlendShaderObjTest, DepthProtectionTest001, TestSize.Level1)
712 {
713     auto shaderObj = BlendShaderObj::CreateForUnmarshalling();
714     EXPECT_TRUE(shaderObj != nullptr);
715 
716     MessageParcel parcel;
717     // Simulate malicious deep nesting by using depth close to limit
718     // This should trigger depth protection when depth >= MAX_NESTING_DEPTH
719     int32_t maliciousDepth = ObjectHelper::MAX_NESTING_DEPTH - 1; // Very close to limit
720     // Test with depth at limit boundary
721     bool isValid = true;
722     bool result = shaderObj->Unmarshalling(parcel, isValid, maliciousDepth);
723     EXPECT_FALSE(result); // Should fail due to depth protection
724 }
725 
726 /*
727  * @tc.name: DepthProtectionTest002
728  * @tc.desc: Test BlendShaderObj depth protection with exact limit
729  * @tc.type: FUNC
730  * @tc.require: AR000GGNV3
731  * @tc.author:
732  */
733 HWTEST_F(BlendShaderObjTest, DepthProtectionTest002, TestSize.Level1)
734 {
735     auto shaderObj = BlendShaderObj::CreateForUnmarshalling();
736     EXPECT_TRUE(shaderObj != nullptr);
737 
738     MessageParcel parcel;
739     // Test with depth exactly at MAX_NESTING_DEPTH
740     int32_t exactLimitDepth = ObjectHelper::MAX_NESTING_DEPTH;
741     bool isValid = true;
742     bool result = shaderObj->Unmarshalling(parcel, isValid, exactLimitDepth);
743     EXPECT_FALSE(result); // Should fail due to depth >= MAX_NESTING_DEPTH
744 }
745 
746 /*
747  * @tc.name: DepthProtectionTest003
748  * @tc.desc: Test BlendShaderObj depth protection with safe depth
749  * @tc.type: FUNC
750  * @tc.require: AR000GGNV3
751  * @tc.author:
752  */
753 HWTEST_F(BlendShaderObjTest, DepthProtectionTest003, TestSize.Level1)
754 {
755     auto shaderObj = BlendShaderObj::CreateForUnmarshalling();
756     EXPECT_TRUE(shaderObj != nullptr);
757 
758     // Set up callbacks for successful parsing
759     ObjectHelper::Instance().SetDataMarshallingCallback(
__anon441abdaa0a02(Parcel& parcel, std::shared_ptr<Drawing::Data> data) 760         [](Parcel& parcel, std::shared_ptr<Drawing::Data> data) -> bool {
761             return RSMarshallingHelper::Marshalling(parcel, data);
762         });
763     ObjectHelper::Instance().SetDataUnmarshallingCallback(
__anon441abdaa0b02(Parcel& parcel) 764         [](Parcel& parcel) -> std::shared_ptr<Drawing::Data> {
765             // Return nullptr to simulate data reading failure
766             return nullptr;
767         });
768 
769     MessageParcel parcel;
770     // Write valid data for BlendShaderObj
771     parcel.WriteInt32(static_cast<int32_t>(BlendMode::SRC_OVER)); // blendMode
772     parcel.WriteBool(false); // isDstLazy = false
773     parcel.WriteBool(false); // isSrcLazy = false
774     // Test with safe depth (well below limit)
775     int32_t safeDepth = ObjectHelper::MAX_NESTING_DEPTH / 10; // Much less than MAX_NESTING_DEPTH
776     bool isValid = true;
777     bool result = shaderObj->Unmarshalling(parcel, isValid, safeDepth);
778     // Should fail due to DataUnmarshallingCallback returning nullptr, not due to depth protection
779     EXPECT_FALSE(result); // Expected to fail due to DataUnmarshallingCallback failure
780     // Clean up callbacks
781     ObjectHelper::Instance().SetDataMarshallingCallback(nullptr);
782     ObjectHelper::Instance().SetDataUnmarshallingCallback(nullptr);
783 }
784 
785 /*
786  * @tc.name: DepthProtectionTest004
787  * @tc.desc: Test depth protection with extremely large depth value
788  * @tc.type: FUNC
789  * @tc.require: AR000GGNV3
790  * @tc.author:
791  */
792 HWTEST_F(BlendShaderObjTest, DepthProtectionTest004, TestSize.Level1)
793 {
794     auto shaderObj = BlendShaderObj::CreateForUnmarshalling();
795     EXPECT_TRUE(shaderObj != nullptr);
796     MessageParcel parcel;
797     // Test with extremely large depth value (simulating attack)
798     int32_t attackDepth = ObjectHelper::MAX_NESTING_DEPTH * 2; // Much larger than MAX_NESTING_DEPTH
799     bool isValid = true;
800     bool result = shaderObj->Unmarshalling(parcel, isValid, attackDepth);
801     EXPECT_FALSE(result); // Should fail immediately due to depth protection
802 }
803 
804 /*
805  * @tc.name: UnmarshallingReadBlendModeFailure001
806  * @tc.desc: Test BlendShaderObj::Unmarshalling with parcel.ReadInt32(blendModeValue) failure
807  * @tc.type: FUNC
808  * @tc.require: AR000GGNV3
809  */
810 HWTEST_F(BlendShaderObjTest, UnmarshallingReadBlendModeFailure001, TestSize.Level1)
811 {
812     auto obj = BlendShaderObj::CreateForUnmarshalling();
813     EXPECT_TRUE(obj != nullptr);
814     // Create an empty Parcel - ReadInt32 will fail due to no data
815     MessageParcel emptyParcel;
816     bool isValid = true;
817     bool result = obj->Unmarshalling(emptyParcel, isValid, 0);
818     EXPECT_FALSE(result);
819 }
820 
821 /*
822  * @tc.name: UnmarshallingReadIsDstLazyFailure001
823  * @tc.desc: Test BlendShaderObj::Unmarshalling with parcel.ReadBool(isDstLazy) failure
824  * @tc.type: FUNC
825  * @tc.require: AR000GGNV3
826  */
827 HWTEST_F(BlendShaderObjTest, UnmarshallingReadIsDstLazyFailure001, TestSize.Level1)
828 {
829     auto obj = BlendShaderObj::CreateForUnmarshalling();
830     EXPECT_TRUE(obj != nullptr);
831     // Create a Parcel with only blendMode - isDstLazy read will fail
832     MessageParcel parcel;
833     parcel.WriteInt32(static_cast<int32_t>(BlendMode::SRC_OVER)); // blendMode
834     // No isDstLazy written, so ReadBool(isDstLazy) will fail
835     bool isValid = true;
836     bool result = obj->Unmarshalling(parcel, isValid, 0);
837     EXPECT_FALSE(result);
838 }
839 
840 /*
841  * @tc.name: UnmarshallingDstLazyShaderFailure001
842  * @tc.desc: Test BlendShaderObj::Unmarshalling with ShaderEffectLazy::Unmarshalling failure for dst
843  * @tc.type: FUNC
844  * @tc.require: AR000GGNV3
845  */
846 HWTEST_F(BlendShaderObjTest, UnmarshallingDstLazyShaderFailure001, TestSize.Level1)
847 {
848     auto obj = BlendShaderObj::CreateForUnmarshalling();
849     EXPECT_TRUE(obj != nullptr);
850     // Create a Parcel with basic data but isDstLazy=true
851     MessageParcel parcel;
852     parcel.WriteInt32(static_cast<int32_t>(BlendMode::MULTIPLY)); // blendMode
853     parcel.WriteBool(true); // isDstLazy = true
854     // Write incomplete data for ShaderEffectLazy to cause failure
855     parcel.WriteInt32(static_cast<int32_t>(Drawing::Object::ObjectType::SHADER_EFFECT));
856     // Missing subType data will cause ShaderEffectLazy::Unmarshalling to fail
857     bool isValid = true;
858     bool result = obj->Unmarshalling(parcel, isValid, 0);
859     EXPECT_FALSE(result);
860 }
861 
862 /*
863  * @tc.name: UnmarshallingDstNonLazyShaderFailure001
864  * @tc.desc: Test BlendShaderObj::Unmarshalling with ShaderEffect::Unmarshalling failure for dst
865  * @tc.type: FUNC
866  * @tc.require: AR000GGNV3
867  */
868 HWTEST_F(BlendShaderObjTest, UnmarshallingDstNonLazyShaderFailure001, TestSize.Level1)
869 {
870     auto obj = BlendShaderObj::CreateForUnmarshalling();
871     EXPECT_TRUE(obj != nullptr);
872     // Create a Parcel with basic data but isDstLazy=false
873     MessageParcel parcel;
874     parcel.WriteInt32(static_cast<int32_t>(BlendMode::OVERLAY)); // blendMode
875     parcel.WriteBool(false); // isDstLazy = false
876     // No shader data written, so ShaderEffect::Unmarshalling will fail
877     bool isValid = true;
878     bool result = obj->Unmarshalling(parcel, isValid, 0);
879     EXPECT_FALSE(result);
880 }
881 
882 /*
883  * @tc.name: UnmarshallingReadIsSrcLazyFailure001
884  * @tc.desc: Test BlendShaderObj::Unmarshalling with parcel.ReadBool(isSrcLazy) failure
885  * @tc.type: FUNC
886  * @tc.require: AR000GGNV3
887  */
888 HWTEST_F(BlendShaderObjTest, UnmarshallingReadIsSrcLazyFailure001, TestSize.Level1)
889 {
890     auto obj = BlendShaderObj::CreateForUnmarshalling();
891     EXPECT_TRUE(obj != nullptr);
892     // Setup successful dst shader unmarshalling first
893     ObjectHelper::Instance().SetDataUnmarshallingCallback(
__anon441abdaa0c02(Parcel& parcel) 894         [](Parcel& parcel) -> std::shared_ptr<Drawing::Data> {
895             std::shared_ptr<Drawing::Data> data;
896             if (RSMarshallingHelper::Unmarshalling(parcel, data)) {
897                 return data;
898             }
899             return nullptr;
900         });
901     MessageParcel parcel;
902     parcel.WriteInt32(static_cast<int32_t>(BlendMode::SCREEN)); // blendMode
903     parcel.WriteBool(false); // isDstLazy = false
904     // Write minimal shader data for dst to succeed
905     parcel.WriteInt32(static_cast<int32_t>(ShaderEffect::ShaderEffectType::COLOR_SHADER));
906     parcel.WriteInt32(0xFF0000FF); // color
907     // No isSrcLazy written, so ReadBool(isSrcLazy) will fail
908     bool isValid = true;
909     bool result = obj->Unmarshalling(parcel, isValid, 0);
910     EXPECT_FALSE(result);
911     ObjectHelper::Instance().SetDataUnmarshallingCallback(nullptr);
912 }
913 
914 /*
915  * @tc.name: UnmarshallingSrcLazyShaderFailure001
916  * @tc.desc: Test BlendShaderObj::Unmarshalling with ShaderEffectLazy::Unmarshalling failure for src
917  * @tc.type: FUNC
918  * @tc.require: AR000GGNV3
919  */
920 HWTEST_F(BlendShaderObjTest, UnmarshallingSrcLazyShaderFailure001, TestSize.Level1)
921 {
922     auto obj = BlendShaderObj::CreateForUnmarshalling();
923     EXPECT_TRUE(obj != nullptr);
924     // Setup successful dst shader unmarshalling first
925     ObjectHelper::Instance().SetDataUnmarshallingCallback(
__anon441abdaa0d02(Parcel& parcel) 926         [](Parcel& parcel) -> std::shared_ptr<Drawing::Data> {
927             std::shared_ptr<Drawing::Data> data;
928             if (RSMarshallingHelper::Unmarshalling(parcel, data)) {
929                 return data;
930             }
931             return nullptr;
932         });
933     MessageParcel parcel;
934     parcel.WriteInt32(static_cast<int32_t>(BlendMode::DARKEN)); // blendMode
935     parcel.WriteBool(false); // isDstLazy = false
936     // Write minimal shader data for dst to succeed
937     parcel.WriteInt32(static_cast<int32_t>(ShaderEffect::ShaderEffectType::COLOR_SHADER));
938     parcel.WriteInt32(0xFF0000FF); // color
939     parcel.WriteBool(true); // isSrcLazy = true
940     // Write incomplete data for ShaderEffectLazy to cause failure
941     parcel.WriteInt32(static_cast<int32_t>(Drawing::Object::ObjectType::SHADER_EFFECT));
942     // Missing subType data will cause ShaderEffectLazy::Unmarshalling to fail
943     bool isValid = true;
944     bool result = obj->Unmarshalling(parcel, isValid, 0);
945     EXPECT_FALSE(result);
946     ObjectHelper::Instance().SetDataUnmarshallingCallback(nullptr);
947 }
948 
949 /*
950  * @tc.name: UnmarshallingSrcNonLazyShaderFailure001
951  * @tc.desc: Test BlendShaderObj::Unmarshalling with ShaderEffect::Unmarshalling failure for src
952  * @tc.type: FUNC
953  * @tc.require: AR000GGNV3
954  */
955 HWTEST_F(BlendShaderObjTest, UnmarshallingSrcNonLazyShaderFailure001, TestSize.Level1)
956 {
957     auto obj = BlendShaderObj::CreateForUnmarshalling();
958     EXPECT_TRUE(obj != nullptr);
959     // Setup successful dst shader unmarshalling first
960     ObjectHelper::Instance().SetDataUnmarshallingCallback(
__anon441abdaa0e02(Parcel& parcel) 961         [](Parcel& parcel) -> std::shared_ptr<Drawing::Data> {
962             std::shared_ptr<Drawing::Data> data;
963             if (RSMarshallingHelper::Unmarshalling(parcel, data)) {
964                 return data;
965             }
966             return nullptr;
967         });
968     MessageParcel parcel;
969     parcel.WriteInt32(static_cast<int32_t>(BlendMode::LIGHTEN)); // blendMode
970     parcel.WriteBool(false); // isDstLazy = false
971     // Write minimal shader data for dst to succeed
972     parcel.WriteInt32(static_cast<int32_t>(ShaderEffect::ShaderEffectType::COLOR_SHADER));
973     parcel.WriteInt32(0xFF0000FF); // color
974     parcel.WriteBool(false); // isSrcLazy = false
975     // No src shader data written, so ShaderEffect::Unmarshalling will fail
976     bool isValid = true;
977     bool result = obj->Unmarshalling(parcel, isValid, 0);
978     EXPECT_FALSE(result);
979     ObjectHelper::Instance().SetDataUnmarshallingCallback(nullptr);
980 }
981 
982 // Mock class that always fails GenerateBaseObject()
983 class MockFailingShaderEffectObj : public ShaderEffectObj {
984 public:
MockFailingShaderEffectObj()985     MockFailingShaderEffectObj() : ShaderEffectObj(static_cast<int32_t>(ShaderEffect::ShaderEffectType::BLEND))
986     {
987     }
988 
GenerateBaseObject()989     virtual std::shared_ptr<void> GenerateBaseObject() override
990     {
991         // Always return nullptr to simulate failure
992         return nullptr;
993     }
994 
995 #ifdef ROSEN_OHOS
Marshalling(Parcel & parcel)996     virtual bool Marshalling(Parcel& parcel) override
997     {
998         // Minimal implementation
999         return parcel.WriteInt32(type_) && parcel.WriteInt32(subType_);
1000     }
1001 
Unmarshalling(Parcel & parcel,bool & isValid,int32_t depth=0)1002     virtual bool Unmarshalling(Parcel& parcel, bool& isValid, int32_t depth = 0) override
1003     {
1004         // Minimal implementation
1005         return true;
1006     }
1007 #endif
1008 };
1009 
1010 /*
1011  * @tc.name: GenerateBaseObjectLazyMaterializeFail001
1012  * @tc.desc: Test BlendShaderObj::GenerateBaseObject with Lazy shader that fails to materialize
1013  * @tc.type: FUNC
1014  * @tc.require: AR000GGNV3
1015  * @tc.author:
1016  */
1017 HWTEST_F(BlendShaderObjTest, GenerateBaseObjectLazyMaterializeFail001, TestSize.Level1)
1018 {
1019     // Strategy: Create a LazyShader with a MockFailingShaderEffectObj that always returns nullptr
1020     // This will cause Materialize() to fail, which should make BlendShaderObj::GenerateBaseObject() return nullptr
1021 
1022     // Create a mock ShaderEffectObj that will fail GenerateBaseObject()
1023     auto failingObj = std::make_shared<MockFailingShaderEffectObj>();
1024     ASSERT_NE(failingObj, nullptr);
1025 
1026     // Verify that the mock object fails as expected
1027     auto baseObject = failingObj->GenerateBaseObject();
1028     EXPECT_EQ(baseObject, nullptr);
1029 
1030     // Create LazyShader using the failing ShaderEffectObj
1031     auto failingLazyShader = ShaderEffectLazy::CreateFromShaderEffectObj(failingObj);
1032     ASSERT_NE(failingLazyShader, nullptr);
1033     EXPECT_TRUE(failingLazyShader->IsLazy());
1034 
1035     // Verify that the LazyShader fails to materialize due to the failing ShaderEffectObj
1036     auto materializedShader = failingLazyShader->Materialize();
1037     EXPECT_EQ(materializedShader, nullptr);
1038 
1039     // Now create a BlendShaderObj with the failing LazyShader and a normal shader
1040     auto normalShader = ShaderEffect::CreateColorShader(0xFF00FF00);
1041     ASSERT_NE(normalShader, nullptr);
1042 
1043     // Test case 1: Failing LazyShader as dst, normal shader as src
1044     auto blendObj1 = BlendShaderObj::Create(failingLazyShader, normalShader, BlendMode::SRC_OVER);
1045     ASSERT_NE(blendObj1, nullptr);
1046 
1047     // This should return nullptr because the dst LazyShader fails to materialize
1048     auto result1 = blendObj1->GenerateBaseObject();
1049     EXPECT_EQ(result1, nullptr); // Target branch: if (!actualDst) return nullptr;
1050 
1051     // Test case 2: Normal shader as dst, failing LazyShader as src
1052     auto blendObj2 = BlendShaderObj::Create(normalShader, failingLazyShader, BlendMode::MULTIPLY);
1053     ASSERT_NE(blendObj2, nullptr);
1054 
1055     // This should return nullptr because the src LazyShader fails to materialize
1056     auto result2 = blendObj2->GenerateBaseObject();
1057     EXPECT_EQ(result2, nullptr); // Target branch: if (!actualSrc) return nullptr;
1058 
1059     // Test case 3: Both shaders are failing LazyShaders
1060     auto blendObj3 = BlendShaderObj::Create(failingLazyShader, failingLazyShader, BlendMode::SCREEN);
1061     ASSERT_NE(blendObj3, nullptr);
1062 
1063     // This should return nullptr because both LazyShaders fail to materialize
1064     auto result3 = blendObj3->GenerateBaseObject();
1065     EXPECT_EQ(result3, nullptr); // Target branch: if (!actualDst) return nullptr;
1066 }
1067 
1068 /*
1069  * @tc.name: GenerateBaseObjectMixedLazyNormal001
1070  * @tc.desc: Test BlendShaderObj::GenerateBaseObject with mixed lazy and normal shaders
1071  * @tc.type: FUNC
1072  * @tc.require: AR000GGNV3
1073  * @tc.author:
1074  */
1075 HWTEST_F(BlendShaderObjTest, GenerateBaseObjectMixedLazyNormal001, TestSize.Level1)
1076 {
1077     // Test mixed scenarios: one lazy, one normal
1078     auto normalDst = ShaderEffect::CreateColorShader(0xFF0000FF);
1079     auto normalSrc = ShaderEffect::CreateColorShader(0xFF00FF00);
1080 
1081     // Create a valid lazy shader
1082     auto lazyShader = ShaderEffectLazy::CreateBlendShader(normalDst, normalSrc, BlendMode::MULTIPLY);
1083     ASSERT_NE(lazyShader, nullptr);
1084     EXPECT_TRUE(lazyShader->IsLazy());
1085 
1086     // Test 1: Normal dst + Lazy src
1087     auto blendObj1 = BlendShaderObj::Create(normalDst, lazyShader, BlendMode::SCREEN);
1088     ASSERT_NE(blendObj1, nullptr);
1089 
1090     auto baseObject1 = blendObj1->GenerateBaseObject();
1091     EXPECT_NE(baseObject1, nullptr);
1092 
1093     auto generatedShader1 = std::static_pointer_cast<ShaderEffect>(baseObject1);
1094     EXPECT_NE(generatedShader1, nullptr);
1095     if (generatedShader1) {
1096         EXPECT_EQ(generatedShader1->GetType(), ShaderEffect::ShaderEffectType::BLEND);
1097         EXPECT_FALSE(generatedShader1->IsLazy()); // Should be materialized
1098     }
1099 
1100     // Test 2: Lazy dst + Normal src
1101     auto blendObj2 = BlendShaderObj::Create(lazyShader, normalSrc, BlendMode::OVERLAY);
1102     ASSERT_NE(blendObj2, nullptr);
1103 
1104     auto baseObject2 = blendObj2->GenerateBaseObject();
1105     EXPECT_NE(baseObject2, nullptr);
1106 
1107     auto generatedShader2 = std::static_pointer_cast<ShaderEffect>(baseObject2);
1108     EXPECT_NE(generatedShader2, nullptr);
1109     if (generatedShader2) {
1110         EXPECT_EQ(generatedShader2->GetType(), ShaderEffect::ShaderEffectType::BLEND);
1111         EXPECT_FALSE(generatedShader2->IsLazy()); // Should be materialized
1112     }
1113 
1114     // Test 3: Both lazy shaders
1115     auto lazyShader2 = ShaderEffectLazy::CreateBlendShader(normalDst, normalSrc, BlendMode::DARKEN);
1116     ASSERT_NE(lazyShader2, nullptr);
1117 
1118     auto blendObj3 = BlendShaderObj::Create(lazyShader, lazyShader2, BlendMode::LIGHTEN);
1119     ASSERT_NE(blendObj3, nullptr);
1120 
1121     auto baseObject3 = blendObj3->GenerateBaseObject();
1122     EXPECT_NE(baseObject3, nullptr);
1123 
1124     auto generatedShader3 = std::static_pointer_cast<ShaderEffect>(baseObject3);
1125     EXPECT_NE(generatedShader3, nullptr);
1126     if (generatedShader3) {
1127         EXPECT_EQ(generatedShader3->GetType(), ShaderEffect::ShaderEffectType::BLEND);
1128         EXPECT_FALSE(generatedShader3->IsLazy()); // Should be materialized
1129     }
1130 }
1131 
1132 /*
1133  * @tc.name: MarshallingNullShadersTest001
1134  * @tc.desc: Test BlendShaderObj::Marshalling with null shaders using direct construction
1135  * @tc.type: FUNC
1136  * @tc.require: AR000GGNV3
1137  * @tc.author:
1138  */
1139 HWTEST_F(BlendShaderObjTest, MarshallingNullShadersTest001, TestSize.Level1)
1140 {
1141     // Test 1: Both shaders null (using default constructor)
1142     auto objBothNull = std::shared_ptr<BlendShaderObj>(new BlendShaderObj());
1143     ASSERT_NE(objBothNull, nullptr);
1144     MessageParcel parcel1;
1145     bool result1 = objBothNull->Marshalling(parcel1);
1146     EXPECT_FALSE(result1); // Should fail due to null shaders
1147 
1148     // Test 2: Only dst null
1149     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
1150     ASSERT_NE(srcShader, nullptr);
1151     auto objDstNull = std::shared_ptr<BlendShaderObj>(
1152         new BlendShaderObj(nullptr, srcShader, BlendMode::MULTIPLY));
1153     ASSERT_NE(objDstNull, nullptr);
1154     MessageParcel parcel2;
1155     bool result2 = objDstNull->Marshalling(parcel2);
1156     EXPECT_FALSE(result2); // Should fail due to null dst shader
1157 
1158     // Test 3: Only src null
1159     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
1160     ASSERT_NE(dstShader, nullptr);
1161     auto objSrcNull = std::shared_ptr<BlendShaderObj>(
1162         new BlendShaderObj(dstShader, nullptr, BlendMode::MULTIPLY));
1163     ASSERT_NE(objSrcNull, nullptr);
1164     MessageParcel parcel3;
1165     bool result3 = objSrcNull->Marshalling(parcel3);
1166     EXPECT_FALSE(result3); // Should fail due to null src shader
1167 }
1168 
1169 /*
1170  * @tc.name: GenerateBaseObjectNullShadersTest001
1171  * @tc.desc: Test BlendShaderObj::GenerateBaseObject with null shaders using direct construction
1172  * @tc.type: FUNC
1173  * @tc.require: AR000GGNV3
1174  * @tc.author:
1175  */
1176 HWTEST_F(BlendShaderObjTest, GenerateBaseObjectNullShadersTest001, TestSize.Level1)
1177 {
1178     // Test 1: Both shaders null (using default constructor)
1179     auto objBothNull = std::shared_ptr<BlendShaderObj>(new BlendShaderObj());
1180     ASSERT_NE(objBothNull, nullptr);
1181     auto result1 = objBothNull->GenerateBaseObject();
1182     EXPECT_EQ(result1, nullptr); // Should return nullptr due to null shaders
1183 
1184     // Test 2: Only dst null
1185     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
1186     ASSERT_NE(srcShader, nullptr);
1187     auto objDstNull = std::shared_ptr<BlendShaderObj>(
1188         new BlendShaderObj(nullptr, srcShader, BlendMode::MULTIPLY));
1189     ASSERT_NE(objDstNull, nullptr);
1190     auto result2 = objDstNull->GenerateBaseObject();
1191     EXPECT_EQ(result2, nullptr); // Should return nullptr due to null dst shader
1192 
1193     // Test 3: Only src null
1194     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
1195     ASSERT_NE(dstShader, nullptr);
1196     auto objSrcNull = std::shared_ptr<BlendShaderObj>(
1197         new BlendShaderObj(dstShader, nullptr, BlendMode::MULTIPLY));
1198     ASSERT_NE(objSrcNull, nullptr);
1199     auto result3 = objSrcNull->GenerateBaseObject();
1200     EXPECT_EQ(result3, nullptr); // Should return nullptr due to null src shader
1201 }
1202 
1203 /*
1204  * @tc.name: MarshallingWriteFailureTest001
1205  * @tc.desc: Test BlendShaderObj::Marshalling write branch failures by filling parcel to capacity
1206  * @tc.type: FUNC
1207  * @tc.require: AR000GGNV3
1208  * @tc.author:
1209  */
1210 HWTEST_F(BlendShaderObjTest, MarshallingWriteFailureTest001, TestSize.Level1)
1211 {
1212     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
1213     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
1214     auto obj = BlendShaderObj::Create(dstShader, srcShader, BlendMode::MULTIPLY);
1215     ASSERT_NE(obj, nullptr);
1216 
1217     // Create buffer to fill parcel capacity (200K minimum)
1218     const size_t BUFFER_SIZE = 200 * 1024; // 200K
1219     std::vector<uint8_t> fillBuffer(BUFFER_SIZE, 0xFF);
1220 
1221     // Test 1: Fill parcel completely, then try Marshalling (should fail on WriteInt32(blendMode))
1222     MessageParcel parcel1;
1223     parcel1.SetMaxCapacity(BUFFER_SIZE);
1224     bool fillResult1 = parcel1.WriteBuffer(fillBuffer.data(), BUFFER_SIZE);
1225     EXPECT_TRUE(fillResult1);
1226     // Now parcel is full, Marshalling should fail on WriteInt32(blendMode)
1227     bool result1 = obj->Marshalling(parcel1);
1228     EXPECT_FALSE(result1);
1229 
1230     // Test 2: Fill parcel leaving space for blendMode only (4 bytes)
1231     MessageParcel parcel2;
1232     parcel2.SetMaxCapacity(BUFFER_SIZE);
1233     bool fillResult2 = parcel2.WriteBuffer(fillBuffer.data(), BUFFER_SIZE - 4);
1234     EXPECT_TRUE(fillResult2);
1235     // Should fail on WriteBool(isDstLazy)
1236     bool result2 = obj->Marshalling(parcel2);
1237     EXPECT_FALSE(result2);
1238 
1239     // Test 3: Fill parcel leaving space for blendMode and isDstLazy (8 bytes)
1240     MessageParcel parcel3;
1241     parcel3.SetMaxCapacity(BUFFER_SIZE);
1242     bool fillResult3 = parcel3.WriteBuffer(fillBuffer.data(), BUFFER_SIZE - 8);
1243     EXPECT_TRUE(fillResult3);
1244     // Should fail on dstShader->Marshalling() due to insufficient space
1245     bool result3 = obj->Marshalling(parcel3);
1246     EXPECT_FALSE(result3);
1247 
1248     // Test 4: Leave more space but insufficient for complete shader marshalling
1249     MessageParcel parcel4;
1250     parcel4.SetMaxCapacity(BUFFER_SIZE);
1251     bool fillResult4 = parcel4.WriteBuffer(fillBuffer.data(), BUFFER_SIZE - 16);
1252     EXPECT_TRUE(fillResult4);
1253     // Should fail somewhere in shader marshalling or on WriteBool(isSrcLazy)
1254     bool result4 = obj->Marshalling(parcel4);
1255     EXPECT_FALSE(result4);
1256 }
1257 
1258 /*
1259  * @tc.name: MarshallingDstShaderFailureTest001
1260  * @tc.desc: Test BlendShaderObj::Marshalling with dstShader->Marshalling failure using parcel capacity control
1261  * @tc.type: FUNC
1262  * @tc.require: AR000GGNV3
1263  * @tc.author:
1264  */
1265 HWTEST_F(BlendShaderObjTest, MarshallingDstShaderFailureTest001, TestSize.Level1)
1266 {
1267     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
1268     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
1269     auto obj = BlendShaderObj::Create(dstShader, srcShader, BlendMode::MULTIPLY);
1270     ASSERT_NE(obj, nullptr);
1271 
1272     // Create buffer to fill parcel capacity
1273     const size_t BUFFER_SIZE = 200 * 1024; // 200K
1274     std::vector<uint8_t> fillBuffer(BUFFER_SIZE, 0xFF);
1275 
1276     // Test: Fill parcel leaving space for blendMode (4 bytes) and isDstLazy (4 bytes)
1277     // This should allow these writes to succeed but cause dstShader->Marshalling() to fail
1278     MessageParcel parcel;
1279     parcel.SetMaxCapacity(BUFFER_SIZE);
1280     bool fillResult = parcel.WriteBuffer(fillBuffer.data(), BUFFER_SIZE - 8);
1281     EXPECT_TRUE(fillResult);
1282 
1283     // Now try marshalling - should fail on dstShader->Marshalling() due to insufficient space
1284     bool result = obj->Marshalling(parcel);
1285     EXPECT_FALSE(result);
1286 }
1287 
1288 /*
1289  * @tc.name: MarshallingSrcShaderFailureTest001
1290  * @tc.desc: Test BlendShaderObj::Marshalling with srcShader->Marshalling failure using parcel capacity control
1291  * @tc.type: FUNC
1292  * @tc.require: AR000GGNV3
1293  * @tc.author:
1294  */
1295 HWTEST_F(BlendShaderObjTest, MarshallingSrcShaderFailureTest001, TestSize.Level1)
1296 {
1297     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
1298     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
1299     auto obj = BlendShaderObj::Create(dstShader, srcShader, BlendMode::MULTIPLY);
1300     ASSERT_NE(obj, nullptr);
1301 
1302     // Create buffer to fill parcel capacity
1303     const size_t BUFFER_SIZE = 200 * 1024; // 200K
1304     std::vector<uint8_t> fillBuffer(BUFFER_SIZE, 0xFF);
1305 
1306     // Test: Fill parcel leaving space for blendMode (4 bytes), isDstLazy (4 bytes),
1307     // dstShader data (minimal), and isSrcLazy (4 bytes), but not enough for srcShader->Marshalling()
1308     // This targets the srcShader->Marshalling() failure branch specifically
1309     MessageParcel parcel;
1310     parcel.SetMaxCapacity(BUFFER_SIZE);
1311     // Leave more space to allow dstShader marshalling but fail on srcShader marshalling
1312     bool fillResult = parcel.WriteBuffer(fillBuffer.data(), BUFFER_SIZE - 32);
1313     EXPECT_TRUE(fillResult);
1314 
1315     // Now try marshalling - should fail on srcShader->Marshalling() due to insufficient space
1316     bool result = obj->Marshalling(parcel);
1317     EXPECT_FALSE(result);
1318 }
1319 
1320 /*
1321  * @tc.name: MarshallingWriteIsSrcLazyFailureTest001
1322  * @tc.desc: Test BlendShaderObj::Marshalling with WriteBool(isSrcLazy) failure
1323  * @tc.type: FUNC
1324  * @tc.require: AR000GGNV3
1325  * @tc.author:
1326  */
1327 HWTEST_F(BlendShaderObjTest, MarshallingWriteIsSrcLazyFailureTest001, TestSize.Level1)
1328 {
1329     auto dstShader = ShaderEffect::CreateColorShader(0xFF0000FF);
1330     auto srcShader = ShaderEffect::CreateColorShader(0xFF00FF00);
1331     auto obj = BlendShaderObj::Create(dstShader, srcShader, BlendMode::MULTIPLY);
1332     ASSERT_NE(obj, nullptr);
1333 
1334     // Create buffer to fill parcel capacity
1335     const size_t BUFFER_SIZE = 200 * 1024; // 200K
1336     std::vector<uint8_t> fillBuffer(BUFFER_SIZE, 0xFF);
1337 
1338     // Test: Fill parcel leaving space for blendMode (4 bytes), isDstLazy (4 bytes),
1339     // dstShader data (assume minimal), and attempt to fail on WriteBool(isSrcLazy)
1340     // This is a probabilistic test - we allocate enough space for earlier operations
1341     // but not enough for the complete marshalling process
1342     MessageParcel parcel;
1343     parcel.SetMaxCapacity(BUFFER_SIZE);
1344     // Leave space for initial writes but make the buffer tight enough to potentially fail on later writes
1345     bool fillResult = parcel.WriteBuffer(fillBuffer.data(), BUFFER_SIZE - 16);
1346     EXPECT_TRUE(fillResult);
1347 
1348     // Now try marshalling - should fail somewhere in the marshalling process
1349     // Due to the tight space allocation, this will likely fail on isSrcLazy or srcShader marshalling
1350     bool result = obj->Marshalling(parcel);
1351     EXPECT_FALSE(result);
1352 }
1353 #endif
1354 
1355 } // namespace Drawing
1356 } // namespace Rosen
1357 } // namespace OHOS
1358