Commit 72004c40 authored by James Cook's avatar James Cook Committed by Commit Bot

lacros: Refactor NotificationPlatformBridgeChromeOs

Lacros needs to support two notification pathways:
* In-process, for the ash-chrome binary
* Out-of-process, for the lacros-chrome binary

However, both of these pathways have some shared behavior around
handling multiple profiles (for the pre-lacros ash case) and transient
notifications. This code lives in NotificationPlatformBridgeChromeOs
and we want to reuse it.

1. Introduce MessageCenterClientLacros. This is a stub for now. In
   a follow-up CL it will send notifications over mojo from lacros
   to ash.
2. Change NotificationPlatformBridgeChromeOs so it supports different
   |impl_| helpers for ash and lacros.
3. Refactor ChromeAshMessageCenterClient to inherit from
   NotificationPlatformBridge. This allows NPBChromeOs to have a
   generic |impl_| for both helpers, and avoids introducing a new
   abstract interface class.

See go/lacros-notifications for overall plan.

Bug: 1113889
Test: existing unit_tests and browser_tests
Change-Id: I159f410f3d84cc6e9bde0b3757015691f2289419
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2343217Reviewed-by: default avatarJun Mukai <mukai@chromium.org>
Commit-Queue: James Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/master@{#796096}
parent ee73f6f8
...@@ -4032,6 +4032,7 @@ static_library("browser") { ...@@ -4032,6 +4032,7 @@ static_library("browser") {
] ]
} }
# TODO(crbug.com/1052397): Rename chromeos_is_browser_only to is_lacros.
if (chromeos_is_browser_only) { if (chromeos_is_browser_only) {
sources += [ sources += [
"chrome_browser_main_extra_parts_lacros.cc", "chrome_browser_main_extra_parts_lacros.cc",
...@@ -4040,6 +4041,11 @@ static_library("browser") { ...@@ -4040,6 +4041,11 @@ static_library("browser") {
"lacros/lacros_chrome_service_delegate_impl.h", "lacros/lacros_chrome_service_delegate_impl.h",
"metrics/lacros_metrics_provider.cc", "metrics/lacros_metrics_provider.cc",
"metrics/lacros_metrics_provider.h", "metrics/lacros_metrics_provider.h",
"notifications/message_center_client_lacros.cc",
"notifications/message_center_client_lacros.h",
"notifications/notification_platform_bridge_chromeos.cc",
"notifications/notification_platform_bridge_chromeos.h",
"notifications/notification_platform_bridge_delegate.h",
] ]
deps += [ deps += [
"//chromeos/crosapi/mojom", "//chromeos/crosapi/mojom",
...@@ -4438,7 +4444,8 @@ static_library("browser") { ...@@ -4438,7 +4444,8 @@ static_library("browser") {
deps += [ "//components/dbus/thread_linux" ] deps += [ "//components/dbus/thread_linux" ]
} }
if (enable_native_notifications) { # TODO(crbug.com/1052397): Rename chromeos_is_browser_only to is_lacros.
if (enable_native_notifications && !chromeos_is_browser_only) {
sources += [ sources += [
"notifications/notification_platform_bridge_linux.cc", "notifications/notification_platform_bridge_linux.cc",
"notifications/notification_platform_bridge_linux.h", "notifications/notification_platform_bridge_linux.h",
......
...@@ -125,7 +125,10 @@ ChromeAshMessageCenterClient::~ChromeAshMessageCenterClient() { ...@@ -125,7 +125,10 @@ ChromeAshMessageCenterClient::~ChromeAshMessageCenterClient() {
} }
void ChromeAshMessageCenterClient::Display( void ChromeAshMessageCenterClient::Display(
const message_center::Notification& notification) { NotificationHandler::Type notification_type,
Profile* profile,
const message_center::Notification& notification,
std::unique_ptr<NotificationCommon::Metadata> metadata) {
auto message_center_notification = auto message_center_notification =
std::make_unique<message_center::Notification>( std::make_unique<message_center::Notification>(
base::WrapRefCounted( base::WrapRefCounted(
...@@ -134,7 +137,8 @@ void ChromeAshMessageCenterClient::Display( ...@@ -134,7 +137,8 @@ void ChromeAshMessageCenterClient::Display(
MessageCenter::Get()->AddNotification(std::move(message_center_notification)); MessageCenter::Get()->AddNotification(std::move(message_center_notification));
} }
void ChromeAshMessageCenterClient::Close(const std::string& notification_id) { void ChromeAshMessageCenterClient::Close(Profile* profile,
const std::string& notification_id) {
// During shutdown, Ash is destroyed before |this|, taking the MessageCenter // During shutdown, Ash is destroyed before |this|, taking the MessageCenter
// with it. // with it.
if (MessageCenter::Get()) { if (MessageCenter::Get()) {
...@@ -143,6 +147,21 @@ void ChromeAshMessageCenterClient::Close(const std::string& notification_id) { ...@@ -143,6 +147,21 @@ void ChromeAshMessageCenterClient::Close(const std::string& notification_id) {
} }
} }
void ChromeAshMessageCenterClient::GetDisplayed(
Profile* profile,
GetDisplayedNotificationsCallback callback) const {
// Right now, this is only used to get web notifications that were created by
// and have outlived a previous browser process. Ash itself doesn't outlive
// the browser process, so there's no need to implement.
std::move(callback).Run(/*notification_ids=*/{}, /*supports_sync=*/false);
}
void ChromeAshMessageCenterClient::SetReadyCallback(
NotificationBridgeReadyCallback callback) {
// Ash is always available in-process, so report the client is ready.
std::move(callback).Run(true);
}
void ChromeAshMessageCenterClient::GetNotifiers() { void ChromeAshMessageCenterClient::GetNotifiers() {
if (!notifier_observers_.might_have_observers()) if (!notifier_observers_.might_have_observers())
return; return;
......
...@@ -12,21 +12,28 @@ ...@@ -12,21 +12,28 @@
#include "chrome/browser/notifications/notification_platform_bridge_delegate.h" #include "chrome/browser/notifications/notification_platform_bridge_delegate.h"
#include "chrome/browser/notifications/notifier_controller.h" #include "chrome/browser/notifications/notifier_controller.h"
// This class serves as Chrome's AshMessageCenterClient, as well as the // Helper for NotificationPlatformBridgeChromeOs. Sends notifications to Ash
// NotificationPlatformBridge for ChromeOS. It dispatches notifications to Ash
// and handles interactions with those notifications, plus it keeps track of // and handles interactions with those notifications, plus it keeps track of
// NotifierControllers to provide notifier settings information to Ash (visible // NotifierControllers to provide notifier settings information to Ash (visible
// in NotifierSettingsView). // in NotifierSettingsView). With Lacros, runs in the ash-chrome process.
class ChromeAshMessageCenterClient : public ash::NotifierSettingsController, class ChromeAshMessageCenterClient : public NotificationPlatformBridge,
public ash::NotifierSettingsController,
public NotifierController::Observer { public NotifierController::Observer {
public: public:
explicit ChromeAshMessageCenterClient( explicit ChromeAshMessageCenterClient(
NotificationPlatformBridgeDelegate* delegate); NotificationPlatformBridgeDelegate* delegate);
~ChromeAshMessageCenterClient() override; ~ChromeAshMessageCenterClient() override;
void Display(const message_center::Notification& notification); // NotificationPlatformBridge:
void Close(const std::string& notification_id); void Display(NotificationHandler::Type notification_type,
Profile* profile,
const message_center::Notification& notification,
std::unique_ptr<NotificationCommon::Metadata> metadata) override;
void Close(Profile* profile, const std::string& notification_id) override;
void GetDisplayed(Profile* profile,
GetDisplayedNotificationsCallback callback) const override;
void SetReadyCallback(NotificationBridgeReadyCallback callback) override;
void DisplayServiceShutDown(Profile* profile) override {}
// ash::NotifierSettingsController: // ash::NotifierSettingsController:
void GetNotifiers() override; void GetNotifiers() override;
......
// Copyright 2020 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_client_lacros.h"
#include <utility>
#include "base/check.h"
#include "base/notreached.h"
MessageCenterClientLacros::MessageCenterClientLacros(
NotificationPlatformBridgeDelegate* delegate)
: delegate_(delegate) {
DCHECK(delegate_);
}
MessageCenterClientLacros::~MessageCenterClientLacros() = default;
void MessageCenterClientLacros::Display(
NotificationHandler::Type notification_type,
Profile* profile,
const message_center::Notification& notification,
std::unique_ptr<NotificationCommon::Metadata> metadata) {
NOTIMPLEMENTED();
}
void MessageCenterClientLacros::Close(Profile* profile,
const std::string& notification_id) {
NOTIMPLEMENTED();
}
void MessageCenterClientLacros::GetDisplayed(
Profile* profile,
GetDisplayedNotificationsCallback callback) const {
NOTIMPLEMENTED();
std::move(callback).Run(/*notification_ids=*/{}, /*supports_sync=*/false);
}
void MessageCenterClientLacros::SetReadyCallback(
NotificationBridgeReadyCallback callback) {
NOTIMPLEMENTED();
std::move(callback).Run(true);
}
void MessageCenterClientLacros::DisplayServiceShutDown(Profile* profile) {
NOTIMPLEMENTED();
}
// Copyright 2020 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.
#ifndef CHROME_BROWSER_NOTIFICATIONS_MESSAGE_CENTER_CLIENT_LACROS_H_
#define CHROME_BROWSER_NOTIFICATIONS_MESSAGE_CENTER_CLIENT_LACROS_H_
#include "chrome/browser/notifications/notification_platform_bridge.h"
class NotificationPlatformBridgeDelegate;
// Sends notifications to ash-chrome over mojo. Responds to user actions like
// clicks on notifications received over mojo. Works together with
// NotificationPlatformBridgeChromeOs because that class contains support for
// transient notifications and multiple profiles.
// TODO(jamescook): Derive from crosapi::mojom::MessageCenterClient once that
// mojo interface is introduced.
class MessageCenterClientLacros : public NotificationPlatformBridge {
public:
explicit MessageCenterClientLacros(
NotificationPlatformBridgeDelegate* delegate);
MessageCenterClientLacros(const MessageCenterClientLacros&) = delete;
MessageCenterClientLacros& operator=(const MessageCenterClientLacros&) =
delete;
~MessageCenterClientLacros() override;
// NotificationPlatformBridge:
void Display(NotificationHandler::Type notification_type,
Profile* profile,
const message_center::Notification& notification,
std::unique_ptr<NotificationCommon::Metadata> metadata) override;
void Close(Profile* profile, const std::string& notification_id) override;
void GetDisplayed(Profile* profile,
GetDisplayedNotificationsCallback callback) const override;
void SetReadyCallback(NotificationBridgeReadyCallback callback) override;
void DisplayServiceShutDown(Profile* profile) override;
// TODO(jamescook): Add "client" methods like OnNotificationClicked,
// OnNotificationClosed, etc.
private:
NotificationPlatformBridgeDelegate* delegate_;
};
#endif // CHROME_BROWSER_NOTIFICATIONS_MESSAGE_CENTER_CLIENT_LACROS_H_
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
#include <memory> #include <memory>
#include "base/callback_list.h" #include "base/callback_list.h"
#include "build/lacros_buildflags.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/notifications/chrome_ash_message_center_client.h"
#include "chrome/browser/notifications/notification_display_service_factory.h" #include "chrome/browser/notifications/notification_display_service_factory.h"
#include "chrome/browser/notifications/notification_display_service_impl.h" #include "chrome/browser/notifications/notification_display_service_impl.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
...@@ -17,6 +17,12 @@ ...@@ -17,6 +17,12 @@
#include "chrome/browser/ui/app_icon_loader.h" #include "chrome/browser/ui/app_icon_loader.h"
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
#if BUILDFLAG(IS_LACROS)
#include "chrome/browser/notifications/message_center_client_lacros.h"
#else
#include "chrome/browser/notifications/chrome_ash_message_center_client.h"
#endif
// static // static
std::unique_ptr<NotificationPlatformBridge> std::unique_ptr<NotificationPlatformBridge>
NotificationPlatformBridge::Create() { NotificationPlatformBridge::Create() {
...@@ -29,10 +35,16 @@ bool NotificationPlatformBridge::CanHandleType( ...@@ -29,10 +35,16 @@ bool NotificationPlatformBridge::CanHandleType(
return true; return true;
} }
NotificationPlatformBridgeChromeOs::NotificationPlatformBridgeChromeOs() NotificationPlatformBridgeChromeOs::NotificationPlatformBridgeChromeOs() {
: impl_(std::make_unique<ChromeAshMessageCenterClient>(this)) {} #if BUILDFLAG(IS_LACROS)
impl_ = std::make_unique<MessageCenterClientLacros>(this);
#else
impl_ = std::make_unique<ChromeAshMessageCenterClient>(this);
#endif
}
NotificationPlatformBridgeChromeOs::~NotificationPlatformBridgeChromeOs() {} NotificationPlatformBridgeChromeOs::~NotificationPlatformBridgeChromeOs() =
default;
void NotificationPlatformBridgeChromeOs::Display( void NotificationPlatformBridgeChromeOs::Display(
NotificationHandler::Type notification_type, NotificationHandler::Type notification_type,
...@@ -41,7 +53,8 @@ void NotificationPlatformBridgeChromeOs::Display( ...@@ -41,7 +53,8 @@ void NotificationPlatformBridgeChromeOs::Display(
std::unique_ptr<NotificationCommon::Metadata> metadata) { std::unique_ptr<NotificationCommon::Metadata> metadata) {
auto active_notification = std::make_unique<ProfileNotification>( auto active_notification = std::make_unique<ProfileNotification>(
profile, notification, notification_type); profile, notification, notification_type);
impl_->Display(active_notification->notification()); impl_->Display(active_notification->type(), profile,
active_notification->notification(), std::move(metadata));
std::string profile_notification_id = std::string profile_notification_id =
active_notification->notification().id(); active_notification->notification().id();
...@@ -56,25 +69,18 @@ void NotificationPlatformBridgeChromeOs::Close( ...@@ -56,25 +69,18 @@ void NotificationPlatformBridgeChromeOs::Close(
const std::string profile_notification_id = const std::string profile_notification_id =
ProfileNotification::GetProfileNotificationId( ProfileNotification::GetProfileNotificationId(
notification_id, NotificationUIManager::GetProfileID(profile)); notification_id, NotificationUIManager::GetProfileID(profile));
impl_->Close(profile, profile_notification_id);
impl_->Close(profile_notification_id);
} }
void NotificationPlatformBridgeChromeOs::GetDisplayed( void NotificationPlatformBridgeChromeOs::GetDisplayed(
Profile* profile, Profile* profile,
GetDisplayedNotificationsCallback callback) const { GetDisplayedNotificationsCallback callback) const {
// Right now, this is only used to get web notifications that were created by impl_->GetDisplayed(profile, std::move(callback));
// and have outlived a previous browser process. Ash itself doesn't outlive
// the browser process, so there's no need to implement.
std::set<std::string> displayed_notifications;
std::move(callback).Run(std::move(displayed_notifications), false);
} }
void NotificationPlatformBridgeChromeOs::SetReadyCallback( void NotificationPlatformBridgeChromeOs::SetReadyCallback(
NotificationBridgeReadyCallback callback) { NotificationBridgeReadyCallback callback) {
// We don't handle the absence of Ash or a failure to open a Mojo connection, impl_->SetReadyCallback(std::move(callback));
// so just assume the client is ready.
std::move(callback).Run(true);
} }
void NotificationPlatformBridgeChromeOs::DisplayServiceShutDown( void NotificationPlatformBridgeChromeOs::DisplayServiceShutDown(
...@@ -91,6 +97,8 @@ void NotificationPlatformBridgeChromeOs::DisplayServiceShutDown( ...@@ -91,6 +97,8 @@ void NotificationPlatformBridgeChromeOs::DisplayServiceShutDown(
for (auto id : ids_to_close) for (auto id : ids_to_close)
HandleNotificationClosed(id, false); HandleNotificationClosed(id, false);
impl_->DisplayServiceShutDown(profile);
} }
void NotificationPlatformBridgeChromeOs::HandleNotificationClosed( void NotificationPlatformBridgeChromeOs::HandleNotificationClosed(
......
...@@ -6,23 +6,22 @@ ...@@ -6,23 +6,22 @@
#define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_PLATFORM_BRIDGE_CHROMEOS_H_ #define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_PLATFORM_BRIDGE_CHROMEOS_H_
#include <map> #include <map>
#include <memory>
#include <string> #include <string>
#include "base/callback_forward.h"
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/notifications/notification_platform_bridge.h" #include "chrome/browser/notifications/notification_platform_bridge.h"
#include "chrome/browser/notifications/notification_platform_bridge_delegate.h" #include "chrome/browser/notifications/notification_platform_bridge_delegate.h"
#include "chrome/browser/notifications/profile_notification.h" #include "chrome/browser/notifications/profile_notification.h"
class ChromeAshMessageCenterClient;
// A platform bridge that uses Ash's message center to display notifications. // A platform bridge that uses Ash's message center to display notifications.
// Forwards requests to a helper implementation class, which either makes
// in-process C++ calls (pre-lacros) or mojo calls (post-lacros).
class NotificationPlatformBridgeChromeOs class NotificationPlatformBridgeChromeOs
: public NotificationPlatformBridge, : public NotificationPlatformBridge,
public NotificationPlatformBridgeDelegate { public NotificationPlatformBridgeDelegate {
public: public:
NotificationPlatformBridgeChromeOs(); NotificationPlatformBridgeChromeOs();
~NotificationPlatformBridgeChromeOs() override; ~NotificationPlatformBridgeChromeOs() override;
// NotificationPlatformBridge: // NotificationPlatformBridge:
...@@ -34,6 +33,7 @@ class NotificationPlatformBridgeChromeOs ...@@ -34,6 +33,7 @@ class NotificationPlatformBridgeChromeOs
void GetDisplayed(Profile* profile, void GetDisplayed(Profile* profile,
GetDisplayedNotificationsCallback callback) const override; GetDisplayedNotificationsCallback callback) const override;
void SetReadyCallback(NotificationBridgeReadyCallback callback) override; void SetReadyCallback(NotificationBridgeReadyCallback callback) override;
void DisplayServiceShutDown(Profile* profile) override;
// NotificationPlatformBridgeDelegate: // NotificationPlatformBridgeDelegate:
void HandleNotificationClosed(const std::string& id, bool by_user) override; void HandleNotificationClosed(const std::string& id, bool by_user) override;
...@@ -44,18 +44,18 @@ class NotificationPlatformBridgeChromeOs ...@@ -44,18 +44,18 @@ class NotificationPlatformBridgeChromeOs
const base::Optional<base::string16>& reply) override; const base::Optional<base::string16>& reply) override;
void HandleNotificationSettingsButtonClicked(const std::string& id) override; void HandleNotificationSettingsButtonClicked(const std::string& id) override;
void DisableNotification(const std::string& id) override; void DisableNotification(const std::string& id) override;
void DisplayServiceShutDown(Profile* profile) override;
private: private:
// Gets the ProfileNotification for the given identifier which has been // Gets the ProfileNotification for the given identifier which has been
// mutated to uniquely identify the profile. This may return null if the // mutated to uniquely identify the profile. This may return null if the
// notification has already been closed due to profile shutdown. Ash may // notification has already been closed due to profile shutdown. Ash may
// asynchronously inform |this| of actions on notificationafter their // asynchronously inform |this| of actions on notifications after their
// associated profile has already been destroyed. // associated profile has already been destroyed.
ProfileNotification* GetProfileNotification( ProfileNotification* GetProfileNotification(
const std::string& profile_notification_id); const std::string& profile_notification_id);
std::unique_ptr<ChromeAshMessageCenterClient> impl_; // Helper implementation.
std::unique_ptr<NotificationPlatformBridge> impl_;
// A container for all active notifications, where IDs are permuted to // A container for all active notifications, where IDs are permuted to
// uniquely identify both the notification and its source profile. The key is // uniquely identify both the notification and its source profile. The key is
......
...@@ -4518,7 +4518,8 @@ test("unit_tests") { ...@@ -4518,7 +4518,8 @@ test("unit_tests") {
} }
if (enable_native_notifications) { if (enable_native_notifications) {
if (is_desktop_linux) { # TODO(crbug.com/1052397): Rename chromeos_is_browser_only to is_lacros.
if (is_desktop_linux && !chromeos_is_browser_only) {
sources += [ "../browser/notifications/notification_platform_bridge_linux_unittest.cc" ] sources += [ "../browser/notifications/notification_platform_bridge_linux_unittest.cc" ]
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment