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"
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/application_manager/application_manager.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/application/application_connection.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/application/application_delegate.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/application/application_impl.h"
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/public/cpp/application/service_provider_impl.h"
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/public/interfaces/application/service_provider.mojom.h"
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h"
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/services/public/cpp/view_manager/lib/view_private.h"
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "mojo/services/public/cpp/view_manager/util.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "mojo/services/public/cpp/view_manager/view_observer.h"
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "mojo/shell/shell_test_helper.h"
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace mojo {
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kWindowManagerURL[] = "mojo:window_manager";
2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kEmbeddedApp1URL[] = "mojo:embedded_app_1";
3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::RunLoop* current_run_loop = NULL;
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DoRunLoop() {
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  base::RunLoop run_loop;
35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_run_loop = &run_loop;
36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_run_loop->Run();
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_run_loop = NULL;
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void QuitRunLoop() {
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  current_run_loop->Quit();
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class ConnectApplicationLoader : public ApplicationLoader,
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 public ApplicationDelegate,
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 public ViewManagerDelegate {
4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public:
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  typedef base::Callback<void(ViewManager*, View*)> LoadedCallback;
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  explicit ConnectApplicationLoader(const LoadedCallback& callback)
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : callback_(callback) {}
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual ~ConnectApplicationLoader() {}
5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private:
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Overridden from ApplicationDelegate:
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void Initialize(ApplicationImpl* app) MOJO_OVERRIDE {
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    view_manager_client_factory_.reset(
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new ViewManagerClientFactory(app->shell(), this));
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Overridden from ApplicationLoader:
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void Load(ApplicationManager* manager,
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    const GURL& url,
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    scoped_refptr<LoadCallbacks> callbacks) OVERRIDE {
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ScopedMessagePipeHandle shell_handle = callbacks->RegisterApplication();
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!shell_handle.is_valid())
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return;
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_ptr<ApplicationImpl> app(new ApplicationImpl(this,
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                        shell_handle.Pass()));
7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    apps_.push_back(app.release());
7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnApplicationError(ApplicationManager* manager,
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  const GURL& url) OVERRIDE {}
7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual bool ConfigureIncomingConnection(ApplicationConnection* connection)
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      OVERRIDE {
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    connection->AddService(view_manager_client_factory_.get());
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return true;
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Overridden from ViewManagerDelegate:
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void OnEmbed(ViewManager* view_manager,
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                       View* root,
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                       ServiceProviderImpl* exported_services,
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                       scoped_ptr<ServiceProvider> imported_services) OVERRIDE {
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    callback_.Run(view_manager, root);
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnViewManagerDisconnected(ViewManager* view_manager) OVERRIDE {}
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScopedVector<ApplicationImpl> apps_;
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  LoadedCallback callback_;
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_;
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ConnectApplicationLoader);
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class BoundsChangeObserver : public ViewObserver {
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  explicit BoundsChangeObserver(View* view) : view_(view) {}
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~BoundsChangeObserver() {}
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Overridden from ViewObserver:
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void OnViewBoundsChanged(View* view,
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   const gfx::Rect& old_bounds,
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   const gfx::Rect& new_bounds) OVERRIDE {
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    DCHECK_EQ(view, view_);
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    QuitRunLoop();
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view_;
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BoundsChangeObserver);
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Wait until the bounds of the supplied view change.
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void WaitForBoundsToChange(View* view) {
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  BoundsChangeObserver observer(view);
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  view->AddObserver(&observer);
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DoRunLoop();
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  view->RemoveObserver(&observer);
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Spins a runloop until the tree beginning at |root| has |tree_size| views
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// (including |root|).
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class TreeSizeMatchesObserver : public ViewObserver {
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TreeSizeMatchesObserver(View* tree, size_t tree_size)
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : tree_(tree),
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        tree_size_(tree_size) {}
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~TreeSizeMatchesObserver() {}
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool IsTreeCorrectSize() {
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return CountViews(tree_) == tree_size_;
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Overridden from ViewObserver:
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnTreeChanged(const TreeChangeParams& params) OVERRIDE {
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (IsTreeCorrectSize())
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      QuitRunLoop();
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  size_t CountViews(const View* view) const {
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    size_t count = 1;
1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    View::Children::const_iterator it = view->children().begin();
1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    for (; it != view->children().end(); ++it)
1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      count += CountViews(*it);
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return count;
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* tree_;
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  size_t tree_size_;
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TreeSizeMatchesObserver);
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void WaitForTreeSizeToMatch(View* view, size_t tree_size) {
1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TreeSizeMatchesObserver observer(view, tree_size);
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (observer.IsTreeCorrectSize())
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
1636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  view->AddObserver(&observer);
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DoRunLoop();
1656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  view->RemoveObserver(&observer);
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Utility class that waits for the destruction of some number of views and
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// views.
1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class DestructionObserver : public ViewObserver {
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // |views| or |views| can be NULL.
1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  explicit DestructionObserver(std::set<Id>* views) : views_(views) {}
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Overridden from ViewObserver:
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnViewDestroyed(View* view) OVERRIDE {
1786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    std::set<Id>::iterator it = views_->find(view->id());
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (it != views_->end())
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      views_->erase(it);
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (CanQuit())
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      QuitRunLoop();
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool CanQuit() {
1866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return !views_ || views_->empty();
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::set<Id>* views_;
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DestructionObserver);
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void WaitForDestruction(ViewManager* view_manager, std::set<Id>* views) {
1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DestructionObserver observer(views);
1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(views);
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (views) {
198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    for (std::set<Id>::const_iterator it = views->begin();
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          it != views->end(); ++it) {
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      view_manager->GetViewById(*it)->AddObserver(&observer);
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DoRunLoop();
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class OrderChangeObserver : public ViewObserver {
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  OrderChangeObserver(View* view) : view_(view) {
2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    view_->AddObserver(this);
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~OrderChangeObserver() {
2126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    view_->RemoveObserver(this);
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
2166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Overridden from ViewObserver:
2176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void OnViewReordered(View* view,
2186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                               View* relative_view,
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               OrderDirection direction) OVERRIDE {
2206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    DCHECK_EQ(view, view_);
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    QuitRunLoop();
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view_;
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OrderChangeObserver);
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void WaitForOrderChange(ViewManager* view_manager, View* view) {
2306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  OrderChangeObserver observer(view);
231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DoRunLoop();
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Tracks a view's destruction. Query is_valid() for current state.
2356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class ViewTracker : public ViewObserver {
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  explicit ViewTracker(View* view) : view_(view) {
2386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    view_->AddObserver(this);
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual ~ViewTracker() {
2416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (view_)
2426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      view_->RemoveObserver(this);
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  bool is_valid() const { return !!view_; }
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
2486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Overridden from ViewObserver:
2496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void OnViewDestroyed(View* view) OVERRIDE {
2506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    DCHECK_EQ(view, view_);
2516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    view_ = NULL;
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int id_;
2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view_;
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ViewTracker);
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// ViewManager -----------------------------------------------------------------
263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2640de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// These tests model synchronization of two peer connections to the view manager
2656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// service, that are given access to some root view.
2660de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class ViewManagerTest : public testing::Test {
268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public:
26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManagerTest()
27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      : connect_loop_(NULL),
27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        loaded_view_manager_(NULL),
27246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        window_manager_(NULL),
27346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        commit_count_(0) {}
274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) protected:
27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* window_manager() { return window_manager_; }
277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* CreateViewInParent(View* parent) {
2796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ViewManager* parent_manager = ViewPrivate(parent).view_manager();
2806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    View* view = View::Create(parent_manager);
2816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    parent->AddChild(view);
2826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return view;
2830de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  }
2840de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
2856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Embeds another version of the test app @ view.
2866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewManager* Embed(ViewManager* view_manager, View* view) {
2876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    DCHECK_EQ(view_manager, ViewPrivate(view).view_manager());
2886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    view->Embed(kEmbeddedApp1URL);
28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    RunRunLoop();
29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return GetLoadedViewManager();
29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* GetLoadedViewManager() {
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ViewManager* view_manager = loaded_view_manager_;
29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    loaded_view_manager_ = NULL;
29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return view_manager;
29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void UnloadApplication(const GURL& url) {
3006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    test_helper_.SetLoaderForURL(scoped_ptr<ApplicationLoader>(), url);
301010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
302010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
303010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private:
304010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Overridden from testing::Test:
305010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
3066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ConnectApplicationLoader::LoadedCallback ready_callback = base::Bind(
3076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        &ViewManagerTest::OnViewManagerLoaded, base::Unretained(this));
308010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    test_helper_.Init();
30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    test_helper_.SetLoaderForURL(
3106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        scoped_ptr<ApplicationLoader>(
3116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            new ConnectApplicationLoader(ready_callback)),
31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        GURL(kWindowManagerURL));
31346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    test_helper_.SetLoaderForURL(
3146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        scoped_ptr<ApplicationLoader>(
3156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            new ConnectApplicationLoader(ready_callback)),
31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        GURL(kEmbeddedApp1URL));
31746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    test_helper_.application_manager()->ConnectToService(
319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        GURL("mojo:mojo_view_manager"), &view_manager_init_);
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ASSERT_TRUE(EmbedRoot(view_manager_init_.get(), kWindowManagerURL));
321010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
322010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void EmbedRootCallback(bool* result_cache, bool result) {
32446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    *result_cache = result;
325010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
326010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool EmbedRoot(ViewManagerInitService* view_manager_init,
328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 const std::string& url) {
32946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    bool result = false;
3306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ServiceProviderPtr sp;
3316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    BindToProxy(new ServiceProviderImpl, &sp);
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    view_manager_init->Embed(
3336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        url, sp.Pass(),
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&ViewManagerTest::EmbedRootCallback, base::Unretained(this),
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   &result));
33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    RunRunLoop();
33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    window_manager_ = GetLoadedViewManager();
33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return result;
339010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
340010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
3416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void OnViewManagerLoaded(ViewManager* view_manager, View* root) {
34246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    loaded_view_manager_ = view_manager;
34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    connect_loop_->Quit();
344010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
345010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void RunRunLoop() {
34746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    base::RunLoop run_loop;
34846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    connect_loop_ = &run_loop;
34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    connect_loop_->Run();
35046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    connect_loop_ = NULL;
351010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
352010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  base::RunLoop* connect_loop_;
35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  shell::ShellTestHelper test_helper_;
355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ViewManagerInitServicePtr view_manager_init_;
35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Used to receive the most recent view manager loaded by an embed action.
35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* loaded_view_manager_;
35846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // The View Manager connection held by the window manager (app running at the
3596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // root view).
36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ViewManager* window_manager_;
36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int commit_count_;
362010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ViewManagerTest);
364010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
365010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, SetUp) {}
367010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, Embed) {
3696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view = View::Create(window_manager());
3706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(view);
3716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), view);
37246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(NULL != embedded);
373010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
3746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view_in_embedded = embedded->GetRoots().front();
3756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(view->parent(), window_manager()->GetRoots().front());
3766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(NULL, view_in_embedded->parent());
377010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
378010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
3796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Window manager has two views, N1 and N11. Embeds A at N1. A should not see
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// N11.
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// TODO(sky): Update client lib to match server.
3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(ViewManagerTest, DISABLED_EmbeddedDoesntSeeChild) {
3836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view = View::Create(window_manager());
3846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(view);
3856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* nested = View::Create(window_manager());
3866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  view->AddChild(nested);
3870de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
3886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), view);
389f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(embedded->GetRoots().front()->children().front()->id(),
390f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            nested->id());
391f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(embedded->GetRoots().front()->children().empty());
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(nested->parent() == NULL);
393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3940de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// http://crbug.com/396300
3966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ViewManagerTest, DISABLED_ViewManagerDestroyed_CleanupView) {
39746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  View* view = View::Create(window_manager());
3986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(view);
3996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), view);
400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
401f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Id view_id = view->id();
402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  UnloadApplication(GURL(kWindowManagerURL));
404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::set<Id> views;
4066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  views.insert(view_id);
4076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  WaitForDestruction(embedded, &views);
408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
409f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(embedded->GetRoots().empty());
410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// TODO(beng): write a replacement test for the one that once existed here:
413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This test validates the following scenario:
4146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// -  a view originating from one connection
415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// -  a view originating from a second connection
4166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// +  the connection originating the view is destroyed
417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// -> the view should still exist (since the second connection is live) but
4186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//    should be disconnected from any views.
4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// http://crbug.com/396300
4206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//
4216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// TODO(beng): The new test should validate the scenario as described above
4226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//             except that the second connection still has a valid tree.
4230de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
4246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Verifies that bounds changes applied to a view hierarchy in one connection
425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// are reflected to another.
42646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, SetBounds) {
4276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view = View::Create(window_manager());
4286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(view);
4296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), view);
43046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view_in_embedded = embedded->GetViewById(view->id());
4326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(view->bounds(), view_in_embedded->bounds());
43346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  view->SetBounds(gfx::Rect(100, 100));
4356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_NE(view->bounds(), view_in_embedded->bounds());
4366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  WaitForBoundsToChange(view_in_embedded);
4376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(view->bounds(), view_in_embedded->bounds());
438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Verifies that bounds changes applied to a view owned by a different
441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// connection are refused.
44246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, SetBoundsSecurity) {
4436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view = View::Create(window_manager());
4446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(view);
4456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), view);
44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view_in_embedded = embedded->GetViewById(view->id());
4486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  view->SetBounds(gfx::Rect(800, 600));
4496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  WaitForBoundsToChange(view_in_embedded);
450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  view_in_embedded->SetBounds(gfx::Rect(1024, 768));
452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Bounds change should have been rejected.
4536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(view->bounds(), view_in_embedded->bounds());
454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Verifies that a view can only be destroyed by the connection that created it.
45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, DestroySecurity) {
4586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view = View::Create(window_manager());
4596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(view);
4606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), view);
46146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view_in_embedded = embedded->GetViewById(view->id());
463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewTracker tracker2(view_in_embedded);
4656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  view_in_embedded->Destroy();
4666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // View should not have been destroyed.
467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(tracker2.is_valid());
468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewTracker tracker1(view);
4706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  view->Destroy();
471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(tracker1.is_valid());
4720de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)}
473010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
47446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(ViewManagerTest, MultiRoots) {
4756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view1 = View::Create(window_manager());
4766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(view1);
4776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view2 = View::Create(window_manager());
4786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(view2);
4796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewManager* embedded1 = Embed(window_manager(), view1);
4806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewManager* embedded2 = Embed(window_manager(), view2);
48146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(embedded1, embedded2);
48246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
484f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ViewManagerTest, EmbeddingIdentity) {
4856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view = View::Create(window_manager());
4866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(view);
4876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), view);
488f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(kWindowManagerURL, embedded->GetEmbedderURL());
489f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
490f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
491f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(ViewManagerTest, Reorder) {
4926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view1 = View::Create(window_manager());
4936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  window_manager()->GetRoots().front()->AddChild(view1);
494f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
4956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ViewManager* embedded = Embed(window_manager(), view1);
496f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
4976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view11 = View::Create(embedded);
4986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  embedded->GetRoots().front()->AddChild(view11);
4996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view12 = View::Create(embedded);
5006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  embedded->GetRoots().front()->AddChild(view12);
5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  View* view1_in_wm = window_manager()->GetViewById(view1->id());
503f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
504f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  {
5056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    WaitForTreeSizeToMatch(view1, 2u);
5066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    view11->MoveToFront();
5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WaitForOrderChange(window_manager(),
5086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                       window_manager()->GetViewById(view11->id()));
509f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
5106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(view1_in_wm->children().front(),
5116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              window_manager()->GetViewById(view12->id()));
5126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(view1_in_wm->children().back(),
5136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              window_manager()->GetViewById(view11->id()));
514f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
515f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
516f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  {
5176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    view11->MoveToBack();
5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WaitForOrderChange(window_manager(),
5196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                       window_manager()->GetViewById(view11->id()));
520f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
5216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(view1_in_wm->children().front(),
5226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              window_manager()->GetViewById(view11->id()));
5236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(view1_in_wm->children().back(),
5246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              window_manager()->GetViewById(view12->id()));
525f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
526f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
527f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
528116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// TODO(beng): tests for view event dispatcher.
529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// - verify that we see events for all views.
530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// TODO(beng): tests for focus:
5326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// - focus between two views known to a connection
5336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// - focus between views unknown to one of the connections.
5346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// - focus between views unknown to either connection.
535116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
536010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace mojo
537