Index: ui/display/display_list.cc |
diff --git a/ui/display/display_list.cc b/ui/display/display_list.cc |
index 7b0f8d755ef94ffc9594c584b140e3964cd7de64..3a60af601fb9dc644e26a90dbba9256194325393 100644 |
--- a/ui/display/display_list.cc |
+++ b/ui/display/display_list.cc |
@@ -4,13 +4,25 @@ |
#include "ui/display/display_list.h" |
+#include "base/memory/ptr_util.h" |
#include "ui/display/display_observer.h" |
namespace display { |
+DisplayListObserverLock::~DisplayListObserverLock() { |
+ display_list_->DecrementObserverSuspendLockCount(); |
+} |
+ |
+DisplayListObserverLock::DisplayListObserverLock(DisplayList* display_list) |
+ : display_list_(display_list) { |
+ display_list_->IncrementObserverSuspendLockCount(); |
+} |
+ |
DisplayList::DisplayList() {} |
-DisplayList::~DisplayList() {} |
+DisplayList::~DisplayList() { |
+ DCHECK(!suspend_observer_state_); |
+} |
void DisplayList::AddObserver(display::DisplayObserver* observer) { |
observers_.AddObserver(observer); |
@@ -44,6 +56,10 @@ DisplayList::Displays::const_iterator DisplayList::GetPrimaryDisplayIterator() |
: displays_.begin() + primary_display_index_; |
} |
+std::unique_ptr<DisplayListObserverLock> DisplayList::SuspendObserverUpdates() { |
+ return base::WrapUnique(new DisplayListObserverLock(this)); |
+} |
+ |
void DisplayList::UpdateDisplay(const display::Display& display, Type type) { |
auto iter = FindDisplayById(display.id()); |
DCHECK(iter != displays_.end()); |
@@ -75,6 +91,12 @@ void DisplayList::UpdateDisplay(const display::Display& display, Type type) { |
changed_values |= |
display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR; |
} |
+ if (suspend_observer_state_) { |
+ // See docs in header for what is supported. |
+ DCHECK(suspend_observer_state_->display_added); |
+ DCHECK(iter + 1 == displays_.end()); |
+ return; |
+ } |
FOR_EACH_OBSERVER(display::DisplayObserver, observers_, |
OnDisplayMetricsChanged(*local_display, changed_values)); |
} |
@@ -84,11 +106,19 @@ void DisplayList::AddDisplay(const display::Display& display, Type type) { |
displays_.push_back(display); |
if (type == Type::PRIMARY) |
primary_display_index_ = static_cast<int>(displays_.size()) - 1; |
- FOR_EACH_OBSERVER(display::DisplayObserver, observers_, |
- OnDisplayAdded(display)); |
+ if (suspend_observer_state_) { |
+ // See docs in header for what is supported. |
+ DCHECK(!suspend_observer_state_->display_added); |
+ suspend_observer_state_->display_added = true; |
+ } else { |
+ FOR_EACH_OBSERVER(display::DisplayObserver, observers_, |
+ OnDisplayAdded(display)); |
+ } |
} |
void DisplayList::RemoveDisplay(int64_t id) { |
+ // See docs in header for what is supported. |
+ DCHECK(!suspend_observer_state_); |
auto iter = FindDisplayById(id); |
DCHECK(displays_.end() != iter); |
if (primary_display_index_ == static_cast<int>(iter - displays_.begin())) { |
@@ -105,4 +135,26 @@ void DisplayList::RemoveDisplay(int64_t id) { |
FOR_EACH_OBSERVER(display::DisplayObserver, observers_, |
OnDisplayRemoved(display)); |
} |
+ |
+void DisplayList::IncrementObserverSuspendLockCount() { |
+ if (!suspend_observer_state_) { |
+ suspend_observer_state_ = base::MakeUnique<SuspendObserverState>(); |
+ suspend_observer_state_->original_display_count = displays_.size(); |
+ } |
+ suspend_observer_state_->count++; |
+} |
+ |
+void DisplayList::DecrementObserverSuspendLockCount() { |
+ DCHECK(suspend_observer_state_); |
+ if (--suspend_observer_state_->count != 0) |
+ return; |
+ |
+ std::unique_ptr<SuspendObserverState> suspend_observer_state = |
+ std::move(suspend_observer_state_); |
+ if (suspend_observer_state->display_added) { |
+ FOR_EACH_OBSERVER(display::DisplayObserver, observers_, |
+ OnDisplayAdded(displays_.back())); |
+ } |
+} |
+ |
} // namespace display |