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