Commit 9faf9cbc authored by ben@chromium.org's avatar ben@chromium.org

Trigger Node destruction notifications from Node's dtor

R=sky@chromium.org
BUG=none

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282403 0039d316-1c4b-4281-b951-d872f2087c98
parent 3f227786
...@@ -37,11 +37,17 @@ Node::Node(NodeDelegate* delegate, const NodeId& id) ...@@ -37,11 +37,17 @@ Node::Node(NodeDelegate* delegate, const NodeId& id)
} }
Node::~Node() { Node::~Node() {
SetView(NULL);
// This is implicitly done during deletion of the window, but we do it here so // This is implicitly done during deletion of the window, but we do it here so
// that we're in a known state. // that we're in a known state.
if (window_.parent()) if (window_.parent())
window_.parent()->RemoveChild(&window_); window_.parent()->RemoveChild(&window_);
// This must be done *after* updating the hierarchy since the hierarchy change
// will remove the node from the connections that know about it, preventing
// this notification from being sent after the destruction notification.
SetView(NULL);
delegate_->OnNodeDestroyed(this);
} }
// static // static
...@@ -133,7 +139,12 @@ void Node::OnWindowHierarchyChanged( ...@@ -133,7 +139,12 @@ void Node::OnWindowHierarchyChanged(
params.new_parent->GetProperty(kNodeKey) : NULL; params.new_parent->GetProperty(kNodeKey) : NULL;
const Node* old_parent = params.old_parent ? const Node* old_parent = params.old_parent ?
params.old_parent->GetProperty(kNodeKey) : NULL; params.old_parent->GetProperty(kNodeKey) : NULL;
delegate_->OnNodeHierarchyChanged(this, new_parent, old_parent); // This check is needed because even the root Node's aura::Window has a
// parent, but the Node itself has no parent (so it's possible for us to
// receive this notification from aura when no logical Node hierarchy change
// has actually ocurred).
if (new_parent != old_parent)
delegate_->OnNodeHierarchyChanged(this, new_parent, old_parent);
} }
gfx::Size Node::GetMinimumSize() const { gfx::Size Node::GetMinimumSize() const {
......
...@@ -24,6 +24,10 @@ class View; ...@@ -24,6 +24,10 @@ class View;
class MOJO_VIEW_MANAGER_EXPORT NodeDelegate { class MOJO_VIEW_MANAGER_EXPORT NodeDelegate {
public: public:
// Invoked at the end of the Node's destructor (after it has been removed from
// the hierarchy and its active view has been reset).
virtual void OnNodeDestroyed(const Node* node) = 0;
// Invoked when the hierarchy has changed. // Invoked when the hierarchy has changed.
virtual void OnNodeHierarchyChanged(const Node* node, virtual void OnNodeHierarchyChanged(const Node* node,
const Node* new_parent, const Node* new_parent,
......
...@@ -48,18 +48,19 @@ RootNodeManager::RootNodeManager(ApplicationConnection* app_connection, ...@@ -48,18 +48,19 @@ RootNodeManager::RootNodeManager(ApplicationConnection* app_connection,
next_connection_id_(1), next_connection_id_(1),
next_server_change_id_(1), next_server_change_id_(1),
root_view_manager_(app_connection, this, view_manager_delegate), root_view_manager_(app_connection, this, view_manager_delegate),
root_(this, RootNodeId()), root_(new Node(this, RootNodeId())),
current_change_(NULL) { current_change_(NULL) {
} }
RootNodeManager::~RootNodeManager() { RootNodeManager::~RootNodeManager() {
aura::client::FocusClient* focus_client = aura::client::FocusClient* focus_client =
aura::client::GetFocusClient(root_.window()); aura::client::GetFocusClient(root_->window());
focus_client->RemoveObserver(this); focus_client->RemoveObserver(this);
while (!connections_created_by_connect_.empty()) while (!connections_created_by_connect_.empty())
delete *(connections_created_by_connect_.begin()); delete *(connections_created_by_connect_.begin());
// All the connections should have been destroyed. // All the connections should have been destroyed.
DCHECK(connection_map_.empty()); DCHECK(connection_map_.empty());
root_.reset();
} }
ConnectionSpecificId RootNodeManager::GetAndAdvanceNextConnectionId() { ConnectionSpecificId RootNodeManager::GetAndAdvanceNextConnectionId() {
...@@ -104,8 +105,8 @@ ViewManagerServiceImpl* RootNodeManager::GetConnection( ...@@ -104,8 +105,8 @@ ViewManagerServiceImpl* RootNodeManager::GetConnection(
} }
Node* RootNodeManager::GetNode(const NodeId& id) { Node* RootNodeManager::GetNode(const NodeId& id) {
if (id == root_.id()) if (id == root_->id())
return &root_; return root_.get();
ConnectionMap::iterator i = connection_map_.find(id.connection_id); ConnectionMap::iterator i = connection_map_.find(id.connection_id);
return i == connection_map_.end() ? NULL : i->second->GetNode(id); return i == connection_map_.end() ? NULL : i->second->GetNode(id);
} }
...@@ -195,7 +196,7 @@ void RootNodeManager::ProcessNodeDeleted(const NodeId& node) { ...@@ -195,7 +196,7 @@ void RootNodeManager::ProcessNodeDeleted(const NodeId& node) {
for (ConnectionMap::iterator i = connection_map_.begin(); for (ConnectionMap::iterator i = connection_map_.begin();
i != connection_map_.end(); ++i) { i != connection_map_.end(); ++i) {
i->second->ProcessNodeDeleted(node, next_server_change_id_, i->second->ProcessNodeDeleted(node, next_server_change_id_,
IsChangeSource(i->first)); IsChangeSource(i->first));
} }
} }
...@@ -250,15 +251,19 @@ ViewManagerServiceImpl* RootNodeManager::EmbedImpl( ...@@ -250,15 +251,19 @@ ViewManagerServiceImpl* RootNodeManager::EmbedImpl(
ViewManagerServiceImpl* connection = ViewManagerServiceImpl* connection =
new ViewManagerServiceImpl(this, new ViewManagerServiceImpl(this,
creator_id, creator_id,
creator_url, creator_url,
url.To<std::string>()); url.To<std::string>());
connection->SetRoots(node_ids); connection->SetRoots(node_ids);
BindToPipe(connection, pipe.handle0.Pass()); BindToPipe(connection, pipe.handle0.Pass());
connections_created_by_connect_.insert(connection); connections_created_by_connect_.insert(connection);
return connection; return connection;
} }
void RootNodeManager::OnNodeDestroyed(const Node* node) {
ProcessNodeDeleted(node->id());
}
void RootNodeManager::OnNodeHierarchyChanged(const Node* node, void RootNodeManager::OnNodeHierarchyChanged(const Node* node,
const Node* new_parent, const Node* new_parent,
const Node* old_parent) { const Node* old_parent) {
......
...@@ -114,7 +114,7 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager ...@@ -114,7 +114,7 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager
// Returns the View identified by |id|. // Returns the View identified by |id|.
View* GetView(const ViewId& id); View* GetView(const ViewId& id);
Node* root() { return &root_; } Node* root() { return root_.get(); }
bool IsProcessingChange() const { return current_change_ != NULL; } bool IsProcessingChange() const { return current_change_ != NULL; }
...@@ -137,6 +137,7 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager ...@@ -137,6 +137,7 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager
// These functions trivially delegate to all ViewManagerServiceImpls, which in // These functions trivially delegate to all ViewManagerServiceImpls, which in
// term notify their clients. // term notify their clients.
void ProcessNodeDestroyed(Node* node);
void ProcessNodeBoundsChanged(const Node* node, void ProcessNodeBoundsChanged(const Node* node,
const gfx::Rect& old_bounds, const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds); const gfx::Rect& new_bounds);
...@@ -187,6 +188,7 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager ...@@ -187,6 +188,7 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager
const Array<Id>& node_ids); const Array<Id>& node_ids);
// Overridden from NodeDelegate: // Overridden from NodeDelegate:
virtual void OnNodeDestroyed(const Node* node) OVERRIDE;
virtual void OnNodeHierarchyChanged(const Node* node, virtual void OnNodeHierarchyChanged(const Node* node,
const Node* new_parent, const Node* new_parent,
const Node* old_parent) OVERRIDE; const Node* old_parent) OVERRIDE;
...@@ -214,7 +216,7 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager ...@@ -214,7 +216,7 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager
RootViewManager root_view_manager_; RootViewManager root_view_manager_;
// Root node. // Root node.
Node root_; scoped_ptr<Node> root_;
// Set of ViewManagerServiceImpls created by way of Connect(). These have to // Set of ViewManagerServiceImpls created by way of Connect(). These have to
// be explicitly destroyed. // be explicitly destroyed.
......
...@@ -47,33 +47,19 @@ ViewManagerServiceImpl::ViewManagerServiceImpl( ...@@ -47,33 +47,19 @@ ViewManagerServiceImpl::ViewManagerServiceImpl(
} }
ViewManagerServiceImpl::~ViewManagerServiceImpl() { ViewManagerServiceImpl::~ViewManagerServiceImpl() {
// Delete any views we own. // Delete any views we created.
while (!view_map_.empty()) { while (!view_map_.empty()) {
bool result = DeleteViewImpl(this, view_map_.begin()->second->id()); bool result = DeleteViewImpl(this, view_map_.begin()->second->id());
DCHECK(result); DCHECK(result);
} }
// We're about to destroy all our nodes. Detach any views from them. // Ditto the nodes.
for (NodeMap::iterator i = node_map_.begin(); i != node_map_.end(); ++i) {
if (i->second->view()) {
bool result = SetViewImpl(i->second, ViewId());
DCHECK(result);
}
}
if (!node_map_.empty()) { if (!node_map_.empty()) {
RootNodeManager::ScopedChange change( RootNodeManager::ScopedChange change(
this, root_node_manager_, this, root_node_manager_,
RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, true); RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, true);
while (!node_map_.empty()) { while (!node_map_.empty())
scoped_ptr<Node> node(node_map_.begin()->second); delete node_map_.begin()->second;
Node* parent = node->GetParent();
const NodeId node_id(node->id());
if (parent)
parent->Remove(node.get());
root_node_manager_->ProcessNodeDeleted(node_id);
node_map_.erase(NodeIdToTransportId(node_id));
}
} }
root_node_manager_->RemoveConnection(this); root_node_manager_->RemoveConnection(this);
...@@ -205,6 +191,8 @@ void ViewManagerServiceImpl::ProcessNodeViewReplaced( ...@@ -205,6 +191,8 @@ void ViewManagerServiceImpl::ProcessNodeViewReplaced(
void ViewManagerServiceImpl::ProcessNodeDeleted(const NodeId& node, void ViewManagerServiceImpl::ProcessNodeDeleted(const NodeId& node,
Id server_change_id, Id server_change_id,
bool originated_change) { bool originated_change) {
node_map_.erase(node.node_id);
const bool in_known = known_nodes_.erase(NodeIdToTransportId(node)) > 0; const bool in_known = known_nodes_.erase(NodeIdToTransportId(node)) > 0;
const bool in_roots = roots_.erase(NodeIdToTransportId(node)) > 0; const bool in_roots = roots_.erase(NodeIdToTransportId(node)) > 0;
...@@ -382,16 +370,7 @@ bool ViewManagerServiceImpl::DeleteNodeImpl(ViewManagerServiceImpl* source, ...@@ -382,16 +370,7 @@ bool ViewManagerServiceImpl::DeleteNodeImpl(ViewManagerServiceImpl* source,
RootNodeManager::ScopedChange change( RootNodeManager::ScopedChange change(
source, root_node_manager_, source, root_node_manager_,
RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, true); RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, true);
if (node->GetParent())
node->GetParent()->Remove(node);
std::vector<Node*> children(node->GetChildren());
for (size_t i = 0; i < children.size(); ++i)
node->Remove(children[i]);
DCHECK(node->GetChildren().empty());
node_map_.erase(node_id.node_id);
delete node; delete node;
node = NULL;
root_node_manager_->ProcessNodeDeleted(node_id);
return true; return true;
} }
...@@ -570,7 +549,7 @@ void ViewManagerServiceImpl::CreateNode( ...@@ -570,7 +549,7 @@ void ViewManagerServiceImpl::CreateNode(
callback.Run(false); callback.Run(false);
return; return;
} }
node_map_[node_id.node_id] = new Node(this, node_id); node_map_[node_id.node_id] = new Node(root_node_manager_, node_id);
known_nodes_.insert(transport_node_id); known_nodes_.insert(transport_node_id);
callback.Run(true); callback.Run(true);
} }
...@@ -802,29 +781,6 @@ void ViewManagerServiceImpl::DispatchOnViewInputEvent(Id transport_view_id, ...@@ -802,29 +781,6 @@ void ViewManagerServiceImpl::DispatchOnViewInputEvent(Id transport_view_id,
} }
} }
void ViewManagerServiceImpl::OnNodeHierarchyChanged(const Node* node,
const Node* new_parent,
const Node* old_parent) {
root_node_manager_->ProcessNodeHierarchyChanged(node, new_parent, old_parent);
}
void ViewManagerServiceImpl::OnNodeBoundsChanged(const Node* node,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
root_node_manager_->ProcessNodeBoundsChanged(node, old_bounds, new_bounds);
}
void ViewManagerServiceImpl::OnNodeViewReplaced(const Node* node,
const View* new_view,
const View* old_view) {
root_node_manager_->ProcessNodeViewReplaced(node, new_view, old_view);
}
void ViewManagerServiceImpl::OnViewInputEvent(const View* view,
const ui::Event* event) {
root_node_manager_->DispatchViewInputEventToWindowManager(view, event);
}
void ViewManagerServiceImpl::OnConnectionEstablished() { void ViewManagerServiceImpl::OnConnectionEstablished() {
root_node_manager_->AddConnection(this); root_node_manager_->AddConnection(this);
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include "base/containers/hash_tables.h" #include "base/containers/hash_tables.h"
#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h" #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
#include "mojo/services/view_manager/ids.h" #include "mojo/services/view_manager/ids.h"
#include "mojo/services/view_manager/node_delegate.h"
#include "mojo/services/view_manager/view_manager_export.h" #include "mojo/services/view_manager/view_manager_export.h"
namespace gfx { namespace gfx {
...@@ -38,8 +37,7 @@ class View; ...@@ -38,8 +37,7 @@ class View;
// Manages a connection from the client. // Manages a connection from the client.
class MOJO_VIEW_MANAGER_EXPORT ViewManagerServiceImpl class MOJO_VIEW_MANAGER_EXPORT ViewManagerServiceImpl
: public InterfaceImpl<ViewManagerService>, : public InterfaceImpl<ViewManagerService> {
public NodeDelegate {
public: public:
ViewManagerServiceImpl(RootNodeManager* root_node_manager, ViewManagerServiceImpl(RootNodeManager* root_node_manager,
ConnectionSpecificId creator_id, ConnectionSpecificId creator_id,
...@@ -216,19 +214,6 @@ class MOJO_VIEW_MANAGER_EXPORT ViewManagerServiceImpl ...@@ -216,19 +214,6 @@ class MOJO_VIEW_MANAGER_EXPORT ViewManagerServiceImpl
virtual void DispatchOnViewInputEvent(Id transport_view_id, virtual void DispatchOnViewInputEvent(Id transport_view_id,
EventPtr event) OVERRIDE; EventPtr event) OVERRIDE;
// Overridden from NodeDelegate:
virtual void OnNodeHierarchyChanged(const Node* node,
const Node* new_parent,
const Node* old_parent) OVERRIDE;
virtual void OnNodeBoundsChanged(const Node* node,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE;
virtual void OnNodeViewReplaced(const Node* node,
const View* new_view,
const View* old_view) OVERRIDE;
virtual void OnViewInputEvent(const View* view,
const ui::Event* event) OVERRIDE;
// InterfaceImp overrides: // InterfaceImp overrides:
virtual void OnConnectionEstablished() MOJO_OVERRIDE; virtual void OnConnectionEstablished() MOJO_OVERRIDE;
...@@ -247,8 +232,9 @@ class MOJO_VIEW_MANAGER_EXPORT ViewManagerServiceImpl ...@@ -247,8 +232,9 @@ class MOJO_VIEW_MANAGER_EXPORT ViewManagerServiceImpl
// The URL of the app that embedded the app this connection was created for. // The URL of the app that embedded the app this connection was created for.
const std::string creator_url_; const std::string creator_url_;
// The nodes and views created by this connection. This connection owns these
// objects.
NodeMap node_map_; NodeMap node_map_;
ViewMap view_map_; ViewMap view_map_;
// The set of nodes that has been communicated to the client. // The set of nodes that has been communicated to the client.
......
...@@ -415,8 +415,8 @@ void EmbedRootCallback(bool* result_cache, ...@@ -415,8 +415,8 @@ void EmbedRootCallback(bool* result_cache,
run_loop->Quit(); run_loop->Quit();
} }
// Resposible for establishing the initial ViewManagerService connection. Blocks // Responsible for establishing the initial ViewManagerService connection.
// until result is determined. // Blocks until result is determined.
bool EmbedRoot(ViewManagerInitService* view_manager_init, bool EmbedRoot(ViewManagerInitService* view_manager_init,
const std::string& url) { const std::string& url) {
bool result = false; bool result = false;
......
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