ExtensionSyncService: Properly differentiate between "pending install" and "pending...
[chromium-blink-merge.git] / components / web_view / frame_apptest.cc
blob8fb2357317fc4e1a22f982adc603a4ed7dbd5b4a
1 // Copyright 2015 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.
5 #include "components/web_view/frame.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "base/test/test_timeouts.h"
13 #include "components/view_manager/public/cpp/view_observer.h"
14 #include "components/view_manager/public/cpp/view_tree_connection.h"
15 #include "components/view_manager/public/cpp/view_tree_delegate.h"
16 #include "components/view_manager/public/cpp/view_tree_host_factory.h"
17 #include "components/web_view/frame.h"
18 #include "components/web_view/frame_tree.h"
19 #include "components/web_view/frame_tree_delegate.h"
20 #include "components/web_view/frame_user_data.h"
21 #include "components/web_view/test_frame_tree_delegate.h"
22 #include "mojo/application/public/cpp/application_connection.h"
23 #include "mojo/application/public/cpp/application_delegate.h"
24 #include "mojo/application/public/cpp/application_impl.h"
25 #include "mojo/application/public/cpp/application_test_base.h"
26 #include "mojo/application/public/cpp/service_provider_impl.h"
28 using mojo::View;
29 using mojo::ViewTreeConnection;
31 namespace web_view {
33 namespace {
35 base::RunLoop* current_run_loop = nullptr;
37 void TimeoutRunLoop(const base::Closure& timeout_task, bool* timeout) {
38 CHECK(current_run_loop);
39 *timeout = true;
40 timeout_task.Run();
43 bool DoRunLoopWithTimeout() {
44 if (current_run_loop != nullptr)
45 return false;
47 bool timeout = false;
48 base::RunLoop run_loop;
49 base::MessageLoop::current()->PostDelayedTask(
50 FROM_HERE, base::Bind(&TimeoutRunLoop, run_loop.QuitClosure(), &timeout),
51 TestTimeouts::action_timeout());
53 current_run_loop = &run_loop;
54 current_run_loop->Run();
55 current_run_loop = nullptr;
56 return !timeout;
59 void QuitRunLoop() {
60 current_run_loop->Quit();
61 current_run_loop = nullptr;
64 } // namespace
66 class FrameTest : public mojo::test::ApplicationTestBase,
67 public mojo::ApplicationDelegate,
68 public mojo::ViewTreeDelegate,
69 public mojo::InterfaceFactory<mojo::ViewTreeClient> {
70 public:
71 FrameTest() : most_recent_connection_(nullptr), window_manager_(nullptr) {}
73 ViewTreeConnection* most_recent_connection() {
74 return most_recent_connection_;
77 // ApplicationDelegate implementation.
78 bool ConfigureIncomingConnection(
79 mojo::ApplicationConnection* connection) override {
80 connection->AddService<mojo::ViewTreeClient>(this);
81 return true;
84 ViewTreeConnection* window_manager() { return window_manager_; }
86 // ApplicationTestBase:
87 ApplicationDelegate* GetApplicationDelegate() override { return this; }
89 // Overridden from ViewTreeDelegate:
90 void OnEmbed(View* root) override {
91 most_recent_connection_ = root->connection();
92 QuitRunLoop();
94 void OnConnectionLost(ViewTreeConnection* connection) override {}
96 private:
97 // Overridden from testing::Test:
98 void SetUp() override {
99 ApplicationTestBase::SetUp();
101 mojo::CreateSingleViewTreeHost(application_impl(), this, &host_);
103 ASSERT_TRUE(DoRunLoopWithTimeout());
104 std::swap(window_manager_, most_recent_connection_);
107 // Overridden from testing::Test:
108 void TearDown() override {
109 ApplicationTestBase::TearDown();
112 // Overridden from mojo::InterfaceFactory<mojo::ViewTreeClient>:
113 void Create(
114 mojo::ApplicationConnection* connection,
115 mojo::InterfaceRequest<mojo::ViewTreeClient> request) override {
116 mojo::ViewTreeConnection::Create(this, request.Pass());
119 mojo::ViewTreeHostPtr host_;
121 // Used to receive the most recent view manager loaded by an embed action.
122 ViewTreeConnection* most_recent_connection_;
123 // The View Manager connection held by the window manager (app running at the
124 // root view).
125 ViewTreeConnection* window_manager_;
127 MOJO_DISALLOW_COPY_AND_ASSIGN(FrameTest);
130 class TestFrameTreeClient : public FrameTreeClient {
131 public:
132 TestFrameTreeClient() : connect_count_(0) {}
133 ~TestFrameTreeClient() override {}
135 int connect_count() const { return connect_count_; }
137 mojo::Array<FrameDataPtr> connect_frames() { return connect_frames_.Pass(); }
139 mojo::Array<FrameDataPtr> adds() { return adds_.Pass(); }
141 // TestFrameTreeClient:
142 void OnConnect(FrameTreeServerPtr server,
143 uint32_t change_id,
144 uint32_t view_id,
145 ViewConnectType view_connect_type,
146 mojo::Array<FrameDataPtr> frames,
147 const OnConnectCallback& callback) override {
148 connect_count_++;
149 connect_frames_ = frames.Pass();
150 server_ = server.Pass();
151 callback.Run();
153 void OnFrameAdded(uint32_t change_id, FrameDataPtr frame) override {
154 adds_.push_back(frame.Pass());
156 void OnFrameRemoved(uint32_t change_id, uint32_t frame_id) override {}
157 void OnFrameClientPropertyChanged(uint32_t frame_id,
158 const mojo::String& name,
159 mojo::Array<uint8_t> new_data) override {}
160 void OnPostMessageEvent(uint32_t source_frame_id,
161 uint32_t target_frame_id,
162 HTMLMessageEventPtr event) override {}
163 void OnWillNavigate(uint32_t frame_id) override {}
165 private:
166 int connect_count_;
167 mojo::Array<FrameDataPtr> connect_frames_;
168 FrameTreeServerPtr server_;
169 mojo::Array<FrameDataPtr> adds_;
171 DISALLOW_COPY_AND_ASSIGN(TestFrameTreeClient);
174 // Verifies the root gets a connect.
175 TEST_F(FrameTest, RootGetsConnect) {
176 TestFrameTreeDelegate tree_delegate;
177 TestFrameTreeClient root_client;
178 FrameTree tree(0u, window_manager()->GetRoot(), &tree_delegate, &root_client,
179 nullptr, Frame::ClientPropertyMap());
180 ASSERT_EQ(1, root_client.connect_count());
181 mojo::Array<FrameDataPtr> frames = root_client.connect_frames();
182 ASSERT_EQ(1u, frames.size());
183 EXPECT_EQ(tree.root()->view()->id(), frames[0]->frame_id);
184 EXPECT_EQ(0u, frames[0]->parent_id);
187 // Verifies adding a child to the root.
188 TEST_F(FrameTest, SingleChild) {
189 TestFrameTreeDelegate tree_delegate;
190 TestFrameTreeClient root_client;
191 FrameTree tree(0u, window_manager()->GetRoot(), &tree_delegate, &root_client,
192 nullptr, Frame::ClientPropertyMap());
194 View* child = window_manager()->CreateView();
195 EXPECT_EQ(nullptr, Frame::FindFirstFrameAncestor(child));
196 window_manager()->GetRoot()->AddChild(child);
197 EXPECT_EQ(tree.root(), Frame::FindFirstFrameAncestor(child));
199 TestFrameTreeClient child_client;
200 Frame* child_frame =
201 tree.CreateAndAddFrame(child, tree.root(), 0u, &child_client, nullptr);
202 EXPECT_EQ(tree.root(), child_frame->parent());
204 ASSERT_EQ(1, child_client.connect_count());
205 mojo::Array<FrameDataPtr> frames_in_child = child_client.connect_frames();
206 // We expect 2 frames. One for the root, one for the child.
207 ASSERT_EQ(2u, frames_in_child.size());
208 EXPECT_EQ(tree.root()->view()->id(), frames_in_child[0]->frame_id);
209 EXPECT_EQ(0u, frames_in_child[0]->parent_id);
210 EXPECT_EQ(child_frame->view()->id(), frames_in_child[1]->frame_id);
211 EXPECT_EQ(tree.root()->view()->id(), frames_in_child[1]->parent_id);
213 // We should have gotten notification of the add.
214 EXPECT_EQ(1u, root_client.adds().size());
217 } // namespace web_view