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

Side by Side Diff: ash/common/system/web_notification/web_notification_tray.cc

Issue 2243563002: Show small notification icons in notification tray (reland) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ash/common/system/web_notification/web_notification_tray.h" 5 #include "ash/common/system/web_notification/web_notification_tray.h"
6 6
7 #include "ash/common/ash_switches.h" 7 #include "ash/common/ash_switches.h"
8 #include "ash/common/material_design/material_design_controller.h" 8 #include "ash/common/material_design/material_design_controller.h"
9 #include "ash/common/session/session_state_delegate.h" 9 #include "ash/common/session/session_state_delegate.h"
10 #include "ash/common/shelf/shelf_constants.h" 10 #include "ash/common/shelf/shelf_constants.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 } 55 }
56 56
57 } // namespace message_center 57 } // namespace message_center
58 58
59 #endif // defined(OS_CHROMEOS) 59 #endif // defined(OS_CHROMEOS)
60 60
61 namespace ash { 61 namespace ash {
62 namespace { 62 namespace {
63 63
64 // Menu commands 64 // Menu commands
65 const int kToggleQuietMode = 0; 65 constexpr int kToggleQuietMode = 0;
66 const int kEnableQuietModeDay = 2; 66 constexpr int kEnableQuietModeDay = 2;
67
68 constexpr int kMaximumSmallIconCount = 3;
69
70 constexpr gfx::Size kTrayItemInnerIconSize(16, 16);
71 constexpr gfx::Size kTrayItemInnerBellIconSize(18, 18);
72 constexpr gfx::Size kTrayItemOuterSize(26, 26);
73 constexpr gfx::Insets kTrayItemInsets(3, 3);
74
75 constexpr int kTrayItemAnimationDurationMS = 200;
76
77 constexpr size_t kMaximumNotificationNumber = 99;
78
79 // Flag to disable animation. Only for testing.
80 bool disable_animations_for_test = false;
67 } 81 }
68 82
69 namespace { 83 namespace {
70 84
71 const SkColor kWebNotificationColorNoUnread = 85 const SkColor kWebNotificationColorNoUnread =
72 SkColorSetARGB(128, 255, 255, 255); 86 SkColorSetARGB(128, 255, 255, 255);
73 const SkColor kWebNotificationColorWithUnread = SK_ColorWHITE; 87 const SkColor kWebNotificationColorWithUnread = SK_ColorWHITE;
74 const int kNoUnreadIconSize = 18; 88 const int kNoUnreadIconSize = 18;
75 } 89 }
76 90
(...skipping 30 matching lines...) Expand all
107 // Convenience accessors. 121 // Convenience accessors.
108 views::TrayBubbleView* bubble_view() const { return bubble_->bubble_view(); } 122 views::TrayBubbleView* bubble_view() const { return bubble_->bubble_view(); }
109 123
110 private: 124 private:
111 std::unique_ptr<message_center::MessageBubbleBase> bubble_; 125 std::unique_ptr<message_center::MessageBubbleBase> bubble_;
112 std::unique_ptr<TrayBubbleWrapper> bubble_wrapper_; 126 std::unique_ptr<TrayBubbleWrapper> bubble_wrapper_;
113 127
114 DISALLOW_COPY_AND_ASSIGN(WebNotificationBubbleWrapper); 128 DISALLOW_COPY_AND_ASSIGN(WebNotificationBubbleWrapper);
115 }; 129 };
116 130
117 class WebNotificationIcon : public views::View { 131 class WebNotificationItem : public views::View, public gfx::AnimationDelegate {
118 public: 132 public:
119 WebNotificationIcon() : is_bubble_visible_(false), unread_count_(0) { 133 WebNotificationItem(gfx::AnimationContainer* container,
134 WebNotificationTray* tray)
135 : tray_(tray) {
136 SetPaintToLayer(true);
137 layer()->SetFillsBoundsOpaquely(false);
138 views::View::SetVisible(false);
139 set_owned_by_client();
140
120 SetLayoutManager(new views::FillLayout); 141 SetLayoutManager(new views::FillLayout);
121 142
122 gfx::ImageSkia image; 143 animation_.reset(new gfx::SlideAnimation(this));
123 if (MaterialDesignController::IsShelfMaterial()) { 144 animation_->SetContainer(container);
124 image = CreateVectorIcon(gfx::VectorIconId::SHELF_NOTIFICATIONS, 145 animation_->SetSlideDuration(kTrayItemAnimationDurationMS);
125 kShelfIconColor); 146 animation_->SetTweenType(gfx::Tween::LINEAR);
126 } else { 147 }
127 image = 148
128 CreateVectorIcon(gfx::VectorIconId::NOTIFICATIONS, kNoUnreadIconSize, 149 void SetVisible(bool set_visible) override {
129 kWebNotificationColorNoUnread); 150 if (!GetWidget() || disable_animations_for_test) {
151 views::View::SetVisible(set_visible);
152 return;
130 } 153 }
131 154
132 no_unread_icon_.SetImage(image); 155 if (!set_visible) {
133 no_unread_icon_.set_owned_by_client(); 156 animation_->Hide();
134 157 AnimationProgressed(animation_.get());
135 unread_label_.set_owned_by_client(); 158 } else {
136 SetupLabelForTray(&unread_label_); 159 animation_->Show();
137 160 AnimationProgressed(animation_.get());
138 AddChildView(&no_unread_icon_); 161 views::View::SetVisible(true);
162 }
139 } 163 }
140 164
141 void SetBubbleVisible(bool visible) { 165 void HideAndDelete() {
142 if (visible == is_bubble_visible_) 166 SetVisible(false);
143 return;
144 167
145 is_bubble_visible_ = visible; 168 if (!visible() && !animation_->is_animating()) {
146 UpdateIconVisibility(); 169 if (parent())
147 } 170 parent()->RemoveChildView(this);
148 171 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
149 void SetUnreadCount(int unread_count) { 172 } else {
150 // base::FormatNumber doesn't convert to arabic numeric characters. 173 delete_after_animation_ = true;
151 // TODO(mukai): use ICU to support conversion for such locales. 174 }
152 unread_count_ = unread_count;
153 UpdateIconVisibility();
154 } 175 }
155 176
156 protected: 177 protected:
157 // Overridden from views::View: 178 // Overridden from views::View:
158 gfx::Size GetPreferredSize() const override { 179 gfx::Size GetPreferredSize() const override {
159 const int size = GetTrayConstant(TRAY_ITEM_HEIGHT_LEGACY); 180 if (!animation_.get() || !animation_->is_animating())
160 return gfx::Size(size, size); 181 return kTrayItemOuterSize;
182
183 // Animate the width (or height) when this item shows (or hides) so that
184 // the icons on the left are shifted with the animation.
185 // Note that TrayItemView does the same thing.
186 gfx::Size size = kTrayItemOuterSize;
187 if (IsHorizontalLayout()) {
188 size.set_width(std::max(
189 1, gfx::ToRoundedInt(size.width() * animation_->GetCurrentValue())));
190 } else {
191 size.set_height(std::max(
192 1, gfx::ToRoundedInt(size.height() * animation_->GetCurrentValue())));
193 }
194 return size;
161 } 195 }
162 196
163 int GetHeightForWidth(int width) const override { 197 int GetHeightForWidth(int width) const override {
164 return GetPreferredSize().height(); 198 return GetPreferredSize().height();
165 } 199 }
166 200
201 bool IsHorizontalLayout() const {
202 return IsHorizontalAlignment(tray_->shelf_alignment());
203 }
204
167 private: 205 private:
168 void UpdateIconVisibility() { 206 // gfx::AnimationDelegate:
169 if (unread_count_ == 0) { 207 void AnimationProgressed(const gfx::Animation* animation) override {
170 if (!Contains(&no_unread_icon_)) { 208 gfx::Transform transform;
171 RemoveAllChildViews(false /* delete_children */); 209 if (IsHorizontalLayout()) {
172 AddChildView(&no_unread_icon_); 210 transform.Translate(0, animation->CurrentValueBetween(
173 } 211 static_cast<double>(height()) / 2., 0.));
174 } else { 212 } else {
175 if (!Contains(&unread_label_)) { 213 transform.Translate(
176 RemoveAllChildViews(false /* delete_children */); 214 animation->CurrentValueBetween(static_cast<double>(width() / 2.), 0.),
177 AddChildView(&unread_label_); 215 0);
178 } 216 }
217 transform.Scale(animation->GetCurrentValue(), animation->GetCurrentValue());
218 layer()->SetTransform(transform);
219 PreferredSizeChanged();
220 }
221 void AnimationEnded(const gfx::Animation* animation) override {
222 if (animation->GetCurrentValue() < 0.1)
223 views::View::SetVisible(false);
179 224
180 // TODO(mukai): move NINE_PLUS message to ui_strings, it doesn't need to 225 if (delete_after_animation_) {
181 // be in ash_strings. 226 if (parent())
182 unread_label_.SetText( 227 parent()->RemoveChildView(this);
183 (unread_count_ > 9) ? l10n_util::GetStringUTF16( 228 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
184 IDS_ASH_NOTIFICATION_UNREAD_COUNT_NINE_PLUS)
185 : base::FormatNumber(unread_count_));
186 unread_label_.SetEnabledColor((unread_count_ > 0)
187 ? kWebNotificationColorWithUnread
188 : kWebNotificationColorNoUnread);
189 } 229 }
230 }
231 void AnimationCanceled(const gfx::Animation* animation) override {
232 AnimationEnded(animation);
233 }
234
235 std::unique_ptr<gfx::SlideAnimation> animation_;
236 bool delete_after_animation_ = false;
237 WebNotificationTray* tray_;
238
239 DISALLOW_COPY_AND_ASSIGN(WebNotificationItem);
240 };
241
242 class WebNotificationImage : public WebNotificationItem {
243 public:
244 WebNotificationImage(const gfx::ImageSkia& image,
245 gfx::Size size,
246 gfx::AnimationContainer* container,
247 WebNotificationTray* tray)
248 : WebNotificationItem(container, tray) {
249 view_ = new views::ImageView();
250 view_->SetImage(image);
251 view_->SetImageSize(size);
252 AddChildView(view_);
253 }
254
255 private:
256 views::ImageView* view_;
257
258 DISALLOW_COPY_AND_ASSIGN(WebNotificationImage);
259 };
260
261 class WebNotificationLabel : public WebNotificationItem {
262 public:
263 WebNotificationLabel(gfx::AnimationContainer* container,
264 WebNotificationTray* tray)
265 : WebNotificationItem(container, tray) {
266 view_ = new views::Label();
267 SetupLabelForTray(view_);
268 AddChildView(view_);
269 }
270
271 void SetNotificationCount(bool small_icons_exist, size_t notification_count) {
272 notification_count = std::min(notification_count,
273 kMaximumNotificationNumber); // cap with 99
274
275 // TODO(yoshiki): Use a string for "99" and "+99".
276
277 base::string16 str = base::FormatNumber(notification_count);
278 if (small_icons_exist) {
279 if (!base::i18n::IsRTL())
280 str = base::ASCIIToUTF16("+") + str;
281 else
282 str = str + base::ASCIIToUTF16("+");
283 }
284
285 view_->SetText(str);
286 view_->SetEnabledColor(kWebNotificationColorWithUnread);
190 SchedulePaint(); 287 SchedulePaint();
191 } 288 }
192 289
193 bool is_bubble_visible_; 290 private:
194 int unread_count_; 291 views::Label* view_;
195 292
196 views::ImageView no_unread_icon_; 293 DISALLOW_COPY_AND_ASSIGN(WebNotificationLabel);
197 views::Label unread_label_;
198
199 DISALLOW_COPY_AND_ASSIGN(WebNotificationIcon);
200 }; 294 };
201 295
202 WebNotificationTray::WebNotificationTray(WmShelf* shelf, 296 WebNotificationTray::WebNotificationTray(WmShelf* shelf,
203 WmWindow* status_area_window, 297 WmWindow* status_area_window,
204 SystemTray* system_tray) 298 SystemTray* system_tray)
205 : TrayBackgroundView(shelf), 299 : TrayBackgroundView(shelf),
206 status_area_window_(status_area_window), 300 status_area_window_(status_area_window),
207 system_tray_(system_tray), 301 system_tray_(system_tray),
208 icon_(new WebNotificationIcon),
209 show_message_center_on_unlock_(false), 302 show_message_center_on_unlock_(false),
210 should_update_tray_content_(false), 303 should_update_tray_content_(false),
211 should_block_shelf_auto_hide_(false) { 304 should_block_shelf_auto_hide_(false) {
212 DCHECK(shelf); 305 DCHECK(shelf);
213 DCHECK(status_area_window_); 306 DCHECK(status_area_window_);
214 DCHECK(system_tray_); 307 DCHECK(system_tray_);
215 308
216 tray_container()->AddChildView(icon_); 309 gfx::ImageSkia bell_image;
310 if (MaterialDesignController::IsShelfMaterial()) {
311 bell_image = CreateVectorIcon(gfx::VectorIconId::SHELF_NOTIFICATIONS,
312 kShelfIconColor);
313 } else {
314 bell_image =
315 CreateVectorIcon(gfx::VectorIconId::NOTIFICATIONS, kNoUnreadIconSize,
316 kWebNotificationColorNoUnread);
317 }
318 bell_icon_.reset(new WebNotificationImage(bell_image,
319 kTrayItemInnerBellIconSize,
320 animation_container_.get(), this));
321 tray_container()->AddChildView(bell_icon_.get());
322
323 counter_.reset(new WebNotificationLabel(animation_container_.get(), this));
324 tray_container()->AddChildView(counter_.get());
325
217 SetContentsBackground(); 326 SetContentsBackground();
218 tray_container()->SetBorder(views::Border::NullBorder()); 327 tray_container()->SetBorder(views::Border::NullBorder());
219 message_center_tray_.reset(new message_center::MessageCenterTray( 328 message_center_tray_.reset(new message_center::MessageCenterTray(
220 this, message_center::MessageCenter::Get())); 329 this, message_center::MessageCenter::Get()));
221 popup_alignment_delegate_.reset(new AshPopupAlignmentDelegate(shelf)); 330 popup_alignment_delegate_.reset(new AshPopupAlignmentDelegate(shelf));
222 popup_collection_.reset(new message_center::MessagePopupCollection( 331 popup_collection_.reset(new message_center::MessagePopupCollection(
223 message_center(), message_center_tray_.get(), 332 message_center(), message_center_tray_.get(),
224 popup_alignment_delegate_.get())); 333 popup_alignment_delegate_.get()));
225 const display::Display& display = 334 const display::Display& display =
226 status_area_window_->GetDisplayNearestWindow(); 335 status_area_window_->GetDisplayNearestWindow();
227 popup_alignment_delegate_->StartObserving(display::Screen::GetScreen(), 336 popup_alignment_delegate_->StartObserving(display::Screen::GetScreen(),
228 display); 337 display);
229 OnMessageCenterTrayChanged(); 338 OnMessageCenterTrayChanged();
339
340 tray_container()->SetMargin(kTrayItemInsets);
230 } 341 }
231 342
232 WebNotificationTray::~WebNotificationTray() { 343 WebNotificationTray::~WebNotificationTray() {
233 // Release any child views that might have back pointers before ~View(). 344 // Release any child views that might have back pointers before ~View().
234 message_center_bubble_.reset(); 345 message_center_bubble_.reset();
235 popup_alignment_delegate_.reset(); 346 popup_alignment_delegate_.reset();
236 popup_collection_.reset(); 347 popup_collection_.reset();
237 } 348 }
238 349
350 // static
351 void WebNotificationTray::DisableAnimationsForTest(bool disable) {
352 disable_animations_for_test = disable;
353 }
354
239 // Public methods. 355 // Public methods.
240 356
241 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) { 357 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) {
242 if (!ShouldShowMessageCenter()) 358 if (!ShouldShowMessageCenter())
243 return false; 359 return false;
244 360
245 should_block_shelf_auto_hide_ = true; 361 should_block_shelf_auto_hide_ = true;
246 message_center::MessageCenterBubble* message_center_bubble = 362 message_center::MessageCenterBubble* message_center_bubble =
247 new message_center::MessageCenterBubble(message_center(), 363 new message_center::MessageCenterBubble(message_center(),
248 message_center_tray_.get(), true); 364 message_center_tray_.get(), true);
249 365
250 int max_height; 366 int max_height;
251 if (IsHorizontalAlignment(shelf()->GetAlignment())) { 367 if (IsHorizontalAlignment(shelf_alignment())) {
252 max_height = shelf()->GetIdealBounds().y(); 368 max_height = shelf()->GetIdealBounds().y();
253 } else { 369 } else {
254 // Assume the status area and bubble bottoms are aligned when vertical. 370 // Assume the status area and bubble bottoms are aligned when vertical.
255 gfx::Rect bounds_in_root = 371 gfx::Rect bounds_in_root =
256 status_area_window_->GetRootWindow()->ConvertRectFromScreen( 372 status_area_window_->GetRootWindow()->ConvertRectFromScreen(
257 status_area_window_->GetBoundsInScreen()); 373 status_area_window_->GetBoundsInScreen());
258 max_height = bounds_in_root.bottom(); 374 max_height = bounds_in_root.bottom();
259 } 375 }
260 message_center_bubble->SetMaxHeight( 376 message_center_bubble->SetMaxHeight(
261 std::max(0, max_height - GetTrayConstant(TRAY_SPACING))); 377 std::max(0, max_height - GetTrayConstant(TRAY_SPACING)));
262 if (show_settings) 378 if (show_settings)
263 message_center_bubble->SetSettingsVisible(); 379 message_center_bubble->SetSettingsVisible();
264 message_center_bubble_.reset( 380 message_center_bubble_.reset(
265 new WebNotificationBubbleWrapper(this, message_center_bubble)); 381 new WebNotificationBubbleWrapper(this, message_center_bubble));
266 382
267 system_tray_->SetHideNotifications(true); 383 system_tray_->SetHideNotifications(true);
268 shelf()->UpdateAutoHideState(); 384 shelf()->UpdateAutoHideState();
269 icon_->SetBubbleVisible(true);
270 SetDrawBackgroundAsActive(true); 385 SetDrawBackgroundAsActive(true);
271 return true; 386 return true;
272 } 387 }
273 388
274 bool WebNotificationTray::ShowMessageCenter() { 389 bool WebNotificationTray::ShowMessageCenter() {
275 return ShowMessageCenterInternal(false /* show_settings */); 390 return ShowMessageCenterInternal(false /* show_settings */);
276 } 391 }
277 392
278 void WebNotificationTray::HideMessageCenter() { 393 void WebNotificationTray::HideMessageCenter() {
279 if (!message_center_bubble()) 394 if (!message_center_bubble())
280 return; 395 return;
281 SetDrawBackgroundAsActive(false); 396 SetDrawBackgroundAsActive(false);
282 message_center_bubble_.reset(); 397 message_center_bubble_.reset();
283 should_block_shelf_auto_hide_ = false; 398 should_block_shelf_auto_hide_ = false;
284 show_message_center_on_unlock_ = false; 399 show_message_center_on_unlock_ = false;
285 system_tray_->SetHideNotifications(false); 400 system_tray_->SetHideNotifications(false);
286 shelf()->UpdateAutoHideState(); 401 shelf()->UpdateAutoHideState();
287 icon_->SetBubbleVisible(false);
288 } 402 }
289 403
290 void WebNotificationTray::SetTrayBubbleHeight(int height) { 404 void WebNotificationTray::SetTrayBubbleHeight(int height) {
291 popup_alignment_delegate_->SetTrayBubbleHeight(height); 405 popup_alignment_delegate_->SetTrayBubbleHeight(height);
292 } 406 }
293 407
294 int WebNotificationTray::tray_bubble_height_for_test() const { 408 int WebNotificationTray::tray_bubble_height_for_test() const {
295 return popup_alignment_delegate_->tray_bubble_height_for_test(); 409 return popup_alignment_delegate_->tray_bubble_height_for_test();
296 } 410 }
297 411
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 base::ThreadTaskRunnerHandle::Get()->PostTask( 577 base::ThreadTaskRunnerHandle::Get()->PostTask(
464 FROM_HERE, 578 FROM_HERE,
465 base::Bind(&WebNotificationTray::UpdateTrayContent, AsWeakPtr())); 579 base::Bind(&WebNotificationTray::UpdateTrayContent, AsWeakPtr()));
466 } 580 }
467 581
468 void WebNotificationTray::UpdateTrayContent() { 582 void WebNotificationTray::UpdateTrayContent() {
469 if (!should_update_tray_content_) 583 if (!should_update_tray_content_)
470 return; 584 return;
471 should_update_tray_content_ = false; 585 should_update_tray_content_ = false;
472 586
587 std::unordered_set<std::string> notification_ids;
588 for (auto pair : visible_small_icons_)
589 notification_ids.insert(pair.first);
590
591 // Add small icons (up to kMaximumSmallIconCount = 3).
473 message_center::MessageCenter* message_center = 592 message_center::MessageCenter* message_center =
474 message_center_tray_->message_center(); 593 message_center_tray_->message_center();
475 icon_->SetUnreadCount(message_center->UnreadNotificationCount()); 594 size_t visible_small_icon_count = 0;
595 for (const auto* notification : message_center->GetVisibleNotifications()) {
596 gfx::Image image = notification->small_image();
597 if (image.IsEmpty())
598 continue;
599
600 if (visible_small_icon_count >= kMaximumSmallIconCount)
601 break;
602 visible_small_icon_count++;
603
604 notification_ids.erase(notification->id());
605 if (visible_small_icons_.count(notification->id()) != 0)
606 continue;
607
608 auto* item =
609 new WebNotificationImage(image.AsImageSkia(), kTrayItemInnerIconSize,
610 animation_container_.get(), this);
611 visible_small_icons_.insert(std::make_pair(notification->id(), item));
612
613 tray_container()->AddChildViewAt(item, 0);
614 item->SetVisible(true);
615 }
616
617 // Remove unnecessary icons.
618 for (const std::string& id : notification_ids) {
619 WebNotificationImage* item = visible_small_icons_[id];
620 visible_small_icons_.erase(id);
621 item->HideAndDelete();
622 }
623
624 // Show or hide the bell icon.
625 size_t visible_notification_count = message_center->NotificationCount();
626 bell_icon_->SetVisible(visible_notification_count == 0);
627
628 // Show or hide the counter.
629 size_t hidden_icon_count =
630 visible_notification_count - visible_small_icon_count;
631 if (hidden_icon_count != 0) {
632 counter_->SetVisible(true);
633 counter_->SetNotificationCount(
634 (visible_small_icon_count != 0), // small_icons_exist
635 hidden_icon_count);
636 } else {
637 counter_->SetVisible(false);
638 }
476 639
477 SetVisible(IsLoggedIn()); 640 SetVisible(IsLoggedIn());
641 PreferredSizeChanged();
478 Layout(); 642 Layout();
479 SchedulePaint(); 643 SchedulePaint();
480 if (IsLoggedIn()) 644 if (IsLoggedIn())
481 system_tray_->SetNextFocusableView(this); 645 system_tray_->SetNextFocusableView(this);
482 } 646 }
483 647
484 void WebNotificationTray::ClickedOutsideBubble() { 648 void WebNotificationTray::ClickedOutsideBubble() {
485 // Only hide the message center 649 // Only hide the message center
486 if (!message_center_bubble()) 650 if (!message_center_bubble())
487 return; 651 return;
(...skipping 20 matching lines...) Expand all
508 672
509 message_center::MessageCenterBubble* 673 message_center::MessageCenterBubble*
510 WebNotificationTray::GetMessageCenterBubbleForTest() { 674 WebNotificationTray::GetMessageCenterBubbleForTest() {
511 if (!message_center_bubble()) 675 if (!message_center_bubble())
512 return NULL; 676 return NULL;
513 return static_cast<message_center::MessageCenterBubble*>( 677 return static_cast<message_center::MessageCenterBubble*>(
514 message_center_bubble()->bubble()); 678 message_center_bubble()->bubble());
515 } 679 }
516 680
517 } // namespace ash 681 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/system/web_notification/web_notification_tray.h ('k') | ash/shelf/shelf_view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698