1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file.
4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "mojo/services/public/cpp/view_manager/view_manager.h"
6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/auto_reset.h"
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/bind.h"
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/logging.h"
1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "mojo/public/cpp/application/application.h"
1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "mojo/service_manager/service_manager.h"
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "mojo/services/public/cpp/view_manager/lib/node_private.h"
13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h"
14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "mojo/services/public/cpp/view_manager/node_observer.h"
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "mojo/services/public/cpp/view_manager/util.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "mojo/services/public/cpp/view_manager/view.h"
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "mojo/services/public/cpp/view_manager/view_observer.h"
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "mojo/shell/shell_test_helper.h"
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace mojo {
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace view_manager {
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kWindowManagerURL[] = "mojo:window_manager";
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kEmbeddedApp1URL[] = "mojo:embedded_app_1";
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::RunLoop* current_run_loop = NULL;
30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DoRunLoop() {
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::RunLoop run_loop;
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_run_loop = &run_loop;
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_run_loop->Run();
35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_run_loop = NULL;
36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void QuitRunLoop() {
39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_run_loop->Quit();
40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WaitForAllChangesToBeAcked(ViewManagerClientImpl* client) {
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  client->set_changes_acked_callback(base::Bind(&QuitRunLoop));
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DoRunLoop();
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  client->ClearChangesAckedCallback();
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ConnectServiceLoader : public ServiceLoader,
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                             public ViewManagerDelegate {
5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  typedef base::Callback<void(ViewManager*, Node*)> LoadedCallback;
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit ConnectServiceLoader(const LoadedCallback& callback)
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      : callback_(callback) {
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual ~ConnectServiceLoader() {}
5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Overridden from ServiceLoader:
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void LoadService(ServiceManager* manager,
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                           const GURL& url,
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                           ScopedMessagePipeHandle shell_handle) OVERRIDE {
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<Application> app(new Application(shell_handle.Pass()));
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ViewManager::Create(app.get(), this);
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    apps_.push_back(app.release());
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual void OnServiceError(ServiceManager* manager,
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                              const GURL& url) OVERRIDE {
6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Overridden from ViewManagerDelegate:
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void OnRootAdded(ViewManager* view_manager,
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           Node* root) OVERRIDE {
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    callback_.Run(view_manager, root);
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ScopedVector<Application> apps_;
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  LoadedCallback callback_;
7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ConnectServiceLoader);
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)};
8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ActiveViewChangedObserver : public NodeObserver {
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit ActiveViewChangedObserver(Node* node)
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : node_(node) {}
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~ActiveViewChangedObserver() {}
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Overridden from NodeObserver:
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void OnNodeActiveViewChange(Node* node,
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      View* old_view,
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      View* new_view,
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      DispositionChangePhase phase) OVERRIDE {
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK_EQ(node, node_);
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    QuitRunLoop();
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node_;
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ActiveViewChangedObserver);
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Waits until the active view id of the supplied node changes.
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WaitForActiveViewToChange(Node* node) {
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ActiveViewChangedObserver observer(node);
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  node->AddObserver(&observer);
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DoRunLoop();
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  node->RemoveObserver(&observer);
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class BoundsChangeObserver : public NodeObserver {
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit BoundsChangeObserver(Node* node) : node_(node) {}
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~BoundsChangeObserver() {}
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Overridden from NodeObserver:
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void OnNodeBoundsChange(Node* node,
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  const gfx::Rect& old_bounds,
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  const gfx::Rect& new_bounds,
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  DispositionChangePhase phase) OVERRIDE {
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK_EQ(node, node_);
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (phase != NodeObserver::DISPOSITION_CHANGED)
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return;
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    QuitRunLoop();
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node_;
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BoundsChangeObserver);
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Wait until the bounds of the supplied node change.
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WaitForBoundsToChange(Node* node) {
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  BoundsChangeObserver observer(node);
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  node->AddObserver(&observer);
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DoRunLoop();
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  node->RemoveObserver(&observer);
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Spins a runloop until the tree beginning at |root| has |tree_size| nodes
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// (including |root|).
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class TreeSizeMatchesObserver : public NodeObserver {
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  TreeSizeMatchesObserver(Node* tree, size_t tree_size)
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : tree_(tree),
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        tree_size_(tree_size) {}
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~TreeSizeMatchesObserver() {}
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool IsTreeCorrectSize() {
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return CountNodes(tree_) == tree_size_;
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Overridden from NodeObserver:
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnTreeChange(const TreeChangeParams& params) OVERRIDE {
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (IsTreeCorrectSize())
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      QuitRunLoop();
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  size_t CountNodes(const Node* node) const {
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    size_t count = 1;
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    Node::Children::const_iterator it = node->children().begin();
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (; it != node->children().end(); ++it)
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      count += CountNodes(*it);
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return count;
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* tree_;
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t tree_size_;
17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TreeSizeMatchesObserver);
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WaitForTreeSizeToMatch(Node* node, size_t tree_size) {
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TreeSizeMatchesObserver observer(node, tree_size);
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (observer.IsTreeCorrectSize())
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  node->AddObserver(&observer);
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DoRunLoop();
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  node->RemoveObserver(&observer);
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Utility class that waits for the destruction of some number of nodes and
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// views.
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class DestructionObserver : public NodeObserver, public ViewObserver {
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // |nodes| or |views| can be NULL.
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DestructionObserver(std::set<Id>* nodes, std::set<Id>* views)
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : nodes_(nodes),
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        views_(views) {}
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Overridden from NodeObserver:
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnNodeDestroy(
198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      Node* node,
199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      NodeObserver::DispositionChangePhase phase) OVERRIDE {
200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (phase != NodeObserver::DISPOSITION_CHANGED)
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return;
2026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    std::set<Id>::iterator it = nodes_->find(node->id());
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (it != nodes_->end())
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      nodes_->erase(it);
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (CanQuit())
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      QuitRunLoop();
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Overridden from ViewObserver:
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnViewDestroy(
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      View* view,
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ViewObserver::DispositionChangePhase phase) OVERRIDE {
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (phase != ViewObserver::DISPOSITION_CHANGED)
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return;
2156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    std::set<Id>::iterator it = views_->find(view->id());
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (it != views_->end())
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      views_->erase(it);
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (CanQuit())
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      QuitRunLoop();
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool CanQuit() {
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return (!nodes_ || nodes_->empty()) && (!views_ || views_->empty());
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::set<Id>* nodes_;
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::set<Id>* views_;
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DestructionObserver);
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WaitForDestruction(ViewManager* view_manager,
233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        std::set<Id>* nodes,
234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        std::set<Id>* views) {
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DestructionObserver observer(nodes, views);
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(nodes || views);
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (nodes) {
238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    for (std::set<Id>::const_iterator it = nodes->begin();
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          it != nodes->end(); ++it) {
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      view_manager->GetNodeById(*it)->AddObserver(&observer);
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (views) {
244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    for (std::set<Id>::const_iterator it = views->begin();
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          it != views->end(); ++it) {
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      view_manager->GetViewById(*it)->AddObserver(&observer);
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DoRunLoop();
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class OrderChangeObserver : public NodeObserver {
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OrderChangeObserver(Node* node) : node_(node) {
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    node_->AddObserver(this);
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~OrderChangeObserver() {
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    node_->RemoveObserver(this);
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Overridden from NodeObserver:
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual void OnNodeReordered(Node* node,
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                               Node* relative_node,
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                               OrderDirection direction,
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                               DispositionChangePhase phase) OVERRIDE {
267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (phase != NodeObserver::DISPOSITION_CHANGED)
268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return;
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DCHECK_EQ(node, node_);
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    QuitRunLoop();
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node_;
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OrderChangeObserver);
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WaitForOrderChange(ViewManager* view_manager, Node* node) {
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OrderChangeObserver observer(node);
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DoRunLoop();
282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Tracks a node's destruction. Query is_valid() for current state.
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class NodeTracker : public NodeObserver {
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit NodeTracker(Node* node) : node_(node) {
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    node_->AddObserver(this);
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~NodeTracker() {
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (node_)
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      node_->RemoveObserver(this);
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool is_valid() const { return !!node_; }
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Overridden from NodeObserver:
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnNodeDestroy(
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      Node* node,
301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      NodeObserver::DispositionChangePhase phase) OVERRIDE {
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (phase != NodeObserver::DISPOSITION_CHANGED)
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return;
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK_EQ(node, node_);
305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    node_ = NULL;
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int id_;
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node_;
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NodeTracker);
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
316010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// ViewManager -----------------------------------------------------------------
317010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
3180de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// These tests model synchronization of two peer connections to the view manager
3190de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// service, that are given access to some root node.
3200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
321010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class ViewManagerTest : public testing::Test {
322010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public:
32346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManagerTest()
32446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      : connect_loop_(NULL),
32546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        loaded_view_manager_(NULL),
32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        window_manager_(NULL),
32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        commit_count_(0) {}
328010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) protected:
33046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* window_manager() { return window_manager_; }
331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* CreateNodeInParent(Node* parent) {
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ViewManager* parent_manager = NodePrivate(parent).view_manager();
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    Node* node = Node::Create(parent_manager);
3350de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    parent->AddChild(node);
3360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)    return node;
3370de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
3380de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Embeds another version of the test app @ node.
340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ViewManager* Embed(ViewManager* view_manager, Node* node) {
341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DCHECK_EQ(view_manager, NodePrivate(node).view_manager());
34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    node->Embed(kEmbeddedApp1URL);
34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    RunRunLoop();
34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return GetLoadedViewManager();
34546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
34746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // TODO(beng): remove these methods once all the tests are migrated.
34846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void DestroyViewManager1() {}
34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* view_manager_1() { return NULL; }
35046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* view_manager_2() { return NULL; }
35146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
35246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* GetLoadedViewManager() {
35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ViewManager* view_manager = loaded_view_manager_;
35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    loaded_view_manager_ = NULL;
35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return view_manager;
35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
35846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void UnloadApplication(const GURL& url) {
35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    test_helper_.SetLoaderForURL(scoped_ptr<ServiceLoader>(), url);
360010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
361010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
362010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private:
363010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Overridden from testing::Test:
364010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ConnectServiceLoader::LoadedCallback ready_callback =
36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        base::Bind(&ViewManagerTest::OnViewManagerLoaded,
36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Unretained(this));
368010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    test_helper_.Init();
36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    test_helper_.SetLoaderForURL(
37046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        scoped_ptr<ServiceLoader>(new ConnectServiceLoader(ready_callback)),
37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        GURL(kWindowManagerURL));
37246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    test_helper_.SetLoaderForURL(
37346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        scoped_ptr<ServiceLoader>(new ConnectServiceLoader(ready_callback)),
37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        GURL(kEmbeddedApp1URL));
37546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ConnectToService(test_helper_.service_provider(),
37746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     "mojo:mojo_view_manager",
37846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                     &view_manager_init_);
379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ASSERT_TRUE(EmbedRoot(view_manager_init_.get(), kWindowManagerURL));
380010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
381010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
382f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void EmbedRootCallback(bool* result_cache, bool result) {
38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    *result_cache = result;
384010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
385010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
386f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool EmbedRoot(ViewManagerInitService* view_manager_init,
387f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 const std::string& url) {
38846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    bool result = false;
389f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    view_manager_init->EmbedRoot(
39046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        url,
391f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&ViewManagerTest::EmbedRootCallback, base::Unretained(this),
392f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   &result));
39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    RunRunLoop();
39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    window_manager_ = GetLoadedViewManager();
39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return result;
396010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
397010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
398f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void OnViewManagerLoaded(ViewManager* view_manager, Node* root) {
39946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    loaded_view_manager_ = view_manager;
40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    connect_loop_->Quit();
401010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
402010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void RunRunLoop() {
40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    base::RunLoop run_loop;
40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    connect_loop_ = &run_loop;
40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    connect_loop_->Run();
40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    connect_loop_ = NULL;
408010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
409010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
41046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::MessageLoop loop_;
41146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::RunLoop* connect_loop_;
41246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  shell::ShellTestHelper test_helper_;
413f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ViewManagerInitServicePtr view_manager_init_;
41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Used to receive the most recent view manager loaded by an embed action.
41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* loaded_view_manager_;
41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The View Manager connection held by the window manager (app running at the
41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // root node).
41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* window_manager_;
41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int commit_count_;
420010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
42146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ViewManagerTest);
422010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
423010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
42446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, SetUp) {}
425010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
42646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, Embed) {
427f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
428f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
42946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
43046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(NULL != embedded);
431010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
432f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node_in_embedded = embedded->GetRoots().front();
433f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(node->parent(), window_manager()->GetRoots().front());
43446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(NULL, node_in_embedded->parent());
435010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
436010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// When Window Manager embeds A @ N, then creates N2 and parents to N, N becomes
43846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// visible to A.
43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// TODO(beng): verify whether or not this is a policy we like.
44046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, HierarchyChanged_NodeAdded) {
441f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
442f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
44346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
444f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* nested = Node::Create(window_manager());
44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node->AddChild(nested);
446f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  WaitForTreeSizeToMatch(embedded->GetRoots().front(), 2);
447f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(embedded->GetRoots().front()->children().front()->id(),
448f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            nested->id());
44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
4500de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Window manager has two nodes, N1 & N2. Embeds A at N1. Creates node N21,
45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// a child of N2. Reparents N2 to N1. N1 should become visible to A.
45346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// TODO(beng): verify whether or not this is a policy we like.
45446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, HierarchyChanged_NodeMoved) {
455f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node1 = Node::Create(window_manager());
456f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node1);
45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node1);
458f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  WaitForTreeSizeToMatch(embedded->GetRoots().front(), 1);
45946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
460f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node2 = Node::Create(window_manager());
461f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node2);
462f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  WaitForTreeSizeToMatch(embedded->GetRoots().front(), 1);
463f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(embedded->GetRoots().front()->children().empty());
46446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
465f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node21 = Node::Create(window_manager());
46646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node2->AddChild(node21);
467f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  WaitForTreeSizeToMatch(embedded->GetRoots().front(), 1);
468f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(embedded->GetRoots().front()->children().empty());
46946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
47046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Makes node21 visible to |embedded|.
47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node1->AddChild(node21);
472f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  WaitForTreeSizeToMatch(embedded->GetRoots().front(), 2);
473f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(embedded->GetRoots().front()->children().empty());
474f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(embedded->GetRoots().front()->children().front()->id(),
475f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            node21->id());
47646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
4770de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
47846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Window manager has two nodes, N1 and N11. Embeds A at N1. Removes N11 from
47946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// N1. N11 should disappear from A.
48046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// TODO(beng): verify whether or not this is a policy we like.
48146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, HierarchyChanged_NodeRemoved) {
482f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
483f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
484f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* nested = Node::Create(window_manager());
48546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node->AddChild(nested);
48646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
48746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
488f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(embedded->GetRoots().front()->children().front()->id(),
489f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            nested->id());
49046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
49146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node->RemoveChild(nested);
492f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  WaitForTreeSizeToMatch(embedded->GetRoots().front(), 1);
493f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(embedded->GetRoots().front()->children().empty());
4940de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)}
4950de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
49646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Window manager has two nodes, N1 and N11. Embeds A at N1. Destroys N11.
49746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// N11 should disappear from A.
49846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// TODO(beng): verify whether or not this is a policy we like.
49946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, NodeDestroyed) {
500f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
501f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
502f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* nested = Node::Create(window_manager());
50346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node->AddChild(nested);
5040de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
50546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
506f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(embedded->GetRoots().front()->children().front()->id(),
507f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            nested->id());
50846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
50946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // |nested| will be deleted after calling Destroy() below.
510f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Id id = nested->id();
51146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  nested->Destroy();
5120de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
513f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::set<Id> nodes;
514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  nodes.insert(id);
51546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WaitForDestruction(embedded, &nodes, NULL);
5160de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
517f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(embedded->GetRoots().front()->children().empty());
51846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(NULL, embedded->GetNodeById(id));
519cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
5200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
52146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, ViewManagerDestroyed_CleanupNode) {
522f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
523f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
52446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
52546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
526f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Id node_id = node->id();
52746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
52846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  UnloadApplication(GURL(kWindowManagerURL));
5290de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
530f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::set<Id> nodes;
53146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  nodes.insert(node_id);
53246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WaitForDestruction(embedded, &nodes, NULL);
5330de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
534f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(embedded->GetRoots().empty());
5350de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)}
5360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
53746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, SetActiveView) {
538f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
539f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
54046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
541cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
54246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  View* view = View::Create(window_manager());
54346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node->SetActiveView(view);
544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
545f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node_in_embedded = embedded->GetNodeById(node->id());
54646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WaitForActiveViewToChange(node_in_embedded);
547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
54846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(node_in_embedded->active_view()->id(), view->id());
549cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
55146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, DestroyView) {
552f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
553f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
55446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
55546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
55646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  View* view = View::Create(window_manager());
55746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node->SetActiveView(view);
558cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
559f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node_in_embedded = embedded->GetNodeById(node->id());
56046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WaitForActiveViewToChange(node_in_embedded);
561cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
56246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(node_in_embedded->active_view()->id(), view->id());
563cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
564f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Id view_id = view->id();
56546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  view->Destroy();
566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
567f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::set<Id> views;
56846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  views.insert(view_id);
56946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WaitForDestruction(embedded, NULL, &views);
57046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(NULL, node_in_embedded->active_view());
57146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(NULL, embedded->GetViewById(view_id));
572cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
573cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
574cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Destroying the connection that created a node and view should result in that
575cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// node and view disappearing from all connections that see them.
57646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, ViewManagerDestroyed_CleanupNodeAndView) {
577f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
578f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
57946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  View* view = View::Create(window_manager());
58046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node->SetActiveView(view);
58146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
583f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Id node_id = node->id();
584f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Id view_id = view->id();
585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
58646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  UnloadApplication(GURL(kWindowManagerURL));
587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
588f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::set<Id> observed_nodes;
58946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  observed_nodes.insert(node_id);
590f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::set<Id> observed_views;
59146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  observed_views.insert(view_id);
59246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WaitForDestruction(embedded, &observed_nodes, &observed_views);
593cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
594f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(embedded->GetRoots().empty());
59546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(NULL, embedded->GetNodeById(node_id));
59646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(NULL, embedded->GetViewById(view_id));
597cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
598cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
599cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This test validates the following scenario:
600cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// -  a node originating from one connection
601cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// -  a view originating from a second connection
602cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// +  the connection originating the node is destroyed
603cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// -> the view should still exist (since the second connection is live) but
604cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//    should be disconnected from any nodes.
605cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(ViewManagerTest,
60646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)       ViewManagerDestroyed_CleanupNodeAndViewFromDifferentConnections) {
607f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
608f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
60946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
61046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  View* view_in_embedded = View::Create(embedded);
611f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node_in_embedded = embedded->GetNodeById(node->id());
61246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node_in_embedded->SetActiveView(view_in_embedded);
613cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
61446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WaitForActiveViewToChange(node);
615cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
616f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Id node_id = node->id();
617f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Id view_id = view_in_embedded->id();
6180de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
61946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  UnloadApplication(GURL(kWindowManagerURL));
620f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::set<Id> nodes;
62146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  nodes.insert(node_id);
62246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WaitForDestruction(embedded, &nodes, NULL);
62346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
624f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(embedded->GetRoots().empty());
62546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // node was owned by the window manager, so it should be gone.
62646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(NULL, embedded->GetNodeById(node_id));
62746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // view_in_embedded was owned by the embedded app, so it should still exist,
62846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // but disconnected from the node tree.
62946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(view_in_embedded, embedded->GetViewById(view_id));
63046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(NULL, view_in_embedded->node());
631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
632cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
633cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This test verifies that it is not possible to set the active view to a view
634cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// defined in a different connection.
635f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// TODO(beng): write these tests for Node::AddChild(), RemoveChild() and
636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//             Contains().
63746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, SetActiveViewAcrossConnection) {
638f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
639f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
64046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
64246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  View* view_in_embedded = View::Create(embedded);
64346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_DEATH(node->SetActiveView(view_in_embedded), "");
644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
646cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This test verifies that a node hierarchy constructed in one connection
647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// becomes entirely visible to the second connection when the hierarchy is
648cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// attached.
64946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, MapSubtreeOnAttach) {
650f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
651f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
65246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
65346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
65446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Create a subtree private to the window manager and make some changes to it.
655f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* child1 = Node::Create(window_manager());
656f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* child11 = Node::Create(window_manager());
65746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  child1->AddChild(child11);
65846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  gfx::Rect child11_bounds(800, 600);
65946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  child11->SetBounds(child11_bounds);
66046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  View* view11 = View::Create(window_manager());
66146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  child11->SetActiveView(view11);
662f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  WaitForAllChangesToBeAcked(
663f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      static_cast<ViewManagerClientImpl*>(window_manager()));
66446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
66546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // When added to the shared node, the entire hierarchy and all property
66646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // changes should become visible to the embedded app.
66746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node->AddChild(child1);
668f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  WaitForTreeSizeToMatch(embedded->GetRoots().front(), 3);
66946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
670f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* child11_in_embedded = embedded->GetNodeById(child11->id());
67146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  View* view11_in_embedded = embedded->GetViewById(view11->id());
67246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(child11_in_embedded != NULL);
67346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(view11_in_embedded, child11_in_embedded->active_view());
67446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(child11_bounds, child11_in_embedded->bounds());
675cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Verifies that bounds changes applied to a node hierarchy in one connection
678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// are reflected to another.
67946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, SetBounds) {
680f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
681f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
68246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
68346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
684f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node_in_embedded = embedded->GetNodeById(node->id());
68546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(node->bounds(), node_in_embedded->bounds());
68646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
68746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node->SetBounds(gfx::Rect(100, 100));
68846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_NE(node->bounds(), node_in_embedded->bounds());
68946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WaitForBoundsToChange(node_in_embedded);
69046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(node->bounds(), node_in_embedded->bounds());
691cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
692cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
693cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Verifies that bounds changes applied to a node owned by a different
694cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// connection are refused.
69546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, SetBoundsSecurity) {
696f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
697f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
69846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
69946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
700f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node_in_embedded = embedded->GetNodeById(node->id());
70146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node->SetBounds(gfx::Rect(800, 600));
70246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  WaitForBoundsToChange(node_in_embedded);
703cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
70446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node_in_embedded->SetBounds(gfx::Rect(1024, 768));
705cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Bounds change should have been rejected.
70646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(node->bounds(), node_in_embedded->bounds());
707cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
708cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
709cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Verifies that a node can only be destroyed by the connection that created it.
71046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, DestroySecurity) {
711f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
712f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
71346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
71446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
715f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node_in_embedded = embedded->GetNodeById(node->id());
716cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
71746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NodeTracker tracker2(node_in_embedded);
71846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node_in_embedded->Destroy();
719cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Node should not have been destroyed.
720cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(tracker2.is_valid());
721cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
72246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  NodeTracker tracker1(node);
72346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  node->Destroy();
724cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(tracker1.is_valid());
7250de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)}
726010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
72746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, MultiRoots) {
728f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node1 = Node::Create(window_manager());
729f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node1);
730f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node2 = Node::Create(window_manager());
731f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node2);
73246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded1 = Embed(window_manager(), node1);
73346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* embedded2 = Embed(window_manager(), node2);
73446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(embedded1, embedded2);
73546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
73646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
737f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ViewManagerTest, EmbeddingIdentity) {
738f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node = Node::Create(window_manager());
739f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node);
740f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node);
741f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(kWindowManagerURL, embedded->GetEmbedderURL());
742f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
743f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
744f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ViewManagerTest, Reorder) {
745f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node1 = Node::Create(window_manager());
746f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(node1);
747f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
748f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node11 = Node::Create(window_manager());
749f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  node1->AddChild(node11);
750f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node12 = Node::Create(window_manager());
751f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  node1->AddChild(node12);
752f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
753f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), node1);
754f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
755f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Node* node1_in_embedded = embedded->GetNodeById(node1->id());
756f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
757f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  {
758f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    node11->MoveToFront();
759f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    WaitForOrderChange(embedded, embedded->GetNodeById(node11->id()));
760f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
761f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(node1_in_embedded->children().front(),
762f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              embedded->GetNodeById(node12->id()));
763f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(node1_in_embedded->children().back(),
764f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              embedded->GetNodeById(node11->id()));
765f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
766f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
767f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  {
768f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    node11->MoveToBack();
769f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    WaitForOrderChange(embedded, embedded->GetNodeById(node11->id()));
770f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
771f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(node1_in_embedded->children().front(),
772f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              embedded->GetNodeById(node11->id()));
773f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(node1_in_embedded->children().back(),
774f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              embedded->GetNodeById(node12->id()));
775f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
776f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
777f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
778010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace view_manager
779010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace mojo
780