1 // Copyright 2019 The Chromium Authors. All rights reserved.
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_platform.h"
6 
7 #include "ui/aura/test/aura_test_base.h"
8 #include "ui/aura/window_tree_host_observer.h"
9 #include "ui/platform_window/stub/stub_window.h"
10 
11 namespace aura {
12 namespace {
13 
14 using WindowTreeHostPlatformTest = test::AuraTestBase;
15 
16 // Trivial WindowTreeHostPlatform implementation that installs a StubWindow as
17 // the PlatformWindow.
18 class TestWindowTreeHost : public WindowTreeHostPlatform {
19  public:
TestWindowTreeHost()20   TestWindowTreeHost() {
21     SetPlatformWindow(std::make_unique<ui::StubWindow>(this));
22     CreateCompositor();
23   }
24 
platform_window()25   ui::PlatformWindow* platform_window() {
26     return WindowTreeHostPlatform::platform_window();
27   }
28 
29  private:
30   DISALLOW_COPY_AND_ASSIGN(TestWindowTreeHost);
31 };
32 
33 // WindowTreeHostObserver that tracks calls to
34 // OnHostWill/DidProcessBoundsChange. Additionally, this triggers a bounds
35 // change from within OnHostResized(). Such a scenario happens in production
36 // code.
37 class TestWindowTreeHostObserver : public aura::WindowTreeHostObserver {
38  public:
TestWindowTreeHostObserver(WindowTreeHostPlatform * host,ui::PlatformWindow * platform_window)39   TestWindowTreeHostObserver(WindowTreeHostPlatform* host,
40                              ui::PlatformWindow* platform_window)
41       : host_(host), platform_window_(platform_window) {
42     host_->AddObserver(this);
43   }
~TestWindowTreeHostObserver()44   ~TestWindowTreeHostObserver() override { host_->RemoveObserver(this); }
45 
on_host_did_process_bounds_change_count() const46   int on_host_did_process_bounds_change_count() const {
47     return on_host_did_process_bounds_change_count_;
48   }
49 
on_host_will_process_bounds_change_count() const50   int on_host_will_process_bounds_change_count() const {
51     return on_host_will_process_bounds_change_count_;
52   }
53 
54   // aura::WindowTreeHostObserver:
OnHostResized(WindowTreeHost * host)55   void OnHostResized(WindowTreeHost* host) override {
56     if (!should_change_bounds_in_on_resized_)
57       return;
58 
59     should_change_bounds_in_on_resized_ = false;
60     gfx::Rect bounds = platform_window_->GetBounds();
61     bounds.set_x(bounds.x() + 1);
62     host_->SetBoundsInPixels(bounds);
63   }
OnHostWillProcessBoundsChange(WindowTreeHost * host)64   void OnHostWillProcessBoundsChange(WindowTreeHost* host) override {
65     ++on_host_will_process_bounds_change_count_;
66   }
OnHostDidProcessBoundsChange(WindowTreeHost * host)67   void OnHostDidProcessBoundsChange(WindowTreeHost* host) override {
68     ++on_host_did_process_bounds_change_count_;
69   }
70 
71  private:
72   WindowTreeHostPlatform* host_;
73   ui::PlatformWindow* platform_window_;
74   bool should_change_bounds_in_on_resized_ = true;
75   int on_host_will_process_bounds_change_count_ = 0;
76   int on_host_did_process_bounds_change_count_ = 0;
77 
78   DISALLOW_COPY_AND_ASSIGN(TestWindowTreeHostObserver);
79 };
80 
81 // Regression test for https://crbug.com/958449
TEST_F(WindowTreeHostPlatformTest,HostWillProcessBoundsChangeRecursion)82 TEST_F(WindowTreeHostPlatformTest, HostWillProcessBoundsChangeRecursion) {
83   TestWindowTreeHost host;
84   TestWindowTreeHostObserver observer(&host, host.platform_window());
85   // This call triggers a recursive bounds change. That is, this results in
86   // WindowTreePlatform::OnBoundsChanged() indirectly calling back into
87   // WindowTreePlatform::OnBoundsChanged(). In such a scenario the observer
88   // should be notified only once (see comment in
89   // WindowTreeHostPlatform::OnBoundsChanged() for details).
90   host.SetBoundsInPixels(gfx::Rect(1, 2, 3, 4));
91   EXPECT_EQ(1, observer.on_host_did_process_bounds_change_count());
92   EXPECT_EQ(1, observer.on_host_will_process_bounds_change_count());
93 }
94 
95 }  // namespace
96 }  // namespace aura
97