Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1062)

Side by Side Diff: mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc

Issue 290703002: Map new subtrees when they are attached to the node hierarchy visible to a connection. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: / Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/services/public/cpp/view_manager/view_manager.h" 5 #include "mojo/services/public/cpp/view_manager/view_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
10 #include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"
9 #include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h" 11 #include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
10 #include "mojo/services/public/cpp/view_manager/util.h" 12 #include "mojo/services/public/cpp/view_manager/util.h"
11 #include "mojo/services/public/cpp/view_manager/view.h" 13 #include "mojo/services/public/cpp/view_manager/view.h"
12 #include "mojo/services/public/cpp/view_manager/view_observer.h" 14 #include "mojo/services/public/cpp/view_manager/view_observer.h"
13 #include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h" 15 #include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h"
14 #include "mojo/shell/shell_test_helper.h" 16 #include "mojo/shell/shell_test_helper.h"
15 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
16 18
17 namespace mojo { 19 namespace mojo {
18 namespace view_manager { 20 namespace view_manager {
19 21
20 base::RunLoop* current_run_loop = NULL; 22 base::RunLoop* current_run_loop = NULL;
21 23
22 void DoRunLoop() { 24 void DoRunLoop() {
23 base::RunLoop run_loop; 25 base::RunLoop run_loop;
24 current_run_loop = &run_loop; 26 current_run_loop = &run_loop;
25 current_run_loop->Run(); 27 current_run_loop->Run();
26 current_run_loop = NULL; 28 current_run_loop = NULL;
27 } 29 }
28 30
29 void QuitRunLoop() { 31 void QuitRunLoop() {
30 current_run_loop->Quit(); 32 current_run_loop->Quit();
31 } 33 }
32 34
35 void QuitRunLoopOnChangesAcked() {
36 QuitRunLoop();
37 }
38
39 void WaitForAllChangesToBeAcked(ViewManager* manager) {
40 ViewManagerPrivate(manager).synchronizer()->set_changes_acked_callback(
41 base::Bind(&QuitRunLoopOnChangesAcked));
sky 2014/05/16 23:28:22 nit: indent 2 more.
42 DoRunLoop();
43 ViewManagerPrivate(manager).synchronizer()->ClearChangesAckedCallback();
44 }
45
46 class ActiveViewChangedObserver : public ViewTreeNodeObserver {
47 public:
48 explicit ActiveViewChangedObserver(ViewTreeNode* node)
49 : node_(node) {}
50 virtual ~ActiveViewChangedObserver() {}
51
52 private:
53 // Overridden from ViewTreeNodeObserver:
54 virtual void OnNodeActiveViewChange(ViewTreeNode* node,
55 View* old_view,
56 View* new_view,
57 DispositionChangePhase phase) OVERRIDE {
58 DCHECK_EQ(node, node_);
59 QuitRunLoop();
60 }
61
62 ViewTreeNode* node_;
63
64 DISALLOW_COPY_AND_ASSIGN(ActiveViewChangedObserver);
65 };
66
67 // Waits until the active view id of the supplied node changes.
68 void WaitForActiveViewToChange(ViewTreeNode* node) {
69 ActiveViewChangedObserver observer(node);
70 node->AddObserver(&observer);
71 DoRunLoop();
72 node->RemoveObserver(&observer);
73 }
74
75 // Spins a runloop until the tree beginning at |root| has |tree_size| nodes
76 // (including |root|).
77 class TreeSizeMatchesObserver : public ViewTreeNodeObserver {
78 public:
79 TreeSizeMatchesObserver(ViewTreeNode* tree, size_t tree_size)
80 : tree_(tree),
81 tree_size_(tree_size) {}
82 virtual ~TreeSizeMatchesObserver() {}
83
84 bool IsTreeCorrectSize() {
85 return CountNodes(tree_) == tree_size_;
86 }
87
88 private:
89 // Overridden from ViewTreeNodeObserver:
90 virtual void OnTreeChange(const TreeChangeParams& params) OVERRIDE {
91 if (params.phase != ViewTreeNodeObserver::DISPOSITION_CHANGED)
92 return;
93 if (IsTreeCorrectSize())
94 QuitRunLoop();
95 }
96
97 size_t CountNodes(const ViewTreeNode* node) const {
98 size_t count = 1;
99 ViewTreeNode::Children::const_iterator it = node->children().begin();
100 for (; it != node->children().end(); ++it)
101 count += CountNodes(*it);
102 return count;
103 }
104
105 ViewTreeNode* tree_;
106 size_t tree_size_;
107 DISALLOW_COPY_AND_ASSIGN(TreeSizeMatchesObserver);
108 };
109
110 void WaitForTreeSizeToMatch(ViewTreeNode* node, size_t tree_size) {
111 TreeSizeMatchesObserver observer(node, tree_size);
112 if (observer.IsTreeCorrectSize())
113 return;
114 node->AddObserver(&observer);
115 DoRunLoop();
116 node->RemoveObserver(&observer);
117 }
118
119
120 // Utility class that waits for the destruction of some number of nodes and
121 // views.
122 class DestructionObserver : public ViewTreeNodeObserver,
123 public ViewObserver {
124 public:
125 // |nodes| or |views| can be NULL.
126 DestructionObserver(std::set<TransportNodeId>* nodes,
127 std::set<TransportViewId>* views)
128 : nodes_(nodes),
129 views_(views) {}
130
131 private:
132 // Overridden from ViewTreeNodeObserver:
133 virtual void OnNodeDestroy(
134 ViewTreeNode* node,
135 ViewTreeNodeObserver::DispositionChangePhase phase) OVERRIDE {
136 if (phase != ViewTreeNodeObserver::DISPOSITION_CHANGED)
137 return;
138 std::set<TransportNodeId>::const_iterator it = nodes_->find(node->id());
139 if (it != nodes_->end())
140 nodes_->erase(it);
141 if (CanQuit())
142 QuitRunLoop();
143 }
144
145 // Overridden from ViewObserver:
146 virtual void OnViewDestroy(
147 View* view,
148 ViewObserver::DispositionChangePhase phase) OVERRIDE {
149 if (phase != ViewObserver::DISPOSITION_CHANGED)
150 return;
151 std::set<TransportViewId>::const_iterator it = views_->find(view->id());
152 if (it != views_->end())
153 views_->erase(it);
154 if (CanQuit())
155 QuitRunLoop();
156 }
157
158 bool CanQuit() {
159 return (!nodes_ || nodes_->empty()) && (!views_ || views_->empty());
160 }
161
162 std::set<TransportNodeId>* nodes_;
163 std::set<TransportViewId>* views_;
164
165 DISALLOW_COPY_AND_ASSIGN(DestructionObserver);
166 };
167
168 void WaitForDestruction(ViewManager* view_manager,
169 std::set<TransportNodeId>* nodes,
170 std::set<TransportViewId>* views) {
171 DestructionObserver observer(nodes, views);
172 DCHECK(nodes || views);
173 if (nodes) {
174 for (std::set<TransportNodeId>::const_iterator it = nodes->begin();
175 it != nodes->end(); ++it) {
176 view_manager->GetNodeById(*it)->AddObserver(&observer);
177 }
178 }
179 if (views) {
180 for (std::set<TransportViewId>::const_iterator it = views->begin();
181 it != views->end(); ++it) {
182 view_manager->GetViewById(*it)->AddObserver(&observer);
183 }
184 }
185 DoRunLoop();
186 }
187
33 // ViewManager ----------------------------------------------------------------- 188 // ViewManager -----------------------------------------------------------------
34 189
35 // These tests model synchronization of two peer connections to the view manager 190 // These tests model synchronization of two peer connections to the view manager
36 // service, that are given access to some root node. 191 // service, that are given access to some root node.
37 192
38 class ViewManagerTest : public testing::Test { 193 class ViewManagerTest : public testing::Test {
39 public: 194 public:
40 ViewManagerTest() : commit_count_(0) {} 195 ViewManagerTest() : commit_count_(0) {}
41 196
42 protected: 197 protected:
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 // Overridden from ViewTreeNodeObserver: 249 // Overridden from ViewTreeNodeObserver:
95 virtual void OnTreeChange(const TreeChangeParams& params) OVERRIDE { 250 virtual void OnTreeChange(const TreeChangeParams& params) OVERRIDE {
96 if (ShouldQuitRunLoop(params)) 251 if (ShouldQuitRunLoop(params))
97 QuitRunLoop(); 252 QuitRunLoop();
98 } 253 }
99 254
100 ViewManager* view_manager_; 255 ViewManager* view_manager_;
101 DISALLOW_COPY_AND_ASSIGN(TreeObserverBase); 256 DISALLOW_COPY_AND_ASSIGN(TreeObserverBase);
102 }; 257 };
103 258
104 // Spins a runloop until the tree beginning at |root| has |tree_size| nodes
105 // (including |root|).
106 class TreeSizeMatchesWaiter : public TreeObserverBase {
107 public:
108 TreeSizeMatchesWaiter(ViewManager* view_manager, size_t tree_size)
109 : TreeObserverBase(view_manager),
110 tree_size_(tree_size) {
111 DoRunLoop();
112 }
113 virtual ~TreeSizeMatchesWaiter() {}
114
115 private:
116 // Overridden from TreeObserverBase:
117 virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE {
118 if (params.phase != ViewTreeNodeObserver::DISPOSITION_CHANGED)
119 return false;
120 return CountNodes(view_manager()->tree()) == tree_size_;
121 }
122
123 size_t CountNodes(ViewTreeNode* node) const {
124 size_t count = 1;
125 ViewTreeNode::Children::const_iterator it = node->children().begin();
126 for (; it != node->children().end(); ++it)
127 count += CountNodes(*it);
128 return count;
129 }
130
131 size_t tree_size_;
132 DISALLOW_COPY_AND_ASSIGN(TreeSizeMatchesWaiter);
133 };
134
135
136 class HierarchyChanged_NodeCreatedObserver : public TreeObserverBase { 259 class HierarchyChanged_NodeCreatedObserver : public TreeObserverBase {
137 public: 260 public:
138 explicit HierarchyChanged_NodeCreatedObserver(ViewManager* view_manager) 261 explicit HierarchyChanged_NodeCreatedObserver(ViewManager* view_manager)
139 : TreeObserverBase(view_manager) {} 262 : TreeObserverBase(view_manager) {}
140 virtual ~HierarchyChanged_NodeCreatedObserver() {} 263 virtual ~HierarchyChanged_NodeCreatedObserver() {}
141 264
142 private: 265 private:
143 // Overridden from TreeObserverBase: 266 // Overridden from TreeObserverBase:
144 virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE { 267 virtual bool ShouldQuitRunLoop(const TreeChangeParams& params) OVERRIDE {
145 if (params.phase != ViewTreeNodeObserver::DISPOSITION_CHANGED) 268 if (params.phase != ViewTreeNodeObserver::DISPOSITION_CHANGED)
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 TransportNodeId old_parent_id_; 309 TransportNodeId old_parent_id_;
187 TransportNodeId new_parent_id_; 310 TransportNodeId new_parent_id_;
188 311
189 DISALLOW_COPY_AND_ASSIGN(HierarchyChanged_NodeMovedObserver); 312 DISALLOW_COPY_AND_ASSIGN(HierarchyChanged_NodeMovedObserver);
190 }; 313 };
191 314
192 TEST_F(ViewManagerTest, HierarchyChanged_NodeMoved) { 315 TEST_F(ViewManagerTest, HierarchyChanged_NodeMoved) {
193 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); 316 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
194 ViewTreeNode* node2 = CreateNodeInParent(view_manager_1()->tree()); 317 ViewTreeNode* node2 = CreateNodeInParent(view_manager_1()->tree());
195 ViewTreeNode* node21 = CreateNodeInParent(node2); 318 ViewTreeNode* node21 = CreateNodeInParent(node2);
196 TreeSizeMatchesWaiter waiter(view_manager_2(), 4); 319 WaitForTreeSizeToMatch(view_manager_2()->tree(), 4);
197 320
198 HierarchyChanged_NodeMovedObserver observer(view_manager_2(), 321 HierarchyChanged_NodeMovedObserver observer(view_manager_2(),
199 node2->id(), 322 node2->id(),
200 node1->id()); 323 node1->id());
201 324
202 node1->AddChild(node21); 325 node1->AddChild(node21);
203 DoRunLoop(); 326 DoRunLoop();
204 327
205 ViewTreeNode* tree2 = view_manager_2()->tree(); 328 ViewTreeNode* tree2 = view_manager_2()->tree();
206 329
(...skipping 20 matching lines...) Expand all
227 return params.receiver == view_manager()->tree() && 350 return params.receiver == view_manager()->tree() &&
228 params.old_parent->id() == params.receiver->id() && 351 params.old_parent->id() == params.receiver->id() &&
229 params.new_parent == 0; 352 params.new_parent == 0;
230 } 353 }
231 354
232 DISALLOW_COPY_AND_ASSIGN(HierarchyChanged_NodeRemovedObserver); 355 DISALLOW_COPY_AND_ASSIGN(HierarchyChanged_NodeRemovedObserver);
233 }; 356 };
234 357
235 TEST_F(ViewManagerTest, HierarchyChanged_NodeRemoved) { 358 TEST_F(ViewManagerTest, HierarchyChanged_NodeRemoved) {
236 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); 359 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
237 TreeSizeMatchesWaiter waiter(view_manager_2(), 2); 360 WaitForTreeSizeToMatch(view_manager_2()->tree(), 2);
238 361
239 HierarchyChanged_NodeRemovedObserver observer(view_manager_2()); 362 HierarchyChanged_NodeRemovedObserver observer(view_manager_2());
240 363
241 view_manager_1()->tree()->RemoveChild(node1); 364 view_manager_1()->tree()->RemoveChild(node1);
242 DoRunLoop(); 365 DoRunLoop();
243 366
244 ViewTreeNode* tree2 = view_manager_2()->tree(); 367 ViewTreeNode* tree2 = view_manager_2()->tree();
245 368
246 EXPECT_TRUE(tree2->children().empty()); 369 EXPECT_TRUE(tree2->children().empty());
247 } 370 }
248 371
249 // Utility class that waits for the destruction of some number of nodes and
250 // views.
251 class DestructionWaiter : public ViewTreeNodeObserver,
252 public ViewObserver {
253 public:
254 // |nodes| or |views| can be NULL.
255 DestructionWaiter(ViewManager* view_manager,
256 std::set<TransportNodeId>* nodes,
257 std::set<TransportViewId>* views)
258 : nodes_(nodes),
259 views_(views) {
260 DCHECK(nodes || views);
261 if (nodes) {
262 for (std::set<TransportNodeId>::const_iterator it = nodes->begin();
263 it != nodes->end(); ++it) {
264 view_manager->GetNodeById(*it)->AddObserver(this);
265 }
266 }
267 if (views) {
268 for (std::set<TransportViewId>::const_iterator it = views->begin();
269 it != views->end(); ++it) {
270 view_manager->GetViewById(*it)->AddObserver(this);
271 }
272 }
273 DoRunLoop();
274 }
275
276 private:
277 // Overridden from ViewTreeNodeObserver:
278 virtual void OnNodeDestroy(
279 ViewTreeNode* node,
280 ViewTreeNodeObserver::DispositionChangePhase phase) OVERRIDE {
281 if (phase != ViewTreeNodeObserver::DISPOSITION_CHANGED)
282 return;
283 std::set<TransportNodeId>::const_iterator it = nodes_->find(node->id());
284 if (it != nodes_->end())
285 nodes_->erase(it);
286 if (CanQuit())
287 QuitRunLoop();
288 }
289
290 // Overridden from ViewObserver:
291 virtual void OnViewDestroy(
292 View* view,
293 ViewObserver::DispositionChangePhase phase) OVERRIDE {
294 if (phase != ViewObserver::DISPOSITION_CHANGED)
295 return;
296 std::set<TransportViewId>::const_iterator it = views_->find(view->id());
297 if (it != views_->end())
298 views_->erase(it);
299 if (CanQuit())
300 QuitRunLoop();
301 }
302
303 bool CanQuit() {
304 return (!nodes_ || nodes_->empty()) && (!views_ || views_->empty());
305 }
306
307 std::set<TransportNodeId>* nodes_;
308 std::set<TransportViewId>* views_;
309
310 DISALLOW_COPY_AND_ASSIGN(DestructionWaiter);
311 };
312
313 TEST_F(ViewManagerTest, NodeDestroyed) { 372 TEST_F(ViewManagerTest, NodeDestroyed) {
314 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); 373 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
315 TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2); 374 WaitForTreeSizeToMatch(view_manager_2()->tree(), 2);
316 375
317 // |node1| will be deleted after calling Destroy() below. 376 // |node1| will be deleted after calling Destroy() below.
318 TransportNodeId id = node1->id(); 377 TransportNodeId id = node1->id();
319 node1->Destroy(); 378 node1->Destroy();
320 379
321 std::set<TransportNodeId> nodes; 380 std::set<TransportNodeId> nodes;
322 nodes.insert(id); 381 nodes.insert(id);
323 DestructionWaiter destroyed_waiter(view_manager_2(), &nodes, NULL); 382 WaitForDestruction(view_manager_2(), &nodes, NULL);
324 383
325 EXPECT_TRUE(view_manager_2()->tree()->children().empty()); 384 EXPECT_TRUE(view_manager_2()->tree()->children().empty());
326 EXPECT_EQ(NULL, view_manager_2()->GetNodeById(id)); 385 EXPECT_EQ(NULL, view_manager_2()->GetNodeById(id));
327 } 386 }
328 387
329 TEST_F(ViewManagerTest, ViewManagerDestroyed_CleanupNode) { 388 TEST_F(ViewManagerTest, ViewManagerDestroyed_CleanupNode) {
330 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); 389 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
331 TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2); 390 WaitForTreeSizeToMatch(view_manager_2()->tree(), 2);
332 391
333 TransportNodeId id = node1->id(); 392 TransportNodeId id = node1->id();
334 DestroyViewManager1(); 393 DestroyViewManager1();
335 std::set<TransportNodeId> nodes; 394 std::set<TransportNodeId> nodes;
336 nodes.insert(id); 395 nodes.insert(id);
337 DestructionWaiter destroyed_waiter(view_manager_2(), &nodes, NULL); 396 WaitForDestruction(view_manager_2(), &nodes, NULL);
338 397
339 // tree() should still be valid, since it's owned by neither connection. 398 // tree() should still be valid, since it's owned by neither connection.
340 EXPECT_TRUE(view_manager_2()->tree()->children().empty()); 399 EXPECT_TRUE(view_manager_2()->tree()->children().empty());
341 } 400 }
342 401
343 // Waits until the active view id of the supplied node changes.
344 class ActiveViewChangedWaiter : public ViewTreeNodeObserver {
345 public:
346 explicit ActiveViewChangedWaiter(ViewTreeNode* node)
347 : node_(node) {
348 node_->AddObserver(this);
349 DoRunLoop();
350 }
351 virtual ~ActiveViewChangedWaiter() {
352 node_->RemoveObserver(this);
353 }
354
355 private:
356 // Overridden from ViewTreeNodeObserver:
357 virtual void OnNodeActiveViewChange(ViewTreeNode* node,
358 View* old_view,
359 View* new_view,
360 DispositionChangePhase phase) OVERRIDE {
361 DCHECK_EQ(node, node_);
362 QuitRunLoop();
363 }
364
365 ViewTreeNode* node_;
366
367 DISALLOW_COPY_AND_ASSIGN(ActiveViewChangedWaiter);
368 };
369
370 TEST_F(ViewManagerTest, SetActiveView) { 402 TEST_F(ViewManagerTest, SetActiveView) {
371 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); 403 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
372 TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2); 404 WaitForTreeSizeToMatch(view_manager_2()->tree(), 2);
373 405
374 View* view1 = View::Create(view_manager_1()); 406 View* view1 = View::Create(view_manager_1());
375 node1->SetActiveView(view1); 407 node1->SetActiveView(view1);
376 408
377 ViewTreeNode* node1_2 = view_manager_2()->tree()->GetChildById(node1->id()); 409 ViewTreeNode* node1_2 = view_manager_2()->tree()->GetChildById(node1->id());
378 ActiveViewChangedWaiter waiter(node1_2); 410 WaitForActiveViewToChange(node1_2);
379 411
380 EXPECT_EQ(node1_2->active_view()->id(), view1->id()); 412 EXPECT_EQ(node1_2->active_view()->id(), view1->id());
381 } 413 }
382 414
383 TEST_F(ViewManagerTest, DestroyView) { 415 TEST_F(ViewManagerTest, DestroyView) {
384 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); 416 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
385 TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2); 417 WaitForTreeSizeToMatch(view_manager_2()->tree(), 2);
386 418
387 View* view1 = View::Create(view_manager_1()); 419 View* view1 = View::Create(view_manager_1());
388 node1->SetActiveView(view1); 420 node1->SetActiveView(view1);
389 421
390 ViewTreeNode* node1_2 = view_manager_2()->tree()->GetChildById(node1->id()); 422 ViewTreeNode* node1_2 = view_manager_2()->tree()->GetChildById(node1->id());
391 ActiveViewChangedWaiter active_view_waiter(node1_2); 423 WaitForActiveViewToChange(node1_2);
392 424
393 TransportViewId view1_id = view1->id(); 425 TransportViewId view1_id = view1->id();
394 view1->Destroy(); 426 view1->Destroy();
395 427
396 std::set<TransportViewId> views; 428 std::set<TransportViewId> views;
397 views.insert(view1_id); 429 views.insert(view1_id);
398 DestructionWaiter destruction_waiter(view_manager_2(), NULL, &views); 430 WaitForDestruction(view_manager_2(), NULL, &views);
399 EXPECT_EQ(NULL, node1_2->active_view()); 431 EXPECT_EQ(NULL, node1_2->active_view());
400 EXPECT_EQ(NULL, view_manager_2()->GetViewById(view1_id)); 432 EXPECT_EQ(NULL, view_manager_2()->GetViewById(view1_id));
401 } 433 }
402 434
403 // Destroying the connection that created a node and view should result in that 435 // Destroying the connection that created a node and view should result in that
404 // node and view disappearing from all connections that see them. 436 // node and view disappearing from all connections that see them.
405 TEST_F(ViewManagerTest, ViewManagerDestroyed_CleanupNodeAndView) { 437 TEST_F(ViewManagerTest, ViewManagerDestroyed_CleanupNodeAndView) {
406 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); 438 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
407 TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2); 439 WaitForTreeSizeToMatch(view_manager_2()->tree(), 2);
408 440
409 View* view1 = View::Create(view_manager_1()); 441 View* view1 = View::Create(view_manager_1());
410 node1->SetActiveView(view1); 442 node1->SetActiveView(view1);
411 443
412 ViewTreeNode* node1_2 = view_manager_2()->tree()->GetChildById(node1->id()); 444 ViewTreeNode* node1_2 = view_manager_2()->tree()->GetChildById(node1->id());
413 { 445 WaitForActiveViewToChange(node1_2);
414 ActiveViewChangedWaiter active_view_waiter(node1_2);
415 }
416 446
417 TransportNodeId node1_id = node1->id(); 447 TransportNodeId node1_id = node1->id();
418 TransportViewId view1_id = view1->id(); 448 TransportViewId view1_id = view1->id();
419 449
420 DestroyViewManager1(); 450 DestroyViewManager1();
421 std::set<TransportNodeId> observed_nodes; 451 std::set<TransportNodeId> observed_nodes;
422 observed_nodes.insert(node1_id); 452 observed_nodes.insert(node1_id);
423 std::set<TransportViewId> observed_views; 453 std::set<TransportViewId> observed_views;
424 observed_views.insert(view1_id); 454 observed_views.insert(view1_id);
425 DestructionWaiter destruction_waiter(view_manager_2(), 455 WaitForDestruction(view_manager_2(), &observed_nodes, &observed_views);
426 &observed_nodes,
427 &observed_views);
428 456
429 // tree() should still be valid, since it's owned by neither connection. 457 // tree() should still be valid, since it's owned by neither connection.
430 EXPECT_TRUE(view_manager_2()->tree()->children().empty()); 458 EXPECT_TRUE(view_manager_2()->tree()->children().empty());
431 EXPECT_EQ(NULL, view_manager_2()->GetNodeById(node1_id)); 459 EXPECT_EQ(NULL, view_manager_2()->GetNodeById(node1_id));
432 EXPECT_EQ(NULL, view_manager_2()->GetViewById(view1_id)); 460 EXPECT_EQ(NULL, view_manager_2()->GetViewById(view1_id));
433 } 461 }
434 462
435 // This test validates the following scenario: 463 // This test validates the following scenario:
436 // - a node originating from one connection 464 // - a node originating from one connection
437 // - a view originating from a second connection 465 // - a view originating from a second connection
438 // + the connection originating the node is destroyed 466 // + the connection originating the node is destroyed
439 // -> the view should still exist (since the second connection is live) but 467 // -> the view should still exist (since the second connection is live) but
440 // should be disconnected from any nodes. 468 // should be disconnected from any nodes.
441 TEST_F(ViewManagerTest, 469 TEST_F(ViewManagerTest,
442 ViewManagerDestroyed_CleanupNodeAndViewFromDifferentConnections) { 470 ViewManagerDestroyed_CleanupNodeAndViewFromDifferentConnections) {
443 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); 471 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
444 TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2); 472 WaitForTreeSizeToMatch(view_manager_2()->tree(), 2);
445 473
446 View* view1_2 = View::Create(view_manager_2()); 474 View* view1_2 = View::Create(view_manager_2());
447 ViewTreeNode* node1_2 = view_manager_2()->tree()->GetChildById(node1->id()); 475 ViewTreeNode* node1_2 = view_manager_2()->tree()->GetChildById(node1->id());
448 node1_2->SetActiveView(view1_2); 476 node1_2->SetActiveView(view1_2);
449 477 WaitForActiveViewToChange(node1);
450 {
451 ActiveViewChangedWaiter active_view_waiter(node1);
452 }
453 478
454 TransportNodeId node1_id = node1->id(); 479 TransportNodeId node1_id = node1->id();
455 TransportViewId view1_2_id = view1_2->id(); 480 TransportViewId view1_2_id = view1_2->id();
456 481
457 DestroyViewManager1(); 482 DestroyViewManager1();
458 std::set<TransportNodeId> nodes; 483 std::set<TransportNodeId> nodes;
459 nodes.insert(node1_id); 484 nodes.insert(node1_id);
460 DestructionWaiter destruction_waiter(view_manager_2(), &nodes, NULL); 485 WaitForDestruction(view_manager_2(), &nodes, NULL);
461 486
462 // tree() should still be valid, since it's owned by neither connection. 487 // tree() should still be valid, since it's owned by neither connection.
463 EXPECT_TRUE(view_manager_2()->tree()->children().empty()); 488 EXPECT_TRUE(view_manager_2()->tree()->children().empty());
464 // node1 was owned by the first connection, so it should be gone. 489 // node1 was owned by the first connection, so it should be gone.
465 EXPECT_EQ(NULL, view_manager_2()->GetNodeById(node1_id)); 490 EXPECT_EQ(NULL, view_manager_2()->GetNodeById(node1_id));
466 // view1_2 was owned by the second connection, so it should still exist, but 491 // view1_2 was owned by the second connection, so it should still exist, but
467 // disconnected from the node tree. 492 // disconnected from the node tree.
468 View* another_view1_2 = view_manager_2()->GetViewById(view1_2_id); 493 View* another_view1_2 = view_manager_2()->GetViewById(view1_2_id);
469 EXPECT_EQ(view1_2, another_view1_2); 494 EXPECT_EQ(view1_2, another_view1_2);
470 EXPECT_EQ(NULL, view1_2->node()); 495 EXPECT_EQ(NULL, view1_2->node());
471 } 496 }
472 497
473 // This test verifies that it is not possible to set the active view to a view 498 // This test verifies that it is not possible to set the active view to a view
474 // defined in a different connection. 499 // defined in a different connection.
475 // TODO(beng): write these tests for ViewTreeNode::AddChild(), RemoveChild() and 500 // TODO(beng): write these tests for ViewTreeNode::AddChild(), RemoveChild() and
476 // Contains(). 501 // Contains().
477 TEST_F(ViewManagerTest, SetActiveViewAcrossConnection) { 502 TEST_F(ViewManagerTest, SetActiveViewAcrossConnection) {
478 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree()); 503 ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
479 TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2); 504 WaitForTreeSizeToMatch(view_manager_2()->tree(), 2);
480 505
481 View* view1_2 = View::Create(view_manager_2()); 506 View* view1_2 = View::Create(view_manager_2());
482 EXPECT_DEATH(node1->SetActiveView(view1_2), ""); 507 EXPECT_DEATH(node1->SetActiveView(view1_2), "");
483 } 508 }
484 509
510 // This test verifies that a node hierarchy constructed in one connection
511 // becomes entirely visible to the second connection when the hierarchy is
512 // attached.
513 TEST_F(ViewManagerTest, MapSubtreeOnAttach) {
514 ViewTreeNode* node1 = ViewTreeNode::Create(view_manager_1());
515 ViewTreeNode* node11 = CreateNodeInParent(node1);
516 View* view11 = View::Create(view_manager_1());
517 node11->SetActiveView(view11);
518 WaitForAllChangesToBeAcked(view_manager_1());
519
520 // Now attach this node tree to the root & wait for it to show up in the
521 // second connection.
522 view_manager_1()->tree()->AddChild(node1);
523 WaitForTreeSizeToMatch(view_manager_2()->tree(), 3);
524
525 ViewTreeNode* node11_2 = view_manager_2()->GetNodeById(node11->id());
526 View* view11_2 = view_manager_2()->GetViewById(view11->id());
527 EXPECT_TRUE(node11_2 != NULL);
528 EXPECT_EQ(view11_2, node11_2->active_view());
529 }
530
485 } // namespace view_manager 531 } // namespace view_manager
486 } // namespace mojo 532 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698