Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(793)

Side by Side Diff: chrome/browser/notifications/balloon_collection.cc

Issue 4635007: When an extension is uninstalled, close all desktop notifications from that e... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/notifications/balloon_collection_impl.h" 5 #include "chrome/browser/notifications/balloon_collection_impl.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/stl_util-inl.h" 8 #include "base/stl_util-inl.h"
9 #include "chrome/browser/notifications/balloon.h" 9 #include "chrome/browser/notifications/balloon.h"
10 #include "chrome/browser/notifications/balloon_host.h" 10 #include "chrome/browser/notifications/balloon_host.h"
(...skipping 27 matching lines...) Expand all
38 38
39 BalloonCollectionImpl::BalloonCollectionImpl() 39 BalloonCollectionImpl::BalloonCollectionImpl()
40 #if USE_OFFSETS 40 #if USE_OFFSETS
41 : ALLOW_THIS_IN_INITIALIZER_LIST(reposition_factory_(this)), 41 : ALLOW_THIS_IN_INITIALIZER_LIST(reposition_factory_(this)),
42 added_as_message_loop_observer_(false) 42 added_as_message_loop_observer_(false)
43 #endif 43 #endif
44 { 44 {
45 } 45 }
46 46
47 BalloonCollectionImpl::~BalloonCollectionImpl() { 47 BalloonCollectionImpl::~BalloonCollectionImpl() {
48 STLDeleteElements(&balloons_);
49 } 48 }
50 49
51 void BalloonCollectionImpl::Add(const Notification& notification, 50 void BalloonCollectionImpl::Add(const Notification& notification,
52 Profile* profile) { 51 Profile* profile) {
53 Balloon* new_balloon = MakeBalloon(notification, profile); 52 Balloon* new_balloon = MakeBalloon(notification, profile);
54 // The +1 on width is necessary because width is fixed on notifications, 53 // The +1 on width is necessary because width is fixed on notifications,
55 // so since we always have the max size, we would always hit the scrollbar 54 // so since we always have the max size, we would always hit the scrollbar
56 // condition. We are only interested in comparing height to maximum. 55 // condition. We are only interested in comparing height to maximum.
57 new_balloon->set_min_scrollbar_size(gfx::Size(1 + layout_.max_balloon_width(), 56 new_balloon->set_min_scrollbar_size(gfx::Size(1 + layout_.max_balloon_width(),
58 layout_.max_balloon_height())); 57 layout_.max_balloon_height()));
59 new_balloon->SetPosition(layout_.OffScreenLocation(), false); 58 new_balloon->SetPosition(layout_.OffScreenLocation(), false);
60 new_balloon->Show(); 59 new_balloon->Show();
61 #if USE_OFFSETS 60 #if USE_OFFSETS
62 if (balloons_.size() > 0) 61 int count = base_.count();
63 new_balloon->set_offset(balloons_[balloons_.size() - 1]->offset()); 62 if (count > 0)
63 new_balloon->set_offset(base_.balloons()[count - 1]->offset());
64 #endif 64 #endif
65 balloons_.push_back(new_balloon); 65 base_.Add(new_balloon);
66 PositionBalloons(false); 66 PositionBalloons(false);
67 67
68 // There may be no listener in a unit test. 68 // There may be no listener in a unit test.
69 if (space_change_listener_) 69 if (space_change_listener_)
70 space_change_listener_->OnBalloonSpaceChanged(); 70 space_change_listener_->OnBalloonSpaceChanged();
71 71
72 // This is used only for testing. 72 // This is used only for testing.
73 if (on_collection_changed_callback_.get()) 73 if (on_collection_changed_callback_.get())
74 on_collection_changed_callback_->Run(); 74 on_collection_changed_callback_->Run();
75 } 75 }
76 76
77 bool BalloonCollectionImpl::Remove(const Notification& notification) { 77 bool BalloonCollectionImpl::RemoveById(const std::string& id) {
78 Balloons::iterator iter; 78 return base_.CloseById(id);
79 for (iter = balloons_.begin(); iter != balloons_.end(); ++iter) { 79 }
80 if (notification.IsSame((*iter)->notification())) { 80
81 // Balloon.CloseByScript() will cause OnBalloonClosed() to be called on 81 bool BalloonCollectionImpl::RemoveBySourceOrigin(const GURL& origin) {
82 // this object, which will remove it from the collection and free it. 82 return base_.CloseAllBySourceOrigin(origin);
83 (*iter)->CloseByScript();
84 return true;
85 }
86 }
87 return false;
88 } 83 }
89 84
90 bool BalloonCollectionImpl::HasSpace() const { 85 bool BalloonCollectionImpl::HasSpace() const {
91 if (count() < kMinAllowedBalloonCount) 86 int count = base_.count();
87 if (count < kMinAllowedBalloonCount)
92 return true; 88 return true;
93 89
94 int max_balloon_size = 0; 90 int max_balloon_size = 0;
95 int total_size = 0; 91 int total_size = 0;
96 layout_.GetMaxLinearSize(&max_balloon_size, &total_size); 92 layout_.GetMaxLinearSize(&max_balloon_size, &total_size);
97 93
98 int current_max_size = max_balloon_size * count(); 94 int current_max_size = max_balloon_size * count;
99 int max_allowed_size = static_cast<int>(total_size * 95 int max_allowed_size = static_cast<int>(total_size *
100 kPercentBalloonFillFactor); 96 kPercentBalloonFillFactor);
101 return current_max_size < max_allowed_size - max_balloon_size; 97 return current_max_size < max_allowed_size - max_balloon_size;
102 } 98 }
103 99
104 void BalloonCollectionImpl::ResizeBalloon(Balloon* balloon, 100 void BalloonCollectionImpl::ResizeBalloon(Balloon* balloon,
105 const gfx::Size& size) { 101 const gfx::Size& size) {
106 balloon->set_content_size(Layout::ConstrainToSizeLimits(size)); 102 balloon->set_content_size(Layout::ConstrainToSizeLimits(size));
107 PositionBalloons(true); 103 PositionBalloons(true);
108 } 104 }
109 105
110 void BalloonCollectionImpl::DisplayChanged() { 106 void BalloonCollectionImpl::DisplayChanged() {
111 layout_.RefreshSystemMetrics(); 107 layout_.RefreshSystemMetrics();
112 PositionBalloons(true); 108 PositionBalloons(true);
113 } 109 }
114 110
115 void BalloonCollectionImpl::OnBalloonClosed(Balloon* source) { 111 void BalloonCollectionImpl::OnBalloonClosed(Balloon* source) {
116 // We want to free the balloon when finished. 112 // We want to free the balloon when finished.
117 scoped_ptr<Balloon> closed(source); 113 const Balloons& balloons = base_.balloons();
118 Balloons::iterator it = balloons_.begin(); 114 Balloons::const_iterator it = balloons.begin();
119 115
120 #if USE_OFFSETS 116 #if USE_OFFSETS
121 gfx::Point offset; 117 gfx::Point offset;
122 bool apply_offset = false; 118 bool apply_offset = false;
123 while (it != balloons_.end()) { 119 while (it != balloons.end()) {
124 if (*it == source) { 120 if (*it == source) {
125 it = balloons_.erase(it); 121 ++it;
126 if (it != balloons_.end()) { 122 if (it != balloons.end()) {
127 apply_offset = true; 123 apply_offset = true;
128 offset.set_y((source)->offset().y() - (*it)->offset().y() + 124 offset.set_y((source)->offset().y() - (*it)->offset().y() +
129 (*it)->content_size().height() - source->content_size().height()); 125 (*it)->content_size().height() - source->content_size().height());
130 } 126 }
131 } else { 127 } else {
132 if (apply_offset) 128 if (apply_offset)
133 (*it)->add_offset(offset); 129 (*it)->add_offset(offset);
134 ++it; 130 ++it;
135 } 131 }
136 } 132 }
137 // Start listening for UI events so we cancel the offset when the mouse 133 // Start listening for UI events so we cancel the offset when the mouse
138 // leaves the balloon area. 134 // leaves the balloon area.
139 if (apply_offset) 135 if (apply_offset)
140 AddMessageLoopObserver(); 136 AddMessageLoopObserver();
141 #else
142 for (; it != balloons_.end(); ++it) {
143 if (*it == source) {
144 balloons_.erase(it);
145 break;
146 }
147 }
148 #endif 137 #endif
149 138
139 base_.Remove(source);
150 PositionBalloons(true); 140 PositionBalloons(true);
151 141
152 // There may be no listener in a unit test. 142 // There may be no listener in a unit test.
153 if (space_change_listener_) 143 if (space_change_listener_)
154 space_change_listener_->OnBalloonSpaceChanged(); 144 space_change_listener_->OnBalloonSpaceChanged();
155 145
156 // This is used only for testing. 146 // This is used only for testing.
157 if (on_collection_changed_callback_.get()) 147 if (on_collection_changed_callback_.get())
158 on_collection_changed_callback_->Run(); 148 on_collection_changed_callback_->Run();
159 } 149 }
160 150
161 void BalloonCollectionImpl::PositionBalloonsInternal(bool reposition) { 151 void BalloonCollectionImpl::PositionBalloonsInternal(bool reposition) {
152 const Balloons& balloons = base_.balloons();
153
162 layout_.RefreshSystemMetrics(); 154 layout_.RefreshSystemMetrics();
163 gfx::Point origin = layout_.GetLayoutOrigin(); 155 gfx::Point origin = layout_.GetLayoutOrigin();
164 for (Balloons::iterator it = balloons_.begin(); it != balloons_.end(); ++it) { 156 for (Balloons::const_iterator it = balloons.begin();
157 it != balloons.end();
158 ++it) {
165 gfx::Point upper_left = layout_.NextPosition((*it)->GetViewSize(), &origin); 159 gfx::Point upper_left = layout_.NextPosition((*it)->GetViewSize(), &origin);
166 (*it)->SetPosition(upper_left, reposition); 160 (*it)->SetPosition(upper_left, reposition);
167 } 161 }
168 } 162 }
169 163
170 #if USE_OFFSETS 164 #if USE_OFFSETS
171 void BalloonCollectionImpl::AddMessageLoopObserver() { 165 void BalloonCollectionImpl::AddMessageLoopObserver() {
172 if (!added_as_message_loop_observer_) { 166 if (!added_as_message_loop_observer_) {
173 MessageLoopForUI::current()->AddObserver(this); 167 MessageLoopForUI::current()->AddObserver(this);
174 added_as_message_loop_observer_ = true; 168 added_as_message_loop_observer_ = true;
175 } 169 }
176 } 170 }
177 171
178 void BalloonCollectionImpl::RemoveMessageLoopObserver() { 172 void BalloonCollectionImpl::RemoveMessageLoopObserver() {
179 if (added_as_message_loop_observer_) { 173 if (added_as_message_loop_observer_) {
180 MessageLoopForUI::current()->RemoveObserver(this); 174 MessageLoopForUI::current()->RemoveObserver(this);
181 added_as_message_loop_observer_ = false; 175 added_as_message_loop_observer_ = false;
182 } 176 }
183 } 177 }
184 178
185 void BalloonCollectionImpl::CancelOffsets() { 179 void BalloonCollectionImpl::CancelOffsets() {
186 reposition_factory_.RevokeAll(); 180 reposition_factory_.RevokeAll();
187 181
188 // Unhook from listening to all UI events. 182 // Unhook from listening to all UI events.
189 RemoveMessageLoopObserver(); 183 RemoveMessageLoopObserver();
190 184
191 for (Balloons::iterator it = balloons_.begin(); it != balloons_.end(); ++it) 185 const Balloons& balloons = base_.balloons();
186 for (Balloons::const_iterator it = balloons.begin();
187 it != balloons.end();
188 ++it)
192 (*it)->set_offset(gfx::Point(0, 0)); 189 (*it)->set_offset(gfx::Point(0, 0));
193 190
194 PositionBalloons(true); 191 PositionBalloons(true);
195 } 192 }
196 193
197 void BalloonCollectionImpl::HandleMouseMoveEvent() { 194 void BalloonCollectionImpl::HandleMouseMoveEvent() {
198 if (!IsCursorInBalloonCollection()) { 195 if (!IsCursorInBalloonCollection()) {
199 // Mouse has left the region. Schedule a reposition after 196 // Mouse has left the region. Schedule a reposition after
200 // a short delay. 197 // a short delay.
201 if (reposition_factory_.empty()) { 198 if (reposition_factory_.empty()) {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 gfx::Rect new_work_area = info_provider->GetPrimaryMonitorWorkArea(); 316 gfx::Rect new_work_area = info_provider->GetPrimaryMonitorWorkArea();
320 #endif 317 #endif
321 if (!work_area_.Equals(new_work_area)) { 318 if (!work_area_.Equals(new_work_area)) {
322 work_area_.SetRect(new_work_area.x(), new_work_area.y(), 319 work_area_.SetRect(new_work_area.x(), new_work_area.y(),
323 new_work_area.width(), new_work_area.height()); 320 new_work_area.width(), new_work_area.height());
324 changed = true; 321 changed = true;
325 } 322 }
326 323
327 return changed; 324 return changed;
328 } 325 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698