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