Enable IME support for Ozone Efl
[platform/framework/web/chromium-efl.git] / ui / aura / window_tree_host_unittest.cc
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/aura/window_tree_host.h"
6
7 #include "base/containers/contains.h"
8 #include "base/test/bind.h"
9 #include "base/test/scoped_feature_list.h"
10 #include "build/build_config.h"
11 #include "build/chromeos_buildflags.h"
12 #include "ui/aura/native_window_occlusion_tracker.h"
13 #include "ui/aura/test/aura_test_base.h"
14 #include "ui/aura/test/aura_test_utils.h"
15 #include "ui/aura/test/test_screen.h"
16 #include "ui/aura/test/window_event_dispatcher_test_api.h"
17 #include "ui/aura/window.h"
18 #include "ui/aura/window_tree_host_platform.h"
19 #include "ui/base/ime/input_method.h"
20 #include "ui/base/ui_base_features.h"
21 #include "ui/compositor/compositor.h"
22 #include "ui/compositor/layer.h"
23 #include "ui/compositor/test/draw_waiter_for_test.h"
24 #include "ui/events/event_rewriter.h"
25 #include "ui/events/keycodes/dom/dom_code.h"
26 #include "ui/events/test/test_event_rewriter.h"
27 #include "ui/platform_window/stub/stub_window.h"
28
29 #if BUILDFLAG(IS_WIN)
30 #include "ui/aura/native_window_occlusion_tracker_win.h"
31 #endif
32
33 namespace aura {
34
35 namespace {
36
37 // A convenient wrapper that makes it easy to invoke this method inside an
38 // EXPECT_EQ statement.
39 gfx::Point ConvertDIPToPixels(const WindowTreeHost* host, gfx::Point point) {
40   host->ConvertDIPToPixels(&point);
41   return point;
42 }
43
44 // A convenient wrapper that makes it easy to invoke this method inside an
45 // EXPECT_EQ statement.
46 gfx::PointF ConvertDIPToPixels(const WindowTreeHost* host, gfx::PointF point) {
47   host->ConvertDIPToPixels(&point);
48   return point;
49 }
50
51 // A convenient wrapper that makes it easy to invoke this method inside an
52 // EXPECT_EQ statement.
53 gfx::Point ConvertPixelsToDIP(const WindowTreeHost* host, gfx::Point point) {
54   host->ConvertPixelsToDIP(&point);
55   return point;
56 }
57
58 // A convenient wrapper that makes it easy to invoke this method inside an
59 // EXPECT_EQ statement.
60 gfx::PointF ConvertPixelsToDIP(const WindowTreeHost* host, gfx::PointF point) {
61   host->ConvertPixelsToDIP(&point);
62   return point;
63 }
64
65 }  // namespace
66
67 using WindowTreeHostTest = test::AuraTestBase;
68
69 TEST_F(WindowTreeHostTest, DPIWindowSize) {
70   constexpr gfx::Rect starting_bounds(
71       aura::test::AuraTestHelper::kDefaultHostSize);
72
73   EXPECT_EQ(starting_bounds.size(), host()->compositor()->size());
74   EXPECT_EQ(starting_bounds, host()->GetBoundsInPixels());
75   EXPECT_EQ(starting_bounds, root_window()->bounds());
76
77   test_screen()->SetDeviceScaleFactor(1.5f);
78   EXPECT_EQ(starting_bounds, host()->GetBoundsInPixels());
79   // Size should be rounded up after scaling.
80   EXPECT_EQ(gfx::Rect(0, 0, 534, 400), root_window()->bounds());
81
82   gfx::Transform transform;
83   transform.Translate(0, -1.1f);
84   host()->SetRootTransform(transform);
85   EXPECT_EQ(gfx::Rect(0, 1, 534, 401), root_window()->bounds());
86
87   EXPECT_EQ(starting_bounds, host()->GetBoundsInPixels());
88   EXPECT_EQ(gfx::Rect(0, 1, 534, 401), root_window()->bounds());
89 }
90
91 TEST_F(WindowTreeHostTest,
92        ShouldHaveExactRootWindowBoundsWithDisplayRotation1xScale) {
93   test_screen()->SetDeviceScaleFactor(1.f);
94
95   host()->SetBoundsInPixels(gfx::Rect(0, 0, 400, 300));
96   test_screen()->SetDisplayRotation(display::Display::ROTATE_0);
97   EXPECT_EQ(host()->GetBoundsInPixels(), gfx::Rect(0, 0, 400, 300));
98   EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().rotation(),
99             display::Display::ROTATE_0);
100   EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().GetSizeInPixel(),
101             gfx::Size(400, 300));
102   EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().bounds(),
103             gfx::Rect(0, 0, 400, 300));
104   EXPECT_EQ(gfx::Rect(400, 300), host()->window()->bounds());
105
106   host()->SetBoundsInPixels(gfx::Rect(0, 0, 400, 300));
107   test_screen()->SetDisplayRotation(display::Display::ROTATE_90);
108   EXPECT_EQ(host()->GetBoundsInPixels(), gfx::Rect(0, 0, 400, 300));
109   EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().rotation(),
110             display::Display::ROTATE_90);
111   EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().GetSizeInPixel(),
112             gfx::Size(300, 400));
113   EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().bounds(),
114             gfx::Rect(0, 0, 300, 400));
115   EXPECT_EQ(gfx::Rect(300, 400), host()->window()->bounds());
116
117   host()->SetBoundsInPixels(gfx::Rect(0, 0, 400, 300));
118   test_screen()->SetDisplayRotation(display::Display::ROTATE_180);
119   EXPECT_EQ(host()->GetBoundsInPixels(), gfx::Rect(0, 0, 400, 300));
120   EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().rotation(),
121             display::Display::ROTATE_180);
122   EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().GetSizeInPixel(),
123             gfx::Size(400, 300));
124   EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().bounds(),
125             gfx::Rect(0, 0, 400, 300));
126   EXPECT_EQ(gfx::Rect(400, 300), host()->window()->bounds());
127
128   host()->SetBoundsInPixels(gfx::Rect(0, 0, 400, 300));
129   test_screen()->SetDisplayRotation(display::Display::ROTATE_270);
130   EXPECT_EQ(host()->GetBoundsInPixels(), gfx::Rect(0, 0, 400, 300));
131   EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().rotation(),
132             display::Display::ROTATE_270);
133   EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().GetSizeInPixel(),
134             gfx::Size(300, 400));
135   EXPECT_EQ(display::Screen::GetScreen()->GetPrimaryDisplay().bounds(),
136             gfx::Rect(0, 0, 300, 400));
137   EXPECT_EQ(gfx::Rect(300, 400), host()->window()->bounds());
138 }
139
140 #if BUILDFLAG(IS_CHROMEOS_ASH)
141 TEST_F(WindowTreeHostTest, HoldPointerMovesOnChildResizing) {
142   aura::WindowEventDispatcher* dispatcher = host()->dispatcher();
143
144   aura::test::WindowEventDispatcherTestApi dispatcher_api(dispatcher);
145
146   EXPECT_FALSE(dispatcher_api.HoldingPointerMoves());
147
148   // Signal to the ui::Compositor that a child is resizing. This will
149   // immediately trigger input throttling.
150   host()->compositor()->OnChildResizing();
151
152   // Pointer moves should be throttled until the next commit. This has the
153   // effect of prioritizing the resize event above other operations in aura.
154   EXPECT_TRUE(dispatcher_api.HoldingPointerMoves());
155
156   // Wait for a CompositorFrame to be activated.
157   ui::DrawWaiterForTest::WaitForCompositingEnded(host()->compositor());
158
159   // Pointer moves should be routed normally after commit.
160   EXPECT_FALSE(dispatcher_api.HoldingPointerMoves());
161 }
162 #endif
163
164 #if !BUILDFLAG(IS_CHROMEOS_ASH)
165 // Tests if scale factor changes take effect. Previously a scale factor change
166 // wouldn't take effect without a bounds change. For context see
167 // https://crbug.com/1087626
168 TEST_F(WindowTreeHostTest, ShouldHandleTextScale) {
169   constexpr gfx::Rect starting_bounds(
170       aura::test::AuraTestHelper::kDefaultHostSize);
171   auto asserter = [&](float test_scale_factor) {
172     test_screen()->SetDeviceScaleFactor(test_scale_factor, false);
173
174     EXPECT_EQ(starting_bounds, host()->GetBoundsInPixels());
175     // Size should be rounded up after scaling.
176     EXPECT_EQ(
177         gfx::ScaleToEnclosingRect(starting_bounds, 1.0f / test_scale_factor),
178         root_window()->bounds());
179     EXPECT_EQ(test_scale_factor, host()->device_scale_factor());
180   };
181
182   asserter(1.0f);
183   asserter(1.05f);
184   asserter(1.5f);
185 }
186 #endif
187
188 TEST_F(WindowTreeHostTest, NoRewritesPostIME) {
189   ui::test::TestEventRewriter event_rewriter;
190   host()->AddEventRewriter(&event_rewriter);
191
192   ui::KeyEvent key_event('A', ui::VKEY_A, ui::DomCode::NONE, 0);
193   ui::EventDispatchDetails details =
194       host()->GetInputMethod()->DispatchKeyEvent(&key_event);
195   ASSERT_TRUE(!details.dispatcher_destroyed && !details.target_destroyed);
196   EXPECT_EQ(0, event_rewriter.events_seen());
197
198   host()->RemoveEventRewriter(&event_rewriter);
199 }
200
201 TEST_F(WindowTreeHostTest, ConvertDIPToPixelsShouldRespectScaleFactor) {
202   const int width_in_pixels = 400;
203   const int height_in_pixels = 300;
204   const int width_in_dip = 200;
205   const int height_in_dip = 150;
206
207   host()->SetBoundsInPixels(gfx::Rect(0, 0, width_in_pixels, height_in_pixels));
208   test_screen()->SetDisplayRotation(display::Display::ROTATE_0);
209
210   test_screen()->SetDeviceScaleFactor(2.f);
211
212   EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(0, 0)), gfx::Point(0, 0));
213   EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(width_in_dip, 0)),
214             gfx::Point(width_in_pixels, 0));
215   EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(0, height_in_dip)),
216             gfx::Point(0, height_in_pixels));
217 }
218
219 TEST_F(WindowTreeHostTest, ConvertDIPToPixelsShouldRespectRotation) {
220   const int width_in_pixels = 400;
221   const int height_in_pixels = 300;
222   const int width_in_dip = 300;
223   const int height_in_dip = 400;
224
225   host()->SetBoundsInPixels(gfx::Rect(0, 0, width_in_pixels, height_in_pixels));
226   test_screen()->SetDeviceScaleFactor(1.f);
227
228   test_screen()->SetDisplayRotation(display::Display::ROTATE_90);
229
230   EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(0, 0)),
231             gfx::Point(width_in_pixels, 0));
232   EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(width_in_dip, 0)),
233             gfx::Point(width_in_pixels, height_in_pixels));
234   EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(width_in_dip, height_in_dip)),
235             gfx::Point(0, height_in_pixels));
236   EXPECT_EQ(ConvertDIPToPixels(host(), gfx::Point(0, height_in_dip)),
237             gfx::Point(0, 0));
238 }
239
240 TEST_F(WindowTreeHostTest, ConvertDIPToPixelsShouldWorkWithPointF) {
241   host()->SetBoundsInPixels(gfx::Rect(0, 0, 400, 400));
242   test_screen()->SetDisplayRotation(display::Display::ROTATE_0);
243   test_screen()->SetDeviceScaleFactor(2.f);
244
245   EXPECT_EQ(ConvertDIPToPixels(host(), gfx::PointF(5.3f, 0)),
246             gfx::PointF(10.6f, 0));
247 }
248
249 TEST_F(WindowTreeHostTest, ConvertPixelsToDIPShouldRespectScaleFactor) {
250   const int width_in_pixels = 400;
251   const int height_in_pixels = 300;
252   const int width_in_dip = 200;
253   const int height_in_dip = 150;
254
255   host()->SetBoundsInPixels(gfx::Rect(0, 0, width_in_pixels, height_in_pixels));
256   test_screen()->SetDisplayRotation(display::Display::ROTATE_0);
257
258   test_screen()->SetDeviceScaleFactor(2.f);
259
260   EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::Point(0, 0)), gfx::Point(0, 0));
261   EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::Point(width_in_pixels, 0)),
262             gfx::Point(width_in_dip, 0));
263   EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::Point(0, height_in_pixels)),
264             gfx::Point(0, height_in_dip));
265 }
266
267 TEST_F(WindowTreeHostTest, ConvertPixelsToDIPShouldRespectRotation) {
268   const int width_in_pixels = 400;
269   const int height_in_pixels = 300;
270   const int width_in_dip = 300;
271   const int height_in_dip = 400;
272
273   host()->SetBoundsInPixels(gfx::Rect(0, 0, width_in_pixels, height_in_pixels));
274   test_screen()->SetDeviceScaleFactor(1.f);
275
276   test_screen()->SetDisplayRotation(display::Display::ROTATE_90);
277
278   EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::Point(0, 0)),
279             gfx::Point(0, height_in_dip));
280   EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::Point(width_in_pixels, 0)),
281             gfx::Point(0, 0));
282   EXPECT_EQ(
283       ConvertPixelsToDIP(host(), gfx::Point(width_in_pixels, height_in_pixels)),
284       gfx::Point(width_in_dip, 0));
285   EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::Point(0, height_in_pixels)),
286             gfx::Point(width_in_dip, height_in_dip));
287 }
288
289 TEST_F(WindowTreeHostTest, ConvertPixelsToDIPShouldWorkWithPointF) {
290   host()->SetBoundsInPixels(gfx::Rect(0, 0, 400, 400));
291   test_screen()->SetDisplayRotation(display::Display::ROTATE_0);
292   test_screen()->SetDeviceScaleFactor(2.f);
293
294   EXPECT_EQ(ConvertPixelsToDIP(host(), gfx::PointF(10.6f, 0)),
295             gfx::PointF(5.3f, 0));
296 }
297
298 class TestWindow : public ui::StubWindow {
299  public:
300   explicit TestWindow(ui::PlatformWindowDelegate* delegate)
301       : StubWindow(delegate, false, gfx::Rect(400, 600)) {}
302
303   TestWindow(const TestWindow&) = delete;
304   TestWindow& operator=(const TestWindow&) = delete;
305
306   ~TestWindow() override {}
307
308  private:
309   // ui::StubWindow
310   void Close() override {
311     // It is possible for the window to receive capture-change messages during
312     // destruction, for example on Windows (see crbug.com/770670).
313     delegate()->OnLostCapture();
314   }
315 };
316
317 class TestWindowTreeHost : public WindowTreeHostPlatform {
318  public:
319   TestWindowTreeHost() {
320     SetPlatformWindow(std::make_unique<TestWindow>(this));
321     CreateCompositor();
322   }
323
324   TestWindowTreeHost(const TestWindowTreeHost&) = delete;
325   TestWindowTreeHost& operator=(const TestWindowTreeHost&) = delete;
326 };
327
328 TEST_F(WindowTreeHostTest, LostCaptureDuringTearDown) {
329 #if BUILDFLAG(IS_WIN)
330   base::test::ScopedFeatureList scoped_feature_list;
331   scoped_feature_list.InitAndDisableFeature(
332       features::kApplyNativeOcclusionToCompositor);
333 #endif
334   TestWindowTreeHost host;
335 }
336
337 #if BUILDFLAG(IS_WIN)
338 class WindowTreeHostWithReleaseTest : public test::AuraTestBase {
339  public:
340   // AuraTestBase:
341   void SetUp() override {
342     // Disable the headless check as the bots run with CHROME_HEADLESS set.
343     NativeWindowOcclusionTracker::SetHeadlessCheckEnabled(false);
344     scoped_feature_list_.InitWithFeaturesAndParameters(
345         {
346             {features::kCalculateNativeWinOcclusion, {}},
347             {features::kApplyNativeOcclusionToCompositor,
348              {{features::kApplyNativeOcclusionToCompositorType,
349                features::kApplyNativeOcclusionToCompositorTypeRelease}}},
350         },
351         {});
352     AuraTestBase::SetUp();
353   }
354
355   void TearDown() override {
356     test::AuraTestBase::TearDown();
357     NativeWindowOcclusionTracker::SetHeadlessCheckEnabled(true);
358   }
359
360  private:
361   base::test::ScopedFeatureList scoped_feature_list_;
362 };
363
364 cc::Layer* ccLayerFromUiLayer(ui::Layer* layer) {
365   return static_cast<ui::LayerAnimationDelegate*>(layer)->GetCcLayer();
366 }
367
368 bool WaitForFrame(WindowTreeHost* host) {
369   base::RunLoop run_loop;
370   bool got_frame = false;
371   host->compositor()->RequestPresentationTimeForNextFrame(
372       base::BindLambdaForTesting(
373           [&](const gfx::PresentationFeedback& feedback) {
374             got_frame = true;
375             run_loop.Quit();
376           }));
377   run_loop.Run();
378   return got_frame;
379 }
380
381 TEST_F(WindowTreeHostWithReleaseTest, ToggleOccluded) {
382   host()->Show();
383   // This tests needs to drive native occlusion. If native occlusion is
384   // used, it'll conflict with this test.
385   NativeWindowOcclusionTracker::DisableNativeWindowOcclusionTracking(host());
386   ASSERT_TRUE(NativeWindowOcclusionTracker::
387                   IsNativeWindowOcclusionTrackingAlwaysEnabled(host()));
388   cc::Layer* host_window_cc_layer =
389       ccLayerFromUiLayer(host()->window()->layer());
390   const cc::Layer* compositor_root_layer = host_window_cc_layer->parent();
391   EXPECT_NE(nullptr, compositor_root_layer);
392   host()->SetNativeWindowOcclusionState(Window::OcclusionState::OCCLUDED, {});
393   // The compositor shouldn't actually hide immediately, it needs a frame to
394   // be generated.
395   EXPECT_TRUE(host()->compositor()->IsVisible());
396   EXPECT_EQ(nullptr, host_window_cc_layer->parent());
397   ASSERT_TRUE(WaitForFrame(host()));
398   EXPECT_FALSE(host()->compositor()->IsVisible());
399   host()->SetNativeWindowOcclusionState(Window::OcclusionState::VISIBLE, {});
400   EXPECT_TRUE(host()->compositor()->IsVisible());
401   EXPECT_EQ(compositor_root_layer, host_window_cc_layer->parent());
402 }
403
404 TEST_F(WindowTreeHostWithReleaseTest, ShowWhileTransitioningToHidden) {
405   host()->Show();
406   // This tests needs to drive native occlusion. If native occlusion is
407   // used, it'll conflict with this test.
408   NativeWindowOcclusionTracker::DisableNativeWindowOcclusionTracking(host());
409   ASSERT_TRUE(NativeWindowOcclusionTracker::
410                   IsNativeWindowOcclusionTrackingAlwaysEnabled(host()));
411   cc::Layer* host_window_cc_layer =
412       ccLayerFromUiLayer(host()->window()->layer());
413   const cc::Layer* compositor_root_layer = host_window_cc_layer->parent();
414   EXPECT_NE(nullptr, compositor_root_layer);
415   host()->SetNativeWindowOcclusionState(Window::OcclusionState::OCCLUDED, {});
416   // The compositor shouldn't actually hide immediately, it needs a frame to
417   // be generated.
418   EXPECT_TRUE(host()->compositor()->IsVisible());
419   EXPECT_EQ(nullptr, host_window_cc_layer->parent());
420   host()->SetNativeWindowOcclusionState(Window::OcclusionState::VISIBLE, {});
421   EXPECT_TRUE(host()->compositor()->IsVisible());
422   EXPECT_EQ(compositor_root_layer, host_window_cc_layer->parent());
423 }
424
425 TEST_F(WindowTreeHostWithReleaseTest, VideoCaptureLockForcesVisible) {
426   ASSERT_TRUE(NativeWindowOcclusionTracker::
427                   IsNativeWindowOcclusionTrackingAlwaysEnabled(host()));
428   // This tests needs to drive native occlusion. If native occlusion is
429   // used, it'll conflict with this test.
430   NativeWindowOcclusionTracker::DisableNativeWindowOcclusionTracking(host());
431   host()->Show();
432   host()->SetNativeWindowOcclusionState(Window::OcclusionState::OCCLUDED, {});
433   ASSERT_TRUE(WaitForFrame(host()));
434   EXPECT_FALSE(host()->compositor()->IsVisible());
435   std::unique_ptr<WindowTreeHost::VideoCaptureLock> lock =
436       host()->CreateVideoCaptureLock();
437   EXPECT_TRUE(host()->compositor()->IsVisible());
438   host()->SetNativeWindowOcclusionState(Window::OcclusionState::VISIBLE, {});
439   EXPECT_TRUE(host()->compositor()->IsVisible());
440   host()->SetNativeWindowOcclusionState(Window::OcclusionState::OCCLUDED, {});
441   EXPECT_TRUE(host()->compositor()->IsVisible());
442   ASSERT_TRUE(WaitForFrame(host()));
443   EXPECT_TRUE(host()->compositor()->IsVisible());
444   lock.reset();
445   ASSERT_TRUE(WaitForFrame(host()));
446   EXPECT_FALSE(host()->compositor()->IsVisible());
447   host()->SetNativeWindowOcclusionState(Window::OcclusionState::VISIBLE, {});
448   EXPECT_TRUE(host()->compositor()->IsVisible());
449   ASSERT_TRUE(WaitForFrame(host()));
450   EXPECT_TRUE(host()->compositor()->IsVisible());
451 }
452
453 class WindowTreeHostWithThrottleTest : public test::AuraTestBase {
454  public:
455   // AuraTestBase:
456   void SetUp() override {
457     // Disable the headless check as the bots run with CHROME_HEADLESS set.
458     NativeWindowOcclusionTracker::SetHeadlessCheckEnabled(false);
459     scoped_feature_list_.InitWithFeaturesAndParameters(
460         {
461             {features::kCalculateNativeWinOcclusion, {}},
462             {features::kApplyNativeOcclusionToCompositor,
463              {{features::kApplyNativeOcclusionToCompositorType,
464                features::kApplyNativeOcclusionToCompositorTypeThrottle}}},
465         },
466         {});
467     AuraTestBase::SetUp();
468   }
469
470   void TearDown() override {
471     test::AuraTestBase::TearDown();
472     NativeWindowOcclusionTracker::SetHeadlessCheckEnabled(true);
473   }
474
475  private:
476   base::test::ScopedFeatureList scoped_feature_list_;
477 };
478
479 TEST_F(WindowTreeHostWithThrottleTest, DISABLED_Basic) {
480   host()->Show();
481   EXPECT_TRUE(host()->compositor()->IsVisible());
482   EXPECT_TRUE(test::GetThrottledHosts().empty());
483   host()->SetNativeWindowOcclusionState(Window::OcclusionState::OCCLUDED, {});
484   EXPECT_TRUE(host()->compositor()->IsVisible());
485   EXPECT_TRUE(base::Contains(test::GetThrottledHosts(), host()));
486   host()->SetNativeWindowOcclusionState(Window::OcclusionState::VISIBLE, {});
487   EXPECT_TRUE(test::GetThrottledHosts().empty());
488   EXPECT_TRUE(host()->compositor()->IsVisible());
489 }
490
491 TEST_F(WindowTreeHostWithThrottleTest, DISABLED_CallHideDirectly) {
492   host()->Show();
493   EXPECT_TRUE(host()->compositor()->IsVisible());
494   EXPECT_TRUE(test::GetThrottledHosts().empty());
495   host()->SetNativeWindowOcclusionState(Window::OcclusionState::OCCLUDED, {});
496   EXPECT_TRUE(host()->compositor()->IsVisible());
497   EXPECT_TRUE(base::Contains(test::GetThrottledHosts(), host()));
498   host()->Hide();
499   EXPECT_TRUE(test::GetThrottledHosts().empty());
500   EXPECT_FALSE(host()->compositor()->IsVisible());
501 }
502
503 #endif  // BUILDFLAG(IS_WIN)
504
505 }  // namespace aura