OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/display/display_list.h" | 5 #include "ui/display/display_list.h" |
6 | 6 |
| 7 #include "base/memory/ptr_util.h" |
7 #include "ui/display/display_observer.h" | 8 #include "ui/display/display_observer.h" |
8 | 9 |
9 namespace display { | 10 namespace display { |
10 | 11 |
| 12 DisplayListObserverLock::~DisplayListObserverLock() { |
| 13 display_list_->DecrementObserverSuspendLockCount(); |
| 14 } |
| 15 |
| 16 DisplayListObserverLock::DisplayListObserverLock(DisplayList* display_list) |
| 17 : display_list_(display_list) { |
| 18 display_list_->IncrementObserverSuspendLockCount(); |
| 19 } |
| 20 |
11 DisplayList::DisplayList() {} | 21 DisplayList::DisplayList() {} |
12 | 22 |
13 DisplayList::~DisplayList() {} | 23 DisplayList::~DisplayList() { |
| 24 DCHECK(!suspend_observer_state_); |
| 25 } |
14 | 26 |
15 void DisplayList::AddObserver(display::DisplayObserver* observer) { | 27 void DisplayList::AddObserver(display::DisplayObserver* observer) { |
16 observers_.AddObserver(observer); | 28 observers_.AddObserver(observer); |
17 } | 29 } |
18 | 30 |
19 void DisplayList::RemoveObserver(display::DisplayObserver* observer) { | 31 void DisplayList::RemoveObserver(display::DisplayObserver* observer) { |
20 observers_.RemoveObserver(observer); | 32 observers_.RemoveObserver(observer); |
21 } | 33 } |
22 | 34 |
23 DisplayList::Displays::const_iterator DisplayList::FindDisplayById( | 35 DisplayList::Displays::const_iterator DisplayList::FindDisplayById( |
(...skipping 13 matching lines...) Expand all Loading... |
37 return displays_.end(); | 49 return displays_.end(); |
38 } | 50 } |
39 | 51 |
40 DisplayList::Displays::const_iterator DisplayList::GetPrimaryDisplayIterator() | 52 DisplayList::Displays::const_iterator DisplayList::GetPrimaryDisplayIterator() |
41 const { | 53 const { |
42 return primary_display_index_ == -1 | 54 return primary_display_index_ == -1 |
43 ? displays_.end() | 55 ? displays_.end() |
44 : displays_.begin() + primary_display_index_; | 56 : displays_.begin() + primary_display_index_; |
45 } | 57 } |
46 | 58 |
| 59 std::unique_ptr<DisplayListObserverLock> DisplayList::SuspendObserverUpdates() { |
| 60 return base::WrapUnique(new DisplayListObserverLock(this)); |
| 61 } |
| 62 |
47 void DisplayList::UpdateDisplay(const display::Display& display, Type type) { | 63 void DisplayList::UpdateDisplay(const display::Display& display, Type type) { |
48 auto iter = FindDisplayById(display.id()); | 64 auto iter = FindDisplayById(display.id()); |
49 DCHECK(iter != displays_.end()); | 65 DCHECK(iter != displays_.end()); |
50 | 66 |
51 display::Display* local_display = &(*iter); | 67 display::Display* local_display = &(*iter); |
52 uint32_t changed_values = 0; | 68 uint32_t changed_values = 0; |
53 if (type == Type::PRIMARY && | 69 if (type == Type::PRIMARY && |
54 static_cast<int>(iter - displays_.begin()) != | 70 static_cast<int>(iter - displays_.begin()) != |
55 static_cast<int>(GetPrimaryDisplayIterator() - displays_.begin())) { | 71 static_cast<int>(GetPrimaryDisplayIterator() - displays_.begin())) { |
56 primary_display_index_ = static_cast<int>(iter - displays_.begin()); | 72 primary_display_index_ = static_cast<int>(iter - displays_.begin()); |
(...skipping 11 matching lines...) Expand all Loading... |
68 } | 84 } |
69 if (local_display->rotation() != display.rotation()) { | 85 if (local_display->rotation() != display.rotation()) { |
70 local_display->set_rotation(display.rotation()); | 86 local_display->set_rotation(display.rotation()); |
71 changed_values |= display::DisplayObserver::DISPLAY_METRIC_ROTATION; | 87 changed_values |= display::DisplayObserver::DISPLAY_METRIC_ROTATION; |
72 } | 88 } |
73 if (local_display->device_scale_factor() != display.device_scale_factor()) { | 89 if (local_display->device_scale_factor() != display.device_scale_factor()) { |
74 local_display->set_device_scale_factor(display.device_scale_factor()); | 90 local_display->set_device_scale_factor(display.device_scale_factor()); |
75 changed_values |= | 91 changed_values |= |
76 display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR; | 92 display::DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR; |
77 } | 93 } |
| 94 if (suspend_observer_state_) { |
| 95 // See docs in header for what is supported. |
| 96 DCHECK(suspend_observer_state_->display_added); |
| 97 DCHECK(iter + 1 == displays_.end()); |
| 98 return; |
| 99 } |
78 FOR_EACH_OBSERVER(display::DisplayObserver, observers_, | 100 FOR_EACH_OBSERVER(display::DisplayObserver, observers_, |
79 OnDisplayMetricsChanged(*local_display, changed_values)); | 101 OnDisplayMetricsChanged(*local_display, changed_values)); |
80 } | 102 } |
81 | 103 |
82 void DisplayList::AddDisplay(const display::Display& display, Type type) { | 104 void DisplayList::AddDisplay(const display::Display& display, Type type) { |
83 DCHECK(displays_.end() == FindDisplayById(display.id())); | 105 DCHECK(displays_.end() == FindDisplayById(display.id())); |
84 displays_.push_back(display); | 106 displays_.push_back(display); |
85 if (type == Type::PRIMARY) | 107 if (type == Type::PRIMARY) |
86 primary_display_index_ = static_cast<int>(displays_.size()) - 1; | 108 primary_display_index_ = static_cast<int>(displays_.size()) - 1; |
87 FOR_EACH_OBSERVER(display::DisplayObserver, observers_, | 109 if (suspend_observer_state_) { |
88 OnDisplayAdded(display)); | 110 // See docs in header for what is supported. |
| 111 DCHECK(!suspend_observer_state_->display_added); |
| 112 suspend_observer_state_->display_added = true; |
| 113 } else { |
| 114 FOR_EACH_OBSERVER(display::DisplayObserver, observers_, |
| 115 OnDisplayAdded(display)); |
| 116 } |
89 } | 117 } |
90 | 118 |
91 void DisplayList::RemoveDisplay(int64_t id) { | 119 void DisplayList::RemoveDisplay(int64_t id) { |
| 120 // See docs in header for what is supported. |
| 121 DCHECK(!suspend_observer_state_); |
92 auto iter = FindDisplayById(id); | 122 auto iter = FindDisplayById(id); |
93 DCHECK(displays_.end() != iter); | 123 DCHECK(displays_.end() != iter); |
94 if (primary_display_index_ == static_cast<int>(iter - displays_.begin())) { | 124 if (primary_display_index_ == static_cast<int>(iter - displays_.begin())) { |
95 // The primary display can only be removed if it is the last display. | 125 // The primary display can only be removed if it is the last display. |
96 // Users must choose a new primary before removing an old primary display. | 126 // Users must choose a new primary before removing an old primary display. |
97 DCHECK_EQ(1u, displays_.size()); | 127 DCHECK_EQ(1u, displays_.size()); |
98 primary_display_index_ = -1; | 128 primary_display_index_ = -1; |
99 } else if (primary_display_index_ > | 129 } else if (primary_display_index_ > |
100 static_cast<int>(iter - displays_.begin())) { | 130 static_cast<int>(iter - displays_.begin())) { |
101 primary_display_index_--; | 131 primary_display_index_--; |
102 } | 132 } |
103 const display::Display display = *iter; | 133 const display::Display display = *iter; |
104 displays_.erase(iter); | 134 displays_.erase(iter); |
105 FOR_EACH_OBSERVER(display::DisplayObserver, observers_, | 135 FOR_EACH_OBSERVER(display::DisplayObserver, observers_, |
106 OnDisplayRemoved(display)); | 136 OnDisplayRemoved(display)); |
107 } | 137 } |
| 138 |
| 139 void DisplayList::IncrementObserverSuspendLockCount() { |
| 140 if (!suspend_observer_state_) { |
| 141 suspend_observer_state_ = base::MakeUnique<SuspendObserverState>(); |
| 142 suspend_observer_state_->original_display_count = displays_.size(); |
| 143 } |
| 144 suspend_observer_state_->count++; |
| 145 } |
| 146 |
| 147 void DisplayList::DecrementObserverSuspendLockCount() { |
| 148 DCHECK(suspend_observer_state_); |
| 149 if (--suspend_observer_state_->count != 0) |
| 150 return; |
| 151 |
| 152 std::unique_ptr<SuspendObserverState> suspend_observer_state = |
| 153 std::move(suspend_observer_state_); |
| 154 if (suspend_observer_state->display_added) { |
| 155 FOR_EACH_OBSERVER(display::DisplayObserver, observers_, |
| 156 OnDisplayAdded(displays_.back())); |
| 157 } |
| 158 } |
| 159 |
108 } // namespace display | 160 } // namespace display |
OLD | NEW |