blob: 9449a00b96b8ef1504b57f96ca01a104f01c4b0f [file] [log] [blame]
// Copyright 2016 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 "chrome/browser/notifications/message_center_display_service.h"
#include <memory>
#include <set>
#include <string>
#include "chrome/browser/browser_process.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/notifications/notification_display_service_factory.h"
#include "chrome/browser/notifications/notification_handler.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_event_dispatcher.h"
#include "ui/message_center/notification_delegate.h"
namespace {
// A NotificationDelegate that passes through click actions to the notification
// display service (and on to the appropriate handler). This is a temporary
// class to ease the transition from NotificationDelegate to
// NotificationHandler.
// TODO(estade): also handle other NotificationDelegate actions as needed.
class PassThroughDelegate : public message_center::NotificationDelegate {
public:
PassThroughDelegate(Profile* profile,
const Notification& notification,
NotificationCommon::Type notification_type)
: profile_(profile),
notification_(notification),
notification_type_(notification_type) {}
void Close(bool by_user) override {
NotificationDisplayServiceFactory::GetForProfile(profile_)
->ProcessNotificationOperation(
NotificationCommon::CLOSE, notification_type_,
notification_.origin_url().possibly_invalid_spec(),
notification_.id(), base::nullopt, base::nullopt, by_user);
}
void Click() override {
NotificationDisplayServiceFactory::GetForProfile(profile_)
->ProcessNotificationOperation(
NotificationCommon::CLICK, notification_type_,
notification_.origin_url().possibly_invalid_spec(),
notification_.id(), base::nullopt, base::nullopt, base::nullopt);
}
void ButtonClick(int button_index) override {
NotificationDisplayServiceFactory::GetForProfile(profile_)
->ProcessNotificationOperation(
NotificationCommon::CLICK, notification_type_,
notification_.origin_url().possibly_invalid_spec(),
notification_.id(), button_index, base::nullopt, base::nullopt);
}
protected:
~PassThroughDelegate() override = default;
private:
Profile* profile_;
Notification notification_;
NotificationCommon::Type notification_type_;
DISALLOW_COPY_AND_ASSIGN(PassThroughDelegate);
};
} // namespace
MessageCenterDisplayService::MessageCenterDisplayService(Profile* profile)
: NotificationDisplayService(profile), profile_(profile) {}
MessageCenterDisplayService::~MessageCenterDisplayService() {}
void MessageCenterDisplayService::Display(
NotificationCommon::Type notification_type,
const std::string& notification_id,
const Notification& notification,
std::unique_ptr<NotificationCommon::Metadata> metadata) {
// TODO(miguelg): MCDS should stop relying on the |notification|'s delegate
// for Close/Click operations once the Notification object becomes a mojom
// type.
// This can be called when the browser is shutting down and the
// NotificationUiManager has already destructed.
NotificationUIManager* ui_manager =
g_browser_process->notification_ui_manager();
if (!ui_manager)
return;
NotificationHandler* handler = GetNotificationHandler(notification_type);
handler->OnShow(profile_, notification_id);
if (notification.delegate()) {
ui_manager->Add(notification, profile_);
return;
}
// If there's no delegate, replace it with a PassThroughDelegate so clicks
// go back to the appropriate handler.
Notification notification_with_delegate(
notification.type(), notification.id(), notification.title(),
notification.message(), notification.icon(), notification.notifier_id(),
notification.display_source(), notification.origin_url(),
notification.tag(), notification.rich_notification_data(),
base::WrapRefCounted(
new PassThroughDelegate(profile_, notification, notification_type)));
ui_manager->Add(notification_with_delegate, profile_);
}
void MessageCenterDisplayService::Close(
NotificationCommon::Type notification_type,
const std::string& notification_id) {
// This can be called when the browser is shutting down and the
// NotificationUiManager has already destructed.
NotificationUIManager* ui_manager =
g_browser_process->notification_ui_manager();
if (ui_manager) {
ui_manager->CancelById(notification_id,
NotificationUIManager::GetProfileID(profile_));
}
}
void MessageCenterDisplayService::GetDisplayed(
const DisplayedNotificationsCallback& callback) {
auto displayed_notifications = std::make_unique<std::set<std::string>>(
g_browser_process->notification_ui_manager()->GetAllIdsByProfile(
NotificationUIManager::GetProfileID(profile_)));
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::BindOnce(callback, base::Passed(&displayed_notifications),
true /* supports_synchronization */));
}