Commit 11f85951 authored by ben@chromium.org's avatar ben@chromium.org

Revert 270122 "Synchronizes View instances across clients."

> Synchronizes View instances across clients.
> 
> Create/DestroyView
> SetActiveView
> 
> also adds some tests for creating views & nodes across connections, and some preliminary validation that client side objects from different connections can't be used together.
> 
> R=sky@chromium.org
> http://crbug.com/365012
> 
> Review URL: https://codereview.chromium.org/272833002

TBR=ben@chromium.org

Review URL: https://codereview.chromium.org/286653003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270125 0039d316-1c4b-4281-b951-d872f2087c98
parent 6eead0e3
......@@ -153,8 +153,6 @@
],
'sources': [
'services/public/cpp/view_manager/lib/view.cc',
'services/public/cpp/view_manager/lib/view_private.cc',
'services/public/cpp/view_manager/lib/view_private.h',
'services/public/cpp/view_manager/lib/view_manager.cc',
'services/public/cpp/view_manager/lib/view_manager_private.cc',
'services/public/cpp/view_manager/lib/view_manager_private.h',
......@@ -168,7 +166,6 @@
'services/public/cpp/view_manager/view.h',
'services/public/cpp/view_manager/view_manager.h',
'services/public/cpp/view_manager/view_manager_types.h',
'services/public/cpp/view_manager/view_observer.h',
'services/public/cpp/view_manager/view_tree_host.h',
'services/public/cpp/view_manager/view_tree_node.h',
'services/public/cpp/view_manager/view_tree_node_observer.h',
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "mojo/services/public/cpp/view_manager/view.h"
#include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
#include "mojo/services/public/cpp/view_manager/lib/view_private.h"
#include "mojo/services/public/cpp/view_manager/view_observer.h"
namespace mojo {
namespace services {
namespace view_manager {
namespace {
class ScopedDestructionNotifier {
public:
explicit ScopedDestructionNotifier(View* view)
: view_(view) {
FOR_EACH_OBSERVER(
ViewObserver,
*ViewPrivate(view_).observers(),
OnViewDestroy(view_, ViewObserver::DISPOSITION_CHANGING));
}
~ScopedDestructionNotifier() {
FOR_EACH_OBSERVER(
ViewObserver,
*ViewPrivate(view_).observers(),
OnViewDestroy(view_, ViewObserver::DISPOSITION_CHANGED));
}
private:
View* view_;
DISALLOW_COPY_AND_ASSIGN(ScopedDestructionNotifier);
};
} // namespace
// static
View* View::Create(ViewManager* manager) {
View* view = new View(manager);
ViewManagerPrivate(manager).AddView(view->id(), view);
return view;
}
void View::Destroy() {
if (manager_)
ViewManagerPrivate(manager_).synchronizer()->DestroyView(id_);
LocalDestroy();
}
void View::AddObserver(ViewObserver* observer) {
observers_.AddObserver(observer);
}
void View::RemoveObserver(ViewObserver* observer) {
observers_.RemoveObserver(observer);
}
View::View(ViewManager* manager)
: id_(ViewManagerPrivate(manager).synchronizer()->CreateView()),
node_(NULL),
manager_(manager) {}
View::View()
: id_(-1),
node_(NULL),
manager_(NULL) {}
View::~View() {
ScopedDestructionNotifier notifier(this);
if (manager_)
ViewManagerPrivate(manager_).RemoveView(id_);
}
void View::LocalDestroy() {
delete this;
}
} // namespace view_manager
} // namespace services
} // namespace mojo
......@@ -6,7 +6,6 @@
#include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"
#include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
#include "mojo/services/public/cpp/view_manager/view.h"
namespace mojo {
namespace services {
......@@ -23,13 +22,6 @@ ViewManager::~ViewManager() {
else
nodes_.erase(it);
}
while (!views_.empty()) {
IdToViewMap::iterator it = views_.begin();
if (synchronizer_->OwnsView(it->second->id()))
it->second->Destroy();
else
views_.erase(it);
}
}
void ViewManager::Init() {
......@@ -41,11 +33,6 @@ ViewTreeNode* ViewManager::GetNodeById(TransportNodeId id) {
return it != nodes_.end() ? it->second : NULL;
}
View* ViewManager::GetViewById(TransportViewId id) {
IdToViewMap::const_iterator it = views_.find(id);
return it != views_.end() ? it->second : NULL;
}
} // namespace view_manager
} // namespace services
} // namespace mojo
......@@ -13,7 +13,6 @@ ViewManagerPrivate::ViewManagerPrivate(ViewManager* manager)
ViewManagerPrivate::~ViewManagerPrivate() {}
void ViewManagerPrivate::AddNode(TransportNodeId node_id, ViewTreeNode* node) {
DCHECK(!manager_->nodes_[node_id]);
manager_->nodes_[node_id] = node;
}
......@@ -23,17 +22,6 @@ void ViewManagerPrivate::RemoveNode(TransportNodeId node_id) {
manager_->nodes_.erase(it);
}
void ViewManagerPrivate::AddView(TransportViewId view_id, View* view) {
DCHECK(!manager_->views_[view_id]);
manager_->views_[view_id] = view;
}
void ViewManagerPrivate::RemoveView(TransportViewId view_id) {
ViewManager::IdToViewMap::iterator it = manager_->views_.find(view_id);
if (it != manager_->views_.end())
manager_->views_.erase(it);
}
} // namespace view_manager
} // namespace services
} // namespace mojo
......@@ -30,9 +30,6 @@ class ViewManagerPrivate {
void AddNode(TransportNodeId node_id, ViewTreeNode* node);
void RemoveNode(TransportNodeId node_id);
void AddView(TransportViewId view_id, View* view);
void RemoveView(TransportViewId view_id);
// Returns true if the ViewManager's synchronizer is connected to the service.
bool connected() { return manager_->synchronizer_->connected(); }
......
......@@ -30,14 +30,11 @@ class ViewManagerSynchronizer : public IViewManagerClient {
bool connected() const { return connected_; }
// API exposed to the node/view implementations that pushes local changes to
// the service.
// API exposed to the node implementation that pushes local changes to the
// service.
TransportNodeId CreateViewTreeNode();
void DestroyViewTreeNode(TransportNodeId node_id);
TransportViewId CreateView();
void DestroyView(TransportViewId view_id);
// These methods take TransportIds. For views owned by the current connection,
// the connection id high word can be zero. In all cases, the TransportId 0x1
// refers to the root node.
......@@ -45,9 +42,6 @@ class ViewManagerSynchronizer : public IViewManagerClient {
void RemoveChild(TransportNodeId child_id, TransportNodeId parent_id);
bool OwnsNode(TransportNodeId id) const;
bool OwnsView(TransportViewId id) const;
void SetActiveView(TransportNodeId node_id, TransportViewId view_id);
private:
friend class ViewManagerTransaction;
......@@ -70,9 +64,6 @@ class ViewManagerSynchronizer : public IViewManagerClient {
uint32_t new_view_id,
uint32_t old_view_id,
TransportChangeId client_change_id) OVERRIDE;
virtual void OnViewDeleted(uint32_t node_id,
uint32_t server_change_id,
uint32_t client_change_id) OVERRIDE;
// Sync the client model with the service by enumerating the pending
// transaction queue and applying them in order.
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "mojo/services/public/cpp/view_manager/lib/view_private.h"
namespace mojo {
namespace services {
namespace view_manager {
ViewPrivate::ViewPrivate(View* view)
: view_(view) {
}
ViewPrivate::~ViewPrivate() {
}
// static
View* ViewPrivate::LocalCreate() {
return new View;
}
} // namespace view_manager
} // namespace services
} // namespace mojo
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_LIB_VIEW_PRIVATE_H_
#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_LIB_VIEW_PRIVATE_H_
#include "base/basictypes.h"
#include "mojo/services/public/cpp/view_manager/view.h"
namespace mojo {
namespace services {
namespace view_manager {
class ViewPrivate {
public:
explicit ViewPrivate(View* view);
~ViewPrivate();
static View* LocalCreate();
void LocalDestroy() {
view_->LocalDestroy();
}
void set_id(TransportViewId id) { view_->id_ = id; }
void set_node(ViewTreeNode* node) { view_->node_ = node; }
ViewManager* view_manager() { return view_->manager_; }
void set_view_manager(ViewManager* manager) {
view_->manager_ = manager;
}
ObserverList<ViewObserver>* observers() { return &view_->observers_; }
private:
View* view_;
DISALLOW_COPY_AND_ASSIGN(ViewPrivate);
};
} // namespace view_manager
} // namespace services
} // namespace mojo
#endif // MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_LIB_VIEW_PRIVATE_H_
......@@ -6,17 +6,13 @@
#include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
#include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"
#include "mojo/services/public/cpp/view_manager/lib/view_private.h"
#include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
#include "mojo/services/public/cpp/view_manager/view.h"
#include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h"
namespace mojo {
namespace services {
namespace view_manager {
namespace {
void NotifyViewTreeChangeAtReceiver(
ViewTreeNode* receiver,
const ViewTreeNodeObserver::TreeChangeParams& params) {
......@@ -91,64 +87,6 @@ void RemoveChildImpl(ViewTreeNode* child, ViewTreeNode::Children* children) {
}
}
class ScopedSetActiveViewNotifier {
public:
ScopedSetActiveViewNotifier(ViewTreeNode* node,
View* old_view,
View* new_view)
: node_(node),
old_view_(old_view),
new_view_(new_view) {
FOR_EACH_OBSERVER(
ViewTreeNodeObserver,
*ViewTreeNodePrivate(node).observers(),
OnNodeActiveViewChange(node_,
old_view_,
new_view_,
ViewTreeNodeObserver::DISPOSITION_CHANGING));
}
~ScopedSetActiveViewNotifier() {
FOR_EACH_OBSERVER(
ViewTreeNodeObserver,
*ViewTreeNodePrivate(node_).observers(),
OnNodeActiveViewChange(node_,
old_view_,
new_view_,
ViewTreeNodeObserver::DISPOSITION_CHANGED));
}
private:
ViewTreeNode* node_;
View* old_view_;
View* new_view_;
DISALLOW_COPY_AND_ASSIGN(ScopedSetActiveViewNotifier);
};
class ScopedDestructionNotifier {
public:
explicit ScopedDestructionNotifier(ViewTreeNode* node)
: node_(node) {
FOR_EACH_OBSERVER(
ViewTreeNodeObserver,
*ViewTreeNodePrivate(node_).observers(),
OnNodeDestroy(node_, ViewTreeNodeObserver::DISPOSITION_CHANGING));
}
~ScopedDestructionNotifier() {
FOR_EACH_OBSERVER(
ViewTreeNodeObserver,
*ViewTreeNodePrivate(node_).observers(),
OnNodeDestroy(node_, ViewTreeNodeObserver::DISPOSITION_CHANGED));
}
private:
ViewTreeNode* node_;
DISALLOW_COPY_AND_ASSIGN(ScopedDestructionNotifier);
};
} // namespace
////////////////////////////////////////////////////////////////////////////////
// ViewTreeNode, public:
......@@ -176,24 +114,18 @@ void ViewTreeNode::RemoveObserver(ViewTreeNodeObserver* observer) {
}
void ViewTreeNode::AddChild(ViewTreeNode* child) {
if (manager_)
CHECK_EQ(ViewTreeNodePrivate(child).view_manager(), manager_);
LocalAddChild(child);
if (manager_)
ViewManagerPrivate(manager_).synchronizer()->AddChild(child->id(), id_);
}
void ViewTreeNode::RemoveChild(ViewTreeNode* child) {
if (manager_)
CHECK_EQ(ViewTreeNodePrivate(child).view_manager(), manager_);
LocalRemoveChild(child);
if (manager_)
ViewManagerPrivate(manager_).synchronizer()->RemoveChild(child->id(), id_);
}
bool ViewTreeNode::Contains(ViewTreeNode* child) const {
if (manager_)
CHECK_EQ(ViewTreeNodePrivate(child).view_manager(), manager_);
for (ViewTreeNode* p = child->parent(); p; p = p->parent()) {
if (p == this)
return true;
......@@ -214,29 +146,25 @@ ViewTreeNode* ViewTreeNode::GetChildById(TransportNodeId id) {
return NULL;
}
void ViewTreeNode::SetActiveView(View* view) {
if (manager_)
CHECK_EQ(ViewPrivate(view).view_manager(), manager_);
LocalSetActiveView(view);
if (manager_) {
ViewManagerPrivate(manager_).synchronizer()->SetActiveView(
id_, active_view_->id());
}
}
////////////////////////////////////////////////////////////////////////////////
// ViewTreeNode, protected:
ViewTreeNode::ViewTreeNode()
: manager_(NULL),
id_(-1),
parent_(NULL),
active_view_(NULL) {}
parent_(NULL) {}
ViewTreeNode::~ViewTreeNode() {
ScopedDestructionNotifier notifier(this);
FOR_EACH_OBSERVER(
ViewTreeNodeObserver,
observers_,
OnNodeDestroy(this, ViewTreeNodeObserver::DISPOSITION_CHANGING));
if (parent_)
parent_->LocalRemoveChild(this);
FOR_EACH_OBSERVER(
ViewTreeNodeObserver,
observers_,
OnNodeDestroy(this, ViewTreeNodeObserver::DISPOSITION_CHANGED));
if (manager_)
ViewManagerPrivate(manager_).RemoveNode(id_);
}
......@@ -247,8 +175,7 @@ ViewTreeNode::~ViewTreeNode() {
ViewTreeNode::ViewTreeNode(ViewManager* manager)
: manager_(manager),
id_(ViewManagerPrivate(manager).synchronizer()->CreateViewTreeNode()),
parent_(NULL),
active_view_(NULL) {}
parent_(NULL) {}
void ViewTreeNode::LocalDestroy() {
delete this;
......@@ -268,15 +195,6 @@ void ViewTreeNode::LocalRemoveChild(ViewTreeNode* child) {
RemoveChildImpl(child, &children_);
}
void ViewTreeNode::LocalSetActiveView(View* view) {
ScopedSetActiveViewNotifier notifier(this, active_view_, view);
if (active_view_)
ViewPrivate(active_view_).set_node(NULL);
active_view_ = view;
if (active_view_)
ViewPrivate(active_view_).set_node(this);
}
} // namespace view_manager
} // namespace services
} // namespace mojo
......
......@@ -5,6 +5,8 @@
#ifndef MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_LIB_VIEW_TREE_NODE_PRIVATE_H_
#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_LIB_VIEW_TREE_NODE_PRIVATE_H_
#include <vector>
#include "base/basictypes.h"
#include "mojo/services/public/cpp/view_manager/view_tree_node.h"
......@@ -41,10 +43,6 @@ class ViewTreeNodePrivate {
node_->LocalRemoveChild(child);
}
void LocalSetActiveView(View* view) {
node_->LocalSetActiveView(view);
}
private:
ViewTreeNode* node_;
......
......@@ -8,8 +8,6 @@
#include "base/logging.h"
#include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
#include "mojo/services/public/cpp/view_manager/util.h"
#include "mojo/services/public/cpp/view_manager/view.h"
#include "mojo/services/public/cpp/view_manager/view_observer.h"
#include "mojo/services/public/cpp/view_manager/view_tree_node_observer.h"
#include "mojo/shell/shell_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -247,68 +245,31 @@ TEST_F(ViewManagerTest, HierarchyChanged_NodeRemoved) {
EXPECT_TRUE(tree2->children().empty());
}
// Utility class that waits for the destruction of some number of nodes and
// views.
class DestructionWaiter : public ViewTreeNodeObserver,
public ViewObserver {
class NodeDestroyed_Waiter : public ViewTreeNodeObserver {
public:
// |nodes| or |views| can be NULL.
DestructionWaiter(ViewManager* view_manager,
std::set<TransportNodeId>* nodes,
std::set<TransportViewId>* views)
: nodes_(nodes),
views_(views) {
DCHECK(nodes || views);
if (nodes) {
for (std::set<TransportNodeId>::const_iterator it = nodes->begin();
it != nodes->end(); ++it) {
view_manager->GetNodeById(*it)->AddObserver(this);
}
}
if (views) {
for (std::set<TransportViewId>::const_iterator it = views->begin();
it != views->end(); ++it) {
view_manager->GetViewById(*it)->AddObserver(this);
}
}
NodeDestroyed_Waiter(ViewManager* view_manager, TransportNodeId id)
: id_(id),
view_manager_(view_manager) {
view_manager_->GetNodeById(id)->AddObserver(this);
DoRunLoop();
}
private:
// Overridden from ViewTreeNodeObserver:
virtual void OnNodeDestroy(
ViewTreeNode* node,
ViewTreeNodeObserver::DispositionChangePhase phase) OVERRIDE {
if (phase != ViewTreeNodeObserver::DISPOSITION_CHANGED)
return;
std::set<TransportNodeId>::const_iterator it = nodes_->find(node->id());
if (it != nodes_->end())
nodes_->erase(it);
if (CanQuit())
QuitRunLoop();
virtual ~NodeDestroyed_Waiter() {
}
// Overridden from ViewObserver:
virtual void OnViewDestroy(
View* view,
ViewObserver::DispositionChangePhase phase) OVERRIDE {
if (phase != ViewObserver::DISPOSITION_CHANGED)
private:
// Overridden from TreeObserverBase:
virtual void OnNodeDestroy(ViewTreeNode* node,
DispositionChangePhase phase) OVERRIDE {
if (phase != DISPOSITION_CHANGED)
return;
std::set<TransportViewId>::const_iterator it = views_->find(view->id());
if (it != views_->end())
views_->erase(it);
if (CanQuit())
if (node->id() == id_)
QuitRunLoop();
}
bool CanQuit() {
return (!nodes_ || nodes_->empty()) && (!views_ || views_->empty());
}
std::set<TransportNodeId>* nodes_;
std::set<TransportViewId>* views_;
TransportNodeId id_;
ViewManager* view_manager_;
DISALLOW_COPY_AND_ASSIGN(DestructionWaiter);
DISALLOW_COPY_AND_ASSIGN(NodeDestroyed_Waiter);
};
TEST_F(ViewManagerTest, NodeDestroyed) {
......@@ -318,171 +279,23 @@ TEST_F(ViewManagerTest, NodeDestroyed) {
// |node1| will be deleted after calling Destroy() below.
TransportNodeId id = node1->id();
node1->Destroy();
std::set<TransportNodeId> nodes;
nodes.insert(id);
DestructionWaiter destroyed_waiter(view_manager_2(), &nodes, NULL);
NodeDestroyed_Waiter destroyed_waiter(view_manager_2(), id);
EXPECT_TRUE(view_manager_2()->tree()->children().empty());
EXPECT_EQ(NULL, view_manager_2()->GetNodeById(id));
}
TEST_F(ViewManagerTest, ViewManagerDestroyed_CleanupNode) {
TEST_F(ViewManagerTest, ViewManagerDestroyed) {
ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2);
TransportNodeId id = node1->id();
DestroyViewManager1();
std::set<TransportNodeId> nodes;
nodes.insert(id);
DestructionWaiter destroyed_waiter(view_manager_2(), &nodes, NULL);
NodeDestroyed_Waiter destroyed_waiter(view_manager_2(), id);
// tree() should still be valid, since it's owned by neither connection.
EXPECT_TRUE(view_manager_2()->tree()->children().empty());
}
// Waits until the active view id of the supplied node changes.
class ActiveViewChangedWaiter : public ViewTreeNodeObserver {
public:
explicit ActiveViewChangedWaiter(ViewTreeNode* node)
: node_(node) {
node_->AddObserver(this);
DoRunLoop();
}
virtual ~ActiveViewChangedWaiter() {
node_->RemoveObserver(this);
}
private:
// Overridden from ViewTreeNodeObserver:
virtual void OnNodeActiveViewChange(ViewTreeNode* node,
View* old_view,
View* new_view,
DispositionChangePhase phase) OVERRIDE {
DCHECK_EQ(node, node_);
QuitRunLoop();
}
ViewTreeNode* node_;
DISALLOW_COPY_AND_ASSIGN(ActiveViewChangedWaiter);
};
TEST_F(ViewManagerTest, SetActiveView) {
ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2);
View* view1 = View::Create(view_manager_1());
node1->SetActiveView(view1);
ViewTreeNode* node1_2 = view_manager_2()->tree()->GetChildById(node1->id());
ActiveViewChangedWaiter waiter(node1_2);
EXPECT_EQ(node1_2->active_view()->id(), view1->id());
}
TEST_F(ViewManagerTest, DestroyView) {
ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2);
View* view1 = View::Create(view_manager_1());
node1->SetActiveView(view1);
ViewTreeNode* node1_2 = view_manager_2()->tree()->GetChildById(node1->id());
ActiveViewChangedWaiter active_view_waiter(node1_2);
TransportViewId view1_id = view1->id();
view1->Destroy();
std::set<TransportViewId> views;
views.insert(view1_id);
DestructionWaiter destruction_waiter(view_manager_2(), NULL, &views);
EXPECT_EQ(NULL, node1_2->active_view());
EXPECT_EQ(NULL, view_manager_2()->GetViewById(view1_id));
}
// Destroying the connection that created a node and view should result in that
// node and view disappearing from all connections that see them.
TEST_F(ViewManagerTest, ViewManagerDestroyed_CleanupNodeAndView) {
ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2);
View* view1 = View::Create(view_manager_1());
node1->SetActiveView(view1);
ViewTreeNode* node1_2 = view_manager_2()->tree()->GetChildById(node1->id());
{
ActiveViewChangedWaiter active_view_waiter(node1_2);
}
TransportNodeId node1_id = node1->id();
TransportViewId view1_id = view1->id();
DestroyViewManager1();
std::set<TransportNodeId> observed_nodes;
observed_nodes.insert(node1_id);
std::set<TransportViewId> observed_views;
observed_views.insert(view1_id);
DestructionWaiter destruction_waiter(view_manager_2(),
&observed_nodes,
&observed_views);
// tree() should still be valid, since it's owned by neither connection.
EXPECT_TRUE(view_manager_2()->tree()->children().empty());
EXPECT_EQ(NULL, view_manager_2()->GetNodeById(node1_id));
EXPECT_EQ(NULL, view_manager_2()->GetViewById(view1_id));
}
// This test validates the following scenario:
// - a node originating from one connection
// - a view originating from a second connection
// + the connection originating the node is destroyed
// -> the view should still exist (since the second connection is live) but
// should be disconnected from any nodes.
TEST_F(ViewManagerTest,
ViewManagerDestroyed_CleanupNodeAndViewFromDifferentConnections) {
ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2);
View* view1_2 = View::Create(view_manager_2());
ViewTreeNode* node1_2 = view_manager_2()->tree()->GetChildById(node1->id());
node1_2->SetActiveView(view1_2);
{
ActiveViewChangedWaiter active_view_waiter(node1);
}
TransportNodeId node1_id = node1->id();
TransportViewId view1_2_id = view1_2->id();
DestroyViewManager1();
std::set<TransportNodeId> nodes;
nodes.insert(node1_id);
DestructionWaiter destruction_waiter(view_manager_2(), &nodes, NULL);
// tree() should still be valid, since it's owned by neither connection.
EXPECT_TRUE(view_manager_2()->tree()->children().empty());
// node1 was owned by the first connection, so it should be gone.
EXPECT_EQ(NULL, view_manager_2()->GetNodeById(node1_id));
// view1_2 was owned by the second connection, so it should still exist, but
// disconnected from the node tree.
View* another_view1_2 = view_manager_2()->GetViewById(view1_2_id);
EXPECT_EQ(view1_2, another_view1_2);
EXPECT_EQ(NULL, view1_2->node());
}
// This test verifies that it is not possible to set the active view to a view
// defined in a different connection.
// TODO(beng): write these tests for ViewTreeNode::AddChild(), RemoveChild() and
// Contains().
TEST_F(ViewManagerTest, SetActiveViewAcrossConnection) {
ViewTreeNode* node1 = CreateNodeInParent(view_manager_1()->tree());
TreeSizeMatchesWaiter init_waiter(view_manager_2(), 2);
View* view1_2 = View::Create(view_manager_2());
EXPECT_DEATH(node1->SetActiveView(view1_2), "");
}
} // namespace view_manager
} // namespace services
} // namespace mojo
......@@ -6,45 +6,14 @@
#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_H_
#include "base/basictypes.h"
#include "base/observer_list.h"
#include "mojo/services/public/cpp/view_manager/view_manager_types.h"
namespace mojo {
namespace services {
namespace view_manager {
class ViewManager;
class ViewObserver;
class ViewTreeNode;
// Views are owned by the ViewManager.
class View {
public:
static View* Create(ViewManager* manager);
void Destroy();
TransportViewId id() const { return id_; }
ViewTreeNode* node() { return node_; }
void AddObserver(ViewObserver* observer);
void RemoveObserver(ViewObserver* observer);
private:
friend class ViewPrivate;
explicit View(ViewManager* manager);
View();
~View();
void LocalDestroy();
TransportViewId id_;
ViewTreeNode* node_;
ViewManager* manager_;
ObserverList<ViewObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(View);
};
......
......@@ -17,7 +17,6 @@ class Shell;
namespace services {
namespace view_manager {
class View;
class ViewManagerSynchronizer;
class ViewTreeNode;
......@@ -45,19 +44,16 @@ class ViewManager {
ViewTreeNode* tree() { return tree_; }
ViewTreeNode* GetNodeById(TransportNodeId id);
View* GetViewById(TransportViewId id);
private:
friend class ViewManagerPrivate;
typedef std::map<TransportNodeId, ViewTreeNode*> IdToNodeMap;
typedef std::map<TransportViewId, View*> IdToViewMap;
Shell* shell_;
scoped_ptr<ViewManagerSynchronizer> synchronizer_;
ViewTreeNode* tree_;
IdToNodeMap nodes_;
IdToViewMap views_;
DISALLOW_COPY_AND_ASSIGN(ViewManager);
};
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_OBSERVER_H_
#define MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_OBSERVER_H_
#include <vector>
#include "base/basictypes.h"
namespace mojo {
namespace services {
namespace view_manager {
class View;
class ViewObserver {
public:
enum DispositionChangePhase {
DISPOSITION_CHANGING,
DISPOSITION_CHANGED
};
virtual void OnViewDestroy(View* view, DispositionChangePhase phase) {}
protected:
virtual ~ViewObserver() {}
};
} // namespace view_manager
} // namespace services
} // namespace mojo
#endif // MOJO_SERVICES_PUBLIC_CPP_VIEW_MANAGER_VIEW_OBSERVER_H_
......@@ -15,7 +15,6 @@ namespace mojo {
namespace services {
namespace view_manager {
class View;
class ViewManager;
class ViewTreeNodeObserver;
......@@ -51,10 +50,6 @@ class ViewTreeNode {
ViewTreeNode* GetChildById(TransportNodeId id);
// View.
void SetActiveView(View* view);
View* active_view() { return active_view_; }
protected:
// This class is subclassed only by test classes that provide a public ctor.
ViewTreeNode();
......@@ -68,7 +63,6 @@ class ViewTreeNode {
void LocalDestroy();
void LocalAddChild(ViewTreeNode* child);
void LocalRemoveChild(ViewTreeNode* child);
void LocalSetActiveView(View* view);
ViewManager* manager_;
TransportNodeId id_;
......@@ -77,8 +71,6 @@ class ViewTreeNode {
ObserverList<ViewTreeNodeObserver> observers_;
View* active_view_;
DISALLOW_COPY_AND_ASSIGN(ViewTreeNode);
};
......
......@@ -13,7 +13,6 @@ namespace mojo {
namespace services {
namespace view_manager {
class View;
class ViewTreeNode;
class ViewTreeNodeObserver {
......@@ -37,11 +36,6 @@ class ViewTreeNodeObserver {
virtual void OnNodeDestroy(ViewTreeNode* node,
DispositionChangePhase phase) {}
virtual void OnNodeActiveViewChange(ViewTreeNode* node,
View* old_view,
View* new_view,
DispositionChangePhase phase) {}
protected:
virtual ~ViewTreeNodeObserver() {}
};
......
......@@ -96,7 +96,9 @@ interface IViewManagerClient {
uint32 client_change_id);
// Invoked when a node is deleted.
OnNodeDeleted(uint32 node, uint32 server_change_id, uint32 client_change_id);
OnNodeDeleted(uint32 node,
uint32 server_change_id,
uint32 client_change_id);
// Invoked when the view associated with a node is replaced by another view.
......@@ -105,9 +107,6 @@ interface IViewManagerClient {
uint32 new_view_id,
uint32 old_view_id,
uint32 client_change_id);
// Invoked when a view is deleted.
OnViewDeleted(uint32 view, uint32 server_change_id, uint32 client_change_id);
};
}
......@@ -116,15 +116,6 @@ void RootNodeManager::NotifyNodeDeleted(const NodeId& node) {
}
}
void RootNodeManager::NotifyViewDeleted(const ViewId& view) {
// TODO(sky): make a macro for this.
for (ConnectionMap::iterator i = connection_map_.begin();
i != connection_map_.end(); ++i) {
i->second->NotifyViewDeleted(view, next_server_change_id_,
GetClientChangeId(i->first));
}
}
void RootNodeManager::PrepareForChange(ViewManagerConnection* connection,
TransportChangeId change_id) {
DCHECK(!change_.get()); // Should only ever have one change in flight.
......
......@@ -85,7 +85,6 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager : public NodeDelegate {
const ViewId& new_view_id,
const ViewId& old_view_id);
void NotifyNodeDeleted(const NodeId& node);
void NotifyViewDeleted(const ViewId& view);
private:
// Used to setup any static state needed by RootNodeManager.
......
......@@ -136,14 +136,6 @@ void ViewManagerConnection::NotifyNodeDeleted(
client_change_id);
}
void ViewManagerConnection::NotifyViewDeleted(
const ViewId& view,
TransportChangeId server_change_id,
TransportChangeId client_change_id) {
client()->OnViewDeleted(ViewIdToTransportId(view), server_change_id,
client_change_id);
}
bool ViewManagerConnection::DeleteNodeImpl(ViewManagerConnection* source,
const NodeId& node_id,
TransportChangeId change_id) {
......@@ -181,7 +173,6 @@ bool ViewManagerConnection::DeleteViewImpl(ViewManagerConnection* source,
view->node()->SetView(NULL);
view_map_.erase(view_id.view_id);
delete view;
context()->NotifyViewDeleted(view_id);
return true;
}
......
......@@ -63,9 +63,6 @@ class MOJO_VIEW_MANAGER_EXPORT ViewManagerConnection
void NotifyNodeDeleted(const NodeId& node,
TransportChangeId server_change_id,
TransportChangeId client_change_id);
void NotifyViewDeleted(const ViewId& view,
TransportChangeId server_change_id,
TransportChangeId client_change_id);
private:
typedef std::map<TransportConnectionSpecificNodeId, Node*> NodeMap;
......
......@@ -239,17 +239,6 @@ class ViewManagerClientImpl : public IViewManagerClient {
NodeIdToString(node).c_str()));
QuitIfNecessary();
}
virtual void OnViewDeleted(TransportViewId view,
TransportChangeId server_change_id,
TransportChangeId client_change_id) OVERRIDE {
changes_.push_back(
base::StringPrintf(
"ViewDeleted change_id=%d,%d view=%s",
static_cast<int>(client_change_id),
static_cast<int>(client_change_id),
NodeIdToString(view).c_str()));
QuitIfNecessary();
}
virtual void OnNodeViewReplaced(TransportNodeId node,
TransportViewId new_view_id,
TransportViewId old_view_id,
......@@ -694,7 +683,7 @@ TEST_F(ViewManagerConnectionTest, SetViewFromSecondConnection) {
client_.DoRunLoopUntilChangesCount(1);
Changes changes(client_.GetAndClearChanges());
ASSERT_EQ(2u, changes.size());
ASSERT_EQ(1u, changes.size());
EXPECT_EQ("change_id=0 node=1,1 new_view=null old_view=2,51", changes[0]);
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment