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

Side by Side Diff: chrome/browser/ui/views/message_center/web_notification_tray.cc

Issue 18003003: Message center re-organized (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moved icon resources Created 7 years, 5 months 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/ui/views/message_center/web_notification_tray.h" 5 #include "chrome/browser/ui/views/message_center/web_notification_tray.h"
6 6
7 #include "base/i18n/number_formatting.h" 7 #include "base/i18n/number_formatting.h"
8 #include "base/strings/string16.h" 8 #include "base/strings/string16.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/status_icons/status_icon.h" 11 #include "chrome/browser/status_icons/status_icon.h"
12 #include "chrome/browser/status_icons/status_tray.h" 12 #include "chrome/browser/status_icons/status_tray.h"
13 #include "chrome/browser/ui/views/message_center/notification_bubble_wrapper.h"
14 #include "content/public/browser/user_metrics.h" 13 #include "content/public/browser/user_metrics.h"
15 #include "grit/chromium_strings.h" 14 #include "grit/chromium_strings.h"
16 #include "grit/theme_resources.h" 15 #include "grit/theme_resources.h"
17 #include "grit/ui_strings.h" 16 #include "grit/ui_strings.h"
18 #include "ui/base/l10n/l10n_util.h" 17 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/base/models/simple_menu_model.h"
20 #include "ui/base/resource/resource_bundle.h" 18 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/gfx/canvas.h" 19 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/image/image_skia_operations.h" 20 #include "ui/gfx/image/image_skia_operations.h"
23 #include "ui/gfx/rect.h" 21 #include "ui/gfx/rect.h"
24 #include "ui/gfx/screen.h" 22 #include "ui/gfx/screen.h"
25 #include "ui/gfx/size.h" 23 #include "ui/gfx/size.h"
26 #include "ui/message_center/message_center_tray.h" 24 #include "ui/message_center/message_center_tray.h"
27 #include "ui/message_center/message_center_tray_delegate.h" 25 #include "ui/message_center/message_center_tray_delegate.h"
28 #include "ui/message_center/views/message_bubble_base.h"
29 #include "ui/message_center/views/message_center_bubble.h"
30 #include "ui/message_center/views/message_popup_collection.h" 26 #include "ui/message_center/views/message_popup_collection.h"
31 #include "ui/views/widget/widget.h" 27 #include "ui/views/widget/widget.h"
32 28
33 namespace { 29 namespace {
34 30
35 // Tray constants 31 // Tray constants
36 const int kScreenEdgePadding = 2; 32 const int kScreenEdgePadding = 2;
37 33
38 const int kSystemTrayWidth = 16; 34 const int kSystemTrayWidth = 16;
39 const int kSystemTrayHeight = 16; 35 const int kSystemTrayHeight = 16;
40 const int kNumberOfSystemTraySprites = 10; 36 const int kNumberOfSystemTraySprites = 10;
41 37
42 gfx::Rect GetCornerAnchorRect() {
43 // TODO(dewittj): Use the preference to determine which corner to anchor from.
44 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
45 gfx::Rect rect = screen->GetPrimaryDisplay().work_area();
46 rect.Inset(kScreenEdgePadding, kScreenEdgePadding);
47 return gfx::Rect(rect.bottom_right(), gfx::Size());
48 }
49
50 gfx::Point GetClosestCorner(gfx::Rect rect, gfx::Point query) {
51 gfx::Point center_point = rect.CenterPoint();
52 gfx::Point rv;
53
54 if (query.x() > center_point.x())
55 rv.set_x(rect.right());
56 else
57 rv.set_x(rect.x());
58
59 if (query.y() > center_point.y())
60 rv.set_y(rect.bottom());
61 else
62 rv.set_y(rect.y());
63
64 return rv;
65 }
66
67 // GetMouseAnchorRect returns a rectangle that has one corner where the mouse
68 // clicked, and the opposite corner at the closest corner of the work area
69 // (inset by an appropriate margin.)
70 gfx::Rect GetMouseAnchorRect(gfx::Point cursor) {
71 // TODO(dewittj): GetNativeScreen could be wrong for Aura.
72 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
73 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
74 work_area.Inset(kScreenEdgePadding, kScreenEdgePadding);
75 gfx::Point corner = GetClosestCorner(work_area, cursor);
76
77 gfx::Rect mouse_anchor_rect(gfx::BoundingRect(cursor, corner));
78 return mouse_anchor_rect;
79 }
80
81 gfx::ImageSkia GetIcon(int unread_count) { 38 gfx::ImageSkia GetIcon(int unread_count) {
82 bool has_unread = unread_count > 0; 39 bool has_unread = unread_count > 0;
83 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 40 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
84 if (!has_unread) 41 if (!has_unread)
85 return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY); 42 return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY);
86 43
87 // TODO(dewittj): Use scale factors other than 100P. 44 // TODO(dewittj): Use scale factors other than 100P.
88 scoped_ptr<gfx::Canvas> canvas( 45 scoped_ptr<gfx::Canvas> canvas(
89 new gfx::Canvas(gfx::Size(kSystemTrayWidth, kSystemTrayHeight), 46 new gfx::Canvas(gfx::Size(kSystemTrayWidth, kSystemTrayHeight),
90 ui::SCALE_FACTOR_100P, 47 ui::SCALE_FACTOR_100P,
(...skipping 18 matching lines...) Expand all
109 false); 66 false);
110 return gfx::ImageSkia(canvas->ExtractImageRep()); 67 return gfx::ImageSkia(canvas->ExtractImageRep());
111 } 68 }
112 69
113 } // namespace 70 } // namespace
114 71
115 using content::UserMetricsAction; 72 using content::UserMetricsAction;
116 73
117 namespace message_center { 74 namespace message_center {
118 75
76 namespace internal {
77
78 // Gets the position of the systray (same as position of taskbar) from the
79 // work area bounds. Returns ALIGNMENT_NONE if position cannot be found.
80 Alignment GetSystrayAlignment() {
dewittj 2013/07/15 18:38:58 In the future we could use AppBar for this on Wind
81 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
82 // TODO(dewittj): It's possible GetPrimaryDisplay is wrong.
83 gfx::Rect screen_bounds = screen->GetPrimaryDisplay().bounds();
84 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
85 work_area.Inset(kScreenEdgePadding, kScreenEdgePadding);
86
87 // Comparing the work area to the screen bounds gives us the location of the
88 // taskbar. If the work area is exactly the same as the screen bounds,
89 // we are unable to locate the systray so we say we don't know it's alignment.
90 if (work_area.height() < screen_bounds.height()) {
91 if (work_area.y() > screen_bounds.y())
92 return ALIGNMENT_TOP;
93 return ALIGNMENT_BOTTOM;
94 }
95 if (work_area.width() < screen_bounds.width()) {
96 if (work_area.x() > screen_bounds.x())
97 return ALIGNMENT_LEFT;
98 return ALIGNMENT_RIGHT;
99 }
100
101 return ALIGNMENT_NONE;
102 }
103
104 gfx::Point GetClosestCorner(const gfx::Rect& rect, const gfx::Point& query) {
105 gfx::Point center_point = rect.CenterPoint();
106 gfx::Point rv;
107
108 if (query.x() > center_point.x())
109 rv.set_x(rect.right());
110 else
111 rv.set_x(rect.x());
112
113 if (query.y() > center_point.y())
114 rv.set_y(rect.bottom());
115 else
116 rv.set_y(rect.y());
117
118 return rv;
119 }
120
121 // Gets the corner of the screen where the message center should pop up.
dewittj 2013/07/15 18:38:58 This comment probably belongs on GetClosestCorner?
122 Alignment GetAnchorAlignment(const gfx::Rect& work_area, gfx::Point corner) {
123 gfx::Point center = work_area.CenterPoint();
124
125 Alignment anchor_alignment =
126 center.y() > corner.y() ? ALIGNMENT_TOP : ALIGNMENT_BOTTOM;
127 anchor_alignment =
128 (Alignment)(anchor_alignment |
129 (center.x() > corner.x() ? ALIGNMENT_LEFT : ALIGNMENT_RIGHT));
130
131 return anchor_alignment;
132 }
133
134 } // namespace internal
135
119 MessageCenterTrayDelegate* CreateMessageCenterTray() { 136 MessageCenterTrayDelegate* CreateMessageCenterTray() {
120 return new WebNotificationTray(); 137 return new WebNotificationTray();
121 } 138 }
122 139
123 WebNotificationTray::WebNotificationTray() 140 WebNotificationTray::WebNotificationTray()
124 : status_icon_(NULL), 141 : message_center_delegate_(NULL),
142 status_icon_(NULL),
125 message_center_visible_(false), 143 message_center_visible_(false),
126 should_update_tray_content_(true) { 144 should_update_tray_content_(true) {
127 message_center_tray_.reset( 145 message_center_tray_.reset(
128 new MessageCenterTray(this, g_browser_process->message_center())); 146 new MessageCenterTray(this, g_browser_process->message_center()));
129 UpdateStatusIcon(); 147 UpdateStatusIcon();
130 } 148 }
131 149
132 WebNotificationTray::~WebNotificationTray() { 150 WebNotificationTray::~WebNotificationTray() {
133 // Reset this early so that delegated events during destruction don't cause 151 // Reset this early so that delegated events during destruction don't cause
134 // problems. 152 // problems.
135 message_center_tray_.reset(); 153 message_center_tray_.reset();
136 DestroyStatusIcon(); 154 DestroyStatusIcon();
137 } 155 }
138 156
139 message_center::MessageCenter* WebNotificationTray::message_center() { 157 message_center::MessageCenter* WebNotificationTray::message_center() {
140 return message_center_tray_->message_center(); 158 return message_center_tray_->message_center();
141 } 159 }
142 160
143 bool WebNotificationTray::ShowPopups() { 161 bool WebNotificationTray::ShowPopups() {
144 popup_collection_.reset(new message_center::MessagePopupCollection( 162 popup_collection_.reset(new message_center::MessagePopupCollection(
145 NULL, message_center(), message_center_tray_.get())); 163 NULL, message_center(), message_center_tray_.get()));
146 return true; 164 return true;
147 } 165 }
148 166
149 void WebNotificationTray::HidePopups() { popup_collection_.reset(); } 167 void WebNotificationTray::HidePopups() { popup_collection_.reset(); }
150 168
151 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) { 169 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) {
152 content::RecordAction(UserMetricsAction("Notifications.ShowMessageCenter")); 170 content::RecordAction(UserMetricsAction("Notifications.ShowMessageCenter"));
153 171
154 // Using MessageBubbleBase instead of MessageCenterBubble to 172 message_center_delegate_ = new MessageCenterWidgetDelegate(
155 // remove dependence on implicit type conversion 173 this,
156 scoped_ptr<message_center::MessageCenterBubble> bubble( 174 message_center_tray_.get(),
157 new message_center::MessageCenterBubble(message_center(), 175 show_settings, /* settings initally invisible */
dewittj 2013/07/15 18:38:58 //-style comment here.
158 message_center_tray_.get())); 176 GetPositionInfo());
159 177
160 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
161 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
162 views::TrayBubbleView::AnchorAlignment alignment = GetAnchorAlignment();
163
164 int max_height = work_area.height();
165
166 // If the alignment is left- or right-oriented, the bubble can fill up the
167 // entire vertical height of the screen since the bubble is rendered to the
168 // side of the clicked icon. Otherwise we have to adjust for the arrow's
169 // height.
170 if (alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM ||
171 alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_TOP) {
172 max_height -= 2 * kScreenEdgePadding;
173
174 // If the work area contains the click point, then we know that the icon is
175 // not in the taskbar. Then we need to subtract the distance of the click
176 // point from the edge of the work area so we can see the whole bubble.
177 if (work_area.Contains(mouse_click_point_)) {
178 max_height -= std::min(mouse_click_point_.y() - work_area.y(),
179 work_area.bottom() - mouse_click_point_.y());
180 }
181 }
182 bubble->SetMaxHeight(max_height);
183 if (show_settings)
184 bubble->SetSettingsVisible();
185
186 message_center_bubble_.reset(new internal::NotificationBubbleWrapper(
187 this,
188 bubble.PassAs<message_center::MessageBubbleBase>(),
189 internal::NotificationBubbleWrapper::BUBBLE_TYPE_MESSAGE_CENTER));
190 return true; 178 return true;
191 } 179 }
192 180
193 bool WebNotificationTray::ShowMessageCenter() { 181 bool WebNotificationTray::ShowMessageCenter() {
194 return ShowMessageCenterInternal(false /* show_settings */); 182 return ShowMessageCenterInternal(false /* show_settings */);
195 } 183 }
196 184
197 void WebNotificationTray::HideMessageCenter() { 185 void WebNotificationTray::HideMessageCenter() {
198 message_center_bubble_.reset(); 186 if (message_center_delegate_) {
187 views::Widget* widget = message_center_delegate_->GetWidget();
188 if (widget)
189 widget->Close();
190 }
199 } 191 }
200 192
201 bool WebNotificationTray::ShowNotifierSettings() { 193 bool WebNotificationTray::ShowNotifierSettings() {
202 if (message_center_bubble_) { 194 if (message_center_delegate_) {
203 static_cast<MessageCenterBubble*>( 195 message_center_delegate_->SetSettingsVisible(true);
204 message_center_bubble_->bubble())->SetSettingsVisible();
205 return true; 196 return true;
206 } 197 }
207 return ShowMessageCenterInternal(true /* show_settings */); 198 return ShowMessageCenterInternal(true /* show_settings */);
208 } 199 }
209 200
210 void WebNotificationTray::OnMessageCenterTrayChanged() { 201 void WebNotificationTray::OnMessageCenterTrayChanged() {
211 // See the comments in ash/system/web_notification/web_notification_tray.cc 202 // See the comments in ash/system/web_notification/web_notification_tray.cc
212 // for why PostTask. 203 // for why PostTask.
213 should_update_tray_content_ = true; 204 should_update_tray_content_ = true;
214 base::MessageLoop::current()->PostTask( 205 base::MessageLoop::current()->PostTask(
215 FROM_HERE, 206 FROM_HERE,
216 base::Bind(&WebNotificationTray::UpdateStatusIcon, AsWeakPtr())); 207 base::Bind(&WebNotificationTray::UpdateStatusIcon, AsWeakPtr()));
217 } 208 }
218 209
219 gfx::Rect WebNotificationTray::GetMessageCenterAnchor() { 210 void WebNotificationTray::OnStatusIconClicked() {
220 return GetMouseAnchorRect(mouse_click_point_); 211 // TODO(dewittj): It's possible GetNativeScreen is wrong for win-aura.
212 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
213 mouse_click_point_ = screen->GetCursorScreenPoint();
214 message_center_tray_->ToggleMessageCenterBubble();
221 } 215 }
222 216
223 gfx::Rect WebNotificationTray::GetPopupAnchor() {
224 return GetCornerAnchorRect();
225 }
226
227 views::TrayBubbleView::AnchorAlignment
228 WebNotificationTray::GetAnchorAlignment() {
229 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
230 // TODO(dewittj): It's possible GetPrimaryDisplay is wrong.
231 gfx::Rect screen_bounds = screen->GetPrimaryDisplay().bounds();
232 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
233
234 // Comparing the work area to the screen bounds gives us the location of the
235 // taskbar. If the work area is less tall than the screen, assume the taskbar
236 // is on the bottom, and cause the arrow to be displayed on the bottom of the
237 // bubble. Otherwise, cause the arrow to be displayed on the side of the
238 // bubble that the taskbar is on.
239 if (work_area.width() < screen_bounds.width()) {
240 if (work_area.x() > screen_bounds.x())
241 return views::TrayBubbleView::ANCHOR_ALIGNMENT_LEFT;
242 return views::TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT;
243 }
244 return views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
245 }
246
247 gfx::NativeView WebNotificationTray::GetBubbleWindowContainer() { return NULL; }
248
249 void WebNotificationTray::UpdateStatusIcon() { 217 void WebNotificationTray::UpdateStatusIcon() {
250 if (!should_update_tray_content_) 218 if (!should_update_tray_content_)
251 return; 219 return;
252 should_update_tray_content_ = false; 220 should_update_tray_content_ = false;
253 221
254 int total_notifications = message_center()->NotificationCount(); 222 int total_notifications = message_center()->NotificationCount();
255 if (total_notifications == 0) { 223 if (total_notifications == 0) {
256 DestroyStatusIcon(); 224 DestroyStatusIcon();
257 return; 225 return;
258 } 226 }
259 227
260 int unread_notifications = message_center()->UnreadNotificationCount(); 228 int unread_notifications = message_center()->UnreadNotificationCount();
261 StatusIcon* status_icon = GetStatusIcon(); 229 StatusIcon* status_icon = GetStatusIcon();
262 if (!status_icon) 230 if (!status_icon)
263 return; 231 return;
264 232
265 status_icon->SetImage(GetIcon(unread_notifications)); 233 status_icon->SetImage(GetIcon(unread_notifications));
266 234
267 string16 product_name(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); 235 string16 product_name(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME));
268 if (unread_notifications > 0) { 236 if (unread_notifications > 0) {
269 string16 str_unread_count = base::FormatNumber(unread_notifications); 237 string16 str_unread_count = base::FormatNumber(unread_notifications);
270 status_icon->SetToolTip(l10n_util::GetStringFUTF16( 238 status_icon->SetToolTip(l10n_util::GetStringFUTF16(
271 IDS_MESSAGE_CENTER_TOOLTIP_UNREAD, product_name, str_unread_count)); 239 IDS_MESSAGE_CENTER_TOOLTIP_UNREAD, product_name, str_unread_count));
272 } else { 240 } else {
273 status_icon->SetToolTip( 241 status_icon->SetToolTip(
274 l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_TOOLTIP, product_name)); 242 l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_TOOLTIP, product_name));
275 } 243 }
276 } 244 }
277 245
278 void WebNotificationTray::OnStatusIconClicked() { 246 void WebNotificationTray::HideBubble() {
279 // TODO(dewittj): It's possible GetNativeScreen is wrong for win-aura. 247 message_center_tray_->HideMessageCenterBubble();
280 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
281 mouse_click_point_ = screen->GetCursorScreenPoint();
282 message_center_tray_->ToggleMessageCenterBubble();
283 } 248 }
284 249
285 void WebNotificationTray::HideBubbleWithView( 250 void WebNotificationTray::SetMessageCenterHidden() {
286 const views::TrayBubbleView* bubble_view) { 251 if (message_center_delegate_) {
287 if (message_center_bubble_.get() && 252 message_center_tray_->SetMessageCenterHidden();
288 bubble_view == message_center_bubble_->bubble_view()) { 253 message_center_delegate_ = NULL;
289 message_center_tray_->HideMessageCenterBubble();
290 } 254 }
291 } 255 }
292 256
257 PositionInfo WebNotificationTray::GetPositionInfo() {
258 PositionInfo pos_info;
259
260 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
261 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
262 work_area.Inset(kScreenEdgePadding, kScreenEdgePadding);
263
264 gfx::Point corner = internal::GetClosestCorner(work_area, mouse_click_point_);
265
266 pos_info.systray_alignment = internal::GetSystrayAlignment();
267
268 // We assume the systray and taskbar are either at the top or at the bottom
269 // if we are not able to find it.
270 if (pos_info.systray_alignment == ALIGNMENT_NONE) {
271 if (mouse_click_point_.y() > corner.y())
272 pos_info.systray_alignment = ALIGNMENT_TOP;
273 else
274 pos_info.systray_alignment = ALIGNMENT_BOTTOM;
275 }
276
277 pos_info.message_center_alignment =
278 internal::GetAnchorAlignment(work_area, corner);
279
280 pos_info.inital_anchor_point = corner;
281 pos_info.max_height = work_area.height();
282
283 if (work_area.Contains(mouse_click_point_)) {
284 pos_info.max_height -= std::abs(mouse_click_point_.y() - corner.y());
285
286 // Message center is in the work area. So position it few pixels above the
287 // mouse click point if alignemnt is towards bottom and few pixels below if
288 // alignment is towards top.
289 pos_info.inital_anchor_point.set_y(mouse_click_point_.y() +
290 (pos_info.message_center_alignment & ALIGNMENT_BOTTOM ? -5 : 5));
291 }
292 return pos_info;
293 }
294
293 StatusIcon* WebNotificationTray::GetStatusIcon() { 295 StatusIcon* WebNotificationTray::GetStatusIcon() {
294 if (status_icon_) 296 if (status_icon_)
295 return status_icon_; 297 return status_icon_;
296 298
297 StatusTray* status_tray = g_browser_process->status_tray(); 299 StatusTray* status_tray = g_browser_process->status_tray();
298 if (!status_tray) 300 if (!status_tray)
299 return NULL; 301 return NULL;
300 302
301 StatusIcon* status_icon = status_tray->CreateStatusIcon(); 303 StatusIcon* status_icon = status_tray->CreateStatusIcon();
302 if (!status_icon) 304 if (!status_icon)
(...skipping 15 matching lines...) Expand all
318 if (status_tray) 320 if (status_tray)
319 status_tray->RemoveStatusIcon(status_icon_); 321 status_tray->RemoveStatusIcon(status_icon_);
320 status_icon_ = NULL; 322 status_icon_ = NULL;
321 } 323 }
322 324
323 void WebNotificationTray::AddQuietModeMenu(StatusIcon* status_icon) { 325 void WebNotificationTray::AddQuietModeMenu(StatusIcon* status_icon) {
324 DCHECK(status_icon); 326 DCHECK(status_icon);
325 status_icon->SetContextMenu(message_center_tray_->CreateQuietModeMenu()); 327 status_icon->SetContextMenu(message_center_tray_->CreateQuietModeMenu());
326 } 328 }
327 329
328 message_center::MessageCenterBubble* 330 MessageCenterWidgetDelegate*
329 WebNotificationTray::GetMessageCenterBubbleForTest() { 331 WebNotificationTray::GetMessageCenterWidgetDelegateForTest() {
330 if (!message_center_bubble_.get()) 332 return message_center_delegate_;
331 return NULL;
332 return static_cast<message_center::MessageCenterBubble*>(
333 message_center_bubble_->bubble());
334 } 333 }
335 334
336 } // namespace message_center 335 } // namespace message_center
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698