diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-11 20:25:20 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-11 20:25:20 +0000 |
commit | 4e72e787a8120681c4c7c96071ff5f2c0fa9f7fd (patch) | |
tree | bd4c57f3366114d980bcae293653a14577aba4e0 /mojo | |
parent | 782a8e944d0276660e8c8c54b9d4db33b05473ca (diff) | |
download | chromium_src-4e72e787a8120681c4c7c96071ff5f2c0fa9f7fd.zip chromium_src-4e72e787a8120681c4c7c96071ff5f2c0fa9f7fd.tar.gz chromium_src-4e72e787a8120681c4c7c96071ff5f2c0fa9f7fd.tar.bz2 |
Attempt at cleaning up a bunch of shutdown issues.
1. Defers command buffer destruction until after the native viewport client has had a chance to cleanup.
2. Destroy the compositor before quitting the view manager message loop.
3. Make various NodeObservers properly unhook themselves as node/view observers during destruction and view swapping.
4. Adds a "ViewManagerDisconnected" method to ViewManagerDelegate to allow the application to exit when the connection to the view manager is closed. This is necessary in addition to root monitoring because for some connections (e.g. the root node->window manager) the root node is not destroyed. I'm not entirely happy with imposing this burden on application developers but I will try and tidy this up later.
5. Instantiate nested AtExitManagers only in a static build. In the component build we can use the shell's.
6. Adds a callback to notify the ViewManagerInitServiceImpl when the NativeViewport is destroyed. The VMISI uses this callback to close its connection to the view manager, which triggers the view manager to shut down.
Since this still crashes, I can't test this yet.
R=sky@chromium.org
http://crbug.com/325901
Review URL: https://codereview.chromium.org/372273004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282683 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo')
31 files changed, 155 insertions, 77 deletions
diff --git a/mojo/examples/aura_demo/aura_demo.cc b/mojo/examples/aura_demo/aura_demo.cc index 4f88dfb..263493f 100644 --- a/mojo/examples/aura_demo/aura_demo.cc +++ b/mojo/examples/aura_demo/aura_demo.cc @@ -152,6 +152,10 @@ class AuraDemo : public ApplicationDelegate, window_tree_host_->Show(); } + virtual void OnViewManagerDisconnected( + view_manager::ViewManager* view_manager) OVERRIDE { + base::MessageLoop::current()->Quit(); + } // WindowTreeHostMojoDelegate: virtual void CompositorContentsChanged(const SkBitmap& bitmap) OVERRIDE { diff --git a/mojo/examples/browser/browser.cc b/mojo/examples/browser/browser.cc index 1474556..ac6f5f1 100644 --- a/mojo/examples/browser/browser.cc +++ b/mojo/examples/browser/browser.cc @@ -205,6 +205,12 @@ class Browser : public ApplicationDelegate, root_->SetFocus(); CreateWidget(root_); } + virtual void OnViewManagerDisconnected( + view_manager::ViewManager* view_manager) OVERRIDE { + DCHECK_EQ(view_manager_, view_manager); + view_manager_ = NULL; + base::MessageLoop::current()->Quit(); + } // views::TextfieldController: virtual bool HandleKeyEvent(views::Textfield* sender, @@ -232,6 +238,10 @@ class Browser : public ApplicationDelegate, else if (gained_focus == root_) focus_client->FocusWindow(widget_->GetNativeView()); } + virtual void OnNodeDestroyed(view_manager::Node* node) OVERRIDE { + DCHECK_EQ(root_, node); + node->RemoveObserver(this); + } scoped_ptr<ViewsInit> views_init_; diff --git a/mojo/examples/compositor_app/compositor_app.cc b/mojo/examples/compositor_app/compositor_app.cc index 6a5a8c4..54aa235 100644 --- a/mojo/examples/compositor_app/compositor_app.cc +++ b/mojo/examples/compositor_app/compositor_app.cc @@ -39,8 +39,9 @@ class SampleApp : public ApplicationDelegate, public NativeViewportClient { virtual void OnCreated() OVERRIDE { } - virtual void OnDestroyed() OVERRIDE { + virtual void OnDestroyed(const mojo::Callback<void()>& callback) OVERRIDE { base::MessageLoop::current()->Quit(); + callback.Run(); } virtual void OnBoundsChanged(RectPtr bounds) OVERRIDE { diff --git a/mojo/examples/embedded_app/embedded_app.cc b/mojo/examples/embedded_app/embedded_app.cc index 7ee4777..631d67c 100644 --- a/mojo/examples/embedded_app/embedded_app.cc +++ b/mojo/examples/embedded_app/embedded_app.cc @@ -5,6 +5,7 @@ #include "base/basictypes.h" #include "base/bind.h" #include "base/logging.h" +#include "base/message_loop/message_loop.h" #include "base/strings/string_number_conversions.h" #include "mojo/public/cpp/application/application_connection.h" #include "mojo/public/cpp/application/application_delegate.h" @@ -97,6 +98,9 @@ class EmbeddedApp : public ApplicationDelegate, roots_[root->id()] = root; ProcessPendingNodeColor(root->id()); } + virtual void OnViewManagerDisconnected(ViewManager* view_manager) OVERRIDE { + base::MessageLoop::current()->Quit(); + } // Overridden from ViewObserver: virtual void OnViewInputEvent(View* view, const EventPtr& event) OVERRIDE { diff --git a/mojo/examples/html_viewer/html_viewer.cc b/mojo/examples/html_viewer/html_viewer.cc index 9a947f4..9fbf3a4 100644 --- a/mojo/examples/html_viewer/html_viewer.cc +++ b/mojo/examples/html_viewer/html_viewer.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/message_loop/message_loop.h" #include "mojo/examples/html_viewer/blink_platform_impl.h" #include "mojo/examples/html_viewer/html_document_view.h" #include "mojo/public/cpp/application/application_connection.h" @@ -77,6 +78,10 @@ class HTMLViewer : public ApplicationDelegate, document_view_->AttachToNode(root); MaybeLoad(); } + virtual void OnViewManagerDisconnected( + view_manager::ViewManager* view_manager) OVERRIDE { + base::MessageLoop::current()->Quit(); + } void MaybeLoad() { if (document_view_ && response_.get()) diff --git a/mojo/examples/keyboard/keyboard.cc b/mojo/examples/keyboard/keyboard.cc index 0941d05..0b76f39 100644 --- a/mojo/examples/keyboard/keyboard.cc +++ b/mojo/examples/keyboard/keyboard.cc @@ -93,6 +93,12 @@ class Keyboard : public ApplicationDelegate, root->SetActiveView(view_manager::View::Create(view_manager)); CreateWidget(root); } + virtual void OnViewManagerDisconnected( + view_manager::ViewManager* view_manager) OVERRIDE { + DCHECK_EQ(view_manager_, view_manager); + view_manager_ = NULL; + base::MessageLoop::current()->Quit(); + } // KeyboardDelegate: virtual void OnKeyPressed(int key_code, int event_flags) OVERRIDE { diff --git a/mojo/examples/media_viewer/media_viewer.cc b/mojo/examples/media_viewer/media_viewer.cc index 2470c46..58cb3ed 100644 --- a/mojo/examples/media_viewer/media_viewer.cc +++ b/mojo/examples/media_viewer/media_viewer.cc @@ -297,6 +297,12 @@ class MediaViewer : public ApplicationDelegate, request->response_details.Pass()); } } + virtual void OnViewManagerDisconnected( + view_manager::ViewManager* view_manager) OVERRIDE { + DCHECK_EQ(view_manager_, view_manager); + view_manager_ = NULL; + base::MessageLoop::current()->Quit(); + } // Overridden from ControlPanel::Delegate: virtual void ButtonPressed(ControlPanel::ControlType type) OVERRIDE { diff --git a/mojo/examples/nesting_app/nesting_app.cc b/mojo/examples/nesting_app/nesting_app.cc index f0b6763..9b488d2 100644 --- a/mojo/examples/nesting_app/nesting_app.cc +++ b/mojo/examples/nesting_app/nesting_app.cc @@ -4,6 +4,7 @@ #include "base/basictypes.h" #include "base/bind.h" +#include "base/message_loop/message_loop.h" #include "base/strings/stringprintf.h" #include "mojo/examples/window_manager/window_manager.mojom.h" #include "mojo/public/cpp/application/application_connection.h" @@ -94,6 +95,9 @@ class NestingApp : public ApplicationDelegate, NavigateChild(); } + virtual void OnViewManagerDisconnected(ViewManager* view_manager) OVERRIDE { + base::MessageLoop::current()->Quit(); + } // Overridden from ViewObserver: virtual void OnViewInputEvent(View* view, const EventPtr& event) OVERRIDE { diff --git a/mojo/examples/pepper_container_app/pepper_container_app.cc b/mojo/examples/pepper_container_app/pepper_container_app.cc index dc4a9ce..cec08cd 100644 --- a/mojo/examples/pepper_container_app/pepper_container_app.cc +++ b/mojo/examples/pepper_container_app/pepper_container_app.cc @@ -55,7 +55,7 @@ class PepperContainerApp: public ApplicationDelegate, plugin_instance_.reset(); } - virtual void OnDestroyed() OVERRIDE { + virtual void OnDestroyed(const mojo::Callback<void()>& callback) OVERRIDE { ppapi::ProxyAutoLock lock; if (plugin_instance_) { @@ -64,6 +64,7 @@ class PepperContainerApp: public ApplicationDelegate, } base::MessageLoop::current()->Quit(); + callback.Run(); } virtual void OnBoundsChanged(RectPtr bounds) OVERRIDE { diff --git a/mojo/examples/png_viewer/png_viewer.cc b/mojo/examples/png_viewer/png_viewer.cc index cc2cd5d..a6f8741 100644 --- a/mojo/examples/png_viewer/png_viewer.cc +++ b/mojo/examples/png_viewer/png_viewer.cc @@ -4,6 +4,7 @@ #include <algorithm> +#include "base/message_loop/message_loop.h" #include "base/strings/string_tokenizer.h" #include "mojo/examples/media_viewer/media_viewer.mojom.h" #include "mojo/public/cpp/application/application_connection.h" @@ -166,6 +167,10 @@ class PNGViewer : public ApplicationDelegate, if (!bitmap_.isNull()) DrawBitmap(); } + virtual void OnViewManagerDisconnected( + view_manager::ViewManager* view_manager) OVERRIDE { + base::MessageLoop::current()->Quit(); + } void DrawBitmap() { if (!content_view_) diff --git a/mojo/examples/sample_app/sample_app.cc b/mojo/examples/sample_app/sample_app.cc index c5a57ab..cfc9ef7 100644 --- a/mojo/examples/sample_app/sample_app.cc +++ b/mojo/examples/sample_app/sample_app.cc @@ -48,8 +48,10 @@ class SampleApp : public ApplicationDelegate, public NativeViewportClient { virtual void OnCreated() MOJO_OVERRIDE { } - virtual void OnDestroyed() MOJO_OVERRIDE { + virtual void OnDestroyed( + const mojo::Callback<void()>& callback) MOJO_OVERRIDE { RunLoop::current()->Quit(); + callback.Run(); } virtual void OnBoundsChanged(RectPtr bounds) MOJO_OVERRIDE { diff --git a/mojo/examples/window_manager/window_manager.cc b/mojo/examples/window_manager/window_manager.cc index 5f1e843..b23e908 100644 --- a/mojo/examples/window_manager/window_manager.cc +++ b/mojo/examples/window_manager/window_manager.cc @@ -18,7 +18,6 @@ #include "mojo/services/public/cpp/view_manager/view_event_dispatcher.h" #include "mojo/services/public/cpp/view_manager/view_manager.h" #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" -#include "mojo/services/public/cpp/view_manager/view_observer.h" #include "mojo/services/public/interfaces/input_events/input_events.mojom.h" #include "mojo/services/public/interfaces/launcher/launcher.mojom.h" #include "mojo/services/public/interfaces/navigation/navigation.mojom.h" @@ -189,7 +188,6 @@ class RootLayoutManager : public NodeObserver { class WindowManager : public ApplicationDelegate, public DebugPanel::Delegate, - public ViewObserver, public ViewManagerDelegate, public ViewEventDispatcher { public: @@ -280,23 +278,27 @@ class WindowManager : public ApplicationDelegate, view_manager_ = view_manager; view_manager_->SetEventDispatcher(this); - Node* node = Node::Create(view_manager); + Node* node = Node::Create(view_manager_); root->AddChild(node); node->SetBounds(gfx::Rect(root->bounds().size())); content_node_id_ = node->id(); root_layout_manager_.reset( - new RootLayoutManager(view_manager, root, content_node_id_)); + new RootLayoutManager(view_manager_, root, content_node_id_)); root->AddObserver(root_layout_manager_.get()); - View* view = View::Create(view_manager); + View* view = View::Create(view_manager_); node->SetActiveView(view); view->SetColor(SK_ColorBLUE); - view->AddObserver(this); CreateLauncherUI(); CreateControlPanel(node); } + virtual void OnViewManagerDisconnected(ViewManager* view_manager) OVERRIDE { + DCHECK_EQ(view_manager_, view_manager); + view_manager_ = NULL; + base::MessageLoop::current()->Quit(); + } // Overridden from ViewEventDispatcher: virtual void DispatchEvent(View* target, EventPtr event) OVERRIDE { diff --git a/mojo/public/cpp/application/lib/mojo_main_chromium.cc b/mojo/public/cpp/application/lib/mojo_main_chromium.cc index 6eb0c63..269b7a2 100644 --- a/mojo/public/cpp/application/lib/mojo_main_chromium.cc +++ b/mojo/public/cpp/application/lib/mojo_main_chromium.cc @@ -11,7 +11,9 @@ extern "C" APPLICATION_EXPORT MojoResult CDECL MojoMain( MojoHandle shell_handle) { base::CommandLine::Init(0, NULL); +#if !defined(COMPONENT_BUILD) base::AtExitManager at_exit; +#endif base::MessageLoop loop; scoped_ptr<mojo::ApplicationDelegate> delegate( mojo::ApplicationDelegate::Create()); diff --git a/mojo/services/native_viewport/native_viewport_service.cc b/mojo/services/native_viewport/native_viewport_service.cc index 1db489b..b7c8052 100644 --- a/mojo/services/native_viewport/native_viewport_service.cc +++ b/mojo/services/native_viewport/native_viewport_service.cc @@ -137,12 +137,15 @@ class NativeViewportImpl } virtual void OnDestroyed() OVERRIDE { - command_buffer_.reset(); - client()->OnDestroyed(); - base::MessageLoop::current()->Quit(); + client()->OnDestroyed(base::Bind(&NativeViewportImpl::AckDestroyed, + base::Unretained(this))); } private: + void AckDestroyed() { + command_buffer_.reset(); + } + shell::Context* context_; gfx::AcceleratedWidget widget_; scoped_ptr<services::NativeViewport> native_viewport_; diff --git a/mojo/services/network/main.cc b/mojo/services/network/main.cc index 3cfc74f..a3f397d 100644 --- a/mojo/services/network/main.cc +++ b/mojo/services/network/main.cc @@ -62,7 +62,9 @@ class Delegate : public mojo::ApplicationDelegate { extern "C" APPLICATION_EXPORT MojoResult CDECL MojoMain( MojoHandle shell_handle) { base::CommandLine::Init(0, NULL); +#if !defined(COMPONENT_BUILD) base::AtExitManager at_exit; +#endif // The IO message loop allows us to use net::URLRequest on this thread. base::MessageLoopForIO loop; diff --git a/mojo/services/public/cpp/view_manager/lib/node.cc b/mojo/services/public/cpp/view_manager/lib/node.cc index 3f704d5..9a60bbb 100644 --- a/mojo/services/public/cpp/view_manager/lib/node.cc +++ b/mojo/services/public/cpp/view_manager/lib/node.cc @@ -194,26 +194,6 @@ class ScopedSetBoundsNotifier { DISALLOW_COPY_AND_ASSIGN(ScopedSetBoundsNotifier); }; -class ScopedDestructionNotifier { - public: - explicit ScopedDestructionNotifier(Node* node) - : node_(node) { - FOR_EACH_OBSERVER(NodeObserver, - *NodePrivate(node_).observers(), - OnNodeDestroying(node_)); - } - ~ScopedDestructionNotifier() { - FOR_EACH_OBSERVER(NodeObserver, - *NodePrivate(node_).observers(), - OnNodeDestroyed(node_)); - } - - private: - Node* node_; - - DISALLOW_COPY_AND_ASSIGN(ScopedDestructionNotifier); -}; - // Some operations are only permitted in the connection that created the node. bool OwnsNode(ViewManager* manager, Node* node) { return !manager || @@ -359,13 +339,14 @@ Node::Node() active_view_(NULL) {} Node::~Node() { - ScopedDestructionNotifier notifier(this); + FOR_EACH_OBSERVER(NodeObserver, observers_, OnNodeDestroying(this)); if (parent_) parent_->LocalRemoveChild(this); // TODO(beng): It'd be better to do this via a destruction observer in the // ViewManagerClientImpl. if (manager_) static_cast<ViewManagerClientImpl*>(manager_)->RemoveNode(id_); + FOR_EACH_OBSERVER(NodeObserver, observers_, OnNodeDestroyed(this)); } //////////////////////////////////////////////////////////////////////////////// diff --git a/mojo/services/public/cpp/view_manager/lib/view.cc b/mojo/services/public/cpp/view_manager/lib/view.cc index 43ac6e9..16cae6f 100644 --- a/mojo/services/public/cpp/view_manager/lib/view.cc +++ b/mojo/services/public/cpp/view_manager/lib/view.cc @@ -13,28 +13,6 @@ namespace mojo { namespace view_manager { -namespace { -class ScopedDestructionNotifier { - public: - explicit ScopedDestructionNotifier(View* view) - : view_(view) { - FOR_EACH_OBSERVER(ViewObserver, - *ViewPrivate(view_).observers(), - OnViewDestroying(view_)); - } - ~ScopedDestructionNotifier() { - FOR_EACH_OBSERVER(ViewObserver, - *ViewPrivate(view_).observers(), - OnViewDestroyed(view_)); - } - - private: - View* view_; - - DISALLOW_COPY_AND_ASSIGN(ScopedDestructionNotifier); -}; -} // namespace - // static View* View::Create(ViewManager* manager) { View* view = new View(manager); @@ -80,11 +58,13 @@ View::View() manager_(NULL) {} View::~View() { - ScopedDestructionNotifier notifier(this); + FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDestroying(this)); // TODO(beng): It'd be better to do this via a destruction observer in the // ViewManagerClientImpl. if (manager_) static_cast<ViewManagerClientImpl*>(manager_)->RemoveView(id_); + + FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDestroyed(this)); } void View::LocalDestroy() { diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.cc index 4dfcd55..d45fab8 100644 --- a/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.cc +++ b/mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.cc @@ -97,6 +97,7 @@ class RootObserver : public NodeObserver { DCHECK_EQ(node, root_); static_cast<ViewManagerClientImpl*>( NodePrivate(root_).view_manager())->RemoveRoot(root_); + node->RemoveObserver(this); delete this; } @@ -535,6 +536,7 @@ ViewManagerClientImpl::ViewManagerClientImpl(ApplicationConnection* connection, dispatcher_(NULL) {} ViewManagerClientImpl::~ViewManagerClientImpl() { + delegate_->OnViewManagerDisconnected(this); while (!nodes_.empty()) { IdToNodeMap::iterator it = nodes_.begin(); if (OwnsNode(it->second->id())) diff --git a/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc b/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc index 7555894..31d5618 100644 --- a/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc +++ b/mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc @@ -83,6 +83,7 @@ class ConnectServiceLoader : public ServiceLoader, Node* root) OVERRIDE { callback_.Run(view_manager, root); } + virtual void OnViewManagerDisconnected(ViewManager* view_manager) OVERRIDE {} ScopedVector<ApplicationImpl> apps_; LoadedCallback callback_; diff --git a/mojo/services/public/cpp/view_manager/view_manager_delegate.h b/mojo/services/public/cpp/view_manager/view_manager_delegate.h index bceee02..d765bda 100644 --- a/mojo/services/public/cpp/view_manager/view_manager_delegate.h +++ b/mojo/services/public/cpp/view_manager/view_manager_delegate.h @@ -13,7 +13,8 @@ class ViewManager; class ViewManagerDelegate { public: - virtual void OnRootAdded(ViewManager* view_manager, Node* root) {} + virtual void OnRootAdded(ViewManager* view_manager, Node* root) = 0; + virtual void OnViewManagerDisconnected(ViewManager* view_manager) = 0; protected: virtual ~ViewManagerDelegate() {} diff --git a/mojo/services/public/interfaces/native_viewport/native_viewport.mojom b/mojo/services/public/interfaces/native_viewport/native_viewport.mojom index ed12feb..b168104 100644 --- a/mojo/services/public/interfaces/native_viewport/native_viewport.mojom +++ b/mojo/services/public/interfaces/native_viewport/native_viewport.mojom @@ -21,7 +21,7 @@ interface NativeViewport { interface NativeViewportClient { OnCreated(); OnBoundsChanged(Rect bounds); - OnDestroyed(); + OnDestroyed() => (); OnEvent(Event event) => (); }; diff --git a/mojo/services/view_manager/root_node_manager.cc b/mojo/services/view_manager/root_node_manager.cc index 612e3ed..4da2184 100644 --- a/mojo/services/view_manager/root_node_manager.cc +++ b/mojo/services/view_manager/root_node_manager.cc @@ -42,12 +42,17 @@ RootNodeManager::Context::~Context() { aura::Env::DeleteInstance(); } -RootNodeManager::RootNodeManager(ApplicationConnection* app_connection, - RootViewManagerDelegate* view_manager_delegate) +RootNodeManager::RootNodeManager( + ApplicationConnection* app_connection, + RootViewManagerDelegate* view_manager_delegate, + const Callback<void()>& native_viewport_closed_callback) : app_connection_(app_connection), next_connection_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, + native_viewport_closed_callback), root_(new Node(this, RootNodeId())), current_change_(NULL) { } diff --git a/mojo/services/view_manager/root_node_manager.h b/mojo/services/view_manager/root_node_manager.h index 12a862b..b2f21a7 100644 --- a/mojo/services/view_manager/root_node_manager.h +++ b/mojo/services/view_manager/root_node_manager.h @@ -82,7 +82,8 @@ class MOJO_VIEW_MANAGER_EXPORT RootNodeManager }; RootNodeManager(ApplicationConnection* app_connection, - RootViewManagerDelegate* view_manager_delegate); + RootViewManagerDelegate* view_manager_delegate, + const Callback<void()>& native_viewport_closed_callback); virtual ~RootNodeManager(); // Returns the id for the next ViewManagerServiceImpl. diff --git a/mojo/services/view_manager/root_view_manager.cc b/mojo/services/view_manager/root_view_manager.cc index 6e7baf0..8b70cd8 100644 --- a/mojo/services/view_manager/root_view_manager.cc +++ b/mojo/services/view_manager/root_view_manager.cc @@ -116,9 +116,11 @@ class WindowTreeClientImpl : public aura::client::WindowTreeClient { DISALLOW_COPY_AND_ASSIGN(WindowTreeClientImpl); }; -RootViewManager::RootViewManager(ApplicationConnection* app_connection, - RootNodeManager* root_node, - RootViewManagerDelegate* delegate) +RootViewManager::RootViewManager( + ApplicationConnection* app_connection, + RootNodeManager* root_node, + RootViewManagerDelegate* delegate, + const Callback<void()>& native_viewport_closed_callback) : delegate_(delegate), root_node_manager_(root_node), in_setup_(false) { @@ -131,7 +133,8 @@ RootViewManager::RootViewManager(ApplicationConnection* app_connection, viewport.Pass(), gfx::Rect(800, 600), base::Bind(&RootViewManager::OnCompositorCreated, - base::Unretained(this)))); + base::Unretained(this)), + native_viewport_closed_callback)); } RootViewManager::~RootViewManager() { diff --git a/mojo/services/view_manager/root_view_manager.h b/mojo/services/view_manager/root_view_manager.h index 8eb3eb5..5215de9 100644 --- a/mojo/services/view_manager/root_view_manager.h +++ b/mojo/services/view_manager/root_view_manager.h @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" +#include "mojo/public/cpp/bindings/callback.h" #include "mojo/public/cpp/gles2/gles2.h" #include "mojo/services/view_manager/view_manager_export.h" @@ -39,7 +40,8 @@ class MOJO_VIEW_MANAGER_EXPORT RootViewManager { public: RootViewManager(ApplicationConnection* app_connection, RootNodeManager* root_node, - RootViewManagerDelegate* delegate); + RootViewManagerDelegate* delegate, + const Callback<void()>& native_viewport_closed_callback); virtual ~RootViewManager(); // See description above field for details. diff --git a/mojo/services/view_manager/view_manager_init_service_impl.cc b/mojo/services/view_manager/view_manager_init_service_impl.cc index 28c7beb..9cb337b 100644 --- a/mojo/services/view_manager/view_manager_init_service_impl.cc +++ b/mojo/services/view_manager/view_manager_init_service_impl.cc @@ -4,6 +4,7 @@ #include "mojo/services/view_manager/view_manager_init_service_impl.h" +#include "base/bind.h" #include "mojo/public/interfaces/service_provider/service_provider.mojom.h" #include "mojo/services/view_manager/ids.h" #include "mojo/services/view_manager/view_manager_service_impl.h" @@ -19,7 +20,11 @@ ViewManagerInitServiceImpl::ConnectParams::~ConnectParams() {} ViewManagerInitServiceImpl::ViewManagerInitServiceImpl( ApplicationConnection* connection) - : root_node_manager_(connection, this), + : root_node_manager_( + connection, + this, + base::Bind(&ViewManagerInitServiceImpl::OnNativeViewportDeleted, + base::Unretained(this))), is_tree_host_ready_(false) { } @@ -57,6 +62,13 @@ void ViewManagerInitServiceImpl::OnRootViewManagerWindowTreeHostCreated() { MaybeEmbedRoot(connect_params_->url, connect_params_->callback); } +void ViewManagerInitServiceImpl::OnNativeViewportDeleted() { + // TODO(beng): Should not have to rely on implementation detail of + // InterfaceImpl to close the connection. Instead should simply + // be able to delete this object. + internal_state()->router()->CloseMessagePipe(); +} + } // namespace service } // namespace view_manager } // namespace mojo diff --git a/mojo/services/view_manager/view_manager_init_service_impl.h b/mojo/services/view_manager/view_manager_init_service_impl.h index b3a0964..b9b5b3b 100644 --- a/mojo/services/view_manager/view_manager_init_service_impl.h +++ b/mojo/services/view_manager/view_manager_init_service_impl.h @@ -57,6 +57,8 @@ class MOJO_VIEW_MANAGER_EXPORT ViewManagerInitServiceImpl // RootViewManagerDelegate overrides: virtual void OnRootViewManagerWindowTreeHostCreated() OVERRIDE; + void OnNativeViewportDeleted(); + ServiceProvider* service_provider_; RootNodeManager root_node_manager_; diff --git a/mojo/services/view_manager/window_tree_host_impl.cc b/mojo/services/view_manager/window_tree_host_impl.cc index 5ef5da4..05d82d2 100644 --- a/mojo/services/view_manager/window_tree_host_impl.cc +++ b/mojo/services/view_manager/window_tree_host_impl.cc @@ -68,9 +68,11 @@ void RootLayoutManager::SetChildBounds(aura::Window* child, WindowTreeHostImpl::WindowTreeHostImpl( NativeViewportPtr viewport, const gfx::Rect& bounds, - const base::Callback<void()>& compositor_created_callback) + const Callback<void()>& compositor_created_callback, + const Callback<void()>& native_viewport_closed_callback) : native_viewport_(viewport.Pass()), compositor_created_callback_(compositor_created_callback), + native_viewport_closed_callback_(native_viewport_closed_callback), bounds_(bounds) { native_viewport_.set_client(this); native_viewport_->Create(Rect::From(bounds)); @@ -178,8 +180,11 @@ void WindowTreeHostImpl::OnBoundsChanged(RectPtr bounds) { OnHostResized(bounds_.size()); } -void WindowTreeHostImpl::OnDestroyed() { - base::MessageLoop::current()->Quit(); +void WindowTreeHostImpl::OnDestroyed(const mojo::Callback<void()>& callback) { + DestroyCompositor(); + native_viewport_closed_callback_.Run(); + // TODO(beng): quit the message loop once we are on our own thread. + callback.Run(); } void WindowTreeHostImpl::OnEvent(EventPtr event, diff --git a/mojo/services/view_manager/window_tree_host_impl.h b/mojo/services/view_manager/window_tree_host_impl.h index fc4b12eb..f54f514 100644 --- a/mojo/services/view_manager/window_tree_host_impl.h +++ b/mojo/services/view_manager/window_tree_host_impl.h @@ -25,9 +25,11 @@ class WindowTreeHostImpl : public aura::WindowTreeHost, public ui::EventSource, public NativeViewportClient { public: - WindowTreeHostImpl(NativeViewportPtr viewport, - const gfx::Rect& bounds, - const base::Callback<void()>& compositor_created_callback); + WindowTreeHostImpl( + NativeViewportPtr viewport, + const gfx::Rect& bounds, + const Callback<void()>& compositor_created_callback, + const Callback<void()>& native_viewport_closed_callback); virtual ~WindowTreeHostImpl(); gfx::Rect bounds() const { return bounds_; } @@ -54,7 +56,7 @@ class WindowTreeHostImpl : public aura::WindowTreeHost, // Overridden from NativeViewportClient: virtual void OnCreated() OVERRIDE; - virtual void OnDestroyed() OVERRIDE; + virtual void OnDestroyed(const mojo::Callback<void()>& callback) OVERRIDE; virtual void OnBoundsChanged(RectPtr bounds) OVERRIDE; virtual void OnEvent(EventPtr event, const mojo::Callback<void()>& callback) OVERRIDE; @@ -62,7 +64,8 @@ class WindowTreeHostImpl : public aura::WindowTreeHost, static ContextFactoryImpl* context_factory_; NativeViewportPtr native_viewport_; - base::Callback<void()> compositor_created_callback_; + Callback<void()> compositor_created_callback_; + Callback<void()> native_viewport_closed_callback_; gfx::Rect bounds_; diff --git a/mojo/views/native_widget_view_manager.cc b/mojo/views/native_widget_view_manager.cc index a903e2b..36a6578 100644 --- a/mojo/views/native_widget_view_manager.cc +++ b/mojo/views/native_widget_view_manager.cc @@ -91,6 +91,7 @@ NativeWidgetViewManager::NativeWidgetViewManager( views::internal::NativeWidgetDelegate* delegate, view_manager::Node* node) : NativeWidgetAura(delegate), node_(node) { + node_->AddObserver(this); node_->active_view()->AddObserver(this); window_tree_host_.reset(new WindowTreeHostMojo(node_, this)); window_tree_host_->InitHost(); @@ -112,7 +113,9 @@ NativeWidgetViewManager::NativeWidgetViewManager( } NativeWidgetViewManager::~NativeWidgetViewManager() { - node_->active_view()->RemoveObserver(this); + if (node_->active_view()) + node_->active_view()->RemoveObserver(this); + node_->RemoveObserver(this); } void NativeWidgetViewManager::InitNativeWidget( @@ -129,6 +132,20 @@ void NativeWidgetViewManager::CompositorContentsChanged( node_->active_view()->SetContents(bitmap); } +void NativeWidgetViewManager::OnNodeDestroyed(view_manager::Node* node) { + window_tree_host_.reset(); +} + +void NativeWidgetViewManager::OnNodeActiveViewChanged( + view_manager::Node* node, + view_manager::View* old_view, + view_manager::View* new_view) { + if (old_view) + old_view->RemoveObserver(this); + if (new_view) + new_view->AddObserver(this); +} + void NativeWidgetViewManager::OnViewInputEvent(view_manager::View* view, const EventPtr& event) { scoped_ptr<ui::Event> ui_event(event.To<scoped_ptr<ui::Event> >()); diff --git a/mojo/views/native_widget_view_manager.h b/mojo/views/native_widget_view_manager.h index c8fa2c9..b8050f3 100644 --- a/mojo/views/native_widget_view_manager.h +++ b/mojo/views/native_widget_view_manager.h @@ -42,6 +42,12 @@ class NativeWidgetViewManager : public views::NativeWidgetAura, // WindowTreeHostMojoDelegate: virtual void CompositorContentsChanged(const SkBitmap& bitmap) OVERRIDE; + // view_manager::NodeObserver: + virtual void OnNodeDestroyed(view_manager::Node* node) OVERRIDE; + virtual void OnNodeActiveViewChanged(view_manager::Node* node, + view_manager::View* old_view, + view_manager::View* new_view) OVERRIDE; + // view_manager::ViewObserver virtual void OnViewInputEvent(view_manager::View* view, const EventPtr& event) OVERRIDE; |