summaryrefslogtreecommitdiffstats
path: root/mojo/services/public/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mojo/services/public/cpp')
-rw-r--r--mojo/services/public/cpp/network/BUILD.gn2
-rw-r--r--mojo/services/public/cpp/view_manager/BUILD.gn2
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view.cc53
-rw-r--r--mojo/services/public/cpp/view_manager/tests/BUILD.gn8
-rw-r--r--mojo/services/public/cpp/view_manager/tests/DEPS1
-rw-r--r--mojo/services/public/cpp/view_manager/tests/view_manager_unittest.cc2
-rw-r--r--mojo/services/public/cpp/view_manager/tests/view_unittest.cc40
-rw-r--r--mojo/services/public/cpp/view_manager/view.h12
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_;