Commit 450ee819 authored by nancy's avatar nancy Committed by Commit Bot

Add web page notifications for ExtensionApps.

For persistent notifications, get the app_id based on the scope url for
the notification.

For non-persistent notifications, get app_ids based on the origin url of
the notification.

TODO: Add web page notifications for WebApps.
TODO: Add tests.

BUG=1068884

Change-Id: I9e453c2095176e74f9db2da7fb74ae71ea05f67d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2162504
Commit-Queue: Nancy Wang <nancylingwang@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarPeter Beverloo <peter@chromium.org>
Cr-Commit-Position: refs/heads/master@{#763443}
parent 55d71197
......@@ -23,7 +23,7 @@ void AppNotifications::RemoveNotification(const std::string& notification_id) {
const std::string app_id = notification_id_to_app_id_[notification_id];
app_id_to_notification_id_[app_id].erase(notification_id);
if (!app_id_to_notification_id_[app_id].empty()) {
if (app_id_to_notification_id_[app_id].empty()) {
app_id_to_notification_id_.erase(app_id);
}
......
......@@ -1045,33 +1045,34 @@ void ExtensionApps::OnArcAppListPrefsDestroyed() {
arc_prefs_ = nullptr;
}
void ExtensionApps::OnDisplay(
const message_center::Notification& notification) {
void ExtensionApps::OnNotificationDisplayed(
const message_center::Notification& notification,
const NotificationCommon::Metadata* const metadata) {
switch (notification.notifier_id().type) {
case message_center::NotifierType::APPLICATION:
MaybeAddNotification(notification.notifier_id().id, notification.id());
return;
case message_center::NotifierType::WEB_PAGE:
// TODO(crbug.com/1068884): Handle web page notifications.
MaybeAddWebPageNotifications(notification, metadata);
return;
default:
return;
}
}
void ExtensionApps::OnClose(const std::string& notification_id) {
void ExtensionApps::OnNotificationClosed(const std::string& notification_id) {
const std::string& app_id =
app_notifications_.GetAppIdForNotification(notification_id);
if (app_id.empty() || MaybeGetExtension(app_id) == nullptr) {
return;
}
app_notifications_.RemoveNotification(notification_id);
Publish(app_notifications_.GetAppWithHasBadgeStatus(app_type_, app_id),
subscribers_);
}
void ExtensionApps::OnWillBeDestroyed(NotificationDisplayService* service) {
void ExtensionApps::OnNotificationDisplayServiceDestroyed(
NotificationDisplayService* service) {
notification_display_service_.Remove(service);
}
......@@ -1086,6 +1087,49 @@ void ExtensionApps::MaybeAddNotification(const std::string& app_id,
subscribers_);
}
void ExtensionApps::MaybeAddWebPageNotifications(
const message_center::Notification& notification,
const NotificationCommon::Metadata* const metadata) {
const GURL& url =
metadata
? PersistentNotificationMetadata::From(metadata)->service_worker_scope
: notification.origin_url();
if (app_type_ == apps::mojom::AppType::kExtension) {
extensions::ExtensionRegistry* registry =
extensions::ExtensionRegistry::Get(profile_);
DCHECK(registry);
const extensions::ExtensionSet& extensions = registry->enabled_extensions();
const extensions::Extension* extension = extensions.GetAppByURL(url);
if (extension) {
MaybeAddNotification(extension->id(), notification.id());
}
return;
}
if (metadata) {
// For persistent notifications, find the web app with the scope url.
base::Optional<web_app::AppId> app_id =
web_app::FindInstalledAppWithUrlInScope(profile_, url,
/*window_only=*/false);
if (app_id.has_value()) {
MaybeAddNotification(app_id.value(), notification.id());
}
} else {
// For non-persistent notifications, find all web apps that are installed
// under the origin url.
auto* web_app_provider = web_app::WebAppProvider::Get(profile_);
if (!web_app_provider) {
return;
}
auto app_ids = web_app_provider->registrar().FindAppsInScope(url);
for (const auto& app_id : app_ids) {
MaybeAddNotification(app_id, notification.id());
}
}
}
// static
bool ExtensionApps::IsBlacklisted(const std::string& app_id) {
// We blacklist (meaning we don't publish the app, in the App Service sense)
......
......@@ -17,6 +17,7 @@
#include "chrome/browser/apps/app_service/app_notifications.h"
#include "chrome/browser/apps/app_service/icon_key_util.h"
#include "chrome/browser/apps/app_service/paused_apps.h"
#include "chrome/browser/notifications/notification_common.h"
#include "chrome/browser/notifications/notification_display_service.h"
#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
#include "chrome/browser/ui/web_applications/web_app_launch_manager.h"
......@@ -178,12 +179,18 @@ class ExtensionApps : public apps::PublisherBase,
void OnArcAppListPrefsDestroyed() override;
// NotificationDisplayService::Observer overrides.
void OnDisplay(const message_center::Notification& notification) override;
void OnClose(const std::string& notification_id) override;
void OnWillBeDestroyed(NotificationDisplayService* service) override;
void OnNotificationDisplayed(
const message_center::Notification& notification,
const NotificationCommon::Metadata* const metadata) override;
void OnNotificationClosed(const std::string& notification_id) override;
void OnNotificationDisplayServiceDestroyed(
NotificationDisplayService* service) override;
void MaybeAddNotification(const std::string& app_id,
const std::string& notification_id);
void MaybeAddWebPageNotifications(
const message_center::Notification& notification,
const NotificationCommon::Metadata* const metadata);
// Checks if extension is disabled and if enable flow should be started.
// Returns true if extension enable flow is started or there is already one
......
......@@ -30,18 +30,22 @@ class NotificationDisplayService : public KeyedService {
public:
class Observer : public base::CheckedObserver {
public:
// Invoked when the |notification| is displayed.
virtual void OnDisplay(
const message_center::Notification& notification) = 0;
// Invoked when the |notification| is displayed. The |metadata| is provided
// for persistent web page notifications only, which require
// |service_worker_scope|.
virtual void OnNotificationDisplayed(
const message_center::Notification& notification,
const NotificationCommon::Metadata* const metadata) = 0;
// Invoked when the notification having |notification_id| is closed.
virtual void OnClose(const std::string& notification_id) = 0;
virtual void OnNotificationClosed(const std::string& notification_id) = 0;
// Invoked when the NotificationDisplayService object (the thing that this
// observer observes) will be destroyed. In response, the observer, |this|,
// should call "RemoveObserver(this)", whether directly or indirectly (e.g.
// via ScopedObserver::Remove).
virtual void OnWillBeDestroyed(NotificationDisplayService* service) = 0;
virtual void OnNotificationDisplayServiceDestroyed(
NotificationDisplayService* service) = 0;
protected:
~Observer() override;
......
......@@ -182,7 +182,7 @@ NotificationDisplayServiceImpl::NotificationDisplayServiceImpl(Profile* profile)
NotificationDisplayServiceImpl::~NotificationDisplayServiceImpl() {
for (auto& obs : observers_)
obs.OnWillBeDestroyed(this);
obs.OnNotificationDisplayServiceDestroyed(this);
}
void NotificationDisplayServiceImpl::ProcessNotificationOperation(
......@@ -268,6 +268,9 @@ void NotificationDisplayServiceImpl::Display(
return;
}
for (auto& observer : observers_)
observer.OnNotificationDisplayed(notification, metadata.get());
#if BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS)
NotificationPlatformBridge* bridge =
NotificationPlatformBridge::CanHandleType(notification_type)
......@@ -282,9 +285,6 @@ void NotificationDisplayServiceImpl::Display(
NotificationHandler* handler = GetNotificationHandler(notification_type);
if (handler)
handler->OnShow(profile_, notification.id());
for (auto& observer : observers_)
observer.OnDisplay(notification);
}
void NotificationDisplayServiceImpl::Close(
......@@ -310,7 +310,7 @@ void NotificationDisplayServiceImpl::Close(
#endif
for (auto& observer : observers_)
observer.OnClose(notification_id);
observer.OnNotificationClosed(notification_id);
}
void NotificationDisplayServiceImpl::GetDisplayed(
......
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