diff options
Diffstat (limited to 'mojo/services/public/cpp')
8 files changed, 111 insertions, 9 deletions
diff --git a/mojo/services/public/cpp/network/BUILD.gn b/mojo/services/public/cpp/network/BUILD.gn index f8db162..5f6ab06 100644 --- a/mojo/services/public/cpp/network/BUILD.gn +++ b/mojo/services/public/cpp/network/BUILD.gn @@ -17,7 +17,7 @@ source_set("network") { "//mojo/application", "//mojo/common", "//mojo/environment:chromium", - "//mojo/public/c/system:for_component", + "//mojo/public/c/system", "//mojo/public/cpp/system", "//mojo/services/public/interfaces/network", ] diff --git a/mojo/services/public/cpp/view_manager/BUILD.gn b/mojo/services/public/cpp/view_manager/BUILD.gn index dffa4f1..90193d4 100644 --- a/mojo/services/public/cpp/view_manager/BUILD.gn +++ b/mojo/services/public/cpp/view_manager/BUILD.gn @@ -28,7 +28,7 @@ source_set("view_manager") { ] deps = [ "//base", - "//mojo/public/c/gles2", + "//mojo/public/c/gles2:headers", "//mojo/public/cpp/application", "//mojo/public/cpp/bindings:bindings", "//mojo/public/interfaces/application", diff --git a/mojo/services/public/cpp/view_manager/lib/view.cc b/mojo/services/public/cpp/view_manager/lib/view.cc index 1ed7a62..0880958 100644 --- a/mojo/services/public/cpp/view_manager/lib/view.cc +++ b/mojo/services/public/cpp/view_manager/lib/view.cc @@ -4,10 +4,13 @@ #include "mojo/services/public/cpp/view_manager/view.h" +#include <set> + #include "mojo/public/cpp/application/service_provider_impl.h" #include "mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h" #include "mojo/services/public/cpp/view_manager/lib/view_private.h" #include "mojo/services/public/cpp/view_manager/view_observer.h" +#include "mojo/services/public/cpp/view_manager/view_tracker.h" namespace mojo { @@ -225,7 +228,7 @@ void View::SetVisible(bool value) { static_cast<ViewManagerClientImpl*>(manager_)->SetVisible(id_, value); FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChanging(this)); visible_ = value; - FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChanged(this)); + NotifyViewVisibilityChanged(this); } void View::SetSharedProperty(const std::string& name, @@ -503,4 +506,52 @@ void View::LocalSetDrawn(bool value) { FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewDrawnChanged(this)); } +void View::NotifyViewVisibilityChanged(View* target) { + if (!NotifyViewVisibilityChangedDown(target)) { + return; // |this| has been deleted. + } + NotifyViewVisibilityChangedUp(target); +} + +bool View::NotifyViewVisibilityChangedAtReceiver(View* target) { + // |this| may be deleted during a call to OnViewVisibilityChanged() on one + // of the observers. We create an local observer for that. In that case we + // exit without further access to any members. + ViewTracker tracker; + tracker.Add(this); + FOR_EACH_OBSERVER(ViewObserver, observers_, OnViewVisibilityChanged(target)); + return tracker.Contains(this); +} + +bool View::NotifyViewVisibilityChangedDown(View* target) { + if (!NotifyViewVisibilityChangedAtReceiver(target)) + return false; // |this| was deleted. + std::set<const View*> child_already_processed; + bool child_destroyed = false; + do { + child_destroyed = false; + for (View::Children::const_iterator it = children_.begin(); + it != children_.end(); ++it) { + if (!child_already_processed.insert(*it).second) + continue; + if (!(*it)->NotifyViewVisibilityChangedDown(target)) { + // |*it| was deleted, |it| is invalid and |children_| has changed. We + // exit the current for-loop and enter a new one. + child_destroyed = true; + break; + } + } + } while (child_destroyed); + return true; +} + +void View::NotifyViewVisibilityChangedUp(View* target) { + // Start with the parent as we already notified |this| + // in NotifyViewVisibilityChangedDown. + for (View* view = parent(); view; view = view->parent()) { + bool ret = view->NotifyViewVisibilityChangedAtReceiver(target); + DCHECK(ret); + } +} + } // namespace mojo diff --git a/mojo/services/public/cpp/view_manager/tests/BUILD.gn b/mojo/services/public/cpp/view_manager/tests/BUILD.gn index d04bb34..c4a117a 100644 --- a/mojo/services/public/cpp/view_manager/tests/BUILD.gn +++ b/mojo/services/public/cpp/view_manager/tests/BUILD.gn @@ -13,18 +13,16 @@ test("mojo_view_manager_lib_unittests") { deps = [ "//base", "//base/test:test_support", - "//testing/gtest", - "//ui/gfx", - "//ui/gfx:test_support", "//mojo/application_manager", "//mojo/converters/geometry", "//mojo/environment:chromium", "//mojo/public/cpp/application", "//mojo/services/public/cpp/geometry", + "//mojo/services/public/cpp/view_manager", "//mojo/services/public/interfaces/geometry", - "//mojo/shell:test_support", "//mojo/services/public/interfaces/view_manager", - "//mojo/services/public/cpp/view_manager", + "//shell:test_support", + "//testing/gtest", ] if (use_aura) { deps += [ "//mojo/services/public/cpp/view_manager/lib:run_unittests" ] diff --git a/mojo/services/public/cpp/view_manager/tests/DEPS b/mojo/services/public/cpp/view_manager/tests/DEPS index 2ecf3db..24dd6d3 100644 --- a/mojo/services/public/cpp/view_manager/tests/DEPS +++ b/mojo/services/public/cpp/view_manager/tests/DEPS @@ -1,3 +1,4 @@ include_rules = [ "+mojo/application_manager", + "+shell/shell_test_helper.h", ] 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 540b145..6b2294e 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 @@ -20,7 +20,7 @@ #include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h" #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" #include "mojo/services/public/cpp/view_manager/view_observer.h" -#include "mojo/shell/shell_test_helper.h" +#include "shell/shell_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" namespace mojo { diff --git a/mojo/services/public/cpp/view_manager/tests/view_unittest.cc b/mojo/services/public/cpp/view_manager/tests/view_unittest.cc index b0bd08b..96b2d5c 100644 --- a/mojo/services/public/cpp/view_manager/tests/view_unittest.cc +++ b/mojo/services/public/cpp/view_manager/tests/view_unittest.cc @@ -695,6 +695,46 @@ TEST_F(ViewObserverTest, SetVisible) { } } +TEST_F(ViewObserverTest, SetVisibleParent) { + TestView parent; + ViewPrivate(&parent).set_id(1); + TestView child; + ViewPrivate(&child).set_id(2); + parent.AddChild(&child); + EXPECT_TRUE(parent.visible()); + EXPECT_TRUE(child.visible()); + { + // Change visibility from true to false and make sure we get notifications + // on the parent. + VisibilityChangeObserver observer(&parent); + child.SetVisible(false); + + Changes changes = observer.GetAndClearChanges(); + ASSERT_EQ(1U, changes.size()); + EXPECT_EQ("view=0,2 phase=changed visibility=false", changes[0]); + } +} + +TEST_F(ViewObserverTest, SetVisibleChild) { + TestView parent; + ViewPrivate(&parent).set_id(1); + TestView child; + ViewPrivate(&child).set_id(2); + parent.AddChild(&child); + EXPECT_TRUE(parent.visible()); + EXPECT_TRUE(child.visible()); + { + // Change visibility from true to false and make sure we get notifications + // on the child. + VisibilityChangeObserver observer(&child); + parent.SetVisible(false); + + Changes changes = observer.GetAndClearChanges(); + ASSERT_EQ(1U, changes.size()); + EXPECT_EQ("view=0,1 phase=changed visibility=false", changes[0]); + } +} + namespace { class SharedPropertyChangeObserver : public ViewObserver { diff --git a/mojo/services/public/cpp/view_manager/view.h b/mojo/services/public/cpp/view_manager/view.h index 56d930f..c585dd5 100644 --- a/mojo/services/public/cpp/view_manager/view.h +++ b/mojo/services/public/cpp/view_manager/view.h @@ -154,6 +154,18 @@ class View { void LocalSetBounds(const Rect& old_bounds, const Rect& new_bounds); void LocalSetDrawn(bool drawn); + // Methods implementing visibility change notifications. See ViewObserver + // for more details. + void NotifyViewVisibilityChanged(View* target); + // Notifies this view's observers. Returns false if |this| was deleted during + // the call (by an observer), otherwise true. + bool NotifyViewVisibilityChangedAtReceiver(View* target); + // Notifies this view and its child hierarchy. Returns false if |this| was + // deleted during the call (by an observer), otherwise true. + bool NotifyViewVisibilityChangedDown(View* target); + // Notifies this view and its parent hierarchy. + void NotifyViewVisibilityChangedUp(View* target); + ViewManager* manager_; Id id_; View* parent_; |