Adds a ServerViewObserver interface
I kept ServerViewDelegate too as the two interfaces are not
exactly the same, and I didn't want the Observer interface to take
non-const arguments.
R=ben@chromium.org
Review URL: https://codereview.chromium.org/1082943002
diff --git a/services/view_manager/BUILD.gn b/services/view_manager/BUILD.gn
index f210a81..74e9db2 100644
--- a/services/view_manager/BUILD.gn
+++ b/services/view_manager/BUILD.gn
@@ -47,6 +47,7 @@
"server_view.cc",
"server_view.h",
"server_view_delegate.h",
+ "server_view_observer.h",
"view_coordinate_conversions.cc",
"view_coordinate_conversions.h",
"view_manager_service_impl.cc",
diff --git a/services/view_manager/connection_manager.cc b/services/view_manager/connection_manager.cc
index 190c061..1df3945 100644
--- a/services/view_manager/connection_manager.cc
+++ b/services/view_manager/connection_manager.cc
@@ -116,7 +116,7 @@
window_manager_client_connection_(nullptr),
next_connection_id_(1),
display_manager_(display_manager.Pass()),
- root_(new ServerView(this, RootViewId())),
+ root_(CreateServerView(RootViewId())),
wm_internal_(wm_internal),
current_change_(nullptr),
in_destructor_(false),
@@ -135,6 +135,12 @@
root_.reset();
}
+ServerView* ConnectionManager::CreateServerView(const ViewId& id) {
+ ServerView* view = new ServerView(this, id);
+ view->AddObserver(this);
+ return view;
+}
+
ConnectionSpecificId ConnectionManager::GetAndAdvanceNextConnectionId() {
const ConnectionSpecificId id = next_connection_id_++;
DCHECK_LT(id, next_connection_id_);
@@ -340,7 +346,7 @@
connection_map_[connection->service()->id()] = connection;
}
-void ConnectionManager::OnWillDestroyView(ServerView* view) {
+void ConnectionManager::PrepareToDestroyView(ServerView* view) {
if (!in_destructor_ && root_->Contains(view) && view != root_.get() &&
view->id() != ClonedViewId()) {
// We're about to destroy a view. Any cloned views need to be reparented
@@ -353,14 +359,9 @@
animation_runner_.CancelAnimationForView(view);
}
-void ConnectionManager::OnViewDestroyed(const ServerView* view) {
- if (!in_destructor_)
- ProcessViewDeleted(view->id());
-}
-
-void ConnectionManager::OnWillChangeViewHierarchy(ServerView* view,
- ServerView* new_parent,
- ServerView* old_parent) {
+void ConnectionManager::PrepareToChangeViewHierarchy(ServerView* view,
+ ServerView* new_parent,
+ ServerView* old_parent) {
if (view->id() == ClonedViewId() || in_destructor_)
return;
@@ -373,11 +374,47 @@
ReparentClonedViews(view->parent(), &parent_above, view);
}
- ProcessWillChangeViewHierarchy(view, new_parent, old_parent);
-
animation_runner_.CancelAnimationForView(view);
}
+void ConnectionManager::PrepareToChangeViewVisibility(ServerView* view) {
+ if (in_destructor_)
+ return;
+
+ if (view != root_.get() && view->id() != ClonedViewId() &&
+ root_->Contains(view) && view->IsDrawn(root_.get())) {
+ // We're about to hide |view|, this would implicitly make any cloned views
+ // hide too. Reparent so that animations are still visible.
+ ServerView* parent_above = view;
+ ReparentClonedViews(view->parent(), &parent_above, view);
+ }
+
+ const bool is_parent_drawn =
+ view->parent() && view->parent()->IsDrawn(root_.get());
+ if (!is_parent_drawn || !view->visible())
+ animation_runner_.CancelAnimationForView(view);
+}
+
+void ConnectionManager::OnScheduleViewPaint(const ServerView* view) {
+ if (!in_destructor_)
+ display_manager_->SchedulePaint(view, gfx::Rect(view->bounds().size()));
+}
+
+void ConnectionManager::OnViewDestroyed(const ServerView* view) {
+ if (!in_destructor_)
+ ProcessViewDeleted(view->id());
+}
+
+void ConnectionManager::OnWillChangeViewHierarchy(
+ const ServerView* view,
+ const ServerView* new_parent,
+ const ServerView* old_parent) {
+ if (view->id() == ClonedViewId() || in_destructor_)
+ return;
+
+ ProcessWillChangeViewHierarchy(view, new_parent, old_parent);
+}
+
void ConnectionManager::OnViewHierarchyChanged(const ServerView* view,
const ServerView* new_parent,
const ServerView* old_parent) {
@@ -412,11 +449,6 @@
display_manager_->SchedulePaint(view->parent(), new_bounds);
}
-void ConnectionManager::OnViewSurfaceIdChanged(const ServerView* view) {
- if (!in_destructor_)
- display_manager_->SchedulePaint(view, gfx::Rect(view->bounds().size()));
-}
-
void ConnectionManager::OnViewReordered(const ServerView* view,
const ServerView* relative,
mojo::OrderDirection direction) {
@@ -424,34 +456,21 @@
display_manager_->SchedulePaint(view, gfx::Rect(view->bounds().size()));
}
-void ConnectionManager::OnWillChangeViewVisibility(ServerView* view) {
+void ConnectionManager::OnWillChangeViewVisibility(const ServerView* view) {
if (in_destructor_)
return;
- // Need to repaint if the view was drawn (which means it'll in the process of
+ // Need to repaint if the view was drawn (which means it's in the process of
// hiding) or the view is transitioning to drawn.
if (view->IsDrawn(root_.get()) || (!view->visible() && view->parent() &&
view->parent()->IsDrawn(root_.get()))) {
display_manager_->SchedulePaint(view->parent(), view->bounds());
}
- if (view != root_.get() && view->id() != ClonedViewId() &&
- root_->Contains(view) && view->IsDrawn(root_.get())) {
- // We're about to hide |view|, this would implicitly make any cloned views
- // hide to. Reparent so that animations are still visible.
- ServerView* parent_above = view;
- ReparentClonedViews(view->parent(), &parent_above, view);
- }
-
for (auto& pair : connection_map_) {
pair.second->service()->ProcessWillChangeViewVisibility(
view, IsChangeSource(pair.first));
}
-
- const bool is_parent_drawn =
- view->parent() && view->parent()->IsDrawn(root_.get());
- if (!is_parent_drawn || !view->visible())
- animation_runner_.CancelAnimationForView(view);
}
void ConnectionManager::OnViewSharedPropertyChanged(
@@ -464,11 +483,6 @@
}
}
-void ConnectionManager::OnScheduleViewPaint(const ServerView* view) {
- if (!in_destructor_)
- display_manager_->SchedulePaint(view, gfx::Rect(view->bounds().size()));
-}
-
void ConnectionManager::DispatchInputEventToView(mojo::Id transport_view_id,
mojo::EventPtr event) {
const ViewId view_id(ViewIdFromTransportId(transport_view_id));
diff --git a/services/view_manager/connection_manager.h b/services/view_manager/connection_manager.h
index c8ce54e..6ba1698 100644
--- a/services/view_manager/connection_manager.h
+++ b/services/view_manager/connection_manager.h
@@ -17,6 +17,7 @@
#include "services/view_manager/animation_runner.h"
#include "services/view_manager/ids.h"
#include "services/view_manager/server_view_delegate.h"
+#include "services/view_manager/server_view_observer.h"
namespace view_manager {
@@ -29,6 +30,7 @@
// ConnectionManager manages the set of connections to the ViewManager (all the
// ViewManagerServiceImpls) as well as providing the root of the hierarchy.
class ConnectionManager : public ServerViewDelegate,
+ public ServerViewObserver,
public mojo::WindowManagerInternalClient {
public:
// Create when a ViewManagerServiceImpl is about to make a change. Ensures
@@ -69,6 +71,10 @@
mojo::WindowManagerInternal* wm_internal);
~ConnectionManager() override;
+ // Creates a new ServerView. The return value is owned by the caller, but must
+ // be destroyed before ConnectionManager.
+ ServerView* CreateServerView(const ViewId& id);
+
// Returns the id for the next ViewManagerServiceImpl.
mojo::ConnectionSpecificId GetAndAdvanceNextConnectionId();
@@ -175,27 +181,32 @@
void DoAnimation();
// Overridden from ServerViewDelegate:
- void OnWillDestroyView(ServerView* view) override;
+ void PrepareToDestroyView(ServerView* view) override;
+ void PrepareToChangeViewHierarchy(ServerView* view,
+ ServerView* new_parent,
+ ServerView* old_parent) override;
+ void PrepareToChangeViewVisibility(ServerView* view) override;
+ void OnScheduleViewPaint(const ServerView* view) override;
+
+ // Overridden from ServerViewObserver:
void OnViewDestroyed(const ServerView* view) override;
- void OnWillChangeViewHierarchy(ServerView* view,
- ServerView* new_parent,
- ServerView* old_parent) override;
+ void OnWillChangeViewHierarchy(const ServerView* view,
+ const ServerView* new_parent,
+ const ServerView* old_parent) override;
void OnViewHierarchyChanged(const ServerView* view,
const ServerView* new_parent,
const ServerView* old_parent) override;
void OnViewBoundsChanged(const ServerView* view,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) override;
- void OnViewSurfaceIdChanged(const ServerView* view) override;
void OnViewReordered(const ServerView* view,
const ServerView* relative,
mojo::OrderDirection direction) override;
- void OnWillChangeViewVisibility(ServerView* view) override;
+ void OnWillChangeViewVisibility(const ServerView* view) override;
void OnViewSharedPropertyChanged(
const ServerView* view,
const std::string& name,
const std::vector<uint8_t>* new_data) override;
- void OnScheduleViewPaint(const ServerView* view) override;
// WindowManagerInternalClient:
void DispatchInputEventToView(mojo::Id transport_view_id,
diff --git a/services/view_manager/server_view.cc b/services/view_manager/server_view.cc
index 1774244..d6272d5 100644
--- a/services/view_manager/server_view.cc
+++ b/services/view_manager/server_view.cc
@@ -8,6 +8,7 @@
#include "base/strings/stringprintf.h"
#include "services/view_manager/server_view_delegate.h"
+#include "services/view_manager/server_view_observer.h"
namespace view_manager {
@@ -21,7 +22,8 @@
}
ServerView::~ServerView() {
- delegate_->OnWillDestroyView(this);
+ delegate_->PrepareToDestroyView(this);
+ FOR_EACH_OBSERVER(ServerViewObserver, observers_, OnWillDestroyView(this));
while (!children_.empty())
children_.front()->parent()->Remove(children_.front());
@@ -29,7 +31,15 @@
if (parent_)
parent_->Remove(this);
- delegate_->OnViewDestroyed(this);
+ FOR_EACH_OBSERVER(ServerViewObserver, observers_, OnViewDestroyed(this));
+}
+
+void ServerView::AddObserver(ServerViewObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void ServerView::RemoveObserver(ServerViewObserver* observer) {
+ observers_.RemoveObserver(observer);
}
void ServerView::Add(ServerView* child) {
@@ -45,13 +55,17 @@
}
ServerView* old_parent = child->parent();
- child->delegate_->OnWillChangeViewHierarchy(child, this, old_parent);
+ child->delegate_->PrepareToChangeViewHierarchy(child, this, old_parent);
+ FOR_EACH_OBSERVER(ServerViewObserver, child->observers_,
+ OnWillChangeViewHierarchy(child, this, old_parent));
+
if (child->parent())
child->parent()->RemoveImpl(child);
child->parent_ = this;
children_.push_back(child);
- child->delegate_->OnViewHierarchyChanged(child, this, old_parent);
+ FOR_EACH_OBSERVER(ServerViewObserver, child->observers_,
+ OnViewHierarchyChanged(child, this, old_parent));
}
void ServerView::Remove(ServerView* child) {
@@ -60,9 +74,12 @@
DCHECK(child != this);
DCHECK(child->parent() == this);
- child->delegate_->OnWillChangeViewHierarchy(child, NULL, this);
+ child->delegate_->PrepareToChangeViewHierarchy(child, NULL, this);
+ FOR_EACH_OBSERVER(ServerViewObserver, child->observers_,
+ OnWillChangeViewHierarchy(child, nullptr, this));
RemoveImpl(child);
- child->delegate_->OnViewHierarchyChanged(child, NULL, this);
+ FOR_EACH_OBSERVER(ServerViewObserver, child->observers_,
+ OnViewHierarchyChanged(child, nullptr, this));
}
void ServerView::Reorder(ServerView* child,
@@ -81,7 +98,8 @@
DCHECK(i != children_.end());
children_.insert(i, child);
}
- delegate_->OnViewReordered(this, relative, direction);
+ FOR_EACH_OBSERVER(ServerViewObserver, observers_,
+ OnViewReordered(this, relative, direction));
}
void ServerView::SetBounds(const gfx::Rect& bounds) {
@@ -90,7 +108,8 @@
const gfx::Rect old_bounds = bounds_;
bounds_ = bounds;
- delegate_->OnViewBoundsChanged(this, old_bounds, bounds);
+ FOR_EACH_OBSERVER(ServerViewObserver, observers_,
+ OnViewBoundsChanged(this, old_bounds, bounds));
}
const ServerView* ServerView::GetRoot() const {
@@ -125,7 +144,9 @@
if (visible_ == value)
return;
- delegate_->OnWillChangeViewVisibility(this);
+ delegate_->PrepareToChangeViewVisibility(this);
+ FOR_EACH_OBSERVER(ServerViewObserver, observers_,
+ OnWillChangeViewVisibility(this));
visible_ = value;
}
@@ -162,7 +183,8 @@
properties_.erase(it);
}
- delegate_->OnViewSharedPropertyChanged(this, name, value);
+ FOR_EACH_OBSERVER(ServerViewObserver, observers_,
+ OnViewSharedPropertyChanged(this, name, value));
}
bool ServerView::IsDrawn(const ServerView* root) const {
@@ -176,7 +198,7 @@
void ServerView::SetSurfaceId(cc::SurfaceId surface_id) {
surface_id_ = surface_id;
- delegate_->OnViewSurfaceIdChanged(this);
+ delegate_->OnScheduleViewPaint(this);
}
#if !defined(NDEBUG)
diff --git a/services/view_manager/server_view.h b/services/view_manager/server_view.h
index 03842e7..f0050a4 100644
--- a/services/view_manager/server_view.h
+++ b/services/view_manager/server_view.h
@@ -8,6 +8,7 @@
#include <vector>
#include "base/logging.h"
+#include "base/observer_list.h"
#include "cc/surfaces/surface_id.h"
#include "mojo/services/view_manager/public/interfaces/view_manager.mojom.h"
#include "services/view_manager/ids.h"
@@ -17,6 +18,7 @@
namespace view_manager {
class ServerViewDelegate;
+class ServerViewObserver;
// Server side representation of a view. Delegate is informed of interesting
// events.
@@ -29,6 +31,9 @@
ServerView(ServerViewDelegate* delegate, const ViewId& id);
virtual ~ServerView();
+ void AddObserver(ServerViewObserver* observer);
+ void RemoveObserver(ServerViewObserver* observer);
+
const ViewId& id() const { return id_; }
void Add(ServerView* child);
@@ -101,6 +106,8 @@
std::map<std::string, std::vector<uint8_t>> properties_;
+ ObserverList<ServerViewObserver> observers_;
+
DISALLOW_COPY_AND_ASSIGN(ServerView);
};
diff --git a/services/view_manager/server_view_delegate.h b/services/view_manager/server_view_delegate.h
index d05a77e..97c14cc 100644
--- a/services/view_manager/server_view_delegate.h
+++ b/services/view_manager/server_view_delegate.h
@@ -19,40 +19,23 @@
class ServerView;
+// ServerViewDelegate is notified at key points in the lifetime of a
+// ServerView. Some of the functions are similar to that of
+// ServerViewObserver. For example, ServerViewDelegate::PrepareToDestroyView()
+// and ServerViewObserver::OnWillDestroyView(). The key difference between
+// the two are the ServerViewDelegate ones are always notified first, and
+// ServerViewDelegate gets non-const arguments.
class ServerViewDelegate {
public:
// Invoked when a view is about to be destroyed; before any of the children
// have been removed and before the view has been removed from its parent.
- virtual void OnWillDestroyView(ServerView* view) = 0;
+ virtual void PrepareToDestroyView(ServerView* view) = 0;
- // Invoked at the end of the View's destructor (after it has been removed from
- // the hierarchy).
- virtual void OnViewDestroyed(const ServerView* view) = 0;
+ virtual void PrepareToChangeViewHierarchy(ServerView* view,
+ ServerView* new_parent,
+ ServerView* old_parent) = 0;
- virtual void OnWillChangeViewHierarchy(ServerView* view,
- ServerView* new_parent,
- ServerView* old_parent) = 0;
-
- virtual void OnViewHierarchyChanged(const ServerView* view,
- const ServerView* new_parent,
- const ServerView* old_parent) = 0;
-
- virtual void OnViewBoundsChanged(const ServerView* view,
- const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) = 0;
-
- virtual void OnViewSurfaceIdChanged(const ServerView* view) = 0;
-
- virtual void OnViewReordered(const ServerView* view,
- const ServerView* relative,
- mojo::OrderDirection direction) = 0;
-
- virtual void OnWillChangeViewVisibility(ServerView* view) = 0;
-
- virtual void OnViewSharedPropertyChanged(
- const ServerView* view,
- const std::string& name,
- const std::vector<uint8_t>* new_data) = 0;
+ virtual void PrepareToChangeViewVisibility(ServerView* view) = 0;
virtual void OnScheduleViewPaint(const ServerView* view) = 0;
diff --git a/services/view_manager/server_view_observer.h b/services/view_manager/server_view_observer.h
new file mode 100644
index 0000000..3765027
--- /dev/null
+++ b/services/view_manager/server_view_observer.h
@@ -0,0 +1,61 @@
+// Copyright 2015 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 SERVICES_VIEW_MANAGER_SERVER_VIEW_OBSERVER_H_
+#define SERVICES_VIEW_MANAGER_SERVER_VIEW_OBSERVER_H_
+
+#include "mojo/services/view_manager/public/interfaces/view_manager_constants.mojom.h"
+
+namespace gfx {
+class Rect;
+}
+
+namespace mojo {
+class ViewportMetrics;
+}
+
+namespace view_manager {
+
+class ServerView;
+
+class ServerViewObserver {
+ public:
+ // Invoked when a view is about to be destroyed; before any of the children
+ // have been removed and before the view has been removed from its parent.
+ virtual void OnWillDestroyView(const ServerView* view) {}
+
+ // Invoked at the end of the View's destructor (after it has been removed from
+ // the hierarchy).
+ virtual void OnViewDestroyed(const ServerView* view) {}
+
+ virtual void OnWillChangeViewHierarchy(const ServerView* view,
+ const ServerView* new_parent,
+ const ServerView* old_parent) {}
+
+ virtual void OnViewHierarchyChanged(const ServerView* view,
+ const ServerView* new_parent,
+ const ServerView* old_parent) {}
+
+ virtual void OnViewBoundsChanged(const ServerView* view,
+ const gfx::Rect& old_bounds,
+ const gfx::Rect& new_bounds) {}
+
+ virtual void OnViewReordered(const ServerView* view,
+ const ServerView* relative,
+ mojo::OrderDirection direction) {}
+
+ virtual void OnWillChangeViewVisibility(const ServerView* view) {}
+
+ virtual void OnViewSharedPropertyChanged(
+ const ServerView* view,
+ const std::string& name,
+ const std::vector<uint8_t>* new_data) {}
+
+ protected:
+ virtual ~ServerViewObserver() {}
+};
+
+} // namespace view_manager
+
+#endif // SERVICES_VIEW_MANAGER_SERVER_VIEW_OBSERVER_H_
diff --git a/services/view_manager/test_server_view_delegate.cc b/services/view_manager/test_server_view_delegate.cc
index cf01d17..9945480 100644
--- a/services/view_manager/test_server_view_delegate.cc
+++ b/services/view_manager/test_server_view_delegate.cc
@@ -12,43 +12,16 @@
TestServerViewDelegate::~TestServerViewDelegate() {
}
-void TestServerViewDelegate::OnWillDestroyView(ServerView* view) {
+void TestServerViewDelegate::PrepareToDestroyView(ServerView* view) {
}
-void TestServerViewDelegate::OnViewDestroyed(const ServerView* view) {
+void TestServerViewDelegate::PrepareToChangeViewHierarchy(
+ ServerView* view,
+ ServerView* new_parent,
+ ServerView* old_parent) {
}
-void TestServerViewDelegate::OnWillChangeViewHierarchy(ServerView* view,
- ServerView* new_parent,
- ServerView* old_parent) {
-}
-
-void TestServerViewDelegate::OnViewHierarchyChanged(
- const ServerView* view,
- const ServerView* new_parent,
- const ServerView* old_parent) {
-}
-
-void TestServerViewDelegate::OnViewBoundsChanged(const ServerView* view,
- const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) {
-}
-
-void TestServerViewDelegate::OnViewSurfaceIdChanged(const ServerView* view) {
-}
-
-void TestServerViewDelegate::OnViewReordered(const ServerView* view,
- const ServerView* relative,
- mojo::OrderDirection direction) {
-}
-
-void TestServerViewDelegate::OnWillChangeViewVisibility(ServerView* view) {
-}
-
-void TestServerViewDelegate::OnViewSharedPropertyChanged(
- const ServerView* view,
- const std::string& name,
- const std::vector<uint8_t>* new_data) {
+void TestServerViewDelegate::PrepareToChangeViewVisibility(ServerView* view) {
}
void TestServerViewDelegate::OnScheduleViewPaint(const ServerView* view) {
diff --git a/services/view_manager/test_server_view_delegate.h b/services/view_manager/test_server_view_delegate.h
index 82f0d83..6f53497 100644
--- a/services/view_manager/test_server_view_delegate.h
+++ b/services/view_manager/test_server_view_delegate.h
@@ -17,26 +17,11 @@
private:
// ServerViewDelegate:
- void OnWillDestroyView(ServerView* view) override;
- void OnViewDestroyed(const ServerView* view) override;
- void OnWillChangeViewHierarchy(ServerView* view,
- ServerView* new_parent,
- ServerView* old_parent) override;
- void OnViewHierarchyChanged(const ServerView* view,
- const ServerView* new_parent,
- const ServerView* old_parent) override;
- void OnViewBoundsChanged(const ServerView* view,
- const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds) override;
- void OnViewSurfaceIdChanged(const ServerView* view) override;
- void OnViewReordered(const ServerView* view,
- const ServerView* relative,
- mojo::OrderDirection direction) override;
- void OnWillChangeViewVisibility(ServerView* view) override;
- void OnViewSharedPropertyChanged(
- const ServerView* view,
- const std::string& name,
- const std::vector<uint8_t>* new_data) override;
+ void PrepareToDestroyView(ServerView* view) override;
+ void PrepareToChangeViewHierarchy(ServerView* view,
+ ServerView* new_parent,
+ ServerView* old_parent) override;
+ void PrepareToChangeViewVisibility(ServerView* view) override;
void OnScheduleViewPaint(const ServerView* view) override;
DISALLOW_COPY_AND_ASSIGN(TestServerViewDelegate);
diff --git a/services/view_manager/view_manager_service_impl.cc b/services/view_manager/view_manager_service_impl.cc
index 48e32c7..6114d94 100644
--- a/services/view_manager/view_manager_service_impl.cc
+++ b/services/view_manager/view_manager_service_impl.cc
@@ -101,7 +101,7 @@
return mojo::ERROR_CODE_ILLEGAL_ARGUMENT;
if (view_map_.find(view_id.view_id) != view_map_.end())
return mojo::ERROR_CODE_VALUE_IN_USE;
- view_map_[view_id.view_id] = new ServerView(connection_manager_, view_id);
+ view_map_[view_id.view_id] = connection_manager_->CreateServerView(view_id);
known_views_.insert(ViewIdToTransportId(view_id));
return mojo::ERROR_CODE_NONE;
}