[modular][storymodel] Don't notify observers when the StoryModel doesn't change.
TEST=fx run-test story_model_owner_unittest
Change-Id: I66d86e9675764d78d8b221ae63c6461663f7e23d
diff --git a/bin/sessionmgr/story/model/story_model_owner.cc b/bin/sessionmgr/story/model/story_model_owner.cc
index 7c65780..324c81e 100644
--- a/bin/sessionmgr/story/model/story_model_owner.cc
+++ b/bin/sessionmgr/story/model/story_model_owner.cc
@@ -148,7 +148,12 @@
// HandleObservedMutations() will only be called on a single thread.
StoryModel old_model;
FXL_CHECK(fidl::Clone(model_, &old_model) == ZX_OK);
- model_ = ApplyMutations(std::move(old_model), std::move(commands));
+ model_ = ApplyMutations(old_model, std::move(commands));
+
+ // Don't notify anyone if the model didn't change.
+ if (model_ == old_model) {
+ return;
+ }
executor_->schedule_task(fit::make_promise([this] {
for (auto& listener : listeners_) {
diff --git a/bin/sessionmgr/story/model/story_model_owner_unittest.cc b/bin/sessionmgr/story/model/story_model_owner_unittest.cc
index 5da2a85..dfa2672 100644
--- a/bin/sessionmgr/story/model/story_model_owner_unittest.cc
+++ b/bin/sessionmgr/story/model/story_model_owner_unittest.cc
@@ -202,6 +202,25 @@
EXPECT_TRUE(got_update3);
}
+TEST_F(StoryModelOwnerTest, ObserversAreNotNotifiedOnNoChange) {
+ // Observers aren't told when an observed mutation doesn't change the model.
+ auto owner = Create("test");
+ auto mutator = owner->NewMutator();
+ auto observer = owner->NewObserver();
+
+ bool got_update{false};
+ observer->RegisterListener([&](const StoryModel& model) {
+ got_update = true;
+ });
+
+ std::vector<StoryModelMutation> commands;
+ commands.resize(1);
+ commands[0].set_set_visibility_state(StoryVisibilityState::DEFAULT);
+ model_storage()->Observe(std::move(commands));
+ RunLoopUntilIdle();
+ EXPECT_FALSE(got_update);
+}
+
TEST_F(StoryModelOwnerTest, ObserversLifecycle_ClientDestroyed) {
// When the client destroys its observer object, it no longer receives
// updates.