blob: b29f3bcc97d887e35faa596f78c37516d3182b4b [file] [log] [blame]
// Copyright 2017 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/notification_platform_bridge_message_center.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/post_task.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/notifications/notification_display_service_impl.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "ui/message_center/public/cpp/notification.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 message_center::Notification& notification,
NotificationHandler::Type notification_type)
: profile_(profile),
notification_(notification),
notification_type_(notification_type) {
DCHECK_NE(notification_type, NotificationHandler::Type::TRANSIENT);
}
void SettingsClick() override {
NotificationDisplayServiceImpl::GetForProfile(profile_)
->ProcessNotificationOperation(
NotificationCommon::OPERATION_SETTINGS, notification_type_,
notification_.origin_url(), notification_.id(), base::nullopt,
base::nullopt, base::nullopt /* by_user */);
}
void DisableNotification() override {
NotificationDisplayServiceImpl::GetForProfile(profile_)
->ProcessNotificationOperation(
NotificationCommon::OPERATION_DISABLE_PERMISSION,
notification_type_, notification_.origin_url(), notification_.id(),
base::nullopt /* action_index */, base::nullopt /* reply */,
base::nullopt /* by_user */);
}
void Close(bool by_user) override {
NotificationDisplayServiceImpl::GetForProfile(profile_)
->ProcessNotificationOperation(
NotificationCommon::OPERATION_CLOSE, notification_type_,
notification_.origin_url(), notification_.id(),
base::nullopt /* action_index */, base::nullopt /* reply */,
by_user);
}
void Click(const base::Optional<int>& button_index,
const base::Optional<base::string16>& reply) override {
NotificationDisplayServiceImpl::GetForProfile(profile_)
->ProcessNotificationOperation(
NotificationCommon::OPERATION_CLICK, notification_type_,
notification_.origin_url(), notification_.id(), button_index, reply,
base::nullopt /* by_user */);
}
protected:
~PassThroughDelegate() override = default;
private:
Profile* profile_;
message_center::Notification notification_;
NotificationHandler::Type notification_type_;
DISALLOW_COPY_AND_ASSIGN(PassThroughDelegate);
};
} // namespace
NotificationPlatformBridgeMessageCenter::
NotificationPlatformBridgeMessageCenter(Profile* profile)
: profile_(profile) {}
NotificationPlatformBridgeMessageCenter::
~NotificationPlatformBridgeMessageCenter() = default;
void NotificationPlatformBridgeMessageCenter::Display(
NotificationHandler::Type notification_type,
Profile* profile,
const message_center::Notification& notification,
std::unique_ptr<NotificationCommon::Metadata> /* metadata */) {
DCHECK_EQ(profile, profile_);
NotificationUIManager* ui_manager =
g_browser_process->notification_ui_manager();
if (!ui_manager)
return; // The process is shutting down.
if (notification.delegate() ||
notification_type == NotificationHandler::Type::TRANSIENT) {
ui_manager->Add(notification, profile_);
return;
}
// If there's no delegate, replace it with a PassThroughDelegate so clicks
// go back to the appropriate handler.
message_center::Notification notification_with_delegate(notification);
notification_with_delegate.set_delegate(base::WrapRefCounted(
new PassThroughDelegate(profile_, notification, notification_type)));
ui_manager->Add(notification_with_delegate, profile_);
}
void NotificationPlatformBridgeMessageCenter::Close(
Profile* profile,
const std::string& notification_id) {
DCHECK_EQ(profile, profile_);
NotificationUIManager* ui_manager =
g_browser_process->notification_ui_manager();
if (!ui_manager)
return; // the process is shutting down
ui_manager->CancelById(notification_id,
NotificationUIManager::GetProfileID(profile_));
}
void NotificationPlatformBridgeMessageCenter::GetDisplayed(
Profile* profile,
GetDisplayedNotificationsCallback callback) const {
DCHECK_EQ(profile, profile_);
auto displayed_notifications =
g_browser_process->notification_ui_manager()->GetAllIdsByProfile(
NotificationUIManager::GetProfileID(profile_));
base::PostTaskWithTraits(
FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(std::move(callback), std::move(displayed_notifications),
true /* supports_synchronization */));
}
void NotificationPlatformBridgeMessageCenter::SetReadyCallback(
NotificationBridgeReadyCallback callback) {
std::move(callback).Run(true /* success */);
}
void NotificationPlatformBridgeMessageCenter::DisplayServiceShutDown(
Profile* profile) {}