blob: 3fd67d1474dd284d53c3ba905c2cd474b3a5a6b0 [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/message_center/ui_controller.h"
#include <memory>
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_types.h"
#include "ui/message_center/notification_blocker.h"
#include "ui/message_center/ui_delegate.h"
#include "ui/message_center/views/notification_menu_model.h"
#include "ui/strings/grit/ui_strings.h"
namespace message_center {
UiController::UiController(UiDelegate* delegate)
: message_center_(MessageCenter::Get()),
message_center_visible_(false),
popups_visible_(false),
delegate_(delegate) {
message_center_->AddObserver(this);
}
UiController::~UiController() {
message_center_->RemoveObserver(this);
}
bool UiController::ShowMessageCenterBubble(bool show_by_click) {
if (message_center_visible_)
return true;
HidePopupBubbleInternal();
message_center_visible_ = delegate_->ShowMessageCenter(show_by_click);
if (message_center_visible_) {
message_center_->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
NotifyUiControllerChanged();
}
return message_center_visible_;
}
bool UiController::HideMessageCenterBubble() {
#if defined(OS_CHROMEOS)
// TODO(yoshiki): Move the message center bubble related logic to ash/.
hide_empty_message_center_callback_.reset();
#endif
if (!message_center_visible_)
return false;
delegate_->HideMessageCenter();
MarkMessageCenterHidden();
return true;
}
void UiController::MarkMessageCenterHidden() {
if (!message_center_visible_)
return;
message_center_visible_ = false;
message_center_->SetVisibility(message_center::VISIBILITY_TRANSIENT);
// Some notifications (like system ones) should appear as popups again
// after the message center is closed.
if (message_center_->HasPopupNotifications()) {
ShowPopupBubble();
return;
}
NotifyUiControllerChanged();
}
void UiController::ShowPopupBubble() {
if (message_center_visible_)
return;
if (popups_visible_) {
NotifyUiControllerChanged();
return;
}
if (!message_center_->HasPopupNotifications())
return;
popups_visible_ = delegate_->ShowPopups();
NotifyUiControllerChanged();
}
bool UiController::HidePopupBubble() {
if (!popups_visible_)
return false;
HidePopupBubbleInternal();
NotifyUiControllerChanged();
return true;
}
void UiController::HidePopupBubbleInternal() {
if (!popups_visible_)
return;
delegate_->HidePopups();
popups_visible_ = false;
}
void UiController::ShowNotifierSettingsBubble() {
if (popups_visible_)
HidePopupBubbleInternal();
message_center_visible_ = delegate_->ShowNotifierSettings();
message_center_->SetVisibility(message_center::VISIBILITY_SETTINGS);
NotifyUiControllerChanged();
}
void UiController::OnNotificationAdded(const std::string& notification_id) {
OnMessageCenterChanged();
}
void UiController::OnNotificationRemoved(const std::string& notification_id,
bool by_user) {
OnMessageCenterChanged();
}
void UiController::OnNotificationUpdated(const std::string& notification_id) {
OnMessageCenterChanged();
}
void UiController::OnNotificationClicked(const std::string& notification_id) {
if (popups_visible_)
OnMessageCenterChanged();
}
void UiController::OnNotificationButtonClicked(
const std::string& notification_id,
int button_index) {
if (popups_visible_)
OnMessageCenterChanged();
}
void UiController::OnNotificationSettingsClicked(bool handled) {
if (!handled)
ShowNotifierSettingsBubble();
}
void UiController::OnNotificationDisplayed(const std::string& notification_id,
const DisplaySource source) {
NotifyUiControllerChanged();
}
void UiController::OnQuietModeChanged(bool in_quiet_mode) {
NotifyUiControllerChanged();
}
void UiController::OnBlockingStateChanged(NotificationBlocker* blocker) {
OnMessageCenterChanged();
}
void UiController::OnMessageCenterChanged() {
#if defined(OS_CHROMEOS)
// TODO(yoshiki): Move the message center bubble related logic to ash/.
if (message_center_visible_ && message_center_->NotificationCount() == 0) {
if (hide_empty_message_center_callback_)
return;
hide_empty_message_center_callback_ =
std::make_unique<base::CancelableClosure>(base::Bind(
base::IgnoreResult(&UiController::HideMessageCenterBubble),
base::Unretained(this)));
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, hide_empty_message_center_callback_->callback());
return;
}
// Cancel the callback if necessary.
if (hide_empty_message_center_callback_)
hide_empty_message_center_callback_.reset();
#endif
if (popups_visible_ && !message_center_->HasPopupNotifications())
HidePopupBubbleInternal();
else if (!popups_visible_ && message_center_->HasPopupNotifications())
ShowPopupBubble();
NotifyUiControllerChanged();
}
void UiController::NotifyUiControllerChanged() {
delegate_->OnMessageCenterContentsChanged();
}
} // namespace message_center