| OLD | NEW |
| (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/system/web_notification/web_notification_tray.h" | |
| 6 | |
| 7 #include "ash/common/ash_switches.h" | |
| 8 #include "ash/common/material_design/material_design_controller.h" | |
| 9 #include "ash/common/session/session_state_delegate.h" | |
| 10 #include "ash/common/shelf/shelf_constants.h" | |
| 11 #include "ash/common/shelf/wm_shelf.h" | |
| 12 #include "ash/common/shelf/wm_shelf_util.h" | |
| 13 #include "ash/common/shell_window_ids.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/wm_lookup.h" | |
| 19 #include "ash/common/wm_root_window_controller.h" | |
| 20 #include "ash/common/wm_shell.h" | |
| 21 #include "ash/common/wm_window.h" | |
| 22 #include "ash/system/status_area_widget.h" | |
| 23 #include "ash/system/tray/system_tray.h" | |
| 24 #include "ash/system/web_notification/ash_popup_alignment_delegate.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 "grit/ash_strings.h" | |
| 31 #include "ui/base/l10n/l10n_util.h" | |
| 32 #include "ui/display/display.h" | |
| 33 #include "ui/display/screen.h" | |
| 34 #include "ui/gfx/paint_vector_icon.h" | |
| 35 #include "ui/gfx/vector_icons_public.h" | |
| 36 #include "ui/message_center/message_center_style.h" | |
| 37 #include "ui/message_center/message_center_tray_delegate.h" | |
| 38 #include "ui/message_center/views/message_bubble_base.h" | |
| 39 #include "ui/message_center/views/message_center_bubble.h" | |
| 40 #include "ui/message_center/views/message_popup_collection.h" | |
| 41 #include "ui/strings/grit/ui_strings.h" | |
| 42 #include "ui/views/bubble/tray_bubble_view.h" | |
| 43 #include "ui/views/controls/button/custom_button.h" | |
| 44 #include "ui/views/controls/image_view.h" | |
| 45 #include "ui/views/controls/label.h" | |
| 46 #include "ui/views/controls/menu/menu_runner.h" | |
| 47 #include "ui/views/layout/fill_layout.h" | |
| 48 | |
| 49 #if defined(OS_CHROMEOS) | |
| 50 | |
| 51 namespace message_center { | |
| 52 | |
| 53 MessageCenterTrayDelegate* CreateMessageCenterTray() { | |
| 54 // On Windows+Ash the Tray will not be hosted in ash::Shell. | |
| 55 NOTREACHED(); | |
| 56 return NULL; | |
| 57 } | |
| 58 | |
| 59 } // namespace message_center | |
| 60 | |
| 61 #endif // defined(OS_CHROMEOS) | |
| 62 | |
| 63 namespace ash { | |
| 64 namespace { | |
| 65 | |
| 66 // Menu commands | |
| 67 const int kToggleQuietMode = 0; | |
| 68 const int kEnableQuietModeDay = 2; | |
| 69 } | |
| 70 | |
| 71 namespace { | |
| 72 | |
| 73 const SkColor kWebNotificationColorNoUnread = | |
| 74 SkColorSetARGB(128, 255, 255, 255); | |
| 75 const SkColor kWebNotificationColorWithUnread = SK_ColorWHITE; | |
| 76 const int kNoUnreadIconSize = 18; | |
| 77 } | |
| 78 | |
| 79 // Class to initialize and manage the WebNotificationBubble and | |
| 80 // TrayBubbleWrapper instances for a bubble. | |
| 81 class WebNotificationBubbleWrapper { | |
| 82 public: | |
| 83 // Takes ownership of |bubble| and creates |bubble_wrapper_|. | |
| 84 WebNotificationBubbleWrapper(WebNotificationTray* tray, | |
| 85 message_center::MessageBubbleBase* bubble) { | |
| 86 bubble_.reset(bubble); | |
| 87 views::TrayBubbleView::AnchorAlignment anchor_alignment = | |
| 88 tray->GetAnchorAlignment(); | |
| 89 views::TrayBubbleView::InitParams init_params = | |
| 90 bubble->GetInitParams(anchor_alignment); | |
| 91 views::View* anchor = tray->tray_container(); | |
| 92 if (anchor_alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM) { | |
| 93 gfx::Point bounds(anchor->width() / 2, 0); | |
| 94 views::View::ConvertPointToWidget(anchor, &bounds); | |
| 95 init_params.arrow_offset = bounds.x(); | |
| 96 } | |
| 97 DCHECK(anchor); | |
| 98 // TrayBubbleView uses |anchor| and |tray| to determine the parent | |
| 99 // container. See WebNotificationTray::OnBeforeBubbleWidgetInit(). | |
| 100 views::TrayBubbleView* bubble_view = | |
| 101 views::TrayBubbleView::Create(anchor, tray, &init_params); | |
| 102 bubble_wrapper_.reset(new TrayBubbleWrapper(tray, bubble_view)); | |
| 103 bubble_view->SetArrowPaintType(views::BubbleBorder::PAINT_NONE); | |
| 104 bubble->InitializeContents(bubble_view); | |
| 105 } | |
| 106 | |
| 107 message_center::MessageBubbleBase* bubble() const { return bubble_.get(); } | |
| 108 | |
| 109 // Convenience accessors. | |
| 110 views::TrayBubbleView* bubble_view() const { return bubble_->bubble_view(); } | |
| 111 | |
| 112 private: | |
| 113 std::unique_ptr<message_center::MessageBubbleBase> bubble_; | |
| 114 std::unique_ptr<TrayBubbleWrapper> bubble_wrapper_; | |
| 115 | |
| 116 DISALLOW_COPY_AND_ASSIGN(WebNotificationBubbleWrapper); | |
| 117 }; | |
| 118 | |
| 119 class WebNotificationButton : public views::CustomButton { | |
| 120 public: | |
| 121 WebNotificationButton(views::ButtonListener* listener) | |
| 122 : views::CustomButton(listener), | |
| 123 is_bubble_visible_(false), | |
| 124 unread_count_(0) { | |
| 125 SetLayoutManager(new views::FillLayout); | |
| 126 | |
| 127 gfx::ImageSkia image; | |
| 128 if (MaterialDesignController::IsShelfMaterial()) { | |
| 129 image = CreateVectorIcon(gfx::VectorIconId::SHELF_NOTIFICATIONS, | |
| 130 kShelfIconColor); | |
| 131 } else { | |
| 132 image = | |
| 133 CreateVectorIcon(gfx::VectorIconId::NOTIFICATIONS, kNoUnreadIconSize, | |
| 134 kWebNotificationColorNoUnread); | |
| 135 } | |
| 136 | |
| 137 no_unread_icon_.SetImage(image); | |
| 138 no_unread_icon_.set_owned_by_client(); | |
| 139 | |
| 140 unread_label_.set_owned_by_client(); | |
| 141 SetupLabelForTray(&unread_label_); | |
| 142 | |
| 143 AddChildView(&unread_label_); | |
| 144 } | |
| 145 | |
| 146 void SetBubbleVisible(bool visible) { | |
| 147 if (visible == is_bubble_visible_) | |
| 148 return; | |
| 149 | |
| 150 is_bubble_visible_ = visible; | |
| 151 UpdateIconVisibility(); | |
| 152 } | |
| 153 | |
| 154 void SetUnreadCount(int unread_count) { | |
| 155 // base::FormatNumber doesn't convert to arabic numeric characters. | |
| 156 // TODO(mukai): use ICU to support conversion for such locales. | |
| 157 unread_count_ = unread_count; | |
| 158 UpdateIconVisibility(); | |
| 159 } | |
| 160 | |
| 161 protected: | |
| 162 // Overridden from views::ImageButton: | |
| 163 gfx::Size GetPreferredSize() const override { | |
| 164 return gfx::Size(kShelfItemHeight, kShelfItemHeight); | |
| 165 } | |
| 166 | |
| 167 int GetHeightForWidth(int width) const override { | |
| 168 return GetPreferredSize().height(); | |
| 169 } | |
| 170 | |
| 171 private: | |
| 172 void UpdateIconVisibility() { | |
| 173 if (unread_count_ == 0) { | |
| 174 if (!Contains(&no_unread_icon_)) { | |
| 175 RemoveAllChildViews(false /* delete_children */); | |
| 176 AddChildView(&no_unread_icon_); | |
| 177 } | |
| 178 } else { | |
| 179 if (!Contains(&unread_label_)) { | |
| 180 RemoveAllChildViews(false /* delete_children */); | |
| 181 AddChildView(&unread_label_); | |
| 182 } | |
| 183 | |
| 184 // TODO(mukai): move NINE_PLUS message to ui_strings, it doesn't need to | |
| 185 // be in ash_strings. | |
| 186 unread_label_.SetText( | |
| 187 (unread_count_ > 9) ? l10n_util::GetStringUTF16( | |
| 188 IDS_ASH_NOTIFICATION_UNREAD_COUNT_NINE_PLUS) | |
| 189 : base::FormatNumber(unread_count_)); | |
| 190 unread_label_.SetEnabledColor((unread_count_ > 0) | |
| 191 ? kWebNotificationColorWithUnread | |
| 192 : kWebNotificationColorNoUnread); | |
| 193 } | |
| 194 SchedulePaint(); | |
| 195 } | |
| 196 | |
| 197 bool is_bubble_visible_; | |
| 198 int unread_count_; | |
| 199 | |
| 200 views::ImageView no_unread_icon_; | |
| 201 views::Label unread_label_; | |
| 202 | |
| 203 DISALLOW_COPY_AND_ASSIGN(WebNotificationButton); | |
| 204 }; | |
| 205 | |
| 206 WebNotificationTray::WebNotificationTray(StatusAreaWidget* status_area_widget) | |
| 207 : TrayBackgroundView(status_area_widget->wm_shelf()), | |
| 208 status_area_widget_(status_area_widget), | |
| 209 button_(NULL), | |
| 210 show_message_center_on_unlock_(false), | |
| 211 should_update_tray_content_(false), | |
| 212 should_block_shelf_auto_hide_(false) { | |
| 213 DCHECK(status_area_widget_); | |
| 214 button_ = new WebNotificationButton(this); | |
| 215 button_->set_triggerable_event_flags(ui::EF_LEFT_MOUSE_BUTTON | | |
| 216 ui::EF_RIGHT_MOUSE_BUTTON); | |
| 217 tray_container()->AddChildView(button_); | |
| 218 button_->SetFocusBehavior(FocusBehavior::NEVER); | |
| 219 SetContentsBackground(); | |
| 220 tray_container()->SetBorder(views::Border::NullBorder()); | |
| 221 message_center_tray_.reset(new message_center::MessageCenterTray( | |
| 222 this, message_center::MessageCenter::Get())); | |
| 223 WmShelf* shelf = WmLookup::Get() | |
| 224 ->GetWindowForWidget(status_area_widget) | |
| 225 ->GetRootWindowController() | |
| 226 ->GetShelf(); | |
| 227 popup_alignment_delegate_.reset(new AshPopupAlignmentDelegate(shelf)); | |
| 228 popup_collection_.reset(new message_center::MessagePopupCollection( | |
| 229 message_center(), message_center_tray_.get(), | |
| 230 popup_alignment_delegate_.get())); | |
| 231 const display::Display& display = WmLookup::Get() | |
| 232 ->GetWindowForWidget(status_area_widget) | |
| 233 ->GetDisplayNearestWindow(); | |
| 234 popup_alignment_delegate_->StartObserving(display::Screen::GetScreen(), | |
| 235 display); | |
| 236 OnMessageCenterTrayChanged(); | |
| 237 } | |
| 238 | |
| 239 WebNotificationTray::~WebNotificationTray() { | |
| 240 // Release any child views that might have back pointers before ~View(). | |
| 241 message_center_bubble_.reset(); | |
| 242 popup_alignment_delegate_.reset(); | |
| 243 popup_collection_.reset(); | |
| 244 } | |
| 245 | |
| 246 // Public methods. | |
| 247 | |
| 248 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) { | |
| 249 if (!ShouldShowMessageCenter()) | |
| 250 return false; | |
| 251 | |
| 252 should_block_shelf_auto_hide_ = true; | |
| 253 message_center::MessageCenterBubble* message_center_bubble = | |
| 254 new message_center::MessageCenterBubble(message_center(), | |
| 255 message_center_tray_.get(), true); | |
| 256 | |
| 257 int max_height; | |
| 258 if (IsHorizontalAlignment(shelf()->GetAlignment())) { | |
| 259 max_height = shelf()->GetIdealBounds().y(); | |
| 260 } else { | |
| 261 // Assume the status area and bubble bottoms are aligned when vertical. | |
| 262 WmWindow* status_area_window = | |
| 263 WmLookup::Get()->GetWindowForWidget(status_area_widget_); | |
| 264 gfx::Rect bounds_in_root = | |
| 265 status_area_window->GetRootWindow()->ConvertRectFromScreen( | |
| 266 status_area_window->GetBoundsInScreen()); | |
| 267 max_height = bounds_in_root.bottom(); | |
| 268 } | |
| 269 message_center_bubble->SetMaxHeight( | |
| 270 std::max(0, max_height - GetTrayConstant(TRAY_SPACING))); | |
| 271 if (show_settings) | |
| 272 message_center_bubble->SetSettingsVisible(); | |
| 273 message_center_bubble_.reset( | |
| 274 new WebNotificationBubbleWrapper(this, message_center_bubble)); | |
| 275 | |
| 276 status_area_widget_->SetHideSystemNotifications(true); | |
| 277 shelf()->UpdateAutoHideState(); | |
| 278 button_->SetBubbleVisible(true); | |
| 279 SetDrawBackgroundAsActive(true); | |
| 280 return true; | |
| 281 } | |
| 282 | |
| 283 bool WebNotificationTray::ShowMessageCenter() { | |
| 284 return ShowMessageCenterInternal(false /* show_settings */); | |
| 285 } | |
| 286 | |
| 287 void WebNotificationTray::HideMessageCenter() { | |
| 288 if (!message_center_bubble()) | |
| 289 return; | |
| 290 SetDrawBackgroundAsActive(false); | |
| 291 message_center_bubble_.reset(); | |
| 292 should_block_shelf_auto_hide_ = false; | |
| 293 show_message_center_on_unlock_ = false; | |
| 294 status_area_widget_->SetHideSystemNotifications(false); | |
| 295 shelf()->UpdateAutoHideState(); | |
| 296 button_->SetBubbleVisible(false); | |
| 297 } | |
| 298 | |
| 299 void WebNotificationTray::SetSystemTrayHeight(int height) { | |
| 300 popup_alignment_delegate_->SetSystemTrayHeight(height); | |
| 301 } | |
| 302 | |
| 303 int WebNotificationTray::system_tray_height_for_test() const { | |
| 304 return popup_alignment_delegate_->system_tray_height_for_test(); | |
| 305 } | |
| 306 | |
| 307 bool WebNotificationTray::ShowPopups() { | |
| 308 if (message_center_bubble()) | |
| 309 return false; | |
| 310 | |
| 311 popup_collection_->DoUpdateIfPossible(); | |
| 312 return true; | |
| 313 } | |
| 314 | |
| 315 void WebNotificationTray::HidePopups() { | |
| 316 DCHECK(popup_collection_.get()); | |
| 317 popup_collection_->MarkAllPopupsShown(); | |
| 318 } | |
| 319 | |
| 320 // Private methods. | |
| 321 | |
| 322 bool WebNotificationTray::ShouldShowMessageCenter() { | |
| 323 return !(status_area_widget_->system_tray() && | |
| 324 status_area_widget_->system_tray()->HasNotificationBubble()); | |
| 325 } | |
| 326 | |
| 327 bool WebNotificationTray::ShouldBlockShelfAutoHide() const { | |
| 328 return should_block_shelf_auto_hide_; | |
| 329 } | |
| 330 | |
| 331 bool WebNotificationTray::IsMessageCenterBubbleVisible() const { | |
| 332 return (message_center_bubble() && | |
| 333 message_center_bubble()->bubble()->IsVisible()); | |
| 334 } | |
| 335 | |
| 336 bool WebNotificationTray::IsMouseInNotificationBubble() const { | |
| 337 return false; | |
| 338 } | |
| 339 | |
| 340 void WebNotificationTray::ShowMessageCenterBubble() { | |
| 341 if (!IsMessageCenterBubbleVisible()) | |
| 342 message_center_tray_->ShowMessageCenterBubble(); | |
| 343 } | |
| 344 | |
| 345 void WebNotificationTray::UpdateAfterLoginStatusChange( | |
| 346 LoginStatus login_status) { | |
| 347 message_center()->SetLockedState(login_status == LoginStatus::LOCKED); | |
| 348 OnMessageCenterTrayChanged(); | |
| 349 } | |
| 350 | |
| 351 void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) { | |
| 352 if (alignment == shelf_alignment()) | |
| 353 return; | |
| 354 TrayBackgroundView::SetShelfAlignment(alignment); | |
| 355 tray_container()->SetBorder(views::Border::NullBorder()); | |
| 356 // Destroy any existing bubble so that it will be rebuilt correctly. | |
| 357 message_center_tray_->HideMessageCenterBubble(); | |
| 358 message_center_tray_->HidePopupBubble(); | |
| 359 } | |
| 360 | |
| 361 void WebNotificationTray::AnchorUpdated() { | |
| 362 if (message_center_bubble()) { | |
| 363 message_center_bubble()->bubble_view()->UpdateBubble(); | |
| 364 UpdateBubbleViewArrow(message_center_bubble()->bubble_view()); | |
| 365 } | |
| 366 } | |
| 367 | |
| 368 base::string16 WebNotificationTray::GetAccessibleNameForTray() { | |
| 369 return l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_ACCESSIBLE_NAME); | |
| 370 } | |
| 371 | |
| 372 void WebNotificationTray::HideBubbleWithView( | |
| 373 const views::TrayBubbleView* bubble_view) { | |
| 374 if (message_center_bubble() && | |
| 375 bubble_view == message_center_bubble()->bubble_view()) { | |
| 376 message_center_tray_->HideMessageCenterBubble(); | |
| 377 } else if (popup_collection_.get()) { | |
| 378 message_center_tray_->HidePopupBubble(); | |
| 379 } | |
| 380 } | |
| 381 | |
| 382 bool WebNotificationTray::PerformAction(const ui::Event& event) { | |
| 383 if (message_center_bubble()) | |
| 384 message_center_tray_->HideMessageCenterBubble(); | |
| 385 else | |
| 386 message_center_tray_->ShowMessageCenterBubble(); | |
| 387 return true; | |
| 388 } | |
| 389 | |
| 390 void WebNotificationTray::BubbleViewDestroyed() { | |
| 391 if (message_center_bubble()) | |
| 392 message_center_bubble()->bubble()->BubbleViewDestroyed(); | |
| 393 } | |
| 394 | |
| 395 void WebNotificationTray::OnMouseEnteredView() {} | |
| 396 | |
| 397 void WebNotificationTray::OnMouseExitedView() {} | |
| 398 | |
| 399 base::string16 WebNotificationTray::GetAccessibleNameForBubble() { | |
| 400 return GetAccessibleNameForTray(); | |
| 401 } | |
| 402 | |
| 403 gfx::Rect WebNotificationTray::GetAnchorRect( | |
| 404 views::Widget* anchor_widget, | |
| 405 views::TrayBubbleView::AnchorType anchor_type, | |
| 406 views::TrayBubbleView::AnchorAlignment anchor_alignment) const { | |
| 407 return GetBubbleAnchorRect(anchor_widget, anchor_type, anchor_alignment); | |
| 408 } | |
| 409 | |
| 410 void WebNotificationTray::OnBeforeBubbleWidgetInit( | |
| 411 views::Widget* anchor_widget, | |
| 412 views::Widget* bubble_widget, | |
| 413 views::Widget::InitParams* params) const { | |
| 414 // Place the bubble in the same root window as |anchor_widget|. | |
| 415 WmLookup::Get() | |
| 416 ->GetWindowForWidget(anchor_widget) | |
| 417 ->GetRootWindowController() | |
| 418 ->ConfigureWidgetInitParamsForContainer( | |
| 419 bubble_widget, kShellWindowId_SettingBubbleContainer, params); | |
| 420 } | |
| 421 | |
| 422 void WebNotificationTray::HideBubble(const views::TrayBubbleView* bubble_view) { | |
| 423 HideBubbleWithView(bubble_view); | |
| 424 } | |
| 425 | |
| 426 bool WebNotificationTray::ShowNotifierSettings() { | |
| 427 if (message_center_bubble()) { | |
| 428 static_cast<message_center::MessageCenterBubble*>( | |
| 429 message_center_bubble()->bubble()) | |
| 430 ->SetSettingsVisible(); | |
| 431 return true; | |
| 432 } | |
| 433 return ShowMessageCenterInternal(true /* show_settings */); | |
| 434 } | |
| 435 | |
| 436 bool WebNotificationTray::IsContextMenuEnabled() const { | |
| 437 return IsLoggedIn(); | |
| 438 } | |
| 439 | |
| 440 message_center::MessageCenterTray* WebNotificationTray::GetMessageCenterTray() { | |
| 441 return message_center_tray_.get(); | |
| 442 } | |
| 443 | |
| 444 bool WebNotificationTray::IsCommandIdChecked(int command_id) const { | |
| 445 if (command_id != kToggleQuietMode) | |
| 446 return false; | |
| 447 return message_center()->IsQuietMode(); | |
| 448 } | |
| 449 | |
| 450 bool WebNotificationTray::IsCommandIdEnabled(int command_id) const { | |
| 451 return true; | |
| 452 } | |
| 453 | |
| 454 bool WebNotificationTray::GetAcceleratorForCommandId( | |
| 455 int command_id, | |
| 456 ui::Accelerator* accelerator) { | |
| 457 return false; | |
| 458 } | |
| 459 | |
| 460 void WebNotificationTray::ExecuteCommand(int command_id, int event_flags) { | |
| 461 if (command_id == kToggleQuietMode) { | |
| 462 bool in_quiet_mode = message_center()->IsQuietMode(); | |
| 463 message_center()->SetQuietMode(!in_quiet_mode); | |
| 464 return; | |
| 465 } | |
| 466 base::TimeDelta expires_in = command_id == kEnableQuietModeDay | |
| 467 ? base::TimeDelta::FromDays(1) | |
| 468 : base::TimeDelta::FromHours(1); | |
| 469 message_center()->EnterQuietModeWithExpire(expires_in); | |
| 470 } | |
| 471 | |
| 472 void WebNotificationTray::ButtonPressed(views::Button* sender, | |
| 473 const ui::Event& event) { | |
| 474 DCHECK_EQ(button_, sender); | |
| 475 PerformAction(event); | |
| 476 } | |
| 477 | |
| 478 void WebNotificationTray::OnMessageCenterTrayChanged() { | |
| 479 // Do not update the tray contents directly. Multiple change events can happen | |
| 480 // consecutively, and calling Update in the middle of those events will show | |
| 481 // intermediate unread counts for a moment. | |
| 482 should_update_tray_content_ = true; | |
| 483 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 484 FROM_HERE, | |
| 485 base::Bind(&WebNotificationTray::UpdateTrayContent, AsWeakPtr())); | |
| 486 } | |
| 487 | |
| 488 void WebNotificationTray::UpdateTrayContent() { | |
| 489 if (!should_update_tray_content_) | |
| 490 return; | |
| 491 should_update_tray_content_ = false; | |
| 492 | |
| 493 message_center::MessageCenter* message_center = | |
| 494 message_center_tray_->message_center(); | |
| 495 button_->SetUnreadCount(message_center->UnreadNotificationCount()); | |
| 496 if (IsMessageCenterBubbleVisible()) | |
| 497 button_->SetState(views::CustomButton::STATE_PRESSED); | |
| 498 else | |
| 499 button_->SetState(views::CustomButton::STATE_NORMAL); | |
| 500 | |
| 501 SetVisible(IsLoggedIn()); | |
| 502 Layout(); | |
| 503 SchedulePaint(); | |
| 504 if (IsLoggedIn()) | |
| 505 status_area_widget_->system_tray()->SetNextFocusableView(this); | |
| 506 } | |
| 507 | |
| 508 void WebNotificationTray::ClickedOutsideBubble() { | |
| 509 // Only hide the message center | |
| 510 if (!message_center_bubble()) | |
| 511 return; | |
| 512 | |
| 513 message_center_tray_->HideMessageCenterBubble(); | |
| 514 } | |
| 515 | |
| 516 message_center::MessageCenter* WebNotificationTray::message_center() const { | |
| 517 return message_center_tray_->message_center(); | |
| 518 } | |
| 519 | |
| 520 bool WebNotificationTray::IsLoggedIn() const { | |
| 521 WmShell* shell = WmShell::Get(); | |
| 522 // TODO(jamescook): Should this also check LoginState::LOCKED? | |
| 523 return shell->system_tray_delegate()->GetUserLoginStatus() != | |
| 524 LoginStatus::NOT_LOGGED_IN && | |
| 525 !shell->GetSessionStateDelegate()->IsInSecondaryLoginScreen(); | |
| 526 } | |
| 527 | |
| 528 // Methods for testing | |
| 529 | |
| 530 bool WebNotificationTray::IsPopupVisible() const { | |
| 531 return message_center_tray_->popups_visible(); | |
| 532 } | |
| 533 | |
| 534 message_center::MessageCenterBubble* | |
| 535 WebNotificationTray::GetMessageCenterBubbleForTest() { | |
| 536 if (!message_center_bubble()) | |
| 537 return NULL; | |
| 538 return static_cast<message_center::MessageCenterBubble*>( | |
| 539 message_center_bubble()->bubble()); | |
| 540 } | |
| 541 | |
| 542 } // namespace ash | |
| OLD | NEW |