1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <gtest/gtest.h>
17
18#include "surface_draw.h"
19#include "display.h"
20#include "display_info.h"
21#include "display_manager.h"
22#include "display_manager_proxy.h"
23#include "window_impl.h"
24
25using namespace testing;
26using namespace testing::ext;
27
28namespace OHOS {
29namespace Rosen {
30namespace {
31const std::string IMAGE_PLACE_HOLDER_PNG_PATH = "/etc/window/resources/bg_place_holder.png";
32const int WAIT_FOR_SYNC_US = 1000 * 500;  // 500ms
33}
34class SurfaceDrawTest : public testing::Test {
35public:
36    static void SetUpTestCase();
37    static void TearDownTestCase();
38    void SetUp() override;
39    void TearDown() override;
40
41public:
42    struct WindowTestInfo {
43        std::string name;
44        Rect rect;
45        WindowType type;
46        WindowMode mode;
47        bool needAvoid;
48        bool parentLimit;
49        bool forbidSplitMove {false};
50        bool showWhenLocked;
51        uint32_t parentId;
52    };
53    sptr<Window> CreateTestWindow(const std::string& name);
54
55    static inline DisplayId displayId_;
56    static inline int32_t displayWidth_;
57    static inline int32_t displayHeight_;
58    WindowTestInfo windowInfo_;
59};
60
61void SurfaceDrawTest::SetUpTestCase()
62{
63    displayId_ = DisplayManager::GetInstance().GetDefaultDisplayId();
64    sptr<Display> display = DisplayManager::GetInstance().GetDefaultDisplay();
65    if (display == nullptr) {
66        return;
67    }
68    displayWidth_ = display->GetWidth();
69    displayHeight_ = display->GetHeight();
70}
71
72void SurfaceDrawTest::TearDownTestCase()
73{
74}
75
76void SurfaceDrawTest::SetUp()
77{
78    windowInfo_ = {
79        .name = "main",
80        .rect = {100, 100, 250, 300},
81        .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
82        .mode = WindowMode::WINDOW_MODE_FLOATING,
83        .needAvoid = true,
84        .parentLimit = false,
85        .parentId = INVALID_WINDOW_ID,
86    };
87}
88
89void SurfaceDrawTest::TearDown()
90{
91}
92
93sptr<Window> SurfaceDrawTest::CreateTestWindow(const std::string& name)
94{
95    sptr<WindowOption> option = new (std::nothrow)WindowOption();
96    if (option == nullptr) {
97        return nullptr;
98    }
99    option->SetDisplayId(displayId_);
100    option->SetWindowType(windowInfo_.type);
101    option->SetWindowRect(windowInfo_.rect);
102    option->SetWindowMode(windowInfo_.mode);
103    option->SetWindowName(name);
104    sptr<Window> window = Window::Create(option->GetWindowName(), option);
105    if (window == nullptr) {
106        return nullptr;
107    }
108    window->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
109    return window;
110}
111
112namespace {
113/**
114 * @tc.name: DrawImage
115 * @tc.desc: SurfaceDraw::DrawImage test
116 * @tc.type: FUNC
117 */
118HWTEST_F(SurfaceDrawTest, DrawImage01, Function | SmallTest | Level1)
119{
120    ASSERT_FALSE(SurfaceDraw::DrawImage(nullptr, 0, 0, ""));
121    sptr<Window> window = CreateTestWindow("testDrawImage");
122    if (window == nullptr) {
123        return;
124    }
125    ASSERT_NE(nullptr, window);
126    window->Show();
127    usleep(WAIT_FOR_SYNC_US / 20); // wait for rect updated
128
129    auto surfaceNode = window->GetSurfaceNode();
130    ASSERT_NE(surfaceNode, nullptr);
131    usleep(WAIT_FOR_SYNC_US / 20); // wait for rect updated
132    uint32_t width = window->GetRect().width_;
133    uint32_t height = window->GetRect().height_;
134    SurfaceDraw::DrawImage(surfaceNode, width, height, IMAGE_PLACE_HOLDER_PNG_PATH);
135    ASSERT_FALSE(SurfaceDraw::DrawImage(surfaceNode, -1, -1, IMAGE_PLACE_HOLDER_PNG_PATH));
136    window->Destroy();
137}
138/**
139 * @tc.name: DecodeImageToPixelMap
140 * @tc.desc: SurfaceDraw::DecodeImageToPixelMap test
141 * @tc.type: FUNC
142 */
143HWTEST_F(SurfaceDrawTest, DecodeImageToPixelMap01, Function | SmallTest | Level1)
144{
145    ASSERT_EQ(SurfaceDraw::DecodeImageToPixelMap(""), nullptr);
146    ASSERT_NE(SurfaceDraw::DecodeImageToPixelMap(IMAGE_PLACE_HOLDER_PNG_PATH), nullptr);
147}
148/**
149 * @tc.name: DrawMasking
150 * @tc.desc: SurfaceDraw::DrawMasking test
151 * @tc.type: FUNC
152 */
153HWTEST_F(SurfaceDrawTest, DrawMasking01, Function | SmallTest | Level1)
154{
155    OHOS::Rosen::Rect screenRect = {0, 0, 0, 0};
156    OHOS::Rosen::Rect transRect = {0, 0, 0, 0};
157    ASSERT_FALSE(SurfaceDraw::DrawMasking(nullptr, screenRect, transRect));
158
159    sptr<Window> window = CreateTestWindow("testDrawMasking");
160    if (window == nullptr) {
161        return;
162    }
163    ASSERT_NE(nullptr, window);
164    window->Show();
165    usleep(WAIT_FOR_SYNC_US / 20); // wait for rect updated
166
167    auto surfaceNode = window->GetSurfaceNode();
168    ASSERT_NE(surfaceNode, nullptr);
169    ASSERT_FALSE(SurfaceDraw::DrawMasking(surfaceNode, screenRect, transRect));
170
171    screenRect.width_ = displayWidth_;
172    screenRect.height_ = displayHeight_;
173    transRect.width_ = displayWidth_;
174    transRect.height_ = displayHeight_;
175    SurfaceDraw::DrawMasking(surfaceNode, screenRect, transRect);
176    window->Destroy();
177}
178/**
179 * @tc.name: DoDrawImageRect
180 * @tc.desc: SurfaceDraw::DoDrawImageRect test
181 * @tc.type: FUNC
182 */
183HWTEST_F(SurfaceDrawTest, DoDrawImageRect01, Function | SmallTest | Level1)
184{
185    sptr<Window> window = CreateTestWindow("testDoDrawImageRect");
186    if (window == nullptr) {
187        return;
188    }
189    ASSERT_NE(window, nullptr);
190    window->Show();
191    usleep(WAIT_FOR_SYNC_US / 20); // wait for rect updated
192
193    OHOS::Rosen::Rect rect = window->GetRect();
194    uint32_t color = 0x00660000;
195
196    auto surfaceNode = window->GetSurfaceNode();
197    ASSERT_NE(surfaceNode, nullptr);
198    sptr<OHOS::Surface> layer = SurfaceDraw::GetLayer(surfaceNode);
199    ASSERT_NE(layer, nullptr);
200    sptr<OHOS::SurfaceBuffer> buffer = SurfaceDraw::GetSurfaceBuffer(layer, rect.width_, rect.height_);
201    if (buffer == nullptr) {
202        return;
203    }
204
205    ASSERT_FALSE(SurfaceDraw::DoDrawImageRect(buffer, rect, nullptr, color, false));
206
207    std::shared_ptr<Media::PixelMap> pixelMap = SurfaceDraw::DecodeImageToPixelMap(IMAGE_PLACE_HOLDER_PNG_PATH);
208    ASSERT_NE(pixelMap, nullptr);
209
210    ASSERT_TRUE(SurfaceDraw::DoDrawImageRect(buffer, rect, pixelMap, color, false));
211    window->Destroy();
212}
213/**
214 * @tc.name: GetSurfaceSnapshot
215 * @tc.desc: SurfaceDraw::GetSurfaceSnapshot test
216 * @tc.type: FUNC
217 */
218HWTEST_F(SurfaceDrawTest, GetSurfaceSnapshot01, Function | SmallTest | Level1)
219{
220    sptr<Window> window = CreateTestWindow("testDoDrawImageRect");
221    if (window == nullptr) {
222        return;
223    }
224    ASSERT_NE(window, nullptr);
225    window->Show();
226    usleep(WAIT_FOR_SYNC_US / 20); // wait for rect updated
227
228    auto surfaceNode = window->GetSurfaceNode();
229    ASSERT_NE(surfaceNode, nullptr);
230
231    std::shared_ptr<Media::PixelMap> pixelMap = SurfaceDraw::DecodeImageToPixelMap(IMAGE_PLACE_HOLDER_PNG_PATH);
232    ASSERT_NE(pixelMap, nullptr);
233
234    ASSERT_FALSE(SurfaceDraw::GetSurfaceSnapshot(nullptr, pixelMap, 0, 0, 0));
235    ASSERT_FALSE(SurfaceDraw::GetSurfaceSnapshot(surfaceNode, pixelMap, 0, 0, 0));
236    window->Destroy();
237}
238
239/**
240 * @tc.name: DrawColor
241 * @tc.desc: SurfaceDraw::DrawColor test
242 * @tc.type: FUNC
243 */
244HWTEST_F(SurfaceDrawTest, DrawColor01, Function | SmallTest | Level1)
245{
246    ASSERT_FALSE(SurfaceDraw::DrawColor(nullptr, 0, 0, 0));
247    sptr<Window> window = CreateTestWindow("DrawColor");
248    if (window == nullptr) {
249        return;
250    }
251    ASSERT_NE(nullptr, window);
252    window->Show();
253    usleep(WAIT_FOR_SYNC_US / 20); // wait for rect updated
254    auto surfaceNode = window->GetSurfaceNode();
255    ASSERT_NE(surfaceNode, nullptr);
256    uint32_t width = window->GetRect().width_;
257    uint32_t height = window->GetRect().height_;
258    uint32_t color = 0x00660000;
259    SurfaceDraw::DrawColor(surfaceNode, width, height, color);
260    SurfaceDraw::DrawColor(surfaceNode, -1, -1, color);
261    ASSERT_EQ(WMError::WM_OK, window->Destroy());
262}
263
264/**
265 * @tc.name: DoDraw
266 * @tc.desc: SurfaceDraw::DoDraw test
267 * @tc.type: FUNC
268 */
269HWTEST_F(SurfaceDrawTest, DoDraw01, Function | SmallTest | Level1)
270{
271    sptr<Window> window = CreateTestWindow("DoDrawTest01");
272    if (window == nullptr) {
273        return;
274    }
275    ASSERT_NE(nullptr, window);
276    window->Show();
277    usleep(WAIT_FOR_SYNC_US / 20); // wait for rect updated
278    OHOS::Rosen::Rect rect = window->GetRect();
279    auto surfaceNode = window->GetSurfaceNode();
280    ASSERT_NE(surfaceNode, nullptr);
281    sptr<OHOS::Surface> layer = SurfaceDraw::GetLayer(surfaceNode);
282    ASSERT_NE(layer, nullptr);
283    sptr<OHOS::SurfaceBuffer> buffer = SurfaceDraw::GetSurfaceBuffer(layer, rect.width_, rect.height_);
284    ASSERT_NE(buffer, nullptr);
285    ASSERT_FALSE(SurfaceDraw::DoDraw(nullptr, 0, 0, ""));
286    window->Destroy();
287}
288
289/**
290 * @tc.name: DoDraw
291 * @tc.desc: SurfaceDraw::DoDraw02 test
292 * @tc.type: FUNC
293 */
294HWTEST_F(SurfaceDrawTest, DoDraw02, Function | SmallTest | Level1)
295{
296    sptr<Window> window = CreateTestWindow("DoDraw02");
297    if (window == nullptr) {
298        return;
299    }
300    ASSERT_NE(window, nullptr);
301    window->Show();
302    usleep(WAIT_FOR_SYNC_US / 20); // wait for rect updated
303    OHOS::Rosen::Rect rect = window->GetRect();
304    auto surfaceNode = window->GetSurfaceNode();
305    ASSERT_NE(surfaceNode, nullptr);
306    sptr<OHOS::Surface> layer = SurfaceDraw::GetLayer(surfaceNode);
307    ASSERT_NE(layer, nullptr);
308    sptr<OHOS::SurfaceBuffer> buffer = SurfaceDraw::GetSurfaceBuffer(layer, rect.width_, rect.height_);
309    if (buffer == nullptr) {
310        return;
311    }
312    std::shared_ptr<Media::PixelMap> pixelMap = SurfaceDraw::DecodeImageToPixelMap(IMAGE_PLACE_HOLDER_PNG_PATH);
313    ASSERT_NE(pixelMap, nullptr);
314    ASSERT_FALSE(SurfaceDraw::DoDraw(nullptr, 0, 0, pixelMap));
315    window->Destroy();
316}
317
318/**
319 * @tc.name: DoDraw03
320 * @tc.desc: SurfaceDraw::DoDraw03 test
321 * @tc.type: FUNC
322 */
323HWTEST_F(SurfaceDrawTest, DoDraw03, Function | SmallTest | Level1)
324{
325    sptr<Window> window = CreateTestWindow("DoDrawTest03");
326    if (window == nullptr) {
327        return;
328    }
329    ASSERT_NE(nullptr, window);
330    window->Show();
331    usleep(WAIT_FOR_SYNC_US / 20); // wait for rect updated
332    OHOS::Rosen::Rect rect = window->GetRect();
333    uint32_t color = 0x00660000;
334    auto surfaceNode = window->GetSurfaceNode();
335    ASSERT_NE(surfaceNode, nullptr);
336    sptr<OHOS::Surface> layer = SurfaceDraw::GetLayer(surfaceNode);
337    ASSERT_NE(layer, nullptr);
338    sptr<OHOS::SurfaceBuffer> buffer = SurfaceDraw::GetSurfaceBuffer(layer, rect.width_, rect.height_);
339    if (buffer == nullptr) {
340        return;
341    }
342    ASSERT_FALSE(SurfaceDraw::DoDraw(nullptr, 0, 0, color));
343    window->Destroy();
344}
345
346/**
347 * @tc.name: DrawImageRect
348 * @tc.desc: SurfaceDraw::DoDrawImageRect test
349 * @tc.type: FUNC
350 */
351HWTEST_F(SurfaceDrawTest, DrawImageRect01, Function | SmallTest | Level1)
352{
353    sptr<Window> window = CreateTestWindow("DrawImageRect");
354    if (window == nullptr) {
355        return;
356    }
357    ASSERT_NE(window, nullptr);
358    window->Show();
359    usleep(WAIT_FOR_SYNC_US / 20); // wait for rect updated
360    OHOS::Rosen::Rect rect = window->GetRect();
361    uint32_t color = 0x00660000;
362    auto surfaceNode = window->GetSurfaceNode();
363    ASSERT_NE(surfaceNode, nullptr);
364    ASSERT_FALSE(SurfaceDraw::DrawImageRect(surfaceNode, rect, nullptr, color, false));
365    std::shared_ptr<Media::PixelMap> pixelMap = SurfaceDraw::DecodeImageToPixelMap(IMAGE_PLACE_HOLDER_PNG_PATH);
366    ASSERT_NE(pixelMap, nullptr);
367    SurfaceDraw::DrawImageRect(surfaceNode, rect, pixelMap, color, false);
368    window->Destroy();
369}
370}
371} // namespace Rosen
372} // namespace OHOS