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

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

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 years, 9 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
« no previous file with comments | « ash/common/system/web_notification/web_notification_tray.h ('k') | ash/common/test/ash_test.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ash/common/system/web_notification/web_notification_tray.h"
6
7 #include "ash/common/material_design/material_design_controller.h"
8 #include "ash/common/session/session_state_delegate.h"
9 #include "ash/common/shelf/shelf_constants.h"
10 #include "ash/common/shelf/wm_shelf.h"
11 #include "ash/common/shelf/wm_shelf_util.h"
12 #include "ash/common/system/status_area_widget.h"
13 #include "ash/common/system/tray/system_tray.h"
14 #include "ash/common/system/tray/system_tray_delegate.h"
15 #include "ash/common/system/tray/tray_bubble_wrapper.h"
16 #include "ash/common/system/tray/tray_constants.h"
17 #include "ash/common/system/tray/tray_utils.h"
18 #include "ash/common/system/web_notification/ash_popup_alignment_delegate.h"
19 #include "ash/common/wm_shell.h"
20 #include "ash/common/wm_window.h"
21 #include "ash/public/cpp/shell_window_ids.h"
22 #include "ash/resources/vector_icons/vector_icons.h"
23 #include "ash/root_window_controller.h"
24 #include "ash/strings/grit/ash_strings.h"
25 #include "base/auto_reset.h"
26 #include "base/i18n/number_formatting.h"
27 #include "base/i18n/rtl.h"
28 #include "base/strings/utf_string_conversions.h"
29 #include "base/threading/thread_task_runner_handle.h"
30 #include "ui/base/l10n/l10n_util.h"
31 #include "ui/display/display.h"
32 #include "ui/display/screen.h"
33 #include "ui/gfx/paint_vector_icon.h"
34 #include "ui/gfx/vector_icons_public.h"
35 #include "ui/message_center/message_center_style.h"
36 #include "ui/message_center/message_center_tray_delegate.h"
37 #include "ui/message_center/views/message_bubble_base.h"
38 #include "ui/message_center/views/message_center_bubble.h"
39 #include "ui/message_center/views/message_popup_collection.h"
40 #include "ui/strings/grit/ui_strings.h"
41 #include "ui/views/bubble/tray_bubble_view.h"
42 #include "ui/views/controls/image_view.h"
43 #include "ui/views/controls/label.h"
44 #include "ui/views/controls/menu/menu_runner.h"
45 #include "ui/views/layout/fill_layout.h"
46
47 namespace message_center {
48
49 MessageCenterTrayDelegate* CreateMessageCenterTray() {
50 // On non-CrOS, the Tray will not be hosted in ash::Shell.
51 NOTREACHED();
52 return nullptr;
53 }
54
55 } // namespace message_center
56
57 namespace ash {
58 namespace {
59
60 // Menu commands
61 constexpr int kToggleQuietMode = 0;
62 constexpr int kEnableQuietModeDay = 2;
63
64 constexpr int kMaximumSmallIconCount = 3;
65
66 constexpr gfx::Size kTrayItemInnerIconSize(16, 16);
67 constexpr gfx::Size kTrayItemInnerBellIconSizeNonMd(18, 18);
68 constexpr gfx::Size kTrayItemOuterSize(26, 26);
69 constexpr int kTrayMainAxisInset = 3;
70 constexpr int kTrayCrossAxisInset = 0;
71
72 constexpr int kTrayItemAnimationDurationMS = 200;
73
74 constexpr size_t kMaximumNotificationNumber = 99;
75
76 // Flag to disable animation. Only for testing.
77 bool disable_animations_for_test = false;
78 }
79
80 namespace {
81
82 const SkColor kWebNotificationColorNoUnread =
83 SkColorSetARGB(128, 255, 255, 255);
84 const SkColor kWebNotificationColorWithUnread = SK_ColorWHITE;
85 const int kNoUnreadIconSize = 18;
86
87 } // namespace
88
89 // Class to initialize and manage the WebNotificationBubble and
90 // TrayBubbleWrapper instances for a bubble.
91 class WebNotificationBubbleWrapper {
92 public:
93 // Takes ownership of |bubble| and creates |bubble_wrapper_|.
94 WebNotificationBubbleWrapper(WebNotificationTray* tray,
95 TrayBackgroundView* anchor_tray,
96 message_center::MessageBubbleBase* bubble) {
97 bubble_.reset(bubble);
98 views::TrayBubbleView::AnchorAlignment anchor_alignment =
99 tray->GetAnchorAlignment();
100 views::TrayBubbleView::InitParams init_params =
101 bubble->GetInitParams(anchor_alignment);
102 views::TrayBubbleView* bubble_view = views::TrayBubbleView::Create(
103 anchor_tray->GetBubbleAnchor(), tray, &init_params);
104 bubble_view->set_anchor_view_insets(anchor_tray->GetBubbleAnchorInsets());
105 bubble_wrapper_.reset(new TrayBubbleWrapper(tray, bubble_view));
106 bubble->InitializeContents(bubble_view);
107 }
108
109 message_center::MessageBubbleBase* bubble() const { return bubble_.get(); }
110
111 // Convenience accessors.
112 views::TrayBubbleView* bubble_view() const { return bubble_->bubble_view(); }
113
114 private:
115 std::unique_ptr<message_center::MessageBubbleBase> bubble_;
116 std::unique_ptr<TrayBubbleWrapper> bubble_wrapper_;
117
118 DISALLOW_COPY_AND_ASSIGN(WebNotificationBubbleWrapper);
119 };
120
121 class WebNotificationItem : public views::View, public gfx::AnimationDelegate {
122 public:
123 WebNotificationItem(gfx::AnimationContainer* container,
124 WebNotificationTray* tray)
125 : tray_(tray) {
126 SetPaintToLayer();
127 layer()->SetFillsBoundsOpaquely(false);
128 views::View::SetVisible(false);
129 set_owned_by_client();
130
131 SetLayoutManager(new views::FillLayout);
132
133 animation_.reset(new gfx::SlideAnimation(this));
134 animation_->SetContainer(container);
135 animation_->SetSlideDuration(kTrayItemAnimationDurationMS);
136 animation_->SetTweenType(gfx::Tween::LINEAR);
137 }
138
139 void SetVisible(bool set_visible) override {
140 if (!GetWidget() || disable_animations_for_test) {
141 views::View::SetVisible(set_visible);
142 return;
143 }
144
145 if (!set_visible) {
146 animation_->Hide();
147 AnimationProgressed(animation_.get());
148 } else {
149 animation_->Show();
150 AnimationProgressed(animation_.get());
151 views::View::SetVisible(true);
152 }
153 }
154
155 void HideAndDelete() {
156 SetVisible(false);
157
158 if (!visible() && !animation_->is_animating()) {
159 if (parent())
160 parent()->RemoveChildView(this);
161 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
162 } else {
163 delete_after_animation_ = true;
164 }
165 }
166
167 protected:
168 // Overridden from views::View:
169 gfx::Size GetPreferredSize() const override {
170 if (!animation_.get() || !animation_->is_animating())
171 return kTrayItemOuterSize;
172
173 // Animate the width (or height) when this item shows (or hides) so that
174 // the icons on the left are shifted with the animation.
175 // Note that TrayItemView does the same thing.
176 gfx::Size size = kTrayItemOuterSize;
177 if (IsHorizontalLayout()) {
178 size.set_width(std::max(
179 1, gfx::ToRoundedInt(size.width() * animation_->GetCurrentValue())));
180 } else {
181 size.set_height(std::max(
182 1, gfx::ToRoundedInt(size.height() * animation_->GetCurrentValue())));
183 }
184 return size;
185 }
186
187 int GetHeightForWidth(int width) const override {
188 return GetPreferredSize().height();
189 }
190
191 bool IsHorizontalLayout() const {
192 return IsHorizontalAlignment(tray_->shelf_alignment());
193 }
194
195 private:
196 // gfx::AnimationDelegate:
197 void AnimationProgressed(const gfx::Animation* animation) override {
198 gfx::Transform transform;
199 if (IsHorizontalLayout()) {
200 transform.Translate(0, animation->CurrentValueBetween(
201 static_cast<double>(height()) / 2., 0.));
202 } else {
203 transform.Translate(
204 animation->CurrentValueBetween(static_cast<double>(width() / 2.), 0.),
205 0);
206 }
207 transform.Scale(animation->GetCurrentValue(), animation->GetCurrentValue());
208 layer()->SetTransform(transform);
209 PreferredSizeChanged();
210 }
211 void AnimationEnded(const gfx::Animation* animation) override {
212 if (animation->GetCurrentValue() < 0.1)
213 views::View::SetVisible(false);
214
215 if (delete_after_animation_) {
216 if (parent())
217 parent()->RemoveChildView(this);
218 base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
219 }
220 }
221 void AnimationCanceled(const gfx::Animation* animation) override {
222 AnimationEnded(animation);
223 }
224
225 std::unique_ptr<gfx::SlideAnimation> animation_;
226 bool delete_after_animation_ = false;
227 WebNotificationTray* tray_;
228
229 DISALLOW_COPY_AND_ASSIGN(WebNotificationItem);
230 };
231
232 class WebNotificationImage : public WebNotificationItem {
233 public:
234 WebNotificationImage(const gfx::ImageSkia& image,
235 const gfx::Size& size,
236 gfx::AnimationContainer* container,
237 WebNotificationTray* tray)
238 : WebNotificationItem(container, tray) {
239 view_ = new views::ImageView();
240 view_->SetImage(image);
241 view_->SetImageSize(size);
242 AddChildView(view_);
243 }
244
245 private:
246 views::ImageView* view_;
247
248 DISALLOW_COPY_AND_ASSIGN(WebNotificationImage);
249 };
250
251 class WebNotificationLabel : public WebNotificationItem {
252 public:
253 WebNotificationLabel(gfx::AnimationContainer* container,
254 WebNotificationTray* tray)
255 : WebNotificationItem(container, tray) {
256 view_ = new views::Label();
257 SetupLabelForTray(view_);
258 AddChildView(view_);
259 }
260
261 void SetNotificationCount(bool small_icons_exist, size_t notification_count) {
262 notification_count = std::min(notification_count,
263 kMaximumNotificationNumber); // cap with 99
264
265 // TODO(yoshiki): Use a string for "99" and "+99".
266
267 base::string16 str = base::FormatNumber(notification_count);
268 if (small_icons_exist) {
269 if (!base::i18n::IsRTL())
270 str = base::ASCIIToUTF16("+") + str;
271 else
272 str = str + base::ASCIIToUTF16("+");
273 }
274
275 view_->SetText(str);
276 view_->SetEnabledColor(kWebNotificationColorWithUnread);
277 SchedulePaint();
278 }
279
280 private:
281 views::Label* view_;
282
283 DISALLOW_COPY_AND_ASSIGN(WebNotificationLabel);
284 };
285
286 WebNotificationTray::WebNotificationTray(WmShelf* shelf,
287 WmWindow* status_area_window,
288 SystemTray* system_tray)
289 : TrayBackgroundView(shelf),
290 status_area_window_(status_area_window),
291 system_tray_(system_tray),
292 show_message_center_on_unlock_(false),
293 should_update_tray_content_(false),
294 should_block_shelf_auto_hide_(false) {
295 DCHECK(shelf);
296 DCHECK(status_area_window_);
297 DCHECK(system_tray_);
298
299 if (MaterialDesignController::IsShelfMaterial()) {
300 SetInkDropMode(InkDropMode::ON);
301 SetContentsBackground(false);
302 gfx::ImageSkia bell_image =
303 CreateVectorIcon(kShelfNotificationsIcon, kShelfIconColor);
304 const gfx::Size bell_icon_size = kTrayItemInnerIconSize;
305 bell_icon_.reset(new WebNotificationImage(
306 bell_image, bell_icon_size, animation_container_.get(), this));
307 } else {
308 SetContentsBackground(true);
309 gfx::ImageSkia bell_image =
310 CreateVectorIcon(gfx::VectorIconId::NOTIFICATIONS, kNoUnreadIconSize,
311 kWebNotificationColorNoUnread);
312 const gfx::Size bell_icon_size = kTrayItemInnerBellIconSizeNonMd;
313 bell_icon_.reset(new WebNotificationImage(
314 bell_image, bell_icon_size, animation_container_.get(), this));
315 }
316 tray_container()->AddChildView(bell_icon_.get());
317
318 counter_.reset(new WebNotificationLabel(animation_container_.get(), this));
319 tray_container()->AddChildView(counter_.get());
320
321 message_center_tray_.reset(new message_center::MessageCenterTray(
322 this, message_center::MessageCenter::Get()));
323 popup_alignment_delegate_.reset(new AshPopupAlignmentDelegate(shelf));
324 popup_collection_.reset(new message_center::MessagePopupCollection(
325 message_center(), message_center_tray_.get(),
326 popup_alignment_delegate_.get()));
327 const display::Display& display =
328 status_area_window_->GetDisplayNearestWindow();
329 popup_alignment_delegate_->StartObserving(display::Screen::GetScreen(),
330 display);
331 OnMessageCenterTrayChanged();
332
333 tray_container()->SetMargin(kTrayMainAxisInset, kTrayCrossAxisInset);
334 }
335
336 WebNotificationTray::~WebNotificationTray() {
337 // Release any child views that might have back pointers before ~View().
338 message_center_bubble_.reset();
339 popup_alignment_delegate_.reset();
340 popup_collection_.reset();
341 }
342
343 // static
344 void WebNotificationTray::DisableAnimationsForTest(bool disable) {
345 disable_animations_for_test = disable;
346 }
347
348 // Public methods.
349
350 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) {
351 if (!ShouldShowMessageCenter())
352 return false;
353
354 should_block_shelf_auto_hide_ = true;
355 message_center::MessageCenterBubble* message_center_bubble =
356 new message_center::MessageCenterBubble(message_center(),
357 message_center_tray_.get());
358
359 // In the horizontal case, message center starts from the top of the shelf.
360 // In the vertical case, it starts from the bottom of WebNotificationTray.
361 const int max_height = IsHorizontalAlignment(shelf_alignment())
362 ? shelf()->GetIdealBounds().y()
363 : GetBoundsInScreen().bottom();
364 message_center_bubble->SetMaxHeight(max_height);
365
366 if (show_settings)
367 message_center_bubble->SetSettingsVisible();
368
369 // For vertical shelf alignments, anchor to the WebNotificationTray, but for
370 // horizontal (i.e. bottom) shelves, anchor to the system tray.
371 TrayBackgroundView* anchor_tray = this;
372 if (IsHorizontalAlignment(shelf_alignment())) {
373 anchor_tray = WmShelf::ForWindow(status_area_window_)
374 ->GetStatusAreaWidget()
375 ->system_tray();
376 }
377
378 message_center_bubble_.reset(new WebNotificationBubbleWrapper(
379 this, anchor_tray, message_center_bubble));
380
381 shelf()->UpdateAutoHideState();
382 SetIsActive(true);
383 return true;
384 }
385
386 bool WebNotificationTray::ShowMessageCenter() {
387 return ShowMessageCenterInternal(false /* show_settings */);
388 }
389
390 void WebNotificationTray::HideMessageCenter() {
391 if (!message_center_bubble())
392 return;
393 SetIsActive(false);
394 message_center_bubble_.reset();
395 should_block_shelf_auto_hide_ = false;
396 show_message_center_on_unlock_ = false;
397 shelf()->UpdateAutoHideState();
398 }
399
400 void WebNotificationTray::SetTrayBubbleHeight(int height) {
401 popup_alignment_delegate_->SetTrayBubbleHeight(height);
402 }
403
404 int WebNotificationTray::tray_bubble_height_for_test() const {
405 return popup_alignment_delegate_->tray_bubble_height_for_test();
406 }
407
408 bool WebNotificationTray::ShowPopups() {
409 if (message_center_bubble())
410 return false;
411
412 popup_collection_->DoUpdateIfPossible();
413 return true;
414 }
415
416 void WebNotificationTray::HidePopups() {
417 DCHECK(popup_collection_.get());
418 popup_collection_->MarkAllPopupsShown();
419 }
420
421 // Private methods.
422
423 bool WebNotificationTray::ShouldShowMessageCenter() {
424 return WmShell::Get()->system_tray_delegate()->ShouldShowNotificationTray();
425 }
426
427 bool WebNotificationTray::ShouldBlockShelfAutoHide() const {
428 return should_block_shelf_auto_hide_;
429 }
430
431 bool WebNotificationTray::IsMessageCenterBubbleVisible() const {
432 return (message_center_bubble() &&
433 message_center_bubble()->bubble()->IsVisible());
434 }
435
436 void WebNotificationTray::ShowMessageCenterBubble() {
437 if (!IsMessageCenterBubbleVisible())
438 message_center_tray_->ShowMessageCenterBubble();
439 }
440
441 void WebNotificationTray::UpdateAfterLoginStatusChange(
442 LoginStatus login_status) {
443 message_center()->SetLockedState(login_status == LoginStatus::LOCKED);
444 OnMessageCenterTrayChanged();
445 }
446
447 void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) {
448 if (alignment == shelf_alignment())
449 return;
450 TrayBackgroundView::SetShelfAlignment(alignment);
451 // Destroy any existing bubble so that it will be rebuilt correctly.
452 message_center_tray_->HideMessageCenterBubble();
453 message_center_tray_->HidePopupBubble();
454 }
455
456 void WebNotificationTray::AnchorUpdated() {
457 if (message_center_bubble()) {
458 message_center_bubble()->bubble_view()->UpdateBubble();
459 UpdateBubbleViewArrow(message_center_bubble()->bubble_view());
460 }
461 }
462
463 base::string16 WebNotificationTray::GetAccessibleNameForTray() {
464 return l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_ACCESSIBLE_NAME);
465 }
466
467 void WebNotificationTray::HideBubbleWithView(
468 const views::TrayBubbleView* bubble_view) {
469 if (message_center_bubble() &&
470 bubble_view == message_center_bubble()->bubble_view()) {
471 message_center_tray_->HideMessageCenterBubble();
472 } else if (popup_collection_.get()) {
473 message_center_tray_->HidePopupBubble();
474 }
475 }
476
477 bool WebNotificationTray::PerformAction(const ui::Event& event) {
478 if (message_center_bubble())
479 message_center_tray_->HideMessageCenterBubble();
480 else
481 message_center_tray_->ShowMessageCenterBubble();
482 return true;
483 }
484
485 void WebNotificationTray::BubbleViewDestroyed() {
486 if (message_center_bubble())
487 message_center_bubble()->bubble()->BubbleViewDestroyed();
488 }
489
490 void WebNotificationTray::OnMouseEnteredView() {}
491
492 void WebNotificationTray::OnMouseExitedView() {}
493
494 base::string16 WebNotificationTray::GetAccessibleNameForBubble() {
495 return GetAccessibleNameForTray();
496 }
497
498 void WebNotificationTray::OnBeforeBubbleWidgetInit(
499 views::Widget* anchor_widget,
500 views::Widget* bubble_widget,
501 views::Widget::InitParams* params) const {
502 // Place the bubble in the same root window as |anchor_widget|.
503 WmWindow::Get(anchor_widget->GetNativeWindow())
504 ->GetRootWindowController()
505 ->ConfigureWidgetInitParamsForContainer(
506 bubble_widget, kShellWindowId_SettingBubbleContainer, params);
507 }
508
509 void WebNotificationTray::HideBubble(const views::TrayBubbleView* bubble_view) {
510 HideBubbleWithView(bubble_view);
511 }
512
513 bool WebNotificationTray::ShowNotifierSettings() {
514 if (message_center_bubble()) {
515 static_cast<message_center::MessageCenterBubble*>(
516 message_center_bubble()->bubble())
517 ->SetSettingsVisible();
518 return true;
519 }
520 return ShowMessageCenterInternal(true /* show_settings */);
521 }
522
523 bool WebNotificationTray::IsContextMenuEnabled() const {
524 return IsLoggedIn();
525 }
526
527 message_center::MessageCenterTray* WebNotificationTray::GetMessageCenterTray() {
528 return message_center_tray_.get();
529 }
530
531 bool WebNotificationTray::IsCommandIdChecked(int command_id) const {
532 if (command_id != kToggleQuietMode)
533 return false;
534 return message_center()->IsQuietMode();
535 }
536
537 bool WebNotificationTray::IsCommandIdEnabled(int command_id) const {
538 return true;
539 }
540
541 void WebNotificationTray::ExecuteCommand(int command_id, int event_flags) {
542 if (command_id == kToggleQuietMode) {
543 bool in_quiet_mode = message_center()->IsQuietMode();
544 message_center()->SetQuietMode(!in_quiet_mode);
545 return;
546 }
547 base::TimeDelta expires_in = command_id == kEnableQuietModeDay
548 ? base::TimeDelta::FromDays(1)
549 : base::TimeDelta::FromHours(1);
550 message_center()->EnterQuietModeWithExpire(expires_in);
551 }
552
553 void WebNotificationTray::OnMessageCenterTrayChanged() {
554 // Do not update the tray contents directly. Multiple change events can happen
555 // consecutively, and calling Update in the middle of those events will show
556 // intermediate unread counts for a moment.
557 should_update_tray_content_ = true;
558 base::ThreadTaskRunnerHandle::Get()->PostTask(
559 FROM_HERE,
560 base::Bind(&WebNotificationTray::UpdateTrayContent, AsWeakPtr()));
561 }
562
563 void WebNotificationTray::UpdateTrayContent() {
564 if (!should_update_tray_content_)
565 return;
566 should_update_tray_content_ = false;
567
568 std::unordered_set<std::string> notification_ids;
569 for (auto pair : visible_small_icons_)
570 notification_ids.insert(pair.first);
571
572 // Add small icons (up to kMaximumSmallIconCount = 3).
573 message_center::MessageCenter* message_center =
574 message_center_tray_->message_center();
575 size_t visible_small_icon_count = 0;
576 for (const auto* notification : message_center->GetVisibleNotifications()) {
577 gfx::Image image = notification->small_image();
578 if (image.IsEmpty())
579 continue;
580
581 if (visible_small_icon_count >= kMaximumSmallIconCount)
582 break;
583 visible_small_icon_count++;
584
585 notification_ids.erase(notification->id());
586 if (visible_small_icons_.count(notification->id()) != 0)
587 continue;
588
589 auto* item =
590 new WebNotificationImage(image.AsImageSkia(), kTrayItemInnerIconSize,
591 animation_container_.get(), this);
592 visible_small_icons_.insert(std::make_pair(notification->id(), item));
593
594 tray_container()->AddChildViewAt(item, 0);
595 item->SetVisible(true);
596 }
597
598 // Remove unnecessary icons.
599 for (const std::string& id : notification_ids) {
600 WebNotificationImage* item = visible_small_icons_[id];
601 visible_small_icons_.erase(id);
602 item->HideAndDelete();
603 }
604
605 // Show or hide the bell icon.
606 size_t visible_notification_count = message_center->NotificationCount();
607 bell_icon_->SetVisible(visible_notification_count == 0);
608
609 // Show or hide the counter.
610 size_t hidden_icon_count =
611 visible_notification_count - visible_small_icon_count;
612 if (hidden_icon_count != 0) {
613 counter_->SetVisible(true);
614 counter_->SetNotificationCount(
615 (visible_small_icon_count != 0), // small_icons_exist
616 hidden_icon_count);
617 } else {
618 counter_->SetVisible(false);
619 }
620
621 SetVisible(IsLoggedIn() && ShouldShowMessageCenter());
622 PreferredSizeChanged();
623 Layout();
624 SchedulePaint();
625 if (IsLoggedIn())
626 system_tray_->SetNextFocusableView(this);
627 }
628
629 void WebNotificationTray::ClickedOutsideBubble() {
630 // Only hide the message center
631 if (!message_center_bubble())
632 return;
633
634 message_center_tray_->HideMessageCenterBubble();
635 }
636
637 message_center::MessageCenter* WebNotificationTray::message_center() const {
638 return message_center_tray_->message_center();
639 }
640
641 bool WebNotificationTray::IsLoggedIn() const {
642 WmShell* shell = WmShell::Get();
643 return shell->system_tray_delegate()->GetUserLoginStatus() !=
644 LoginStatus::NOT_LOGGED_IN &&
645 !shell->GetSessionStateDelegate()->IsInSecondaryLoginScreen();
646 }
647
648 // Methods for testing
649
650 bool WebNotificationTray::IsPopupVisible() const {
651 return message_center_tray_->popups_visible();
652 }
653
654 message_center::MessageCenterBubble*
655 WebNotificationTray::GetMessageCenterBubbleForTest() {
656 if (!message_center_bubble())
657 return nullptr;
658 return static_cast<message_center::MessageCenterBubble*>(
659 message_center_bubble()->bubble());
660 }
661
662 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/system/web_notification/web_notification_tray.h ('k') | ash/common/test/ash_test.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698