1 /*
2 * Copyright (c) 2021-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 // gtest
17 #include <gtest/gtest.h>
18
19 #include <atomic>
20 #include <chrono>
21 #include <condition_variable>
22 #include <mutex>
23
24 #include <transaction/rs_transaction.h>
25 #include "display_manager.h"
26 #include "wm_common.h"
27 #include "window_manager.h"
28 #include "window_test_utils.h"
29 #include "surface_draw.h"
30 #include "window_manager.h"
31
32 using namespace testing;
33 using namespace testing::ext;
34
35 namespace OHOS {
36 namespace Rosen {
37 namespace {
38 constexpr uint32_t COLOR_RED = 0xffff0000;
39 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowVisibilityInfoTest"};
40 constexpr uint8_t ALPHA = 255;
41 }
42
43 using Utils = WindowTestUtils;
44 constexpr int WAIT_ASYNC_MS_TIME_OUT = 5000; // 5000ms, filling color is slow
45
46 class VisibilityChangedListenerImpl : public IVisibilityChangedListener {
47 public:
VisibilityChangedListenerImpl(std::mutex & mutex,std::condition_variable & cv)48 VisibilityChangedListenerImpl(std::mutex& mutex, std::condition_variable& cv) : mutex_(mutex), cv_(cv) {}
49 void OnWindowVisibilityChanged(const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfo) override;
50 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos_;
51 bool isCallbackCalled_ { false };
52 private:
53 std::mutex& mutex_;
54 std::condition_variable& cv_;
55 };
56
OnWindowVisibilityChanged(const std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfo)57 void VisibilityChangedListenerImpl::OnWindowVisibilityChanged(
58 const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfo)
59 {
60 std::unique_lock<std::mutex> lock(mutex_);
61 WLOGFI("size:%{public}zu", windowVisibilityInfo.size());
62 windowVisibilityInfos_ = std::move(windowVisibilityInfo);
63 for (auto& info : windowVisibilityInfos_) {
64 WLOGFI("windowId:%{public}u, isVisible_:%{public}d, pid:%{public}d, uid:%{public}d, windowType:%{public}u",
65 info->windowId_, info->isVisible_, info->pid_, info->uid_, static_cast<uint32_t>(info->windowType_));
66 }
67 isCallbackCalled_ = true;
68 cv_.notify_all();
69 }
70
71 class WindowVisibilityInfoTest : public testing::Test {
72 public:
73 static void SetUpTestCase();
74
75 static void TearDownTestCase();
76
77 virtual void SetUp() override;
78
79 virtual void TearDown() override;
80
81 static inline std::mutex mutex_;
82 static inline std::condition_variable cv_;
83 static inline sptr<VisibilityChangedListenerImpl> visibilityChangedListener_ =
84 new VisibilityChangedListenerImpl(mutex_, cv_);
85
ResetCallbackCalledFLag()86 static inline void ResetCallbackCalledFLag()
87 {
88 std::unique_lock<std::mutex> lock(mutex_);
89 visibilityChangedListener_->isCallbackCalled_ = false;
90 visibilityChangedListener_->windowVisibilityInfos_.clear();
91 }
92
93 static void WaitForCallback();
94 Utils::TestWindowInfo fullScreenAppInfo_;
95 Utils::TestWindowInfo floatAppInfo_;
96 Utils::TestWindowInfo subAppInfo_;
97 bool FillColor(sptr<Window> window);
98 };
99
FillColor(sptr<Window> window)100 bool WindowVisibilityInfoTest::FillColor(sptr<Window> window)
101 {
102 if (window == nullptr) {
103 return false;
104 }
105 auto surfaceNode = window->GetSurfaceNode();
106 if (surfaceNode == nullptr) {
107 return false;
108 }
109 Rect rect = window->GetRect();
110 bool isDrawSuccess = SurfaceDraw::DrawColor(surfaceNode, rect.width_, rect.height_, COLOR_RED);
111 surfaceNode->SetAbilityBGAlpha(ALPHA);
112 RSTransaction::FlushImplicitTransaction();
113 return isDrawSuccess;
114 }
115
SetUpTestCase()116 void WindowVisibilityInfoTest::SetUpTestCase()
117 {
118 auto display = DisplayManager::GetInstance().GetDisplayById(0);
119 ASSERT_TRUE((display != nullptr));
120 WLOGFI("GetDefaultDisplay: id %{public}" PRIu64", w %{public}d, h %{public}d, fps %{public}u",
121 display->GetId(), display->GetWidth(), display->GetHeight(), display->GetRefreshRate());
122 Rect displayRect = {0, 0,
123 static_cast<uint32_t>(display->GetWidth()), static_cast<uint32_t>(display->GetHeight())};
124 Utils::InitByDisplayRect(displayRect);
125 WindowManager::GetInstance().RegisterVisibilityChangedListener(visibilityChangedListener_);
126 auto displayId = DisplayManager::GetInstance().GetDefaultDisplayId();
127 WindowManager::GetInstance().MinimizeAllAppWindows(displayId);
128 }
129
TearDownTestCase()130 void WindowVisibilityInfoTest::TearDownTestCase()
131 {
132 WindowManager::GetInstance().UnregisterVisibilityChangedListener(visibilityChangedListener_);
133 }
134
SetUp()135 void WindowVisibilityInfoTest::SetUp()
136 {
137 fullScreenAppInfo_ = {
138 .name = "FullWindow",
139 .rect = Utils::customAppRect_,
140 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
141 .mode = WindowMode::WINDOW_MODE_FULLSCREEN,
142 .needAvoid = false,
143 .parentLimit = false,
144 .showWhenLocked = true,
145 .parentId = INVALID_WINDOW_ID,
146 };
147 floatAppInfo_ = {
148 .name = "ParentWindow",
149 .rect = Utils::customAppRect_,
150 .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
151 .mode = WindowMode::WINDOW_MODE_FLOATING,
152 .needAvoid = false,
153 .parentLimit = false,
154 .showWhenLocked = true,
155 .parentId = INVALID_WINDOW_ID,
156 };
157 subAppInfo_ = {
158 .name = "SubWindow",
159 .rect = Utils::customAppRect_,
160 .type = WindowType::WINDOW_TYPE_APP_SUB_WINDOW,
161 .mode = WindowMode::WINDOW_MODE_FLOATING,
162 .needAvoid = false,
163 .parentLimit = false,
164 .showWhenLocked = true,
165 .parentId = INVALID_WINDOW_ID,
166 };
167 }
168
TearDown()169 void WindowVisibilityInfoTest::TearDown()
170 {
171 }
172
WaitForCallback()173 void WindowVisibilityInfoTest::WaitForCallback()
174 {
175 std::unique_lock<std::mutex> lock(mutex_);
176 visibilityChangedListener_->isCallbackCalled_ = false;
177 visibilityChangedListener_->windowVisibilityInfos_.clear();
178 auto now = std::chrono::system_clock::now();
179 if (!cv_.wait_until(lock, now + std::chrono::milliseconds(WAIT_ASYNC_MS_TIME_OUT),
180 []() { return visibilityChangedListener_->isCallbackCalled_; })) {
181 WLOGFI("wait_until time out");
182 }
183 }
184
185 namespace {
186 /**
187 * @tc.name: WindowVisibilityInfoTest01
188 * @tc.desc: window show or hide
189 * @tc.type: FUNC
190 * @tc.require: issueI5FSQW
191 */
192 HWTEST_F(WindowVisibilityInfoTest, WindowVisibilityInfoTest01, Function | MediumTest | Level1)
193 {
194 floatAppInfo_.name = "window1";
195 floatAppInfo_.rect = {0, 0, 300, 100};
196 sptr<Window> window1 = Utils::CreateTestWindow(floatAppInfo_);
197
198 subAppInfo_.name = "subWindow1";
199 subAppInfo_.rect = {0, 600, 300, 100};
200 subAppInfo_.parentId = window1->GetWindowId();
201 sptr<Window> subWindow1 = Utils::CreateTestWindow(subAppInfo_);
202
203 bool isWindowVisible = false;
204 bool isSubWindowVisible = false;
205
206 uint32_t visibilityInfoCount = 0;
207 ASSERT_EQ(WMError::WM_OK, window1->Show());
208 isWindowVisible = FillColor(window1);
209 WaitForCallback();
210 visibilityInfoCount = isWindowVisible ? 1 : 0;
211 ResetCallbackCalledFLag();
212
213 ASSERT_EQ(WMError::WM_OK, subWindow1->Show());
214 isSubWindowVisible = FillColor(subWindow1);
215 WaitForCallback();
216 visibilityInfoCount = isSubWindowVisible ? 1 : 0;
217 ResetCallbackCalledFLag();
218
219 ASSERT_EQ(WMError::WM_OK, subWindow1->Hide());
220 WaitForCallback();
221 visibilityInfoCount = isSubWindowVisible ? 1 : 0;
222 ResetCallbackCalledFLag();
223
224 ASSERT_EQ(WMError::WM_OK, window1->Hide());
225 WaitForCallback();
226 visibilityInfoCount = isWindowVisible ? 1 : 0;
227 ResetCallbackCalledFLag();
228
229 window1->Destroy();
230 subWindow1->Destroy();
231 sleep(2);
232 }
233 }
234 } // namespace Rosen
235 } // namespace OHOS
236
237